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 "sort" | |
12 | |
13 "mojo/public/go/system" | |
14 ) | |
15 | |
16 // encodingState has information required to encode/decode a one-level value. | |
17 type encodingState struct { | |
18 // Index of the first unprocessed byte. | |
19 offset int | |
20 | |
21 // Index of the first unprocessed bit of buffer[offset] byte. | |
22 bitOffset uint32 | |
23 | |
24 // Index of the first byte after the claimed buffer block for the curren
t | |
25 // one-level value. | |
26 limit int | |
27 | |
28 // Number of elements declared in the data header for the current one-le
vel | |
29 // value. | |
30 elements uint32 | |
31 | |
32 // Number of elements already encoded/decoded of the current one-level | |
33 // value. | |
34 elementsProcessed uint32 | |
35 | |
36 // Whether the number of elements processed should be checked. | |
37 checkElements bool | |
38 } | |
39 | |
40 func (s *encodingState) alignOffsetToBytes() { | |
41 if s.bitOffset > 0 { | |
42 s.offset++ | |
43 s.bitOffset = 0 | |
44 } | |
45 } | |
46 | |
47 func (s *encodingState) skipBits(count uint32) { | |
48 s.bitOffset += count | |
49 s.offset += int(s.bitOffset >> 3) // equal to s.bitOffset / 8 | |
50 s.bitOffset &= 7 // equal to s.bitOffset % 8 | |
51 } | |
52 | |
53 func (s *encodingState) skipBytes(count int) { | |
54 s.bitOffset = 0 | |
55 s.offset += count | |
56 } | |
57 | |
58 // Encoder is a helper to encode mojo complex elements into mojo archive format. | |
59 type Encoder struct { | |
60 // Buffer containing encoded data. | |
61 buf []byte | |
62 | |
63 // Index of the first unclaimed byte in buf. | |
64 end int | |
65 | |
66 // Array containing encoded handles. | |
67 handles []system.UntypedHandle | |
68 | |
69 // A stack of encoder states matching current one-level value stack | |
70 // of the encoding data structure. | |
71 stateStack []encodingState | |
72 | |
73 // By default encoding is non-deterministic because the encoding of | |
74 // a mojom map does not specify the order of the keys and values. | |
75 // If |deterministic| is true then keys and values will be sorted | |
76 // in ascending key order. | |
77 deterministic bool | |
78 } | |
79 | |
80 func ensureElementBitSizeAndCapacity(state *encodingState, bitSize uint32) error
{ | |
81 if state == nil { | |
82 return fmt.Errorf("empty state stack") | |
83 } | |
84 if state.checkElements && state.elementsProcessed >= state.elements { | |
85 return fmt.Errorf("can't process more than elements defined in h
eader(%d)", state.elements) | |
86 } | |
87 byteSize := bytesForBits(uint64(state.bitOffset + bitSize)) | |
88 if align(state.offset+byteSize, byteSize) > state.limit { | |
89 return fmt.Errorf("buffer size limit exceeded") | |
90 } | |
91 return nil | |
92 } | |
93 | |
94 // claimData claims a block of |size| bytes for a one-level value, resizing | |
95 // buffer if needed. | |
96 func (e *Encoder) claimData(size int) { | |
97 e.end += size | |
98 if e.end < len(e.buf) { | |
99 return | |
100 } | |
101 newLen := e.end | |
102 if l := 2 * len(e.buf); newLen < l { | |
103 newLen = l | |
104 } | |
105 tmp := make([]byte, newLen) | |
106 copy(tmp, e.buf) | |
107 e.buf = tmp | |
108 } | |
109 | |
110 func (e *Encoder) popState() { | |
111 if len(e.stateStack) != 0 { | |
112 e.stateStack = e.stateStack[:len(e.stateStack)-1] | |
113 } | |
114 } | |
115 | |
116 func (e *Encoder) pushState(header DataHeader, checkElements bool) { | |
117 oldEnd := e.end | |
118 e.claimData(align(int(header.Size), defaultAlignment)) | |
119 elements := uint32(0) | |
120 if checkElements { | |
121 elements = header.ElementsOrVersion | |
122 } | |
123 e.stateStack = append(e.stateStack, encodingState{ | |
124 offset: oldEnd, | |
125 limit: e.end, | |
126 elements: elements, | |
127 checkElements: checkElements, | |
128 }) | |
129 } | |
130 | |
131 // state returns encoder state of the top-level value. | |
132 func (e *Encoder) state() *encodingState { | |
133 if len(e.stateStack) == 0 { | |
134 return nil | |
135 } | |
136 return &e.stateStack[len(e.stateStack)-1] | |
137 } | |
138 | |
139 // NewEncoder returns a new instance of encoder. | |
140 func NewEncoder() *Encoder { | |
141 return &Encoder{} | |
142 } | |
143 | |
144 // SetDeterministic sets whether or not this encoder is deterministic. | |
145 // By default encoding is non-deterministic because the encoding of | |
146 // a mojom map does not specify the order of the keys and values. | |
147 // If SetDeterministic(true) is invoked then this encoder will, from then on, | |
148 // have the property that keys and values will be sorted in ascending key order. | |
149 // Warning: This causes encoding to be more expensive. | |
150 func (e *Encoder) SetDeterministic(deterministic bool) { | |
151 e.deterministic = deterministic | |
152 } | |
153 | |
154 func (e *Encoder) Deterministic() bool { | |
155 return e.deterministic | |
156 } | |
157 | |
158 // StartArray starts encoding an array and writes its data header. | |
159 // Note: it doesn't write a pointer to the encoded array. | |
160 // Call |Finish()| after writing all array elements. | |
161 func (e *Encoder) StartArray(length, elementBitSize uint32) { | |
162 dataSize := dataHeaderSize + bytesForBits(uint64(length)*uint64(elementB
itSize)) | |
163 header := DataHeader{uint32(dataSize), length} | |
164 e.pushState(header, true) | |
165 e.writeDataHeader(header) | |
166 } | |
167 | |
168 // StartMap starts encoding a map and writes its data header. | |
169 // Note: it doesn't write a pointer to the encoded map. | |
170 // Call |Finish()| after writing keys array and values array. | |
171 func (e *Encoder) StartMap() { | |
172 e.pushState(mapHeader, false) | |
173 e.writeDataHeader(mapHeader) | |
174 } | |
175 | |
176 // StartStruct starts encoding a struct and writes its data header. | |
177 // Note: it doesn't write a pointer to the encoded struct. | |
178 // Call |Finish()| after writing all fields. | |
179 func (e *Encoder) StartStruct(size, version uint32) { | |
180 dataSize := dataHeaderSize + int(size) | |
181 header := DataHeader{uint32(dataSize), version} | |
182 e.pushState(header, false) | |
183 e.writeDataHeader(header) | |
184 } | |
185 | |
186 // StartNestedUnion starts encoding a nested union. | |
187 // Note: it doesn't write a pointer or a union header. | |
188 // Call |Finish()| after writing all fields. | |
189 func (e *Encoder) StartNestedUnion() { | |
190 header := DataHeader{uint32(16), uint32(0)} | |
191 e.pushState(header, false) | |
192 } | |
193 | |
194 func (e *Encoder) writeDataHeader(header DataHeader) { | |
195 binary.LittleEndian.PutUint32(e.buf[e.state().offset:], header.Size) | |
196 binary.LittleEndian.PutUint32(e.buf[e.state().offset+4:], header.Element
sOrVersion) | |
197 e.state().offset += 8 | |
198 } | |
199 | |
200 // WriteUnionHeader writes a union header for a non-null union. | |
201 // (See. WriteNullUnion) | |
202 func (e *Encoder) WriteUnionHeader(tag uint32) error { | |
203 if err := ensureElementBitSizeAndCapacity(e.state(), 64); err != nil { | |
204 return err | |
205 } | |
206 e.state().alignOffsetToBytes() | |
207 e.state().offset = align(e.state().offset, 8) | |
208 binary.LittleEndian.PutUint32(e.buf[e.state().offset:], 16) | |
209 binary.LittleEndian.PutUint32(e.buf[e.state().offset+4:], tag) | |
210 e.state().offset += 8 | |
211 if err := ensureElementBitSizeAndCapacity(e.state(), 64); err != nil { | |
212 return err | |
213 } | |
214 return nil | |
215 } | |
216 | |
217 // FinishWritingUnionValue should call after the union value has been read in | |
218 // order to indicate to move the encoder past the union value field. | |
219 func (e *Encoder) FinishWritingUnionValue() { | |
220 e.state().offset = align(e.state().offset, 8) | |
221 e.state().alignOffsetToBytes() | |
222 } | |
223 | |
224 // Finish indicates the encoder that you have finished writing elements of | |
225 // a one-level value. | |
226 func (e *Encoder) Finish() error { | |
227 if e.state() == nil { | |
228 return fmt.Errorf("state stack is empty") | |
229 } | |
230 if e.state().checkElements && e.state().elementsProcessed != e.state().e
lements { | |
231 return fmt.Errorf("unexpected number of elements written: define
d in header %d, but written %d", e.state().elements, e.state().elementsProcessed
) | |
232 } | |
233 e.popState() | |
234 return nil | |
235 } | |
236 | |
237 // Data returns an encoded message with attached handles. | |
238 // Call this method after finishing encoding of a value. | |
239 func (e *Encoder) Data() ([]byte, []system.UntypedHandle, error) { | |
240 if len(e.stateStack) != 0 { | |
241 return nil, nil, fmt.Errorf("can't return data when encoder has
non-empty state stack") | |
242 } | |
243 return e.buf[:e.end], e.handles, nil | |
244 } | |
245 | |
246 // WriteBool writes a bool value. | |
247 func (e *Encoder) WriteBool(value bool) error { | |
248 if err := ensureElementBitSizeAndCapacity(e.state(), 1); err != nil { | |
249 return err | |
250 } | |
251 if value { | |
252 e.buf[e.state().offset] |= 1 << e.state().bitOffset | |
253 } | |
254 e.state().skipBits(1) | |
255 e.state().elementsProcessed++ | |
256 return nil | |
257 } | |
258 | |
259 // WriteBool writes an int8 value. | |
260 func (e *Encoder) WriteInt8(value int8) error { | |
261 return e.WriteUint8(uint8(value)) | |
262 } | |
263 | |
264 // WriteUint8 writes an uint8 value. | |
265 func (e *Encoder) WriteUint8(value uint8) error { | |
266 if err := ensureElementBitSizeAndCapacity(e.state(), 8); err != nil { | |
267 return err | |
268 } | |
269 e.state().alignOffsetToBytes() | |
270 e.buf[e.state().offset] = value | |
271 e.state().skipBytes(1) | |
272 e.state().elementsProcessed++ | |
273 return nil | |
274 } | |
275 | |
276 // WriteInt16 writes an int16 value. | |
277 func (e *Encoder) WriteInt16(value int16) error { | |
278 return e.WriteUint16(uint16(value)) | |
279 } | |
280 | |
281 // WriteUint16 writes an uint16 value. | |
282 func (e *Encoder) WriteUint16(value uint16) error { | |
283 if err := ensureElementBitSizeAndCapacity(e.state(), 16); err != nil { | |
284 return err | |
285 } | |
286 e.state().alignOffsetToBytes() | |
287 e.state().offset = align(e.state().offset, 2) | |
288 binary.LittleEndian.PutUint16(e.buf[e.state().offset:], value) | |
289 e.state().skipBytes(2) | |
290 e.state().elementsProcessed++ | |
291 return nil | |
292 } | |
293 | |
294 // WriteInt32 writes an int32 value. | |
295 func (e *Encoder) WriteInt32(value int32) error { | |
296 return e.WriteUint32(uint32(value)) | |
297 } | |
298 | |
299 // WriteUint32 writes an uint32 value. | |
300 func (e *Encoder) WriteUint32(value uint32) error { | |
301 if err := ensureElementBitSizeAndCapacity(e.state(), 32); err != nil { | |
302 return err | |
303 } | |
304 e.state().alignOffsetToBytes() | |
305 e.state().offset = align(e.state().offset, 4) | |
306 binary.LittleEndian.PutUint32(e.buf[e.state().offset:], value) | |
307 e.state().skipBytes(4) | |
308 e.state().elementsProcessed++ | |
309 return nil | |
310 } | |
311 | |
312 // WriteInt64 writes an int64 value. | |
313 func (e *Encoder) WriteInt64(value int64) error { | |
314 return e.WriteUint64(uint64(value)) | |
315 } | |
316 | |
317 // WriteUint64 writes an uint64 value. | |
318 func (e *Encoder) WriteUint64(value uint64) error { | |
319 if err := ensureElementBitSizeAndCapacity(e.state(), 64); err != nil { | |
320 return err | |
321 } | |
322 e.state().alignOffsetToBytes() | |
323 e.state().offset = align(e.state().offset, 8) | |
324 binary.LittleEndian.PutUint64(e.buf[e.state().offset:], value) | |
325 e.state().skipBytes(8) | |
326 e.state().elementsProcessed++ | |
327 return nil | |
328 } | |
329 | |
330 // WriteFloat32 writes a float32 value. | |
331 func (e *Encoder) WriteFloat32(value float32) error { | |
332 return e.WriteUint32(math.Float32bits(value)) | |
333 } | |
334 | |
335 // WriteFloat64 writes a float64 value. | |
336 func (e *Encoder) WriteFloat64(value float64) error { | |
337 return e.WriteUint64(math.Float64bits(value)) | |
338 } | |
339 | |
340 // WriteNullUnion writes a null union. | |
341 func (e *Encoder) WriteNullUnion() error { | |
342 if err := e.WriteUint64(0); err != nil { | |
343 return err | |
344 } | |
345 e.state().elementsProcessed-- | |
346 return e.WriteUint64(0) | |
347 } | |
348 | |
349 // WriteNullPointer writes a null pointer. | |
350 func (e *Encoder) WriteNullPointer() error { | |
351 return e.WriteUint64(0) | |
352 } | |
353 | |
354 // WriteString writes a string value. It doesn't write a pointer to the encoded | |
355 // string. | |
356 func (e *Encoder) WriteString(value string) error { | |
357 bytes := []byte(value) | |
358 e.StartArray(uint32(len(bytes)), 8) | |
359 for _, b := range bytes { | |
360 if err := e.WriteUint8(b); err != nil { | |
361 return err | |
362 } | |
363 } | |
364 return e.Finish() | |
365 } | |
366 | |
367 // WritePointer writes a pointer to first unclaimed byte index. | |
368 func (e *Encoder) WritePointer() error { | |
369 e.state().alignOffsetToBytes() | |
370 e.state().offset = align(e.state().offset, 8) | |
371 return e.WriteUint64(uint64(e.end - e.state().offset)) | |
372 } | |
373 | |
374 // WriteInvalidHandle an invalid handle. | |
375 func (e *Encoder) WriteInvalidHandle() error { | |
376 return e.WriteInt32(-1) | |
377 } | |
378 | |
379 // WriteHandle writes a handle and invalidates the passed handle object. | |
380 func (e *Encoder) WriteHandle(handle system.Handle) error { | |
381 if !handle.IsValid() { | |
382 return fmt.Errorf("can't write an invalid handle") | |
383 } | |
384 UntypedHandle := handle.ToUntypedHandle() | |
385 e.handles = append(e.handles, UntypedHandle) | |
386 return e.WriteUint32(uint32(len(e.handles) - 1)) | |
387 } | |
388 | |
389 // WriteInvalidInterface writes an invalid interface. | |
390 func (e *Encoder) WriteInvalidInterface() error { | |
391 if err := e.WriteInvalidHandle(); err != nil { | |
392 return err | |
393 } | |
394 e.state().elementsProcessed-- | |
395 return e.WriteUint32(0) | |
396 } | |
397 | |
398 // WriteInterface writes an interface and invalidates the passed handle object. | |
399 func (e *Encoder) WriteInterface(handle system.Handle) error { | |
400 if err := e.WriteHandle(handle); err != nil { | |
401 return err | |
402 } | |
403 e.state().elementsProcessed-- | |
404 // Set the version field to 0 for now. | |
405 return e.WriteUint32(0) | |
406 } | |
407 | |
408 // SortMapKeys will sort the slice pointed to by |slicePointer| | |
409 // if |slicePointer| is a pointer to a slice of a type that | |
410 // may be the key of a Mojo map. Otherwise SortMapKeys will do nothing. | |
411 func SortMapKeys(slicePointer interface{}) { | |
412 switch slicePointer := slicePointer.(type) { | |
413 case *[]bool: | |
414 sort.Sort(boolSlice(*slicePointer)) | |
415 case *[]float32: | |
416 sort.Sort(float32Slice(*slicePointer)) | |
417 case *[]float64: | |
418 sort.Float64s(*slicePointer) | |
419 case *[]int: | |
420 sort.Ints(*slicePointer) | |
421 case *[]int8: | |
422 sort.Sort(int8Slice(*slicePointer)) | |
423 case *[]int16: | |
424 sort.Sort(int16Slice(*slicePointer)) | |
425 case *[]int32: | |
426 sort.Sort(int32Slice(*slicePointer)) | |
427 case *[]int64: | |
428 sort.Sort(int64Slice(*slicePointer)) | |
429 case *[]string: | |
430 sort.Strings(*slicePointer) | |
431 case *[]uint8: | |
432 sort.Sort(uint8Slice(*slicePointer)) | |
433 case *[]uint16: | |
434 sort.Sort(uint16Slice(*slicePointer)) | |
435 case *[]uint32: | |
436 sort.Sort(uint32Slice(*slicePointer)) | |
437 case *[]uint64: | |
438 sort.Sort(uint64Slice(*slicePointer)) | |
439 default: | |
440 // Note(rudominer) Currently enums may not be used as map keys b
ut | |
441 // that may change in the future in which case we should handle
them | |
442 // here. | |
443 } | |
444 } | |
445 | |
446 // boolSlice | |
447 type boolSlice []bool | |
448 | |
449 func (s boolSlice) Len() int { | |
450 return len(s) | |
451 } | |
452 | |
453 func (s boolSlice) Less(i, j int) bool { | |
454 return s[i] && !s[j] | |
455 } | |
456 | |
457 func (s boolSlice) Swap(i, j int) { | |
458 s[i], s[j] = s[j], s[i] | |
459 } | |
460 | |
461 // float32Slice | |
462 type float32Slice []float32 | |
463 | |
464 func (s float32Slice) Len() int { | |
465 return len(s) | |
466 } | |
467 | |
468 func (s float32Slice) Less(i, j int) bool { | |
469 return s[i] < s[j] | |
470 } | |
471 | |
472 func (s float32Slice) Swap(i, j int) { | |
473 s[i], s[j] = s[j], s[i] | |
474 } | |
475 | |
476 // int8Slice | |
477 type int8Slice []int8 | |
478 | |
479 func (s int8Slice) Len() int { | |
480 return len(s) | |
481 } | |
482 | |
483 func (s int8Slice) Less(i, j int) bool { | |
484 return s[i] < s[j] | |
485 } | |
486 | |
487 func (s int8Slice) Swap(i, j int) { | |
488 s[i], s[j] = s[j], s[i] | |
489 } | |
490 | |
491 // int16Slice | |
492 type int16Slice []int16 | |
493 | |
494 func (s int16Slice) Len() int { | |
495 return len(s) | |
496 } | |
497 | |
498 func (s int16Slice) Less(i, j int) bool { | |
499 return s[i] < s[j] | |
500 } | |
501 | |
502 func (s int16Slice) Swap(i, j int) { | |
503 s[i], s[j] = s[j], s[i] | |
504 } | |
505 | |
506 // int32Slice | |
507 type int32Slice []int32 | |
508 | |
509 func (s int32Slice) Len() int { | |
510 return len(s) | |
511 } | |
512 | |
513 func (s int32Slice) Less(i, j int) bool { | |
514 return s[i] < s[j] | |
515 } | |
516 | |
517 func (s int32Slice) Swap(i, j int) { | |
518 s[i], s[j] = s[j], s[i] | |
519 } | |
520 | |
521 // int64Slice | |
522 type int64Slice []int64 | |
523 | |
524 func (s int64Slice) Len() int { | |
525 return len(s) | |
526 } | |
527 | |
528 func (s int64Slice) Less(i, j int) bool { | |
529 return s[i] < s[j] | |
530 } | |
531 | |
532 func (s int64Slice) Swap(i, j int) { | |
533 s[i], s[j] = s[j], s[i] | |
534 } | |
535 | |
536 // uint8Slice | |
537 type uint8Slice []uint8 | |
538 | |
539 func (s uint8Slice) Len() int { | |
540 return len(s) | |
541 } | |
542 | |
543 func (s uint8Slice) Less(i, j int) bool { | |
544 return s[i] < s[j] | |
545 } | |
546 | |
547 func (s uint8Slice) Swap(i, j int) { | |
548 s[i], s[j] = s[j], s[i] | |
549 } | |
550 | |
551 // uint16Slice | |
552 type uint16Slice []uint16 | |
553 | |
554 func (s uint16Slice) Len() int { | |
555 return len(s) | |
556 } | |
557 | |
558 func (s uint16Slice) Less(i, j int) bool { | |
559 return s[i] < s[j] | |
560 } | |
561 | |
562 func (s uint16Slice) Swap(i, j int) { | |
563 s[i], s[j] = s[j], s[i] | |
564 } | |
565 | |
566 // uint32Slice | |
567 type uint32Slice []uint32 | |
568 | |
569 func (s uint32Slice) Len() int { | |
570 return len(s) | |
571 } | |
572 | |
573 func (s uint32Slice) Less(i, j int) bool { | |
574 return s[i] < s[j] | |
575 } | |
576 | |
577 func (s uint32Slice) Swap(i, j int) { | |
578 s[i], s[j] = s[j], s[i] | |
579 } | |
580 | |
581 // uint64Slice | |
582 type uint64Slice []uint64 | |
583 | |
584 func (s uint64Slice) Len() int { | |
585 return len(s) | |
586 } | |
587 | |
588 func (s uint64Slice) Less(i, j int) bool { | |
589 return s[i] < s[j] | |
590 } | |
591 | |
592 func (s uint64Slice) Swap(i, j int) { | |
593 s[i], s[j] = s[j], s[i] | |
594 } | |
OLD | NEW |