BSON

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

        future for efficiency.

    *   Turning this option on entails a significant speed penalty as tied
        hashes are slower than regular Perl hashes.

    The default is false.

  prefer_numeric
    When false, scalar values will be encoded as a number if they were
    originally a number or were ever used in a numeric context. However, a
    string that looks like a number but was never used in a numeric context
    (e.g. "42") will be encoded as a string.

    If "prefer_numeric" is set to true, the encoder will attempt to coerce
    strings that look like a number into a numeric value. If the string
    doesn't look like a double or integer, it will be encoded as a string.

    IMPORTANT CAVEAT: the heuristics for determining whether something is a
    string or number are less accurate on older Perls. See BSON::Types for
    wrapper classes that specify exact serialization types.

README  view on Meta::CPAN

        Math::BigInt
        Math::Int64
        -------------------------------------------------------------------
        BSON::MaxKey                0x7F MAXKEY         BSON::MaxKey
        MongoDB::MaxKey[d]
        -------------------------------------------------------------------
        BSON::MinKey                0xFF MINKEY         BSON::MinKey
        MongoDB::MinKey[d]

        [d] Deprecated or soon to be deprecated.
        [1] Scalar with "NV" internal representation or a string that looks
            like a float if the 'prefer_numeric' option is true.
        [2] If the 'wrap_numbers' option is true, numeric types will be wrapped
            as BSON::Double, BSON::Int32 or BSON::Int64 as appropriate to ensure
            round-tripping. If the 'wrap_strings' option is true, strings will
            be wrapped as BSON::String, likewise.
        [3] Scalar without "NV" or "IV" representation and not identified as a
            number by notes [1] or [7].
        [4] If 'ordered' option is set, will return a tied hash that preserves
            order (deprecated 'ixhash' option still works).
        [5] If the document appears to contain a DBRef and a 'dbref_callback'
            exists, that callback is executed with the deserialized document.
        [6] Code is serialized as CODE or CODEWSCOPE depending on whether a
            scope hashref exists in BSON::Code/MongoDB::Code.
        [7] Scalar with "IV" internal representation or a string that looks like
            an integer if the 'prefer_numeric' option is true.
        [8] Only if the integer fits in 32 bits.
        [9] On 32-bit platforms, 64-bit integers are deserialized to
            Math::BigInt objects (even if subsequently wrapped into
            BSON::Int64 if 'wrap_scalars' is true).

THREADS
    Threads are never recommended in Perl, but this module is thread safe.

ENVIRONMENT

lib/BSON.pm  view on Meta::CPAN

# ABSTRACT: BSON serialization and deserialization (EOL)

use base 'Exporter';
our @EXPORT_OK = qw/encode decode/;

use version;
our $VERSION = 'v1.12.2';

use Carp;
use Config;
use Scalar::Util qw/blessed looks_like_number/;

use Moo 2.002004; # safer generated code
use boolean;
use BSON::OID;

use constant {
    HAS_INT64 => $Config{use64bitint},
    HAS_LD    => $Config{uselongdouble},
};

lib/BSON.pm  view on Meta::CPAN

#pod =cut

has ordered => (
    is => 'ro',
);

#pod =attr prefer_numeric
#pod
#pod When false, scalar values will be encoded as a number if they were
#pod originally a number or were ever used in a numeric context.  However, a
#pod string that looks like a number but was never used in a numeric context
#pod (e.g. "42") will be encoded as a string.
#pod
#pod If C<prefer_numeric> is set to true, the encoder will attempt to coerce
#pod strings that look like a number into a numeric value.  If the string
#pod doesn't look like a double or integer, it will be encoded as a string.
#pod
#pod B<IMPORTANT CAVEAT>: the heuristics for determining whether something is a
#pod string or number are less accurate on older Perls.  See L<BSON::Types>
#pod for wrapper classes that specify exact serialization types.
#pod

lib/BSON.pm  view on Meta::CPAN

        return undef; ## no critic
    }

    if (blessed($data) and $data->can('TO_JSON')) {
        my $json_data = $data->TO_JSON;
        return $json_data;
    }

    if (not ref $data) {

        if (looks_like_number($data)) {
            if ($ENV{BSON_EXTJSON_RELAXED}) {
                return $data;
            }

            if ($data =~ m{\A-?[0-9_]+\z}) {
                if ($data <= $max_int32) {
                    return { '$numberInt' => "$data" };
                }
                else {
                    return { '$numberLong' => "$data" };

lib/BSON.pm  view on Meta::CPAN

Turning this option on entails a significant speed penalty as tied hashes are slower than regular Perl hashes.

=back

The default is false.

=head2 prefer_numeric

When false, scalar values will be encoded as a number if they were
originally a number or were ever used in a numeric context.  However, a
string that looks like a number but was never used in a numeric context
(e.g. "42") will be encoded as a string.

If C<prefer_numeric> is set to true, the encoder will attempt to coerce
strings that look like a number into a numeric value.  If the string
doesn't look like a double or integer, it will be encoded as a string.

B<IMPORTANT CAVEAT>: the heuristics for determining whether something is a
string or number are less accurate on older Perls.  See L<BSON::Types>
for wrapper classes that specify exact serialization types.

lib/BSON.pm  view on Meta::CPAN

    Math::BigInt
    Math::Int64
    -------------------------------------------------------------------
    BSON::MaxKey                0x7F MAXKEY         BSON::MaxKey
    MongoDB::MaxKey[d]
    -------------------------------------------------------------------
    BSON::MinKey                0xFF MINKEY         BSON::MinKey
    MongoDB::MinKey[d]

    [d] Deprecated or soon to be deprecated.
    [1] Scalar with "NV" internal representation or a string that looks
        like a float if the 'prefer_numeric' option is true.
    [2] If the 'wrap_numbers' option is true, numeric types will be wrapped
        as BSON::Double, BSON::Int32 or BSON::Int64 as appropriate to ensure
        round-tripping. If the 'wrap_strings' option is true, strings will
        be wrapped as BSON::String, likewise.
    [3] Scalar without "NV" or "IV" representation and not identified as a
        number by notes [1] or [7].
    [4] If 'ordered' option is set, will return a tied hash that preserves
        order (deprecated 'ixhash' option still works).
    [5] If the document appears to contain a DBRef and a 'dbref_callback'
        exists, that callback is executed with the deserialized document.
    [6] Code is serialized as CODE or CODEWSCOPE depending on whether a
        scope hashref exists in BSON::Code/MongoDB::Code.
    [7] Scalar with "IV" internal representation or a string that looks like
        an integer if the 'prefer_numeric' option is true.
    [8] Only if the integer fits in 32 bits.
    [9] On 32-bit platforms, 64-bit integers are deserialized to
        Math::BigInt objects (even if subsequently wrapped into
        BSON::Int64 if 'wrap_scalars' is true).

=head1 THREADS

Threads are never recommended in Perl, but this module is thread safe.

lib/BSON/OID.pm  view on Meta::CPAN

use warnings;

package BSON::OID;
# ABSTRACT: BSON type wrapper for Object IDs

use version;
our $VERSION = 'v1.12.2';

use Carp;
use Config;
use Scalar::Util 'looks_like_number';
use Sys::Hostname;
use threads::shared; # NOP if threads.pm not loaded
use Crypt::URandom ();

use constant {
    HAS_INT64 => $Config{use64bitint},
    INT64_MAX => 9223372036854775807,
    INT32_MAX => 2147483647,
    ZERO_FILL => ("\0" x 8),
};

lib/BSON/OID.pm  view on Meta::CPAN

#pod
#pod   use Crypt::Random 'urandom';
#pod   my $oid = BSON::OID->from_epoch(1467545180, urandom(8));
#pod
#pod =cut

sub from_epoch {
    my ($self, $epoch, $fill) = @_;

    croak "BSON::OID::from_epoch expects an epoch in seconds, not '$epoch'"
      unless looks_like_number( $epoch );

    $fill = ZERO_FILL if defined $fill && looks_like_number($fill) && $fill == 0;

    croak "BSON::OID expects the second argument to be missing, 0 or an 8-byte string"
      unless @_ == 2 || length($fill) == 8;

    my $oid = defined $fill
      ? _packed_oid_special($epoch, $fill)
      : _packed_oid($epoch);

    if (ref $self) {
        $self->{oid} = $oid;

lib/BSON/PP.pm  view on Meta::CPAN


package BSON::PP;
# ABSTRACT: Pure Perl BSON implementation

use version;
our $VERSION = 'v1.12.2';

use B;
use Carp;
use Config;
use Scalar::Util qw/blessed looks_like_number refaddr reftype/;
use List::Util qw/first/;
use Tie::IxHash;

use BSON::Types ();
use boolean;
use mro;

use re 'regexp_pattern';

use constant {

lib/BSON/PP.pm  view on Meta::CPAN


            # Unsupported type
            else  {
                croak("For key '$key', can't encode value of type '$type'");
            }
        }

        # SCALAR
        else {
            # If a numeric value exists based on internal flags, use it;
            # otherwise, if prefer_numeric is true and it looks like a
            # number, then coerce to a number of the right type;
            # otherwise, leave it as a string

            my $flags = B::svref_2object(\$value)->FLAGS;

            if ( $flags & B::SVf_NOK() ) {
                $bson .= pack( BSON_TYPE_NAME.BSON_DOUBLE, 0x01, $utf8_key, $value );
            }
            elsif ( $flags & B::SVf_IOK() ) {
                # Force numeric; fixes dual-vars comparison bug on old Win32s

lib/BSON/PP.pm  view on Meta::CPAN

                if ( $value > $max_int64 || $value < $min_int64 ) {
                    croak("BSON can only handle 8-byte integers. Key '$key' is '$value'");
                }
                elsif ( $value > $max_int32 || $value < $min_int32 ) {
                    $bson .= pack( BSON_TYPE_NAME, 0x12, $utf8_key ) . _pack_int64($value);
                }
                else {
                    $bson .= pack( BSON_TYPE_NAME . BSON_INT32, 0x10, $utf8_key, $value );
                }
            }
            elsif ( $opt->{prefer_numeric} && looks_like_number($value) ) {
                # Looks like int: type heuristic based on size
                if ( $value =~ $int_re ) {
                    if ( $value > $max_int64 || $value < $min_int64 ) {
                        croak("BSON can only handle 8-byte integers. Key '$key' is '$value'");
                    }
                    elsif ( $value > $max_int32 || $value < $min_int32 ) {
                        $bson .= pack( BSON_TYPE_NAME, 0x12, $utf8_key ) . _pack_int64($value);
                    }
                    else {
                        $bson .= pack( BSON_TYPE_NAME . BSON_INT32, 0x10, $utf8_key, $value );
                    }
                }

                # Looks like double
                elsif ( $value =~ $doub_re ) {
                    $bson .= pack( BSON_TYPE_NAME.BSON_DOUBLE, 0x01, $utf8_key, $value );
                }

                # looks_like_number true, but doesn't match int/double
                # regexes, so as a last resort we leave as string
                else {
                    utf8::encode($value);
                    $bson .= pack( BSON_TYPE_NAME.BSON_STRING, 0x02, $utf8_key, $value );
                }
            }
            else {
                # Not coercing or didn't look like a number
                utf8::encode($value);
                $bson .= pack( BSON_TYPE_NAME.BSON_STRING, 0x02, $utf8_key, $value );

lib/BSON/Time.pm  view on Meta::CPAN


package BSON::Time;
# ABSTRACT: BSON type wrapper for date and time

use version;
our $VERSION = 'v1.12.2';

use Carp qw/croak/;
use Config;
use Time::HiRes qw/time/;
use Scalar::Util qw/looks_like_number/;

use if !$Config{use64bitint}, 'Math::BigInt';
use if !$Config{use64bitint}, 'Math::BigFloat';

use Moo;

#pod =attr value
#pod
#pod A integer representing milliseconds since the Unix epoch.  The default
#pod is 0.

lib/BSON/Time.pm  view on Meta::CPAN

            $args{value} =  time() * 1000;
        }
        else {
            $args{value} = Math::BigFloat->new(time());
            $args{value}->bmul(1000);
            $args{value} = $args{value}->as_number('zero');
        }
    }
    elsif ( $n == 1 ) {
        croak "argument to BSON::Time::new must be epoch seconds, not '$_[0]'"
          unless looks_like_number( $_[0] );

        if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) {
            $args{value} = Math::BigFloat->new(shift);
            $args{value}->bmul(1000);
            $args{value} = $args{value}->as_number('zero');
        }
        else {
            $args{value} = 1000 * shift;
        }
    }
    elsif ( $n % 2 == 0 ) {
        %args = @_;
        if ( defined $args{value} ) {
            croak "argument to BSON::Time::new must be epoch seconds, not '$args{value}'"
              unless looks_like_number( $args{value} ) || overload::Overloaded($args{value});

            if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) {
                $args{value} = Math::BigInt->new($args{value});
            }
        }
        else {
            if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) {
                $args{value} = Math::BigFloat->new(shift);
                $args{value}->bmul(1000);
                $args{value} = $args{value}->as_number('zero');



( run in 0.470 second using v1.01-cache-2.11-cpan-64827b87656 )