active_model_serializers_binary 0.2.0 → 0.2.1

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: 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