active_model_serializers_binary 0.0.10 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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