File Coverage

blib/lib/BSON.pm
Criterion Covered Total %
statement 219 313 69.9
branch 116 214 54.2
condition 39 85 45.8
subroutine 27 32 84.3
pod 9 10 90.0
total 410 654 62.6


line stmt bran cond sub pod time code
1 71     71   7033524 use 5.010001;
  71         764  
2 71     71   398 use strict;
  71         101  
  71         1349  
3 71     71   281 use warnings;
  71         112  
  71         2494  
4              
5             package BSON;
6             # ABSTRACT: BSON serialization and deserialization (EOL)
7              
8 71     71   348 use base 'Exporter';
  71         101  
  71         11132  
9             our @EXPORT_OK = qw/encode decode/;
10              
11 71     71   785 use version;
  71         148523  
  71         345  
12             our $VERSION = 'v1.12.2';
13              
14 71     71   5687 use Carp;
  71         123  
  71         7986  
15 71     71   380 use Config;
  71         146  
  71         2408  
16 71     71   318 use Scalar::Util qw/blessed looks_like_number/;
  71         108  
  71         3492  
17              
18 71     71   649 use Moo 2.002004; # safer generated code
  71         785461  
  71         473  
19 71     71   20717 use boolean;
  71         143469  
  71         794  
20 71     71   10491 use BSON::OID;
  71         315  
  71         4021  
21              
22             use constant {
23             HAS_INT64 => $Config{use64bitint},
24             HAS_LD => $Config{uselongdouble},
25 71     71   575 };
  71         130  
  71         14589  
26              
27 71     71   756 use if !HAS_INT64, "Math::BigInt";
  71         41911  
  71         377  
28              
29             my $bools_re = qr/::(?:Boolean|_Bool|Bool)\z/;
30              
31 71     71   21167 use namespace::clean -except => 'meta';
  71         151  
  71         571  
32              
33             my $max_int32 = 2147483647;
34              
35             # Dependency-free equivalent of what we need from Module::Runtime
36             sub _try_load {
37 141     141   304 my ( $mod, $ver ) = @_;
38 141         622 ( my $file = "$mod.pm" ) =~ s{::}{/}g;
39 141 50       232 my $load = eval { require $file; $mod->VERSION($ver) if defined $ver; 1 };
  141         1198  
  71         443  
  71         178  
40 141 100       60911 delete $INC{$file} if !$load; # for old, broken perls
41 141 100       785 die $@ if !$load;
42 71         449 return 1;
43             }
44              
45             BEGIN {
46 71     71   51856 my ($class, @errs);
47 71 100 33     381 if ( $class = $ENV{PERL_BSON_BACKEND} ) {
    50 33        
    50          
48 1         1 eval { _try_load($class) };
  1         4  
49 1 50       4 if ( my $err = $@ ) {
50 0         0 $err =~ s{ at \S+ line .*}{};
51 0         0 die "Error: PERL_BSON_BACKEND '$class' could not be loaded: $err\n";
52             }
53 1 50 33     22 unless ($class->can("_encode_bson") && $class->can("_decode_bson") ) {
54 0         0 die "Error: PERL_BSON_BACKEND '$class' does not implement the correct API.\n";
55             }
56             }
57 70         220 elsif ( eval { _try_load( $class = "BSON::XS" ) } or do { push @errs, $@; 0 } ) {
  70         186  
  70         230  
58             # module loaded; nothing else to do
59             }
60 70         177 elsif ( eval { _try_load( $class = "BSON::PP" ) } or do { push @errs, $@; 0 } ) {
  0         0  
  0         0  
61             # module loaded; nothing else to do
62             }
63             else {
64 0         0 s/\n/ /g for @errs;
65 0         0 die join( "\n* ", "Error: Couldn't load a BSON backend:", @errs ) . "\n";
66             }
67              
68 71         1006 *_encode_bson = $class->can("_encode_bson");
69 71         392 *_decode_bson = $class->can("_decode_bson");
70 71     0   2321 *_backend_class = sub { $class }; # for debugging
  0         0  
71             }
72              
73             # LOAD AFTER XS/PP, so that modules can pick up right version of helpers
74 71     71   599 use BSON::Types (); # loads types for extjson inflation
  71         115  
  71         284802  
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 or C)
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.
94             #pod
95             #pod =cut
96              
97             has 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              
109             has 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 decoding (the
120             #pod latter is necessary for prevention of resource consumption attacks).
121             #pod
122             #pod =cut
123              
124             has 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, the C 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              
139             has 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:
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              
163             has 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 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: the heuristics for determining whether something is a
179             #pod string or number are less accurate on older Perls. See L
180             #pod for wrapper classes that specify exact serialization types.
181             #pod
182             #pod The default is false.
183             #pod
184             #pod =cut
185              
186             has 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 objects. If false, they are decoded into ordinary hash
195             #pod references (or ordered hashes, if C is true).
196             #pod
197             #pod The default is true.
198             #pod
199             #pod =cut
200              
201             has 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, L or L.
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              
215             has 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. 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              
229             has 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, which returns objects of type L. 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 in the L
239             #pod driver.
240             #pod
241             #pod Other acceptable values are L (explicitly), L,
242             #pod L, L, L.
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              
251             has dt_type => (
252             is => 'ro',
253             isa => sub { return if !defined($_[0]); die "not a string" if ref $_[0] },
254             );
255              
256             sub BUILD {
257 763     763 0 3917427 my ($self) = @_;
258 763 50       3218 $self->{wrap_dbrefs} = 1 unless defined $self->{wrap_dbrefs};
259 763 100       5427 $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 is defined, it and C
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; 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              
290             sub encode_one {
291 2494     2494 1 70495 my ( $self, $document, $options ) = @_;
292 2494         13252 my $type = ref($document);
293              
294 2494 100       5411 Carp::croak "Can't encode scalars" unless $type;
295             # qr// is blessed to 'Regexp';
296 2493 100 100     17266 if ( $type eq "Regexp"
      100        
297             || !( blessed($document) || $type eq 'HASH' || $type eq 'ARRAY' ) )
298             {
299 2         200 Carp::croak "Can't encode non-container of type '$type'";
300             }
301              
302 2491 100       5192 $document = BSON::Doc->new(@$document)
303             if $type eq 'ARRAY';
304              
305 2491 100       12791 my $merged_opts = { %$self, ( $options ? %$options : () ) };
306              
307 2491         4541 my $bson = eval { _encode_bson( $document, $merged_opts ) };
  2491         10392  
308             # XXX this is a late max_length check -- it should be checked during
309             # encoding after each key
310 2491 100 66     12840 if ( $@ or ( $merged_opts->{max_length} && length($bson) > $merged_opts->{max_length} ) ) {
      100        
311 12   66     43 my $msg = $@ || "Document exceeds maximum size $merged_opts->{max_length}";
312 12 50       32 if ( $merged_opts->{error_callback} ) {
313 0         0 $merged_opts->{error_callback}->( $msg, $document, 'encode_one' );
314             }
315             else {
316 12         1126 Carp::croak("During encode_one, $msg");
317             }
318             }
319              
320 2479         12981 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              
344             sub decode_one {
345 2159     2159 1 1487514 my ( $self, $string, $options ) = @_;
346              
347 2159 100       11233 my $merged_opts = { %$self, ( $options ? %$options : () ) };
348              
349 2159 100 66     7150 if ( $merged_opts->{max_length} && length($string) > $merged_opts->{max_length} ) {
350 1         4 my $msg = "Document exceeds maximum size $merged_opts->{max_length}";
351 1 50       3 if ( $merged_opts->{error_callback} ) {
352 0         0 $merged_opts->{error_callback}->( $msg, \$string, 'decode_one' );
353             }
354             else {
355 1         82 Carp::croak("During decode_one, $msg");
356             }
357             }
358              
359 2158         4134 my $document = eval { _decode_bson( $string, $merged_opts ) };
  2158         7330  
360 2158 100       7286 if ( $@ ) {
361 79 100       196 if ( $merged_opts->{error_callback} ) {
362 1         5 $merged_opts->{error_callback}->( $@, \$string, 'decode_one' );
363             }
364             else {
365 78         7057 Carp::croak("During decode_one, $@");
366             }
367             }
368              
369 2080         8284 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              
381             sub clone {
382 0     0 1 0 my ($self, @args) = @_;
383 0         0 my $class = ref($self);
384 0 0 0     0 if ( @args == 1 && ref( $args[0] ) eq 'HASH' ) {
385 0         0 return $class->new( %$self, %{$args[0]} );
  0         0  
386             }
387              
388 0         0 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. 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              
407 3     3 1 2145 sub 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
412             #pod specification.
413             #pod
414             #pod Use L instead.
415             #pod
416             #pod =cut
417              
418             sub inflate_extjson {
419 0     0 1 0 my ( $self, $hash ) = @_;
420              
421 0         0 for my $k ( keys %$hash ) {
422 0         0 my $v = $hash->{$k};
423 0 0       0 if ( substr( $k, 0, 1 ) eq '$' ) {
424 0         0 croak "Dollar-prefixed key '$k' is not legal in top-level hash";
425             }
426 0         0 my $type = ref($v);
427 0 0       0 $hash->{$k} =
    0          
    0          
    0          
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 0         0 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
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 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 environment variable.
453             #pod
454             #pod =cut
455              
456             my $use_win32_specials = ($^O eq 'MSWin32' && $] lt "5.022");
457              
458             my $is_inf = $use_win32_specials ? qr/^1.\#INF/i : qr/^inf/i;
459             my $is_ninf = $use_win32_specials ? qr/^-1.\#INF/i : qr/^-inf/i;
460             my $is_nan = $use_win32_specials ? qr/^-?1.\#(?:IND|QNAN)/i : qr/^-?nan/i;
461              
462             sub perl_to_extjson {
463 3667     3667 1 37422 my ($class, $data, $options) = @_;
464              
465 3667         15791 local $ENV{BSON_EXTJSON} = 1;
466 3667         11575 local $ENV{BSON_EXTJSON_RELAXED} = $ENV{BSON_EXTJSON_RELAXED};
467 3667         8643 $ENV{BSON_EXTJSON_RELAXED} = $options->{relaxed};
468              
469 3667 100       6485 if (not defined $data) {
470 6         33 return undef; ## no critic
471             }
472              
473 3661 100 100     15991 if (blessed($data) and $data->can('TO_JSON')) {
474 1766         4785 my $json_data = $data->TO_JSON;
475 1766         20575 return $json_data;
476             }
477              
478 1895 100       4324 if (not ref $data) {
479              
480 67 100       353 if (looks_like_number($data)) {
481 25 100       108 if ($ENV{BSON_EXTJSON_RELAXED}) {
482 16         94 return $data;
483             }
484              
485 9 50       56 if ($data =~ m{\A-?[0-9_]+\z}) {
486 9 50       24 if ($data <= $max_int32) {
487 9         63 return { '$numberInt' => "$data" };
488             }
489             else {
490 0         0 return { '$numberLong' => "$data" };
491             }
492             }
493             else {
494 0 0       0 return { '$numberDouble' => 'Infinity' }
495             if $data =~ $is_inf;
496 0 0       0 return { '$numberDouble' => '-Infinity' }
497             if $data =~ $is_ninf;
498 0 0       0 return { '$numberDouble' => 'NaN' }
499             if $data =~ $is_nan;
500 0         0 my $value = "$data";
501 0         0 $value = $value / 1.0;
502 0         0 return { '$numberDouble' => "$value" };
503             }
504             }
505              
506 42         247 return $data;
507             }
508              
509 1828 50       4963 if (boolean::isBoolean($data)) {
510 0         0 return $data;
511             }
512              
513 1828 100       34647 if (ref $data eq 'HASH') {
514 1812         5340 for my $key (keys %$data) {
515 1850         25448 my $value = $data->{$key};
516 1850         15411 $data->{$key} = $class->perl_to_extjson($value, $options);
517             }
518 1812         28326 return $data;
519             }
520              
521 16 100       36 if (ref $data eq 'ARRAY') {
522 10         25 for my $index (0 .. $#$data) {
523 16         25 my $value = $data->[$index];
524 16         29 $data->[$index] = $class->perl_to_extjson($value, $options);
525             }
526 10         75 return $data;
527             }
528              
529 6 100 66     36 if (blessed($data) and $data->isa('JSON::PP::Boolean')) {
530 4         25 return $data;
531             }
532              
533 2 50 33     31 if (
      33        
534             blessed($data) and (
535             $data->isa('Math::BigInt') or
536             $data->isa('Math::BigFloat')
537             )
538             ) {
539 2         47 return $data;
540             }
541              
542 0         0 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
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 wrapper types. Plain numeric
558             #pod values will be left as-is.
559             #pod
560             #pod =cut
561              
562             sub extjson_to_perl {
563 2054     2054 1 3251413 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 2054         6864 for my $key (keys %$data) {
568 2102         30144 my $value = $data->{$key};
569 2102         14013 $data->{$key} = $class->_extjson_to_perl($value);
570             }
571 2054         30535 return $data;
572             }
573              
574             sub _extjson_to_perl {
575 2177     2177   3767 my ($class, $data) = @_;
576              
577 2177 100       5779 if (ref $data eq 'HASH') {
578              
579 2101 100       5709 if ( exists $data->{'$oid'} ) {
580 26         143 return BSON::OID->new( oid => pack( "H*", $data->{'$oid'} ) );
581             }
582              
583 2075 100       10833 if ( exists $data->{'$numberInt'} ) {
584 38         956 return BSON::Int32->new( value => $data->{'$numberInt'} );
585             }
586              
587 2037 100       9245 if ( exists $data->{'$numberLong'} ) {
588 27         88 if (HAS_INT64) {
589 27         525 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 2010 100       8977 if ( exists $data->{'$binary'} ) {
597 24         170 require MIME::Base64;
598 24 50       48 if (exists $data->{'$type'}) {
599             return BSON::Bytes->new(
600             data => MIME::Base64::decode_base64($data->{'$binary'}),
601 0   0     0 subtype => hex( $data->{'$type'} || 0 ),
602             );
603             }
604             else {
605 24         117 my $value = $data->{'$binary'};
606             return BSON::Bytes->new(
607             data => MIME::Base64::decode_base64($value->{base64}),
608 24   50     196 subtype => hex( $value->{subType} || 0 ),
609             );
610             }
611             }
612              
613 1986 100       9455 if ( exists $data->{'$date'} ) {
614 17         77 my $v = $data->{'$date'};
615 17 100       121 $v = ref($v) eq 'HASH' ? $class->_extjson_to_perl($v) : _iso8601_to_epochms($v);
616 17         276 return BSON::Time->new( value => $v );
617             }
618              
619 1969 100       8487 if ( exists $data->{'$minKey'} ) {
620 4         27 return BSON::MinKey->new;
621             }
622              
623 1965 100       7848 if ( exists $data->{'$maxKey'} ) {
624 4         26 return BSON::MaxKey->new;
625             }
626              
627 1961 100       8144 if ( exists $data->{'$timestamp'} ) {
628             return BSON::Timestamp->new(
629             seconds => $data->{'$timestamp'}{t},
630             increment => $data->{'$timestamp'}{i},
631 10         46 );
632             }
633              
634 1951 50 33     8051 if ( exists $data->{'$regex'} and not ref $data->{'$regex'}) {
635             return BSON::Regex->new(
636             pattern => $data->{'$regex'},
637 0 0       0 ( exists $data->{'$options'} ? ( flags => $data->{'$options'} ) : () ),
638             );
639             }
640              
641 1951 100       9254 if ( exists $data->{'$regularExpression'} ) {
642 24         108 my $value = $data->{'$regularExpression'};
643             return BSON::Regex->new(
644             pattern => $value->{pattern},
645 24 50       156 ( exists $value->{options} ? ( flags => $value->{options} ) : () ),
646             );
647             }
648              
649 1927 100       8155 if ( exists $data->{'$code'} ) {
650             return BSON::Code->new(
651             code => $data->{'$code'},
652             ( exists $data->{'$scope'}
653 20 100       104 ? ( scope => $class->_extjson_to_perl($data->{'$scope'}) )
654             : ()
655             ),
656             );
657             }
658              
659 1907 100       8232 if ( exists $data->{'$undefined'} ) {
660 2         14 return undef; ## no critic
661             }
662              
663 1905 100       8301 if ( exists $data->{'$dbPointer'} ) {
664 8         34 my $data = $data->{'$dbPointer'};
665 8         51 my $id = $data->{'$id'};
666 8 50       52 $id = $class->_extjson_to_perl($id) if ref($id) eq 'HASH';
667             return BSON::DBPointer->new(
668 8         131 '$ref' => $data->{'$ref'},
669             '$id' => $id,
670             );
671             }
672              
673 1897 100       7853 if ( exists $data->{'$ref'} ) {
674 10         54 my $id = delete $data->{'$id'};
675 10 50       274 $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 10         48 '$db' => delete $data->{'$db'},
680             %$data, # extra
681             );
682             }
683              
684 1887 100       8545 if ( exists $data->{'$numberDecimal'} ) {
685 1823         46859 return BSON::Decimal128->new( value => $data->{'$numberDecimal'} );
686             }
687              
688             # Following extended JSON is non-standard
689              
690 64 100       284 if ( exists $data->{'$numberDouble'} ) {
691 28 0 33     128 if ( $data->{'$numberDouble'} eq '-0' && $] lt '5.014' && ! HAS_LD ) {
      50        
692 0         0 $data->{'$numberDouble'} = '-0.0';
693             }
694 28         750 return BSON::Double->new( value => $data->{'$numberDouble'} );
695             }
696              
697 36 100       398 if ( exists $data->{'$symbol'} ) {
698 12         304 return BSON::Symbol->new(value => $data->{'$symbol'});
699             }
700              
701 24         112 for my $key (keys %$data) {
702 14         182 my $value = $data->{$key};
703 14         109 $data->{$key} = $class->_extjson_to_perl($value);
704             }
705 24         463 return $data;
706             }
707              
708 76 100       181 if (ref $data eq 'ARRAY') {
709 10         27 for my $index (0 .. $#$data) {
710 16         22 my $value = $data->[$index];
711 16 50       45 $data->[$index] = ref($value)
712             ? $class->_extjson_to_perl($value)
713             : $value;
714             }
715 10         40 return $data;
716             }
717              
718 66         188 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 740 50 33 740 1 114899 if ( defined $_[0] && ( $_[0] eq 'BSON' || ( blessed($_[0]) && $_[0]->isa('BSON') ) ) ) {
      33        
748 0         0 Carp::croak("Error: 'encode' is a function, not a method");
749             }
750 740         1712 my $doc = shift;
751 740 100       2007 $CODEC = BSON->new unless defined $CODEC;
752 740 100 66     4423 if ( @_ == 1 && ref( $_[0] ) eq 'HASH' ) {
    50          
753 101         187 return $CODEC->encode_one( $doc, $_[0] );
754             }
755             elsif ( @_ % 2 == 0 ) {
756 639         2956 return $CODEC->encode_one( $doc, {@_} );
757             }
758             else {
759 0         0 Carp::croak("Options for 'encode' must be a hashref or key-value pairs");
760             }
761             }
762              
763             sub decode {
764 698 50 33 698 1 111226 if ( defined $_[0] && ( $_[0] eq 'BSON' || ( blessed($_[0]) && $_[0]->isa('BSON') ) ) ) {
      33        
765 0         0 Carp::croak("Error: 'decode' is a function, not a method");
766             }
767 698         1376 my $doc = shift;
768 698 100       2207 $CODEC = BSON->new unless defined $CODEC;
769 698         1167 my $args;
770 698 50 33     3930 if ( @_ == 1 && ref( $_[0] ) eq 'HASH' ) {
    50          
771 0         0 $args = shift;
772             }
773             elsif ( @_ % 2 == 0 ) {
774 698         1569 $args = { @_ };
775             }
776             else {
777 0         0 Carp::croak("Options for 'decode' must be a hashref or key-value pairs");
778             }
779             $args->{ordered} = delete $args->{ixhash}
780 698 100 66     2563 if exists $args->{ixhash} && !exists $args->{ordered};
781 698         2617 return $CODEC->decode_one( $doc, $args );
782             }
783             }
784              
785             #--------------------------------------------------------------------------#
786             # private functions
787             #--------------------------------------------------------------------------#
788              
789             sub _inflate_hash {
790 0     0   0 my ( $class, $hash ) = @_;
791              
792 0 0       0 if ( exists $hash->{'$oid'} ) {
793 0         0 return BSON::OID->new( oid => pack( "H*", $hash->{'$oid'} ) );
794             }
795              
796 0 0       0 if ( exists $hash->{'$numberInt'} ) {
797 0         0 return BSON::Int32->new( value => $hash->{'$numberInt'} );
798             }
799              
800 0 0       0 if ( exists $hash->{'$numberLong'} ) {
801 0         0 if (HAS_INT64) {
802 0         0 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 0 0       0 if ( exists $hash->{'$binary'} ) {
810 0         0 require MIME::Base64;
811             return BSON::Bytes->new(
812             data => MIME::Base64::decode_base64($hash->{'$binary'}),
813 0   0     0 subtype => hex( $hash->{'$type'} || 0 )
814             );
815             }
816              
817 0 0       0 if ( exists $hash->{'$date'} ) {
818 0         0 my $v = $hash->{'$date'};
819 0 0       0 $v = ref($v) eq 'HASH' ? BSON->_inflate_hash($v) : _iso8601_to_epochms($v);
820 0         0 return BSON::Time->new( value => $v );
821             }
822              
823 0 0       0 if ( exists $hash->{'$minKey'} ) {
824 0         0 return BSON::MinKey->new;
825             }
826              
827 0 0       0 if ( exists $hash->{'$maxKey'} ) {
828 0         0 return BSON::MaxKey->new;
829             }
830              
831 0 0       0 if ( exists $hash->{'$timestamp'} ) {
832             return BSON::Timestamp->new(
833             seconds => $hash->{'$timestamp'}{t},
834             increment => $hash->{'$timestamp'}{i},
835 0         0 );
836             }
837              
838 0 0       0 if ( exists $hash->{'$regex'} ) {
839             return BSON::Regex->new(
840             pattern => $hash->{'$regex'},
841 0 0       0 ( exists $hash->{'$options'} ? ( flags => $hash->{'$options'} ) : () ),
842             );
843             }
844              
845 0 0       0 if ( exists $hash->{'$code'} ) {
846             return BSON::Code->new(
847             code => $hash->{'$code'},
848 0 0       0 ( exists $hash->{'$scope'} ? ( scope => $hash->{'$scope'} ) : () ),
849             );
850             }
851              
852 0 0       0 if ( exists $hash->{'$undefined'} ) {
853 0         0 return undef; ## no critic
854             }
855              
856 0 0       0 if ( exists $hash->{'$ref'} ) {
857 0         0 my $id = $hash->{'$id'};
858 0 0       0 $id = BSON->_inflate_hash($id) if ref($id) eq 'HASH';
859 0         0 return BSON::DBRef->new( '$ref' => $hash->{'$ref'}, '$id' => $id );
860             }
861              
862 0 0       0 if ( exists $hash->{'$numberDecimal'} ) {
863 0         0 return BSON::Decimal128->new( value => $hash->{'$numberDecimal'} );
864             }
865              
866             # Following extended JSON is non-standard
867              
868 0 0       0 if ( exists $hash->{'$numberDouble'} ) {
869 0 0 0     0 if ( $hash->{'$numberDouble'} eq '-0' && $] lt '5.014' && ! HAS_LD ) {
      0        
870 0         0 $hash->{'$numberDouble'} = '-0.0';
871             }
872 0         0 return BSON::Double->new( value => $hash->{'$numberDouble'} );
873             }
874              
875 0 0       0 if ( exists $hash->{'$symbol'} ) {
876 0         0 return $hash->{'$symbol'};
877             }
878              
879 0         0 return $hash;
880             }
881              
882             sub _inflate_array {
883 0     0   0 my ($class, $array) = @_;
884 0 0       0 if (@$array) {
885 0         0 for my $i ( 0 .. $#$array ) {
886 0         0 my $v = $array->[$i];
887 0 0       0 $array->[$i] =
    0          
888             ref($v) eq 'HASH' ? BSON->_inflate_hash($v)
889             : ref($v) eq 'ARRAY' ? _inflate_array($v)
890             : $v;
891             }
892             }
893 0         0 return $array;
894             }
895              
896             my $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              
902             sub _iso8601_to_epochms {
903 2     2   5 my ($date) = shift;
904 2         21 require Time::Local;
905              
906 2         2615 my $zone_offset = 0;;
907 2 50       9 if ( substr($date,-1,1) eq 'Z' ) {
908 2         6 chop($date);
909             }
910              
911 2 50       64 if ( $date =~ /\A$iso8601_re\z/ ) {
912 2         21 my ($Y,$M,$D,$h,$m,$s,$z) = ($1,$2-1,$3,$4,$5,$6,$7);
913 2 50 33     8 if (defined($z) && length($z)) {
914 0         0 $z =~ tr[:][];
915 0 0       0 $z .= "00" if length($z) < 5;
916 0         0 my $zd = substr($z,0,1);
917 0         0 my $zh = substr($z,1,2);
918 0         0 my $zm = substr($z,3,2);
919 0 0       0 $zone_offset = ($zd eq '-' ? -1 : 1 ) * (3600 * $zh + 60 * $zm);
920             }
921 2         8 my $frac = $s - int($s);
922 2         10 my $epoch = Time::Local::timegm(int($s), $m, $h, $D, $M, $Y) - $zone_offset;
923 2         71 $epoch = HAS_INT64 ? 1000 * $epoch : Math::BigInt->new($epoch) * 1000;
924 2         5 $epoch += HAS_INT64 ? $frac * 1000 : Math::BigFloat->new($frac) * 1000;
925 2         6 return $epoch;
926             }
927             else {
928 0           Carp::croak("Couldn't parse '\$date' field: $date\n");
929             }
930             }
931              
932             1;
933              
934             =pod
935              
936             =encoding UTF-8
937              
938             =head1 NAME
939              
940             BSON - BSON serialization and deserialization (EOL)
941              
942             =head1 VERSION
943              
944             version v1.12.2
945              
946             =head1 END OF LIFE NOTICE
947              
948             Version v1.12.0 was the final feature release of the MongoDB BSON library
949             and version v1.12.2 is the final patch release.
950              
951             B
952             reached end of life and are no longer supported by MongoDB.> See the
953             L
954             notice|https://www.mongodb.com/blog/post/the-mongodb-perl-driver-is-being-deprecated>
955             for rationale.
956              
957             If members of the community wish to continue development, they are welcome
958             to fork the code under the terms of the Apache 2 license and release it
959             under a new namespace. Specifications and test files for MongoDB drivers
960             and libraries are published in an open repository:
961             L.
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              
983             This class implements a BSON encoder/decoder ("codec"). It consumes
984             "documents" (typically hash references) and emits BSON strings and vice
985             versa in accordance with the L.
986              
987             BSON is the primary data representation for L. While this module
988             has several features that support MongoDB-specific needs and conventions,
989             it can be used as a standalone serialization format.
990              
991             The codec may be customized through attributes on the codec option as well
992             as 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              
999             Because BSON is strongly-typed and Perl is not, this module supports
1000             a number of "type wrappers" – classes that wrap Perl data to indicate how
1001             they should serialize. The L module describes these and
1002             provides associated helper functions. See L
1003             for more details.
1004              
1005             When decoding, type wrappers are used for any data that has no native Perl
1006             representation. Optionally, all data may be wrapped for precise control of
1007             round-trip encoding.
1008              
1009             Please read the configuration attributes carefully to understand more about
1010             how to control encoding and decoding.
1011              
1012             At compile time, this module will select an implementation backend. It
1013             will prefer C (released separately) if available, or will fall
1014             back to L (bundled with this module). See L for
1015             a way to control the selection of the backend.
1016              
1017             =head1 ATTRIBUTES
1018              
1019             =head2 error_callback
1020              
1021             This attribute specifies a function reference that will be called with
1022             three positional arguments:
1023              
1024             =over 4
1025              
1026             =item *
1027              
1028             an error string argument describing the error condition
1029              
1030             =item *
1031              
1032             a reference to the problematic document or byte-string
1033              
1034             =item *
1035              
1036             the method in which the error occurred (e.g. C or C)
1037              
1038             =back
1039              
1040             Note: for decoding errors, the byte-string is passed as a reference to avoid
1041             copying possibly large strings.
1042              
1043             If not provided, errors messages will be thrown with C.
1044              
1045             =head2 invalid_chars
1046              
1047             A string containing ASCII characters that must not appear in keys. The default
1048             is the empty string, meaning there are no invalid characters.
1049              
1050             =head2 max_length
1051              
1052             This attribute defines the maximum document size. The default is 0, which
1053             disables any maximum.
1054              
1055             If set to a positive number, it applies to both encoding B decoding (the
1056             latter is necessary for prevention of resource consumption attacks).
1057              
1058             =head2 op_char
1059              
1060             This is a single character to use for special MongoDB-specific query
1061             operators. If a key starts with C, the C character will
1062             be replaced with "$".
1063              
1064             The default is "$", meaning that no replacement is necessary.
1065              
1066             =head2 ordered
1067              
1068             If set to a true value, then decoding will return a reference to a tied
1069             hash that preserves key order. Otherwise, a regular (unordered) hash
1070             reference will be returned.
1071              
1072             B:
1073              
1074             =over 4
1075              
1076             =item *
1077              
1078             When '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              
1082             Turning this option on entails a significant speed penalty as tied hashes are slower than regular Perl hashes.
1083              
1084             =back
1085              
1086             The default is false.
1087              
1088             =head2 prefer_numeric
1089              
1090             When false, scalar values will be encoded as a number if they were
1091             originally a number or were ever used in a numeric context. However, a
1092             string that looks like a number but was never used in a numeric context
1093             (e.g. "42") will be encoded as a string.
1094              
1095             If C is set to true, the encoder will attempt to coerce
1096             strings that look like a number into a numeric value. If the string
1097             doesn't look like a double or integer, it will be encoded as a string.
1098              
1099             B: the heuristics for determining whether something is a
1100             string or number are less accurate on older Perls. See L
1101             for wrapper classes that specify exact serialization types.
1102              
1103             The default is false.
1104              
1105             =head2 wrap_dbrefs
1106              
1107             If set to true, during decoding, documents with the fields C<'$id'> and
1108             C<'$ref'> (literal dollar signs, not variables) will be wrapped as
1109             L objects. If false, they are decoded into ordinary hash
1110             references (or ordered hashes, if C is true).
1111              
1112             The default is true.
1113              
1114             =head2 wrap_numbers
1115              
1116             If set to true, during decoding, numeric values will be wrapped into
1117             BSON type-wrappers: L, L or L.
1118             While very slow, this can help ensure fields can round-trip if unmodified.
1119              
1120             The default is false.
1121              
1122             =head2 wrap_strings
1123              
1124             If set to true, during decoding, string values will be wrapped into a BSON
1125             type-wrappers, L. While very slow, this can help ensure
1126             fields can round-trip if unmodified.
1127              
1128             The default is false.
1129              
1130             =head2 dt_type (Discouraged)
1131              
1132             Sets the type of object which is returned for BSON DateTime fields. The
1133             default is C, which returns objects of type L. This is
1134             overloaded to be the integer epoch value when used as a number or string,
1135             so is somewhat backwards compatible with C in the L
1136             driver.
1137              
1138             Other acceptable values are L (explicitly), L,
1139             L, L, L.
1140              
1141             Because BSON::Time objects have methods to convert to DateTime,
1142             Time::Moment or DateTime::Tiny, use of this field is discouraged. Users
1143             should use these methods on demand. This option is provided for backwards
1144             compatibility 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              
1153             Takes a "document", typically a hash reference, an array reference, or a
1154             Tie::IxHash object and returns a byte string with the BSON representation of
1155             the document.
1156              
1157             An optional hash reference of options may be provided. Valid options include:
1158              
1159             =over 4
1160              
1161             =item *
1162              
1163             first_key – if C is defined, it and C will be encoded first in the output BSON; any matching key found in the document will be ignored.
1164              
1165             =item *
1166              
1167             first_value - value to assign to C; will encode as Null if omitted
1168              
1169             =item *
1170              
1171             error_callback – overrides codec default
1172              
1173             =item *
1174              
1175             invalid_chars – overrides codec default
1176              
1177             =item *
1178              
1179             max_length – overrides codec default
1180              
1181             =item *
1182              
1183             op_char – overrides codec default
1184              
1185             =item *
1186              
1187             prefer_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              
1196             Takes a byte string with a BSON-encoded document and returns a
1197             hash reference representing the decoded document.
1198              
1199             An optional hash reference of options may be provided. Valid options include:
1200              
1201             =over 4
1202              
1203             =item *
1204              
1205             dt_type – overrides codec default
1206              
1207             =item *
1208              
1209             error_callback – overrides codec default
1210              
1211             =item *
1212              
1213             max_length – overrides codec default
1214              
1215             =item *
1216              
1217             ordered - overrides codec default
1218              
1219             =item *
1220              
1221             wrap_dbrefs - overrides codec default
1222              
1223             =item *
1224              
1225             wrap_numbers - overrides codec default
1226              
1227             =item *
1228              
1229             wrap_strings - overrides codec default
1230              
1231             =back
1232              
1233             =head2 clone
1234              
1235             $copy = $codec->clone( ordered => 1 );
1236              
1237             Constructs a copy of the original codec, but allows changing
1238             attributes in the copy.
1239              
1240             =head2 create_oid
1241              
1242             $oid = BSON->create_oid;
1243              
1244             This class method returns a new L. This abstracts OID
1245             generation away from any specific Object ID class and makes it an interface
1246             on a BSON codec. Alternative BSON codecs should define a similar class
1247             method that returns an Object ID of whatever type is appropriate.
1248              
1249             =head2 inflate_extjson (DEPRECATED)
1250              
1251             This legacy method does not follow the L
1252             specification.
1253              
1254             Use L 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              
1262             Takes a perl data structure (i.e. hashref) and turns it into an
1263             L
1264             structure. Note that the structure will still have to be serialized.
1265              
1266             Possible options are:
1267              
1268             =over 4
1269              
1270             =item *
1271              
1272             C A boolean indicating if "relaxed extended JSON" should
1273              
1274             be generated. If not set, the default value is taken from the
1275             C 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              
1285             Takes an
1286             L
1287             data structure and inflates it into a Perl data structure. Note that
1288             you have to decode the JSON string manually beforehand.
1289              
1290             Canonically specified numerical values like C<{"$numberInt":"23"}> will
1291             be inflated into their respective C wrapper types. Plain numeric
1292             values will be left as-is.
1293              
1294             =head1 FUNCTIONS
1295              
1296             =head2 encode
1297              
1298             my $bson = encode({ bar => 'foo' }, \%options);
1299              
1300             This is the legacy, functional interface and is only exported on demand.
1301             It takes a hashref and returns a BSON string.
1302             It uses an internal codec singleton with default attributes.
1303              
1304             =head2 decode
1305              
1306             my $hash = decode( $bson, \%options );
1307              
1308             This is the legacy, functional interface and is only exported on demand.
1309             It takes a BSON string and returns a hashref.
1310             It uses an internal codec singleton with default attributes.
1311              
1312             =for Pod::Coverage BUILD
1313              
1314             =head1 PERL-BSON TYPE MAPPING
1315              
1316             BSON has numerous data types and Perl does not.
1317              
1318             When B, each BSON type should result in a single, predictable
1319             Perl type. Where no native Perl type is appropriate, BSON decodes to an
1320             object of a particular class (a "type wrapper").
1321              
1322             When B, for historical reasons, there may be many Perl
1323             representations that should encode to a particular BSON type. For example,
1324             all the popular "boolean" type modules on CPAN should encode to the BSON
1325             boolean type. Likewise, as this module is intended to supersede the
1326             type wrappers that have shipped with the L module, those
1327             type wrapper are supported by this codec.
1328              
1329             The table below describes the BSON/Perl mapping for both encoding and
1330             decoding.
1331              
1332             On the left are all the Perl types or classes this BSON codec
1333             knows how to serialize to BSON. The middle column is the BSON type for
1334             each class. The right-most column is the Perl type or class that the BSON
1335             type 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              
1436             Threads are never recommended in Perl, but this module is thread safe.
1437              
1438             =head1 ENVIRONMENT
1439              
1440             =over 4
1441              
1442             =item *
1443              
1444             PERL_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.
1445              
1446             =item *
1447              
1448             BSON_EXTJSON - if set, serializing BSON type wrappers via C will produce Extended JSON v2 output.
1449              
1450             =item *
1451              
1452             BSON_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              
1458             Starting with BSON C, this module is using a "tick-tock"
1459             three-part version-tuple numbering scheme: C
1460              
1461             =over 4
1462              
1463             =item *
1464              
1465             In stable releases, C will be incremented for incompatible API changes.
1466              
1467             =item *
1468              
1469             Even-value increments of C indicate stable releases with new functionality. C will be incremented for bug fixes.
1470              
1471             =item *
1472              
1473             Odd-value increments of C indicate unstable ("development") releases that should not be used in production. C increments have no semantic meaning; they indicate only successive development releases. Development releases may have API-breaking changes, usually indicated by C equal to "999".
1474              
1475             =back
1476              
1477             =head1 HISTORY AND ROADMAP
1478              
1479             This module was originally written by Stefan G. In 2014, he graciously
1480             transferred ongoing maintenance to MongoDB, Inc.
1481              
1482             The C helper functions in L were inspired by similar
1483             work in L by Sebastian Riedel.
1484              
1485             =head1 AUTHORS
1486              
1487             =over 4
1488              
1489             =item *
1490              
1491             David Golden
1492              
1493             =item *
1494              
1495             Stefan G.
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              
1507             Eric Daniels
1508              
1509             =item *
1510              
1511             Finn
1512              
1513             =item *
1514              
1515             Olivier Duclos
1516              
1517             =item *
1518              
1519             Pat Gunn
1520              
1521             =item *
1522              
1523             Petr Písař
1524              
1525             =item *
1526              
1527             Robert Sedlacek
1528              
1529             =item *
1530              
1531             Thomas Bloor
1532              
1533             =item *
1534              
1535             Tobias Leich
1536              
1537             =item *
1538              
1539             Wallace Reis
1540              
1541             =item *
1542              
1543             Yury Zavarin
1544              
1545             =item *
1546              
1547             Oleg Kostyuk
1548              
1549             =back
1550              
1551             =head1 COPYRIGHT AND LICENSE
1552              
1553             This software is Copyright (c) 2020 by Stefan G. and MongoDB, Inc.
1554              
1555             This is free software, licensed under:
1556              
1557             The Apache License, Version 2.0, January 2004
1558              
1559             =cut
1560              
1561             __END__