|
- // 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 bsonx // import "go.mongodb.org/mongo-driver/x/bsonx"
-
- import (
- "bytes"
- "errors"
- "fmt"
- "strconv"
-
- "go.mongodb.org/mongo-driver/bson/bsontype"
- "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
- )
-
- // ErrNilArray indicates that an operation was attempted on a nil *Array.
- var ErrNilArray = errors.New("array is nil")
-
- // Arr represents an array in BSON.
- type Arr []Val
-
- // String implements the fmt.Stringer interface.
- func (a Arr) String() string {
- var buf bytes.Buffer
- buf.Write([]byte("bson.Array["))
- for idx, val := range a {
- if idx > 0 {
- buf.Write([]byte(", "))
- }
- fmt.Fprintf(&buf, "%s", val)
- }
- buf.WriteByte(']')
-
- return buf.String()
- }
-
- // MarshalBSONValue implements the bsoncodec.ValueMarshaler interface.
- func (a Arr) MarshalBSONValue() (bsontype.Type, []byte, error) {
- if a == nil {
- // TODO: Should we do this?
- return bsontype.Null, nil, nil
- }
-
- idx, dst := bsoncore.ReserveLength(nil)
- for idx, value := range a {
- t, data, _ := value.MarshalBSONValue() // marshalBSONValue never returns an error.
- dst = append(dst, byte(t))
- dst = append(dst, strconv.Itoa(idx)...)
- dst = append(dst, 0x00)
- dst = append(dst, data...)
- }
- dst = append(dst, 0x00)
- dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
- return bsontype.Array, dst, nil
- }
-
- // UnmarshalBSONValue implements the bsoncodec.ValueUnmarshaler interface.
- func (a *Arr) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
- if a == nil {
- return ErrNilArray
- }
- *a = (*a)[:0]
-
- elements, err := bsoncore.Document(data).Elements()
- if err != nil {
- return err
- }
-
- for _, elem := range elements {
- var val Val
- rawval := elem.Value()
- err = val.UnmarshalBSONValue(rawval.Type, rawval.Data)
- if err != nil {
- return err
- }
- *a = append(*a, val)
- }
- return nil
- }
-
- // Equal compares this document to another, returning true if they are equal.
- func (a Arr) Equal(a2 Arr) bool {
- if len(a) != len(a2) {
- return false
- }
- for idx := range a {
- if !a[idx].Equal(a2[idx]) {
- return false
- }
- }
- return true
- }
-
- func (Arr) idoc() {}
|