ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/CBOR-XS/XS.xs
(Generate patch)

Comparing cvsroot/CBOR-XS/XS.xs (file contents):
Revision 1.30 by root, Thu Nov 28 11:36:53 2013 UTC vs.
Revision 1.33 by root, Sat Nov 30 15:23:59 2013 UTC

59 CBOR_TAG_MAGIC = 55799 // self-describe cbor 59 CBOR_TAG_MAGIC = 55799 // self-describe cbor
60}; 60};
61 61
62#define F_SHRINK 0x00000001UL 62#define F_SHRINK 0x00000001UL
63#define F_ALLOW_UNKNOWN 0x00000002UL 63#define F_ALLOW_UNKNOWN 0x00000002UL
64#define F_ALLOW_SHARING 0x00000004UL //TODO 64#define F_ALLOW_SHARING 0x00000004UL
65#define F_ALLOW_STRINGREF 0x00000008UL //TODO 65#define F_PACK_STRINGS 0x00000008UL
66 66
67#define INIT_SIZE 32 // initial scalar size to be allocated 67#define INIT_SIZE 32 // initial scalar size to be allocated
68 68
69#define SB do { 69#define SB do {
70#define SE } while (0) 70#define SE } while (0)
189static void 189static void
190encode_uint (enc_t *enc, int major, UV len) 190encode_uint (enc_t *enc, int major, UV len)
191{ 191{
192 need (enc, 9); 192 need (enc, 9);
193 193
194 if (len < 24) 194 if (ecb_expect_true (len < 24))
195 *enc->cur++ = major | len; 195 *enc->cur++ = major | len;
196 else if (len <= 0xff) 196 else if (ecb_expect_true (len <= 0xff))
197 { 197 {
198 *enc->cur++ = major | 24; 198 *enc->cur++ = major | 24;
199 *enc->cur++ = len; 199 *enc->cur++ = len;
200 } 200 }
201 else if (len <= 0xffff) 201 else if (len <= 0xffff)
242} 242}
243 243
244static void 244static void
245encode_strref (enc_t *enc, int utf8, char *str, STRLEN len) 245encode_strref (enc_t *enc, int utf8, char *str, STRLEN len)
246{ 246{
247 if (ecb_expect_false (enc->cbor.flags & F_ALLOW_STRINGREF)) 247 if (ecb_expect_false (enc->cbor.flags & F_PACK_STRINGS))
248 { 248 {
249 SV **svp = hv_fetch (enc->stringref[!!utf8], str, len, 1); 249 SV **svp = hv_fetch (enc->stringref[!!utf8], str, len, 1);
250 250
251 if (SvOK (*svp)) 251 if (SvOK (*svp))
252 { 252 {
326// encode objects, arrays and special \0=false and \1=true values. 326// encode objects, arrays and special \0=false and \1=true values.
327static void 327static void
328encode_rv (enc_t *enc, SV *sv) 328encode_rv (enc_t *enc, SV *sv)
329{ 329{
330 SvGETMAGIC (sv); 330 SvGETMAGIC (sv);
331
332 if (ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING)
333 && ecb_expect_false (SvREFCNT (sv) > 1))
334 {
335 if (!enc->shareable)
336 enc->shareable = (HV *)sv_2mortal ((SV *)newHV ());
337
338 SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1);
339
340 if (SvOK (*svp))
341 {
342 encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF);
343 encode_uint (enc, 0x00, SvUV (*svp));
344 return;
345 }
346 else
347 {
348 sv_setuv (*svp, enc->shareable_idx);
349 ++enc->shareable_idx;
350 encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE);
351 }
352 }
353 331
354 svtype svt = SvTYPE (sv); 332 svtype svt = SvTYPE (sv);
355 333
356 if (ecb_expect_false (SvOBJECT (sv))) 334 if (ecb_expect_false (SvOBJECT (sv)))
357 { 335 {
440 encode_hv (enc, (HV *)sv); 418 encode_hv (enc, (HV *)sv);
441 else if (svt == SVt_PVAV) 419 else if (svt == SVt_PVAV)
442 encode_av (enc, (AV *)sv); 420 encode_av (enc, (AV *)sv);
443 else 421 else
444 { 422 {
423 if (ecb_expect_false (SvREFCNT (sv) > 1)
424 && ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING))
425 {
426 if (!enc->shareable)
427 enc->shareable = (HV *)sv_2mortal ((SV *)newHV ());
428
429 SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1);
430
431 if (SvOK (*svp))
432 {
433 encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF);
434 encode_uint (enc, 0x00, SvUV (*svp));
435 return;
436 }
437 else
438 {
439 sv_setuv (*svp, enc->shareable_idx);
440 ++enc->shareable_idx;
441 encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE);
442 }
443 }
444
445 encode_tag (enc, CBOR_TAG_INDIRECTION); 445 encode_tag (enc, CBOR_TAG_INDIRECTION);
446 encode_sv (enc, sv); 446 encode_sv (enc, sv);
447 } 447 }
448} 448}
449 449
526 enc.cur = SvPVX (enc.sv); 526 enc.cur = SvPVX (enc.sv);
527 enc.end = SvEND (enc.sv); 527 enc.end = SvEND (enc.sv);
528 528
529 SvPOK_only (enc.sv); 529 SvPOK_only (enc.sv);
530 530
531 if (cbor->flags & F_ALLOW_STRINGREF) 531 if (cbor->flags & F_PACK_STRINGS)
532 { 532 {
533 encode_tag (&enc, CBOR_TAG_STRINGREF_NAMESPACE); 533 encode_tag (&enc, CBOR_TAG_STRINGREF_NAMESPACE);
534 enc.stringref[0]= (HV *)sv_2mortal ((SV *)newHV ()); 534 enc.stringref[0]= (HV *)sv_2mortal ((SV *)newHV ());
535 enc.stringref[1]= (HV *)sv_2mortal ((SV *)newHV ()); 535 enc.stringref[1]= (HV *)sv_2mortal ((SV *)newHV ());
536 } 536 }
753{ 753{
754 SV *sv = 0; 754 SV *sv = 0;
755 755
756 if ((*dec->cur & 31) == 31) 756 if ((*dec->cur & 31) == 31)
757 { 757 {
758 // indefinite length strings
758 ++dec->cur; 759 ++dec->cur;
759 760
761 unsigned char major = *dec->cur & 0xe0;
762
760 sv = newSVpvn ("", 0); 763 sv = newSVpvn ("", 0);
761 764
762 // not very fast, and certainly not robust against illegal input
763 for (;;) 765 for (;;)
764 { 766 {
765 WANT (1); 767 WANT (1);
766 768
769 if ((*dec->cur ^ major) >= 31)
767 if (*dec->cur == (0xe0 | 31)) 770 if (*dec->cur == (0xe0 | 31))
768 { 771 {
769 ++dec->cur; 772 ++dec->cur;
770 break; 773 break;
771 } 774 }
775 else
776 ERR ("corrupted CBOR data (invalid chunks in indefinite length string)");
772 777
773 sv_catsv (sv, decode_sv (dec)); 778 STRLEN len = decode_uint (dec);
779
780 WANT (len);
781 sv_catpvn (sv, dec->cur, len);
782 dec->cur += len;
774 } 783 }
775 } 784 }
776 else 785 else
777 { 786 {
778 STRLEN len = decode_uint (dec); 787 STRLEN len = decode_uint (dec);
1145void shrink (CBOR *self, int enable = 1) 1154void shrink (CBOR *self, int enable = 1)
1146 ALIAS: 1155 ALIAS:
1147 shrink = F_SHRINK 1156 shrink = F_SHRINK
1148 allow_unknown = F_ALLOW_UNKNOWN 1157 allow_unknown = F_ALLOW_UNKNOWN
1149 allow_sharing = F_ALLOW_SHARING 1158 allow_sharing = F_ALLOW_SHARING
1150 allow_stringref = F_ALLOW_STRINGREF 1159 pack_strings = F_PACK_STRINGS
1151 PPCODE: 1160 PPCODE:
1152{ 1161{
1153 if (enable) 1162 if (enable)
1154 self->flags |= ix; 1163 self->flags |= ix;
1155 else 1164 else
1161void get_shrink (CBOR *self) 1170void get_shrink (CBOR *self)
1162 ALIAS: 1171 ALIAS:
1163 get_shrink = F_SHRINK 1172 get_shrink = F_SHRINK
1164 get_allow_unknown = F_ALLOW_UNKNOWN 1173 get_allow_unknown = F_ALLOW_UNKNOWN
1165 get_allow_sharing = F_ALLOW_SHARING 1174 get_allow_sharing = F_ALLOW_SHARING
1166 get_allow_stringref = F_ALLOW_STRINGREF 1175 get_pack_strings = F_PACK_STRINGS
1167 PPCODE: 1176 PPCODE:
1168 XPUSHs (boolSV (self->flags & ix)); 1177 XPUSHs (boolSV (self->flags & ix));
1169 1178
1170void max_depth (CBOR *self, U32 max_depth = 0x80000000UL) 1179void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1171 PPCODE: 1180 PPCODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines