Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 337 lines (284 sloc) 8.471 kb
36b5369 @mnunberg initial commit
authored
1 #ifndef PERL_JSONSL_H_
2 #define PERL_JSONSL_H_
3 #define PERL_NO_GET_CONTEXT
4
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8 #include "ppport.h"
ee3f8a2 @mnunberg Added some tuba tests.
authored
9 #include <limits.h>
36b5369 @mnunberg initial commit
authored
10 /**
11 * Default depth limit to use, if none supplied
12 */
13 #define PLJSONSL_MAX_DEFAULT 512
14
15 /**
16 * Key names for the information returned by
17 * JSONpointer results
18 */
19 #define PLJSONSL_INFO_KEY_PATH "Path"
20 #define PLJSONSL_INFO_KEY_VALUE "Value"
21 #define PLJSONSL_INFO_KEY_QUERY "JSONPointer"
22
23 /**
24 * Names of various perl globs
25 */
26 #define PLJSONSL_CLASS_NAME "JSON::SL"
27 #define PLJSONSL_BOOLEAN_NAME "JSON::SL::Boolean"
28 #define PLJSONSL_PLACEHOLDER_NAME "JSON::SL::Placeholder"
29
30 #define PLTUBA_CLASS_NAME "JSON::SL::Tuba"
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
31 #define PLTUBA_HKEY_NAME "_TUBA"
32
36b5369 @mnunberg initial commit
authored
33
288c839 @mnunberg Work on tuba, object_drip
authored
34 #if PERL_VERSION >= 10
35 #define PLJSONSL_HAVE_HV_COMMON
36 #else
37 #warning "You are using a Perl from the stone age. This code might work.."
38 #endif /* 5.10.0 */
39
ee3f8a2 @mnunberg Added some tuba tests.
authored
40
36b5369 @mnunberg initial commit
authored
41 /**
42 * Extended fields for a stack state
43 * sv: the raw SV (never a reference)
44 * u_loc.idx / u_loc.key: the numerical index or the HE key, depending
45 * on parent type.
46 * matchres: the result of the last match
47 * matchjpr: the jsonsl_jpr_t object (assuming a successful match [COMPLETE] )
48 */
49 #define JSONSL_STATE_USER_FIELDS \
50 SV *sv; \
51 union { \
52 int idx; \
53 HE *key; \
54 } u_loc; \
55 int matchres; \
56 int uescapes; \
57 jsonsl_jpr_t matchjpr;
58
59 /**
60 * We take advantage of the JSONSL_API and make all symbols
61 * non-exportable
62 */
63 #define JSONSL_API static
87f4838 @mnunberg submodule test
authored
64 #include "jsonsl/jsonsl.h"
65 #include "jsonsl/jsonsl.c"
36b5369 @mnunberg initial commit
authored
66
67 /**
68 * For threaded perls, this stores the THX/my_perl context
69 * inside the object's pl_thx field. For non threaded perls,
70 * this is a nop.
71 */
72 #ifndef tTHX
73 #define tTHX PerlInterpreter*
74 #endif
75
76 #ifdef PERL_IMPLICIT_CONTEXT
77 #define PLJSONSL_dTHX(pjsn) \
78 pTHX = (tTHX)pjsn->pl_thx
79 #define PLJSONSL_mkTHX(pjsn) \
80 pjsn->pl_thx = my_perl;
81 #else
82 #define PLJSONSL_dTHX(pjsn)
83 #define PLJSONSL_mkTHX(pjsn)
84 #endif /* PERL_IMPLICIT_CONTEXT */
85
288c839 @mnunberg Work on tuba, object_drip
authored
86
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
87 /*
88 * This is the 'abstract base class' for both JSON::SL and JSON::SL::Tuba
89 */
288c839 @mnunberg Work on tuba, object_drip
authored
90 #define PLJSONSL_COMMON_FIELDS \
91 /* The lexer */ \
92 jsonsl_t jsn; \
93 /* Input buffer */ \
94 SV *buf; \
95 /* Start position of the buffer (relative to input stream) */ \
96 size_t pos_min_valid; \
97 /* Position of the beginning of the earlist of (SPECIAL,STRINGY) */ \
98 size_t keep_pos; \
99 /* Context for threaded Perls */ \
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
100 void *pl_thx; \
101 /* Stash for booleans */ \
102 HV *stash_boolean; \
103 /* Escape table */ \
104 int escape_table[0x80];
105
106 /* These are the escapes we care about: */
107 #define PLJSONSL_ESCTBL_INIT(tbl) \
108 memset(ESCTBL, 0, sizeof(ESCTBL)); \
109 tbl['"'] = 1; \
110 tbl['\\'] = 1; \
111 tbl['/'] = 1; \
112 tbl['b'] = 1; \
113 tbl['n'] = 1; \
114 tbl['r'] = 1; \
115 tbl['f'] = 1; \
116 tbl['u'] = 1; \
117 tbl['t'] = 1;
118
288c839 @mnunberg Work on tuba, object_drip
authored
119
36b5369 @mnunberg initial commit
authored
120 typedef struct {
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
121 PLJSONSL_COMMON_FIELDS
36b5369 @mnunberg initial commit
authored
122
123 /* Root perl data structure. This is either an HV* or AV* */
124 SV *root;
125
126 /**
127 * "current" hash key. This is always a pointer to an HE* of an existing
128 * hash entry, and thus should never be freed/destroyed directly.
129 * This variable should only be non-null during until the next PUSH
130 * callback
131 */
132 HE *curhk;
133
288c839 @mnunberg Work on tuba, object_drip
authored
134 #ifndef PLJSONSL_HAVE_HV_COMMON
36b5369 @mnunberg initial commit
authored
135 /**
136 * For older perls not exposing hv_common, we need a key sv.
288c839 @mnunberg Work on tuba, object_drip
authored
137 * make this as efficient as possible. Instead of instantiating a new
138 * SV each time for hv_fetch_ent, we keep one cached, and change its
139 * PV slot as needed. I am able to do this because I have looked at 5.8's
140 * implementation for the hv_* methods in hv.c and unless the hash is magical,
141 * the behavior is to simply extract the PV from the SV in the beginning
142 * anyway.
36b5369 @mnunberg initial commit
authored
143 */
144 SV *ksv;
145 char *ksv_origpv;
288c839 @mnunberg Work on tuba, object_drip
authored
146 #endif
36b5369 @mnunberg initial commit
authored
147
148
149 struct {
150 int utf8; /** Set the SvUTF8 flag */
151 int nopath; /** Don't include path context in results */
152 int noqstr; /** Don't include original query string in results */
288c839 @mnunberg Work on tuba, object_drip
authored
153 int max_size; /** maximum input size (from JSON::XS) */
154 /* ignore the jsonpointer settings and allow an 'iv-drip' of
155 * objects to be returned via feed */
156 int object_drip;
36b5369 @mnunberg initial commit
authored
157 } options;
158
159 /**
160 * Private options
161 */
162 struct {
163 /* whether this is the 'global' JSON::SL object used
164 * for decode_json()
165 */
166 int is_global;
167 } priv_global;
168
169 /**
170 * If we allocate a bunch of JPR objects, keep a reference to
171 * them here in order to destroy them along with ourselves.
172 */
173 jsonsl_jpr_t *jprs;
174 size_t njprs;
175
176 /**
177 * This is the 'result stack'
178 */
179 AV *results;
180
181 /**
182 * Escape preferences
183 */
184 } PLJSONSL;
185
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
186
187 #define PLTUBA_XCALLBACK \
188 JSONSL_XTYPE \
189 X(DATA, 'c') \
190 X(ERROR, '!') \
191 X(JSON, 'D') \
192 X(NUMBER, '=') \
193 X(BOOLEAN, '?') \
194 X(NULL, '~') \
195 X(ANY, '.') \
196
36b5369 @mnunberg initial commit
authored
197 typedef enum {
198 #define X(o,c) \
199 PLTUBA_CALLBACK_##o = c,
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
200 PLTUBA_XCALLBACK
36b5369 @mnunberg initial commit
authored
201 #undef X
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
202 PLTUBA_CALLBACK_blah
36b5369 @mnunberg initial commit
authored
203 } pltuba_callback_type;
204
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
205 #define PLTUBA_ACTION_ON '>'
206
207
208 #define PLTUBA_DEFINE_XMETHGV
87f4838 @mnunberg submodule test
authored
209 #include "srcout/tuba_dispatch_getmeth.h"
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
210 #undef PLTUBA_DEFINE_XMETHGV
211
212 /* These are stringified as the 'Info' keys */
213 #define PLTUBA_XPARAMS \
214 X(Escaped) \
215 X(Key) \
216 X(Type) \
217 X(Mode) \
218 X(Value) \
219 X(Index)
220
221
36b5369 @mnunberg initial commit
authored
222 /**
223 * This can be considered to be a 'subset' of the
224 * PLJSONSL structure, but with some slight subtleties and
225 * differences.
226 */
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
227
228 struct pltuba_param_entry_st {
229 HE *he;
230 SV *sv;
231 };
232
36b5369 @mnunberg initial commit
authored
233 typedef struct {
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
234 PLJSONSL_COMMON_FIELDS
36b5369 @mnunberg initial commit
authored
235
288c839 @mnunberg Work on tuba, object_drip
authored
236 /* When we invoke a callback, instead of re-creating the
237 * mortalized rv each time, we just keep a static reference
238 * to ourselves
36b5369 @mnunberg initial commit
authored
239 */
288c839 @mnunberg Work on tuba, object_drip
authored
240 SV *selfrv;
36b5369 @mnunberg initial commit
authored
241
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
242 /* This is last known stash for our methods.
243 * In the rare event that someone decides to rebless
244 * us into a different class, we compare and swap out
245 * in favor of the new one (SvSTASH(SvRV(tuba->selfrv)));
246 */
247 HV *last_stash;
248
288c839 @mnunberg Work on tuba, object_drip
authored
249 /* set by hkey and string callbacks */
250 int shift_quote;
36b5369 @mnunberg initial commit
authored
251
252 /* Options */
253 struct {
254 int utf8;
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
255 int no_cache_mro;
256 int accum_kv;
257 int cb_unified;
ee3f8a2 @mnunberg Added some tuba tests.
authored
258 int allow_unhandled;
36b5369 @mnunberg initial commit
authored
259 } options;
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
260
261 #define PLTUBA_METHGV_STRUCT
87f4838 @mnunberg submodule test
authored
262 #include "srcout/tuba_dispatch_getmeth.h"
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
263 #undef PLTUBA_METHGV_STRUCT
264 /* The accumulators */
265 SV *accum;
266 SV *kaccum;
267
268 /**
269 * The following structures contain registers for the
270 * HEs which are hash entries for the info hash, and the
271 * corresponding SVs which they contain.
272 */
273 struct {
274 #define X(vname) \
275 struct pltuba_param_entry_st pe_##vname;
276 PLTUBA_XPARAMS
277 #undef X
278 } p_ents;
279
280 /* Our info hash, and its reference */
281 HV *paramhv;
282 SV *paramhvrv;
283
284 /* Table of various callbacks to invoke */
285 int accum_options[0x100];
286
36b5369 @mnunberg initial commit
authored
287 } PLTUBA;
288
1a2501d @mnunberg Tuba tuba tuba. also fixed compiler warnings and some more docs
authored
289 /**
290 * These macros manipulate the static entries within the hash
291 * which is passed into callbacks.
292 * There are two primary variables to work with:
293 * 1) The actual static SV which contains the value
294 * 2) The HE which points to the SV
295 *
296 * And three operations
297 * 1) Assigning the value to the SV
298 * 2) Tying the HE with the SV, so a lookup on the hash
299 * entry yields the SV
300 * 3) Decoupling the HE and the SV, so the SV remains allocated
301 * but the HE will now point to &PL_sv_placeholder and not yield
302 * a result.
303 */
304 #define PLTUBA_PARAM_FIELD(tuba, b) \
305 (tuba->p_ents.pe_##b)
306
307 /**
308 * Assign an SV to the named field. The HE is made to point to the SV
309 */
310 #define PLTUBA_SET_PARAMFIELDS_sv(tuba, field, sv) \
311 HeVAL(PLTUBA_PARAM_FIELD(tuba,field).he) = sv;
312
313 /**
314 * Convenience macro which assigns the SV to the HE, and then sets
315 * the IVX slot.
316 */
317 #define PLTUBA_SET_PARAMFIELDS_iv(tuba, field, iv) \
318 /* assign the IV */ \
319 assert(PLTUBA_PARAM_FIELD(tuba,field).sv); \
320 assert(SvIOK(PLTUBA_PARAM_FIELD(tuba,field).sv)); \
321 SvIVX(PLTUBA_PARAM_FIELD(tuba, field).sv) = iv; \
322 /* set the he's value to the just-assigned sv */ \
323 PLTUBA_SET_PARAMFIELDS_sv(tuba, field, PLTUBA_PARAM_FIELD(tuba,field).sv)
324
325 #define PLTUBA_SET_PARAMFIELDS_dv(tuba, field, c) \
326 PLTUBA_SET_PARAMFIELDS_iv(tuba, field, c); \
327 *SvPVX(PLTUBA_PARAM_FIELD(tuba,field).sv) = (char)c; \
328
329 /**
330 * Sets the HE to point to &PL_sv_placeholder.
331 */
332 #define PLTUBA_RESET_PARAMFIELD(tuba, field) \
333 HeVAL(PLTUBA_PARAM_FIELD(tuba, field).he) = &PL_sv_placeholder;
334
335
36b5369 @mnunberg initial commit
authored
336 #endif /* PERL_JSONSL_H_ */
Something went wrong with that request. Please try again.