| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
/* Must be defined before including Perl header files or we slow down by 2x! */ |
|
2
|
|
|
|
|
|
|
#define PERL_NO_GET_CONTEXT |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
#include "EXTERN.h" |
|
5
|
|
|
|
|
|
|
#include "perl.h" |
|
6
|
|
|
|
|
|
|
#include "XSUB.h" |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
#define NEED_newSV_type_GLOBAL |
|
9
|
|
|
|
|
|
|
#include "ppport.h" |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
#include "srl_encoder.h" |
|
12
|
|
|
|
|
|
|
#include "srl_buffer.h" |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
/* Generated code for exposing C constants to Perl */ |
|
15
|
|
|
|
|
|
|
#include "srl_protocol.h" |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#include "ptable.h" |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#ifndef GvCV_set |
|
20
|
|
|
|
|
|
|
# define GvCV_set(gv, cv) (GvCV(gv) = (cv)) |
|
21
|
|
|
|
|
|
|
#endif |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#if defined(cv_set_call_checker) && defined(XopENTRY_set) |
|
24
|
|
|
|
|
|
|
# define USE_CUSTOM_OPS 1 |
|
25
|
|
|
|
|
|
|
#else |
|
26
|
|
|
|
|
|
|
# define USE_CUSTOM_OPS 0 |
|
27
|
|
|
|
|
|
|
#endif |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#define pp1_sereal_encode_with_object(has_hdr) THX_pp1_sereal_encode_with_object(aTHX_ has_hdr) |
|
30
|
|
|
|
|
|
|
static void |
|
31
|
944896
|
|
|
|
|
|
THX_pp1_sereal_encode_with_object(pTHX_ U8 has_hdr) |
|
32
|
|
|
|
|
|
|
{ |
|
33
|
|
|
|
|
|
|
SV *encoder_ref_sv, *encoder_sv, *body_sv, *header_sv; |
|
34
|
|
|
|
|
|
|
srl_encoder_t *enc; |
|
35
|
|
|
|
|
|
|
char *stash_name; |
|
36
|
|
|
|
|
|
|
SV *ret_sv; |
|
37
|
944896
|
|
|
|
|
|
dSP; |
|
38
|
|
|
|
|
|
|
|
|
39
|
944896
|
100
|
|
|
|
|
header_sv = has_hdr ? POPs : NULL; |
|
40
|
944896
|
|
|
|
|
|
body_sv = POPs; |
|
41
|
944896
|
|
|
|
|
|
PUTBACK; |
|
42
|
|
|
|
|
|
|
|
|
43
|
944896
|
|
|
|
|
|
encoder_ref_sv = TOPs; |
|
44
|
|
|
|
|
|
|
|
|
45
|
944896
|
50
|
|
|
|
|
if (!expect_true( |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
encoder_ref_sv && |
|
47
|
|
|
|
|
|
|
SvROK(encoder_ref_sv) && |
|
48
|
|
|
|
|
|
|
(encoder_sv = SvRV(encoder_ref_sv)) && |
|
49
|
|
|
|
|
|
|
SvOBJECT(encoder_sv) && |
|
50
|
|
|
|
|
|
|
(stash_name= HvNAME(SvSTASH(encoder_sv))) && |
|
51
|
|
|
|
|
|
|
!strcmp(stash_name, "Sereal::Encoder") |
|
52
|
|
|
|
|
|
|
)) |
|
53
|
|
|
|
|
|
|
{ |
|
54
|
0
|
|
|
|
|
|
croak("handle is not a Sereal::Encoder handle"); |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
/* we should never have an IV smaller than a PTR */ |
|
57
|
944896
|
50
|
|
|
|
|
enc= INT2PTR(srl_encoder_t *,SvIV(encoder_sv)); |
|
58
|
|
|
|
|
|
|
|
|
59
|
944896
|
100
|
|
|
|
|
if (header_sv && !SvOK(header_sv)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
60
|
168
|
|
|
|
|
|
header_sv = NULL; |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
/* We always copy the string since we might reuse the string buffer. That |
|
63
|
|
|
|
|
|
|
* means we already have to do a malloc and we might as well use the |
|
64
|
|
|
|
|
|
|
* opportunity to allocate only as much memory as we really need to hold |
|
65
|
|
|
|
|
|
|
* the output. */ |
|
66
|
944896
|
|
|
|
|
|
ret_sv= srl_dump_data_structure_mortal_sv(aTHX_ enc, body_sv, header_sv, SRL_ENC_SV_COPY_ALWAYS); |
|
67
|
944893
|
|
|
|
|
|
SPAGAIN; |
|
68
|
944893
|
|
|
|
|
|
TOPs = ret_sv; |
|
69
|
944893
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
#if USE_CUSTOM_OPS |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
static OP * |
|
74
|
243721
|
|
|
|
|
|
THX_pp_sereal_encode_with_object(pTHX) |
|
75
|
|
|
|
|
|
|
{ |
|
76
|
243721
|
|
|
|
|
|
pp1_sereal_encode_with_object(PL_op->op_private); |
|
77
|
243721
|
|
|
|
|
|
return NORMAL; |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
static OP * |
|
81
|
84
|
|
|
|
|
|
THX_ck_entersub_args_sereal_encode_with_object(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) |
|
82
|
|
|
|
|
|
|
{ |
|
83
|
|
|
|
|
|
|
OP *pushop, *firstargop, *cvop, *lastargop, *argop, *newop; |
|
84
|
|
|
|
|
|
|
int arity; |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
/* Walk the OP structure under the "entersub" to validate that we |
|
87
|
|
|
|
|
|
|
* can use the custom OP implementation. */ |
|
88
|
|
|
|
|
|
|
|
|
89
|
84
|
|
|
|
|
|
entersubop = ck_entersub_args_proto(entersubop, namegv, ckobj); |
|
90
|
84
|
|
|
|
|
|
pushop = cUNOPx(entersubop)->op_first; |
|
91
|
84
|
50
|
|
|
|
|
if (!OpHAS_SIBLING(pushop)) |
|
92
|
84
|
|
|
|
|
|
pushop = cUNOPx(pushop)->op_first; |
|
93
|
84
|
50
|
|
|
|
|
firstargop = OpSIBLING(pushop); |
|
94
|
|
|
|
|
|
|
|
|
95
|
252
|
50
|
|
|
|
|
for (cvop = firstargop; OpHAS_SIBLING(cvop); cvop = OpSIBLING(cvop)) ; |
|
|
|
100
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
|
|
97
|
252
|
100
|
|
|
|
|
for (arity = 0, lastargop = pushop, argop = firstargop; argop != cvop; |
|
98
|
168
|
50
|
|
|
|
|
lastargop = argop, argop = OpSIBLING(argop)) |
|
99
|
|
|
|
|
|
|
{ |
|
100
|
168
|
|
|
|
|
|
arity++; |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
84
|
50
|
|
|
|
|
if (expect_false(arity < 2 || arity > 3)) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
104
|
0
|
|
|
|
|
|
return entersubop; |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
/* If we get here, we can replace the entersub with a suitable |
|
107
|
|
|
|
|
|
|
* sereal_encode_with_object custom OP. */ |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
#ifdef op_sibling_splice |
|
110
|
|
|
|
|
|
|
/* op_sibling_splice is new in 5.31 and we have to do things differenly */ |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
/* cut out all ops between the pushmark and the RV2CV */ |
|
113
|
84
|
|
|
|
|
|
op_sibling_splice(NULL, pushop, arity, NULL); |
|
114
|
|
|
|
|
|
|
/* then throw everything else out */ |
|
115
|
84
|
|
|
|
|
|
op_free(entersubop); |
|
116
|
84
|
|
|
|
|
|
newop = newUNOP(OP_NULL, 0, NULL); |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
#else |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
OpMORESIB_set(pushop, cvop); |
|
121
|
|
|
|
|
|
|
OpLASTSIB_set(lastargop, op_parent(lastargop)); |
|
122
|
|
|
|
|
|
|
op_free(entersubop); |
|
123
|
|
|
|
|
|
|
newop = newUNOP(OP_NULL, 0, firstargop); |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
#endif |
|
126
|
|
|
|
|
|
|
|
|
127
|
84
|
|
|
|
|
|
newop->op_type = OP_CUSTOM; |
|
128
|
84
|
|
|
|
|
|
newop->op_private = arity == 3; |
|
129
|
84
|
|
|
|
|
|
newop->op_ppaddr = THX_pp_sereal_encode_with_object; |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
#ifdef op_sibling_splice |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
/* attach the spliced-out args as children of the custom op, while |
|
134
|
|
|
|
|
|
|
* deleting the stub op created by newUNOP() */ |
|
135
|
84
|
|
|
|
|
|
op_sibling_splice(newop, NULL, 1, firstargop); |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
#endif |
|
138
|
|
|
|
|
|
|
|
|
139
|
84
|
|
|
|
|
|
return newop; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
#endif /* USE_CUSTOM_OPS */ |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
static void |
|
145
|
701175
|
|
|
|
|
|
THX_xsfunc_sereal_encode_with_object(pTHX_ CV *cv) |
|
146
|
|
|
|
|
|
|
{ |
|
147
|
701175
|
|
|
|
|
|
dMARK; |
|
148
|
701175
|
|
|
|
|
|
dSP; |
|
149
|
701175
|
|
|
|
|
|
SSize_t arity = SP - MARK; |
|
150
|
|
|
|
|
|
|
PERL_UNUSED_ARG(cv); |
|
151
|
701175
|
50
|
|
|
|
|
if (arity < 2 || arity > 3) |
|
|
|
50
|
|
|
|
|
|
|
152
|
0
|
|
|
|
|
|
croak("bad Sereal encoder usage"); |
|
153
|
701175
|
|
|
|
|
|
pp1_sereal_encode_with_object(arity == 3); |
|
154
|
701172
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
#define MY_CXT_KEY "Sereal::Encoder::_stash" XS_VERSION |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
typedef struct { |
|
159
|
|
|
|
|
|
|
sv_with_hash options[SRL_ENC_OPT_COUNT]; |
|
160
|
|
|
|
|
|
|
} my_cxt_t; |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
START_MY_CXT |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
MODULE = Sereal::Encoder PACKAGE = Sereal::Encoder |
|
165
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
BOOT: |
|
168
|
|
|
|
|
|
|
{ |
|
169
|
|
|
|
|
|
|
{ |
|
170
|
|
|
|
|
|
|
MY_CXT_INIT; |
|
171
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_ALIASED_DEDUPE_STRINGS, SRL_ENC_OPT_STR_ALIASED_DEDUPE_STRINGS ); |
|
172
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_CANONICAL, SRL_ENC_OPT_STR_CANONICAL ); |
|
173
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_CANONICAL_REFS, SRL_ENC_OPT_STR_CANONICAL_REFS ); |
|
174
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_COMPRESS, SRL_ENC_OPT_STR_COMPRESS ); |
|
175
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_COMPRESS_LEVEL, SRL_ENC_OPT_STR_COMPRESS_LEVEL ); |
|
176
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_COMPRESS_THRESHOLD, SRL_ENC_OPT_STR_COMPRESS_THRESHOLD ); |
|
177
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_CROAK_ON_BLESS, SRL_ENC_OPT_STR_CROAK_ON_BLESS ); |
|
178
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_DEDUPE_STRINGS, SRL_ENC_OPT_STR_DEDUPE_STRINGS ); |
|
179
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_FREEZE_CALLBACKS, SRL_ENC_OPT_STR_FREEZE_CALLBACKS ); |
|
180
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_MAX_RECURSION_DEPTH, SRL_ENC_OPT_STR_MAX_RECURSION_DEPTH ); |
|
181
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_NO_BLESS_OBJECTS, SRL_ENC_OPT_STR_NO_BLESS_OBJECTS ); |
|
182
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_NO_SHARED_HASHKEYS, SRL_ENC_OPT_STR_NO_SHARED_HASHKEYS ); |
|
183
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_PROTOCOL_VERSION, SRL_ENC_OPT_STR_PROTOCOL_VERSION ); |
|
184
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_SNAPPY, SRL_ENC_OPT_STR_SNAPPY ); |
|
185
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_SNAPPY_INCR, SRL_ENC_OPT_STR_SNAPPY_INCR ); |
|
186
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_SNAPPY_THRESHOLD, SRL_ENC_OPT_STR_SNAPPY_THRESHOLD ); |
|
187
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_SORT_KEYS, SRL_ENC_OPT_STR_SORT_KEYS ); |
|
188
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_STRINGIFY_UNKNOWN, SRL_ENC_OPT_STR_STRINGIFY_UNKNOWN ); |
|
189
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_UNDEF_UNKNOWN, SRL_ENC_OPT_STR_UNDEF_UNKNOWN ); |
|
190
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_USE_PROTOCOL_V1, SRL_ENC_OPT_STR_USE_PROTOCOL_V1 ); |
|
191
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_WARN_UNKNOWN, SRL_ENC_OPT_STR_WARN_UNKNOWN ); |
|
192
|
87
|
|
|
|
|
|
SRL_INIT_OPTION( SRL_ENC_OPT_IDX_USE_STANDARD_DOUBLE, SRL_ENC_OPT_STR_USE_STANDARD_DOUBLE ); |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
#if USE_CUSTOM_OPS |
|
195
|
|
|
|
|
|
|
{ |
|
196
|
|
|
|
|
|
|
XOP *xop; |
|
197
|
87
|
|
|
|
|
|
Newxz(xop, 1, XOP); |
|
198
|
87
|
|
|
|
|
|
XopENTRY_set(xop, xop_name, "sereal_encode_with_object"); |
|
199
|
87
|
|
|
|
|
|
XopENTRY_set(xop, xop_desc, "sereal_encode_with_object"); |
|
200
|
87
|
|
|
|
|
|
XopENTRY_set(xop, xop_class, OA_UNOP); |
|
201
|
87
|
|
|
|
|
|
Perl_custom_op_register(aTHX_ THX_pp_sereal_encode_with_object, xop); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
#endif /* USE_CUSTOM_OPS */ |
|
204
|
|
|
|
|
|
|
{ |
|
205
|
|
|
|
|
|
|
GV *gv; |
|
206
|
87
|
|
|
|
|
|
CV *cv = newXSproto_portable("Sereal::Encoder::sereal_encode_with_object", |
|
207
|
|
|
|
|
|
|
THX_xsfunc_sereal_encode_with_object, __FILE__, "$$;$"); |
|
208
|
|
|
|
|
|
|
#if USE_CUSTOM_OPS |
|
209
|
87
|
|
|
|
|
|
cv_set_call_checker(cv, THX_ck_entersub_args_sereal_encode_with_object, (SV*)cv); |
|
210
|
|
|
|
|
|
|
#endif /* USE_CUSTOM_OPS */ |
|
211
|
87
|
|
|
|
|
|
gv = gv_fetchpv("Sereal::Encoder::encode", GV_ADDMULTI, SVt_PVCV); |
|
212
|
87
|
|
|
|
|
|
GvCV_set(gv, cv); |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
srl_encoder_t * |
|
217
|
|
|
|
|
|
|
new(CLASS, opt = NULL) |
|
218
|
|
|
|
|
|
|
char *CLASS; |
|
219
|
|
|
|
|
|
|
HV *opt; |
|
220
|
|
|
|
|
|
|
PREINIT: |
|
221
|
|
|
|
|
|
|
dMY_CXT; |
|
222
|
|
|
|
|
|
|
CODE: |
|
223
|
338
|
|
|
|
|
|
RETVAL = srl_build_encoder_struct(aTHX_ opt, MY_CXT.options); |
|
224
|
338
|
|
|
|
|
|
RETVAL->flags |= SRL_F_REUSE_ENCODER; |
|
225
|
|
|
|
|
|
|
OUTPUT: RETVAL |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
void |
|
228
|
|
|
|
|
|
|
DESTROY(enc) |
|
229
|
|
|
|
|
|
|
srl_encoder_t *enc; |
|
230
|
|
|
|
|
|
|
CODE: |
|
231
|
338
|
|
|
|
|
|
srl_destroy_encoder(aTHX_ enc); |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
U32 |
|
234
|
|
|
|
|
|
|
flags(enc) |
|
235
|
|
|
|
|
|
|
srl_encoder_t *enc; |
|
236
|
|
|
|
|
|
|
CODE: |
|
237
|
0
|
|
|
|
|
|
RETVAL = enc->flags; |
|
238
|
|
|
|
|
|
|
OUTPUT: RETVAL |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
void |
|
241
|
|
|
|
|
|
|
encode_sereal(src, opt = NULL) |
|
242
|
|
|
|
|
|
|
SV *src; |
|
243
|
|
|
|
|
|
|
HV *opt; |
|
244
|
|
|
|
|
|
|
PREINIT: |
|
245
|
|
|
|
|
|
|
srl_encoder_t *enc; |
|
246
|
|
|
|
|
|
|
dMY_CXT; |
|
247
|
|
|
|
|
|
|
PPCODE: |
|
248
|
244246
|
|
|
|
|
|
enc = srl_build_encoder_struct(aTHX_ opt, MY_CXT.options); |
|
249
|
|
|
|
|
|
|
assert(enc != NULL); |
|
250
|
|
|
|
|
|
|
/* Avoid copy by stealing string buffer if it is not too large. |
|
251
|
|
|
|
|
|
|
* This makes sense in the functional interface since the string |
|
252
|
|
|
|
|
|
|
* buffer isn't ever going to be reused. */ |
|
253
|
244246
|
|
|
|
|
|
ST(0) = srl_dump_data_structure_mortal_sv(aTHX_ enc, src, NULL, SRL_ENC_SV_REUSE_MAYBE); |
|
254
|
244245
|
|
|
|
|
|
XSRETURN(1); |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
void |
|
257
|
|
|
|
|
|
|
encode_sereal_with_header_data(src, hdr_user_data_src, opt = NULL) |
|
258
|
|
|
|
|
|
|
SV *src; |
|
259
|
|
|
|
|
|
|
SV *hdr_user_data_src; |
|
260
|
|
|
|
|
|
|
HV *opt; |
|
261
|
|
|
|
|
|
|
PREINIT: |
|
262
|
|
|
|
|
|
|
srl_encoder_t *enc; |
|
263
|
|
|
|
|
|
|
dMY_CXT; |
|
264
|
|
|
|
|
|
|
PPCODE: |
|
265
|
2
|
50
|
|
|
|
|
if (!SvOK(hdr_user_data_src)) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
266
|
0
|
|
|
|
|
|
hdr_user_data_src = NULL; |
|
267
|
2
|
|
|
|
|
|
enc = srl_build_encoder_struct(aTHX_ opt, MY_CXT.options); |
|
268
|
|
|
|
|
|
|
assert(enc != NULL); |
|
269
|
|
|
|
|
|
|
/* Avoid copy by stealing string buffer if it is not too large. |
|
270
|
|
|
|
|
|
|
* This makes sense in the functional interface since the string |
|
271
|
|
|
|
|
|
|
* buffer isn't ever going to be reused. */ |
|
272
|
2
|
|
|
|
|
|
ST(0) = srl_dump_data_structure_mortal_sv(aTHX_ enc, src, hdr_user_data_src, SRL_ENC_SV_REUSE_MAYBE); |
|
273
|
2
|
|
|
|
|
|
XSRETURN(1); |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
MODULE = Sereal::Encoder PACKAGE = Sereal::Encoder::_ptabletest |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
void |
|
278
|
|
|
|
|
|
|
test() |
|
279
|
|
|
|
|
|
|
PREINIT: |
|
280
|
|
|
|
|
|
|
PTABLE_t *tbl; |
|
281
|
|
|
|
|
|
|
PTABLE_ITER_t *iter; |
|
282
|
|
|
|
|
|
|
PTABLE_ENTRY_t *ent; |
|
283
|
1
|
|
|
|
|
|
UV i, n = 20; |
|
284
|
|
|
|
|
|
|
char *check[20]; |
|
285
|
1
|
|
|
|
|
|
char fail[5] = "not "; |
|
286
|
1
|
|
|
|
|
|
char noop[1] = ""; |
|
287
|
|
|
|
|
|
|
CODE: |
|
288
|
1
|
|
|
|
|
|
tbl = PTABLE_new_size(10); |
|
289
|
21
|
100
|
|
|
|
|
for (i = 0; i < (UV)n; ++i) { |
|
290
|
20
|
|
|
|
|
|
PTABLE_store(tbl, INT2PTR(void *,(1000+i)), INT2PTR(void *, (1000+i))); |
|
291
|
20
|
|
|
|
|
|
check[i] = fail; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
21
|
100
|
|
|
|
|
for (i = 0; i < (UV)n; ++i) { |
|
294
|
20
|
|
|
|
|
|
const UV res = PTR2UV(PTABLE_fetch(tbl, INT2PTR(void *, (1000+i)))); |
|
295
|
20
|
50
|
|
|
|
|
printf("%sok %u - fetch %u\n", (res == (UV)(1000+i)) ? noop : fail, (unsigned int)(1+i), (unsigned int)(i+1)); |
|
296
|
|
|
|
|
|
|
} |
|
297
|
1
|
|
|
|
|
|
iter = PTABLE_iter_new(tbl); |
|
298
|
21
|
100
|
|
|
|
|
while ( NULL != (ent = PTABLE_iter_next(iter)) ) { |
|
299
|
20
|
|
|
|
|
|
const UV res = (PTR2UV(ent->value)) - 1000; |
|
300
|
20
|
50
|
|
|
|
|
if (res < 20) |
|
301
|
20
|
|
|
|
|
|
check[res] = noop; |
|
302
|
|
|
|
|
|
|
else |
|
303
|
0
|
|
|
|
|
|
abort(); |
|
304
|
|
|
|
|
|
|
} |
|
305
|
21
|
100
|
|
|
|
|
for (i = 0; i < (UV)n; ++i) { |
|
306
|
20
|
|
|
|
|
|
printf("%sok %u - iter %u\n", check[i], (unsigned int)(21+i), (unsigned int)(i+1)); |
|
307
|
|
|
|
|
|
|
} |
|
308
|
1
|
|
|
|
|
|
PTABLE_iter_free(iter); |
|
309
|
1
|
|
|
|
|
|
PTABLE_free(tbl); |