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.25 by root, Fri Nov 22 05:54:07 2013 UTC vs.
Revision 1.28 by root, Sat Nov 23 18:30:59 2013 UTC

19# define HvNAMELEN(hv) HvNAMELEN_get (hv) 19# define HvNAMELEN(hv) HvNAMELEN_get (hv)
20#endif 20#endif
21#ifndef HvNAMEUTF8 21#ifndef HvNAMEUTF8
22# define HvNAMEUTF8(hv) 0 22# define HvNAMEUTF8(hv) 0
23#endif 23#endif
24#ifndef SvREFCNT_dec_NN
25# define SvREFCNT_dec_NN(sv) SvREFCNT_dec (sv)
26#endif
24 27
25// known tags 28// known tags
26enum cbor_tag 29enum cbor_tag
27{ 30{
28 // inofficial extensions (pending iana registration) 31 // inofficial extensions (pending iana registration)
79# define CBOR_SLOW 0 82# define CBOR_SLOW 0
80# define CBOR_STASH cbor_stash 83# define CBOR_STASH cbor_stash
81#endif 84#endif
82 85
83static HV *cbor_stash, *types_boolean_stash, *types_error_stash, *cbor_tagged_stash; // CBOR::XS:: 86static HV *cbor_stash, *types_boolean_stash, *types_error_stash, *cbor_tagged_stash; // CBOR::XS::
84static SV *types_true, *types_false, *types_error, *sv_cbor; 87static SV *types_true, *types_false, *types_error, *sv_cbor, *default_filter;
85 88
86typedef struct { 89typedef struct {
87 U32 flags; 90 U32 flags;
88 U32 max_depth; 91 U32 max_depth;
89 STRLEN max_size; 92 STRLEN max_size;
93 SV *filter;
90} CBOR; 94} CBOR;
91 95
92ecb_inline void 96ecb_inline void
93cbor_init (CBOR *cbor) 97cbor_init (CBOR *cbor)
94{ 98{
95 Zero (cbor, 1, CBOR); 99 Zero (cbor, 1, CBOR);
96 cbor->max_depth = 512; 100 cbor->max_depth = 512;
101}
102
103ecb_inline void
104cbor_free (CBOR *cbor)
105{
106 SvREFCNT_dec (cbor->filter);
97} 107}
98 108
99///////////////////////////////////////////////////////////////////////////// 109/////////////////////////////////////////////////////////////////////////////
100// utility functions 110// utility functions
101 111
271 } 281 }
272 282
273 --enc->depth; 283 --enc->depth;
274} 284}
275 285
276ecb_inline void
277encode_he (enc_t *enc, HE *he)
278{
279}
280
281static void 286static void
282encode_hv (enc_t *enc, HV *hv) 287encode_hv (enc_t *enc, HV *hv)
283{ 288{
284 HE *he; 289 HE *he;
285 290
547 CBOR cbor; 552 CBOR cbor;
548 U32 depth; // recursion depth 553 U32 depth; // recursion depth
549 U32 maxdepth; // recursion depth limit 554 U32 maxdepth; // recursion depth limit
550 AV *shareable; 555 AV *shareable;
551 AV *stringref; 556 AV *stringref;
557 SV *decode_tagged;
552} dec_t; 558} dec_t;
553 559
554#define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE 560#define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE
555 561
556#define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") 562#define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data")
910 916
911 default: 917 default:
912 { 918 {
913 sv = decode_sv (dec); 919 sv = decode_sv (dec);
914 920
921 dSP;
922 ENTER; SAVETMPS; PUSHMARK (SP);
923 EXTEND (SP, 2);
924 PUSHs (newSVuv (tag));
925 PUSHs (sv);
926
927 PUTBACK;
928 int count = call_sv (dec->cbor.filter ? dec->cbor.filter : default_filter, G_ARRAY | G_EVAL);
929 SPAGAIN;
930
931 if (SvTRUE (ERRSV))
932 {
933 FREETMPS; LEAVE;
934 ERR (SvPVutf8_nolen (sv_2mortal (SvREFCNT_inc (ERRSV))));
935 }
936
937 if (count)
938 {
939 SvREFCNT_dec (sv);
940 sv = SvREFCNT_inc (POPs);
941 }
942 else
943 {
915 AV *av = newAV (); 944 AV *av = newAV ();
916 av_push (av, newSVuv (tag)); 945 av_push (av, newSVuv (tag));
917 av_push (av, sv); 946 av_push (av, sv);
918 947
919 HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash 948 HV *tagged_stash = !CBOR_SLOW || cbor_tagged_stash
920 ? cbor_tagged_stash 949 ? cbor_tagged_stash
921 : gv_stashpv ("CBOR::XS::Tagged" , 1); 950 : gv_stashpv ("CBOR::XS::Tagged" , 1);
922
923 sv = sv_bless (newRV_noinc ((SV *)av), tagged_stash); 951 sv = sv_bless (newRV_noinc ((SV *)av), tagged_stash);
952 }
953
954 PUTBACK;
955
956 FREETMPS; LEAVE;
924 } 957 }
925 break; 958 break;
926 } 959 }
927 960
928 return sv; 961 return sv;
1074 1107
1075 types_true = get_bool ("Types::Serialiser::true" ); 1108 types_true = get_bool ("Types::Serialiser::true" );
1076 types_false = get_bool ("Types::Serialiser::false"); 1109 types_false = get_bool ("Types::Serialiser::false");
1077 types_error = get_bool ("Types::Serialiser::error"); 1110 types_error = get_bool ("Types::Serialiser::error");
1078 1111
1112 default_filter = newSVpv ("CBOR::XS::default_filter", 0);
1113
1079 sv_cbor = newSVpv ("CBOR", 0); 1114 sv_cbor = newSVpv ("CBOR", 0);
1080 SvREADONLY_on (sv_cbor); 1115 SvREADONLY_on (sv_cbor);
1081} 1116}
1082 1117
1083PROTOTYPES: DISABLE 1118PROTOTYPES: DISABLE
1146 CODE: 1181 CODE:
1147 RETVAL = self->max_size; 1182 RETVAL = self->max_size;
1148 OUTPUT: 1183 OUTPUT:
1149 RETVAL 1184 RETVAL
1150 1185
1186void filter (CBOR *self, SV *filter = 0)
1187 PPCODE:
1188 SvREFCNT_dec (self->filter);
1189 self->filter = filter ? newSVsv (filter) : filter;
1190 XPUSHs (ST (0));
1191
1192SV *get_filter (CBOR *self)
1193 CODE:
1194 RETVAL = self->filter ? self->filter : NEWSV (0, 0);
1195 OUTPUT:
1196 RETVAL
1197
1151void encode (CBOR *self, SV *scalar) 1198void encode (CBOR *self, SV *scalar)
1152 PPCODE: 1199 PPCODE:
1153 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN; 1200 PUTBACK; scalar = encode_cbor (scalar, self); SPAGAIN;
1154 XPUSHs (scalar); 1201 XPUSHs (scalar);
1155 1202
1167 EXTEND (SP, 2); 1214 EXTEND (SP, 2);
1168 PUSHs (sv); 1215 PUSHs (sv);
1169 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr)))); 1216 PUSHs (sv_2mortal (newSVuv (offset - SvPVX (cborstr))));
1170} 1217}
1171 1218
1219void DESTROY (CBOR *self)
1220 PPCODE:
1221 cbor_free (self);
1222
1172PROTOTYPES: ENABLE 1223PROTOTYPES: ENABLE
1173 1224
1174void encode_cbor (SV *scalar) 1225void encode_cbor (SV *scalar)
1175 PPCODE: 1226 PPCODE:
1176{ 1227{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines