Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(515)

Unified Diff: third_party/mojo/src/mojo/public/go/bindings/decoder.go

Issue 883843002: Update mojo sdk to rev 126532ce21c5c3c55a1e1693731411cb60169efd (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Response to review Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/mojo/src/mojo/public/go/bindings/decoder.go
diff --git a/third_party/mojo/src/mojo/public/go/bindings/decoder.go b/third_party/mojo/src/mojo/public/go/bindings/decoder.go
new file mode 100644
index 0000000000000000000000000000000000000000..2dccd0ad99230ee81f32ee533d341d189c95a1ba
--- /dev/null
+++ b/third_party/mojo/src/mojo/public/go/bindings/decoder.go
@@ -0,0 +1,315 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package bindings
+
+import (
+ "encoding/binary"
+ "fmt"
+ "math"
+
+ "mojo/public/go/system"
+)
+
+// Decoder is a helper to decode mojo complex elements from mojo archive format.
+type Decoder struct {
+ // Buffer containing data to decode.
+ buf []byte
+
+ // Index of the first unclaimed byte in buf.
+ end int
+
+ // Array containing handles to decode.
+ handles []system.UntypedHandle
+
+ // The first unclaimed handle index.
+ nextHandle int
+
+ // A stack of encoding states matching current one-level value stack
+ // of the decoding data structure.
+ stateStack []encodingState
+}
+
+// NewDecoder returns a decoder that will decode structured data from provided
+// byte array and with handles.
+func NewDecoder(bytes []byte, handles []system.UntypedHandle) *Decoder {
+ return &Decoder{buf: bytes, handles: handles}
+}
+
+// claimData claims a block of |size| bytes for a one-level value.
+func (d *Decoder) claimData(size int) error {
+ if d.end+size > len(d.buf) {
+ return fmt.Errorf("data buffer is too small")
+ }
+ d.end += size
+ return nil
+}
+
+func (d *Decoder) claimHandle(index int) (system.UntypedHandle, error) {
+ if index >= len(d.handles) {
+ return nil, fmt.Errorf("trying to access non present handle")
+ }
+ if index < d.nextHandle {
+ return nil, fmt.Errorf("trying to access handle out of order")
+ }
+ d.nextHandle = index + 1
+ return d.handles[index], nil
+}
+
+func (d *Decoder) popState() {
+ if len(d.stateStack) != 0 {
+ d.stateStack = d.stateStack[:len(d.stateStack)-1]
+ }
+}
+
+func (d *Decoder) pushState(header DataHeader, elementBitSize uint32) error {
+ oldEnd := d.end
+ if err := d.claimData(int(header.Size - dataHeaderSize)); err != nil {
+ return err
+ }
+ d.stateStack = append(d.stateStack, encodingState{
+ offset: oldEnd,
+ limit: d.end,
+ elementBitSize: elementBitSize,
+ elements: header.Elements,
+ })
+ return nil
+}
+
+// state returns state of the top-level value.
+func (d *Decoder) state() *encodingState {
+ if len(d.stateStack) == 0 {
+ return nil
+ }
+ return &d.stateStack[len(d.stateStack)-1]
+}
+
+// StartArray starts decoding an array and reads its data header,
+// returning number of elements declared in data header.
+// Note: it doesn't read a pointer to the encoded array.
+// Call |Finish()| after reading all array elements.
+func (d *Decoder) StartArray(elementBitSize uint32) (uint32, error) {
+ header, err := d.readDataHeader()
+ if err != nil {
+ return 0, err
+ }
+ if got, want := int(header.Size), dataHeaderSize+bytesForBits(uint64(header.Elements)*uint64(elementBitSize)); got < want {
+ return 0, fmt.Errorf("data header size is too small: is %d, but should be at least %d", got, want)
+ }
+ if err := d.pushState(header, elementBitSize); err != nil {
+ return 0, err
+ }
+ return header.Elements, nil
+}
+
+// StartMap starts decoding a map and reads its data header.
+// Note: it doesn't read a pointer to the encoded map.
+// Call |Finish()| after reading keys array and values array.
+func (d *Decoder) StartMap() error {
+ header, err := d.readDataHeader()
+ if err != nil {
+ return err
+ }
+ if header != mapHeader {
+ return fmt.Errorf("invalid map header: %v", header)
+ }
+ if err := d.pushState(header, pointerBitSize); err != nil {
+ return err
+ }
+ return nil
+}
+
+// StartArray starts decoding a struct and reads its data header,
+// returning number of fields declared in data header.
+// Note: it doesn't read a pointer to the encoded struct.
+// Call |Finish()| after reading all fields.
+func (d *Decoder) StartStruct() (uint32, error) {
+ header, err := d.readDataHeader()
+ if err != nil {
+ return 0, err
+ }
+ if header.Size < dataHeaderSize {
+ return 0, fmt.Errorf("data header size is too small: is %d, but should be at least %d", header.Size, dataHeaderSize)
+ }
+ if err := d.pushState(header, 0); err != nil {
+ return 0, err
+ }
+ return header.Elements, nil
+}
+
+func (d *Decoder) readDataHeader() (DataHeader, error) {
+ if err := d.claimData(dataHeaderSize); err != nil {
+ return DataHeader{}, err
+ }
+ oldEnd := d.end - dataHeaderSize
+ header := DataHeader{
+ Size: binary.LittleEndian.Uint32(d.buf[oldEnd:]),
+ Elements: binary.LittleEndian.Uint32(d.buf[oldEnd+4:]),
+ }
+ return header, nil
+}
+
+// Finish indicates the decoder that you have finished reading elements of
+// a one-level value.
+func (d *Decoder) Finish() error {
+ if d.state() == nil {
+ return fmt.Errorf("state stack is empty")
+ }
+ if d.state().elementBitSize != 0 && d.state().elementsProcessed != d.state().elements {
+ return fmt.Errorf("unexpected number of elements read: defined in header %d, but read %d", d.state().elements, d.state().elementsProcessed)
+ }
+ d.popState()
+ return nil
+}
+
+// ReadBool reads a bool value.
+func (d *Decoder) ReadBool() (bool, error) {
+ if err := ensureElementBitSizeAndCapacity(d.state(), 1); err != nil {
+ return false, err
+ }
+ value := ((d.buf[d.state().offset] >> d.state().bitOffset) & 1) == 1
+ d.state().skipBits(1)
+ d.state().elementsProcessed++
+ return value, nil
+}
+
+// ReadInt8 reads an int8 value.
+func (d *Decoder) ReadInt8() (int8, error) {
+ value, err := d.ReadUint8()
+ return int8(value), err
+}
+
+// ReadUint8 reads an uint8 value.
+func (d *Decoder) ReadUint8() (uint8, error) {
+ if err := ensureElementBitSizeAndCapacity(d.state(), 8); err != nil {
+ return 0, err
+ }
+ value := d.buf[d.state().offset]
+ d.state().skipBytes(1)
+ d.state().elementsProcessed++
+ return value, nil
+}
+
+// ReadInt16 reads an int16 value.
+func (d *Decoder) ReadInt16() (int16, error) {
+ value, err := d.ReadUint16()
+ return int16(value), err
+}
+
+// ReadUint16 reads an uint16 value.
+func (d *Decoder) ReadUint16() (uint16, error) {
+ if err := ensureElementBitSizeAndCapacity(d.state(), 16); err != nil {
+ return 0, err
+ }
+ d.state().offset = align(d.state().offset, 2)
+ value := binary.LittleEndian.Uint16(d.buf[d.state().offset:])
+ d.state().skipBytes(2)
+ d.state().elementsProcessed++
+ return value, nil
+}
+
+// ReadInt32 reads an int32 value.
+func (d *Decoder) ReadInt32() (int32, error) {
+ value, err := d.ReadUint32()
+ return int32(value), err
+}
+
+// ReadUint32 reads an uint32 value.
+func (d *Decoder) ReadUint32() (uint32, error) {
+ if err := ensureElementBitSizeAndCapacity(d.state(), 32); err != nil {
+ return 0, err
+ }
+ d.state().offset = align(d.state().offset, 4)
+ value := binary.LittleEndian.Uint32(d.buf[d.state().offset:])
+ d.state().skipBytes(4)
+ d.state().elementsProcessed++
+ return value, nil
+}
+
+// ReadInt64 reads an int64 value.
+func (d *Decoder) ReadInt64() (int64, error) {
+ value, err := d.ReadUint64()
+ return int64(value), err
+}
+
+// ReadUint64 reads an uint64 value.
+func (d *Decoder) ReadUint64() (uint64, error) {
+ if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil {
+ return 0, err
+ }
+ d.state().offset = align(d.state().offset, 8)
+ value := binary.LittleEndian.Uint64(d.buf[d.state().offset:])
+ d.state().skipBytes(8)
+ d.state().elementsProcessed++
+ return value, nil
+}
+
+// ReadFloat32 reads a float32 value.
+func (d *Decoder) ReadFloat32() (float32, error) {
+ bits, err := d.ReadUint32()
+ return math.Float32frombits(bits), err
+}
+
+// ReadFloat64 reads a float64 value.
+func (d *Decoder) ReadFloat64() (float64, error) {
+ bits, err := d.ReadUint64()
+ return math.Float64frombits(bits), err
+}
+
+// ReadString reads a string value. It doesn't read a pointer to the encoded
+// string.
+func (d *Decoder) ReadString() (string, error) {
+ length, err := d.StartArray(8)
+ if err != nil {
+ return "", err
+ }
+ var bytes []byte
+ for i := uint32(0); i < length; i++ {
+ b, err := d.ReadUint8()
+ if err != nil {
+ return "", err
+ }
+ bytes = append(bytes, b)
+ }
+ if err := d.Finish(); err != nil {
+ return "", err
+ }
+ return string(bytes), nil
+}
+
+// ReadPointer reads a pointer and reassigns first unclaimed byte index if the
+// pointer is not null.
+func (d *Decoder) ReadPointer() (uint64, error) {
+ oldEnd := d.state().offset
+ pointer, err := d.ReadUint64()
+ if err != nil {
+ return pointer, err
+ }
+ if pointer == 0 {
+ return pointer, nil
+ }
+
+ newEnd := uint64(oldEnd) + pointer
+ if newEnd >= uint64(len(d.buf)) {
+ return 0, fmt.Errorf("trying to access out of range memory")
+ }
+ if newEnd < uint64(d.end) {
+ return 0, fmt.Errorf("trying to access memory out of order")
+ }
+ if newEnd%8 != 0 {
+ return 0, fmt.Errorf("incorrect pointer data alignment: %d", newEnd)
+ }
+ d.claimData(d.end - int(newEnd))
+ return pointer, nil
+}
+
+// ReadMessagePipeHandle reads a message pipe handle.
+func (d *Decoder) ReadMessagePipeHandle() (system.MessagePipeHandle, error) {
+ handleIndex, err := d.ReadUint32()
+ if err != nil {
+ return nil, err
+ }
+ untypedHandle, err := d.claimHandle(int(handleIndex))
+ return untypedHandle.ToMessagePipeHandle(), err
+}
« no previous file with comments | « third_party/mojo/src/mojo/public/dart/src/stub.dart ('k') | third_party/mojo/src/mojo/public/go/bindings/encoder.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698