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

111 lines
3.6 KiB

  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 bson
  7. import (
  8. "errors"
  9. "reflect"
  10. "go.mongodb.org/mongo-driver/bson/bsoncodec"
  11. "go.mongodb.org/mongo-driver/bson/bsonrw"
  12. )
  13. var primitiveCodecs PrimitiveCodecs
  14. // PrimitiveCodecs is a namespace for all of the default bsoncodec.Codecs for the primitive types
  15. // defined in this package.
  16. type PrimitiveCodecs struct{}
  17. // RegisterPrimitiveCodecs will register the encode and decode methods attached to PrimitiveCodecs
  18. // with the provided RegistryBuilder. if rb is nil, a new empty RegistryBuilder will be created.
  19. func (pc PrimitiveCodecs) RegisterPrimitiveCodecs(rb *bsoncodec.RegistryBuilder) {
  20. if rb == nil {
  21. panic(errors.New("argument to RegisterPrimitiveCodecs must not be nil"))
  22. }
  23. rb.
  24. RegisterEncoder(tRawValue, bsoncodec.ValueEncoderFunc(pc.RawValueEncodeValue)).
  25. RegisterEncoder(tRaw, bsoncodec.ValueEncoderFunc(pc.RawEncodeValue)).
  26. RegisterDecoder(tRawValue, bsoncodec.ValueDecoderFunc(pc.RawValueDecodeValue)).
  27. RegisterDecoder(tRaw, bsoncodec.ValueDecoderFunc(pc.RawDecodeValue))
  28. }
  29. // RawValueEncodeValue is the ValueEncoderFunc for RawValue.
  30. func (PrimitiveCodecs) RawValueEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
  31. if !val.IsValid() || val.Type() != tRawValue {
  32. return bsoncodec.ValueEncoderError{Name: "RawValueEncodeValue", Types: []reflect.Type{tRawValue}, Received: val}
  33. }
  34. rawvalue := val.Interface().(RawValue)
  35. return bsonrw.Copier{}.CopyValueFromBytes(vw, rawvalue.Type, rawvalue.Value)
  36. }
  37. // RawValueDecodeValue is the ValueDecoderFunc for RawValue.
  38. func (PrimitiveCodecs) RawValueDecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
  39. if !val.CanSet() || val.Type() != tRawValue {
  40. return bsoncodec.ValueDecoderError{Name: "RawValueDecodeValue", Types: []reflect.Type{tRawValue}, Received: val}
  41. }
  42. t, value, err := bsonrw.Copier{}.CopyValueToBytes(vr)
  43. if err != nil {
  44. return err
  45. }
  46. val.Set(reflect.ValueOf(RawValue{Type: t, Value: value}))
  47. return nil
  48. }
  49. // RawEncodeValue is the ValueEncoderFunc for Reader.
  50. func (PrimitiveCodecs) RawEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
  51. if !val.IsValid() || val.Type() != tRaw {
  52. return bsoncodec.ValueEncoderError{Name: "RawEncodeValue", Types: []reflect.Type{tRaw}, Received: val}
  53. }
  54. rdr := val.Interface().(Raw)
  55. return bsonrw.Copier{}.CopyDocumentFromBytes(vw, rdr)
  56. }
  57. // RawDecodeValue is the ValueDecoderFunc for Reader.
  58. func (PrimitiveCodecs) RawDecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
  59. if !val.CanSet() || val.Type() != tRaw {
  60. return bsoncodec.ValueDecoderError{Name: "RawDecodeValue", Types: []reflect.Type{tRaw}, Received: val}
  61. }
  62. if val.IsNil() {
  63. val.Set(reflect.MakeSlice(val.Type(), 0, 0))
  64. }
  65. val.SetLen(0)
  66. rdr, err := bsonrw.Copier{}.AppendDocumentBytes(val.Interface().(Raw), vr)
  67. val.Set(reflect.ValueOf(rdr))
  68. return err
  69. }
  70. func (pc PrimitiveCodecs) encodeRaw(ec bsoncodec.EncodeContext, dw bsonrw.DocumentWriter, raw Raw) error {
  71. var copier bsonrw.Copier
  72. elems, err := raw.Elements()
  73. if err != nil {
  74. return err
  75. }
  76. for _, elem := range elems {
  77. dvw, err := dw.WriteDocumentElement(elem.Key())
  78. if err != nil {
  79. return err
  80. }
  81. val := elem.Value()
  82. err = copier.CopyValueFromBytes(dvw, val.Type, val.Value)
  83. if err != nil {
  84. return err
  85. }
  86. }
  87. return dw.WriteDocumentEnd()
  88. }