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 |
+} |