active_model_serializers_binary 0.0.10 → 0.0.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6b15a22af56d99e5309303d942972061b28f5f7
4
- data.tar.gz: 34fe1c2c45fec1ab4e4d02bba3c4a7a3fb3d9ed4
3
+ metadata.gz: 2f3830d0d3a2a18ae95bb47c427e1af2ea6d2d86
4
+ data.tar.gz: 546aff445bb2ec63c9734955c762f3a87029b4b3
5
5
  SHA512:
6
- metadata.gz: ba001a7dc0310b82190fcb392dfe2d8748139bc5753705e1f136fb1eeec5c1ba8a96b3bf70ea776bfdb623025f9a14c71641a25b7957618d1c3200f285bfe0b3
7
- data.tar.gz: 0ca34aff960f7de5470af3c63bd1ac0a98af8b0e141c33bcb8764421f9e182094e580efc3e83644b51eac749c7dd4980d5fbc04f189abafc7ea13b511a17a68f
6
+ metadata.gz: 92274b86db2b91c5085e29e659279428d0221b1bd3bcfd4c9f650de4d32db55800887e22919261fea282960ac87efed344844da28a3955386848ece83e2c4509
7
+ data.tar.gz: 272721accba6bd385c4b1c967afd42af2a155e132c4c807d69752bb4673e05cbb6d72da8f64cf0f3767cbbfc0e5ea9797c12db564d655fed3d29436b944976de
data/.gitignore CHANGED
@@ -6,3 +6,4 @@ test/dummy/db/*.sqlite3-journal
6
6
  test/dummy/log/*.log
7
7
  test/dummy/tmp/
8
8
  test/dummy/.sass-cache
9
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_model_serializers_binary (0.0.9)
4
+ active_model_serializers_binary (0.0.12)
5
5
  activemodel (~> 4.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # README #
1
+ # Active model serializers binary #
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/active_model_serializers_binary.svg)](https://badge.fury.io/rb/active_model_serializers_binary)
2
4
 
3
5
  Serializador/Deserializador de bytes en Ruby
4
6
 
@@ -15,11 +15,59 @@ module ActiveModel
15
15
 
16
16
  class_attribute :attr_config
17
17
  self.attr_config = {}
18
+
19
+ def initialize
20
+ super
21
+ self.attr_config.each do |key, options|
22
+ options[:parent] = self
23
+ end
24
+ end
18
25
  end
19
26
 
20
27
  module ClassMethods
21
- def serialize_options(attr_name, coder, count=1, length=1)
22
- self.attr_config.merge!(attr_name.to_s => {:coder => coder, :count => count, :length => length})
28
+ # todo: agrupar parametros en hash (rompe la compatibilidad hacia atras)
29
+ def serialize_options(attr_name, coder, count=1, length=1, &block )
30
+ self.attr_config.merge!(attr_name.to_s => {:coder => coder, :count => count, :length => length, :block => block, :name => attr_name})
31
+ end
32
+
33
+ def int8( attr_name, options = {}, &block )
34
+ serialize_options attr_name, DataTypes::Int8, options[:count], options[:length], &block
35
+ end
36
+
37
+ def int16( attr_name, options = {}, &block )
38
+ serialize_options attr_name, DataTypes::Int16, options[:count], options[:length], &block
39
+ end
40
+
41
+ def int32( attr_name, options = {}, &block )
42
+ serialize_options attr_name, DataTypes::Int32, options[:count], options[:length], &block
43
+ end
44
+
45
+ def uint8( attr_name, options = {}, &block )
46
+ serialize_options attr_name, DataTypes::UInt8, options[:count], options[:length], &block
47
+ end
48
+
49
+ def uint16( attr_name, options = {}, &block )
50
+ serialize_options attr_name, DataTypes::UInt16, options[:count], options[:length], &block
51
+ end
52
+
53
+ def uint32( attr_name, options = {}, &block )
54
+ serialize_options attr_name, DataTypes::UInt32, options[:count], options[:length], &block
55
+ end
56
+
57
+ def bitfield( attr_name, options = {}, &block )
58
+ serialize_options attr_name, DataTypes::BitField, options[:count], options[:length], &block
59
+ end
60
+
61
+ def float32( attr_name, options = {}, &block )
62
+ serialize_options attr_name, DataTypes::Float32, options[:count], options[:length], &block
63
+ end
64
+
65
+ def char( attr_name, options = {}, &block )
66
+ serialize_options attr_name, DataTypes::Char, options[:count], options[:length], &block
67
+ end
68
+
69
+ def bool( attr_name, options = {}, &block )
70
+ serialize_options attr_name, DataTypes::Bool, options[:count], options[:length], &block
23
71
  end
24
72
  end
25
73
 
@@ -39,8 +87,8 @@ module ActiveModel
39
87
  tmp_buffer = [] # Buffer temporal en bytes
40
88
  current_address = start_address*2 + 0.0 # Dirección en bytes
41
89
 
42
- @serializable.attr_config.each do |key, value|
43
- var = value[:coder].new(value[:count], value[:length])
90
+ @serializable.attr_config.each do |key, options|
91
+ var = options[:coder].new(options)
44
92
  # Busca el valor del atributo y si no existe devuelve nil
45
93
  var.value = serializable_values[key] rescue nil
46
94
 
@@ -50,20 +98,28 @@ module ActiveModel
50
98
  tmp_buffer = var.dump
51
99
 
52
100
  if @options[:align]
53
- # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
54
- if var.bit_length > 8 and current_address.modulo(2) != 0
55
- byte += 1
56
- bit = 0
57
- end
58
- # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
59
- if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
60
- byte += 4-byte%4
61
- bit = 0
101
+ if !var.type.in? [:bitfield, :bool]
102
+ # Se posiciona al principio de un byte
103
+ if bit != 0
104
+ byte += 1
105
+ bit = 0
106
+ current_address = (byte+bit/8.0)
107
+ end
108
+ # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
109
+ if var.bit_length > 8 and current_address.modulo(2) != 0
110
+ byte += 1
111
+ bit = 0
112
+ end
113
+ # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
114
+ if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
115
+ byte += 4-byte%4
116
+ bit = 0
117
+ end
62
118
  end
63
119
  end
64
120
 
65
121
  # Si los datos ocupan mas de un byte concatena los arrays
66
- if var.bit_length >= 8 and @options[:align]
122
+ if !var.type.in? [:bitfield, :bool] and @options[:align]
67
123
  buffer.insert(byte, tmp_buffer).flatten!
68
124
  else # En caso de ser bits
69
125
  tmp_buffer.flatten!
@@ -90,23 +146,31 @@ module ActiveModel
90
146
 
91
147
  current_address = start_address*2 + 0.0 # Dirección en bytes
92
148
 
93
- @serializable.attr_config.each do |key, value|
94
- #puts "#{key} - #{value}"
149
+ @serializable.attr_config.each do |key, options|
150
+ #puts "#{key} - #{options}"
95
151
  byte = current_address.floor
96
152
  bit = (current_address.modulo(1)*8).round
97
153
 
98
- var = value[:coder].new(value[:count], value[:length]) #creo objeto del tipo de dato pasado
154
+ var = options[:coder].new(options) #creo objeto del tipo de dato pasado
99
155
 
100
156
  if @options[:align]
101
- # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
102
- if var.bit_length > 8 and current_address.modulo(2) != 0
103
- byte += 1
104
- bit = 0
105
- end
106
- # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
107
- if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
108
- byte += 4-byte%4
109
- bit = 0
157
+ if !var.type.in? [:bitfield, :bool]
158
+ # Se posiciona al principio de un byte
159
+ if bit != 0
160
+ byte += 1
161
+ bit = 0
162
+ current_address = (byte+bit/8.0)
163
+ end
164
+ # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
165
+ if var.bit_length > 8 and current_address.modulo(2) != 0
166
+ byte += 1
167
+ bit = 0
168
+ end
169
+ # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
170
+ if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
171
+ byte += 4-byte%4
172
+ bit = 0
173
+ end
110
174
  end
111
175
  end
112
176
 
@@ -114,7 +178,7 @@ module ActiveModel
114
178
  if var.bit_length >= 8 and @options[:align]
115
179
  result_deserialized=var.load(buffer.slice(byte, var.size))
116
180
  else # En caso de ser bits
117
- tmp_buffer = buffer.slice(byte, var.size.ceil)
181
+ tmp_buffer = buffer.slice(byte, (var.size+bit/8.0).ceil)
118
182
  result_deserialized=var.load([tmp_buffer.pack('C*').unpack('b*').first.slice(bit,var.size*8)].pack('b*').unpack('C*'))
119
183
  end
120
184
  # puts result_deserialized.inspect
@@ -138,47 +202,29 @@ module ActiveModel
138
202
 
139
203
  end #close class serializer
140
204
 
141
- # Returns XML representing the model. Configuration can be
205
+ # Returns a binary array representing the model. Configuration can be
142
206
  # passed through +options+.
143
207
  #
144
- # Without any +options+, the returned XML string will include all the
145
- # model's attributes.
146
- #
147
- # user = User.find(1)
148
- # user.to_xml
208
+ # person = Person.find(1)
209
+ # person.to_bytes
149
210
  #
150
- # <?xml version="1.0" encoding="UTF-8"?>
151
- # <user>
152
- # <id type="integer">1</id>
153
- # <name>David</name>
154
- # <age type="integer">16</age>
155
- # <created-at type="dateTime">2011-01-30T22:29:23Z</created-at>
156
- # </user>
211
+ # => [98, 111, 98, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1]
157
212
  #
158
- # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
159
- # attributes included, and work similar to the +attributes+ method.
160
- #
161
- # To include the result of some method calls on the model use <tt>:methods</tt>.
162
- #
163
- # To include associations use <tt>:include</tt>.
164
- #
165
- # For further documentation, see <tt>ActiveRecord::Serialization#to_xml</tt>
166
213
  def to_bytes(options = {}, &block)
167
214
  default_options = {
168
215
  :align => true,
169
- :block => block
170
216
  }
171
217
  options = default_options.deep_merge(options)
172
- if !options[:block].blank?
173
- instance_exec(self, &options[:block])
218
+ if block_given?
219
+ yield self
174
220
  end
175
221
  Serializer.new(self, options).dump
176
222
  end
177
223
 
178
- # Sets the model +attributes+ from an XML string. Returns +self+.
224
+ # Sets the model +attributes+ from an Binary string. Returns +self+.
179
225
  #
180
226
  # class Person
181
- # include ActiveModel::Serializers::Xml
227
+ # include ActiveModel::Serializers::Binary
182
228
  #
183
229
  # attr_accessor :name, :age, :awesome
184
230
  #
@@ -191,24 +237,35 @@ module ActiveModel
191
237
  # def attributes
192
238
  # instance_values
193
239
  # end
240
+ #
241
+ # char :name, count: 1, length: 10
242
+ # int16 :age
243
+ # bool :awesome
194
244
  # end
195
245
  #
196
- # xml = { name: 'bob', age: 22, awesome:true }.to_xml
246
+ # bytes = [98, 111, 98, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1]
197
247
  # person = Person.new
198
- # person.from_xml(xml) # => #<Person:0x007fec5e3b3c40 @age=22, @awesome=true, @name="bob">
199
- # person.name # => "bob"
200
- # person.age # => 22
201
- # person.awesome # => true
248
+ # person.from_bytes(bytes) do |p|
249
+ # p.name.upcase!
250
+ # end
251
+ # => #<Person:0x007fec5e3b3c40 @age=22, @awesome=true, @name="bob">
252
+ #
253
+ # @param [Array] buffer byte array with model data to deserialize
254
+ # @param [Hash] options deserealization options
255
+ #
256
+ # @return [Object] Deserialized object
257
+ #
258
+ # @yield code block to execute after deserialization
259
+ #
202
260
  def from_bytes(buffer, options = {}, &block)
203
261
  default_options = {
204
- :align => true,
205
- :block => block
262
+ :align => true
206
263
  }
207
264
  options = default_options.deep_merge(options)
208
265
  retVal = Serializer.new(self, options).load buffer
209
266
 
210
- if !options[:block].blank?
211
- instance_exec(self, &options[:block])
267
+ if block_given?
268
+ yield self
212
269
  end
213
270
  retVal
214
271
  end
@@ -0,0 +1,136 @@
1
+ module DataTypes
2
+
3
+ class Type
4
+
5
+ attr_accessor :raw_value, :bit_length, :type, :sign, :count, :length, :value, :name, :parent
6
+
7
+ def initialize(options = {})
8
+ @default_value = options[:default_value] || 0
9
+ @raw_value = nil
10
+ @bit_length = options[:bit_length] # Cantidad de bits del tipo de dato
11
+ @type = type
12
+ @sign = options[:sign] # :signed / :unsigned
13
+ @count = options[:count] || 1 # Cantidad de elementos del array
14
+ @length = options[:length] || 1 # En char y bitfield especifica la longitud del campo. Ignorado para el resto de los tipos
15
+ @value = check_value( @default_value )
16
+ @block = options[:block]
17
+ @name = options[:name]
18
+ @parent = options[:parent]
19
+ end
20
+
21
+ def to_s
22
+ @value.to_s
23
+ end
24
+
25
+ def type
26
+ self.class.to_s.split('::').last.downcase.to_sym
27
+ end
28
+
29
+ # Return size of object in bytes
30
+ def size
31
+ ((@bit_length*@length*@count)/8.0).ceil
32
+ end
33
+
34
+ def check( value, options = {} )
35
+ type = options[:type]
36
+ count = options[:count]
37
+ length = options[:length]
38
+ bit_length = options[:bit_length]
39
+ sign = options[:sign]
40
+ default_value = options[:default_value]
41
+
42
+ value = Array(value) # Se asegura de que sea un array
43
+ value = value[0...count] # Corta el array según la cantidad de elementos especificados en la declaración
44
+ # Lo convierte al tipo especificado
45
+ value.map! do |v|
46
+ if v.nil?
47
+ default_value
48
+ else
49
+ case type
50
+ when :float32
51
+ v.to_f
52
+ when :char
53
+ v.to_s[0...length]
54
+ when :bool
55
+ (v.in? [0, false]) ? false : true
56
+ else
57
+ v.to_i
58
+ end
59
+ end
60
+ end
61
+
62
+ trim(value, bit_length, sign) # Se asegura de que los valores esten dentro de los rangos permitidos pra el tipo de dato declarado
63
+ value.fill(default_value, value.length...count) # Completa los elementos faltantes del array con default_value
64
+ end
65
+
66
+ def check_value(value)
67
+ check(value, {
68
+ :type => @type,
69
+ :count => @count,
70
+ :length => @length,
71
+ :bit_length => @bit_length,
72
+ :sign => @sign,
73
+ :default_value => @default_value,
74
+ })
75
+ end
76
+
77
+ # Los datos siempre vienen en bytes
78
+ def check_raw_value(value)
79
+ check(value, {
80
+ :type => :uint8,
81
+ :count => size,
82
+ :length => 1,
83
+ :bit_length => 8,
84
+ :sign => :unsigned,
85
+ :default_value => 0,
86
+ })
87
+ end
88
+
89
+ def trim(value, bit_length, sign)
90
+ # Recorta los valores según el bit_length
91
+ value.map! do |v|
92
+ if sign == :signed
93
+ [-2**(bit_length-1),[v.to_i,2**(bit_length-1)-1].min].max
94
+ elsif sign == :unsigned
95
+ [0,[v.to_i,2**(bit_length)-1].min].max
96
+ else
97
+ v
98
+ end
99
+ end
100
+ end
101
+
102
+ def value=(value)
103
+ @value = check_value(value)
104
+ end
105
+
106
+
107
+ #
108
+ # Se ejecuta antes de serializar los datos
109
+ #
110
+ # @param [Object] value valor del objeto a serializar original
111
+ #
112
+ # @return [Array] nuevo valor del objeto a serializar
113
+ #
114
+ def before_dump(value)
115
+ self.value = value if !value.nil?
116
+ if !@block.nil?
117
+ value = @parent.instance_exec( self, :dump, &@block )
118
+ self.value = value if !value.nil?
119
+ end
120
+ end
121
+
122
+ #
123
+ # Se ejecuta después de deserializar los datos. @value contiene los datos deserializados
124
+ #
125
+ #
126
+ # @return [Array] Array con los datos deserializados
127
+ #
128
+ def after_load
129
+ if !@block.nil?
130
+ value = @parent.instance_exec( self, :load, &@block )
131
+ self.value = value if !value.nil?
132
+ end
133
+ @value
134
+ end
135
+ end
136
+ end
@@ -1,218 +1,187 @@
1
+ require_relative 'base_type.rb'
2
+
1
3
  module DataTypes
2
- class Type
3
- attr_accessor :value, :bit_length
4
4
 
5
- def initialize(bit_length=nil, sign=nil, count=1, length=1)
6
- @bit_length = bit_length
7
- @sign = sign
8
- @count = count
9
- @length = length
10
- @default_value = 0
5
+ class Int8 < Type
6
+ def initialize(options = {})
7
+ super options.merge :bit_length => 8, :sign => :signed
11
8
  end
12
9
 
13
- def to_s
14
- @value.to_s
10
+ def dump(value=nil)
11
+ before_dump( value )
12
+ @raw_value = @value
15
13
  end
16
14
 
17
- # Return size of object in bytes
18
- def size
19
- (@bit_length*@length*@count)/8.0
15
+ def load(raw_value)
16
+ self.value = check_raw_value(raw_value)
17
+ after_load
20
18
  end
19
+ end
21
20
 
22
- def check_value(value)
23
- if value.nil?
24
- value=@value
25
- else
26
- value=(value.is_a? Array) ? value : [value]
27
- end
28
-
29
- value.map!{|v| v.nil? ? @default_value : v}
30
- value.map! do |v|
31
- case @default_value.class.name
32
- when "Float"
33
- v.to_f
34
- when "String"
35
- v.to_s[0...@length]
36
- else
37
- v.to_i
38
- end
39
- end
40
-
41
- value=value[0...@count]
42
- value.fill(@default_value, value.length...@count)
21
+ class Int16 < Type
22
+ def initialize(options = {})
23
+ super options.merge :bit_length => 16, :sign => :signed
43
24
  end
44
25
 
45
- def value=(value)
46
- value = check_value(value)
26
+ def dump(value=nil)
27
+ before_dump( value )
28
+ @raw_value = @value.pack('v*').unpack('C*')
29
+ end
47
30
 
48
- # Recorta los valores según el bit_length
49
- value.map! do |v|
50
- (@sign == :signed)?[-2**(@bit_length-1),[v.to_i,2**(@bit_length-1)-1].min].max :
51
- ((@sign == :unsigned)? [0,[v.to_i,2**(@bit_length)-1].min].max : v )
52
- end
53
- @value=value
31
+ def load(raw_value)
32
+ self.value = check_raw_value(raw_value).pack('C*').unpack('v*')
33
+ after_load
54
34
  end
55
35
  end
56
36
 
57
- class Int8 < Type
58
- def initialize(count=1, length=1)
59
- super 8, :signed, count
60
- self.value = @default_value
37
+ class Int32 < Type
38
+ def initialize(options = {})
39
+ super options.merge :bit_length => 32, :sign => :signed
61
40
  end
62
41
 
63
42
  def dump(value=nil)
64
- self.value = value if !value.nil?
65
- @value
43
+ before_dump( value )
44
+ @raw_value = @value.pack('V*').unpack('C*')
66
45
  end
67
46
 
68
- def load(value)
69
- self.value = value if !value.nil?
70
- @value
47
+ def load(raw_value)
48
+ self.value = check_raw_value(raw_value).pack('C*').unpack('V*') if !value.nil?
49
+ after_load
71
50
  end
72
51
  end
73
52
 
74
- class Int16 < Type
75
- def initialize(count=1, length=1)
76
- super 16, :signed, count
77
- self.value = @default_value
53
+ class UInt16 < Type
54
+ def initialize(options = {})
55
+ super options.merge :bit_length => 16, :sign => :unsigned
78
56
  end
79
57
 
80
58
  def dump(value=nil)
81
- self.value = value if !value.nil?
82
- @value.pack('v*').unpack('C*')
59
+ before_dump( value )
60
+ @raw_value = @value.pack('v*').unpack('C*')
83
61
  end
84
62
 
85
- def load(value)
86
- self.value = value.pack('C*').unpack('v*') if !value.nil?
87
- @value
63
+ def load(raw_value)
64
+ @raw_value = check_raw_value(raw_value)
65
+ self.value = @raw_value.pack('C*').unpack('v*')
66
+ after_load
88
67
  end
89
68
  end
90
69
 
91
- class Int32 < Type
92
- def initialize(count=1, length=1)
93
- super 32, :signed, count
94
- self.value = @default_value
70
+ class UInt32 < Type
71
+ def initialize(options = {})
72
+ super options.merge :bit_length => 32, :sign => :unsigned
95
73
  end
96
74
 
97
75
  def dump(value=nil)
98
- self.value = value if !value.nil?
99
- @value.pack('V*').unpack('C*')
76
+ before_dump( value )
77
+ @raw_value = @value.pack('l*').unpack('C*')
100
78
  end
101
79
 
102
- def load(value)
103
- self.value = value.pack('C*').unpack('V*') if !value.nil?
104
- @value
80
+ def load(raw_value)
81
+ self.value = check_raw_value(raw_value).pack('C*').unpack('l*') if !value.nil?
82
+ after_load
105
83
  end
106
84
  end
107
85
 
108
- class UInt16 < Type
109
- def initialize(count=1, length=1)
110
- super 16, :unsigned, count
111
- self.value = @default_value
86
+ class UInt8 < Type
87
+ def initialize(options = {})
88
+ super options.merge :bit_length => 8, :sign => :unsigned
112
89
  end
113
90
 
114
91
  def dump(value=nil)
115
- self.value = value if !value.nil?
116
- @value.pack('v*').unpack('C*')
92
+ before_dump( value )
93
+ @raw_value = @value
117
94
  end
118
95
 
119
- def load(value)
120
- self.value = value.pack('C*').unpack('v*') if !value.nil?
121
- @value
96
+ def load(raw_value)
97
+ self.value = check_raw_value(raw_value)
98
+ after_load
122
99
  end
123
100
  end
124
101
 
125
- class UInt32 < Type
126
- def initialize(count=1, length=1)
127
- super 32, :unsigned, count
128
- self.value = @default_value
102
+ class BitField < Type
103
+ def initialize(options = {})
104
+ length = 32 if length > 32
105
+ super options.merge :bit_length => length, :sign => :unsigned
129
106
  end
130
107
 
131
- def dump(value=nil)
132
- self.value = value if !value.nil?
133
- @value.pack('l*').unpack('C*')
134
- end
135
-
136
- def load(value)
137
- self.value = value.pack('C*').unpack('l*') if !value.nil?
138
- @value
108
+ def format
109
+ if bit_length <= 8 # 8 bits
110
+ 'C*'
111
+ elsif bit_length <= 16 # 16 bits
112
+ 'v*'
113
+ else # 32 bits
114
+ 'l*'
115
+ end
139
116
  end
140
- end
141
117
 
142
- class UInt8 < Type
143
- def initialize(count=1, length=1)
144
- super 8, :unsigned, count
145
- self.value = @default_value
118
+ def word_length
119
+ if bit_length <= 8 # 8 bits
120
+ 8
121
+ elsif bit_length <= 16 # 16 bits
122
+ 16
123
+ else # 32 bits
124
+ 32
125
+ end
146
126
  end
147
127
 
148
128
  def dump(value=nil)
149
- self.value = value if !value.nil?
150
- @value
129
+ before_dump( value )
130
+ data = @value.pack(format).unpack('b*').first.chars.each_slice(word_length).map(&:join).map{|n| n.slice(0,bit_length)}
131
+ @raw_value = [data.join].pack('b*').unpack('C*')
151
132
  end
152
133
 
153
- def load(value)
154
- self.value = value if !value.nil?
155
- @value
134
+ def load(raw_value)
135
+ self.value = check_raw_value(raw_value).pack('C*').unpack('b*').first.chars.slice(0,@bit_length*@count).each_slice(bit_length).map(&:join).map{|n| [n].pack('b*').unpack('C*').first}
136
+ after_load
156
137
  end
157
138
  end
158
139
 
159
140
  class Char < Type
160
- def initialize(count=1, length=1)
161
- super 8, nil, count, length
162
- @default_value = "\x0"
163
- self.value = @default_value
164
- end
165
-
166
- #@todo: corregir lo de abajo:
167
- def self.serialize(value)
168
- var = Char.new
169
- var.value = value
170
- var.serialize
141
+ def initialize(options = {})
142
+ super options.merge :bit_length => 8, :sign => nil, :default_value => "\x0"
171
143
  end
172
144
 
173
145
  def dump(value=nil)
174
- self.value = value if !value.nil?
175
- @value.map{|v| v.ljust(@length, @default_value).slice(0,@length).unpack('C*')}
146
+ before_dump( value )
147
+ @raw_value = @value.map{|v| v.ljust(@length, @default_value).slice(0,@length).unpack('C*')}
176
148
  end
177
149
 
178
- def load(value)
179
- self.value = value.pack('C*').unpack("Z#{@length}") if !value.nil?
180
- @value
150
+ def load(raw_value)
151
+ self.value = check_raw_value(raw_value).pack('C*').unpack("Z#{@length}") if !value.nil?
152
+ after_load
181
153
  end
182
154
  end
183
155
 
184
156
  class Bool < Type
185
- def initialize(count=1, length=1)
186
- super 1, :unsigned, count
187
- self.value = 0
157
+ def initialize(options = {})
158
+ super options.merge :bit_length => 1, :default_value => false
188
159
  end
189
160
 
190
161
  def dump(value=nil)
191
- self.value = value if !value.nil?
192
- [@value.join].pack('b*').unpack('C*')
162
+ before_dump( value )
163
+ @raw_value = Array(@value.map{|v| v ? 1 : 0}.join).pack('b*').unpack('C*')
193
164
  end
194
165
 
195
- def load(value)
196
- self.value = value.pack('C*').unpack('b*').first.slice(0,size*8).split('').map(&:to_i) if !value.nil?
197
- @value
166
+ def load(raw_value)
167
+ self.value = check_raw_value(raw_value).pack('C*').unpack('b*').first.slice(0,size*8).split('').map(&:to_i) if !value.nil?
168
+ after_load
198
169
  end
199
170
  end
200
171
 
201
172
  class Float32 < Type
202
- def initialize(count=1, length=1)
203
- super 32, nil, count
204
- @default_value = 0.0
205
- self.value = @default_value
173
+ def initialize(options = {})
174
+ super options.merge :bit_length => 32, :sign => nil, :default_value => 0.0
206
175
  end
207
176
 
208
177
  def dump(value=nil)
209
- self.value = value if !value.nil?
210
- @value.pack('e*').unpack('C*')
178
+ before_dump( value )
179
+ @raw_value = @value.pack('e*').unpack('C*')
211
180
  end
212
181
 
213
- def load(value)
214
- self.value = value.pack('C*').unpack('e*') if !value.nil?
215
- @value
182
+ def load(raw_value)
183
+ self.value = check_raw_value(raw_value).pack('C*').unpack('e*') if !value.nil?
184
+ after_load
216
185
  end
217
186
  end
218
187
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveModelSerializersBinary
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.13"
3
3
  end
@@ -16,6 +16,12 @@ class Producto
16
16
  instance_values
17
17
  end
18
18
 
19
+ def attributes=(hash)
20
+ hash.each do |key, value|
21
+ instance_variable_set("@#{key}", value)
22
+ end
23
+ end
24
+
19
25
  # def metodo
20
26
  # self.instance_variable_get("@variable")
21
27
  # end
@@ -24,49 +30,44 @@ class Producto
24
30
  # self.instance_variable_set("@variable", value)
25
31
  # end
26
32
 
27
- # Formato atributo, Coder, Count, Length
28
- serialize_options :id, Int16
29
- serialize_options :silo, Int16
30
- serialize_options :nombre, Char,1, 20
31
- serialize_options :total_acumulado, Int32
32
- serialize_options :bits1, Bool, 1
33
- serialize_options :bits2, Bool, 1
34
- serialize_options :total_acumulado_1, Int32
35
- serialize_options :float, Float32
36
- serialize_options :variable, Char, 1, 20
37
-
38
- def initialize
39
- @start_address = 0
40
- @id = 1
41
- @silo = 0
42
- @nombre = "MAIZ"
43
- @total_acumulado = 50
44
- @bits1 = 1
45
- @bits2 = 1
46
- @total_acumulado_1 = 20
47
- @float= 1.2345678
48
- @variable = '012345678901234567890123456789'
33
+ int16 :id
34
+ int16 :silo
35
+ char :nombre, count: 1, length: 20
36
+ int32 :total_acumulado
37
+ bool :bits1
38
+ bool :bits2
39
+ int32 :total_acumulado_1
40
+ float32 :float
41
+ char :variable, count: 1, length: 20 do |field, mode|
42
+ puts (mode.to_s + ': variable block').blue
49
43
  end
50
44
  end
51
45
 
46
+
52
47
  orig = Producto.new
48
+ orig.start_address = 0
49
+ orig.id = 1
50
+ orig.silo = 0
51
+ orig.nombre = "MAIZ"
52
+ orig.total_acumulado = 50
53
+ orig.bits1 = 1
54
+ orig.bits2 = 1
55
+ orig.total_acumulado_1 = 20
56
+ orig.float= 1.2345678
57
+ orig.variable = '012345678901234567890123456789'
53
58
 
54
59
  puts 'Datos originales...'
55
60
  puts orig.inspect.green
56
61
 
57
62
  puts 'serializando...'
58
63
  serial = orig.to_bytes do |b|
59
- puts '@variable original: ', b.variable
60
- b.variable = b.variable.map {|c| (c.ord+10).chr}
61
- puts '@variable modificada: ', b.variable
64
+ puts 'to_bytes block'.blue
62
65
  end
63
66
 
64
67
  puts serial.inspect.yellow
65
68
 
66
69
  puts 'deserializando...'
67
70
  deser = Producto.new.from_bytes serial do |b|
68
- puts 'datos leidos: ', b.variable
69
- b.variable = b.variable.map {|c| (c.ord-10).chr}
70
- puts 'datos modificados: ', b.variable
71
+ puts 'from_bytes block'.blue
71
72
  end
72
73
  puts deser.inspect.green
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_model_serializers_binary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - ByS Sistemas de Control
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-25 00:00:00.000000000 Z
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -237,6 +237,7 @@ files:
237
237
  - active_model_serializers_binary.gemspec
238
238
  - lib/active_model_serializers_binary.rb
239
239
  - lib/active_model_serializers_binary/active_model_serializers_binary.rb
240
+ - lib/active_model_serializers_binary/base_type.rb
240
241
  - lib/active_model_serializers_binary/data_types.rb
241
242
  - lib/active_model_serializers_binary/version.rb
242
243
  - lib/tasks/active_model_serializers_binary_tasks.rake