tlv 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ This package is copyrighted free software by Tim Becker <tim@kuriositaet.de>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ (see COPYING.txt file), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict
21
+ with standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
+ files under the ./missing directory. See each file for the copying
46
+ condition.
47
+
48
+ 5. The scripts and library files supplied as input to or produced as
49
+ output from the software do not automatically fall under the
50
+ copyright of the software, but belong to whomever generated them,
51
+ and may be sold commercially, and may be aggregated with this
52
+ software.
53
+
54
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
+ PURPOSE.
58
+
data/README ADDED
@@ -0,0 +1,38 @@
1
+ = tlv -- lib to facilitate working with tlv data
2
+
3
+
4
+ == Installing
5
+
6
+ Having a "Installing" section is a bit of a chicken or egg question.
7
+ Someone reading this README has, in all likelyhood already installed the
8
+ package.
9
+
10
+ You can install the +tlv+ package by executing:
11
+
12
+ gem install tlv -r
13
+
14
+ alternatively, you can download +.tar.gz+ or +.zip+ archives from
15
+ Rubyforge[http://rubyforge.org/frs/?group_id=2203].
16
+
17
+
18
+ == Mail
19
+
20
+ In case you discover bugs, spelling errors, offer suggestions for
21
+ improvements or would like to help out with the project, you can contact
22
+ me directly (tim@kuriositaet.de).
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+ =
@@ -0,0 +1,163 @@
1
+ require "rdoc/task"
2
+ require "rubygems/package_task"
3
+ require "rake/testtask"
4
+ require "rake/clean"
5
+ require "rubygems"
6
+
7
+ # Some definitions that you'll need to edit in case you reuse this
8
+ # Rakefile for your own project.
9
+
10
+ SHORTNAME ='tlv' # this should be the rubyforge project name
11
+ DESC ='lib for handling tlv data'
12
+ PKG_VERSION ='0.0.3'
13
+ LONG_DESC = <<END_DESC
14
+ lib for handling tlv (der) and dgi encoded data
15
+ END_DESC
16
+ RUBYFORGE_USER ='a2800276'
17
+ AUTHOR = "Tim Becker"
18
+ EMAIL = "tim@kuriositaet.de"
19
+ HOMEPAGE = "http://github.com/a2800276/tlv"
20
+
21
+
22
+ # Specifies the default task to execute. This is often the "test" task
23
+ # and we'll change things around as soon as we have some tests.
24
+
25
+ task :default => [:test]
26
+
27
+ # The directory to generate +rdoc+ in.
28
+ RDOC_DIR="doc/html"
29
+
30
+ # This global variable contains files that will be erased by the `clean` task.
31
+ # The `clean` task itself is automatically generated by requiring `rake/clean`.
32
+
33
+ CLEAN << RDOC_DIR << "pkg"
34
+
35
+
36
+ # This is the task that generates the +rdoc+ documentation from the
37
+ # source files. Instantiating Rake::RDocTask automatically generates a
38
+ # task called `rdoc`.
39
+
40
+ Rake::RDocTask.new do |rd|
41
+ # Options for documenation generation are specified inside of
42
+ # this block. For example the following line specifies that the
43
+ # content of the README file should be the main page of the
44
+ # documenation.
45
+ rd.main = "README"
46
+
47
+ # The following line specifies all the files to extract
48
+ # documenation from.
49
+ rd.rdoc_files.include( "README", "AUTHORS", "LICENSE", "TODO",
50
+ "CHANGELOG", "bin/**/*", "lib/**/*.rb",
51
+ "examples/**/*rb", "doc/*.rdoc")
52
+ # This one specifies the output directory ...
53
+ rd.rdoc_dir = "doc/html"
54
+
55
+ # Or the HTML title of the generated documentation set.
56
+ rd.title = "#{SHORTNAME}: #{DESC}"
57
+
58
+ # These are options specifiying how source code inlined in the
59
+ # documentation should be formatted.
60
+
61
+ rd.options = ["--line-numbers", "--inline-source"]
62
+
63
+ # Check:
64
+ # `rdoc --help` for more rdoc options
65
+ # the {rdoc documenation home}[http://www.ruby-doc.org/stdlib/libdoc/rdoc/rdoc/index.html]
66
+ # or the documentation for the +Rake::RDocTask+ task[http://rake.rubyforge.org/classes/Rake/RDocTask.html]
67
+ end
68
+ Rake::RDocTask.new(:rdoc_dev) do |rd|
69
+ # Options for documenation generation are specified inside of
70
+ # this block. For example the following line specifies that the
71
+ # content of the README file should be the main page of the
72
+ # documenation.
73
+ rd.main = "README"
74
+
75
+ # The following line specifies all the files to extract
76
+ # documenation from.
77
+ rd.rdoc_files.include( "README", "AUTHORS", "LICENSE", "TODO",
78
+ "CHANGELOG", "bin/**/*", "lib/**/*.rb",
79
+ "examples/**/*rb","test/**/*.rb", "doc/*.rdoc")
80
+ # This one specifies the output directory ...
81
+ rd.rdoc_dir = "doc/dev_html"
82
+
83
+ # Or the HTML title of the generated documentation set.
84
+ rd.title = "#{SHORTNAME}: #{DESC}"
85
+
86
+ # These are options specifiying how source code inlined in the
87
+ # documentation should be formatted.
88
+
89
+ rd.options = ["--line-numbers", "--inline-source"]
90
+
91
+ # Check:
92
+ # `rdoc --help` for more rdoc options
93
+ # the {rdoc documenation home}[http://www.ruby-doc.org/stdlib/libdoc/rdoc/rdoc/index.html]
94
+ # or the documentation for the +Rake::RDocTask+ task[http://rake.rubyforge.org/classes/Rake/RDocTask.html]
95
+ end
96
+
97
+ # The GemPackageTask facilitates getting all your files collected
98
+ # together into gem archives. You can also use it to generate tarball
99
+ # and zip archives.
100
+
101
+ # First you'll need to assemble a gemspec
102
+
103
+ PKG_FILES = FileList['lib/**/*.rb', 'bin/**/*', 'examples/**/*', '[A-Z]*', 'test/**/*'].to_a
104
+
105
+ spec = Gem::Specification.new do |s|
106
+ s.platform = Gem::Platform::RUBY
107
+ s.summary = "#{SHORTNAME}: #{DESC}"
108
+ s.add_dependency "hexy"
109
+ s.name = SHORTNAME
110
+ s.version = PKG_VERSION
111
+ s.files = PKG_FILES
112
+ s.requirements << "none"
113
+ s.require_path = 'lib'
114
+ s.description = LONG_DESC
115
+ s.author = AUTHOR
116
+ s.email = EMAIL
117
+ s.homepage = HOMEPAGE
118
+ s.has_rdoc = true
119
+ s.executables = ["parse_tlv", "parse_dgi"]
120
+ end
121
+
122
+ # Adding a new GemPackageTask adds a task named `package`, which generates
123
+ # packages as gems, tarball and zip archives.
124
+ Gem::PackageTask.new(spec) do |pkg|
125
+ pkg.need_zip = true
126
+ pkg.need_tar_gz = true
127
+ end
128
+
129
+
130
+ # This task is used to demonstrate how to upload files to Rubyforge.
131
+ # Calling `upload_page` creates a current version of the +rdoc+
132
+ # documentation and uploads it to the Rubyforge homepage of the project,
133
+ # assuming it's hosted there and naming conventions haven't changed.
134
+ #
135
+ # This task uses `sh` to call the `scp` binary, which is plattform
136
+ # dependant and may not be installed on your computer if you're using
137
+ # Windows. I'm currently not aware of any pure ruby way to do scp
138
+ # transfers.
139
+
140
+ RubyForgeProject=SHORTNAME
141
+
142
+ desc "Upload the web pages to the web."
143
+ task :upload_pages => ["rdoc"] do
144
+ if RubyForgeProject then
145
+ path = "/var/www/gforge-projects/#{RubyForgeProject}"
146
+ sh "scp -r doc/html/* #{RUBYFORGE_USER}@rubyforge.org:#{path}"
147
+ sh "scp doc/images/*.png #{RUBYFORGE_USER}@rubyforge.org:#{path}/images"
148
+ end
149
+ end
150
+
151
+ # This task will run the unit tests provided in files called
152
+ # `test/test*.rb`. The task itself can be run with a call to `rake test`
153
+
154
+ Rake::TestTask.new do |t|
155
+ t.libs << "test"
156
+ t.libs << "lib"
157
+ t.test_files = FileList['test/*.rb']
158
+ t.ruby_opts = ["-rubygems"]
159
+ t.verbose = true
160
+ end
161
+
162
+
163
+
data/THANKS ADDED
File without changes
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ * Unit Tests
2
+ testin for `payload_hook`
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'tlv'
5
+ require 'tlv/parser/dictionaries/dictionaries'
6
+
7
+ USAGE =<<END
8
+ usage: parse_dgi [-hex] [-dictionaries] [-d dictionary] (file_to_parse | < file_to_parse)
9
+ -hex interpred input data as hex
10
+ -dictionaries list available dictionaries
11
+ END
12
+
13
+ hex = ARGV.delete "-hex"
14
+ list_dictionaries = ARGV.delete "-dictionaries"
15
+
16
+ if (i = ARGV.index("-d"))
17
+ dict = TLV::DICTIONARIES[ARGV[i+1]]
18
+ ARGV.delete_at i
19
+ ARGV.delete_at i
20
+ end
21
+ file = ARGV.last
22
+
23
+ if file
24
+ unless File.exists?(file) && File.readable?(file)
25
+ STDERR.puts USAGE
26
+ exit(1)
27
+ end
28
+ end
29
+
30
+ if list_dictionaries
31
+ TLV::DICTIONARIES.each_key{|key|
32
+ puts key
33
+ }
34
+ exit(0)
35
+ end
36
+
37
+ io = file ? File.open(file) : STDIN
38
+
39
+ lines = io.readlines
40
+ #lines.each {|line|
41
+ # puts TLV.s2b(line)+"<<<<<"
42
+ # puts line
43
+ #}
44
+ if hex
45
+ puts TLV.parse_dgi_hex(lines.join, dict || {})
46
+ else
47
+ puts TLV.parse_dgi(lines.join, dict || {})
48
+ end
49
+
50
+ io.close
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'tlv'
5
+ require 'tlv/parser/dictionaries/dictionaries'
6
+
7
+
8
+ USAGE =<<END
9
+ usage: parse_tlv [-hex] [-dictionaries] [-d dictionary] (file_to_parse | < file_to_parse)
10
+ -hex interpred input data as hex
11
+ -dictionaries list available dictionaries
12
+ END
13
+
14
+ hex = ARGV.delete "-hex"
15
+ list_dictionaries = ARGV.delete "-dictionaries"
16
+
17
+ if (i = ARGV.index("-d"))
18
+ dict = TLV::DICTIONARIES[ARGV[i+1]]
19
+ ARGV.delete_at i
20
+ ARGV.delete_at i
21
+ end
22
+ file = ARGV.last
23
+
24
+ if file
25
+ unless File.exists?(file) && File.readable?(file)
26
+ STDERR.puts USAGE
27
+ exit(1)
28
+ end
29
+ end
30
+
31
+ if list_dictionaries
32
+ TLV::DICTIONARIES.each_key{|key|
33
+ puts key
34
+ }
35
+ exit(0)
36
+ end
37
+
38
+ io = file ? File.open(file) : STDIN
39
+
40
+
41
+ lines = io.readlines
42
+ #lines.each {|line|
43
+ # puts TLV.s2b(line)
44
+ #}
45
+ if hex
46
+ puts TLV.parse_hex(lines.join, dict)
47
+ else
48
+ puts TLV.parse(lines.join,dict)
49
+ end
50
+
51
+ io.close
@@ -0,0 +1,11 @@
1
+
2
+ require 'tlv/field'
3
+ require 'tlv/tlv'
4
+ require 'tlv/b'
5
+ require 'tlv/raw'
6
+ require 'tlv/parse'
7
+ require 'tlv/tag'
8
+ require 'tlv/constructed'
9
+ require 'tlv/to_bytes'
10
+ require 'tlv/dgi'
11
+ require 'tlv/parser/parser'
@@ -0,0 +1,32 @@
1
+ module TLV
2
+
3
+ class TLV
4
+ class B < Field
5
+ def define_accessor clazz
6
+ super
7
+ name = @name
8
+ len = @length
9
+ clazz.instance_eval{
10
+ define_method("#{name}="){|val|
11
+ raise("invalid value nil") unless val
12
+ raise("must be a String #{val}") unless val.is_a?(String)
13
+ raise("incorrect length: #{val}") unless (val.length*8) <= len
14
+ self.instance_variable_set("@#{name}", val)
15
+ }
16
+
17
+ define_method("#{name}") {
18
+ self.instance_variable_get("@#{name}") || "\x00" * (len/8)
19
+ }
20
+ }
21
+ end
22
+
23
+ def parse tlv, bytes, _len
24
+ val = bytes[0, length/8]
25
+ rest = bytes[length/8, bytes.length]
26
+ # check val...
27
+ tlv.send("#{name}=", val)
28
+ rest
29
+ end
30
+ end
31
+ end
32
+ end # module
@@ -0,0 +1,116 @@
1
+ module TLV
2
+ class TLV
3
+ class << self
4
+
5
+ def mand_tags
6
+ @mand_tags ||= (self == TLV ? [] : superclass.mand_tags.dup)
7
+ end
8
+ def opt_tags
9
+ @opt_tags ||= (self == TLV ? [] : superclass.opt_tags.dup)
10
+ end
11
+
12
+ # Takes either a subclass of TLV or the following options, which are used to
13
+ # create an subclass.
14
+ # Options:
15
+ # :tag
16
+ # :display_name
17
+ #
18
+ # :classname (will be derived from display_name if not given)
19
+ # :accessor_name (will be derived from display_name if not given)
20
+ def mandatory tlv, accessor_name=nil
21
+ handle_subtag mand_tags, tlv, accessor_name
22
+ end
23
+
24
+ # for constructed tlv's, add subtags that may be present
25
+ def optional tlv, accessor_name=nil
26
+ handle_subtag opt_tags, tlv, accessor_name
27
+ end
28
+
29
+ def register tlv
30
+ @tlv_classes ||= {}
31
+ warn "tag #{TLV.b2s(tlv.tag)} already defined!" if @tlv_classes[tlv.tag]
32
+ @tlv_classes[tlv.tag] = tlv
33
+ end
34
+
35
+ def lookup tag
36
+ return self if tag == self.tag
37
+ @tlv_classes ||= {}
38
+ tlv = @tlv_classes[tag]
39
+ if !tlv && ! (self == TLV)
40
+ warn "looking up tag #{TLV.b2s(tag)} in super!"
41
+ raise "bla"
42
+ tlv ||= super
43
+ end
44
+ tlv
45
+ end
46
+
47
+ # internal, common functionality for mndatory and optional
48
+ def handle_subtag arr, tlv, accessor_name
49
+ tlv = handle_options(tlv) if tlv.is_a? Hash
50
+ raise "#{tlv} must be a subclass of TLV!" unless tlv.ancestors.include? TLV
51
+ if accessor_name
52
+ tlv= tlv.dup
53
+ tlv.accessor_name= accessor_name
54
+ end
55
+ define_accessor(tlv)
56
+
57
+ register(tlv)
58
+ arr << tlv
59
+ end
60
+
61
+ def handle_options options
62
+ tag = options[:tag]
63
+ display_name = options[:display_name]
64
+ classname = options[:classname] || rubify_c(display_name)
65
+ new_class = self.const_set(classname, Class.new(TLV))
66
+ new_class.tlv(tag, display_name, options[:accessor_name])
67
+ new_class.raw
68
+ new_class
69
+ end
70
+
71
+ def rubify_a display
72
+ name = display.strip.gsub(/\s+/, "_")
73
+ name = name.downcase.to_sym
74
+ end
75
+
76
+ def rubify_c display
77
+ name = display.gsub(/\s+/, "")
78
+ end
79
+
80
+ def define_accessor tlv_class
81
+ s = tlv_class
82
+ # check we are actually creating an accessor for an TLV
83
+ while s = s.superclass
84
+ break if s == TLV
85
+ end
86
+ raise "not a TLV class!" unless s
87
+
88
+ # determine the accessor name
89
+ # currently the call graph of this method ensures the class
90
+ # will have an accessor name.
91
+ name = tlv_class.accessor_name
92
+
93
+ define_method("#{name}="){ |val|
94
+ # must either be an instance of tlv_val
95
+ # or a raw value.
96
+ if val.is_a? TLV
97
+ self.instance_variable_set("@#{name}", val)
98
+ else
99
+ v = tlv_class.new
100
+ # _should_ be a String, but we'll bang anything
101
+ # into value for now...
102
+ v.value = val.to_s
103
+ self.instance_variable_set("@#{name}", v)
104
+ end
105
+ }
106
+
107
+ define_method("#{name}") {
108
+ self.instance_variable_get("@#{name}")
109
+ }
110
+
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+ end #module