gvariant 0.0.1 → 0.1.0

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