bit_mask 0.0.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,44 @@
1
+ .rvmrc
2
+ Gemfile.lock
3
+ # rcov generated
4
+ coverage
5
+
6
+ # rdoc generated
7
+ rdoc
8
+
9
+ # yard generated
10
+ doc
11
+ .yardoc
12
+
13
+ # bundler
14
+ .bundle
15
+
16
+ # jeweler generated
17
+ pkg
18
+
19
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
20
+ #
21
+ # * Create a file at ~/.gitignore
22
+ # * Include files you want ignored
23
+ # * Run: git config --global core.excludesfile ~/.gitignore
24
+ #
25
+ # After doing this, these files will be ignored in all your git projects,
26
+ # saving you from having to 'pollute' every project you touch with them
27
+ #
28
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
29
+ #
30
+ # For MacOS:
31
+ #
32
+ .DS_Store
33
+ #
34
+ # For TextMate
35
+ #*.tmproj
36
+ #tmtags
37
+ #
38
+ # For emacs:
39
+ #*~
40
+ #\#*
41
+ #.\#*
42
+ #
43
+ # For vim:
44
+ *.swp
data/Gemfile CHANGED
@@ -1,15 +1,4 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
- # Add dependencies to develop your gem here.
6
- # Include everything needed to run rake, tests, features, etc.
7
- gem 'activesupport'
1
+ source 'https://rubygems.org'
8
2
 
9
- group :development do
10
- gem "shoulda", ">= 0"
11
- gem "bundler", "~> 1.0.0"
12
- gem "jeweler", "~> 1.5.2"
13
- gem "rcov", ">= 0"
14
- gem "rspec"
15
- end
3
+ # Specify your gem's dependencies in bit_mask.gemspec
4
+ gemspec
data/LICENSE.txt CHANGED
@@ -1,4 +1,6 @@
1
- Copyright (c) 2011 Ryan Ong
1
+ Copyright (c) 2012 Ryan Ong
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
@@ -18,3 +20,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
@@ -1,8 +1,8 @@
1
- = bit_mask
1
+ # BitMask
2
2
 
3
3
  A simple class that allows you to store data in a bit mask. It automagically manages bit sizes and base conversion of binary bitmask.
4
4
 
5
- == Usage
5
+ ## Usage
6
6
 
7
7
  When writing these config maps. Try to put the mose used options first so the string can be shorter.
8
8
 
@@ -14,12 +14,12 @@ When writing these config maps. Try to put the mose used options first so the st
14
14
  # Integer up to 62
15
15
  set_base 62
16
16
 
17
- field :air, :values => 2, # number of options must be 2 or greater
17
+ field :air, :values => 2 # number of options must be 2 or greater
18
18
  field :color, :values => ['blue','green','red'] # bit_mask can map arrays of data, the default setting will be the first value in the array
19
19
  field :body_style, :values => [:sedan,:mini_van,:suv] # Array values can be anything that can be found using the Array#index function
20
- field :transmission,:values => 6,
20
+ field :transmission,:values => 6
21
21
  field :min_price, :values => (50..100).to_a # ( just a way to store ranges of numbers)
22
- field :max_price, :values => (1..5).to_a.map {|n| 10000+(n*20)},
22
+ field :max_price, :values => (1..5).to_a.map {|n| 10000+(n*20)}
23
23
 
24
24
  # overwrite default accessors
25
25
 
@@ -57,32 +57,27 @@ When writing these config maps. Try to put the mose used options first so the st
57
57
  SearchParams.load(@search.to_s(36),36) # load from different base
58
58
  SearchParams.load(@search.to_s('asldkfjv'),'asldkfjv')
59
59
 
60
-
61
-
62
- == TODO
60
+ ## TODO
63
61
 
64
62
  * Impliment more tests
65
63
  * Storage of strings?
66
- * Allow for embeded bit_masks
67
64
  * create javascript version for easy communication between ruby and javascript
68
65
 
69
- == Contributing to bit_mask
66
+ ## Contributing
70
67
 
71
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
72
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
73
- * Fork the project
74
- * Start a feature/bugfix branch
75
- * Commit and push until you are happy with your contribution
76
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
77
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
78
73
 
79
- == Credits
74
+ ## Credits
80
75
 
81
76
  Ryan Ong - ryanong@gmail.com
82
77
 
83
78
  Developed for and with CarZen[link:http://carzen.com]
84
79
 
85
- == Copyright
80
+ ## Copyright
86
81
 
87
82
  Copyright (c) 2011 Ryan Ong. See LICENSE.txt for
88
83
  further details.
data/Rakefile CHANGED
@@ -1,49 +1 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "bit_mask"
16
- gem.homepage = "http://github.com/ryanong/bit_hash"
17
- gem.license = "MIT"
18
- gem.summary = %Q{bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.}
19
- gem.description = %Q{bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients}
20
- gem.email = "ryanong@gmail.com"
21
- gem.authors = ["Ryan Ong"]
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_development_dependency 'rspec', '> 1.2.3'
25
- end
26
- Jeweler::RubygemsDotOrgTasks.new
27
-
28
- require 'rspec/core'
29
- require 'rspec/core/rake_task'
30
- RSpec::Core::RakeTask.new(:spec) do |spec|
31
- spec.pattern = FileList['spec/**/*_spec.rb']
32
- end
33
-
34
- RSpec::Core::RakeTask.new(:rcov) do |spec|
35
- spec.pattern = 'spec/**/*_spec.rb'
36
- spec.rcov = true
37
- end
38
-
39
- task :default => :spec
40
-
41
- require 'rake/rdoctask'
42
- Rake::RDocTask.new do |rdoc|
43
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
-
45
- rdoc.rdoc_dir = 'rdoc'
46
- rdoc.title = "bit_mask #{version}"
47
- rdoc.rdoc_files.include('README*')
48
- rdoc.rdoc_files.include('lib/**/*.rb')
49
- end
1
+ require "bundler/gem_tasks"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.1.0
data/bit_mask.gemspec CHANGED
@@ -1,73 +1,24 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bit_mask/version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = %q{bit_mask}
8
- s.version = "0.0.2"
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "bit_mask"
8
+ gem.version = BitMask::VERSION
9
+ gem.authors = ["Ryan Ong"]
10
+ gem.email = ["ryanong@gmail.com"]
9
11
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{Ryan Ong}]
12
- s.date = %q{2011-07-21}
13
- s.description = %q{bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients}
14
- s.email = %q{ryanong@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".rspec",
22
- "Gemfile",
23
- "LICENSE.txt",
24
- "README.rdoc",
25
- "Rakefile",
26
- "VERSION",
27
- "bit_mask.gemspec",
28
- "lib/bit_mask.rb",
29
- "spec/bit_mask_spec.rb",
30
- "spec/models/car_search.rb",
31
- "spec/models/dealership_search.rb",
32
- "spec/spec_helper.rb"
33
- ]
34
- s.homepage = %q{http://github.com/ryanong/bit_hash}
35
- s.licenses = [%q{MIT}]
36
- s.require_paths = [%q{lib}]
37
- s.rubygems_version = %q{1.8.5}
38
- s.summary = %q{bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.}
39
- s.test_files = [
40
- "spec/bit_mask_spec.rb",
41
- "spec/models/car_search.rb",
42
- "spec/models/dealership_search.rb",
43
- "spec/spec_helper.rb"
44
- ]
12
+ gem.description = %q{bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients}
13
+ gem.summary = %q{bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.}
14
+ gem.homepage = %q{http://github.com/ryanong/bit_hash}
45
15
 
46
- if s.respond_to? :specification_version then
47
- s.specification_version = 3
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
48
20
 
49
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<activesupport>, [">= 0"])
51
- s.add_development_dependency(%q<shoulda>, [">= 0"])
52
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
53
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
54
- s.add_development_dependency(%q<rcov>, [">= 0"])
55
- s.add_development_dependency(%q<rspec>, [">= 0"])
56
- else
57
- s.add_dependency(%q<activesupport>, [">= 0"])
58
- s.add_dependency(%q<shoulda>, [">= 0"])
59
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
61
- s.add_dependency(%q<rcov>, [">= 0"])
62
- s.add_dependency(%q<rspec>, [">= 0"])
63
- end
64
- else
65
- s.add_dependency(%q<activesupport>, [">= 0"])
66
- s.add_dependency(%q<shoulda>, [">= 0"])
67
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
68
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
69
- s.add_dependency(%q<rcov>, [">= 0"])
70
- s.add_dependency(%q<rspec>, [">= 0"])
71
- end
21
+ gem.add_development_dependency "activesupport", ">= 0"
22
+ gem.add_development_dependency "rspec", ">= 0"
72
23
  end
73
24
 
@@ -0,0 +1,77 @@
1
+ class BitMask::Field
2
+ attr_reader :name
3
+ attr_reader :options
4
+
5
+ def initialize(name, opts)
6
+ @name = name
7
+ @options = opts
8
+ if !values.is_a?(Integer) && !values.is_a?(Array)
9
+ raise "#{values.class} is an invalid class for values."
10
+ end
11
+ end
12
+
13
+ def bits
14
+ @bits ||=
15
+ if options[:bits]
16
+ options[:bits]
17
+ elsif values.kind_of?(Integer) && values < 0
18
+ -1
19
+ else
20
+ if options[:limit]
21
+ max_number = options[:limit]
22
+ elsif values.is_a?(Integer)
23
+ max_number = values
24
+ elsif values.is_a?(Array)
25
+ max_number = values.size
26
+ end
27
+
28
+ max_number += 1 if null
29
+
30
+ Math.log2(max_number).ceil
31
+ end
32
+ end
33
+
34
+ def values
35
+ options[:values]
36
+ end
37
+
38
+ def null
39
+ options[:null]
40
+ end
41
+
42
+ def default
43
+ @default ||=
44
+ if null
45
+ nil
46
+ elsif values.kind_of? Integer
47
+ 0
48
+ elsif values.respond_to? :first
49
+ values.first
50
+ elsif values.respond_to? :defaults
51
+ values.defaults
52
+ end
53
+ end
54
+
55
+ def to_bin(value)
56
+ if self.null && value.nil?
57
+ value = 0
58
+ elsif self.values.respond_to? :index
59
+ value = self.values.index(value)
60
+ value += 1 if self.null
61
+ end
62
+ value = value.to_s(2)
63
+ value = value.rjust(self.bits,'0') if self.bits > 0
64
+ value
65
+ end
66
+
67
+ def from_i(value)
68
+ value -= 1 if self.null
69
+
70
+ if self.null && value == -1
71
+ value = nil
72
+ elsif self.values.respond_to?(:at)
73
+ value = self.values.at(value)
74
+ end
75
+ value
76
+ end
77
+ end
@@ -0,0 +1,44 @@
1
+ class BitMask
2
+ module Radix
3
+ class << self
4
+ def integer_to_string(integer, characters)
5
+ characters = process_characters(characters)
6
+ radix = characters.length
7
+
8
+ result = ''
9
+ while integer != 0
10
+ result += characters[integer%radix].chr
11
+ integer /= radix
12
+ end
13
+ result.reverse
14
+ end
15
+
16
+ def string_to_integer(string, characters)
17
+ characters = process_characters(characters)
18
+ radix = characters.length
19
+
20
+ int_val = 0
21
+ string.reverse.split('').each_with_index do |char,index|
22
+ if char_index = characters.index(char)
23
+ int_val += (char_index)*(radix**(index))
24
+ else
25
+ raise ArgumentError, "Character #{char} at index #{index} is not a valid character for Base #{characters} String."
26
+ end
27
+ end
28
+ int_val
29
+ end
30
+
31
+ private
32
+
33
+ def process_characters(characters)
34
+ if characters.is_a? String
35
+ characters = characters.split('')
36
+ end
37
+ if characters != characters.uniq
38
+ raise ArgumentError, "There are duplicate characters in #{characters}"
39
+ end
40
+ characters
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ class BitMask
2
+ VERSION = "0.2.0"
3
+ end
data/lib/bit_mask.rb CHANGED
@@ -1,44 +1,50 @@
1
1
  require 'active_support/core_ext/class/attribute'
2
+ require 'active_support/ordered_hash'
3
+
4
+ require "bit_mask/version"
5
+ require "bit_mask/field"
6
+ require "bit_mask/radix"
2
7
 
3
8
  class BitMask
4
9
  CHARACTER_SET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
5
- class_attribute :fields, :defaults, :base
10
+ class_attribute :fields, :base
11
+
6
12
  def self.inherited(sub)
7
- sub.fields = []
8
- sub.defaults = {}
13
+ sub.fields = ActiveSupport::OrderedHash.new
9
14
  sub.base = 62
10
15
  end
11
16
 
12
- def initialize(args = {})
13
- self.replace(self.defaults.merge(args))
17
+ def initialize(new_attributes = {})
18
+ @attributes = {}
19
+ self.assign_attributes(
20
+ self.class.defaults.merge(new_attributes)
21
+ )
14
22
  end
15
23
 
16
- def replace(args)
17
- args.each do |field,value|
18
- self[field]= value
24
+ def assign_attributes(new_attributes)
25
+ new_attributes.each do |field, value|
26
+ self.send("#{field}=",value)
19
27
  end
20
28
  end
21
29
 
22
- alias_method :attributes=, :replace
30
+ alias_method :attributes=, :assign_attributes
23
31
 
24
32
  def [](field)
25
- raise "#{field} is an invalid key" unless self.respond_to?(field)
26
- self.send(field)
33
+ self.read_attribute(field)
27
34
  end
28
35
 
29
36
  def []=(field,value)
30
- raise "#{field} is an invalid key" unless self.respond_to?("#{field}=")
31
- self.send("#{field}=",value)
37
+ self.write_attribute(field,value)
32
38
  end
33
39
 
34
40
  def read_attribute(key)
35
- self.instance_variable_get("@#{key}".to_sym)
41
+ @attributes[key]
36
42
  end
37
43
 
38
44
  def write_attribute(key,value)
39
- if field = self.fields.assoc(key)
40
- if self.class.check_value(field,value)
41
- self.instance_variable_set("@#{key}".to_sym,value)
45
+ if field = self.fields[key]
46
+ if self.class.check_and_cast_value(field,value)
47
+ @attributes[field.name] = value
42
48
  else
43
49
  raise "Invalid input for #{key}: #{value} field: #{field}"
44
50
  end
@@ -48,17 +54,9 @@ class BitMask
48
54
  end
49
55
 
50
56
  def to_bin
51
- self.fields.reverse.map do |field,conf|
52
- val = self.read_attribute(field)
53
- if conf[:nil] && val.nil?
54
- val = 0
55
- elsif conf[:values].respond_to? :index
56
- val = conf[:values].index(val)
57
- val += 1 if conf[:nil]
58
- end
59
- val = val.to_i.to_s(2)
60
- val = val.rjust(conf[:bits],'0') if conf[:bits] > 0
61
- val
57
+ self.fields.values.reverse.map do |field|
58
+ val = self.read_attribute(field.name)
59
+ field.to_bin(val)
62
60
  end.join('').sub(/\A0+/,'')
63
61
  end
64
62
 
@@ -68,23 +66,8 @@ class BitMask
68
66
  end
69
67
 
70
68
  def to_s(radix=nil)
71
- radix ||= self.base
72
- characters = CHARACTER_SET
73
-
74
- if radix.kind_of? String
75
- characters = radix.dup
76
- radix = radix.size
77
- elsif !radix.kind_of?(Integer) || radix < 0 || radix > 64
78
- raise '#{radix} is and invalid base to convert to. It must be a string or between 0 and 64'
79
- end
80
-
81
- dec = self.to_i
82
- result = ''
83
- while dec != 0
84
- result += characters[dec%radix].chr
85
- dec /= radix
86
- end
87
- result.reverse
69
+ characters = self.class.get_characters(radix)
70
+ Radix.integer_to_string(self.to_i, characters)
88
71
  end
89
72
 
90
73
  def keys
@@ -108,29 +91,17 @@ class BitMask
108
91
  self.attributes.inspect
109
92
  end
110
93
 
94
+ private
95
+
111
96
  class << self
112
97
 
113
98
  def keys
114
- self.fields.map {|f| f[0]}
99
+ self.fields.keys
115
100
  end
116
101
 
117
102
  def from_s(string,radix = nil)
118
- radix ||= self.base
119
- if radix.kind_of? String
120
- char_ref = radix
121
- radix = radix.size
122
- elsif !radix.kind_of?(Integer) || radix < 0 || radix > 64
123
- raise '#{radix} is and invalid base to convert to. It must be a string or between 0 and 64'
124
- else
125
- char_ref = CHARACTER_SET[0..radix]
126
- end
127
-
128
- int_val = 0
129
- string.reverse.split('').each_with_index do |char,index|
130
- raise ArgumentError, "Character #{char} at index #{index} is not a valid character for to_insane Base #{radix} String." unless char_index = char_ref.index(char)
131
- int_val += (char_index)*(radix**(index))
132
- end
133
- self.from_i(int_val)
103
+ characters = self.get_characters(radix)
104
+ self.from_i(Radix.string_to_integer(string, characters))
134
105
  end
135
106
 
136
107
  alias_method :load, :from_s
@@ -141,109 +112,65 @@ class BitMask
141
112
 
142
113
  def from_bin(binary_string)
143
114
  binary_array = binary_string.split('')
144
- bit_hash = self.new
145
- self.fields.each do |field,conf|
146
- value = (conf[:bits] == -1) ? binary_array : binary_array.pop(conf[:bits])
115
+ bit_mask = self.new
116
+ self.fields.values.each do |field|
117
+ value = (field.bits == -1) ? binary_array : binary_array.pop(field.bits)
147
118
  break if value.nil?
148
- value = value.join('').to_i(2)
149
- value -= 1 if conf[:nil]
150
-
151
- if conf[:nil] && value == -1
152
- value = nil
153
- elsif conf[:values].respond_to?(:at)
154
- value = conf[:values].at(value)
155
- elsif conf[:values].respond_to?(:from_i)
156
- value = conf[:values].from_i(value)
157
- end
158
- bit_hash.write_attribute(field,value)
159
- end
160
- bit_hash
161
- end
162
-
163
- def set_base(base)
164
- if base.kind_of? Integer && base <= 36
165
- self.base = base
166
- end
167
- end
168
-
169
- def bit_length
170
- bits = 0
171
- self.fields.each do |field,opts|
172
- bits += opts[:bits]
119
+ value = value.join.to_i(2)
120
+ value = field.from_i(value)
121
+ bit_mask.write_attribute(field.name,value)
173
122
  end
174
- bits
123
+ bit_mask
175
124
  end
176
125
 
177
126
  def field(name,opts)
178
127
  name = name.to_sym
179
- unless opts[:bits]
180
- unless opts[:limit]
181
- if opts[:characters]
182
- opts[:limit] = opts[:characters].to_i*self.base
183
- elsif opts[:values].respond_to? :bit_length
184
- opts[:bits] = opts[:values].bit_length
185
- elsif opts[:values].kind_of? Integer
186
- if opts[:values] == -1
187
- opts[:bits] = -1
188
- else
189
- opts[:limit] = opts[:values]
190
- opts[:limit] += 1 if opts[:nil]
191
- end
192
- else
193
- opts[:limit] = opts[:values].size
194
- opts[:limit] += 1 if opts[:nil]
195
- end
196
- end
197
- opts[:bits] ||= (opts[:limit].to_i-1).to_s(2).length
198
- end
199
- raise "value cannot be negative" if opts[:values].class == Integer && opts[:values] < 0
200
- options = {:values => opts[:values], :bits => opts[:bits].to_i, :nil => opts[:nil]}
201
- if index = self.fields.index{|f| f[0] == name}
202
- self.fields[index][1] = options
203
- else
204
- self.fields << [name, options]
205
- end
206
- self.defaults[name]=get_default(options)
207
-
208
- define_method name do
209
- self.read_attribute(name)
210
- end
128
+ self.fields[name] = Field.new(name,opts)
211
129
 
212
- define_method "#{name}=" do |*args|
213
- self.write_attribute(name,*args)
214
- end
130
+ include(Module.new do
131
+ define_method(name) do
132
+ read_attribute(name)
133
+ end
215
134
 
135
+ define_method("#{name}=") do |*args|
136
+ write_attribute(name,*args)
137
+ end
138
+ end)
216
139
  end
217
140
 
218
- def get_default(opts)
219
- return nil if opts[:nil]
220
- values = opts[:values]
221
- if values.kind_of? Integer
222
- 0
223
- elsif values.respond_to? :first
224
- values.first
225
- elsif values.respond_to? :defaults
226
- values.defaults
141
+ def defaults
142
+ fields_array = fields.values.map do |field|
143
+ [field.name, field.default]
227
144
  end
145
+ Hash[fields_array]
228
146
  end
229
147
 
230
- def check_value(key,value)
231
- field = (key.class == Array) ? key : self.fields.assoc(key)
232
-
233
- if opts = field[1]
234
- return true if opts[:nil] && value.nil?
235
- if values = opts[:values]
148
+ def check_and_cast_value(key,value)
149
+ if field = (key.is_a? Field) ? key : self.fields[key]
150
+ return true if field.null && value.nil?
151
+ if values = field.values
236
152
  if values.kind_of? Integer
237
- return false if value < 0
238
- return values == -1 || value <= values
239
- elsif values.kind_of? BitMask
240
- return value.kind_of? BitMask && value.fields.hash == value.fields.hash
153
+ value = value.to_i
154
+ return nil if value < 0
155
+ return value if (values == -1 || value <= values)
241
156
  else
242
- return values.include?(value)
157
+ return value if values.include?(value)
243
158
  end
244
159
  end
245
160
  end
246
- false
161
+ nil
162
+ end
163
+
164
+ def get_characters(radix = nil)
165
+ radix ||= self.base
166
+
167
+ if radix.kind_of?(String)
168
+ radix
169
+ elsif radix.kind_of?(Integer) && radix > 1 && radix <= CHARACTER_SET.length
170
+ CHARACTER_SET[0..radix-1]
171
+ else
172
+ raise "#{radix} is and invali base to convert to. It must be a string or between 2 and #{CHARACTER_SET.length}"
173
+ end
247
174
  end
248
175
  end
249
176
  end
@@ -3,15 +3,15 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
  describe BitMask do
4
4
 
5
5
  it "should have values set at 2" do
6
- CarSearch.fields.assoc(:segment_1)[1][:values].should == 2
6
+ CarSearch.fields[:segment_1].values.should == 2
7
7
  end
8
8
 
9
9
  it "should have bits set to 1" do
10
- CarSearch.fields.assoc(:segment_1)[1][:bits].should == 1
10
+ CarSearch.fields[(:segment_1)].bits.should == 1
11
11
  end
12
12
 
13
13
  it "should have bits set to 4" do
14
- CarSearch.fields.assoc(:min_price_cents)[1][:bits].should == 4
14
+ CarSearch.fields[(:min_price_cents)].bits.should == 4
15
15
  end
16
16
 
17
17
  it "should raise an error if config lacks name" do
@@ -45,7 +45,7 @@ describe BitMask do
45
45
 
46
46
  it "should replace setting" do
47
47
  config = CarSearch.new
48
- config.replace({:air=>1})
48
+ config.assign_attributes({:air=>1})
49
49
  config[:air].should eql(1)
50
50
  end
51
51
 
@@ -1,5 +1,5 @@
1
1
  class DealershipSearch < BitMask
2
- field :makes, :values => ['honda','toyota','ford'], :nil => true
3
- field :zip, :values => 99999, :nil => true
2
+ field :makes, :values => ['honda','toyota','ford'], :null => true
3
+ field :zip, :values => 99999, :null => true
4
4
  field :distance, :values => -1
5
5
  end
metadata CHANGED
@@ -1,137 +1,100 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: bit_mask
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
4
5
  prerelease:
5
- version: 0.0.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Ryan Ong
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-07-21 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2012-12-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: activesupport
17
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
- requirements:
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: "0"
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: shoulda
28
- requirement: &id002 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: "0"
34
- type: :development
35
- prerelease: false
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: bundler
39
- requirement: &id003 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
42
- - - ~>
43
- - !ruby/object:Gem::Version
44
- version: 1.0.0
45
- type: :development
46
- prerelease: false
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: jeweler
50
- requirement: &id004 !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ~>
54
- - !ruby/object:Gem::Version
55
- version: 1.5.2
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
56
22
  type: :development
57
23
  prerelease: false
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
60
- name: rcov
61
- requirement: &id005 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
62
25
  none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- version: "0"
67
- type: :development
68
- prerelease: false
69
- version_requirements: *id005
70
- - !ruby/object:Gem::Dependency
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
71
31
  name: rspec
72
- requirement: &id006 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
73
33
  none: false
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: "0"
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
78
38
  type: :development
79
39
  prerelease: false
80
- version_requirements: *id006
81
- description: bit_mask creates a simple api to create bit mask models. By bit masking dataing you can compress the amount of data that needs to be sent between servers and clients
82
- email: ryanong@gmail.com
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: bit_mask creates a simple api to create bit mask models. By bit masking
47
+ dataing you can compress the amount of data that needs to be sent between servers
48
+ and clients
49
+ email:
50
+ - ryanong@gmail.com
83
51
  executables: []
84
-
85
52
  extensions: []
86
-
87
- extra_rdoc_files:
88
- - LICENSE.txt
89
- - README.rdoc
90
- files:
53
+ extra_rdoc_files: []
54
+ files:
91
55
  - .document
56
+ - .gitignore
92
57
  - .rspec
93
58
  - Gemfile
94
59
  - LICENSE.txt
95
- - README.rdoc
60
+ - README.md
96
61
  - Rakefile
97
62
  - VERSION
98
63
  - bit_mask.gemspec
99
64
  - lib/bit_mask.rb
65
+ - lib/bit_mask/field.rb
66
+ - lib/bit_mask/radix.rb
67
+ - lib/bit_mask/version.rb
100
68
  - spec/bit_mask_spec.rb
101
69
  - spec/models/car_search.rb
102
70
  - spec/models/dealership_search.rb
103
71
  - spec/spec_helper.rb
104
72
  homepage: http://github.com/ryanong/bit_hash
105
- licenses:
106
- - MIT
73
+ licenses: []
107
74
  post_install_message:
108
75
  rdoc_options: []
109
-
110
- require_paths:
76
+ require_paths:
111
77
  - lib
112
- required_ruby_version: !ruby/object:Gem::Requirement
78
+ required_ruby_version: !ruby/object:Gem::Requirement
113
79
  none: false
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- hash: 4147955215867335187
118
- segments:
119
- - 0
120
- version: "0"
121
- required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
85
  none: false
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- version: "0"
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
127
90
  requirements: []
128
-
129
91
  rubyforge_project:
130
- rubygems_version: 1.8.5
92
+ rubygems_version: 1.8.23
131
93
  signing_key:
132
94
  specification_version: 3
133
- summary: bit_mask allows you to serialize/bitmask simple data sets into short compact ascii strings.
134
- test_files:
95
+ summary: bit_mask allows you to serialize/bitmask simple data sets into short compact
96
+ ascii strings.
97
+ test_files:
135
98
  - spec/bit_mask_spec.rb
136
99
  - spec/models/car_search.rb
137
100
  - spec/models/dealership_search.rb