You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

array.go 2.3 kB

5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (C) MongoDB, Inc. 2017-present.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. package bsonx // import "go.mongodb.org/mongo-driver/x/bsonx"
  7. import (
  8. "bytes"
  9. "errors"
  10. "fmt"
  11. "strconv"
  12. "go.mongodb.org/mongo-driver/bson/bsontype"
  13. "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
  14. )
  15. // ErrNilArray indicates that an operation was attempted on a nil *Array.
  16. var ErrNilArray = errors.New("array is nil")
  17. // Arr represents an array in BSON.
  18. type Arr []Val
  19. // String implements the fmt.Stringer interface.
  20. func (a Arr) String() string {
  21. var buf bytes.Buffer
  22. buf.Write([]byte("bson.Array["))
  23. for idx, val := range a {
  24. if idx > 0 {
  25. buf.Write([]byte(", "))
  26. }
  27. fmt.Fprintf(&buf, "%s", val)
  28. }
  29. buf.WriteByte(']')
  30. return buf.String()
  31. }
  32. // MarshalBSONValue implements the bsoncodec.ValueMarshaler interface.
  33. func (a Arr) MarshalBSONValue() (bsontype.Type, []byte, error) {
  34. if a == nil {
  35. // TODO: Should we do this?
  36. return bsontype.Null, nil, nil
  37. }
  38. idx, dst := bsoncore.ReserveLength(nil)
  39. for idx, value := range a {
  40. t, data, _ := value.MarshalBSONValue() // marshalBSONValue never returns an error.
  41. dst = append(dst, byte(t))
  42. dst = append(dst, strconv.Itoa(idx)...)
  43. dst = append(dst, 0x00)
  44. dst = append(dst, data...)
  45. }
  46. dst = append(dst, 0x00)
  47. dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
  48. return bsontype.Array, dst, nil
  49. }
  50. // UnmarshalBSONValue implements the bsoncodec.ValueUnmarshaler interface.
  51. func (a *Arr) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
  52. if a == nil {
  53. return ErrNilArray
  54. }
  55. *a = (*a)[:0]
  56. elements, err := bsoncore.Document(data).Elements()
  57. if err != nil {
  58. return err
  59. }
  60. for _, elem := range elements {
  61. var val Val
  62. rawval := elem.Value()
  63. err = val.UnmarshalBSONValue(rawval.Type, rawval.Data)
  64. if err != nil {
  65. return err
  66. }
  67. *a = append(*a, val)
  68. }
  69. return nil
  70. }
  71. // Equal compares this document to another, returning true if they are equal.
  72. func (a Arr) Equal(a2 Arr) bool {
  73. if len(a) != len(a2) {
  74. return false
  75. }
  76. for idx := range a {
  77. if !a[idx].Equal(a2[idx]) {
  78. return false
  79. }
  80. }
  81. return true
  82. }
  83. func (Arr) idoc() {}