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 }