github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go (about)

     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  
     7  package bsonrw
     8  
     9  import (
    10  	"fmt"
    11  	"io"
    12  
    13  	"go.mongodb.org/mongo-driver/bson/bsontype"
    14  	"go.mongodb.org/mongo-driver/bson/primitive"
    15  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    16  )
    17  
    18  // Copier is a type that allows copying between ValueReaders, ValueWriters, and
    19  // []byte values.
    20  //
    21  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
    22  // supported in Go Driver 2.0.
    23  type Copier struct{}
    24  
    25  // NewCopier creates a new copier with the given registry. If a nil registry is provided
    26  // a default registry is used.
    27  //
    28  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
    29  // supported in Go Driver 2.0.
    30  func NewCopier() Copier {
    31  	return Copier{}
    32  }
    33  
    34  // CopyDocument handles copying a document from src to dst.
    35  //
    36  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
    37  // supported in Go Driver 2.0.
    38  func CopyDocument(dst ValueWriter, src ValueReader) error {
    39  	return Copier{}.CopyDocument(dst, src)
    40  }
    41  
    42  // CopyDocument handles copying one document from the src to the dst.
    43  //
    44  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
    45  // supported in Go Driver 2.0.
    46  func (c Copier) CopyDocument(dst ValueWriter, src ValueReader) error {
    47  	dr, err := src.ReadDocument()
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	dw, err := dst.WriteDocument()
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	return c.copyDocumentCore(dw, dr)
    58  }
    59  
    60  // CopyArrayFromBytes copies the values from a BSON array represented as a
    61  // []byte to a ValueWriter.
    62  //
    63  // Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be
    64  // supported in Go Driver 2.0.
    65  func (c Copier) CopyArrayFromBytes(dst ValueWriter, src []byte) error {
    66  	aw, err := dst.WriteArray()
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	err = c.CopyBytesToArrayWriter(aw, src)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	return aw.WriteArrayEnd()
    77  }
    78  
    79  // CopyDocumentFromBytes copies the values from a BSON document represented as a
    80  // []byte to a ValueWriter.
    81  //
    82  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
    83  // supported in Go Driver 2.0.
    84  func (c Copier) CopyDocumentFromBytes(dst ValueWriter, src []byte) error {
    85  	dw, err := dst.WriteDocument()
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	err = c.CopyBytesToDocumentWriter(dw, src)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	return dw.WriteDocumentEnd()
    96  }
    97  
    98  type writeElementFn func(key string) (ValueWriter, error)
    99  
   100  // CopyBytesToArrayWriter copies the values from a BSON Array represented as a []byte to an
   101  // ArrayWriter.
   102  //
   103  // Deprecated: Copying BSON arrays using the ArrayWriter interface will not be supported in Go
   104  // Driver 2.0.
   105  func (c Copier) CopyBytesToArrayWriter(dst ArrayWriter, src []byte) error {
   106  	wef := func(_ string) (ValueWriter, error) {
   107  		return dst.WriteArrayElement()
   108  	}
   109  
   110  	return c.copyBytesToValueWriter(src, wef)
   111  }
   112  
   113  // CopyBytesToDocumentWriter copies the values from a BSON document represented as a []byte to a
   114  // DocumentWriter.
   115  //
   116  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
   117  // supported in Go Driver 2.0.
   118  func (c Copier) CopyBytesToDocumentWriter(dst DocumentWriter, src []byte) error {
   119  	wef := func(key string) (ValueWriter, error) {
   120  		return dst.WriteDocumentElement(key)
   121  	}
   122  
   123  	return c.copyBytesToValueWriter(src, wef)
   124  }
   125  
   126  func (c Copier) copyBytesToValueWriter(src []byte, wef writeElementFn) error {
   127  	// TODO(skriptble): Create errors types here. Anything thats a tag should be a property.
   128  	length, rem, ok := bsoncore.ReadLength(src)
   129  	if !ok {
   130  		return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src))
   131  	}
   132  	if len(src) < int(length) {
   133  		return fmt.Errorf("length read exceeds number of bytes available. length=%d bytes=%d", len(src), length)
   134  	}
   135  	rem = rem[:length-4]
   136  
   137  	var t bsontype.Type
   138  	var key string
   139  	var val bsoncore.Value
   140  	for {
   141  		t, rem, ok = bsoncore.ReadType(rem)
   142  		if !ok {
   143  			return io.EOF
   144  		}
   145  		if t == bsontype.Type(0) {
   146  			if len(rem) != 0 {
   147  				return fmt.Errorf("document end byte found before end of document. remaining bytes=%v", rem)
   148  			}
   149  			break
   150  		}
   151  
   152  		key, rem, ok = bsoncore.ReadKey(rem)
   153  		if !ok {
   154  			return fmt.Errorf("invalid key found. remaining bytes=%v", rem)
   155  		}
   156  
   157  		// write as either array element or document element using writeElementFn
   158  		vw, err := wef(key)
   159  		if err != nil {
   160  			return err
   161  		}
   162  
   163  		val, rem, ok = bsoncore.ReadValue(rem, t)
   164  		if !ok {
   165  			return fmt.Errorf("not enough bytes available to read type. bytes=%d type=%s", len(rem), t)
   166  		}
   167  		err = c.CopyValueFromBytes(vw, t, val.Data)
   168  		if err != nil {
   169  			return err
   170  		}
   171  	}
   172  	return nil
   173  }
   174  
   175  // CopyDocumentToBytes copies an entire document from the ValueReader and
   176  // returns it as bytes.
   177  //
   178  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
   179  // supported in Go Driver 2.0.
   180  func (c Copier) CopyDocumentToBytes(src ValueReader) ([]byte, error) {
   181  	return c.AppendDocumentBytes(nil, src)
   182  }
   183  
   184  // AppendDocumentBytes functions the same as CopyDocumentToBytes, but will
   185  // append the result to dst.
   186  //
   187  // Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
   188  // supported in Go Driver 2.0.
   189  func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) {
   190  	if br, ok := src.(BytesReader); ok {
   191  		_, dst, err := br.ReadValueBytes(dst)
   192  		return dst, err
   193  	}
   194  
   195  	vw := vwPool.Get().(*valueWriter)
   196  	defer vwPool.Put(vw)
   197  
   198  	vw.reset(dst)
   199  
   200  	err := c.CopyDocument(vw, src)
   201  	dst = vw.buf
   202  	return dst, err
   203  }
   204  
   205  // AppendArrayBytes copies an array from the ValueReader to dst.
   206  //
   207  // Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be
   208  // supported in Go Driver 2.0.
   209  func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
   210  	if br, ok := src.(BytesReader); ok {
   211  		_, dst, err := br.ReadValueBytes(dst)
   212  		return dst, err
   213  	}
   214  
   215  	vw := vwPool.Get().(*valueWriter)
   216  	defer vwPool.Put(vw)
   217  
   218  	vw.reset(dst)
   219  
   220  	err := c.copyArray(vw, src)
   221  	dst = vw.buf
   222  	return dst, err
   223  }
   224  
   225  // CopyValueFromBytes will write the value represtend by t and src to dst.
   226  //
   227  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.UnmarshalValue] instead.
   228  func (c Copier) CopyValueFromBytes(dst ValueWriter, t bsontype.Type, src []byte) error {
   229  	if wvb, ok := dst.(BytesWriter); ok {
   230  		return wvb.WriteValueBytes(t, src)
   231  	}
   232  
   233  	vr := vrPool.Get().(*valueReader)
   234  	defer vrPool.Put(vr)
   235  
   236  	vr.reset(src)
   237  	vr.pushElement(t)
   238  
   239  	return c.CopyValue(dst, vr)
   240  }
   241  
   242  // CopyValueToBytes copies a value from src and returns it as a bsontype.Type and a
   243  // []byte.
   244  //
   245  // Deprecated: Use [go.mongodb.org/mongo-driver/bson.MarshalValue] instead.
   246  func (c Copier) CopyValueToBytes(src ValueReader) (bsontype.Type, []byte, error) {
   247  	return c.AppendValueBytes(nil, src)
   248  }
   249  
   250  // AppendValueBytes functions the same as CopyValueToBytes, but will append the
   251  // result to dst.
   252  //
   253  // Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
   254  // Driver 2.0.
   255  func (c Copier) AppendValueBytes(dst []byte, src ValueReader) (bsontype.Type, []byte, error) {
   256  	if br, ok := src.(BytesReader); ok {
   257  		return br.ReadValueBytes(dst)
   258  	}
   259  
   260  	vw := vwPool.Get().(*valueWriter)
   261  	defer vwPool.Put(vw)
   262  
   263  	start := len(dst)
   264  
   265  	vw.reset(dst)
   266  	vw.push(mElement)
   267  
   268  	err := c.CopyValue(vw, src)
   269  	if err != nil {
   270  		return 0, dst, err
   271  	}
   272  
   273  	return bsontype.Type(vw.buf[start]), vw.buf[start+2:], nil
   274  }
   275  
   276  // CopyValue will copy a single value from src to dst.
   277  //
   278  // Deprecated: Copying BSON values using the ValueWriter and ValueReader interfaces will not be
   279  // supported in Go Driver 2.0.
   280  func (c Copier) CopyValue(dst ValueWriter, src ValueReader) error {
   281  	var err error
   282  	switch src.Type() {
   283  	case bsontype.Double:
   284  		var f64 float64
   285  		f64, err = src.ReadDouble()
   286  		if err != nil {
   287  			break
   288  		}
   289  		err = dst.WriteDouble(f64)
   290  	case bsontype.String:
   291  		var str string
   292  		str, err = src.ReadString()
   293  		if err != nil {
   294  			return err
   295  		}
   296  		err = dst.WriteString(str)
   297  	case bsontype.EmbeddedDocument:
   298  		err = c.CopyDocument(dst, src)
   299  	case bsontype.Array:
   300  		err = c.copyArray(dst, src)
   301  	case bsontype.Binary:
   302  		var data []byte
   303  		var subtype byte
   304  		data, subtype, err = src.ReadBinary()
   305  		if err != nil {
   306  			break
   307  		}
   308  		err = dst.WriteBinaryWithSubtype(data, subtype)
   309  	case bsontype.Undefined:
   310  		err = src.ReadUndefined()
   311  		if err != nil {
   312  			break
   313  		}
   314  		err = dst.WriteUndefined()
   315  	case bsontype.ObjectID:
   316  		var oid primitive.ObjectID
   317  		oid, err = src.ReadObjectID()
   318  		if err != nil {
   319  			break
   320  		}
   321  		err = dst.WriteObjectID(oid)
   322  	case bsontype.Boolean:
   323  		var b bool
   324  		b, err = src.ReadBoolean()
   325  		if err != nil {
   326  			break
   327  		}
   328  		err = dst.WriteBoolean(b)
   329  	case bsontype.DateTime:
   330  		var dt int64
   331  		dt, err = src.ReadDateTime()
   332  		if err != nil {
   333  			break
   334  		}
   335  		err = dst.WriteDateTime(dt)
   336  	case bsontype.Null:
   337  		err = src.ReadNull()
   338  		if err != nil {
   339  			break
   340  		}
   341  		err = dst.WriteNull()
   342  	case bsontype.Regex:
   343  		var pattern, options string
   344  		pattern, options, err = src.ReadRegex()
   345  		if err != nil {
   346  			break
   347  		}
   348  		err = dst.WriteRegex(pattern, options)
   349  	case bsontype.DBPointer:
   350  		var ns string
   351  		var pointer primitive.ObjectID
   352  		ns, pointer, err = src.ReadDBPointer()
   353  		if err != nil {
   354  			break
   355  		}
   356  		err = dst.WriteDBPointer(ns, pointer)
   357  	case bsontype.JavaScript:
   358  		var js string
   359  		js, err = src.ReadJavascript()
   360  		if err != nil {
   361  			break
   362  		}
   363  		err = dst.WriteJavascript(js)
   364  	case bsontype.Symbol:
   365  		var symbol string
   366  		symbol, err = src.ReadSymbol()
   367  		if err != nil {
   368  			break
   369  		}
   370  		err = dst.WriteSymbol(symbol)
   371  	case bsontype.CodeWithScope:
   372  		var code string
   373  		var srcScope DocumentReader
   374  		code, srcScope, err = src.ReadCodeWithScope()
   375  		if err != nil {
   376  			break
   377  		}
   378  
   379  		var dstScope DocumentWriter
   380  		dstScope, err = dst.WriteCodeWithScope(code)
   381  		if err != nil {
   382  			break
   383  		}
   384  		err = c.copyDocumentCore(dstScope, srcScope)
   385  	case bsontype.Int32:
   386  		var i32 int32
   387  		i32, err = src.ReadInt32()
   388  		if err != nil {
   389  			break
   390  		}
   391  		err = dst.WriteInt32(i32)
   392  	case bsontype.Timestamp:
   393  		var t, i uint32
   394  		t, i, err = src.ReadTimestamp()
   395  		if err != nil {
   396  			break
   397  		}
   398  		err = dst.WriteTimestamp(t, i)
   399  	case bsontype.Int64:
   400  		var i64 int64
   401  		i64, err = src.ReadInt64()
   402  		if err != nil {
   403  			break
   404  		}
   405  		err = dst.WriteInt64(i64)
   406  	case bsontype.Decimal128:
   407  		var d128 primitive.Decimal128
   408  		d128, err = src.ReadDecimal128()
   409  		if err != nil {
   410  			break
   411  		}
   412  		err = dst.WriteDecimal128(d128)
   413  	case bsontype.MinKey:
   414  		err = src.ReadMinKey()
   415  		if err != nil {
   416  			break
   417  		}
   418  		err = dst.WriteMinKey()
   419  	case bsontype.MaxKey:
   420  		err = src.ReadMaxKey()
   421  		if err != nil {
   422  			break
   423  		}
   424  		err = dst.WriteMaxKey()
   425  	default:
   426  		err = fmt.Errorf("Cannot copy unknown BSON type %s", src.Type())
   427  	}
   428  
   429  	return err
   430  }
   431  
   432  func (c Copier) copyArray(dst ValueWriter, src ValueReader) error {
   433  	ar, err := src.ReadArray()
   434  	if err != nil {
   435  		return err
   436  	}
   437  
   438  	aw, err := dst.WriteArray()
   439  	if err != nil {
   440  		return err
   441  	}
   442  
   443  	for {
   444  		vr, err := ar.ReadValue()
   445  		if err == ErrEOA {
   446  			break
   447  		}
   448  		if err != nil {
   449  			return err
   450  		}
   451  
   452  		vw, err := aw.WriteArrayElement()
   453  		if err != nil {
   454  			return err
   455  		}
   456  
   457  		err = c.CopyValue(vw, vr)
   458  		if err != nil {
   459  			return err
   460  		}
   461  	}
   462  
   463  	return aw.WriteArrayEnd()
   464  }
   465  
   466  func (c Copier) copyDocumentCore(dw DocumentWriter, dr DocumentReader) error {
   467  	for {
   468  		key, vr, err := dr.ReadElement()
   469  		if err == ErrEOD {
   470  			break
   471  		}
   472  		if err != nil {
   473  			return err
   474  		}
   475  
   476  		vw, err := dw.WriteDocumentElement(key)
   477  		if err != nil {
   478  			return err
   479  		}
   480  
   481  		err = c.CopyValue(vw, vr)
   482  		if err != nil {
   483  			return err
   484  		}
   485  	}
   486  
   487  	return dw.WriteDocumentEnd()
   488  }