mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-19 04:52:59 +01:00
Merge branch 'master' of tokuhirom@git.sourceforge.jp:/gitroot/msgpack/msgpack
Conflicts: perl/lib/Data/MessagePack.pm
This commit is contained in:
commit
3397d261d8
@ -20,10 +20,14 @@ XS(xs_unpacker_data);
|
|||||||
XS(xs_unpacker_reset);
|
XS(xs_unpacker_reset);
|
||||||
XS(xs_unpacker_destroy);
|
XS(xs_unpacker_destroy);
|
||||||
|
|
||||||
|
void boot_Data__MessagePack_pack(void);
|
||||||
|
|
||||||
XS(boot_Data__MessagePack) {
|
XS(boot_Data__MessagePack) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
HV * stash;
|
HV * stash;
|
||||||
|
|
||||||
|
boot_Data__MessagePack_pack();
|
||||||
|
|
||||||
newXS("Data::MessagePack::pack", xs_pack, __FILE__);
|
newXS("Data::MessagePack::pack", xs_pack, __FILE__);
|
||||||
newXS("Data::MessagePack::unpack", xs_unpack, __FILE__);
|
newXS("Data::MessagePack::unpack", xs_unpack, __FILE__);
|
||||||
stash = gv_stashpvn("Data::MessagePack", strlen("Data::MessagePack"), TRUE);
|
stash = gv_stashpvn("Data::MessagePack", strlen("Data::MessagePack"), TRUE);
|
||||||
|
@ -5,6 +5,7 @@ use XSLoader;
|
|||||||
use 5.008001;
|
use 5.008001;
|
||||||
|
|
||||||
our $VERSION = '0.03';
|
our $VERSION = '0.03';
|
||||||
|
our $PreferInteger = 0;
|
||||||
|
|
||||||
XSLoader::load(__PACKAGE__, $VERSION);
|
XSLoader::load(__PACKAGE__, $VERSION);
|
||||||
|
|
||||||
|
93
perl/pack.c
93
perl/pack.c
@ -26,7 +26,7 @@ typedef struct {
|
|||||||
char *end; /* SvEND (sv) */
|
char *end; /* SvEND (sv) */
|
||||||
SV *sv; /* result scalar */
|
SV *sv; /* result scalar */
|
||||||
} enc_t;
|
} enc_t;
|
||||||
void need(enc_t *enc, STRLEN len);
|
static void need(enc_t *enc, STRLEN len);
|
||||||
|
|
||||||
#define msgpack_pack_user enc_t*
|
#define msgpack_pack_user enc_t*
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ void need(enc_t *enc, STRLEN len);
|
|||||||
#define PACK_WRAPPER(t) _PACK_WRAPPER(t)
|
#define PACK_WRAPPER(t) _PACK_WRAPPER(t)
|
||||||
#define INIT_SIZE 32 /* initial scalar size to be allocated */
|
#define INIT_SIZE 32 /* initial scalar size to be allocated */
|
||||||
|
|
||||||
void need(enc_t *enc, STRLEN len)
|
static void need(enc_t *enc, STRLEN len)
|
||||||
{
|
{
|
||||||
if (enc->cur + len >= enc->end) {
|
if (enc->cur + len >= enc->end) {
|
||||||
STRLEN cur = enc->cur - (char *)SvPVX (enc->sv);
|
STRLEN cur = enc->cur - (char *)SvPVX (enc->sv);
|
||||||
@ -51,16 +51,92 @@ void need(enc_t *enc, STRLEN len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int looks_like_int(const char *str, size_t len) {
|
|
||||||
int i;
|
static int s_pref_int = 0;
|
||||||
for (i=0; i<len; i++) {
|
|
||||||
if (!isDIGIT(str[i])) {
|
static int pref_int_set(pTHX_ SV* sv, MAGIC* mg) {
|
||||||
|
if (SvTRUE(sv)) {
|
||||||
|
s_pref_int = 1;
|
||||||
|
} else {
|
||||||
|
s_pref_int = 0;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MGVTBL pref_int_vtbl = {
|
||||||
|
NULL,
|
||||||
|
pref_int_set,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
#ifdef MGf_LOCAL
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void boot_Data__MessagePack_pack(void) {
|
||||||
|
SV* var = get_sv("Data::MessagePack::PreferInteger", 0);
|
||||||
|
sv_magicext(var, NULL, PERL_MAGIC_ext, &pref_int_vtbl, NULL, 0);
|
||||||
|
SvSETMAGIC(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int try_int(enc_t* enc, const char *p, size_t len) {
|
||||||
|
int negative = 0;
|
||||||
|
const char* pe = p + len;
|
||||||
|
uint64_t num = 0;
|
||||||
|
|
||||||
|
if (len == 0) { return 0; }
|
||||||
|
|
||||||
|
if (*p == '-') {
|
||||||
|
/* length(-0x80000000) == 11 */
|
||||||
|
if (len <= 1 || len > 11) { return 0; }
|
||||||
|
negative = 1;
|
||||||
|
++p;
|
||||||
|
} else {
|
||||||
|
/* length(0xFFFFFFFF) == 10 */
|
||||||
|
if (len > 10) { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if '9'=='8'+1 && '8'=='7'+1 && '7'=='6'+1 && '6'=='5'+1 && '5'=='4'+1 \
|
||||||
|
&& '4'=='3'+1 && '3'=='2'+1 && '2'=='1'+1 && '1'=='0'+1
|
||||||
|
do {
|
||||||
|
unsigned int c = ((int)*(p++)) - '0';
|
||||||
|
if (c > 9) { return 0; }
|
||||||
|
num = num * 10 + c;
|
||||||
|
} while(p < pe);
|
||||||
|
#else
|
||||||
|
do {
|
||||||
|
switch (*(p++)) {
|
||||||
|
case '0': num = num * 10 + 0; break;
|
||||||
|
case '1': num = num * 10 + 1; break;
|
||||||
|
case '2': num = num * 10 + 2; break;
|
||||||
|
case '3': num = num * 10 + 3; break;
|
||||||
|
case '4': num = num * 10 + 4; break;
|
||||||
|
case '5': num = num * 10 + 5; break;
|
||||||
|
case '6': num = num * 10 + 6; break;
|
||||||
|
case '7': num = num * 10 + 7; break;
|
||||||
|
case '8': num = num * 10 + 8; break;
|
||||||
|
case '9': num = num * 10 + 9; break;
|
||||||
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
} while(p < pe);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
if (num > 0x80000000) { return 0; }
|
||||||
|
msgpack_pack_int32(enc, ((int32_t)num) * -1);
|
||||||
|
} else {
|
||||||
|
if (num > 0xFFFFFFFF) { return 0; }
|
||||||
|
msgpack_pack_uint32(enc, (uint32_t)num);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _msgpack_pack_sv(enc_t *enc, SV* val) {
|
static void _msgpack_pack_sv(enc_t *enc, SV* val) {
|
||||||
if (val==NULL) {
|
if (val==NULL) {
|
||||||
msgpack_pack_nil(enc);
|
msgpack_pack_nil(enc);
|
||||||
@ -131,11 +207,8 @@ static void _msgpack_pack_sv(enc_t *enc, SV* val) {
|
|||||||
if (SvPOKp(val)) {
|
if (SvPOKp(val)) {
|
||||||
STRLEN len;
|
STRLEN len;
|
||||||
char * cval = SvPV(val, len);
|
char * cval = SvPV(val, len);
|
||||||
const int U32_STRLEN = 10; /* length(0xFFFFFFFF) */
|
|
||||||
|
|
||||||
SV* pref_int = get_sv("Data::MessagePack::PreferInteger", 0);
|
if (s_pref_int && try_int(enc, cval, len)) {
|
||||||
if (pref_int && SvTRUE(pref_int) && len <= U32_STRLEN && looks_like_int(cval, len) && SvUV(val) < U32_MAX) {
|
|
||||||
PACK_WRAPPER(uint32)(enc, SvUV(val));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,15 +17,24 @@ sub pis ($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my @dat = (
|
my @dat = (
|
||||||
|
'', 'a0',
|
||||||
'0', '00',
|
'0', '00',
|
||||||
'1', '01',
|
'1', '01',
|
||||||
'10', '0a',
|
'10', '0a',
|
||||||
|
'-1', 'ff',
|
||||||
|
'-10', 'f6',
|
||||||
|
'-', 'a1 2d',
|
||||||
''.0xEFFF => 'cd ef ff',
|
''.0xEFFF => 'cd ef ff',
|
||||||
''.0xFFFF => 'cd ff ff',
|
''.0xFFFF => 'cd ff ff',
|
||||||
''.0xFFFFFF => 'ce 00 ff ff ff',
|
''.0xFFFFFF => 'ce 00 ff ff ff',
|
||||||
''.0xFFFFFFFF => 'aa 34 32 39 34 39 36 37 32 39 35',
|
''.0xFFFFFFFF => 'ce ff ff ff ff',
|
||||||
''.0xFFFFFFFFF => 'ab 36 38 37 31 39 34 37 36 37 33 35',
|
''.0xFFFFFFFFF => 'ab 36 38 37 31 39 34 37 36 37 33 35',
|
||||||
''.0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF => 'b4 38 2e 33 30 37 36 37 34 39 37 33 36 35 35 37 32 65 2b 33 34',
|
''.0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF => 'b4 38 2e 33 30 37 36 37 34 39 37 33 36 35 35 37 32 65 2b 33 34',
|
||||||
|
'-'.0x8000000 => 'd2 f8 00 00 00',
|
||||||
|
'-'.0x80000000 => 'd2 80 00 00 00',
|
||||||
|
'-'.0x800000000 => 'ac 2d 33 34 33 35 39 37 33 38 33 36 38',
|
||||||
|
'-'.0x8000000000 => 'ad 2d 35 34 39 37 35 35 38 31 33 38 38 38',
|
||||||
|
'-'.0x800000000000000000000000000000 => 'b5 2d 36 2e 36 34 36 31 33 39 39 37 38 39 32 34 35 38 65 2b 33 35',
|
||||||
{'0' => '1'}, '81 00 01',
|
{'0' => '1'}, '81 00 01',
|
||||||
{'abc' => '1'}, '81 a3 61 62 63 01',
|
{'abc' => '1'}, '81 a3 61 62 63 01',
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user