seba-365 - implemented dep
Change-Id: Ia6226d50e7615935a0c8876809a687427ff88c22
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/network/wiremessage/msg.go b/vendor/github.com/mongodb/mongo-go-driver/x/network/wiremessage/msg.go
new file mode 100644
index 0000000..07f35ab
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/network/wiremessage/msg.go
@@ -0,0 +1,298 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package wiremessage
+
+import (
+ "errors"
+
+ "github.com/mongodb/mongo-go-driver/bson"
+ "github.com/mongodb/mongo-go-driver/x/bsonx"
+)
+
+// Msg represents the OP_MSG message of the MongoDB wire protocol.
+type Msg struct {
+ MsgHeader Header
+ FlagBits MsgFlag
+ Sections []Section
+ Checksum uint32
+}
+
+// MarshalWireMessage implements the Marshaler and WireMessage interfaces.
+func (m Msg) MarshalWireMessage() ([]byte, error) {
+ b := make([]byte, 0, m.Len())
+ return m.AppendWireMessage(b)
+}
+
+// ValidateWireMessage implements the Validator and WireMessage interfaces.
+func (m Msg) ValidateWireMessage() error {
+ if int(m.MsgHeader.MessageLength) != m.Len() {
+ return errors.New("incorrect header: message length is not correct")
+ }
+ if m.MsgHeader.OpCode != OpMsg {
+ return errors.New("incorrect header: opcode is not OpMsg")
+ }
+
+ return nil
+}
+
+// AppendWireMessage implements the Appender and WireMessage interfaces.
+//
+// AppendWireMesssage will set the MessageLength property of the MsgHeader if it is zero. It will also set the Opcode
+// to OP_MSG if it is zero. If either of these properties are non-zero and not correct, this method will return both the
+// []byte with the wire message appended to it and an invalid header error.
+func (m Msg) AppendWireMessage(b []byte) ([]byte, error) {
+ var err error
+ err = m.MsgHeader.SetDefaults(m.Len(), OpMsg)
+
+ b = m.MsgHeader.AppendHeader(b)
+ b = appendInt32(b, int32(m.FlagBits))
+
+ for _, section := range m.Sections {
+ newB := make([]byte, 0)
+ newB = section.AppendSection(newB)
+
+ b = section.AppendSection(b)
+ }
+
+ return b, err
+}
+
+// String implements the fmt.Stringer interface.
+func (m Msg) String() string {
+ panic("not implemented")
+}
+
+// Len implements the WireMessage interface.
+func (m Msg) Len() int {
+ // Header + Flags + len of each section + optional checksum
+ totalLen := 16 + 4 // header and flag
+
+ for _, section := range m.Sections {
+ totalLen += section.Len()
+ }
+
+ if m.FlagBits&ChecksumPresent > 0 {
+ totalLen += 4
+ }
+
+ return totalLen
+}
+
+// UnmarshalWireMessage implements the Unmarshaler interface.
+func (m *Msg) UnmarshalWireMessage(b []byte) error {
+ var err error
+
+ m.MsgHeader, err = ReadHeader(b, 0)
+ if err != nil {
+ return err
+ }
+ if len(b) < int(m.MsgHeader.MessageLength) {
+ return Error{
+ Type: ErrOpMsg,
+ Message: "[]byte too small",
+ }
+ }
+
+ m.FlagBits = MsgFlag(readInt32(b, 16))
+
+ // read each section
+ sectionBytes := m.MsgHeader.MessageLength - 16 - 4 // number of bytes taken up by sections
+ hasChecksum := m.FlagBits&ChecksumPresent > 0
+ if hasChecksum {
+ sectionBytes -= 4 // 4 bytes at end for checksum
+ }
+
+ m.Sections = make([]Section, 0)
+ position := 20 // position to read from
+ for sectionBytes > 0 {
+ sectionType := SectionType(b[position])
+ position++
+
+ switch sectionType {
+ case SingleDocument:
+ rdr, size, err := readDocument(b, int32(position))
+ if err.Message != "" {
+ err.Type = ErrOpMsg
+ return err
+ }
+
+ position += size
+ sb := SectionBody{
+ Document: rdr,
+ }
+ sb.PayloadType = sb.Kind()
+
+ sectionBytes -= int32(sb.Len())
+ m.Sections = append(m.Sections, sb)
+ case DocumentSequence:
+ sds := SectionDocumentSequence{}
+ sds.Size = readInt32(b, int32(position))
+ position += 4
+
+ identifier, err := readCString(b, int32(position))
+ if err != nil {
+ return err
+ }
+
+ sds.Identifier = identifier
+ position += len(identifier) + 1 // +1 for \0
+ sds.PayloadType = sds.Kind()
+
+ // length of documents to read
+ // sequenceLen - 4 bytes for size field - identifierLength (including \0)
+ docsLen := int(sds.Size) - 4 - len(identifier) - 1
+ for docsLen > 0 {
+ rdr, size, err := readDocument(b, int32(position))
+ if err.Message != "" {
+ err.Type = ErrOpMsg
+ return err
+ }
+
+ position += size
+ sds.Documents = append(sds.Documents, rdr)
+ docsLen -= size
+ }
+
+ sectionBytes -= int32(sds.Len())
+ m.Sections = append(m.Sections, sds)
+ }
+ }
+
+ if hasChecksum {
+ m.Checksum = uint32(readInt32(b, int32(position)))
+ }
+
+ return nil
+}
+
+// GetMainDocument returns the document containing the message to send.
+func (m *Msg) GetMainDocument() (bsonx.Doc, error) {
+ return bsonx.ReadDoc(m.Sections[0].(SectionBody).Document)
+}
+
+// GetSequenceArray returns this message's document sequence as a BSON array along with the array identifier.
+// If this message has no associated document sequence, a nil array is returned.
+func (m *Msg) GetSequenceArray() (bsonx.Arr, string, error) {
+ if len(m.Sections) == 1 {
+ return nil, "", nil
+ }
+
+ arr := bsonx.Arr{}
+ sds := m.Sections[1].(SectionDocumentSequence)
+
+ for _, rdr := range sds.Documents {
+ doc, err := bsonx.ReadDoc([]byte(rdr))
+ if err != nil {
+ return nil, "", err
+ }
+
+ arr = append(arr, bsonx.Document(doc))
+ }
+
+ return arr, sds.Identifier, nil
+}
+
+// AcknowledgedWrite returns true if this msg represents an acknowledged write command.
+func (m *Msg) AcknowledgedWrite() bool {
+ return m.FlagBits&MoreToCome == 0
+}
+
+// MsgFlag represents the flags on an OP_MSG message.
+type MsgFlag uint32
+
+// These constants represent the individual flags on an OP_MSG message.
+const (
+ ChecksumPresent MsgFlag = 1 << iota
+ MoreToCome
+
+ ExhaustAllowed MsgFlag = 1 << 16
+)
+
+// Section represents a section on an OP_MSG message.
+type Section interface {
+ Kind() SectionType
+ Len() int
+ AppendSection([]byte) []byte
+}
+
+// SectionBody represents the kind body of an OP_MSG message.
+type SectionBody struct {
+ PayloadType SectionType
+ Document bson.Raw
+}
+
+// Kind implements the Section interface.
+func (sb SectionBody) Kind() SectionType {
+ return SingleDocument
+}
+
+// Len implements the Section interface
+func (sb SectionBody) Len() int {
+ return 1 + len(sb.Document) // 1 for PayloadType
+}
+
+// AppendSection implements the Section interface.
+func (sb SectionBody) AppendSection(dest []byte) []byte {
+ dest = append(dest, byte(SingleDocument))
+ dest = append(dest, sb.Document...)
+ return dest
+}
+
+// SectionDocumentSequence represents the kind document sequence of an OP_MSG message.
+type SectionDocumentSequence struct {
+ PayloadType SectionType
+ Size int32
+ Identifier string
+ Documents []bson.Raw
+}
+
+// Kind implements the Section interface.
+func (sds SectionDocumentSequence) Kind() SectionType {
+ return DocumentSequence
+}
+
+// Len implements the Section interface
+func (sds SectionDocumentSequence) Len() int {
+ // PayloadType + Size + Identifier + 1 (null terminator) + totalDocLen
+ totalDocLen := 0
+ for _, doc := range sds.Documents {
+ totalDocLen += len(doc)
+ }
+
+ return 1 + 4 + len(sds.Identifier) + 1 + totalDocLen
+}
+
+// PayloadLen returns the length of the payload
+func (sds SectionDocumentSequence) PayloadLen() int {
+ // 4 bytes for size field, len identifier (including \0), and total docs len
+ return sds.Len() - 1
+}
+
+// AppendSection implements the Section interface
+func (sds SectionDocumentSequence) AppendSection(dest []byte) []byte {
+ dest = append(dest, byte(DocumentSequence))
+ dest = appendInt32(dest, sds.Size)
+ dest = appendCString(dest, sds.Identifier)
+
+ for _, doc := range sds.Documents {
+ dest = append(dest, doc...)
+ }
+
+ return dest
+}
+
+// SectionType represents the type for 1 section in an OP_MSG
+type SectionType uint8
+
+// These constants represent the individual section types for a section in an OP_MSG
+const (
+ SingleDocument SectionType = iota
+ DocumentSequence
+)
+
+// OpmsgWireVersion is the minimum wire version needed to use OP_MSG
+const OpmsgWireVersion = 6