summaryrefslogtreecommitdiffstats
path: root/third_party/mojo/src/mojo/public/go/bindings/message.go
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/mojo/src/mojo/public/go/bindings/message.go')
-rw-r--r--third_party/mojo/src/mojo/public/go/bindings/message.go164
1 files changed, 164 insertions, 0 deletions
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 0000000..786ec47
--- /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
+}