Created
May 20, 2015 23:47
-
-
Save dagolden/2953781d8cbb3b6cb3d7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 38d79a190b9f2adf34c2c84c4014f90912f368d9 | |
Author: David Golden <[email protected]> | |
Date: Wed May 20 19:47:03 2015 -0400 | |
encode integers as BSON Int32 if they fit | |
diff --git a/perl_mongo.c b/perl_mongo.c | |
index 54833fe..9cc619b 100644 | |
--- a/perl_mongo.c | |
+++ b/perl_mongo.c | |
@@ -908,7 +908,13 @@ sv_to_bson_elem (bson_t * bson, const char * in_key, SV *sv, HV *opts, stackette | |
/* if it's publicly an int OR (privately an int AND not publicly a string) */ | |
if (aggressively_number || (!is_string && (SvIOK(sv) || (SvIOKp(sv) && !SvPOK(sv))))) { | |
#if defined(MONGO_USE_64_BIT_INT) | |
- bson_append_int64(bson, key, -1, (int64_t)SvIV(sv)); | |
+ IV i = SvIV(sv); | |
+ if ( i >= INT32_MIN && i <= INT32_MAX) { | |
+ bson_append_int32(bson, key, -1, (int)i); | |
+ } | |
+ else { | |
+ bson_append_int64(bson, key, -1, (int64_t)i); | |
+ } | |
#else | |
bson_append_int32(bson, key, -1, (int)SvIV(sv)); | |
#endif | |
diff --git a/t/bson_codec/elements.t b/t/bson_codec/elements.t | |
index bbcc7e0..e0c769d 100644 | |
--- a/t/bson_codec/elements.t | |
+++ b/t/bson_codec/elements.t | |
@@ -19,6 +19,7 @@ use Test::More 0.96; | |
use Test::Deep 0.086; # num() function | |
use Test::Fatal; | |
+use Config; | |
use DateTime; | |
use DateTime::Tiny; | |
use MongoDB; | |
@@ -69,6 +70,8 @@ use constant { | |
BSON_DATETIME => "\x09", | |
BSON_NULL => "\x0A", | |
BSON_REGEXP => "\x0B", | |
+ BSON_INT32 => "\x10", | |
+ BSON_INT64 => "\x12", | |
}; | |
my $class = "MongoDB::BSON"; | |
@@ -144,8 +147,37 @@ my @cases = ( | |
output => | |
{ a => [ '$db' => $dbref->db, '$id' => $dbref->id, '$ref' => $dbref->ref ] }, | |
}, | |
+ { | |
+ label => "BSON Int32", | |
+ input => { a => 66 }, | |
+ bson => _doc( BSON_INT32 . _ename("a") . _int32(66) ), | |
+ output => { a => 66 }, | |
+ }, | |
+ { | |
+ label => "BSON Int64 (max 32 bit int)", | |
+ input => { a => 2147483647 }, | |
+ bson => _doc( BSON_INT32 . _ename("a") . _int32(2147483647) ), | |
+ output => { a => 2147483647 }, | |
+ }, | |
+ { | |
+ label => "BSON Int64 (min 32 bit int)", | |
+ input => { a => -2147483647-1 }, | |
+ bson => _doc( BSON_INT32 . _ename("a") . _int32(-2147483647-1) ), | |
+ output => { a => -2147483647-1 }, | |
+ }, | |
); | |
+if ( $Config{use64bitint} ) { | |
+ my $big = 20 << 40; | |
+ push @cases, | |
+ { | |
+ label => "BSON Int64", | |
+ input => { a => $big }, | |
+ bson => _doc( BSON_INT64 . _ename("a") . _int64($big) ), | |
+ output => { a => $big }, | |
+ }; | |
+} | |
+ | |
for my $c (@cases) { | |
my ( $label, $input, $bson, $output ) = @{$c}{qw/label input bson output/}; | |
my $encoded = $codec->encode_one( $input, $c->{enc_opts} || {} ); | |
@@ -175,6 +207,10 @@ BEGIN { *_ename = \&_cstring } | |
sub _double { return pack( "d", shift ) } | |
+sub _int32 { return pack( P_INT32, shift ) } | |
+ | |
+sub _int64 { return pack( P_INT64, shift ) } | |
+ | |
sub _string { | |
my ($string) = shift; | |
return pack( P_INT32, 1 + length($string) ) . $string . "\x00"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment