| Index: third_party/mojo/src/mojo/public/go/bindings/message.go
|
| diff --git a/third_party/mojo/src/mojo/public/go/bindings/message.go b/third_party/mojo/src/mojo/public/go/bindings/message.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..786ec470fedf0468fce10dbaaffe2d15ee676b6a
|
| --- /dev/null
|
| +++ b/third_party/mojo/src/mojo/public/go/bindings/message.go
|
| @@ -0,0 +1,164 @@
|
| +// 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 (
|
| + "fmt"
|
| +
|
| + "mojo/public/go/system"
|
| +)
|
| +
|
| +const (
|
| + // Flag for a header of a simple message.
|
| + MessageNoFlag = 0
|
| +
|
| + // Flag for a header of a message that expected a response.
|
| + MessageExpectsResponseFlag = 1 << 0
|
| +
|
| + // Flag for a header of a message that is a response.
|
| + MessageIsResponseFlag = 1 << 1
|
| +
|
| + dataHeaderSize = 8
|
| + defaultAlignment = 8
|
| + pointerBitSize = 64
|
| +)
|
| +
|
| +var mapHeader DataHeader
|
| +
|
| +func init() {
|
| + mapHeader = DataHeader{24, 2}
|
| +}
|
| +
|
| +// Payload is an interface implemented by a mojo struct that can encode/decode
|
| +// itself into mojo archive format.
|
| +type Payload interface {
|
| + Encode(encoder *Encoder) error
|
| + Decode(decoder *Decoder) error
|
| +}
|
| +
|
| +// DataHeader is a header for a mojo complex element.
|
| +type DataHeader struct {
|
| + Size uint32
|
| + Elements uint32
|
| +}
|
| +
|
| +// MessageHeader is a header information for a message.
|
| +type MessageHeader struct {
|
| + Type uint32
|
| + Flags uint32
|
| + RequestId uint64
|
| +}
|
| +
|
| +func (h *MessageHeader) Encode(encoder *Encoder) error {
|
| + encoder.StartStruct(h.dataSize(), h.numFields())
|
| + if err := encoder.WriteUint32(h.Type); err != nil {
|
| + return err
|
| + }
|
| + if err := encoder.WriteUint32(h.Flags); err != nil {
|
| + return err
|
| + }
|
| + if h.RequestId != 0 {
|
| + if err := encoder.WriteUint64(h.RequestId); err != nil {
|
| + return err
|
| + }
|
| + }
|
| + return encoder.Finish()
|
| +}
|
| +
|
| +func (h *MessageHeader) Decode(decoder *Decoder) error {
|
| + numFields, err := decoder.StartStruct()
|
| + if err != nil {
|
| + return err
|
| + }
|
| + if numFields < 2 || numFields > 3 {
|
| + return fmt.Errorf("Invalid message header: it should have 2 or 3 fileds, but has %d", numFields)
|
| + }
|
| + if h.Type, err = decoder.ReadUint32(); err != nil {
|
| + return err
|
| + }
|
| + if h.Flags, err = decoder.ReadUint32(); err != nil {
|
| + return err
|
| + }
|
| + if numFields == 3 {
|
| + if h.Flags != MessageExpectsResponseFlag && h.Flags != MessageIsResponseFlag {
|
| + return fmt.Errorf("Message header flags(%v) should be MessageExpectsResponseFlag or MessageIsResponseFlag", h.Flags)
|
| + }
|
| + if h.RequestId, err = decoder.ReadUint64(); err != nil {
|
| + return err
|
| + }
|
| + } else {
|
| + if h.Flags != MessageNoFlag {
|
| + return fmt.Errorf("Message header flags(%v) should be MessageNoFlag", h.Flags)
|
| + }
|
| + }
|
| + return decoder.Finish()
|
| +}
|
| +
|
| +func (h *MessageHeader) dataSize() uint32 {
|
| + var size uint32
|
| + size = 2 * 4
|
| + if h.RequestId != 0 {
|
| + size += 8
|
| + }
|
| + return size
|
| +}
|
| +
|
| +func (h *MessageHeader) numFields() uint32 {
|
| + if h.RequestId != 0 {
|
| + return 3
|
| + } else {
|
| + return 2
|
| + }
|
| +}
|
| +
|
| +// Message is a a raw message to be sent/received from a message pipe handle
|
| +// which contains a message header.
|
| +type Message struct {
|
| + Header MessageHeader
|
| + Bytes []byte
|
| + Handles []system.UntypedHandle
|
| + Payload []byte
|
| +}
|
| +
|
| +func newMessage(header MessageHeader, bytes []byte, handles []system.UntypedHandle) *Message {
|
| + return &Message{header, bytes, handles, bytes[header.dataSize()+dataHeaderSize:]}
|
| +}
|
| +
|
| +// DecodePayload decodes the provided payload from the message.
|
| +func (m *Message) DecodePayload(payload Payload) error {
|
| + decoder := NewDecoder(m.Payload, m.Handles)
|
| + if err := payload.Decode(decoder); err != nil {
|
| + return err
|
| + }
|
| + return nil
|
| +}
|
| +
|
| +// EncodeMessage returns a message with provided header that has provided
|
| +// payload encoded in mojo archive format.
|
| +func EncodeMessage(header MessageHeader, payload Payload) (*Message, error) {
|
| + encoder := NewEncoder()
|
| + if err := header.Encode(encoder); err != nil {
|
| + return nil, err
|
| + }
|
| + if err := payload.Encode(encoder); err != nil {
|
| + return nil, err
|
| + }
|
| + if bytes, handles, err := encoder.Data(); err != nil {
|
| + return nil, err
|
| + } else {
|
| + return newMessage(header, bytes, handles), nil
|
| + }
|
| +}
|
| +
|
| +// ParseMessage parses message header from byte buffer with attached handles
|
| +// and returnes parsed message.
|
| +func ParseMessage(bytes []byte, handles []system.UntypedHandle) (*Message, error) {
|
| + decoder := NewDecoder(bytes, []system.UntypedHandle{})
|
| + var header MessageHeader
|
| + if err := header.Decode(decoder); err != nil {
|
| + return nil, err
|
| + }
|
| + return newMessage(header, bytes, handles), nil
|
| +}
|
|
|