1use 5.010001; 2use strict; 3use warnings; 4 5package BSON; 6# ABSTRACT: BSON serialization and deserialization (EOL) 7 8use base 'Exporter'; 9our @EXPORT_OK = qw/encode decode/; 10 11use version; 12our $VERSION = 'v1.12.2'; 13 14use Carp; 15use Config; 16use Scalar::Util qw/blessed looks_like_number/; 17 18use Moo 2.002004; # safer generated code 19use boolean; 20use BSON::OID; 21 22use constant { 23 HAS_INT64 => $Config{use64bitint}, 24 HAS_LD => $Config{uselongdouble}, 25}; 26 27use if !HAS_INT64, "Math::BigInt"; 28 29my $bools_re = qr/::(?:Boolean|_Bool|Bool)\z/; 30 31use namespace::clean -except => 'meta'; 32 33my $max_int32 = 2147483647; 34 35# Dependency-free equivalent of what we need from Module::Runtime 36sub _try_load { 37 my ( $mod, $ver ) = @_; 38 ( my $file = "$mod.pm" ) =~ s{::}{/}g; 39 my $load = eval { require $file; $mod->VERSION($ver) if defined $ver; 1 }; 40 delete $INC{$file} if !$load; # for old, broken perls 41 die $@ if !$load; 42 return 1; 43} 44 45BEGIN { 46 my ($class, @errs); 47 if ( $class = $ENV{PERL_BSON_BACKEND} ) { 48 eval { _try_load($class) }; 49 if ( my $err = $@ ) { 50 $err =~ s{ at \S+ line .*}{}; 51 die "Error: PERL_BSON_BACKEND '$class' could not be loaded: $err\n"; 52 } 53 unless ($class->can("_encode_bson") && $class->can("_decode_bson") ) { 54 die "Error: PERL_BSON_BACKEND '$class' does not implement the correct API.\n"; 55 } 56 } 57 elsif ( eval { _try_load( $class = "BSON::XS" ) } or do { push @errs, $@; 0 } ) { 58 # module loaded; nothing else to do 59 } 60 elsif ( eval { _try_load( $class = "BSON::PP" ) } or do { push @errs, $@; 0 } ) { 61 # module loaded; nothing else to do 62 } 63 else { 64 s/\n/ /g for @errs; 65 die join( "\n* ", "Error: Couldn't load a BSON backend:", @errs ) . "\n"; 66 } 67 68 *_encode_bson = $class->can("_encode_bson"); 69 *_decode_bson = $class->can("_decode_bson"); 70 *_backend_class = sub { $class }; # for debugging 71} 72 73# LOAD AFTER XS/PP, so that modules can pick up right version of helpers 74use BSON::Types (); # loads types for extjson inflation 75 76#--------------------------------------------------------------------------# 77# public attributes 78#--------------------------------------------------------------------------# 79 80#pod =attr error_callback 81#pod 82#pod This attribute specifies a function reference that will be called with 83#pod three positional arguments: 84#pod 85#pod =for :list 86#pod * an error string argument describing the error condition 87#pod * a reference to the problematic document or byte-string 88#pod * the method in which the error occurred (e.g. C<encode_one> or C<decode_one>) 89#pod 90#pod Note: for decoding errors, the byte-string is passed as a reference to avoid 91#pod copying possibly large strings. 92#pod 93#pod If not provided, errors messages will be thrown with C<Carp::croak>. 94#pod 95#pod =cut 96 97has error_callback => ( 98 is => 'ro', 99 isa => sub { die "not a code reference" if defined $_[0] && ! ref $_[0] eq 'CODE' }, 100); 101 102#pod =attr invalid_chars 103#pod 104#pod A string containing ASCII characters that must not appear in keys. The default 105#pod is the empty string, meaning there are no invalid characters. 106#pod 107#pod =cut 108 109has invalid_chars => ( 110 is => 'ro', 111 isa => sub { die "not a string" if ! defined $_[0] || ref $_[0] }, 112); 113 114#pod =attr max_length 115#pod 116#pod This attribute defines the maximum document size. The default is 0, which 117#pod disables any maximum. 118#pod 119#pod If set to a positive number, it applies to both encoding B<and> decoding (the 120#pod latter is necessary for prevention of resource consumption attacks). 121#pod 122#pod =cut 123 124has max_length => ( 125 is => 'ro', 126 isa => sub { die "not a non-negative number" unless defined $_[0] && $_[0] >= 0 }, 127); 128 129#pod =attr op_char 130#pod 131#pod This is a single character to use for special MongoDB-specific query 132#pod operators. If a key starts with C<op_char>, the C<op_char> character will 133#pod be replaced with "$". 134#pod 135#pod The default is "$", meaning that no replacement is necessary. 136#pod 137#pod =cut 138 139has op_char => ( 140 is => 'ro', 141 isa => sub { die "not a single character" if defined $_[0] && length $_[0] > 1 }, 142); 143 144#pod =attr ordered 145#pod 146#pod If set to a true value, then decoding will return a reference to a tied 147#pod hash that preserves key order. Otherwise, a regular (unordered) hash 148#pod reference will be returned. 149#pod 150#pod B<IMPORTANT CAVEATS>: 151#pod 152#pod =for :list 153#pod * When 'ordered' is true, users must not rely on the return value being any 154#pod particular tied hash implementation. It may change in the future for 155#pod efficiency. 156#pod * Turning this option on entails a significant speed penalty as tied hashes 157#pod are slower than regular Perl hashes. 158#pod 159#pod The default is false. 160#pod 161#pod =cut 162 163has ordered => ( 164 is => 'ro', 165); 166 167#pod =attr prefer_numeric 168#pod 169#pod When false, scalar values will be encoded as a number if they were 170#pod originally a number or were ever used in a numeric context. However, a 171#pod string that looks like a number but was never used in a numeric context 172#pod (e.g. "42") will be encoded as a string. 173#pod 174#pod If C<prefer_numeric> is set to true, the encoder will attempt to coerce 175#pod strings that look like a number into a numeric value. If the string 176#pod doesn't look like a double or integer, it will be encoded as a string. 177#pod 178#pod B<IMPORTANT CAVEAT>: the heuristics for determining whether something is a 179#pod string or number are less accurate on older Perls. See L<BSON::Types> 180#pod for wrapper classes that specify exact serialization types. 181#pod 182#pod The default is false. 183#pod 184#pod =cut 185 186has prefer_numeric => ( 187 is => 'ro', 188); 189 190#pod =attr wrap_dbrefs 191#pod 192#pod If set to true, during decoding, documents with the fields C<'$id'> and 193#pod C<'$ref'> (literal dollar signs, not variables) will be wrapped as 194#pod L<BSON::DBRef> objects. If false, they are decoded into ordinary hash 195#pod references (or ordered hashes, if C<ordered> is true). 196#pod 197#pod The default is true. 198#pod 199#pod =cut 200 201has wrap_dbrefs => ( 202 is => 'ro', 203); 204 205#pod =attr wrap_numbers 206#pod 207#pod If set to true, during decoding, numeric values will be wrapped into 208#pod BSON type-wrappers: L<BSON::Double>, L<BSON::Int64> or L<BSON::Int32>. 209#pod While very slow, this can help ensure fields can round-trip if unmodified. 210#pod 211#pod The default is false. 212#pod 213#pod =cut 214 215has wrap_numbers => ( 216 is => 'ro', 217); 218 219#pod =attr wrap_strings 220#pod 221#pod If set to true, during decoding, string values will be wrapped into a BSON 222#pod type-wrappers, L<BSON::String>. While very slow, this can help ensure 223#pod fields can round-trip if unmodified. 224#pod 225#pod The default is false. 226#pod 227#pod =cut 228 229has wrap_strings => ( 230 is => 'ro', 231); 232 233#pod =attr dt_type (Discouraged) 234#pod 235#pod Sets the type of object which is returned for BSON DateTime fields. The 236#pod default is C<undef>, which returns objects of type L<BSON::Time>. This is 237#pod overloaded to be the integer epoch value when used as a number or string, 238#pod so is somewhat backwards compatible with C<dt_type> in the L<MongoDB> 239#pod driver. 240#pod 241#pod Other acceptable values are L<BSON::Time> (explicitly), L<DateTime>, 242#pod L<Time::Moment>, L<DateTime::Tiny>, L<Mango::BSON::Time>. 243#pod 244#pod Because BSON::Time objects have methods to convert to DateTime, 245#pod Time::Moment or DateTime::Tiny, use of this field is discouraged. Users 246#pod should use these methods on demand. This option is provided for backwards 247#pod compatibility only. 248#pod 249#pod =cut 250 251has dt_type => ( 252 is => 'ro', 253 isa => sub { return if !defined($_[0]); die "not a string" if ref $_[0] }, 254); 255 256sub BUILD { 257 my ($self) = @_; 258 $self->{wrap_dbrefs} = 1 unless defined $self->{wrap_dbrefs}; 259 $self->{invalid_chars} = "" unless defined $self->{invalid_chars}; 260} 261 262#--------------------------------------------------------------------------# 263# public methods 264#--------------------------------------------------------------------------# 265 266#pod =method encode_one 267#pod 268#pod $byte_string = $codec->encode_one( $doc ); 269#pod $byte_string = $codec->encode_one( $doc, \%options ); 270#pod 271#pod Takes a "document", typically a hash reference, an array reference, or a 272#pod Tie::IxHash object and returns a byte string with the BSON representation of 273#pod the document. 274#pod 275#pod An optional hash reference of options may be provided. Valid options include: 276#pod 277#pod =for :list 278#pod * first_key – if C<first_key> is defined, it and C<first_value> 279#pod will be encoded first in the output BSON; any matching key found in the 280#pod document will be ignored. 281#pod * first_value - value to assign to C<first_key>; will encode as Null if omitted 282#pod * error_callback – overrides codec default 283#pod * invalid_chars – overrides codec default 284#pod * max_length – overrides codec default 285#pod * op_char – overrides codec default 286#pod * prefer_numeric – overrides codec default 287#pod 288#pod =cut 289 290sub encode_one { 291 my ( $self, $document, $options ) = @_; 292 my $type = ref($document); 293 294 Carp::croak "Can't encode scalars" unless $type; 295 # qr// is blessed to 'Regexp'; 296 if ( $type eq "Regexp" 297 || !( blessed($document) || $type eq 'HASH' || $type eq 'ARRAY' ) ) 298 { 299 Carp::croak "Can't encode non-container of type '$type'"; 300 } 301 302 $document = BSON::Doc->new(@$document) 303 if $type eq 'ARRAY'; 304 305 my $merged_opts = { %$self, ( $options ? %$options : () ) }; 306 307 my $bson = eval { _encode_bson( $document, $merged_opts ) }; 308 # XXX this is a late max_length check -- it should be checked during 309 # encoding after each key 310 if ( $@ or ( $merged_opts->{max_length} && length($bson) > $merged_opts->{max_length} ) ) { 311 my $msg = $@ || "Document exceeds maximum size $merged_opts->{max_length}"; 312 if ( $merged_opts->{error_callback} ) { 313 $merged_opts->{error_callback}->( $msg, $document, 'encode_one' ); 314 } 315 else { 316 Carp::croak("During encode_one, $msg"); 317 } 318 } 319 320 return $bson; 321} 322 323#pod =method decode_one 324#pod 325#pod $doc = $codec->decode_one( $byte_string ); 326#pod $doc = $codec->decode_one( $byte_string, \%options ); 327#pod 328#pod Takes a byte string with a BSON-encoded document and returns a 329#pod hash reference representing the decoded document. 330#pod 331#pod An optional hash reference of options may be provided. Valid options include: 332#pod 333#pod =for :list 334#pod * dt_type – overrides codec default 335#pod * error_callback – overrides codec default 336#pod * max_length – overrides codec default 337#pod * ordered - overrides codec default 338#pod * wrap_dbrefs - overrides codec default 339#pod * wrap_numbers - overrides codec default 340#pod * wrap_strings - overrides codec default 341#pod 342#pod =cut 343 344sub decode_one { 345 my ( $self, $string, $options ) = @_; 346 347 my $merged_opts = { %$self, ( $options ? %$options : () ) }; 348 349 if ( $merged_opts->{max_length} && length($string) > $merged_opts->{max_length} ) { 350 my $msg = "Document exceeds maximum size $merged_opts->{max_length}"; 351 if ( $merged_opts->{error_callback} ) { 352 $merged_opts->{error_callback}->( $msg, \$string, 'decode_one' ); 353 } 354 else { 355 Carp::croak("During decode_one, $msg"); 356 } 357 } 358 359 my $document = eval { _decode_bson( $string, $merged_opts ) }; 360 if ( $@ ) { 361 if ( $merged_opts->{error_callback} ) { 362 $merged_opts->{error_callback}->( $@, \$string, 'decode_one' ); 363 } 364 else { 365 Carp::croak("During decode_one, $@"); 366 } 367 } 368 369 return $document; 370} 371 372#pod =method clone 373#pod 374#pod $copy = $codec->clone( ordered => 1 ); 375#pod 376#pod Constructs a copy of the original codec, but allows changing 377#pod attributes in the copy. 378#pod 379#pod =cut 380 381sub clone { 382 my ($self, @args) = @_; 383 my $class = ref($self); 384 if ( @args == 1 && ref( $args[0] ) eq 'HASH' ) { 385 return $class->new( %$self, %{$args[0]} ); 386 } 387 388 return $class->new( %$self, @args ); 389} 390 391 392#--------------------------------------------------------------------------# 393# public class methods 394#--------------------------------------------------------------------------# 395 396#pod =method create_oid 397#pod 398#pod $oid = BSON->create_oid; 399#pod 400#pod This class method returns a new L<BSON::OID>. This abstracts OID 401#pod generation away from any specific Object ID class and makes it an interface 402#pod on a BSON codec. Alternative BSON codecs should define a similar class 403#pod method that returns an Object ID of whatever type is appropriate. 404#pod 405#pod =cut 406 407sub create_oid { return BSON::OID->new } 408 409#pod =method inflate_extjson (DEPRECATED) 410#pod 411#pod This legacy method does not follow the L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 412#pod specification. 413#pod 414#pod Use L</extjson_to_perl> instead. 415#pod 416#pod =cut 417 418sub inflate_extjson { 419 my ( $self, $hash ) = @_; 420 421 for my $k ( keys %$hash ) { 422 my $v = $hash->{$k}; 423 if ( substr( $k, 0, 1 ) eq '$' ) { 424 croak "Dollar-prefixed key '$k' is not legal in top-level hash"; 425 } 426 my $type = ref($v); 427 $hash->{$k} = 428 $type eq 'HASH' ? $self->_inflate_hash($v) 429 : $type eq 'ARRAY' ? $self->_inflate_array($v) 430 : $type =~ $bools_re ? ( $v ? true : false ) 431 : $v; 432 } 433 434 return $hash; 435} 436 437#pod =method perl_to_extjson 438#pod 439#pod use JSON::MaybeXS; 440#pod my $ext = BSON->perl_to_extjson($data, \%options); 441#pod my $json = encode_json($ext); 442#pod 443#pod Takes a perl data structure (i.e. hashref) and turns it into an 444#pod L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 445#pod structure. Note that the structure will still have to be serialized. 446#pod 447#pod Possible options are: 448#pod 449#pod =for :list 450#pod * C<relaxed> A boolean indicating if "relaxed extended JSON" should 451#pod be generated. If not set, the default value is taken from the 452#pod C<BSON_EXTJSON_RELAXED> environment variable. 453#pod 454#pod =cut 455 456my $use_win32_specials = ($^O eq 'MSWin32' && $] lt "5.022"); 457 458my $is_inf = $use_win32_specials ? qr/^1.\#INF/i : qr/^inf/i; 459my $is_ninf = $use_win32_specials ? qr/^-1.\#INF/i : qr/^-inf/i; 460my $is_nan = $use_win32_specials ? qr/^-?1.\#(?:IND|QNAN)/i : qr/^-?nan/i; 461 462sub perl_to_extjson { 463 my ($class, $data, $options) = @_; 464 465 local $ENV{BSON_EXTJSON} = 1; 466 local $ENV{BSON_EXTJSON_RELAXED} = $ENV{BSON_EXTJSON_RELAXED}; 467 $ENV{BSON_EXTJSON_RELAXED} = $options->{relaxed}; 468 469 if (not defined $data) { 470 return undef; ## no critic 471 } 472 473 if (blessed($data) and $data->can('TO_JSON')) { 474 my $json_data = $data->TO_JSON; 475 return $json_data; 476 } 477 478 if (not ref $data) { 479 480 if (looks_like_number($data)) { 481 if ($ENV{BSON_EXTJSON_RELAXED}) { 482 return $data; 483 } 484 485 if ($data =~ m{\A-?[0-9_]+\z}) { 486 if ($data <= $max_int32) { 487 return { '$numberInt' => "$data" }; 488 } 489 else { 490 return { '$numberLong' => "$data" }; 491 } 492 } 493 else { 494 return { '$numberDouble' => 'Infinity' } 495 if $data =~ $is_inf; 496 return { '$numberDouble' => '-Infinity' } 497 if $data =~ $is_ninf; 498 return { '$numberDouble' => 'NaN' } 499 if $data =~ $is_nan; 500 my $value = "$data"; 501 $value = $value / 1.0; 502 return { '$numberDouble' => "$value" }; 503 } 504 } 505 506 return $data; 507 } 508 509 if (boolean::isBoolean($data)) { 510 return $data; 511 } 512 513 if (ref $data eq 'HASH') { 514 for my $key (keys %$data) { 515 my $value = $data->{$key}; 516 $data->{$key} = $class->perl_to_extjson($value, $options); 517 } 518 return $data; 519 } 520 521 if (ref $data eq 'ARRAY') { 522 for my $index (0 .. $#$data) { 523 my $value = $data->[$index]; 524 $data->[$index] = $class->perl_to_extjson($value, $options); 525 } 526 return $data; 527 } 528 529 if (blessed($data) and $data->isa('JSON::PP::Boolean')) { 530 return $data; 531 } 532 533 if ( 534 blessed($data) and ( 535 $data->isa('Math::BigInt') or 536 $data->isa('Math::BigFloat') 537 ) 538 ) { 539 return $data; 540 } 541 542 die sprintf "Unsupported ref value (%s)", ref($data); 543} 544 545#pod =method extjson_to_perl 546#pod 547#pod use JSON::MaybeXS; 548#pod my $ext = decode_json($json); 549#pod my $data = $bson->extjson_to_perl($ext); 550#pod 551#pod Takes an 552#pod L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 553#pod data structure and inflates it into a Perl data structure. Note that 554#pod you have to decode the JSON string manually beforehand. 555#pod 556#pod Canonically specified numerical values like C<{"$numberInt":"23"}> will 557#pod be inflated into their respective C<BSON::*> wrapper types. Plain numeric 558#pod values will be left as-is. 559#pod 560#pod =cut 561 562sub extjson_to_perl { 563 my ($class, $data) = @_; 564 # top level keys are never extended JSON elements, so we wrap the 565 # _extjson_to_perl inflater so it applies only to values, not the 566 # original data structure 567 for my $key (keys %$data) { 568 my $value = $data->{$key}; 569 $data->{$key} = $class->_extjson_to_perl($value); 570 } 571 return $data; 572} 573 574sub _extjson_to_perl { 575 my ($class, $data) = @_; 576 577 if (ref $data eq 'HASH') { 578 579 if ( exists $data->{'$oid'} ) { 580 return BSON::OID->new( oid => pack( "H*", $data->{'$oid'} ) ); 581 } 582 583 if ( exists $data->{'$numberInt'} ) { 584 return BSON::Int32->new( value => $data->{'$numberInt'} ); 585 } 586 587 if ( exists $data->{'$numberLong'} ) { 588 if (HAS_INT64) { 589 return BSON::Int64->new( value => $data->{'$numberLong'} ); 590 } 591 else { 592 return BSON::Int64->new( value => Math::BigInt->new($data->{'$numberLong'}) ); 593 } 594 } 595 596 if ( exists $data->{'$binary'} ) { 597 require MIME::Base64; 598 if (exists $data->{'$type'}) { 599 return BSON::Bytes->new( 600 data => MIME::Base64::decode_base64($data->{'$binary'}), 601 subtype => hex( $data->{'$type'} || 0 ), 602 ); 603 } 604 else { 605 my $value = $data->{'$binary'}; 606 return BSON::Bytes->new( 607 data => MIME::Base64::decode_base64($value->{base64}), 608 subtype => hex( $value->{subType} || 0 ), 609 ); 610 } 611 } 612 613 if ( exists $data->{'$date'} ) { 614 my $v = $data->{'$date'}; 615 $v = ref($v) eq 'HASH' ? $class->_extjson_to_perl($v) : _iso8601_to_epochms($v); 616 return BSON::Time->new( value => $v ); 617 } 618 619 if ( exists $data->{'$minKey'} ) { 620 return BSON::MinKey->new; 621 } 622 623 if ( exists $data->{'$maxKey'} ) { 624 return BSON::MaxKey->new; 625 } 626 627 if ( exists $data->{'$timestamp'} ) { 628 return BSON::Timestamp->new( 629 seconds => $data->{'$timestamp'}{t}, 630 increment => $data->{'$timestamp'}{i}, 631 ); 632 } 633 634 if ( exists $data->{'$regex'} and not ref $data->{'$regex'}) { 635 return BSON::Regex->new( 636 pattern => $data->{'$regex'}, 637 ( exists $data->{'$options'} ? ( flags => $data->{'$options'} ) : () ), 638 ); 639 } 640 641 if ( exists $data->{'$regularExpression'} ) { 642 my $value = $data->{'$regularExpression'}; 643 return BSON::Regex->new( 644 pattern => $value->{pattern}, 645 ( exists $value->{options} ? ( flags => $value->{options} ) : () ), 646 ); 647 } 648 649 if ( exists $data->{'$code'} ) { 650 return BSON::Code->new( 651 code => $data->{'$code'}, 652 ( exists $data->{'$scope'} 653 ? ( scope => $class->_extjson_to_perl($data->{'$scope'}) ) 654 : () 655 ), 656 ); 657 } 658 659 if ( exists $data->{'$undefined'} ) { 660 return undef; ## no critic 661 } 662 663 if ( exists $data->{'$dbPointer'} ) { 664 my $data = $data->{'$dbPointer'}; 665 my $id = $data->{'$id'}; 666 $id = $class->_extjson_to_perl($id) if ref($id) eq 'HASH'; 667 return BSON::DBPointer->new( 668 '$ref' => $data->{'$ref'}, 669 '$id' => $id, 670 ); 671 } 672 673 if ( exists $data->{'$ref'} ) { 674 my $id = delete $data->{'$id'}; 675 $id = $class->_extjson_to_perl($id) if ref($id) eq 'HASH'; 676 return BSON::DBRef->new( 677 '$ref' => delete $data->{'$ref'}, 678 '$id' => $id, 679 '$db' => delete $data->{'$db'}, 680 %$data, # extra 681 ); 682 } 683 684 if ( exists $data->{'$numberDecimal'} ) { 685 return BSON::Decimal128->new( value => $data->{'$numberDecimal'} ); 686 } 687 688 # Following extended JSON is non-standard 689 690 if ( exists $data->{'$numberDouble'} ) { 691 if ( $data->{'$numberDouble'} eq '-0' && $] lt '5.014' && ! HAS_LD ) { 692 $data->{'$numberDouble'} = '-0.0'; 693 } 694 return BSON::Double->new( value => $data->{'$numberDouble'} ); 695 } 696 697 if ( exists $data->{'$symbol'} ) { 698 return BSON::Symbol->new(value => $data->{'$symbol'}); 699 } 700 701 for my $key (keys %$data) { 702 my $value = $data->{$key}; 703 $data->{$key} = $class->_extjson_to_perl($value); 704 } 705 return $data; 706 } 707 708 if (ref $data eq 'ARRAY') { 709 for my $index (0 .. $#$data) { 710 my $value = $data->[$index]; 711 $data->[$index] = ref($value) 712 ? $class->_extjson_to_perl($value) 713 : $value; 714 } 715 return $data; 716 } 717 718 return $data; 719} 720 721#--------------------------------------------------------------------------# 722# legacy functional interface 723#--------------------------------------------------------------------------# 724 725#pod =func encode 726#pod 727#pod my $bson = encode({ bar => 'foo' }, \%options); 728#pod 729#pod This is the legacy, functional interface and is only exported on demand. 730#pod It takes a hashref and returns a BSON string. 731#pod It uses an internal codec singleton with default attributes. 732#pod 733#pod =func decode 734#pod 735#pod my $hash = decode( $bson, \%options ); 736#pod 737#pod This is the legacy, functional interface and is only exported on demand. 738#pod It takes a BSON string and returns a hashref. 739#pod It uses an internal codec singleton with default attributes. 740#pod 741#pod =cut 742 743{ 744 my $CODEC; 745 746 sub encode { 747 if ( defined $_[0] && ( $_[0] eq 'BSON' || ( blessed($_[0]) && $_[0]->isa('BSON') ) ) ) { 748 Carp::croak("Error: 'encode' is a function, not a method"); 749 } 750 my $doc = shift; 751 $CODEC = BSON->new unless defined $CODEC; 752 if ( @_ == 1 && ref( $_[0] ) eq 'HASH' ) { 753 return $CODEC->encode_one( $doc, $_[0] ); 754 } 755 elsif ( @_ % 2 == 0 ) { 756 return $CODEC->encode_one( $doc, {@_} ); 757 } 758 else { 759 Carp::croak("Options for 'encode' must be a hashref or key-value pairs"); 760 } 761 } 762 763 sub decode { 764 if ( defined $_[0] && ( $_[0] eq 'BSON' || ( blessed($_[0]) && $_[0]->isa('BSON') ) ) ) { 765 Carp::croak("Error: 'decode' is a function, not a method"); 766 } 767 my $doc = shift; 768 $CODEC = BSON->new unless defined $CODEC; 769 my $args; 770 if ( @_ == 1 && ref( $_[0] ) eq 'HASH' ) { 771 $args = shift; 772 } 773 elsif ( @_ % 2 == 0 ) { 774 $args = { @_ }; 775 } 776 else { 777 Carp::croak("Options for 'decode' must be a hashref or key-value pairs"); 778 } 779 $args->{ordered} = delete $args->{ixhash} 780 if exists $args->{ixhash} && !exists $args->{ordered}; 781 return $CODEC->decode_one( $doc, $args ); 782 } 783} 784 785#--------------------------------------------------------------------------# 786# private functions 787#--------------------------------------------------------------------------# 788 789sub _inflate_hash { 790 my ( $class, $hash ) = @_; 791 792 if ( exists $hash->{'$oid'} ) { 793 return BSON::OID->new( oid => pack( "H*", $hash->{'$oid'} ) ); 794 } 795 796 if ( exists $hash->{'$numberInt'} ) { 797 return BSON::Int32->new( value => $hash->{'$numberInt'} ); 798 } 799 800 if ( exists $hash->{'$numberLong'} ) { 801 if (HAS_INT64) { 802 return BSON::Int64->new( value => $hash->{'$numberLong'} ); 803 } 804 else { 805 return BSON::Int64->new( value => Math::BigInt->new($hash->{'$numberLong'}) ); 806 } 807 } 808 809 if ( exists $hash->{'$binary'} ) { 810 require MIME::Base64; 811 return BSON::Bytes->new( 812 data => MIME::Base64::decode_base64($hash->{'$binary'}), 813 subtype => hex( $hash->{'$type'} || 0 ) 814 ); 815 } 816 817 if ( exists $hash->{'$date'} ) { 818 my $v = $hash->{'$date'}; 819 $v = ref($v) eq 'HASH' ? BSON->_inflate_hash($v) : _iso8601_to_epochms($v); 820 return BSON::Time->new( value => $v ); 821 } 822 823 if ( exists $hash->{'$minKey'} ) { 824 return BSON::MinKey->new; 825 } 826 827 if ( exists $hash->{'$maxKey'} ) { 828 return BSON::MaxKey->new; 829 } 830 831 if ( exists $hash->{'$timestamp'} ) { 832 return BSON::Timestamp->new( 833 seconds => $hash->{'$timestamp'}{t}, 834 increment => $hash->{'$timestamp'}{i}, 835 ); 836 } 837 838 if ( exists $hash->{'$regex'} ) { 839 return BSON::Regex->new( 840 pattern => $hash->{'$regex'}, 841 ( exists $hash->{'$options'} ? ( flags => $hash->{'$options'} ) : () ), 842 ); 843 } 844 845 if ( exists $hash->{'$code'} ) { 846 return BSON::Code->new( 847 code => $hash->{'$code'}, 848 ( exists $hash->{'$scope'} ? ( scope => $hash->{'$scope'} ) : () ), 849 ); 850 } 851 852 if ( exists $hash->{'$undefined'} ) { 853 return undef; ## no critic 854 } 855 856 if ( exists $hash->{'$ref'} ) { 857 my $id = $hash->{'$id'}; 858 $id = BSON->_inflate_hash($id) if ref($id) eq 'HASH'; 859 return BSON::DBRef->new( '$ref' => $hash->{'$ref'}, '$id' => $id ); 860 } 861 862 if ( exists $hash->{'$numberDecimal'} ) { 863 return BSON::Decimal128->new( value => $hash->{'$numberDecimal'} ); 864 } 865 866 # Following extended JSON is non-standard 867 868 if ( exists $hash->{'$numberDouble'} ) { 869 if ( $hash->{'$numberDouble'} eq '-0' && $] lt '5.014' && ! HAS_LD ) { 870 $hash->{'$numberDouble'} = '-0.0'; 871 } 872 return BSON::Double->new( value => $hash->{'$numberDouble'} ); 873 } 874 875 if ( exists $hash->{'$symbol'} ) { 876 return $hash->{'$symbol'}; 877 } 878 879 return $hash; 880} 881 882sub _inflate_array { 883 my ($class, $array) = @_; 884 if (@$array) { 885 for my $i ( 0 .. $#$array ) { 886 my $v = $array->[$i]; 887 $array->[$i] = 888 ref($v) eq 'HASH' ? BSON->_inflate_hash($v) 889 : ref($v) eq 'ARRAY' ? _inflate_array($v) 890 : $v; 891 } 892 } 893 return $array; 894} 895 896my $iso8601_re = qr{ 897 (\d{4}) - (\d{2}) - (\d{2}) T # date 898 (\d{2}) : (\d{2}) : ( \d+ (?:\. \d+ )? ) # time 899 (?: Z | ([+-] \d{2} :? (?: \d{2} )? ) )? # maybe TZ 900}x; 901 902sub _iso8601_to_epochms { 903 my ($date) = shift; 904 require Time::Local; 905 906 my $zone_offset = 0;; 907 if ( substr($date,-1,1) eq 'Z' ) { 908 chop($date); 909 } 910 911 if ( $date =~ /\A$iso8601_re\z/ ) { 912 my ($Y,$M,$D,$h,$m,$s,$z) = ($1,$2-1,$3,$4,$5,$6,$7); 913 if (defined($z) && length($z)) { 914 $z =~ tr[:][]; 915 $z .= "00" if length($z) < 5; 916 my $zd = substr($z,0,1); 917 my $zh = substr($z,1,2); 918 my $zm = substr($z,3,2); 919 $zone_offset = ($zd eq '-' ? -1 : 1 ) * (3600 * $zh + 60 * $zm); 920 } 921 my $frac = $s - int($s); 922 my $epoch = Time::Local::timegm(int($s), $m, $h, $D, $M, $Y) - $zone_offset; 923 $epoch = HAS_INT64 ? 1000 * $epoch : Math::BigInt->new($epoch) * 1000; 924 $epoch += HAS_INT64 ? $frac * 1000 : Math::BigFloat->new($frac) * 1000; 925 return $epoch; 926 } 927 else { 928 Carp::croak("Couldn't parse '\$date' field: $date\n"); 929 } 930} 931 9321; 933 934=pod 935 936=encoding UTF-8 937 938=head1 NAME 939 940BSON - BSON serialization and deserialization (EOL) 941 942=head1 VERSION 943 944version v1.12.2 945 946=head1 END OF LIFE NOTICE 947 948Version v1.12.0 was the final feature release of the MongoDB BSON library 949and version v1.12.2 is the final patch release. 950 951B<As of August 13, 2020, the MongoDB Perl driver and related libraries have 952reached end of life and are no longer supported by MongoDB.> See the 953L<August 2019 deprecation 954notice|https://www.mongodb.com/blog/post/the-mongodb-perl-driver-is-being-deprecated> 955for rationale. 956 957If members of the community wish to continue development, they are welcome 958to fork the code under the terms of the Apache 2 license and release it 959under a new namespace. Specifications and test files for MongoDB drivers 960and libraries are published in an open repository: 961L<mongodb/specifications|https://github.com/mongodb/specifications/tree/master/source>. 962 963=head1 SYNOPSIS 964 965 use BSON; 966 use BSON::Types ':all'; 967 use boolean; 968 969 my $codec = BSON->new; 970 971 my $document = { 972 _id => bson_oid(), 973 creation_time => bson_time(), # now 974 zip_code => bson_string("08544"), 975 hidden => false, 976 }; 977 978 my $bson = $codec->encode_one( $document ); 979 my $doc = $codec->decode_one( $bson ); 980 981=head1 DESCRIPTION 982 983This class implements a BSON encoder/decoder ("codec"). It consumes 984"documents" (typically hash references) and emits BSON strings and vice 985versa in accordance with the L<BSON Specification|http://bsonspec.org>. 986 987BSON is the primary data representation for L<MongoDB>. While this module 988has several features that support MongoDB-specific needs and conventions, 989it can be used as a standalone serialization format. 990 991The codec may be customized through attributes on the codec option as well 992as encode/decode specific options on methods: 993 994 my $codec = BSON->new( \%global_attributes ); 995 996 my $bson = $codec->encode_one( $document, \%encode_options ); 997 my $doc = $codec->decode_one( $bson , \%decode_options ); 998 999Because BSON is strongly-typed and Perl is not, this module supports 1000a number of "type wrappers" – classes that wrap Perl data to indicate how 1001they should serialize. The L<BSON::Types> module describes these and 1002provides associated helper functions. See L</PERL-BSON TYPE MAPPING> 1003for more details. 1004 1005When decoding, type wrappers are used for any data that has no native Perl 1006representation. Optionally, all data may be wrapped for precise control of 1007round-trip encoding. 1008 1009Please read the configuration attributes carefully to understand more about 1010how to control encoding and decoding. 1011 1012At compile time, this module will select an implementation backend. It 1013will prefer C<BSON::XS> (released separately) if available, or will fall 1014back to L<BSON::PP> (bundled with this module). See L</ENVIRONMENT> for 1015a way to control the selection of the backend. 1016 1017=head1 ATTRIBUTES 1018 1019=head2 error_callback 1020 1021This attribute specifies a function reference that will be called with 1022three positional arguments: 1023 1024=over 4 1025 1026=item * 1027 1028an error string argument describing the error condition 1029 1030=item * 1031 1032a reference to the problematic document or byte-string 1033 1034=item * 1035 1036the method in which the error occurred (e.g. C<encode_one> or C<decode_one>) 1037 1038=back 1039 1040Note: for decoding errors, the byte-string is passed as a reference to avoid 1041copying possibly large strings. 1042 1043If not provided, errors messages will be thrown with C<Carp::croak>. 1044 1045=head2 invalid_chars 1046 1047A string containing ASCII characters that must not appear in keys. The default 1048is the empty string, meaning there are no invalid characters. 1049 1050=head2 max_length 1051 1052This attribute defines the maximum document size. The default is 0, which 1053disables any maximum. 1054 1055If set to a positive number, it applies to both encoding B<and> decoding (the 1056latter is necessary for prevention of resource consumption attacks). 1057 1058=head2 op_char 1059 1060This is a single character to use for special MongoDB-specific query 1061operators. If a key starts with C<op_char>, the C<op_char> character will 1062be replaced with "$". 1063 1064The default is "$", meaning that no replacement is necessary. 1065 1066=head2 ordered 1067 1068If set to a true value, then decoding will return a reference to a tied 1069hash that preserves key order. Otherwise, a regular (unordered) hash 1070reference will be returned. 1071 1072B<IMPORTANT CAVEATS>: 1073 1074=over 4 1075 1076=item * 1077 1078When 'ordered' is true, users must not rely on the return value being any particular tied hash implementation. It may change in the future for efficiency. 1079 1080=item * 1081 1082Turning this option on entails a significant speed penalty as tied hashes are slower than regular Perl hashes. 1083 1084=back 1085 1086The default is false. 1087 1088=head2 prefer_numeric 1089 1090When false, scalar values will be encoded as a number if they were 1091originally a number or were ever used in a numeric context. However, a 1092string that looks like a number but was never used in a numeric context 1093(e.g. "42") will be encoded as a string. 1094 1095If C<prefer_numeric> is set to true, the encoder will attempt to coerce 1096strings that look like a number into a numeric value. If the string 1097doesn't look like a double or integer, it will be encoded as a string. 1098 1099B<IMPORTANT CAVEAT>: the heuristics for determining whether something is a 1100string or number are less accurate on older Perls. See L<BSON::Types> 1101for wrapper classes that specify exact serialization types. 1102 1103The default is false. 1104 1105=head2 wrap_dbrefs 1106 1107If set to true, during decoding, documents with the fields C<'$id'> and 1108C<'$ref'> (literal dollar signs, not variables) will be wrapped as 1109L<BSON::DBRef> objects. If false, they are decoded into ordinary hash 1110references (or ordered hashes, if C<ordered> is true). 1111 1112The default is true. 1113 1114=head2 wrap_numbers 1115 1116If set to true, during decoding, numeric values will be wrapped into 1117BSON type-wrappers: L<BSON::Double>, L<BSON::Int64> or L<BSON::Int32>. 1118While very slow, this can help ensure fields can round-trip if unmodified. 1119 1120The default is false. 1121 1122=head2 wrap_strings 1123 1124If set to true, during decoding, string values will be wrapped into a BSON 1125type-wrappers, L<BSON::String>. While very slow, this can help ensure 1126fields can round-trip if unmodified. 1127 1128The default is false. 1129 1130=head2 dt_type (Discouraged) 1131 1132Sets the type of object which is returned for BSON DateTime fields. The 1133default is C<undef>, which returns objects of type L<BSON::Time>. This is 1134overloaded to be the integer epoch value when used as a number or string, 1135so is somewhat backwards compatible with C<dt_type> in the L<MongoDB> 1136driver. 1137 1138Other acceptable values are L<BSON::Time> (explicitly), L<DateTime>, 1139L<Time::Moment>, L<DateTime::Tiny>, L<Mango::BSON::Time>. 1140 1141Because BSON::Time objects have methods to convert to DateTime, 1142Time::Moment or DateTime::Tiny, use of this field is discouraged. Users 1143should use these methods on demand. This option is provided for backwards 1144compatibility only. 1145 1146=head1 METHODS 1147 1148=head2 encode_one 1149 1150 $byte_string = $codec->encode_one( $doc ); 1151 $byte_string = $codec->encode_one( $doc, \%options ); 1152 1153Takes a "document", typically a hash reference, an array reference, or a 1154Tie::IxHash object and returns a byte string with the BSON representation of 1155the document. 1156 1157An optional hash reference of options may be provided. Valid options include: 1158 1159=over 4 1160 1161=item * 1162 1163first_key – if C<first_key> is defined, it and C<first_value> will be encoded first in the output BSON; any matching key found in the document will be ignored. 1164 1165=item * 1166 1167first_value - value to assign to C<first_key>; will encode as Null if omitted 1168 1169=item * 1170 1171error_callback – overrides codec default 1172 1173=item * 1174 1175invalid_chars – overrides codec default 1176 1177=item * 1178 1179max_length – overrides codec default 1180 1181=item * 1182 1183op_char – overrides codec default 1184 1185=item * 1186 1187prefer_numeric – overrides codec default 1188 1189=back 1190 1191=head2 decode_one 1192 1193 $doc = $codec->decode_one( $byte_string ); 1194 $doc = $codec->decode_one( $byte_string, \%options ); 1195 1196Takes a byte string with a BSON-encoded document and returns a 1197hash reference representing the decoded document. 1198 1199An optional hash reference of options may be provided. Valid options include: 1200 1201=over 4 1202 1203=item * 1204 1205dt_type – overrides codec default 1206 1207=item * 1208 1209error_callback – overrides codec default 1210 1211=item * 1212 1213max_length – overrides codec default 1214 1215=item * 1216 1217ordered - overrides codec default 1218 1219=item * 1220 1221wrap_dbrefs - overrides codec default 1222 1223=item * 1224 1225wrap_numbers - overrides codec default 1226 1227=item * 1228 1229wrap_strings - overrides codec default 1230 1231=back 1232 1233=head2 clone 1234 1235 $copy = $codec->clone( ordered => 1 ); 1236 1237Constructs a copy of the original codec, but allows changing 1238attributes in the copy. 1239 1240=head2 create_oid 1241 1242 $oid = BSON->create_oid; 1243 1244This class method returns a new L<BSON::OID>. This abstracts OID 1245generation away from any specific Object ID class and makes it an interface 1246on a BSON codec. Alternative BSON codecs should define a similar class 1247method that returns an Object ID of whatever type is appropriate. 1248 1249=head2 inflate_extjson (DEPRECATED) 1250 1251This legacy method does not follow the L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 1252specification. 1253 1254Use L</extjson_to_perl> instead. 1255 1256=head2 perl_to_extjson 1257 1258 use JSON::MaybeXS; 1259 my $ext = BSON->perl_to_extjson($data, \%options); 1260 my $json = encode_json($ext); 1261 1262Takes a perl data structure (i.e. hashref) and turns it into an 1263L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 1264structure. Note that the structure will still have to be serialized. 1265 1266Possible options are: 1267 1268=over 4 1269 1270=item * 1271 1272C<relaxed> A boolean indicating if "relaxed extended JSON" should 1273 1274be generated. If not set, the default value is taken from the 1275C<BSON_EXTJSON_RELAXED> environment variable. 1276 1277=back 1278 1279=head2 extjson_to_perl 1280 1281 use JSON::MaybeXS; 1282 my $ext = decode_json($json); 1283 my $data = $bson->extjson_to_perl($ext); 1284 1285Takes an 1286L<MongoDB Extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> 1287data structure and inflates it into a Perl data structure. Note that 1288you have to decode the JSON string manually beforehand. 1289 1290Canonically specified numerical values like C<{"$numberInt":"23"}> will 1291be inflated into their respective C<BSON::*> wrapper types. Plain numeric 1292values will be left as-is. 1293 1294=head1 FUNCTIONS 1295 1296=head2 encode 1297 1298 my $bson = encode({ bar => 'foo' }, \%options); 1299 1300This is the legacy, functional interface and is only exported on demand. 1301It takes a hashref and returns a BSON string. 1302It uses an internal codec singleton with default attributes. 1303 1304=head2 decode 1305 1306 my $hash = decode( $bson, \%options ); 1307 1308This is the legacy, functional interface and is only exported on demand. 1309It takes a BSON string and returns a hashref. 1310It uses an internal codec singleton with default attributes. 1311 1312=for Pod::Coverage BUILD 1313 1314=head1 PERL-BSON TYPE MAPPING 1315 1316BSON has numerous data types and Perl does not. 1317 1318When B<decoding>, each BSON type should result in a single, predictable 1319Perl type. Where no native Perl type is appropriate, BSON decodes to an 1320object of a particular class (a "type wrapper"). 1321 1322When B<encoding>, for historical reasons, there may be many Perl 1323representations that should encode to a particular BSON type. For example, 1324all the popular "boolean" type modules on CPAN should encode to the BSON 1325boolean type. Likewise, as this module is intended to supersede the 1326type wrappers that have shipped with the L<MongoDB> module, those 1327type wrapper are supported by this codec. 1328 1329The table below describes the BSON/Perl mapping for both encoding and 1330decoding. 1331 1332On the left are all the Perl types or classes this BSON codec 1333knows how to serialize to BSON. The middle column is the BSON type for 1334each class. The right-most column is the Perl type or class that the BSON 1335type deserializes to. Footnotes indicate variations or special behaviors. 1336 1337 Perl type/class -> BSON type -> Perl type/class 1338 ------------------------------------------------------------------- 1339 float[1] 0x01 DOUBLE float[2] 1340 BSON::Double 1341 ------------------------------------------------------------------- 1342 string[3] 0x02 UTF8 string[2] 1343 BSON::String 1344 ------------------------------------------------------------------- 1345 hashref 0x03 DOCUMENT hashref[4][5] 1346 BSON::Doc 1347 BSON::Raw 1348 MongoDB::BSON::Raw[d] 1349 Tie::IxHash 1350 ------------------------------------------------------------------- 1351 arrayref 0x04 ARRAY arrayref 1352 ------------------------------------------------------------------- 1353 BSON::Bytes 0x05 BINARY BSON::Bytes 1354 scalarref 1355 BSON::Binary[d] 1356 MongoDB::BSON::Binary[d] 1357 ------------------------------------------------------------------- 1358 n/a 0x06 UNDEFINED[d] undef 1359 ------------------------------------------------------------------- 1360 BSON::OID 0x07 OID BSON::OID 1361 BSON::ObjectId[d] 1362 MongoDB::OID[d] 1363 ------------------------------------------------------------------- 1364 boolean 0x08 BOOL boolean 1365 BSON::Bool[d] 1366 JSON::XS::Boolean 1367 JSON::PP::Boolean 1368 JSON::Tiny::_Bool 1369 Mojo::JSON::_Bool 1370 Cpanel::JSON::XS::Boolean 1371 Types::Serialiser::Boolean 1372 ------------------------------------------------------------------- 1373 BSON::Time 0x09 DATE_TIME BSON::Time 1374 DateTime 1375 DateTime::Tiny 1376 Time::Moment 1377 Mango::BSON::Time 1378 ------------------------------------------------------------------- 1379 undef 0x0a NULL undef 1380 ------------------------------------------------------------------- 1381 BSON::Regex 0x0b REGEX BSON::Regex 1382 qr// reference 1383 MongoDB::BSON::Regexp[d] 1384 ------------------------------------------------------------------- 1385 n/a 0x0c DBPOINTER[d] BSON::DBRef 1386 ------------------------------------------------------------------- 1387 BSON::Code[6] 0x0d CODE BSON::Code 1388 MongoDB::Code[6] 1389 ------------------------------------------------------------------- 1390 n/a 0x0e SYMBOL[d] string 1391 ------------------------------------------------------------------- 1392 BSON::Code[6] 0x0f CODEWSCOPE BSON::Code 1393 MongoDB::Code[6] 1394 ------------------------------------------------------------------- 1395 integer[7][8] 0x10 INT32 integer[2] 1396 BSON::Int32 1397 ------------------------------------------------------------------- 1398 BSON::Timestamp 0x11 TIMESTAMP BSON::Timestamp 1399 MongoDB::Timestamp[d] 1400 ------------------------------------------------------------------- 1401 integer[7] 0x12 INT64 integer[2][9] 1402 BSON::Int64 1403 Math::BigInt 1404 Math::Int64 1405 ------------------------------------------------------------------- 1406 BSON::MaxKey 0x7F MAXKEY BSON::MaxKey 1407 MongoDB::MaxKey[d] 1408 ------------------------------------------------------------------- 1409 BSON::MinKey 0xFF MINKEY BSON::MinKey 1410 MongoDB::MinKey[d] 1411 1412 [d] Deprecated or soon to be deprecated. 1413 [1] Scalar with "NV" internal representation or a string that looks 1414 like a float if the 'prefer_numeric' option is true. 1415 [2] If the 'wrap_numbers' option is true, numeric types will be wrapped 1416 as BSON::Double, BSON::Int32 or BSON::Int64 as appropriate to ensure 1417 round-tripping. If the 'wrap_strings' option is true, strings will 1418 be wrapped as BSON::String, likewise. 1419 [3] Scalar without "NV" or "IV" representation and not identified as a 1420 number by notes [1] or [7]. 1421 [4] If 'ordered' option is set, will return a tied hash that preserves 1422 order (deprecated 'ixhash' option still works). 1423 [5] If the document appears to contain a DBRef and a 'dbref_callback' 1424 exists, that callback is executed with the deserialized document. 1425 [6] Code is serialized as CODE or CODEWSCOPE depending on whether a 1426 scope hashref exists in BSON::Code/MongoDB::Code. 1427 [7] Scalar with "IV" internal representation or a string that looks like 1428 an integer if the 'prefer_numeric' option is true. 1429 [8] Only if the integer fits in 32 bits. 1430 [9] On 32-bit platforms, 64-bit integers are deserialized to 1431 Math::BigInt objects (even if subsequently wrapped into 1432 BSON::Int64 if 'wrap_scalars' is true). 1433 1434=head1 THREADS 1435 1436Threads are never recommended in Perl, but this module is thread safe. 1437 1438=head1 ENVIRONMENT 1439 1440=over 4 1441 1442=item * 1443 1444PERL_BSON_BACKEND – if set at compile time, this will be treated as a module name. The module will be loaded and used as the BSON backend implementation. It must implement the same API as C<BSON::PP>. 1445 1446=item * 1447 1448BSON_EXTJSON - if set, serializing BSON type wrappers via C<TO_JSON> will produce Extended JSON v2 output. 1449 1450=item * 1451 1452BSON_EXTJSON_RELAXED - if producing Extended JSON output, if this is true, values will use the "Relaxed" form of Extended JSON, which sacrifices type round-tripping for improved human readability. 1453 1454=back 1455 1456=head1 SEMANTIC VERSIONING SCHEME 1457 1458Starting with BSON C<v0.999.0>, this module is using a "tick-tock" 1459three-part version-tuple numbering scheme: C<vX.Y.Z> 1460 1461=over 4 1462 1463=item * 1464 1465In stable releases, C<X> will be incremented for incompatible API changes. 1466 1467=item * 1468 1469Even-value increments of C<Y> indicate stable releases with new functionality. C<Z> will be incremented for bug fixes. 1470 1471=item * 1472 1473Odd-value increments of C<Y> indicate unstable ("development") releases that should not be used in production. C<Z> increments have no semantic meaning; they indicate only successive development releases. Development releases may have API-breaking changes, usually indicated by C<Y> equal to "999". 1474 1475=back 1476 1477=head1 HISTORY AND ROADMAP 1478 1479This module was originally written by Stefan G. In 2014, he graciously 1480transferred ongoing maintenance to MongoDB, Inc. 1481 1482The C<bson_xxxx> helper functions in L<BSON::Types> were inspired by similar 1483work in L<Mango::BSON> by Sebastian Riedel. 1484 1485=head1 AUTHORS 1486 1487=over 4 1488 1489=item * 1490 1491David Golden <david@mongodb.com> 1492 1493=item * 1494 1495Stefan G. <minimalist@lavabit.com> 1496 1497=back 1498 1499=head1 CONTRIBUTORS 1500 1501=for stopwords Eric Daniels Finn Olivier Duclos Pat Gunn Petr Písař Robert Sedlacek Thomas Bloor Tobias Leich Wallace Reis Yury Zavarin Oleg Kostyuk 1502 1503=over 4 1504 1505=item * 1506 1507Eric Daniels <eric.daniels@mongodb.com> 1508 1509=item * 1510 1511Finn <toyou1995@gmail.com> 1512 1513=item * 1514 1515Olivier Duclos <odc@cpan.org> 1516 1517=item * 1518 1519Pat Gunn <pgunn@mongodb.com> 1520 1521=item * 1522 1523Petr Písař <ppisar@redhat.com> 1524 1525=item * 1526 1527Robert Sedlacek <rs@474.at> 1528 1529=item * 1530 1531Thomas Bloor <tbsliver@shadow.cat> 1532 1533=item * 1534 1535Tobias Leich <email@froggs.de> 1536 1537=item * 1538 1539Wallace Reis <wallace@reis.me> 1540 1541=item * 1542 1543Yury Zavarin <yury.zavarin@gmail.com> 1544 1545=item * 1546 1547Oleg Kostyuk <cub@cpan.org> 1548 1549=back 1550 1551=head1 COPYRIGHT AND LICENSE 1552 1553This software is Copyright (c) 2020 by Stefan G. and MongoDB, Inc. 1554 1555This is free software, licensed under: 1556 1557 The Apache License, Version 2.0, January 2004 1558 1559=cut 1560 1561__END__ 1562 1563 1564# vim: set ts=4 sts=4 sw=4 et tw=75: 1565