gvariant 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gvariant.rb +127 -11
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 474158feb1e3e77fa47defab829eb37de58133ef
4
- data.tar.gz: 54927059812535d1b6f5da8106ff777860a2b047
3
+ metadata.gz: e5fee5e459cf887ec7cb21758f5d5639b2aab9a0
4
+ data.tar.gz: 6217118ee8a4b62eea11b8fa137a6b86a1c4ffca
5
5
  SHA512:
6
- metadata.gz: e96e389ed9f1417987e59a8983a2764612a669628c7518c9a7f8d919fbd81593aca23b59e522240a1a16859c5aa9025ed467f8cbb74703dfa036c64c681535eb
7
- data.tar.gz: 93c4b94b1ad02d59edd8682713b380721928396a63d53fdc4d710c71be48bc5650a2040f0e1df4a5e9a0f767ef437d3c8ae385b46d4d0dd336c9f61708ebcf75
6
+ metadata.gz: da65060d983455ba3611cf0b86de1490ce6276589460783a8ec8ba94d025f7c3dfd71e326e1be07f20160176bc380a9898cfe48da09f4f0813ea6ebf0c746688
7
+ data.tar.gz: 4551f98e735677109f132dfd67229283f1c0dba2d7edaf4d7d4ce9914de223960e242cb0901ae8658ce599b03ae24e8666b8bea6da90f8858f464fa8d88af2a3
data/lib/gvariant.rb CHANGED
@@ -2,7 +2,7 @@ class GVariantBasicType
2
2
  attr_reader :id, :fixed_size, :default_value, :alignment
3
3
 
4
4
  def initialize(id, unpack, alignment, fixed_size, default_value)
5
- @id, @unpack, @alignment, @fixed_size, @default_value =
5
+ @id, @pack_format, @alignment, @fixed_size, @default_value =
6
6
  id, unpack, alignment, fixed_size, default_value
7
7
  end
8
8
 
@@ -10,9 +10,20 @@ class GVariantBasicType
10
10
  (i + @alignment - 1) & ~(@alignment - 1)
11
11
  end
12
12
 
13
+ def pad(buf)
14
+ l = buf.length
15
+ (align(l) - l).times do
16
+ buf.concat(0)
17
+ end
18
+ end
19
+
13
20
  def read(buf)
14
21
  return @default_value if @fixed_size && buf.length != @fixed_size
15
- buf.unpack("#{@unpack}").first
22
+ buf.unpack(@pack_format).first
23
+ end
24
+
25
+ def write(value)
26
+ [value || @default_value].pack(@pack_format)
16
27
  end
17
28
  end
18
29
 
@@ -73,6 +84,10 @@ class GVariantBooleanType < GVariantBasicType
73
84
  b = super(buf)
74
85
  b != false && b != 0
75
86
  end
87
+
88
+ def write(value)
89
+ super((value != 0 && value != false && value != nil) ? 1: 0)
90
+ end
76
91
  end
77
92
 
78
93
  class GVariantStringType < GVariantBasicType
@@ -106,6 +121,16 @@ class GVariantMaybeType < GVariantBasicType
106
121
  @element.read(buf[0..l - 1])
107
122
  end
108
123
  end
124
+
125
+ def write(val)
126
+ if val
127
+ buf = @element.write(val)
128
+ buf.concat(0) unless @element.fixed_size
129
+ buf
130
+ else
131
+ ""
132
+ end
133
+ end
109
134
  end
110
135
 
111
136
  class GVariantVariantType < GVariantBasicType
@@ -117,6 +142,12 @@ class GVariantVariantType < GVariantBasicType
117
142
  value, sep, type = buf[0..buf.length - 1].rpartition("\x00")
118
143
  { type: type, value: GVariant.read(type, value) }
119
144
  end
145
+
146
+ def write(variant)
147
+ buf = GVariant.write(variant[:type], variant[:value])
148
+ buf.concat(0)
149
+ buf << variant[:type]
150
+ end
120
151
  end
121
152
 
122
153
  class GVariantOffsetType < GVariantBasicType
@@ -128,24 +159,47 @@ class GVariantOffsetType < GVariantBasicType
128
159
 
129
160
  def read_offset(buf, n)
130
161
  l = buf.length
162
+ determine_offset_type(l)
163
+ buf.unpack("@#{l + @offset_size * n}#{@offset_pack_format}")[0]
164
+ end
131
165
 
166
+ def write_offsets(buf, offsets)
167
+ return buf if offsets.empty?
168
+ offset_size_prev = nil
169
+ packed_size = 0
170
+ packed = ""
171
+
172
+ loop do
173
+ determine_offset_type(buf.length + packed_size)
174
+ break if @offset_size == offset_size_prev
175
+ offset_size_prev = @offset_size
176
+
177
+ packed_size = offsets.count * @offset_size
178
+ packed = offsets.pack("#{@offset_pack_format}*")
179
+ end
180
+
181
+ buf << packed
182
+ end
183
+
184
+ private
185
+
186
+ def determine_offset_type(l)
132
187
  if @offset_size.nil?
133
188
  if (l < 0xff)
134
189
  @offset_size = 1
135
- @offset_unpack = 'C'
190
+ @offset_pack_format = 'C'
136
191
  elsif (l <= 0xffff)
137
192
  @offset_size = 2
138
- @offset_unpack = 'S'
193
+ @offset_pack_format = 'S'
139
194
  elsif (l < 0xffffffff)
140
195
  @offset_size = 4
141
- @offset_unpack = 'L'
196
+ @offset_pack_format = 'L'
142
197
  else
143
198
  raise ArgumentError.new("Offset range too big.")
144
199
  end
145
200
  end
146
-
147
- buf.unpack("@#{l + @offset_size * n}#{@offset_unpack}")[0]
148
201
  end
202
+
149
203
  end
150
204
 
151
205
  class GVariantDictionaryType < GVariantOffsetType
@@ -177,6 +231,28 @@ class GVariantDictionaryType < GVariantOffsetType
177
231
 
178
232
  Hash[key, value]
179
233
  end
234
+
235
+ def write(vals)
236
+ buf = ""
237
+ offsets = []
238
+
239
+ vals.each_pair do |key, value|
240
+ @key_element.pad(buf)
241
+ buf << @key_element.write(key.to_s)
242
+ unless @key_element.fixed_size
243
+ offsets << buf.length
244
+ end
245
+
246
+ @value_element.pad(buf)
247
+ buf << @value_element.write(value)
248
+ unless @value_element.fixed_size || key == vals.keys.last
249
+ offsets << buf.length
250
+ end
251
+ end
252
+
253
+ write_offsets(buf, offsets)
254
+ buf
255
+ end
180
256
  end
181
257
 
182
258
  class GVariantArrayType < GVariantOffsetType
@@ -215,6 +291,21 @@ class GVariantArrayType < GVariantOffsetType
215
291
 
216
292
  values
217
293
  end
294
+
295
+ def write(vals)
296
+ buf = ""
297
+ offsets = []
298
+
299
+ vals.each do |val|
300
+ v = @element.write(val)
301
+ @element.pad(buf)
302
+ buf << v
303
+ offsets << buf.length
304
+ end
305
+
306
+ write_offsets(buf, offsets) unless @element.fixed_size
307
+ buf
308
+ end
218
309
  end
219
310
 
220
311
  class GVariantTupleType < GVariantOffsetType
@@ -270,6 +361,27 @@ class GVariantTupleType < GVariantOffsetType
270
361
  v
271
362
  end
272
363
  end
364
+
365
+ def write(vals)
366
+ buf = ""
367
+ offsets = []
368
+ o = 0
369
+ i = 0
370
+
371
+ @elements.each do |element|
372
+ b = element.write(vals[i])
373
+ element.pad(buf)
374
+ buf << b
375
+ i += 1
376
+
377
+ o += b.length
378
+ offsets << o unless element.fixed_size || element == @elements.last
379
+ end
380
+
381
+ pad(buf)
382
+ write_offsets(buf, offsets)
383
+ buf
384
+ end
273
385
  end
274
386
 
275
387
  class GVariant
@@ -340,11 +452,15 @@ class GVariant
340
452
  type
341
453
  end
342
454
 
343
- def self.read(typestr, buffer)
344
- buffer = buffer.pack("C*") if buffer.is_a? Array
345
- buffer.freeze if RUBY_VERSION >= '2.1.0'
455
+ def self.read(typestr, buf)
456
+ buf = buf.pack("C*") if buf.is_a? Array
457
+ buf.freeze if RUBY_VERSION >= '2.1.0'
346
458
  type = parse_type(typestr)
347
- type.read(buffer)
459
+ type.read(buf)
348
460
  end
349
461
 
462
+ def self.write(typestr, value)
463
+ type = parse_type(typestr)
464
+ type.write(value)
465
+ end
350
466
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gvariant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Mack
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-10 00:00:00.000000000 Z
11
+ date: 2016-06-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple reader and writer for the GVariant serialization format
14
14
  email: github@zonque.org