bit-packer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ gem "lookup-hash", ">= 0.2.0"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "bundler", "~> 1.0.0"
10
+ gem "jeweler", "~> 1.5.2"
11
+ gem "riot", ">= 0.12.1"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ hash-utils (0.11.0)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ lookup-hash (0.2.0)
11
+ hash-utils (>= 0.11.0)
12
+ rake (0.8.7)
13
+ riot (0.12.1)
14
+ rr
15
+ term-ansicolor
16
+ rr (1.0.2)
17
+ term-ansicolor (1.0.5)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ bundler (~> 1.0.0)
24
+ jeweler (~> 1.5.2)
25
+ lookup-hash (>= 0.2.0)
26
+ riot (>= 0.12.1)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Martin Kozák
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ BitPacker
2
+ =========
3
+
4
+ **bit-packer** provides easy declarative way of analyzing the packed bit
5
+ arrays. See an example:
6
+
7
+ require "bit-packer"
8
+
9
+ bp = BitPacker::new(7) do
10
+ number (:alfa) {2} # length of the entry in bits in block
11
+ boolean :beta
12
+ end
13
+
14
+ p bp.data
15
+ # will print out #<struct alfa=3, beta=true>
16
+
17
+ You can both read from data struct and write to it:
18
+
19
+ bp.data.boolean = false
20
+ bp.data.number = 2
21
+
22
+ p bp.to_i
23
+ # will print out 4
24
+
25
+ Contributing
26
+ ------------
27
+
28
+ 1. Fork it.
29
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
30
+ 3. Commit your changes (`git commit -am "Added something"`).
31
+ 4. Push to the branch (`git push origin 20101220-my-change`).
32
+ 5. Create an [Issue][2] with a link to your branch.
33
+ 6. Enjoy a refreshing Diet Coke and wait.
34
+
35
+ Copyright
36
+ ---------
37
+
38
+ Copyright &copy; 2011 [Martin Kozák][3]. See `LICENSE.txt` for
39
+ further details.
40
+
41
+ [2]: http://github.com/martinkozak/bit-packer/issues
42
+ [3]: http://www.martinkozak.net/
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+ require 'rake'
12
+
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gem|
15
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
16
+ gem.name = "bit-packer"
17
+ gem.homepage = "http://github.com/martinkozak/bit-packer"
18
+ gem.license = "MIT"
19
+ gem.summary = 'Provides easy declarative way of analyzing the packed bit arrays.'
20
+ gem.email = "martinkozak@martinkozak.net"
21
+ gem.authors = ["Martin Kozák"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/rdoctask'
30
+ Rake::RDocTask.new do |rdoc|
31
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = "hash-utils #{version}"
35
+ rdoc.rdoc_files.include('README*')
36
+ rdoc.rdoc_files.include('lib/**/*.rb')
37
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{bit-packer}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Martin Kozák"]
12
+ s.date = %q{2011-03-02}
13
+ s.email = %q{martinkozak@martinkozak.net}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bit-packer.gemspec",
27
+ "lib/bit-packer.rb",
28
+ "test"
29
+ ]
30
+ s.homepage = %q{http://github.com/martinkozak/bit-packer}
31
+ s.licenses = ["MIT"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.5.3}
34
+ s.summary = %q{Provides easy declarative way of analyzing the packed bit arrays.}
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ s.add_runtime_dependency(%q<lookup-hash>, [">= 0.2.0"])
41
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
42
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
43
+ s.add_development_dependency(%q<riot>, [">= 0.12.1"])
44
+ else
45
+ s.add_dependency(%q<lookup-hash>, [">= 0.2.0"])
46
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
47
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
48
+ s.add_dependency(%q<riot>, [">= 0.12.1"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<lookup-hash>, [">= 0.2.0"])
52
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
53
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
54
+ s.add_dependency(%q<riot>, [">= 0.12.1"])
55
+ end
56
+ end
57
+
data/lib/bit-packer.rb ADDED
@@ -0,0 +1,242 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "lookup-hash/frozen"
5
+
6
+ class BitPacker
7
+
8
+ ##
9
+ # Holds types index.
10
+ #
11
+
12
+ TYPES = Frozen::LookupHash[
13
+ :number,
14
+ :boolean
15
+ ]
16
+
17
+ ##
18
+ # Indicates size of one byte.
19
+ #
20
+
21
+ BYTESIZE = 8
22
+
23
+ ##
24
+ # Holds resultant data structure.
25
+ #
26
+
27
+ @struct
28
+
29
+ ##
30
+ # Holds type stack.
31
+ #
32
+
33
+ @stack
34
+
35
+ ##
36
+ # Holds data.
37
+ #
38
+
39
+ @data
40
+
41
+ ##
42
+ # Holds raw data.
43
+ # @return [Integer] raw (original) integer data
44
+ #
45
+
46
+ attr_reader :raw
47
+ @raw
48
+
49
+ ##
50
+ # Holds total length.
51
+ #
52
+ # @return [Integer] total length of the packed data according
53
+ # to declaration
54
+ #
55
+
56
+ attr_reader :length
57
+ @length
58
+
59
+ ##
60
+ # Constructor.
61
+ #
62
+ # @param [Integer] data raw integer for unpack
63
+ # @param [Proc] block block with declaration
64
+ # @see #declare
65
+ #
66
+
67
+ def initialize(data = nil, &block)
68
+ @stack = [ ]
69
+ @length = 0
70
+ self.declare(&block)
71
+
72
+ if not data.nil?
73
+ self << data
74
+ end
75
+ end
76
+
77
+ ##
78
+ # Receives declaration.
79
+ #
80
+ # Adds declaration of bit array items. Can be call multiple times.
81
+ # New delcarations are joind to end of the array.
82
+ #
83
+ # @example
84
+ # packer.declare do
85
+ # number (:number) {2}
86
+ # boolean :boolean
87
+ # end
88
+ #
89
+ # @param [Proc] block block with declaration
90
+ # @see TYPES
91
+ #
92
+
93
+ def declare(&block)
94
+ self.instance_eval(&block)
95
+ end
96
+
97
+ ##
98
+ # Handles missing methods as declarations.
99
+ #
100
+ # @param [Symbol] name data type of the entry
101
+ # @param [Array] args first argument is expected to be name
102
+ # @param [Proc] block block which returns length of the entry in bits
103
+ # @return [Integer] new length of the packed data
104
+ # @see #declare
105
+ #
106
+
107
+ def method_missing(name, *args, &block)
108
+ if not self.class::TYPES.include? name
109
+ raise Exception::new("Invalid type/method specified: '" << name.to_s << "'.")
110
+ end
111
+
112
+ if not block.nil?
113
+ length = block.call()
114
+ else
115
+ length = 1
116
+ end
117
+
118
+ self.add(args.first, name, length)
119
+ end
120
+
121
+ ##
122
+ # Adds declaration.
123
+ #
124
+ # @param [Symbol] name name of the entry
125
+ # @param [Symbol] type type of the entry
126
+ # @param [Integer] length length of the entry in bits
127
+ # @return [Integer] new length of the packed data
128
+ #
129
+
130
+ def add(name, type, length = 1)
131
+ @stack << [name, type, @length, length]
132
+ @struct = nil
133
+ @length += length
134
+ end
135
+
136
+ ##
137
+ # Fills by input data.
138
+ # @param [Integer] value raw integer data for unpack
139
+ #
140
+
141
+ def <<(value)
142
+ if not value.kind_of? Integer
143
+ raise Exception::new("Integer is expected for BitPacker.")
144
+ end
145
+
146
+ @raw = value
147
+ @data = nil
148
+ end
149
+
150
+ ##
151
+ # Returns structure analyze.
152
+ # @return [Class] struct with the packed data
153
+ #
154
+
155
+ def data
156
+ if @data.nil?
157
+ values = [ ]
158
+
159
+ @stack.each do |name, type, position, length|
160
+ rel_pos = @length - position - length
161
+ value = @raw & __mask(rel_pos, length)
162
+
163
+ case type
164
+ when :boolean
165
+ values << (value > 0)
166
+ when :number
167
+ values << (value >> rel_pos)
168
+ end
169
+ end
170
+
171
+ @data = __struct::new(*values)
172
+ end
173
+
174
+ return @data
175
+ end
176
+
177
+ ##
178
+ # Converts to integer.
179
+ # @return [Integer] resultant integer according to current data state
180
+ #
181
+
182
+ def to_i
183
+ result = 0
184
+ @stack.each do |name, type, position, length|
185
+ rel_pos = @length - position - length
186
+ value = self.data[name]
187
+
188
+ case type
189
+ when :boolean
190
+ mask = __mask(rel_pos, length)
191
+ if value === true
192
+ result |= mask
193
+ else
194
+ result &= ~mask
195
+ end
196
+ when :number
197
+ value &= __mask(0, length)
198
+ value = value << rel_pos
199
+ result |= value
200
+ end
201
+ end
202
+
203
+ return result
204
+ end
205
+
206
+ alias :to_int :to_i
207
+
208
+
209
+ protected
210
+
211
+ ##
212
+ # Generates mask.
213
+ #
214
+
215
+ def __mask(position, length = 1)
216
+
217
+ # length of mask
218
+ mask = 0
219
+ length.times do |i|
220
+ mask += 2 ** i
221
+ end
222
+
223
+ # position of mask
224
+ mask = mask << position
225
+
226
+ return mask
227
+ end
228
+
229
+ ##
230
+ # Returns data struct.
231
+ #
232
+
233
+ def __struct
234
+ if @struct.nil?
235
+ members = @stack.map { |i| i[0] }
236
+ @struct = Struct::new(*members)
237
+ end
238
+
239
+ return @struct
240
+ end
241
+
242
+ end
data/test ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
4
+
5
+ $:.push("./lib")
6
+ require "bit-packer"
7
+ require "riot"
8
+
9
+ context "BitPacker" do
10
+ setup do
11
+ BitPacker::new(7) do
12
+ number (:number) {2}
13
+ boolean :boolean
14
+ end
15
+ end
16
+
17
+ asserts("correct unpacking") do
18
+ (topic.data.boolean == true) and (topic.data.number == 3)
19
+ end
20
+ asserts("correct packing") do
21
+ topic.data.boolean = false
22
+ topic.data.number = 2
23
+ topic.to_i == 4
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bit-packer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - "Martin Koz\xC3\xA1k"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-02 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: lookup-hash
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: jeweler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.2
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: riot
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.12.1
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ description:
61
+ email: martinkozak@martinkozak.net
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files:
67
+ - LICENSE.txt
68
+ - README.md
69
+ files:
70
+ - .document
71
+ - Gemfile
72
+ - Gemfile.lock
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - VERSION
77
+ - bit-packer.gemspec
78
+ - lib/bit-packer.rb
79
+ - test
80
+ has_rdoc: true
81
+ homepage: http://github.com/martinkozak/bit-packer
82
+ licenses:
83
+ - MIT
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: -1036686220775041030
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.5.3
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Provides easy declarative way of analyzing the packed bit arrays.
111
+ test_files: []
112
+