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); |