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

Comparing CBOR-XS/XS.xs (file contents):
Revision 1.5 by root, Sat Oct 26 21:14:20 2013 UTC vs.
Revision 1.43 by root, Sun Jan 5 14:24:54 2014 UTC

9#include <limits.h> 9#include <limits.h>
10#include <float.h> 10#include <float.h>
11 11
12#include "ecb.h" 12#include "ecb.h"
13 13
14// compatibility with perl <5.18
15#ifndef HvNAMELEN_get
16# define HvNAMELEN_get(hv) strlen (HvNAME (hv))
17#endif
18#ifndef HvNAMELEN
19# define HvNAMELEN(hv) HvNAMELEN_get (hv)
20#endif
21#ifndef HvNAMEUTF8
22# define HvNAMEUTF8(hv) 0
23#endif
24#ifndef SvREFCNT_dec_NN
25# define SvREFCNT_dec_NN(sv) SvREFCNT_dec (sv)
26#endif
27
28// known major and minor types
29enum cbor_type
30{
31 MAJOR_SHIFT = 5,
32 MINOR_MASK = 0x1f,
33
34 MAJOR_POS_INT = 0 << MAJOR_SHIFT,
35 MAJOR_NEG_INT = 1 << MAJOR_SHIFT,
36 MAJOR_BYTES = 2 << MAJOR_SHIFT,
37 MAJOR_TEXT = 3 << MAJOR_SHIFT,
38 MAJOR_ARRAY = 4 << MAJOR_SHIFT,
39 MAJOR_MAP = 5 << MAJOR_SHIFT,
40 MAJOR_TAG = 6 << MAJOR_SHIFT,
41 MAJOR_MISC = 7 << MAJOR_SHIFT,
42
43 // INT/STRING/ARRAY/MAP subtypes
44 LENGTH_EXT1 = 24,
45 LENGTH_EXT2 = 25,
46 LENGTH_EXT4 = 26,
47 LENGTH_EXT8 = 27,
48
49 // SIMPLE types (effectively MISC subtypes)
50 SIMPLE_FALSE = 20,
51 SIMPLE_TRUE = 21,
52 SIMPLE_NULL = 22,
53 SIMPLE_UNDEF = 23,
54
55 // MISC subtype (unused)
56 MISC_EXT1 = 24,
57 MISC_FLOAT16 = 25,
58 MISC_FLOAT32 = 26,
59 MISC_FLOAT64 = 27,
60
61 // BYTES/TEXT/ARRAY/MAP
62 MINOR_INDEF = 31,
63};
64
65// known tags
66enum cbor_tag
67{
68 // extensions
69 CBOR_TAG_STRINGREF = 25, // http://cbor.schmorp.de/stringref
70 CBOR_TAG_PERL_OBJECT = 26, // http://cbor.schmorp.de/perl-object
71 CBOR_TAG_GENERIC_OBJECT = 27, // http://cbor.schmorp.de/generic-object
72 CBOR_TAG_VALUE_SHAREABLE = 28, // http://cbor.schmorp.de/value-sharing
73 CBOR_TAG_VALUE_SHAREDREF = 29, // http://cbor.schmorp.de/value-sharing
74 CBOR_TAG_STRINGREF_NAMESPACE = 256, // http://cbor.schmorp.de/stringref
75 CBOR_TAG_INDIRECTION = 22098, // http://cbor.schmorp.de/indirection
76
77 // rfc7049
78 CBOR_TAG_DATETIME = 0, // rfc4287, utf-8
79 CBOR_TAG_TIMESTAMP = 1, // unix timestamp, any
80 CBOR_TAG_POS_BIGNUM = 2, // byte string
81 CBOR_TAG_NEG_BIGNUM = 3, // byte string
82 CBOR_TAG_DECIMAL = 4, // decimal fraction, array
83 CBOR_TAG_BIGFLOAT = 5, // array
84
85 CBOR_TAG_CONV_B64U = 21, // base64url, any
86 CBOR_TAG_CONV_B64 = 22, // base64, any
87 CBOR_TAG_CONV_HEX = 23, // base16, any
88 CBOR_TAG_CBOR = 24, // embedded cbor, byte string
89
90 CBOR_TAG_URI = 32, // URI rfc3986, utf-8
91 CBOR_TAG_B64U = 33, // base64url rfc4648, utf-8
92 CBOR_TAG_B64 = 34, // base6 rfc46484, utf-8
93 CBOR_TAG_REGEX = 35, // regex pcre/ecma262, utf-8
94 CBOR_TAG_MIME = 36, // mime message rfc2045, utf-8
95
96 CBOR_TAG_MAGIC = 55799, // self-describe cbor
97};
98
14#define F_SHRINK 0x00000200UL 99#define F_SHRINK 0x00000001UL
15#define F_ALLOW_UNKNOWN 0x00002000UL 100#define F_ALLOW_UNKNOWN 0x00000002UL
101#define F_ALLOW_SHARING 0x00000004UL
102#define F_ALLOW_CYCLES 0x00000008UL
103#define F_PACK_STRINGS 0x00000010UL
104#define F_VALIDATE_UTF8 0x00000020UL
16 105
17#define INIT_SIZE 32 // initial scalar size to be allocated 106#define INIT_SIZE 32 // initial scalar size to be allocated
18 107
19#define SB do { 108#define SB do {
20#define SE } while (0) 109#define SE } while (0)
31#else 120#else
32# define CBOR_SLOW 0 121# define CBOR_SLOW 0
33# define CBOR_STASH cbor_stash 122# define CBOR_STASH cbor_stash
34#endif 123#endif
35 124
36static HV *cbor_stash, *cbor_boolean_stash; // CBOR::XS:: 125static HV *cbor_stash, *types_boolean_stash, *types_error_stash, *cbor_tagged_stash; // CBOR::XS::
37static SV *cbor_true, *cbor_false; 126static SV *types_true, *types_false, *types_error, *sv_cbor, *default_filter;
38 127
39typedef struct { 128typedef struct {
40 U32 flags; 129 U32 flags;
41 U32 max_depth; 130 U32 max_depth;
42 STRLEN max_size; 131 STRLEN max_size;
132 SV *filter;
43 133
44 SV *cb_object; 134 // for the incremental parser
45 HV *cb_sk_object; 135 STRLEN incr_pos; // the current offset into the text
136 STRLEN incr_need; // minimum bytes needed to decode
137 AV *incr_count; // for every nesting level, the number of outstanding values, or -1 for indef.
46} CBOR; 138} CBOR;
47 139
48ecb_inline void 140ecb_inline void
49cbor_init (CBOR *cbor) 141cbor_init (CBOR *cbor)
50{ 142{
51 Zero (cbor, 1, CBOR); 143 Zero (cbor, 1, CBOR);
52 cbor->max_depth = 512; 144 cbor->max_depth = 512;
145}
146
147ecb_inline void
148cbor_free (CBOR *cbor)
149{
150 SvREFCNT_dec (cbor->filter);
151 SvREFCNT_dec (cbor->incr_count);
53} 152}
54 153
55///////////////////////////////////////////////////////////////////////////// 154/////////////////////////////////////////////////////////////////////////////
56// utility functions 155// utility functions
57 156
79 SvPV_renew (sv, SvCUR (sv) + 1); 178 SvPV_renew (sv, SvCUR (sv) + 1);
80#endif 179#endif
81 } 180 }
82} 181}
83 182
84///////////////////////////////////////////////////////////////////////////// 183// minimum length of a string to be registered for stringref
85// fp hell 184ecb_inline int
86 185minimum_string_length (UV idx)
87//TODO 186{
187 return idx > 23
188 ? idx > 0xffU
189 ? idx > 0xffffU
190 ? idx > 0xffffffffU
191 ? 11
192 : 7
193 : 5
194 : 4
195 : 3;
196}
88 197
89///////////////////////////////////////////////////////////////////////////// 198/////////////////////////////////////////////////////////////////////////////
90// encoder 199// encoder
91 200
92// structure used for encoding CBOR 201// structure used for encoding CBOR
95 char *cur; // SvPVX (sv) + current output position 204 char *cur; // SvPVX (sv) + current output position
96 char *end; // SvEND (sv) 205 char *end; // SvEND (sv)
97 SV *sv; // result scalar 206 SV *sv; // result scalar
98 CBOR cbor; 207 CBOR cbor;
99 U32 depth; // recursion level 208 U32 depth; // recursion level
209 HV *stringref[2]; // string => index, or 0 ([0] = bytes, [1] = utf-8)
210 UV stringref_idx;
211 HV *shareable; // ptr => index, or 0
212 UV shareable_idx;
100} enc_t; 213} enc_t;
101 214
102ecb_inline void 215ecb_inline void
103need (enc_t *enc, STRLEN len) 216need (enc_t *enc, STRLEN len)
104{ 217{
121static void 234static void
122encode_uint (enc_t *enc, int major, UV len) 235encode_uint (enc_t *enc, int major, UV len)
123{ 236{
124 need (enc, 9); 237 need (enc, 9);
125 238
126 if (len < 24) 239 if (ecb_expect_true (len < LENGTH_EXT1))
127 *enc->cur++ = major | len; 240 *enc->cur++ = major | len;
128 else if (len <= 0xff) 241 else if (ecb_expect_true (len <= 0xffU))
129 { 242 {
130 *enc->cur++ = major | 24; 243 *enc->cur++ = major | LENGTH_EXT1;
131 *enc->cur++ = len; 244 *enc->cur++ = len;
132 } 245 }
133 else if (len <= 0xffff) 246 else if (len <= 0xffffU)
134 { 247 {
135 *enc->cur++ = major | 25; 248 *enc->cur++ = major | LENGTH_EXT2;
136 *enc->cur++ = len >> 8; 249 *enc->cur++ = len >> 8;
137 *enc->cur++ = len; 250 *enc->cur++ = len;
138 } 251 }
139 else if (len <= 0xffffffff) 252 else if (len <= 0xffffffffU)
140 { 253 {
141 *enc->cur++ = major | 26; 254 *enc->cur++ = major | LENGTH_EXT4;
142 *enc->cur++ = len >> 24; 255 *enc->cur++ = len >> 24;
143 *enc->cur++ = len >> 16; 256 *enc->cur++ = len >> 16;
144 *enc->cur++ = len >> 8; 257 *enc->cur++ = len >> 8;
145 *enc->cur++ = len; 258 *enc->cur++ = len;
146 } 259 }
147 else 260 else
148 { 261 {
149 *enc->cur++ = major | 27; 262 *enc->cur++ = major | LENGTH_EXT8;
150 *enc->cur++ = len >> 56; 263 *enc->cur++ = len >> 56;
151 *enc->cur++ = len >> 48; 264 *enc->cur++ = len >> 48;
152 *enc->cur++ = len >> 40; 265 *enc->cur++ = len >> 40;
153 *enc->cur++ = len >> 32; 266 *enc->cur++ = len >> 32;
154 *enc->cur++ = len >> 24; 267 *enc->cur++ = len >> 24;
156 *enc->cur++ = len >> 8; 269 *enc->cur++ = len >> 8;
157 *enc->cur++ = len; 270 *enc->cur++ = len;
158 } 271 }
159} 272}
160 273
161static void 274ecb_inline void
275encode_tag (enc_t *enc, UV tag)
276{
277 encode_uint (enc, MAJOR_TAG, tag);
278}
279
280ecb_inline void
162encode_str (enc_t *enc, int utf8, char *str, STRLEN len) 281encode_str (enc_t *enc, int utf8, char *str, STRLEN len)
163{ 282{
164 encode_uint (enc, utf8 ? 0x60 : 0x40, len); 283 encode_uint (enc, utf8 ? MAJOR_TEXT : MAJOR_BYTES, len);
165 need (enc, len); 284 need (enc, len);
166 memcpy (enc->cur, str, len); 285 memcpy (enc->cur, str, len);
167 enc->cur += len; 286 enc->cur += len;
168} 287}
169 288
289static void
290encode_strref (enc_t *enc, int utf8, char *str, STRLEN len)
291{
292 if (ecb_expect_false (enc->cbor.flags & F_PACK_STRINGS))
293 {
294 SV **svp = hv_fetch (enc->stringref[!!utf8], str, len, 1);
295
296 if (SvOK (*svp))
297 {
298 // already registered, use stringref
299 encode_tag (enc, CBOR_TAG_STRINGREF);
300 encode_uint (enc, MAJOR_POS_INT, SvUV (*svp));
301 return;
302 }
303 else if (len >= minimum_string_length (enc->stringref_idx))
304 {
305 // register only
306 sv_setuv (*svp, enc->stringref_idx);
307 ++enc->stringref_idx;
308 }
309 }
310
311 encode_str (enc, utf8, str, len);
312}
313
170static void encode_sv (enc_t *enc, SV *sv); 314static void encode_sv (enc_t *enc, SV *sv);
171 315
172static void 316static void
173encode_av (enc_t *enc, AV *av) 317encode_av (enc_t *enc, AV *av)
174{ 318{
177 if (enc->depth >= enc->cbor.max_depth) 321 if (enc->depth >= enc->cbor.max_depth)
178 croak (ERR_NESTING_EXCEEDED); 322 croak (ERR_NESTING_EXCEEDED);
179 323
180 ++enc->depth; 324 ++enc->depth;
181 325
182 encode_uint (enc, 0x80, len + 1); 326 encode_uint (enc, MAJOR_ARRAY, len + 1);
183 327
184 for (i = 0; i <= len; ++i) 328 for (i = 0; i <= len; ++i)
185 { 329 {
186 SV **svp = av_fetch (av, i, 0); 330 SV **svp = av_fetch (av, i, 0);
187 encode_sv (enc, svp ? *svp : &PL_sv_undef); 331 encode_sv (enc, svp ? *svp : &PL_sv_undef);
202 346
203 int pairs = hv_iterinit (hv); 347 int pairs = hv_iterinit (hv);
204 int mg = SvMAGICAL (hv); 348 int mg = SvMAGICAL (hv);
205 349
206 if (mg) 350 if (mg)
207 encode_ch (enc, 0xa0 | 31); 351 encode_ch (enc, MAJOR_MAP | MINOR_INDEF);
208 else 352 else
209 encode_uint (enc, 0xa0, pairs); 353 encode_uint (enc, MAJOR_MAP, pairs);
210 354
211 while ((he = hv_iternext (hv))) 355 while ((he = hv_iternext (hv)))
212 { 356 {
213 if (HeKLEN (he) == HEf_SVKEY) 357 if (HeKLEN (he) == HEf_SVKEY)
214 encode_sv (enc, HeSVKEY (he)); 358 encode_sv (enc, HeSVKEY (he));
215 else 359 else
216 encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); 360 encode_strref (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he));
217 361
218 encode_sv (enc, ecb_expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he)); 362 encode_sv (enc, ecb_expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he));
219 } 363 }
220 364
221 if (mg) 365 if (mg)
222 encode_ch (enc, 0xe0 | 31); 366 encode_ch (enc, MAJOR_MISC | MINOR_INDEF);
223 367
224 --enc->depth; 368 --enc->depth;
225} 369}
226 370
227// encode objects, arrays and special \0=false and \1=true values. 371// encode objects, arrays and special \0=false and \1=true values.
228static void 372static void
229encode_rv (enc_t *enc, SV *sv) 373encode_rv (enc_t *enc, SV *sv)
230{ 374{
231 svtype svt;
232
233 SvGETMAGIC (sv); 375 SvGETMAGIC (sv);
376
234 svt = SvTYPE (sv); 377 svtype svt = SvTYPE (sv);
235 378
236 if (ecb_expect_false (SvOBJECT (sv))) 379 if (ecb_expect_false (SvOBJECT (sv)))
237 { 380 {
238 HV *stash = !CBOR_SLOW || cbor_boolean_stash 381 HV *boolean_stash = !CBOR_SLOW || types_boolean_stash
239 ? cbor_boolean_stash 382 ? types_boolean_stash
383 : gv_stashpv ("Types::Serialiser::Boolean", 1);
384 HV *error_stash = !CBOR_SLOW || types_error_stash
385 ? types_error_stash
386 : gv_stashpv ("Types::Serialiser::Error", 1);
387 HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash
388 ? cbor_tagged_stash
240 : gv_stashpv ("CBOR::XS::Boolean", 1); 389 : gv_stashpv ("CBOR::XS::Tagged" , 1);
241 390
242 if (SvSTASH (sv) == stash) 391 HV *stash = SvSTASH (sv);
243 encode_ch (enc, SvIV (sv) ? 0xe0 | 21 : 0xe0 | 20); 392
393 if (stash == boolean_stash)
394 {
395 encode_ch (enc, SvIV (sv) ? MAJOR_MISC | SIMPLE_TRUE : MAJOR_MISC | SIMPLE_FALSE);
396 return;
397 }
398 else if (stash == error_stash)
399 {
400 encode_ch (enc, MAJOR_MISC | SIMPLE_UNDEF);
401 return;
402 }
403 else if (stash == tagged_stash)
404 {
405 if (svt != SVt_PVAV)
406 croak ("encountered CBOR::XS::Tagged object that isn't an array");
407
408 encode_uint (enc, MAJOR_TAG, SvUV (*av_fetch ((AV *)sv, 0, 1)));
409 encode_sv (enc, *av_fetch ((AV *)sv, 1, 1));
410
411 return;
412 }
413 }
414
415 if (ecb_expect_false (SvREFCNT (sv) > 1)
416 && ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING))
417 {
418 if (!enc->shareable)
419 enc->shareable = (HV *)sv_2mortal ((SV *)newHV ());
420
421 SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1);
422
423 if (SvOK (*svp))
424 {
425 encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF);
426 encode_uint (enc, MAJOR_POS_INT, SvUV (*svp));
427 return;
428 }
244 else 429 else
245 { 430 {
246#if 0 //TODO 431 sv_setuv (*svp, enc->shareable_idx);
247 if (enc->cbor.flags & F_CONV_BLESSED) 432 ++enc->shareable_idx;
433 encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE);
434 }
435 }
436
437 if (ecb_expect_false (SvOBJECT (sv)))
438 {
439 HV *stash = SvSTASH (sv);
440 GV *method;
441
442 if ((method = gv_fetchmethod_autoload (stash, "TO_CBOR", 0)))
248 { 443 {
444 dSP;
445
446 ENTER; SAVETMPS; PUSHMARK (SP);
249 // we re-bless the reference to get overload and other niceties right 447 // we re-bless the reference to get overload and other niceties right
250 GV *to_cbor = gv_fetchmethod_autoload (SvSTASH (sv), "TO_CBOR", 0);
251
252 if (to_cbor)
253 {
254 dSP;
255
256 ENTER; SAVETMPS; PUSHMARK (SP);
257 XPUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), SvSTASH (sv))); 448 XPUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), stash));
258 449
259 // calling with G_SCALAR ensures that we always get a 1 return value
260 PUTBACK; 450 PUTBACK;
451 // G_SCALAR ensures that return value is 1
261 call_sv ((SV *)GvCV (to_cbor), G_SCALAR); 452 call_sv ((SV *)GvCV (method), G_SCALAR);
262 SPAGAIN; 453 SPAGAIN;
263 454
264 // catch this surprisingly common error 455 // catch this surprisingly common error
265 if (SvROK (TOPs) && SvRV (TOPs) == sv) 456 if (SvROK (TOPs) && SvRV (TOPs) == sv)
266 croak ("%s::TO_CBOR method returned same object as was passed instead of a new one", HvNAME (SvSTASH (sv))); 457 croak ("%s::TO_CBOR method returned same object as was passed instead of a new one", HvNAME (stash));
267 458
268 sv = POPs;
269 PUTBACK;
270
271 encode_sv (enc, sv); 459 encode_sv (enc, POPs);
272 460
461 PUTBACK;
462
273 FREETMPS; LEAVE; 463 FREETMPS; LEAVE;
274 }
275 else if (enc->cbor.flags & F_ALLOW_BLESSED)
276 encode_str (enc, "null", 4, 0);
277 else
278 croak ("encountered object '%s', but neither allow_blessed enabled nor TO_CBOR method available on it",
279 SvPV_nolen (sv_2mortal (newRV_inc (sv))));
280 } 464 }
281 else if (enc->cbor.flags & F_ALLOW_BLESSED) 465 else if ((method = gv_fetchmethod_autoload (stash, "FREEZE", 0)) != 0)
282 encode_str (enc, "null", 4, 0); 466 {
467 dSP;
468
469 ENTER; SAVETMPS; PUSHMARK (SP);
470 EXTEND (SP, 2);
471 // we re-bless the reference to get overload and other niceties right
472 PUSHs (sv_bless (sv_2mortal (newRV_inc (sv)), stash));
473 PUSHs (sv_cbor);
474
475 PUTBACK;
476 int count = call_sv ((SV *)GvCV (method), G_ARRAY);
477 SPAGAIN;
478
479 // catch this surprisingly common error
480 if (count == 1 && SvROK (TOPs) && SvRV (TOPs) == sv)
481 croak ("%s::FREEZE(CBOR) method returned same object as was passed instead of a new one", HvNAME (stash));
482
483 encode_tag (enc, CBOR_TAG_PERL_OBJECT);
484 encode_uint (enc, MAJOR_ARRAY, count + 1);
485 encode_strref (enc, HvNAMEUTF8 (stash), HvNAME (stash), HvNAMELEN (stash));
486
487 while (count)
488 encode_sv (enc, SP[1 - count--]);
489
490 PUTBACK;
491
492 FREETMPS; LEAVE;
493 }
283 else 494 else
284 croak ("encountered object '%s', but neither allow_blessed nor convert_blessed settings are enabled", 495 croak ("encountered object '%s', but no TO_CBOR or FREEZE methods available on it",
285 SvPV_nolen (sv_2mortal (newRV_inc (sv)))); 496 SvPV_nolen (sv_2mortal (newRV_inc (sv))));
286#endif
287 }
288 } 497 }
289 else if (svt == SVt_PVHV) 498 else if (svt == SVt_PVHV)
290 encode_hv (enc, (HV *)sv); 499 encode_hv (enc, (HV *)sv);
291 else if (svt == SVt_PVAV) 500 else if (svt == SVt_PVAV)
292 encode_av (enc, (AV *)sv); 501 encode_av (enc, (AV *)sv);
293 else if (svt < SVt_PVAV)
294 {
295 STRLEN len = 0;
296 char *pv = svt ? SvPV (sv, len) : 0;
297
298 if (len == 1 && *pv == '1')
299 encode_ch (enc, 0xe0 | 21);
300 else if (len == 1 && *pv == '0')
301 encode_ch (enc, 0xe0 | 20);
302 else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
303 encode_ch (enc, 0xe0 | 23);
304 else
305 croak ("cannot encode reference to scalar '%s' unless the scalar is 0 or 1",
306 SvPV_nolen (sv_2mortal (newRV_inc (sv))));
307 }
308 else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
309 encode_ch (enc, 0xe0 | 23);
310 else 502 else
311 croak ("encountered %s, but CBOR can only represent references to arrays or hashes", 503 {
312 SvPV_nolen (sv_2mortal (newRV_inc (sv)))); 504 encode_tag (enc, CBOR_TAG_INDIRECTION);
505 encode_sv (enc, sv);
506 }
313} 507}
314 508
315static void 509static void
316encode_nv (enc_t *enc, SV *sv) 510encode_nv (enc_t *enc, SV *sv)
317{ 511{
318 double nv = SvNVX (sv); 512 double nv = SvNVX (sv);
319 513
320 need (enc, 9); 514 need (enc, 9);
321 515
322 if (ecb_expect_false (nv == (U32)nv)) 516 if (ecb_expect_false (nv == (NV)(U32)nv))
323 encode_uint (enc, 0x00, (U32)nv); 517 encode_uint (enc, MAJOR_POS_INT, (U32)nv);
324 //TODO: maybe I32? 518 //TODO: maybe I32?
325 else if (ecb_expect_false (nv == (float)nv)) 519 else if (ecb_expect_false (nv == (float)nv))
326 { 520 {
327 uint32_t fp = ecb_float_to_binary32 (nv); 521 uint32_t fp = ecb_float_to_binary32 (nv);
328 522
329 *enc->cur++ = 0xe0 | 26; 523 *enc->cur++ = MAJOR_MISC | MISC_FLOAT32;
330 524
331 if (!ecb_big_endian ()) 525 if (!ecb_big_endian ())
332 fp = ecb_bswap32 (fp); 526 fp = ecb_bswap32 (fp);
333 527
334 memcpy (enc->cur, &fp, 4); 528 memcpy (enc->cur, &fp, 4);
336 } 530 }
337 else 531 else
338 { 532 {
339 uint64_t fp = ecb_double_to_binary64 (nv); 533 uint64_t fp = ecb_double_to_binary64 (nv);
340 534
341 *enc->cur++ = 0xe0 | 27; 535 *enc->cur++ = MAJOR_MISC | MISC_FLOAT64;
342 536
343 if (!ecb_big_endian ()) 537 if (!ecb_big_endian ())
344 fp = ecb_bswap64 (fp); 538 fp = ecb_bswap64 (fp);
345 539
346 memcpy (enc->cur, &fp, 8); 540 memcpy (enc->cur, &fp, 8);
355 549
356 if (SvPOKp (sv)) 550 if (SvPOKp (sv))
357 { 551 {
358 STRLEN len; 552 STRLEN len;
359 char *str = SvPV (sv, len); 553 char *str = SvPV (sv, len);
360 encode_str (enc, SvUTF8 (sv), str, len); 554 encode_strref (enc, SvUTF8 (sv), str, len);
361 } 555 }
362 else if (SvNOKp (sv)) 556 else if (SvNOKp (sv))
363 encode_nv (enc, sv); 557 encode_nv (enc, sv);
364 else if (SvIOKp (sv)) 558 else if (SvIOKp (sv))
365 { 559 {
366 if (SvIsUV (sv)) 560 if (SvIsUV (sv))
367 encode_uint (enc, 0x00, SvUVX (sv)); 561 encode_uint (enc, MAJOR_POS_INT, SvUVX (sv));
368 else if (SvIVX (sv) >= 0) 562 else if (SvIVX (sv) >= 0)
369 encode_uint (enc, 0x00, SvIVX (sv)); 563 encode_uint (enc, MAJOR_POS_INT, SvIVX (sv));
370 else 564 else
371 encode_uint (enc, 0x20, -(SvIVX (sv) + 1)); 565 encode_uint (enc, MAJOR_NEG_INT, -(SvIVX (sv) + 1));
372 } 566 }
373 else if (SvROK (sv)) 567 else if (SvROK (sv))
374 encode_rv (enc, SvRV (sv)); 568 encode_rv (enc, SvRV (sv));
375 else if (!SvOK (sv)) 569 else if (!SvOK (sv))
376 encode_ch (enc, 0xe0 | 22); 570 encode_ch (enc, MAJOR_MISC | SIMPLE_NULL);
377 else if (enc->cbor.flags & F_ALLOW_UNKNOWN) 571 else if (enc->cbor.flags & F_ALLOW_UNKNOWN)
378 encode_ch (enc, 0xe0 | 23); 572 encode_ch (enc, MAJOR_MISC | SIMPLE_UNDEF);
379 else 573 else
380 croak ("encountered perl type (%s,0x%x) that CBOR cannot handle, check your input data", 574 croak ("encountered perl type (%s,0x%x) that CBOR cannot handle, check your input data",
381 SvPV_nolen (sv), (unsigned int)SvFLAGS (sv)); 575 SvPV_nolen (sv), (unsigned int)SvFLAGS (sv));
382} 576}
383 577
384static SV * 578static SV *
385encode_cbor (SV *scalar, CBOR *cbor) 579encode_cbor (SV *scalar, CBOR *cbor)
386{ 580{
387 enc_t enc; 581 enc_t enc = { };
388 582
389 enc.cbor = *cbor; 583 enc.cbor = *cbor;
390 enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE)); 584 enc.sv = sv_2mortal (NEWSV (0, INIT_SIZE));
391 enc.cur = SvPVX (enc.sv); 585 enc.cur = SvPVX (enc.sv);
392 enc.end = SvEND (enc.sv); 586 enc.end = SvEND (enc.sv);
393 enc.depth = 0;
394 587
395 SvPOK_only (enc.sv); 588 SvPOK_only (enc.sv);
589
590 if (cbor->flags & F_PACK_STRINGS)
591 {
592 encode_tag (&enc, CBOR_TAG_STRINGREF_NAMESPACE);
593 enc.stringref[0]= (HV *)sv_2mortal ((SV *)newHV ());
594 enc.stringref[1]= (HV *)sv_2mortal ((SV *)newHV ());
595 }
596
396 encode_sv (&enc, scalar); 597 encode_sv (&enc, scalar);
397 598
398 SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv)); 599 SvCUR_set (enc.sv, enc.cur - SvPVX (enc.sv));
399 *SvEND (enc.sv) = 0; // many xs functions expect a trailing 0 for text strings 600 *SvEND (enc.sv) = 0; // many xs functions expect a trailing 0 for text strings
400 601
414 U8 *end; // end of input string 615 U8 *end; // end of input string
415 const char *err; // parse error, if != 0 616 const char *err; // parse error, if != 0
416 CBOR cbor; 617 CBOR cbor;
417 U32 depth; // recursion depth 618 U32 depth; // recursion depth
418 U32 maxdepth; // recursion depth limit 619 U32 maxdepth; // recursion depth limit
620 AV *shareable;
621 AV *stringref;
622 SV *decode_tagged;
419} dec_t; 623} dec_t;
420 624
421#define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE 625#define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE
422 626
423#define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") 627#define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data")
426#define DEC_DEC_DEPTH --dec->depth 630#define DEC_DEC_DEPTH --dec->depth
427 631
428static UV 632static UV
429decode_uint (dec_t *dec) 633decode_uint (dec_t *dec)
430{ 634{
431 switch (*dec->cur & 31) 635 U8 m = *dec->cur & MINOR_MASK;
432 { 636 ++dec->cur;
433 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
434 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
435 case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
436 return *dec->cur++ & 31;
437 637
438 case 24: 638 if (ecb_expect_true (m < LENGTH_EXT1))
639 return m;
640 else if (ecb_expect_true (m == LENGTH_EXT1))
641 {
439 WANT (2); 642 WANT (1);
440 dec->cur += 2; 643 dec->cur += 1;
441 return dec->cur[-1]; 644 return dec->cur[-1];
442 645 }
443 case 25: 646 else if (ecb_expect_true (m == LENGTH_EXT2))
647 {
444 WANT (3); 648 WANT (2);
445 dec->cur += 3; 649 dec->cur += 2;
446 return (((UV)dec->cur[-2]) << 8) 650 return (((UV)dec->cur[-2]) << 8)
447 | ((UV)dec->cur[-1]); 651 | ((UV)dec->cur[-1]);
448 652 }
449 case 26: 653 else if (ecb_expect_true (m == LENGTH_EXT4))
654 {
450 WANT (5); 655 WANT (4);
451 dec->cur += 5; 656 dec->cur += 4;
452 return (((UV)dec->cur[-4]) << 24) 657 return (((UV)dec->cur[-4]) << 24)
453 | (((UV)dec->cur[-3]) << 16) 658 | (((UV)dec->cur[-3]) << 16)
454 | (((UV)dec->cur[-2]) << 8) 659 | (((UV)dec->cur[-2]) << 8)
455 | ((UV)dec->cur[-1]); 660 | ((UV)dec->cur[-1]);
456 661 }
457 case 27: 662 else if (ecb_expect_true (m == LENGTH_EXT8))
663 {
458 WANT (9); 664 WANT (8);
459 dec->cur += 9; 665 dec->cur += 8;
666
667 return
668#if UVSIZE < 8
669 0
670#else
460 return (((UV)dec->cur[-8]) << 56) 671 (((UV)dec->cur[-8]) << 56)
461 | (((UV)dec->cur[-7]) << 48) 672 | (((UV)dec->cur[-7]) << 48)
462 | (((UV)dec->cur[-6]) << 40) 673 | (((UV)dec->cur[-6]) << 40)
463 | (((UV)dec->cur[-5]) << 32) 674 | (((UV)dec->cur[-5]) << 32)
675#endif
464 | (((UV)dec->cur[-4]) << 24) 676 | (((UV)dec->cur[-4]) << 24)
465 | (((UV)dec->cur[-3]) << 16) 677 | (((UV)dec->cur[-3]) << 16)
466 | (((UV)dec->cur[-2]) << 8) 678 | (((UV)dec->cur[-2]) << 8)
467 | ((UV)dec->cur[-1]); 679 | ((UV)dec->cur[-1]);
468 680 }
469 default: 681 else
470 ERR ("corrupted CBOR data (unsupported integer minor encoding)"); 682 ERR ("corrupted CBOR data (unsupported integer minor encoding)");
471 }
472 683
473fail: 684fail:
474 return 0; 685 return 0;
475} 686}
476 687
481{ 692{
482 AV *av = newAV (); 693 AV *av = newAV ();
483 694
484 DEC_INC_DEPTH; 695 DEC_INC_DEPTH;
485 696
486 if ((*dec->cur & 31) == 31) 697 if (*dec->cur == (MAJOR_ARRAY | MINOR_INDEF))
487 { 698 {
488 ++dec->cur; 699 ++dec->cur;
489 700
490 for (;;) 701 for (;;)
491 { 702 {
492 WANT (1); 703 WANT (1);
493 704
494 if (*dec->cur == (0xe0 | 31)) 705 if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
495 { 706 {
496 ++dec->cur; 707 ++dec->cur;
497 break; 708 break;
498 } 709 }
499 710
502 } 713 }
503 else 714 else
504 { 715 {
505 int i, len = decode_uint (dec); 716 int i, len = decode_uint (dec);
506 717
718 WANT (len); // complexity check for av_fill - need at least one byte per value, do not allow supersize arrays
507 av_fill (av, len - 1); 719 av_fill (av, len - 1);
508 720
509 for (i = 0; i < len; ++i) 721 for (i = 0; i < len; ++i)
510 AvARRAY (av)[i] = decode_sv (dec); 722 AvARRAY (av)[i] = decode_sv (dec);
511 } 723 }
517 SvREFCNT_dec (av); 729 SvREFCNT_dec (av);
518 DEC_DEC_DEPTH; 730 DEC_DEC_DEPTH;
519 return &PL_sv_undef; 731 return &PL_sv_undef;
520} 732}
521 733
734static void
735decode_he (dec_t *dec, HV *hv)
736{
737 // for speed reasons, we specialcase single-string
738 // byte or utf-8 strings as keys, but only when !stringref
739
740 if (ecb_expect_true (!dec->stringref))
741 if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8))
742 {
743 I32 len = decode_uint (dec);
744 char *key = (char *)dec->cur;
745
746 dec->cur += len;
747
748 hv_store (hv, key, len, decode_sv (dec), 0);
749
750 return;
751 }
752 else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8))
753 {
754 I32 len = decode_uint (dec);
755 char *key = (char *)dec->cur;
756
757 dec->cur += len;
758
759 if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
760 if (!is_utf8_string (key, len))
761 ERR ("corrupted CBOR data (invalid UTF-8 in map key)");
762
763 hv_store (hv, key, -len, decode_sv (dec), 0);
764
765 return;
766 }
767
768 SV *k = decode_sv (dec);
769 SV *v = decode_sv (dec);
770
771 hv_store_ent (hv, k, v, 0);
772 SvREFCNT_dec (k);
773
774fail:
775 ;
776}
777
522static SV * 778static SV *
523decode_hv (dec_t *dec) 779decode_hv (dec_t *dec)
524{ 780{
525 HV *hv = newHV (); 781 HV *hv = newHV ();
526 782
527 DEC_INC_DEPTH; 783 DEC_INC_DEPTH;
528 784
529 if ((*dec->cur & 31) == 31) 785 if (*dec->cur == (MAJOR_MAP | MINOR_INDEF))
530 { 786 {
531 ++dec->cur; 787 ++dec->cur;
532 788
533 for (;;) 789 for (;;)
534 { 790 {
535 WANT (1); 791 WANT (1);
536 792
537 if (*dec->cur == (0xe0 | 31)) 793 if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
538 { 794 {
539 ++dec->cur; 795 ++dec->cur;
540 break; 796 break;
541 } 797 }
542 798
543 SV *k = decode_sv (dec); 799 decode_he (dec, hv);
544 SV *v = decode_sv (dec);
545
546 hv_store_ent (hv, k, v, 0);
547 } 800 }
548 } 801 }
549 else 802 else
550 { 803 {
551 int len = decode_uint (dec); 804 int pairs = decode_uint (dec);
552 805
553 while (len--) 806 while (pairs--)
554 { 807 decode_he (dec, hv);
555 SV *k = decode_sv (dec);
556 SV *v = decode_sv (dec);
557
558 hv_store_ent (hv, k, v, 0);
559 }
560 } 808 }
561 809
562 DEC_DEC_DEPTH; 810 DEC_DEC_DEPTH;
563 return newRV_noinc ((SV *)hv); 811 return newRV_noinc ((SV *)hv);
564
565#if 0
566 SV *sv;
567 HV *hv = newHV ();
568
569 DEC_INC_DEPTH;
570 decode_ws (dec);
571
572 for (;;)
573 {
574 // heuristic: assume that
575 // a) decode_str + hv_store_ent are abysmally slow.
576 // b) most hash keys are short, simple ascii text.
577 // => try to "fast-match" such strings to avoid
578 // the overhead of decode_str + hv_store_ent.
579 {
580 SV *value;
581 char *p = dec->cur;
582 char *e = p + 24; // only try up to 24 bytes
583
584 for (;;)
585 {
586 // the >= 0x80 is false on most architectures
587 if (p == e || *p < 0x20 || *p >= 0x80 || *p == '\\')
588 {
589 // slow path, back up and use decode_str
590 SV *key = decode_str (dec);
591 if (!key)
592 goto fail;
593
594 decode_ws (dec); EXPECT_CH (':');
595
596 decode_ws (dec);
597 value = decode_sv (dec);
598 if (!value)
599 {
600 SvREFCNT_dec (key);
601 goto fail;
602 }
603
604 hv_store_ent (hv, key, value, 0);
605 SvREFCNT_dec (key);
606
607 break;
608 }
609 else if (*p == '"')
610 {
611 // fast path, got a simple key
612 char *key = dec->cur;
613 int len = p - key;
614 dec->cur = p + 1;
615
616 decode_ws (dec); EXPECT_CH (':');
617
618 decode_ws (dec);
619 value = decode_sv (dec);
620 if (!value)
621 goto fail;
622
623 hv_store (hv, key, len, value, 0);
624
625 break;
626 }
627
628 ++p;
629 }
630 }
631
632 decode_ws (dec);
633
634 if (*dec->cur == '}')
635 {
636 ++dec->cur;
637 break;
638 }
639
640 if (*dec->cur != ',')
641 ERR (", or } expected while parsing object/hash");
642
643 ++dec->cur;
644
645 decode_ws (dec);
646
647 if (*dec->cur == '}' && dec->cbor.flags & F_RELAXED)
648 {
649 ++dec->cur;
650 break;
651 }
652 }
653
654 DEC_DEC_DEPTH;
655 sv = newRV_noinc ((SV *)hv);
656
657 // check filter callbacks
658 if (dec->cbor.flags & F_HOOK)
659 {
660 if (dec->cbor.cb_sk_object && HvKEYS (hv) == 1)
661 {
662 HE *cb, *he;
663
664 hv_iterinit (hv);
665 he = hv_iternext (hv);
666 hv_iterinit (hv);
667
668 // the next line creates a mortal sv each time its called.
669 // might want to optimise this for common cases.
670 cb = hv_fetch_ent (dec->cbor.cb_sk_object, hv_iterkeysv (he), 0, 0);
671
672 if (cb)
673 {
674 dSP;
675 int count;
676
677 ENTER; SAVETMPS; PUSHMARK (SP);
678 XPUSHs (HeVAL (he));
679 sv_2mortal (sv);
680
681 PUTBACK; count = call_sv (HeVAL (cb), G_ARRAY); SPAGAIN;
682
683 if (count == 1)
684 {
685 sv = newSVsv (POPs);
686 FREETMPS; LEAVE;
687 return sv;
688 }
689
690 SvREFCNT_inc (sv);
691 FREETMPS; LEAVE;
692 }
693 }
694
695 if (dec->cbor.cb_object)
696 {
697 dSP;
698 int count;
699
700 ENTER; SAVETMPS; PUSHMARK (SP);
701 XPUSHs (sv_2mortal (sv));
702
703 PUTBACK; count = call_sv (dec->cbor.cb_object, G_ARRAY); SPAGAIN;
704
705 if (count == 1)
706 {
707 sv = newSVsv (POPs);
708 FREETMPS; LEAVE;
709 return sv;
710 }
711
712 SvREFCNT_inc (sv);
713 FREETMPS; LEAVE;
714 }
715 }
716
717 return sv;
718#endif
719 812
720fail: 813fail:
721 SvREFCNT_dec (hv); 814 SvREFCNT_dec (hv);
722 DEC_DEC_DEPTH; 815 DEC_DEC_DEPTH;
723 return &PL_sv_undef; 816 return &PL_sv_undef;
724} 817}
725 818
726static SV * 819static SV *
727decode_str (dec_t *dec, int utf8) 820decode_str (dec_t *dec, int utf8)
728{ 821{
729 SV *sv; 822 SV *sv = 0;
730 823
731 if ((*dec->cur & 31) == 31) 824 if ((*dec->cur & MINOR_MASK) == MINOR_INDEF)
732 { 825 {
826 // indefinite length strings
733 ++dec->cur; 827 ++dec->cur;
734 828
829 U8 major = *dec->cur & MAJOR_MISC;
830
735 sv = newSVpvn ("", 0); 831 sv = newSVpvn ("", 0);
736 832
737 // not very fast, and certainly not robust against illegal input
738 for (;;) 833 for (;;)
739 { 834 {
740 WANT (1); 835 WANT (1);
741 836
742 if (*dec->cur == (0xe0 | 31)) 837 if ((*dec->cur - major) > LENGTH_EXT8)
838 if (*dec->cur == (MAJOR_MISC | MINOR_INDEF))
743 { 839 {
744 ++dec->cur; 840 ++dec->cur;
745 break; 841 break;
746 } 842 }
843 else
844 ERR ("corrupted CBOR data (invalid chunks in indefinite length string)");
747 845
748 SV *sv2 = decode_sv (dec); 846 STRLEN len = decode_uint (dec);
749 sv_catsv (sv, sv2); 847
848 WANT (len);
849 sv_catpvn (sv, dec->cur, len);
850 dec->cur += len;
750 } 851 }
751 } 852 }
752 else 853 else
753 { 854 {
754 STRLEN len = decode_uint (dec); 855 STRLEN len = decode_uint (dec);
755 856
756 WANT (len); 857 WANT (len);
757 sv = newSVpvn (dec->cur, len); 858 sv = newSVpvn (dec->cur, len);
758 dec->cur += len; 859 dec->cur += len;
860
861 if (ecb_expect_false (dec->stringref)
862 && SvCUR (sv) >= minimum_string_length (AvFILLp (dec->stringref) + 1))
863 av_push (dec->stringref, SvREFCNT_inc_NN (sv));
759 } 864 }
760 865
761 if (utf8) 866 if (utf8)
867 {
868 if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
869 if (!is_utf8_string (SvPVX (sv), SvCUR (sv)))
870 ERR ("corrupted CBOR data (invalid UTF-8 in text string)");
871
762 SvUTF8_on (sv); 872 SvUTF8_on (sv);
873 }
763 874
764 return sv; 875 return sv;
765 876
766fail: 877fail:
878 SvREFCNT_dec (sv);
767 return &PL_sv_undef; 879 return &PL_sv_undef;
768} 880}
769 881
770static SV * 882static SV *
771decode_tagged (dec_t *dec) 883decode_tagged (dec_t *dec)
772{ 884{
885 SV *sv = 0;
773 UV tag = decode_uint (dec); 886 UV tag = decode_uint (dec);
887
888 WANT (1);
889
890 switch (tag)
891 {
892 case CBOR_TAG_MAGIC:
774 SV *sv = decode_sv (dec); 893 sv = decode_sv (dec);
894 break;
775 895
776 if (tag == 55799) // 2.4.5 Self-Describe CBOR 896 case CBOR_TAG_INDIRECTION:
897 sv = newRV_noinc (decode_sv (dec));
898 break;
899
900 case CBOR_TAG_STRINGREF_NAMESPACE:
901 {
902 ENTER; SAVETMPS;
903
904 SAVESPTR (dec->stringref);
905 dec->stringref = (AV *)sv_2mortal ((SV *)newAV ());
906
907 sv = decode_sv (dec);
908
909 FREETMPS; LEAVE;
910 }
911 break;
912
913 case CBOR_TAG_STRINGREF:
914 {
915 if ((*dec->cur >> MAJOR_SHIFT) != (MAJOR_POS_INT >> MAJOR_SHIFT))
916 ERR ("corrupted CBOR data (stringref index not an unsigned integer)");
917
918 UV idx = decode_uint (dec);
919
920 if (!dec->stringref || (int)idx > AvFILLp (dec->stringref))
921 ERR ("corrupted CBOR data (stringref index out of bounds or outside namespace)");
922
923 sv = newSVsv (AvARRAY (dec->stringref)[idx]);
924 }
925 break;
926
927 case CBOR_TAG_VALUE_SHAREABLE:
928 {
929 if (ecb_expect_false (!dec->shareable))
930 dec->shareable = (AV *)sv_2mortal ((SV *)newAV ());
931
932 if (dec->cbor.flags & F_ALLOW_CYCLES)
933 {
934 sv = newSV (0);
935 av_push (dec->shareable, SvREFCNT_inc_NN (sv));
936
937 SV *osv = decode_sv (dec);
938 sv_setsv (sv, osv);
939 SvREFCNT_dec_NN (osv);
940 }
941 else
942 {
943 av_push (dec->shareable, &PL_sv_undef);
944 int idx = AvFILLp (dec->shareable);
945 sv = decode_sv (dec);
946 av_store (dec->shareable, idx, SvREFCNT_inc_NN (sv));
947 }
948 }
949 break;
950
951 case CBOR_TAG_VALUE_SHAREDREF:
952 {
953 if ((*dec->cur >> MAJOR_SHIFT) != (MAJOR_POS_INT >> MAJOR_SHIFT))
954 ERR ("corrupted CBOR data (sharedref index not an unsigned integer)");
955
956 UV idx = decode_uint (dec);
957
958 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable))
959 ERR ("corrupted CBOR data (sharedref index out of bounds)");
960
961 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]);
962
963 if (sv == &PL_sv_undef)
964 ERR ("cyclic CBOR data structure found, but allow_cycles is not enabled");
965 }
966 break;
967
968 case CBOR_TAG_PERL_OBJECT:
969 {
970 sv = decode_sv (dec);
971
972 if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV)
973 ERR ("corrupted CBOR data (non-array perl object)");
974
975 AV *av = (AV *)SvRV (sv);
976 int len = av_len (av) + 1;
977 HV *stash = gv_stashsv (*av_fetch (av, 0, 1), 0);
978
979 if (!stash)
980 ERR ("cannot decode perl-object (package does not exist)");
981
982 GV *method = gv_fetchmethod_autoload (stash, "THAW", 0);
983
984 if (!method)
985 ERR ("cannot decode perl-object (package does not have a THAW method)");
986
987 dSP;
988
989 ENTER; SAVETMPS; PUSHMARK (SP);
990 EXTEND (SP, len + 1);
991 // we re-bless the reference to get overload and other niceties right
992 PUSHs (*av_fetch (av, 0, 1));
993 PUSHs (sv_cbor);
994
995 int i;
996
997 for (i = 1; i < len; ++i)
998 PUSHs (*av_fetch (av, i, 1));
999
1000 PUTBACK;
1001 call_sv ((SV *)GvCV (method), G_SCALAR | G_EVAL);
1002 SPAGAIN;
1003
1004 if (SvTRUE (ERRSV))
1005 {
1006 FREETMPS; LEAVE;
1007 ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
1008 }
1009
1010 SvREFCNT_dec (sv);
1011 sv = SvREFCNT_inc (POPs);
1012
1013 PUTBACK;
1014
1015 FREETMPS; LEAVE;
1016 }
1017 break;
1018
1019 default:
1020 {
1021 sv = decode_sv (dec);
1022
1023 dSP;
1024 ENTER; SAVETMPS; PUSHMARK (SP);
1025 EXTEND (SP, 2);
1026 PUSHs (newSVuv (tag));
1027 PUSHs (sv);
1028
1029 PUTBACK;
1030 int count = call_sv (dec->cbor.filter ? dec->cbor.filter : default_filter, G_ARRAY | G_EVAL);
1031 SPAGAIN;
1032
1033 if (SvTRUE (ERRSV))
1034 {
1035 FREETMPS; LEAVE;
1036 ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
1037 }
1038
1039 if (count)
1040 {
1041 SvREFCNT_dec (sv);
1042 sv = SvREFCNT_inc (POPs);
1043 }
1044 else
1045 {
1046 AV *av = newAV ();
1047 av_push (av, newSVuv (tag));
1048 av_push (av, sv);
1049
1050 HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash
1051 ? cbor_tagged_stash
1052 : gv_stashpv ("CBOR::XS::Tagged" , 1);
1053 sv = sv_bless (newRV_noinc ((SV *)av), tagged_stash);
1054 }
1055
1056 PUTBACK;
1057
1058 FREETMPS; LEAVE;
1059 }
1060 break;
1061 }
1062
777 return sv; 1063 return sv;
778 1064
779 AV *av = newAV (); 1065fail:
780 av_push (av, newSVuv (tag)); 1066 SvREFCNT_dec (sv);
781 av_push (av, sv); 1067 return &PL_sv_undef;
782 return newRV_noinc ((SV *)av);
783} 1068}
784 1069
785static SV * 1070static SV *
786decode_sv (dec_t *dec) 1071decode_sv (dec_t *dec)
787{ 1072{
788 WANT (1); 1073 WANT (1);
789 1074
790 switch (*dec->cur >> 5) 1075 switch (*dec->cur >> MAJOR_SHIFT)
791 { 1076 {
792 case 0: // unsigned int 1077 case MAJOR_POS_INT >> MAJOR_SHIFT: return newSVuv (decode_uint (dec));
793 //TODO: 64 bit values on 3 2bit perls 1078 case MAJOR_NEG_INT >> MAJOR_SHIFT: return newSViv (-1 - (IV)decode_uint (dec));
794 return newSVuv (decode_uint (dec)); 1079 case MAJOR_BYTES >> MAJOR_SHIFT: return decode_str (dec, 0);
795 case 1: // negative int 1080 case MAJOR_TEXT >> MAJOR_SHIFT: return decode_str (dec, 1);
796 return newSViv (-1 - (IV)decode_uint (dec)); 1081 case MAJOR_ARRAY >> MAJOR_SHIFT: return decode_av (dec);
797 case 2: // octet string 1082 case MAJOR_MAP >> MAJOR_SHIFT: return decode_hv (dec);
798 return decode_str (dec, 0); 1083 case MAJOR_TAG >> MAJOR_SHIFT: return decode_tagged (dec);
799 case 3: // utf-8 string 1084
800 return decode_str (dec, 1); 1085 case MAJOR_MISC >> MAJOR_SHIFT:
801 case 4: // array
802 return decode_av (dec);
803 case 5: // map
804 return decode_hv (dec);
805 case 6: // tag
806 return decode_tagged (dec);
807 case 7: // misc
808 switch (*dec->cur++ & 31) 1086 switch (*dec->cur++ & MINOR_MASK)
809 { 1087 {
810 case 20: 1088 case SIMPLE_FALSE:
811#if CBOR_SLOW 1089#if CBOR_SLOW
812 cbor_false = get_bool ("CBOR::XS::false"); 1090 types_false = get_bool ("Types::Serialiser::false");
813#endif 1091#endif
814 return newSVsv (cbor_false); 1092 return newSVsv (types_false);
815 case 21: 1093 case SIMPLE_TRUE:
816#if CBOR_SLOW 1094#if CBOR_SLOW
817 cbor_true = get_bool ("CBOR::XS::true"); 1095 types_true = get_bool ("Types::Serialiser::true");
818#endif 1096#endif
819 return newSVsv (cbor_true); 1097 return newSVsv (types_true);
820 case 22: 1098 case SIMPLE_NULL:
821 return newSVsv (&PL_sv_undef); 1099 return newSVsv (&PL_sv_undef);
1100 case SIMPLE_UNDEF:
1101#if CBOR_SLOW
1102 types_error = get_bool ("Types::Serialiser::error");
1103#endif
1104 return newSVsv (types_error);
822 1105
823 case 25: 1106 case MISC_FLOAT16:
824 { 1107 {
825 WANT (2); 1108 WANT (2);
826 1109
827 uint16_t fp = (dec->cur[0] << 8) | dec->cur[1]; 1110 uint16_t fp = (dec->cur[0] << 8) | dec->cur[1];
828 dec->cur += 2; 1111 dec->cur += 2;
829 1112
830 return newSVnv (ecb_binary16_to_float (fp)); 1113 return newSVnv (ecb_binary16_to_float (fp));
831 } 1114 }
832 1115
833 case 26: 1116 case MISC_FLOAT32:
834 { 1117 {
835 uint32_t fp; 1118 uint32_t fp;
836 WANT (4); 1119 WANT (4);
837 memcpy (&fp, dec->cur, 4); 1120 memcpy (&fp, dec->cur, 4);
838 dec->cur += 4; 1121 dec->cur += 4;
841 fp = ecb_bswap32 (fp); 1124 fp = ecb_bswap32 (fp);
842 1125
843 return newSVnv (ecb_binary32_to_float (fp)); 1126 return newSVnv (ecb_binary32_to_float (fp));
844 } 1127 }
845 1128
846 case 27: 1129 case MISC_FLOAT64:
847 { 1130 {
848 uint64_t fp; 1131 uint64_t fp;
849 WANT (8); 1132 WANT (8);
850 memcpy (&fp, dec->cur, 8); 1133 memcpy (&fp, dec->cur, 8);
851 dec->cur += 8; 1134 dec->cur += 8;
854 fp = ecb_bswap64 (fp); 1137 fp = ecb_bswap64 (fp);
855 1138
856 return newSVnv (ecb_binary64_to_double (fp)); 1139 return newSVnv (ecb_binary64_to_double (fp));
857 } 1140 }
858 1141
859 // 0..19 unassigned 1142 // 0..19 unassigned simple
860 // 24 reserved + unassigned (reserved values are not encodable) 1143 // 24 reserved + unassigned simple (reserved values are not encodable)
1144 // 28-30 unassigned misc
1145 // 31 break code
861 default: 1146 default:
862 ERR ("corrupted CBOR data (reserved/unassigned major 7 value)"); 1147 ERR ("corrupted CBOR data (reserved/unassigned/unexpected major 7 value)");
863 } 1148 }
864 1149
865 break; 1150 break;
866 } 1151 }
867#if 0
868 switch (*dec->cur)
869 {
870 //case '"': ++dec->cur; return decode_str (dec);
871 case '[': ++dec->cur; return decode_av (dec);
872 case '{': ++dec->cur; return decode_hv (dec);
873
874 case '-':
875 case '0': case '1': case '2': case '3': case '4':
876 case '5': case '6': case '7': case '8': case '9':
877 //TODO return decode_num (dec);
878
879 case 't':
880 if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
881 {
882 dec->cur += 4;
883#if CBOR_SLOW
884 cbor_true = get_bool ("CBOR::XS::true");
885#endif
886 return newSVsv (cbor_true);
887 }
888 else
889 ERR ("'true' expected");
890
891 break;
892
893 case 'f':
894 if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
895 {
896 dec->cur += 5;
897#if CBOR_SLOW
898 cbor_false = get_bool ("CBOR::XS::false");
899#endif
900 return newSVsv (cbor_false);
901 }
902 else
903 ERR ("'false' expected");
904
905 break;
906
907 case 'n':
908 if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "null", 4))
909 {
910 dec->cur += 4;
911 return newSVsv (&PL_sv_undef);
912 }
913 else
914 ERR ("'null' expected");
915
916 break;
917
918 default:
919 ERR ("malformed CBOR string, neither array, object, number, string or atom");
920 break;
921 }
922#endif
923 1152
924fail: 1153fail:
925 return &PL_sv_undef; 1154 return &PL_sv_undef;
926} 1155}
927 1156
928static SV * 1157static SV *
929decode_cbor (SV *string, CBOR *cbor, char **offset_return) 1158decode_cbor (SV *string, CBOR *cbor, char **offset_return)
930{ 1159{
931 dec_t dec; 1160 dec_t dec = { };
932 SV *sv; 1161 SV *sv;
1162 STRLEN len;
1163 char *data = SvPVbyte (string, len);
933 1164
934 /* work around bugs in 5.10 where manipulating magic values
935 * makes perl ignore the magic in subsequent accesses.
936 * also make a copy of non-PV values, to get them into a clean
937 * state (SvPV should do that, but it's buggy, see below).
938 */
939 /*SvGETMAGIC (string);*/
940 if (SvMAGICAL (string) || !SvPOK (string))
941 string = sv_2mortal (newSVsv (string));
942
943 SvUPGRADE (string, SVt_PV);
944
945 /* work around a bug in perl 5.10, which causes SvCUR to fail an
946 * assertion with -DDEBUGGING, although SvCUR is documented to
947 * return the xpv_cur field which certainly exists after upgrading.
948 * according to nicholas clark, calling SvPOK fixes this.
949 * But it doesn't fix it, so try another workaround, call SvPV_nolen
950 * and hope for the best.
951 * Damnit, SvPV_nolen still trips over yet another assertion. This
952 * assertion business is seriously broken, try yet another workaround
953 * for the broken -DDEBUGGING.
954 */
955 {
956#ifdef DEBUGGING
957 STRLEN offset = SvOK (string) ? sv_len (string) : 0;
958#else
959 STRLEN offset = SvCUR (string);
960#endif
961
962 if (offset > cbor->max_size && cbor->max_size) 1165 if (len > cbor->max_size && cbor->max_size)
963 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu", 1166 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
964 (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); 1167 (unsigned long)len, (unsigned long)cbor->max_size);
965 }
966
967 sv_utf8_downgrade (string, 0);
968 1168
969 dec.cbor = *cbor; 1169 dec.cbor = *cbor;
970 dec.cur = (U8 *)SvPVX (string); 1170 dec.cur = (U8 *)data;
971 dec.end = (U8 *)SvEND (string); 1171 dec.end = (U8 *)data + len;
972 dec.err = 0;
973 dec.depth = 0;
974
975 if (dec.cbor.cb_object || dec.cbor.cb_sk_object)
976 ;//TODO dec.cbor.flags |= F_HOOK;
977 1172
978 sv = decode_sv (&dec); 1173 sv = decode_sv (&dec);
979 1174
980 if (offset_return) 1175 if (offset_return)
981 *offset_return = dec.cur; 1176 *offset_return = dec.cur;
984 if (dec.cur != dec.end && !dec.err) 1179 if (dec.cur != dec.end && !dec.err)
985 dec.err = "garbage after CBOR object"; 1180 dec.err = "garbage after CBOR object";
986 1181
987 if (dec.err) 1182 if (dec.err)
988 { 1183 {
1184 if (dec.shareable)
1185 {
1186 // need to break cyclic links, which whould all be in shareable
1187 int i;
1188 SV **svp;
1189
1190 for (i = av_len (dec.shareable) + 1; i--; )
1191 if ((svp = av_fetch (dec.shareable, i, 0)))
1192 sv_setsv (*svp, &PL_sv_undef);
1193 }
1194
989 SvREFCNT_dec (sv); 1195 SvREFCNT_dec (sv);
990 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); 1196 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur);
991 } 1197 }
992 1198
993 sv = sv_2mortal (sv); 1199 sv = sv_2mortal (sv);
994 1200
995 return sv; 1201 return sv;
996} 1202}
997 1203
1204/////////////////////////////////////////////////////////////////////////////
1205// incremental parser
1206
1207#define INCR_DONE(cbor) (AvFILLp (cbor->incr_count) < 0)
1208
1209// returns 0 for notyet, 1 for success or error
1210static int
1211incr_parse (CBOR *self, SV *cborstr)
1212{
1213 STRLEN cur;
1214 SvPV (cborstr, cur);
1215
1216 while (ecb_expect_true (self->incr_need <= cur))
1217 {
1218 // table of integer count bytes
1219 static I8 incr_len[MINOR_MASK + 1] = {
1220 0, 0, 0, 0, 0, 0, 0, 0,
1221 0, 0, 0, 0, 0, 0, 0, 0,
1222 0, 0, 0, 0, 0, 0, 0, 0,
1223 1, 2, 4, 8,-1,-1,-1,-2
1224 };
1225
1226 const U8 *p = SvPVX (cborstr) + self->incr_pos;
1227 U8 m = *p & MINOR_MASK;
1228 IV count = SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]);
1229 I8 ilen = incr_len[m];
1230
1231 self->incr_need = self->incr_pos + 1;
1232
1233 if (ecb_expect_false (ilen < 0))
1234 {
1235 if (m != MINOR_INDEF)
1236 return 1; // error
1237
1238 if (*p == (MAJOR_MISC | MINOR_INDEF))
1239 {
1240 if (count >= 0)
1241 return 1; // error
1242
1243 count = 1;
1244 }
1245 else
1246 {
1247 av_push (self->incr_count, newSViv (-1)); //TODO: nest
1248 count = -1;
1249 }
1250 }
1251 else
1252 {
1253 self->incr_need += ilen;
1254 if (ecb_expect_false (self->incr_need > cur))
1255 return 0;
1256
1257 int major = *p >> MAJOR_SHIFT;
1258
1259 switch (major)
1260 {
1261 case MAJOR_BYTES >> MAJOR_SHIFT:
1262 case MAJOR_TEXT >> MAJOR_SHIFT:
1263 case MAJOR_ARRAY >> MAJOR_SHIFT:
1264 case MAJOR_MAP >> MAJOR_SHIFT:
1265 {
1266 UV len;
1267
1268 if (ecb_expect_false (ilen))
1269 {
1270 len = 0;
1271
1272 do {
1273 len = (len << 8) | *++p;
1274 } while (--ilen);
1275 }
1276 else
1277 len = m;
1278
1279 switch (major)
1280 {
1281 case MAJOR_BYTES >> MAJOR_SHIFT:
1282 case MAJOR_TEXT >> MAJOR_SHIFT:
1283 self->incr_need += len;
1284 if (ecb_expect_false (self->incr_need > cur))
1285 return 0;
1286
1287 break;
1288
1289 case MAJOR_MAP >> MAJOR_SHIFT:
1290 len <<= 1;
1291 case MAJOR_ARRAY >> MAJOR_SHIFT:
1292 if (len)
1293 {
1294 av_push (self->incr_count, newSViv (len + 1)); //TODO: nest
1295 count = len + 1;
1296 }
1297 break;
1298 }
1299 }
1300 }
1301 }
1302
1303 self->incr_pos = self->incr_need;
1304
1305 if (count > 0)
1306 {
1307 while (!--count)
1308 {
1309 if (!AvFILLp (self->incr_count))
1310 return 1; // done
1311
1312 SvREFCNT_dec_NN (av_pop (self->incr_count));
1313 count = SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]);
1314 }
1315
1316 SvIVX (AvARRAY (self->incr_count)[AvFILLp (self->incr_count)]) = count;
1317 }
1318 }
1319
1320 return 0;
1321}
1322
1323
998///////////////////////////////////////////////////////////////////////////// 1324/////////////////////////////////////////////////////////////////////////////
999// XS interface functions 1325// XS interface functions
1000 1326
1001MODULE = CBOR::XS PACKAGE = CBOR::XS 1327MODULE = CBOR::XS PACKAGE = CBOR::XS
1002 1328
1003BOOT: 1329BOOT:
1004{ 1330{
1005 cbor_stash = gv_stashpv ("CBOR::XS" , 1); 1331 cbor_stash = gv_stashpv ("CBOR::XS" , 1);
1006 cbor_boolean_stash = gv_stashpv ("CBOR::XS::Boolean", 1); 1332 cbor_tagged_stash = gv_stashpv ("CBOR::XS::Tagged" , 1);
1007 1333
1008 cbor_true = get_bool ("CBOR::XS::true"); 1334 types_boolean_stash = gv_stashpv ("Types::Serialiser::Boolean", 1);
1009 cbor_false = get_bool ("CBOR::XS::false"); 1335 types_error_stash = gv_stashpv ("Types::Serialiser::Error" , 1);
1336
1337 types_true = get_bool ("Types::Serialiser::true" );
1338 types_false = get_bool ("Types::Serialiser::false");
1339 types_error = get_bool ("Types::Serialiser::error");
1340
1341 default_filter = newSVpv ("CBOR::XS::default_filter", 0);
1342
1343 sv_cbor = newSVpv ("CBOR", 0);
1344 SvREADONLY_on (sv_cbor);
1010} 1345}
1011 1346
1012PROTOTYPES: DISABLE 1347PROTOTYPES: DISABLE
1013 1348
1014void CLONE (...) 1349void CLONE (...)
1015 CODE: 1350 CODE:
1016 cbor_stash = 0; 1351 cbor_stash = 0;
1352 cbor_tagged_stash = 0;
1353 types_error_stash = 0;
1017 cbor_boolean_stash = 0; 1354 types_boolean_stash = 0;
1018 1355
1019void new (char *klass) 1356void new (char *klass)
1020 PPCODE: 1357 PPCODE:
1021{ 1358{
1022 SV *pv = NEWSV (0, sizeof (CBOR)); 1359 SV *pv = NEWSV (0, sizeof (CBOR));
1030 1367
1031void shrink (CBOR *self, int enable = 1) 1368void shrink (CBOR *self, int enable = 1)
1032 ALIAS: 1369 ALIAS:
1033 shrink = F_SHRINK 1370 shrink = F_SHRINK
1034 allow_unknown = F_ALLOW_UNKNOWN 1371 allow_unknown = F_ALLOW_UNKNOWN
1372 allow_sharing = F_ALLOW_SHARING
1373 allow_cycles = F_ALLOW_CYCLES
1374 pack_strings = F_PACK_STRINGS
1375 validate_utf8 = F_VALIDATE_UTF8
1035 PPCODE: 1376 PPCODE:
1036{ 1377{
1037 if (enable) 1378 if (enable)
1038 self->flags |= ix; 1379 self->flags |= ix;
1039 else 1380 else
1044 1385
1045void get_shrink (CBOR *self) 1386void get_shrink (CBOR *self)
1046 ALIAS: 1387 ALIAS:
1047 get_shrink = F_SHRINK 1388 get_shrink = F_SHRINK
1048 get_allow_unknown = F_ALLOW_UNKNOWN 1389 get_allow_unknown = F_ALLOW_UNKNOWN
1390 get_allow_sharing = F_ALLOW_SHARING
1391 get_allow_cycles = F_ALLOW_CYCLES
1392 get_pack_strings = F_PACK_STRINGS
1393 get_validate_utf8 = F_VALIDATE_UTF8
1049 PPCODE: 1394 PPCODE:
1050 XPUSHs (boolSV (self->flags & ix)); 1395 XPUSHs (boolSV (self->flags & ix));
1051 1396
1052void max_depth (CBOR *self, U32 max_depth = 0x80000000UL) 1397void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1053 PPCODE: 1398 PPCODE:
1069 CODE: 1414 CODE:
1070 RETVAL = self->max_size; 1415 RETVAL = self->max_size;
1071 OUTPUT: 1416 OUTPUT:
1072 RETVAL 1417 RETVAL
1073 1418
1074#if 0 //TODO 1419void filter (CBOR *self, SV *filter = 0)
1075
1076void filter_cbor_object (CBOR *self, SV *cb = &PL_sv_undef)
1077 PPCODE: 1420 PPCODE:
1078{
1079 SvREFCNT_dec (self->cb_object); 1421 SvREFCNT_dec (self->filter);
1080 self->cb_object = SvOK (cb) ? newSVsv (cb) : 0; 1422 self->filter = filter ? newSVsv (filter) : filter;
1081
1082 XPUSHs (ST (0)); 1423 XPUSHs (ST (0));
1083}
1084 1424
1085void filter_cbor_single_key_object (CBOR *self, SV *key, SV *cb = &PL_sv_undef) 1425SV *get_filter (CBOR *self)
1086 PPCODE: 1426 CODE:
1087{ 1427 RETVAL = self->filter ? self->filter : NEWSV (0, 0);
1088 if (!self->cb_sk_object) 1428 OUTPUT:
1089 self->cb_sk_object = newHV (); 1429 RETVAL
1090
1091 if (SvOK (cb))
1092 hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
1093 else
1094 {
1095 hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
1096
1097 if (!HvKEYS (self->cb_sk_object))
1098 {
1099 SvREFCNT_dec (self->cb_sk_object);
1100 self->cb_sk_object = 0;
1101 }
1102 }
1103
1104 XPUSHs (ST (0));
1105}
1106
1107#endif
1108 1430
1109void encode (CBOR *self, SV *scalar) 1431void encode (CBOR *self, SV *scalar)
1110 PPCODE: 1432 PPCODE:
1111 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; 1433 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1112 XPUSHs (scalar); 1434 XPUSHs (scalar);
1125 EXTEND (SP, 2); 1447 EXTEND (SP, 2);
1126 PUSHs (sv); 1448 PUSHs (sv);
1127 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); 1449 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1128} 1450}
1129 1451
1452void incr_parse (CBOR *self, SV *cborstr)
1453 ALIAS:
1454 incr_parse_multiple = 1
1455 PPCODE:
1456{
1457 if (SvUTF8 (cborstr))
1458 sv_utf8_downgrade (cborstr, 0);
1459
1460 if (!self->incr_count)
1461 {
1462 self->incr_count = newAV ();
1463 self->incr_pos = 0;
1464 self->incr_need = 1;
1465
1466 av_push (self->incr_count, newSViv (1));
1467 }
1468
1469 do
1470 {
1471 if (!incr_parse (self, cborstr))
1472 {
1473 if (self->incr_need > self->max_size && self->max_size)
1474 croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu",
1475 (unsigned long)self->incr_need, (unsigned long)self->max_size);
1476
1477 break;
1478 }
1479
1480 SV *sv;
1481 char *offset;
1482
1483 PUTBACK; sv = decode_cbor (cborstr, self, &offset); SPAGAIN;
1484 XPUSHs (sv);
1485
1486 sv_chop (cborstr, offset);
1487
1488 av_clear (self->incr_count);
1489 av_push (self->incr_count, newSViv (1));
1490
1491 self->incr_pos = 0;
1492 self->incr_need = self->incr_pos + 1;
1493 }
1494 while (ix);
1495}
1496
1497void incr_reset (CBOR *self)
1498 CODE:
1499{
1500 SvREFCNT_dec (self->incr_count);
1501 self->incr_count = 0;
1502}
1503
1130void DESTROY (CBOR *self) 1504void DESTROY (CBOR *self)
1131 CODE: 1505 PPCODE:
1132 SvREFCNT_dec (self->cb_sk_object); 1506 cbor_free (self);
1133 SvREFCNT_dec (self->cb_object);
1134 1507
1135PROTOTYPES: ENABLE 1508PROTOTYPES: ENABLE
1136 1509
1137void encode_cbor (SV *scalar) 1510void encode_cbor (SV *scalar)
1511 ALIAS:
1512 encode_cbor = 0
1513 encode_cbor_sharing = F_ALLOW_SHARING
1138 PPCODE: 1514 PPCODE:
1139{ 1515{
1140 CBOR cbor; 1516 CBOR cbor;
1141 cbor_init (&cbor); 1517 cbor_init (&cbor);
1518 cbor.flags |= ix;
1142 PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN; 1519 PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN;
1143 XPUSHs (scalar); 1520 XPUSHs (scalar);
1144} 1521}
1145 1522
1146void decode_cbor (SV *cborstr) 1523void decode_cbor (SV *cborstr)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines