OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package bindings | |
6 | |
7 import ( | |
8 "encoding/binary" | |
9 "fmt" | |
10 "math" | |
11 | |
12 "mojo/public/go/system" | |
13 ) | |
14 | |
15 // Decoder is a helper to decode mojo complex elements from mojo archive format. | |
16 type Decoder struct { | |
17 // Buffer containing data to decode. | |
18 buf []byte | |
19 | |
20 // Index of the first unclaimed byte in buf. | |
21 end int | |
22 | |
23 // Array containing handles to decode. | |
24 handles []system.UntypedHandle | |
25 | |
26 // The first unclaimed handle index. | |
27 nextHandle int | |
28 | |
29 // A stack of encoding states matching current one-level value stack | |
30 // of the decoding data structure. | |
31 stateStack []encodingState | |
32 } | |
33 | |
34 // NewDecoder returns a decoder that will decode structured data from provided | |
35 // byte array and with handles. | |
36 func NewDecoder(bytes []byte, handles []system.UntypedHandle) *Decoder { | |
37 return &Decoder{buf: bytes, handles: handles} | |
38 } | |
39 | |
40 // claimData claims a block of |size| bytes for a one-level value. | |
41 func (d *Decoder) claimData(size int) error { | |
42 if d.end+size > len(d.buf) { | |
43 return &ValidationError{IllegalMemoryRange, "data buffer is too
small"} | |
44 } | |
45 d.end += size | |
46 return nil | |
47 } | |
48 | |
49 func (d *Decoder) claimHandle(index int) (system.UntypedHandle, error) { | |
50 if index >= len(d.handles) { | |
51 return nil, &ValidationError{IllegalHandle, "trying to access no
n present handle"} | |
52 } | |
53 if index < d.nextHandle { | |
54 return nil, &ValidationError{IllegalHandle, "trying to access ha
ndle out of order"} | |
55 } | |
56 d.nextHandle = index + 1 | |
57 return d.handles[index], nil | |
58 } | |
59 | |
60 func (d *Decoder) popState() { | |
61 if len(d.stateStack) != 0 { | |
62 d.stateStack = d.stateStack[:len(d.stateStack)-1] | |
63 } | |
64 } | |
65 | |
66 func (d *Decoder) pushState(header DataHeader, checkElements bool) error { | |
67 oldEnd := d.end | |
68 if err := d.claimData(int(header.Size - dataHeaderSize)); err != nil { | |
69 return err | |
70 } | |
71 elements := uint32(0) | |
72 if checkElements { | |
73 elements = header.ElementsOrVersion | |
74 } | |
75 d.stateStack = append(d.stateStack, encodingState{ | |
76 offset: oldEnd, | |
77 limit: d.end, | |
78 elements: elements, | |
79 checkElements: checkElements, | |
80 }) | |
81 return nil | |
82 } | |
83 | |
84 // state returns state of the top-level value. | |
85 func (d *Decoder) state() *encodingState { | |
86 if len(d.stateStack) == 0 { | |
87 return nil | |
88 } | |
89 return &d.stateStack[len(d.stateStack)-1] | |
90 } | |
91 | |
92 // StartArray starts decoding an array and reads its data header, | |
93 // returning number of elements declared in data header. | |
94 // Note: it doesn't read a pointer to the encoded array. | |
95 // Call |Finish()| after reading all array elements. | |
96 func (d *Decoder) StartArray(elementBitSize uint32) (uint32, error) { | |
97 header, err := d.readDataHeader() | |
98 if err != nil { | |
99 return 0, err | |
100 } | |
101 minSize := bytesForBits(uint64(header.ElementsOrVersion) * uint64(elemen
tBitSize)) | |
102 if got, want := int(header.Size), dataHeaderSize+minSize; got < want { | |
103 return 0, &ValidationError{UnexpectedArrayHeader, | |
104 fmt.Sprintf("data header size(%d) should be at least %d"
, got, want), | |
105 } | |
106 } | |
107 if err := d.pushState(header, true); err != nil { | |
108 return 0, err | |
109 } | |
110 return header.ElementsOrVersion, nil | |
111 } | |
112 | |
113 // StartMap starts decoding a map and reads its data header. | |
114 // Note: it doesn't read a pointer to the encoded map. | |
115 // Call |Finish()| after reading keys array and values array. | |
116 func (d *Decoder) StartMap() error { | |
117 header, err := d.readDataHeader() | |
118 if err != nil { | |
119 return err | |
120 } | |
121 if header != mapHeader { | |
122 return &ValidationError{UnexpectedStructHeader, | |
123 fmt.Sprintf("invalid map header: %v", header), | |
124 } | |
125 } | |
126 if err := d.pushState(header, false); err != nil { | |
127 return err | |
128 } | |
129 return nil | |
130 } | |
131 | |
132 // StartStruct starts decoding a struct and reads its data header. | |
133 // Returns the read data header. The caller should check if it is valid. | |
134 // Note: it doesn't read a pointer to the encoded struct. | |
135 // Call |Finish()| after reading all fields. | |
136 func (d *Decoder) StartStruct() (DataHeader, error) { | |
137 header, err := d.readDataHeader() | |
138 if err != nil { | |
139 return DataHeader{}, err | |
140 } | |
141 if header.Size < dataHeaderSize { | |
142 return DataHeader{}, &ValidationError{UnexpectedStructHeader, | |
143 fmt.Sprintf("data header size(%d) should be at least %d"
, header.Size, dataHeaderSize), | |
144 } | |
145 } | |
146 if err := d.pushState(header, false); err != nil { | |
147 return DataHeader{}, err | |
148 } | |
149 return header, nil | |
150 } | |
151 | |
152 // StartNestedUnion starts decoding a union. | |
153 // Note: it doesn't read a pointer to the encoded struct or the union header. | |
154 // Call |Finish()| after reading the header and data. | |
155 func (d *Decoder) StartNestedUnion() error { | |
156 // We have to trick pushState into claiming 16 bytes. | |
157 header := DataHeader{uint32(24), uint32(0)} | |
158 if err := d.pushState(header, false); err != nil { | |
159 return err | |
160 } | |
161 return nil | |
162 } | |
163 | |
164 // ReadUnionHeader reads the union header and returns the union's size and tag. | |
165 func (d *Decoder) ReadUnionHeader() (uint32, uint32, error) { | |
166 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
167 return 0, 0, err | |
168 } | |
169 d.state().alignOffsetToBytes() | |
170 d.state().offset = align(d.state().offset, 8) | |
171 size := binary.LittleEndian.Uint32(d.buf[d.state().offset:]) | |
172 tag := binary.LittleEndian.Uint32(d.buf[d.state().offset+4:]) | |
173 d.state().offset += 8 | |
174 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
175 return 0, 0, err | |
176 } | |
177 return size, tag, nil | |
178 } | |
179 | |
180 // FinishReadingUnionValue should be called after the union value has been read | |
181 // in order to indicate to move the decoder past the union value field. | |
182 func (d *Decoder) FinishReadingUnionValue() { | |
183 d.state().offset = align(d.state().offset, 8) | |
184 d.state().alignOffsetToBytes() | |
185 } | |
186 | |
187 // SkipUnionValue skips the union's value. | |
188 func (d *Decoder) SkipUnionValue() { | |
189 d.state().offset += 8 | |
190 d.state().elementsProcessed += 1 | |
191 } | |
192 | |
193 func (d *Decoder) readDataHeader() (DataHeader, error) { | |
194 if err := d.claimData(dataHeaderSize); err != nil { | |
195 return DataHeader{}, err | |
196 } | |
197 oldEnd := d.end - dataHeaderSize | |
198 header := DataHeader{ | |
199 Size: binary.LittleEndian.Uint32(d.buf[oldEnd:]), | |
200 ElementsOrVersion: binary.LittleEndian.Uint32(d.buf[oldEnd+4:]), | |
201 } | |
202 return header, nil | |
203 } | |
204 | |
205 // Finish indicates the decoder that you have finished reading elements of | |
206 // a one-level value. | |
207 func (d *Decoder) Finish() error { | |
208 if d.state() == nil { | |
209 return fmt.Errorf("state stack is empty") | |
210 } | |
211 if d.state().checkElements && d.state().elementsProcessed != d.state().e
lements { | |
212 return fmt.Errorf("unexpected number of elements read: defined i
n header %d, but read %d", d.state().elements, d.state().elementsProcessed) | |
213 } | |
214 d.popState() | |
215 return nil | |
216 } | |
217 | |
218 // ReadBool reads a bool value. | |
219 func (d *Decoder) ReadBool() (bool, error) { | |
220 if err := ensureElementBitSizeAndCapacity(d.state(), 1); err != nil { | |
221 return false, err | |
222 } | |
223 value := ((d.buf[d.state().offset] >> d.state().bitOffset) & 1) == 1 | |
224 d.state().skipBits(1) | |
225 d.state().elementsProcessed++ | |
226 return value, nil | |
227 } | |
228 | |
229 // ReadInt8 reads an int8 value. | |
230 func (d *Decoder) ReadInt8() (int8, error) { | |
231 value, err := d.ReadUint8() | |
232 return int8(value), err | |
233 } | |
234 | |
235 // ReadUint8 reads an uint8 value. | |
236 func (d *Decoder) ReadUint8() (uint8, error) { | |
237 if err := ensureElementBitSizeAndCapacity(d.state(), 8); err != nil { | |
238 return 0, err | |
239 } | |
240 d.state().alignOffsetToBytes() | |
241 value := d.buf[d.state().offset] | |
242 d.state().skipBytes(1) | |
243 d.state().elementsProcessed++ | |
244 return value, nil | |
245 } | |
246 | |
247 // ReadInt16 reads an int16 value. | |
248 func (d *Decoder) ReadInt16() (int16, error) { | |
249 value, err := d.ReadUint16() | |
250 return int16(value), err | |
251 } | |
252 | |
253 // ReadUint16 reads an uint16 value. | |
254 func (d *Decoder) ReadUint16() (uint16, error) { | |
255 if err := ensureElementBitSizeAndCapacity(d.state(), 16); err != nil { | |
256 return 0, err | |
257 } | |
258 d.state().alignOffsetToBytes() | |
259 d.state().offset = align(d.state().offset, 2) | |
260 value := binary.LittleEndian.Uint16(d.buf[d.state().offset:]) | |
261 d.state().skipBytes(2) | |
262 d.state().elementsProcessed++ | |
263 return value, nil | |
264 } | |
265 | |
266 // ReadInt32 reads an int32 value. | |
267 func (d *Decoder) ReadInt32() (int32, error) { | |
268 value, err := d.ReadUint32() | |
269 return int32(value), err | |
270 } | |
271 | |
272 // ReadUint32 reads an uint32 value. | |
273 func (d *Decoder) ReadUint32() (uint32, error) { | |
274 if err := ensureElementBitSizeAndCapacity(d.state(), 32); err != nil { | |
275 return 0, err | |
276 } | |
277 d.state().alignOffsetToBytes() | |
278 d.state().offset = align(d.state().offset, 4) | |
279 value := binary.LittleEndian.Uint32(d.buf[d.state().offset:]) | |
280 d.state().skipBytes(4) | |
281 d.state().elementsProcessed++ | |
282 return value, nil | |
283 } | |
284 | |
285 // ReadInt64 reads an int64 value. | |
286 func (d *Decoder) ReadInt64() (int64, error) { | |
287 value, err := d.ReadUint64() | |
288 return int64(value), err | |
289 } | |
290 | |
291 // ReadUint64 reads an uint64 value. | |
292 func (d *Decoder) ReadUint64() (uint64, error) { | |
293 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
294 return 0, err | |
295 } | |
296 d.state().alignOffsetToBytes() | |
297 d.state().offset = align(d.state().offset, 8) | |
298 value := binary.LittleEndian.Uint64(d.buf[d.state().offset:]) | |
299 d.state().skipBytes(8) | |
300 d.state().elementsProcessed++ | |
301 return value, nil | |
302 } | |
303 | |
304 // ReadFloat32 reads a float32 value. | |
305 func (d *Decoder) ReadFloat32() (float32, error) { | |
306 bits, err := d.ReadUint32() | |
307 return math.Float32frombits(bits), err | |
308 } | |
309 | |
310 // ReadFloat64 reads a float64 value. | |
311 func (d *Decoder) ReadFloat64() (float64, error) { | |
312 bits, err := d.ReadUint64() | |
313 return math.Float64frombits(bits), err | |
314 } | |
315 | |
316 // ReadString reads a string value. It doesn't read a pointer to the encoded | |
317 // string. | |
318 func (d *Decoder) ReadString() (string, error) { | |
319 length, err := d.StartArray(8) | |
320 if err != nil { | |
321 return "", err | |
322 } | |
323 var bytes []byte | |
324 for i := uint32(0); i < length; i++ { | |
325 b, err := d.ReadUint8() | |
326 if err != nil { | |
327 return "", err | |
328 } | |
329 bytes = append(bytes, b) | |
330 } | |
331 if err := d.Finish(); err != nil { | |
332 return "", err | |
333 } | |
334 return string(bytes), nil | |
335 } | |
336 | |
337 // ReadPointer reads a pointer and reassigns first unclaimed byte index if the | |
338 // pointer is not null. | |
339 func (d *Decoder) ReadPointer() (uint64, error) { | |
340 pointer, err := d.ReadUint64() | |
341 if err != nil { | |
342 return pointer, err | |
343 } | |
344 if pointer == 0 { | |
345 return pointer, nil | |
346 } | |
347 | |
348 newEnd := uint64(d.state().offset-8) + pointer | |
349 if pointer >= uint64(len(d.buf)) || newEnd >= uint64(len(d.buf)) { | |
350 return 0, &ValidationError{IllegalPointer, "trying to access out
of range memory"} | |
351 } | |
352 if newEnd < uint64(d.end) { | |
353 return 0, &ValidationError{IllegalMemoryRange, "trying to access
memory out of order"} | |
354 } | |
355 if newEnd%8 != 0 { | |
356 return 0, &ValidationError{MisalignedObject, | |
357 fmt.Sprintf("incorrect pointer data alignment: %d", newE
nd), | |
358 } | |
359 } | |
360 d.claimData(int(newEnd) - d.end) | |
361 return pointer, nil | |
362 } | |
363 | |
364 // ReadUntypedHandle reads an untyped handle. | |
365 func (d *Decoder) ReadUntypedHandle() (system.UntypedHandle, error) { | |
366 handleIndex, err := d.ReadUint32() | |
367 if err != nil { | |
368 return nil, err | |
369 } | |
370 if handleIndex == ^uint32(0) { | |
371 return &InvalidHandle{}, nil | |
372 } | |
373 return d.claimHandle(int(handleIndex)) | |
374 } | |
375 | |
376 // ReadHandle reads a handle. | |
377 func (d *Decoder) ReadHandle() (system.Handle, error) { | |
378 return d.ReadUntypedHandle() | |
379 } | |
380 | |
381 // ReadMessagePipeHandle reads a message pipe handle. | |
382 func (d *Decoder) ReadMessagePipeHandle() (system.MessagePipeHandle, error) { | |
383 if handle, err := d.ReadUntypedHandle(); err != nil { | |
384 return nil, err | |
385 } else { | |
386 return handle.ToMessagePipeHandle(), nil | |
387 } | |
388 } | |
389 | |
390 // ReadConsumerHandle reads a data pipe consumer handle. | |
391 func (d *Decoder) ReadConsumerHandle() (system.ConsumerHandle, error) { | |
392 if handle, err := d.ReadUntypedHandle(); err != nil { | |
393 return nil, err | |
394 } else { | |
395 return handle.ToConsumerHandle(), nil | |
396 } | |
397 } | |
398 | |
399 // ReadProducerHandle reads a data pipe producer handle. | |
400 func (d *Decoder) ReadProducerHandle() (system.ProducerHandle, error) { | |
401 if handle, err := d.ReadUntypedHandle(); err != nil { | |
402 return nil, err | |
403 } else { | |
404 return handle.ToProducerHandle(), nil | |
405 } | |
406 } | |
407 | |
408 // ReadSharedBufferHandle reads a shared buffer handle. | |
409 func (d *Decoder) ReadSharedBufferHandle() (system.SharedBufferHandle, error) { | |
410 if handle, err := d.ReadUntypedHandle(); err != nil { | |
411 return nil, err | |
412 } else { | |
413 return handle.ToSharedBufferHandle(), nil | |
414 } | |
415 } | |
416 | |
417 // ReadInterface reads an encoded interface and returns the message pipe handle. | |
418 // The version field is ignored for now. | |
419 func (d *Decoder) ReadInterface() (system.MessagePipeHandle, error) { | |
420 handle, err := d.ReadMessagePipeHandle() | |
421 if err != nil { | |
422 return nil, err | |
423 } | |
424 d.state().elementsProcessed-- | |
425 if _, err := d.ReadUint32(); err != nil { | |
426 return nil, err | |
427 } | |
428 return handle, nil | |
429 } | |
OLD | NEW |