active_model_serializers_binary 0.2.0 → 0.2.1

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: 876801a003f61b57070687c4049198f3a7407a21
4
- data.tar.gz: e9c677a84305f640f0f77280d01767246da97f9d
3
+ metadata.gz: 596d98d9d3ebdccccb17e210ba65d1c21f3402a1
4
+ data.tar.gz: c8b0dfdb53e10abb64d79185687d6530a440e0fb
5
5
  SHA512:
6
- metadata.gz: 34ed74da0e671a9be0e153940416150b8550e091d8e5ee10ab8c74caf89c30cbe963dfe62cdb47b3926b13b9cd9e7140d1617473e42d27197f7873e1fa0ba859
7
- data.tar.gz: f7e0803f4e919c2c7b2c3d7e32718f0b912aaeff3be7288b86016c26bc21b3dbeb1ff1edc4bea9af6783dcb189d929fcae2ac1a8d961d389e36edd4c89c027d9
6
+ metadata.gz: 524d45fbc3dc9b1208cf49a5efe72a3beac8860b0ddc98e6897999f4f60f532e37512db7f2fa76cdbbf15681d250e0c899386933ab02ff39124949209521b7ad
7
+ data.tar.gz: c6b4b8d0e2a58b39d111fad53e10ef3ea40d2b540bcc6ad00b0661c4ed2174864a0e57465e997c4802d0d58f642d1d4a58e06cf7c59f33ea79272a238b2fd5fd
@@ -7,6 +7,7 @@ module ActiveModel
7
7
  # == Active Model Binary serializer
8
8
  module Binary
9
9
  extend ActiveSupport::Concern
10
+ include ActiveModel::Model
10
11
  include ActiveModel::Serialization
11
12
  include DataTypes
12
13
 
@@ -16,10 +17,7 @@ module ActiveModel
16
17
  class_attribute :attr_config
17
18
  class_attribute :serialize_options_global
18
19
  self.attr_config = []
19
- self.serialize_options_global = {
20
- align: false, # Don't align data to byte/word/dword boundary
21
- endianess: :little
22
- }
20
+ self.serialize_options_global = {}
23
21
 
24
22
  def attributes
25
23
  keys = self.attr_config.select{ |attr| attr[:virtual]==true }.map{ |attr| attr[:name] }
@@ -28,8 +26,8 @@ module ActiveModel
28
26
  end
29
27
 
30
28
  def initialize( *args )
31
- super rescue super()
32
29
  initialize_serializer
30
+ super rescue super()
33
31
  end
34
32
 
35
33
  def initialize_serializer
@@ -37,6 +35,9 @@ module ActiveModel
37
35
  end
38
36
 
39
37
  after_initialize :initialize_serializer rescue nil
38
+
39
+ endianess :little
40
+ align false
40
41
  end
41
42
 
42
43
  module ClassMethods
@@ -59,14 +60,6 @@ module ActiveModel
59
60
  end
60
61
  end
61
62
 
62
- # todo: agrupar parametros en hash (rompe la compatibilidad hacia atras)
63
- def serialize_options( attr_name, coder, count=1, length=1, virtual=false, &block )
64
- self.attr_config.push({:coder => coder, :count => count, :length => length, :block => block, :name => attr_name.to_s, :virtual => virtual})
65
- if virtual==true
66
- attr_accessor attr_name
67
- end
68
- end
69
-
70
63
  def serialize_attribute_options( attr_name, options, &block )
71
64
  self.attr_config.push(options.merge({:name => attr_name.to_s, block: block }))
72
65
  if options[:virtual]==true
@@ -75,12 +68,12 @@ module ActiveModel
75
68
  end
76
69
 
77
70
  def int8( attr_name, options = {}, &block )
78
- options = serialize_options_global.merge(options)
71
+ options = self.serialize_options_global.merge(options)
79
72
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::Int8}), &block
80
73
  end
81
74
 
82
75
  def int16( attr_name, options = {}, &block )
83
- options = serialize_options_global.merge(options)
76
+ options = self.serialize_options_global.merge(options)
84
77
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::Int16}), &block
85
78
  end
86
79
 
@@ -93,7 +86,7 @@ module ActiveModel
93
86
  end
94
87
 
95
88
  def int32( attr_name, options = {}, &block )
96
- options = serialize_options_global.merge(options)
89
+ options = self.serialize_options_global.merge(options)
97
90
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::Int32}), &block
98
91
  end
99
92
 
@@ -102,16 +95,16 @@ module ActiveModel
102
95
  end
103
96
 
104
97
  def int32be( attr_name, options = {}, &block )
105
- int16( attr_name, options.merge({endianess: :big}), &block )
98
+ int32( attr_name, options.merge({endianess: :big}), &block )
106
99
  end
107
100
 
108
101
  def uint8( attr_name, options = {}, &block )
109
- options = serialize_options_global.merge(options)
102
+ options = self.serialize_options_global.merge(options)
110
103
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::UInt8}), &block
111
104
  end
112
105
 
113
106
  def uint16( attr_name, options = {}, &block )
114
- options = serialize_options_global.merge(options)
107
+ options = self.serialize_options_global.merge(options)
115
108
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::UInt16}), &block
116
109
  end
117
110
 
@@ -124,7 +117,7 @@ module ActiveModel
124
117
  end
125
118
 
126
119
  def uint32( attr_name, options = {}, &block )
127
- options = serialize_options_global.merge(options)
120
+ options = self.serialize_options_global.merge(options)
128
121
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::UInt32}), &block
129
122
  end
130
123
 
@@ -137,55 +130,117 @@ module ActiveModel
137
130
  end
138
131
 
139
132
  def bitfield( attr_name, options = {}, &block )
140
- options = serialize_options_global.merge(options)
141
- serialize_attribute_options attr_name, options.merge({coder: DataTypes::BitField}), &block
133
+ options = self.serialize_options_global.merge(options)
134
+ serialize_attribute_options attr_name, options.merge({coder: DataTypes::BitField, type: :bitfield}), &block
142
135
  end
143
136
 
144
137
  def float32( attr_name, options = {}, &block )
145
- options = serialize_options_global.merge(options)
138
+ options = self.serialize_options_global.merge(options)
146
139
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::Float32}), &block
147
140
  end
148
141
 
149
142
  def float64( attr_name, options = {}, &block )
150
- options = serialize_options_global.merge(options)
151
- serialize_attribute_options attr_name, options.merge({coder: DataTypes::Float32}), &block
143
+ options = self.serialize_options_global.merge(options)
144
+ serialize_attribute_options attr_name, options.merge({coder: DataTypes::Float64}), &block
152
145
  end
153
146
 
154
147
  def char( attr_name, options = {}, &block )
155
- options = serialize_options_global.merge(options)
148
+ options = self.serialize_options_global.merge(options)
156
149
  serialize_attribute_options attr_name, options.merge({coder: DataTypes::Char}), &block
157
150
  end
158
151
 
159
152
  def bool( attr_name, options = {}, &block )
160
- options = serialize_options_global.merge(options)
161
- serialize_attribute_options attr_name, options.merge({coder: DataTypes::Bool}), &block
153
+ options = self.serialize_options_global.merge(options)
154
+ serialize_attribute_options attr_name, options.merge({coder: DataTypes::Bool, type: :bool}), &block
162
155
  end
163
156
 
164
157
  def nest( attr_name, options={}, &block )
165
- options = serialize_options_global.merge(options)
158
+ options = self.serialize_options_global.merge(options)
166
159
  serialize_attribute_options attr_name, options.merge({type: :nest}), &block
167
160
  end
168
161
 
169
162
  def endianess( type = :little )
170
- serialize_options_global.merge!({endianess: type})
163
+ self.serialize_options_global.merge!({endianess: type})
164
+ end
165
+
166
+ def align( boundary = false )
167
+ self.serialize_options_global.merge!({align: boundary})
171
168
  end
172
169
  end
173
170
 
174
171
  class Serializer #:nodoc:
175
- #attr_reader :options
172
+ attr_accessor :start_address
176
173
 
177
174
  def initialize(serializable, options = nil)
178
175
  @serializable = serializable
179
176
  @options = options ? options.dup : {}
177
+ @current_address = 0
178
+ @start_address = 0
179
+ @current_byte = 0
180
+ @current_bit = 0
181
+ end
182
+
183
+ def current_address= (value)
184
+ @current_address = value
185
+ @current_byte = value.floor
186
+ @current_bit = (value.modulo(1)*8).round
187
+ end
188
+
189
+ def current_address
190
+ @current_address
191
+ end
192
+
193
+ def current_byte= (value)
194
+ @current_byte = value
195
+ @current_address = (@current_byte+@current_bit/8.0)
196
+ end
197
+
198
+ def current_byte
199
+ @current_byte
200
+ end
201
+
202
+ def current_bit= (value)
203
+ @current_bit = value
204
+ @current_address = (@current_byte+@current_bit/8.0)
205
+ end
206
+
207
+ def current_bit
208
+ @current_bit
209
+ end
210
+
211
+ def align_data( attr_options, var )
212
+ # XXX: hay que sacar nest de acá
213
+ if !attr_options[:type].in? [:bitfield, :bool, :nest]
214
+ # Se posiciona al principio de un byte
215
+ if self.current_bit != 0
216
+ self.current_address = self.current_address.ceil
217
+ end
218
+ if @options[:align]==:dword
219
+ # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
220
+ if var.bit_length > 8 and (self.current_address + self.start_address).modulo(2) != 0
221
+ self.current_byte += 1
222
+ end
223
+ # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
224
+ if var.bit_length > 16 and (self.current_address + self.start_address).modulo(4) != 0
225
+ self.current_byte += 4-self.current_byte%4
226
+ end
227
+ elsif @options[:align]==:word
228
+ # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
229
+ if var.bit_length > 8 and (self.current_address + self.start_address).modulo(2) != 0
230
+ self.current_byte += 1
231
+ end
232
+ end
233
+ end
180
234
  end
181
235
 
182
236
  def dump
183
237
  serializable_values = @serializable.serializable_hash(@options)
184
- start_address = @options[:start_address] || 0
238
+ self.start_address = @options[:start_address] || 0
185
239
 
186
240
  buffer = [] # Data Buffer
187
241
  tmp_buffer = [] # Aux Data Buffer
188
- current_address = start_address*2 + 0.0 # Address in bytes
242
+
243
+ self.current_address = self.start_address # Address in bytes
189
244
 
190
245
  @serializable.attr_config.each do |attr_options|
191
246
  attr_name = attr_options[:name]
@@ -197,46 +252,24 @@ module ActiveModel
197
252
  var = attr_options[:coder].new(var_value)
198
253
  end
199
254
 
200
- byte = current_address.floor
201
- bit = (current_address.modulo(1)*8).round
202
-
203
255
  tmp_buffer = var.dump
204
256
 
205
- if @options[:align]
206
- if !attr_options[:type].in? [:bitfield, :bool, :nest]
207
- # Se posiciona al principio de un byte
208
- if bit != 0
209
- byte += 1
210
- bit = 0
211
- current_address = (byte+bit/8.0)
212
- end
213
- # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
214
- if var.bit_length > 8 and current_address.modulo(2) != 0
215
- byte += 1
216
- bit = 0
217
- end
218
- # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
219
- if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
220
- byte += 4-byte%4
221
- bit = 0
222
- end
223
- end
224
- end
257
+ align_data(attr_options, var) if @options[:align]
225
258
 
226
259
  # Si los datos ocupan mas de un byte concatena los arrays
227
260
  if !attr_options[:type].in? [:bitfield, :bool] and @options[:align]
228
- buffer.insert(byte, tmp_buffer).flatten!
261
+ buffer.insert(self.current_byte, tmp_buffer).flatten!
229
262
  else # En caso de ser bits
230
263
  tmp_buffer.flatten!
231
264
  tmp_bits=tmp_buffer.pack('C*').unpack('b*').first.slice(0,var.size*8)
232
- tmp_buffer=[tmp_bits.rjust(tmp_bits.length+bit,'0')].pack('b*').unpack('C*')
265
+ tmp_buffer=[tmp_bits.rjust(tmp_bits.length+self.current_bit,'0')].pack('b*').unpack('C*')
233
266
 
234
267
  tmp_buffer.each_with_index do |v,i|
235
- buffer[byte+i] = (buffer[byte+i] || 0) | v
268
+ buffer[self.current_byte+i] = (buffer[self.current_byte+i] || 0) | v
236
269
  end
237
270
  end
238
271
 
239
- current_address = (byte+bit/8.0)+var.size
272
+ self.current_address += var.size
240
273
  end
241
274
  buffer.map!{|el| el || 0}
242
275
  end
@@ -244,47 +277,26 @@ module ActiveModel
244
277
  #deserializado
245
278
  def load (buffer=[])
246
279
  serialized_values = {}
247
- start_address = @options[:start_address] || 0
280
+ self.start_address = @options[:start_address] || 0
248
281
 
249
282
  buffer ||= [] # Buffer en bytes
250
283
  tmp_buffer = [] # Buffer temporal en bytes
251
284
 
252
- current_address = start_address*2 + 0.0 # Dirección en bytes
285
+ self.current_address = self.start_address # Dirección en bytes
253
286
 
254
287
  @serializable.attr_config.each do |attr_options|
255
288
  attr_name = attr_options[:name]
256
- byte = current_address.floor
257
- bit = (current_address.modulo(1)*8).round
258
289
 
259
290
  var = attr_options[:coder].new(attr_options.merge(parent: @serializable)) #creo objeto del tipo de dato pasado
260
291
 
261
- if @options[:align]
262
- if !attr_options[:type].in? [:bitfield, :bool, :nest]
263
- # Se posiciona al principio de un byte
264
- if bit != 0
265
- byte += 1
266
- bit = 0
267
- current_address = (byte+bit/8.0)
268
- end
269
- # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
270
- if var.bit_length > 8 and current_address.modulo(2) != 0
271
- byte += 1
272
- bit = 0
273
- end
274
- # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
275
- if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
276
- byte += 4-byte%4
277
- bit = 0
278
- end
279
- end
280
- end
292
+ align_data(attr_options, var) if @options[:align]
281
293
 
282
294
  # Si los datos ocupan mas de un byte, obtiene los bytes completos del buffer original
283
295
  if !attr_options[:type].in? [:bitfield, :bool] and @options[:align]
284
- result_deserialized=var.load(buffer.slice(byte, var.size))
296
+ result_deserialized=var.load(buffer.slice(self.current_byte, var.size))
285
297
  else # En caso de ser bits
286
- tmp_buffer = buffer.slice(byte, (var.size+bit/8.0).ceil)
287
- result_deserialized=var.load([tmp_buffer.pack('C*').unpack('b*').first.slice(bit,var.size*8)].pack('b*').unpack('C*'))
298
+ tmp_buffer = buffer.slice(self.current_byte, (var.size+self.current_bit/8.0).ceil)
299
+ result_deserialized=var.load([tmp_buffer.pack('C*').unpack('b*').first.slice(self.current_bit,var.size*8)].pack('b*').unpack('C*'))
288
300
  end
289
301
 
290
302
  if attr_options[:type] == :nest
@@ -292,7 +304,7 @@ module ActiveModel
292
304
  else
293
305
  serialized_values["#{attr_name}"] = result_deserialized.count>1 ? result_deserialized : result_deserialized.first
294
306
  end
295
- current_address = (byte+bit/8.0)+var.size
307
+ self.current_address += var.size
296
308
  end
297
309
 
298
310
  # Asigno los datos leidos
@@ -305,39 +317,18 @@ module ActiveModel
305
317
  # Return size of object in bytes
306
318
  def size
307
319
  serializable_values = @serializable.serializable_hash(@options)
308
- start_address = @options[:start_address] || 0
320
+ self.start_address = @options[:start_address] || 0
309
321
 
310
322
  current_address = 0.0 # Dirección en bytes
311
323
 
312
324
  @serializable.attr_config.each do |attr_options|
313
325
  var = attr_options[:coder].new(attr_options.merge(parent: @serializable))
314
326
 
315
- byte = current_address.floor
316
- bit = (current_address.modulo(1)*8).round
317
-
318
- if @options[:align]
319
- if !attr_options[:type].in? [:bitfield, :bool, :nest]
320
- # Se posiciona al principio de un byte
321
- if bit != 0
322
- byte += 1
323
- bit = 0
324
- current_address = (byte+bit/8.0)
325
- end
326
- # Si el dato es una palabra simple, alinea los datos en el siguiente byte par
327
- if var.bit_length > 8 and current_address.modulo(2) != 0
328
- byte += 1
329
- bit = 0
330
- end
331
- # Si el dato es una palabra doble, alinea los datos en la siguiente palabra par
332
- if var.bit_length > 16 and (current_address + start_address*2).modulo(4) != 0
333
- byte += 4-byte%4
334
- bit = 0
335
- end
336
- end
337
- end
338
- current_address = (byte+bit/8.0)+var.size
327
+ align_data(attr_options, var) if @options[:align]
328
+
329
+ self.current_address += var.size
339
330
  end
340
- current_address-start_address
331
+ self.current_address-self.start_address
341
332
  end
342
333
 
343
334
  end #close class serializer
@@ -48,7 +48,7 @@ module DataTypes
48
48
  default_value
49
49
  else
50
50
  case type
51
- when :float32
51
+ when :float32, :float64
52
52
  v.to_f
53
53
  when :char
54
54
  v.to_s[0...length]
@@ -1,251 +1,251 @@
1
- require_relative 'base_type.rb'
2
-
3
- module DataTypes
4
-
5
- class Int8 < BaseType
6
- def initialize(options = {})
7
- super options.merge :bit_length => 8, :sign => :signed
8
- end
9
-
10
- def dump(value=nil)
11
- before_dump( value ).pack('c*').unpack('C*')
12
- @raw_value = @value
13
- end
14
-
15
- def load(raw_value)
16
- self.value = check_raw_value(raw_value).pack('C*').unpack('c*')
17
- after_load
18
- end
19
- end
20
-
21
- class Int16 < BaseType
22
- def initialize(options = {})
23
- super options.merge :bit_length => 16, :sign => :signed
24
- end
25
-
26
- def dump(value=nil)
27
- before_dump( value )
28
- if @endianess == :big
29
- @raw_value = @value.pack('s>*').unpack('C*')
30
- else
31
- @raw_value = @value.pack('s<*').unpack('C*')
32
- end
33
- end
34
-
35
- def load(raw_value)
36
- if @endianess == :big
37
- self.value = check_raw_value(raw_value).pack('C*').unpack('s>*')
38
- else
39
- self.value = check_raw_value(raw_value).pack('C*').unpack('s<*')
40
- end
41
- after_load
42
- end
43
- end
44
-
45
- class Int32 < BaseType
46
- def initialize(options = {})
47
- super options.merge :bit_length => 32, :sign => :signed
48
- end
49
-
50
- def dump(value=nil)
51
- before_dump( value )
52
- if @endianess == :big
53
- @raw_value = @value.pack('l>*').unpack('C*')
54
- else
55
- @raw_value = @value.pack('l<*').unpack('C*')
56
- end
57
- end
58
-
59
- def load(raw_value)
60
- if @endianess == :big
61
- self.value = check_raw_value(raw_value).pack('C*').unpack('l>*') if !value.nil?
62
- else
63
- self.value = check_raw_value(raw_value).pack('C*').unpack('l<*') if !value.nil?
64
- end
65
- after_load
66
- end
67
- end
68
-
69
- class UInt16 < BaseType
70
- def initialize(options = {})
71
- super options.merge :bit_length => 16, :sign => :unsigned
72
- end
73
-
74
- def dump(value=nil)
75
- before_dump( value )
76
- if @endianess == :big
77
- @raw_value = @value.pack('S>*').unpack('C*')
78
- else
79
- @raw_value = @value.pack('S<*').unpack('C*')
80
- end
81
- end
82
-
83
- def load(raw_value)
84
- @raw_value = check_raw_value(raw_value)
85
- if @endianess == :big
86
- self.value = @raw_value.pack('C*').unpack('S>*')
87
- else
88
- self.value = @raw_value.pack('C*').unpack('S<*')
89
- end
90
- after_load
91
- end
92
- end
93
-
94
- class UInt32 < BaseType
95
- def initialize(options = {})
96
- super options.merge :bit_length => 32, :sign => :unsigned
97
- end
98
-
99
- def dump(value=nil)
100
- before_dump( value )
101
- if @endianess == :big
102
- @raw_value = @value.pack('L>*').unpack('C*')
103
- else
104
- @raw_value = @value.pack('L<*').unpack('C*')
105
- end
106
- end
107
-
108
- def load(raw_value)
109
- if @endianess == :big
110
- self.value = check_raw_value(raw_value).pack('C*').unpack('L>*') if !value.nil?
111
- else
112
- self.value = check_raw_value(raw_value).pack('C*').unpack('L<*') if !value.nil?
113
- end
114
- after_load
115
- end
116
- end
117
-
118
- class UInt8 < BaseType
119
- def initialize(options = {})
120
- super options.merge :bit_length => 8, :sign => :unsigned
121
- end
122
-
123
- def dump(value=nil)
124
- before_dump( value )
125
- @raw_value = @value
126
- end
127
-
128
- def load(raw_value)
129
- self.value = check_raw_value(raw_value)
130
- after_load
131
- end
132
- end
133
-
134
- class BitField < BaseType
135
- def initialize(options = {})
136
- length = options[:bin_length].blank? ? 1 : (options[:bin_length] > 32 ? 32 : options[:bin_length])
137
- super options.merge :bit_length => length, :sign => :unsigned
138
- end
139
-
140
- def format
141
- if bit_length <= 8 # 8 bits
142
- 'C*'
143
- elsif bit_length <= 16 # 16 bits
144
- 'v*'
145
- else # 32 bits
146
- 'l*'
147
- end
148
- end
149
-
150
- def word_length
151
- if bit_length <= 8 # 8 bits
152
- 8
153
- elsif bit_length <= 16 # 16 bits
154
- 16
155
- else # 32 bits
156
- 32
157
- end
158
- end
159
-
160
- def dump(value=nil)
161
- before_dump( value )
162
- data = @value.pack(format).unpack('b*').first.chars.each_slice(word_length).map(&:join).map{|n| n.slice(0,bit_length)}
163
- @raw_value = [data.join].pack('b*').unpack('C*')
164
- end
165
-
166
- def load(raw_value)
167
- 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}
168
- after_load
169
- end
170
- end
171
-
172
- class Char < BaseType
173
- def initialize(options = {})
174
- super options.merge :bit_length => 8, :sign => nil, :default_value => "\x0"
175
- end
176
-
177
- def dump(value=nil)
178
- before_dump( value )
179
- @raw_value = @value.map{|v| v.ljust(@length, @default_value).slice(0,@length).unpack('C*')}
180
- end
181
-
182
- def load(raw_value)
183
- self.value = check_raw_value(raw_value).pack('C*').unpack("Z#{@length}") if !value.nil?
184
- after_load
185
- end
186
- end
187
-
188
- class Bool < BaseType
189
- def initialize(options = {})
190
- super options.merge :bit_length => 1, :default_value => false
191
- end
192
-
193
- def dump(value=nil)
194
- before_dump( value )
195
- @raw_value = Array(@value.map{|v| v ? 1 : 0}.join).pack('b*').unpack('C*')
196
- end
197
-
198
- def load(raw_value)
199
- self.value = check_raw_value(raw_value).pack('C*').unpack('b*').first.slice(0,size*8).split('').map(&:to_i) if !value.nil?
200
- after_load
201
- end
202
- end
203
-
204
- class Float32 < BaseType
205
- def initialize(options = {})
206
- super options.merge :bit_length => 32, :sign => nil, :default_value => 0.0
207
- end
208
-
209
- def dump(value=nil)
210
- before_dump( value )
211
- if @endianess == :big
212
- @raw_value = @value.pack('g*').unpack('C*')
213
- else
214
- @raw_value = @value.pack('e*').unpack('C*')
215
- end
216
- end
217
-
218
- def load(raw_value)
219
- if @endianess == :big
220
- self.value = check_raw_value(raw_value).pack('C*').unpack('g*') if !value.nil?
221
- else
222
- self.value = check_raw_value(raw_value).pack('C*').unpack('e*') if !value.nil?
223
- end
224
- after_load
225
- end
226
- end
227
-
228
- class Float64 < BaseType
229
- def initialize(options = {})
230
- super options.merge :bit_length => 64, :sign => nil, :default_value => 0.0
231
- end
232
-
233
- def dump(value=nil)
234
- before_dump( value )
235
- if @endianess == :big
236
- @raw_value = @value.pack('G*').unpack('C*')
237
- else
238
- @raw_value = @value.pack('E*').unpack('C*')
239
- end
240
- end
241
-
242
- def load(raw_value)
243
- if @endianess == :big
244
- self.value = check_raw_value(raw_value).pack('C*').unpack('G*') if !value.nil?
245
- else
246
- self.value = check_raw_value(raw_value).pack('C*').unpack('E*') if !value.nil?
247
- end
248
- after_load
249
- end
250
- end
1
+ require_relative 'base_type.rb'
2
+
3
+ module DataTypes
4
+
5
+ class Int8 < BaseType
6
+ def initialize(options = {})
7
+ super options.merge :bit_length => 8, :sign => :signed
8
+ end
9
+
10
+ def dump(value=nil)
11
+ before_dump( value )
12
+ @raw_value = @value.pack('c*').unpack('C*')
13
+ end
14
+
15
+ def load(raw_value)
16
+ self.value = check_raw_value(raw_value).pack('C*').unpack('c*')
17
+ after_load
18
+ end
19
+ end
20
+
21
+ class Int16 < BaseType
22
+ def initialize(options = {})
23
+ super options.merge :bit_length => 16, :sign => :signed
24
+ end
25
+
26
+ def dump(value=nil)
27
+ before_dump( value )
28
+ if @endianess == :big
29
+ @raw_value = @value.pack('s>*').unpack('C*')
30
+ else
31
+ @raw_value = @value.pack('s<*').unpack('C*')
32
+ end
33
+ end
34
+
35
+ def load(raw_value)
36
+ if @endianess == :big
37
+ self.value = check_raw_value(raw_value).pack('C*').unpack('s>*')
38
+ else
39
+ self.value = check_raw_value(raw_value).pack('C*').unpack('s<*')
40
+ end
41
+ after_load
42
+ end
43
+ end
44
+
45
+ class Int32 < BaseType
46
+ def initialize(options = {})
47
+ super options.merge :bit_length => 32, :sign => :signed
48
+ end
49
+
50
+ def dump(value=nil)
51
+ before_dump( value )
52
+ if @endianess == :big
53
+ @raw_value = @value.pack('l>*').unpack('C*')
54
+ else
55
+ @raw_value = @value.pack('l<*').unpack('C*')
56
+ end
57
+ end
58
+
59
+ def load(raw_value)
60
+ if @endianess == :big
61
+ self.value = check_raw_value(raw_value).pack('C*').unpack('l>*') if !value.nil?
62
+ else
63
+ self.value = check_raw_value(raw_value).pack('C*').unpack('l<*') if !value.nil?
64
+ end
65
+ after_load
66
+ end
67
+ end
68
+
69
+ class UInt16 < BaseType
70
+ def initialize(options = {})
71
+ super options.merge :bit_length => 16, :sign => :unsigned
72
+ end
73
+
74
+ def dump(value=nil)
75
+ before_dump( value )
76
+ if @endianess == :big
77
+ @raw_value = @value.pack('S>*').unpack('C*')
78
+ else
79
+ @raw_value = @value.pack('S<*').unpack('C*')
80
+ end
81
+ end
82
+
83
+ def load(raw_value)
84
+ @raw_value = check_raw_value(raw_value)
85
+ if @endianess == :big
86
+ self.value = @raw_value.pack('C*').unpack('S>*')
87
+ else
88
+ self.value = @raw_value.pack('C*').unpack('S<*')
89
+ end
90
+ after_load
91
+ end
92
+ end
93
+
94
+ class UInt32 < BaseType
95
+ def initialize(options = {})
96
+ super options.merge :bit_length => 32, :sign => :unsigned
97
+ end
98
+
99
+ def dump(value=nil)
100
+ before_dump( value )
101
+ if @endianess == :big
102
+ @raw_value = @value.pack('L>*').unpack('C*')
103
+ else
104
+ @raw_value = @value.pack('L<*').unpack('C*')
105
+ end
106
+ end
107
+
108
+ def load(raw_value)
109
+ if @endianess == :big
110
+ self.value = check_raw_value(raw_value).pack('C*').unpack('L>*') if !value.nil?
111
+ else
112
+ self.value = check_raw_value(raw_value).pack('C*').unpack('L<*') if !value.nil?
113
+ end
114
+ after_load
115
+ end
116
+ end
117
+
118
+ class UInt8 < BaseType
119
+ def initialize(options = {})
120
+ super options.merge :bit_length => 8, :sign => :unsigned
121
+ end
122
+
123
+ def dump(value=nil)
124
+ before_dump( value )
125
+ @raw_value = @value
126
+ end
127
+
128
+ def load(raw_value)
129
+ self.value = check_raw_value(raw_value)
130
+ after_load
131
+ end
132
+ end
133
+
134
+ class BitField < BaseType
135
+ def initialize(options = {})
136
+ length = options[:bin_length].blank? ? 1 : (options[:bin_length] > 32 ? 32 : options[:bin_length])
137
+ super options.merge :bit_length => length, :sign => :unsigned
138
+ end
139
+
140
+ def format
141
+ if bit_length <= 8 # 8 bits
142
+ 'C*'
143
+ elsif bit_length <= 16 # 16 bits
144
+ 'v*'
145
+ else # 32 bits
146
+ 'l*'
147
+ end
148
+ end
149
+
150
+ def word_length
151
+ if bit_length <= 8 # 8 bits
152
+ 8
153
+ elsif bit_length <= 16 # 16 bits
154
+ 16
155
+ else # 32 bits
156
+ 32
157
+ end
158
+ end
159
+
160
+ def dump(value=nil)
161
+ before_dump( value )
162
+ data = @value.pack(format).unpack('b*').first.chars.each_slice(word_length).map(&:join).map{|n| n.slice(0,bit_length)}
163
+ @raw_value = [data.join].pack('b*').unpack('C*')
164
+ end
165
+
166
+ def load(raw_value)
167
+ 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}
168
+ after_load
169
+ end
170
+ end
171
+
172
+ class Char < BaseType
173
+ def initialize(options = {})
174
+ super options.merge :bit_length => 8, :sign => nil, :default_value => "\x0"
175
+ end
176
+
177
+ def dump(value=nil)
178
+ before_dump( value )
179
+ @raw_value = @value.map{|v| v.ljust(@length, @default_value).slice(0,@length).unpack('C*')}
180
+ end
181
+
182
+ def load(raw_value)
183
+ self.value = check_raw_value(raw_value).pack('C*').unpack("Z#{@length}") if !value.nil?
184
+ after_load
185
+ end
186
+ end
187
+
188
+ class Bool < BaseType
189
+ def initialize(options = {})
190
+ super options.merge :bit_length => 1, :default_value => false
191
+ end
192
+
193
+ def dump(value=nil)
194
+ before_dump( value )
195
+ @raw_value = Array(@value.map{|v| v ? 1 : 0}.join).pack('b*').unpack('C*')
196
+ end
197
+
198
+ def load(raw_value)
199
+ self.value = check_raw_value(raw_value).pack('C*').unpack('b*').first.slice(0,size*8).split('').map(&:to_i) if !value.nil?
200
+ after_load
201
+ end
202
+ end
203
+
204
+ class Float32 < BaseType
205
+ def initialize(options = {})
206
+ super options.merge :bit_length => 32, :sign => nil, :default_value => 0.0
207
+ end
208
+
209
+ def dump(value=nil)
210
+ before_dump( value )
211
+ if @endianess == :big
212
+ @raw_value = @value.pack('g*').unpack('C*')
213
+ else
214
+ @raw_value = @value.pack('e*').unpack('C*')
215
+ end
216
+ end
217
+
218
+ def load(raw_value)
219
+ if @endianess == :big
220
+ self.value = check_raw_value(raw_value).pack('C*').unpack('g*') if !value.nil?
221
+ else
222
+ self.value = check_raw_value(raw_value).pack('C*').unpack('e*') if !value.nil?
223
+ end
224
+ after_load
225
+ end
226
+ end
227
+
228
+ class Float64 < BaseType
229
+ def initialize(options = {})
230
+ super options.merge :bit_length => 64, :sign => nil, :default_value => 0.0
231
+ end
232
+
233
+ def dump(value=nil)
234
+ before_dump( value )
235
+ if @endianess == :big
236
+ @raw_value = @value.pack('G*').unpack('C*')
237
+ else
238
+ @raw_value = @value.pack('E*').unpack('C*')
239
+ end
240
+ end
241
+
242
+ def load(raw_value)
243
+ if @endianess == :big
244
+ self.value = check_raw_value(raw_value).pack('C*').unpack('G*') if !value.nil?
245
+ else
246
+ self.value = check_raw_value(raw_value).pack('C*').unpack('E*') if !value.nil?
247
+ end
248
+ after_load
249
+ end
250
+ end
251
251
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveModelSerializersBinary
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -0,0 +1,27 @@
1
+ class Product
2
+ include ActiveModel::Serializers::Binary
3
+
4
+ endianess :big
5
+ align :dword
6
+
7
+ int8 :int8
8
+ int16 :int16
9
+ int16le :int16le
10
+ int16be :int16be
11
+ int32 :int32
12
+ int32le :int32le
13
+ int32be :int32be
14
+ uint8 :uint8
15
+ uint16 :uint16
16
+ uint16le :uint16le
17
+ uint16be :uint16be
18
+ uint32 :uint32
19
+ uint32le :uint32le
20
+ uint32be :uint32be
21
+ bitfield :bitfield
22
+ float32 :float32
23
+ float64 :float64
24
+ char :char
25
+ bool :bool
26
+ nest :type, coder: Type
27
+ end
@@ -0,0 +1,7 @@
1
+ class Type
2
+ include ActiveModel::Serializers::Binary
3
+
4
+ int16 :product_id
5
+ char :name, count: 1, length: 20
6
+
7
+ end
@@ -7,10 +7,28 @@ class String
7
7
  end
8
8
  end
9
9
 
10
- orig = Producto.new
11
- orig.silo = 0xFF7F
12
- orig.nombre = "AAAAAAAAAAAAAAAAAAAA"
13
- orig.tipo = Tipo.new({name:"BBBBBBBBBBBBBBBBBBBB", producto_id: 0xFF7F})
10
+ orig = Product.new
11
+
12
+ orig.int8 = 1;
13
+ orig.int16 = 1;
14
+ orig.int16le = 1;
15
+ orig.int16be = 1;
16
+ orig.int32 = 1;
17
+ orig.int32le = 1;
18
+ orig.int32be = 1;
19
+ orig.uint8 = 1;
20
+ orig.uint16 = 1;
21
+ orig.uint16le = 1;
22
+ orig.uint16be = 1;
23
+ orig.uint32 = 1;
24
+ orig.uint32le = 1;
25
+ orig.uint32be = 1;
26
+ orig.bitfield = 1;
27
+ orig.float32 = 1;
28
+ orig.float64 = 1;
29
+ orig.char = "A";
30
+ orig.bool = 1;
31
+ orig.type = Type.new({product_id: 1, name: "ABCDEFGHIJKLMNOPQRST"})
14
32
 
15
33
  puts 'Datos originales...'
16
34
  puts orig.inspect.green
@@ -21,7 +39,7 @@ serial = orig.to_bytes
21
39
  puts serial.inspect.yellow
22
40
 
23
41
  puts 'deserializando...'
24
- deser = Producto.new.from_bytes serial
42
+ deser = Product.new.from_bytes serial
25
43
  puts deser.inspect.green
26
44
 
27
45
  must_be_equal = (serial <=> deser.to_bytes) === 0
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.2.0
4
+ version: 0.2.1
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: 2017-08-17 00:00:00.000000000 Z
11
+ date: 2017-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,8 +128,8 @@ files:
128
128
  - test/dummy/app/mailers/.keep
129
129
  - test/dummy/app/models/.keep
130
130
  - test/dummy/app/models/concerns/.keep
131
- - test/dummy/app/models/producto.rb
132
- - test/dummy/app/models/tipo.rb
131
+ - test/dummy/app/models/product.rb
132
+ - test/dummy/app/models/type.rb
133
133
  - test/dummy/app/views/layouts/application.html.erb
134
134
  - test/dummy/bin/bundle
135
135
  - test/dummy/bin/rails
@@ -153,9 +153,6 @@ files:
153
153
  - test/dummy/config/locales/en.yml
154
154
  - test/dummy/config/routes.rb
155
155
  - test/dummy/config/secrets.yml
156
- - test/dummy/db/migrate/20160608024807_create_productos.rb
157
- - test/dummy/db/migrate/20170817015810_create_tipos.rb
158
- - test/dummy/db/schema.rb
159
156
  - test/dummy/lib/assets/.keep
160
157
  - test/dummy/lib/test_parser.rb
161
158
  - test/dummy/log/.keep
@@ -205,8 +202,8 @@ test_files:
205
202
  - test/dummy/app/mailers/.keep
206
203
  - test/dummy/app/models/.keep
207
204
  - test/dummy/app/models/concerns/.keep
208
- - test/dummy/app/models/producto.rb
209
- - test/dummy/app/models/tipo.rb
205
+ - test/dummy/app/models/product.rb
206
+ - test/dummy/app/models/type.rb
210
207
  - test/dummy/app/views/layouts/application.html.erb
211
208
  - test/dummy/bin/bundle
212
209
  - test/dummy/bin/rails
@@ -230,9 +227,6 @@ test_files:
230
227
  - test/dummy/config/locales/en.yml
231
228
  - test/dummy/config/routes.rb
232
229
  - test/dummy/config/secrets.yml
233
- - test/dummy/db/migrate/20160608024807_create_productos.rb
234
- - test/dummy/db/migrate/20170817015810_create_tipos.rb
235
- - test/dummy/db/schema.rb
236
230
  - test/dummy/lib/assets/.keep
237
231
  - test/dummy/lib/test_parser.rb
238
232
  - test/dummy/log/.keep
@@ -1,47 +0,0 @@
1
- # == Schema Information
2
- #
3
- # Table name: productos
4
- #
5
- # id :integer not null, primary key
6
- # uid :integer
7
- # silo :integer
8
- # nombre :string(255)
9
- # total_acumulado :integer
10
- # bits1 :boolean
11
- # bits2 :boolean
12
- # ffloat :float
13
- # variable :string(255)
14
- # created_at :datetime
15
- # updated_at :datetime
16
- #
17
-
18
- class Producto < ActiveRecord::Base
19
- include ActiveModel::Serializers::Binary
20
-
21
- int16 :uid
22
- int16 :silo
23
- char :nombre, count: 1, length: 20
24
- int32 :total_acumulado
25
- bool :bits1
26
- bool :bits2
27
- bool :bits3, virtual: true
28
- bool :bits4, virtual: true
29
- bool :bits5, virtual: true
30
- bool :bits6, virtual: true
31
- bool :bits7, virtual: true
32
- bool :bits8, virtual: true
33
- bool :bits9, virtual: true
34
- bool :bits10, virtual: true
35
- bool :bits11, virtual: true
36
- bool :bits12, virtual: true
37
- bool :bits13, virtual: true
38
- bool :bits14, virtual: true
39
- bool :bits15, virtual: true
40
- bool :bits16, virtual: true
41
- float32 :ffloat
42
- char :variable, count: 1, length: 20 do |field, mode|
43
- puts (mode.to_s + ': variable block').blue
44
- end
45
- int32 :test, count: 10, virtual: true # No existe en la DB
46
- nest :tipo, coder: Tipo
47
- end
@@ -1,18 +0,0 @@
1
- # == Schema Information
2
- #
3
- # Table name: tipos
4
- #
5
- # id :integer not null, primary key
6
- # name :string
7
- # producto_id :integer
8
- # created_at :datetime not null
9
- # updated_at :datetime not null
10
- #
11
-
12
- class Tipo < ActiveRecord::Base
13
- include ActiveModel::Serializers::Binary
14
-
15
- int16 :producto_id
16
- char :name, count: 1, length: 20
17
-
18
- end
@@ -1,16 +0,0 @@
1
- class CreateProductos < ActiveRecord::Migration
2
- def change
3
- create_table :productos do |t|
4
- t.integer :uid
5
- t.integer :silo
6
- t.string :nombre
7
- t.integer :total_acumulado
8
- t.boolean :bits1
9
- t.boolean :bits2
10
- t.float :ffloat
11
- t.string :variable
12
-
13
- t.timestamps
14
- end
15
- end
16
- end
@@ -1,9 +0,0 @@
1
- class CreateTipos < ActiveRecord::Migration[5.0]
2
- def change
3
- create_table :tipos do |t|
4
- t.string :name
5
-
6
- t.timestamps
7
- end
8
- end
9
- end
@@ -1,36 +0,0 @@
1
- # This file is auto-generated from the current state of the database. Instead
2
- # of editing this file, please use the migrations feature of Active Record to
3
- # incrementally modify your database, and then regenerate this schema definition.
4
- #
5
- # Note that this schema.rb definition is the authoritative source for your
6
- # database schema. If you need to create the application database on another
7
- # system, you should be using db:schema:load, not running all the migrations
8
- # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
- # you'll amass, the slower it'll run and the greater likelihood for issues).
10
- #
11
- # It's strongly recommended that you check this file into your version control system.
12
-
13
- ActiveRecord::Schema.define(version: 20170817015810) do
14
-
15
- create_table "productos", force: :cascade do |t|
16
- t.integer "uid"
17
- t.integer "silo"
18
- t.string "nombre"
19
- t.integer "total_acumulado"
20
- t.boolean "bits1"
21
- t.boolean "bits2"
22
- t.float "ffloat"
23
- t.string "variable"
24
- t.datetime "created_at"
25
- t.datetime "updated_at"
26
- end
27
-
28
- create_table "tipos", force: :cascade do |t|
29
- t.string "name"
30
- t.integer "producto_id"
31
- t.datetime "created_at", null: false
32
- t.datetime "updated_at", null: false
33
- t.index ["producto_id"], name: "index_tipos_on_producto_id"
34
- end
35
-
36
- end