/* zx.h - Common definitions for zx generated code (encoders, decoders, etc.) * Copyright (c) 2006-2007 Symlabs (symlabs@symlabs.com), All Rights Reserved. * Author: Sampo Kellomaki (sampo@iki.fi) * This is confidential unpublished proprietary source code of the author. * NO WARRANTY, not even implied warranties. Contains trade secrets. * Distribution prohibited unless authorized in writing. * Licensed under Apache License 2.0, see file COPYING. * $Id: zx.h,v 1.32 2007-10-11 04:54:25 sampo Exp $ * * 28.5.2006, created --Sampo * 7.8.2006, renamed from dec.h to zx.h and added comments --Sampo * 26.8.2006, some refactoring for CSE --Sampo * 23.9.2006, mild re-engineering for WO support --Sampo * * This file is included from various generated grammar files. */ #ifndef _zx_h #define _zx_h #include #include #include #ifdef USE_OPENSSL #include #else #define RSA void* #endif #define ZXERR_EOF 0x0001 /* return due to EOF condition */ #define ZXERR_MISMATCH_CLOSE 0x0002 /* mismatching close tag */ #define ZXERR_BAD_ATTR_NS 0x0004 /* namespace violation in attribute */ #define ZXERR_BAD_ELEM_NS 0x0008 /* namespace violation in element */ #define ZXERR_MISSING_ATTR 0x0010 /* mandatory attribute(s) missing */ #define ZXERR_EXTRA_ATTR 0x0020 /* unforeseen attribute(s) present */ #define ZXERR_MISSING_ELEM 0x0040 /* mandatory element(s) missing or of wrong cardinality */ #define ZXERR_EXTRA_ELEM 0x0080 /* unforeseen element(s) present */ #define ZXERR_ELEM_ORDER 0x0100 /* ordering of elements violates schema */ #define ZXERR_BAD_NS_PREFIX 0x0200 /* unknown namespace prefix has appeared */ #define ZXERR_TAG_NOT_CLOSED 0x0400 /* open tag seen, but eof seen before close */ #define ZXERR_MASK 0x7fff #define ZXERR_ATTR_FLAG 0x8000 /* Not an error. Marker to distinguish elements from attributes. */ struct zx_any_elem_s; struct zx_any_attr_s; /* Namespace management. The context references this table. The array is * terminated by an element with empty URL (url_len == 0). The elements * of the array are the official namespace prefixes derived from * target() directives in the .sg files. The linked list hanging from * n field contains a stack of runtime assigned namespace prefixes. * The empty marker element serves as a root for list holding namespace * prefixes of namespaces not understood by the system. */ struct zx_ns_s { struct zx_ns_s* n; /* For holding runtime equivalences as a linked list. */ struct zx_ns_s* m; /* For an equivalence, pointer to the master entry. */ struct zx_ns_s* seen; /* Pointer to other "seen" namespaces with same prefix (stack) */ struct zx_ns_s* seen_n; /* Next prefix in seen structure (list) */ struct zx_ns_s* seen_p; /* Next prefix in seen structure (list) */ struct zx_ns_s* seen_pop; /* Pop list for seen stack (used in end of element). */ struct zx_ns_s* inc_n; /* Next link for InclusiveNamespaces */ #if 0 char flags; /* 0x01 == unknown */ char pad1; char pad2; char pad3; #endif int prefix_len; char* prefix; int url_len; /* 0 = end of nstab */ char* url; }; /* Context tracks the input and namespaces. It is also passed to memory allocator. */ struct zx_ctx { char* base; char* p; /* Current scan pointer */ char* lim; struct zx_ns_s* ns_tab; /* Array, such as zx_ns_tab, see zx_prepare_dec_ctx() */ struct zx_ns_s* unknown_ns; /* Linked list of unknown namespaces. */ /* Namespace prefixes that have been "seen", each prefix is a stack. * We keep these prefixes in a doubly linked list so we can add and * remove in the middle. */ struct zx_ns_s guard_seen_n; struct zx_ns_s guard_seen_p; void* exclude_sig; /* If nonnull, causes specified signature to be * excluded. This is needed to avoid the signature * under verification in the canonicalization. * See zxsig.c:zxsig_validate(). */ struct zx_ns_s* inc_ns_len; /* Derived from InclusiveNamespaces/@PrefixList,length computation phase, */ struct zx_ns_s* inc_ns; /* Encoding phase. See zxsig_validate(). */ }; /* We arrange all structs to start with a common header. */ struct zx_node_s { struct zx_node_s* n; /* next pointer for compile time construction of data structures */ struct zx_node_s* wo; /* next pointer for canonicalization order (wire order) */ struct zx_ns_s* ns; /* namespace of an element or attribute */ short tok; /* token number of the tag represented by this struct */ short err; /* error mask */ }; #define ZX_NEXT(x) ((void*)((struct zx_node_s*)(x))->n) /* Simple elements, base type for complex elements. */ struct zx_elem_s { struct zx_node_s g; /* Common fields for all nodes */ struct zx_elem_s* kids; /* root of wo list representing child elements */ struct zx_any_attr_s* any_attr; /* list of attributes not understood by parser */ struct zx_any_elem_s* any_elem; /* list of elements not understood by parser */ struct zx_str* xmlns; /* xmlns attributes, if any */ struct zx_str* content; /* non-element content, if any */ }; struct zx_elem_s* zx_new_simple_elem(struct zx_ctx* c, struct zx_str* ss); struct zx_elem_s* zx_ref_len_simple_elem(struct zx_ctx* c, int len, char* s); struct zx_elem_s* zx_ref_simple_elem(struct zx_ctx* c, char* s); struct zx_elem_s* zx_dup_len_simple_elem(struct zx_ctx* c, int len, char* s); struct zx_elem_s* zx_dup_simple_elem(struct zx_ctx* c, char* s); /* All attributes are represented as a string, as follows. */ struct zx_str { struct zx_node_s g; int len; char* s; }; struct zx_str* zx_ref_str(struct zx_ctx* c, char* s); /* ref points to underlying data */ struct zx_str* zx_ref_len_str(struct zx_ctx* c, int len, char* s); struct zx_str* zx_new_len_str(struct zx_ctx* c, int len); struct zx_str* zx_dup_str(struct zx_ctx* c, char* s); /* data is new memory */ struct zx_str* zx_dup_len_str(struct zx_ctx* c, int len, char* s); struct zx_str* zx_strf(struct zx_ctx* c, char* f, ...); /* data is new memory */ void zx_str_free(struct zx_ctx* c, struct zx_str* ss); /* free both ss->s and ss */ char* zx_str_to_c(struct zx_ctx* c, struct zx_str* ss); void zx_str_conv(struct zx_str* ss, int* out_len, char** out_s); /* SWIG typemap friendly */ int zx_str_ends_in(struct zx_str* ss, int len, char* suffix); #define ZX_STR_ENDS_IN_CONST(ss, suffix) zx_str_ends_in((ss), sizeof(suffix)-1, (suffix)) /* Elements that are unforeseen (errornous or extensions). */ struct zx_any_elem_s { struct zx_elem_s gg; int name_len; char* name; }; #define ZX_ANY_EL(x) ((struct zx_any_elem_s*)(x)) /* Attributes that are unforeseen (errornous or extensions). */ struct zx_any_attr_s { struct zx_str ss; int name_len; char* name; }; #define ZX_ANY_AT(x) ((struct zx_any_attr_s*)(x)) #define ZX_ELEM_EXT struct zx_elem_s gg; char* zx_memmem(char* haystack, int haystack_len, char* needle, int needle_len); void* zx_alloc(struct zx_ctx* c, int size); void* zx_zalloc(struct zx_ctx* c, int size); void* zx_free(struct zx_ctx* c, void* p); char* zx_dup_cstr(struct zx_ctx* c, char* str); #define ZX_ALLOC(c, size) zx_alloc((c), (size)) #define ZX_ZALLOC(c, typ) ((typ*)zx_zalloc((c), sizeof(typ))) #define ZX_DUPALLOC(c, typ, n, o) (n) = (typ*)zx_alloc((c), sizeof(typ)); memcpy((n), (o), sizeof(typ)) #define ZX_FREE(c, p) zx_free((c), (p)) /* N.B. All string scanning assumes buffer is terminated with C string style nul byte. */ #define ZX_SKIP_WS_P(c,p,x) MB for (; ONE_OF_4(*(p), ' ', '\n', '\r', '\t'); ++(p)) ; if (!*(p)) return x; ME #define ZX_SKIP_WS(c,x) ZX_SKIP_WS_P((c),(c)->p,x) #define ZX_LOOK_FOR_P(c,ch,p) MB char* pp = memchr((p), (ch), (c)->lim - (p)); if (!pp) goto look_for_not_found; else (p) = pp; ME #define ZX_LOOK_FOR(c,ch) ZX_LOOK_FOR_P((c),(ch),(c)->p) #define ZX_OUT_CH(p, ch) (*((p)++) = (ch)) #define ZX_OUT_MEM(p, mem, len) MB memcpy((p), (mem), (len)); (p) += (len); ME #define ZX_OUT_STR(p, str) ZX_OUT_MEM(p, ((struct zx_str*)(x))->s, ((struct zx_str*)(x))->len) #define ZX_OUT_TAG(p, tag) ZX_OUT_MEM(p, tag, sizeof(tag)-1) #define ZX_OUT_SIMPLE_TAG(p, tag, len) MB ZX_OUT_CH(p, '<'); ZX_OUT_MEM(p, tag, len); ME #define ZX_OUT_CLOSE_TAG(p, tag) ZX_OUT_MEM(p, tag, sizeof(tag)-1) #define ZX_OUT_SIMPLE_CLOSE_TAG(p, tag, len) MB ZX_OUT_CH(p, '<'); ZX_OUT_CH(p, '/'); ZX_OUT_MEM(p, tag, len); ZX_OUT_CH(p, '>'); ME /* Special token values. */ #define ZX_TOK_XMLNS (-4) #define ZX_TOK_DATA (-3) #define ZX_TOK_NOT_FOUND (-2) struct zx_tok { const char* name; const char* prefix; struct zx_ns_s* ns; }; /*struct zx_note_s* zx_clone_any(struct zx_ctx* c, struct zx_note_s* n, int dup_strs); TBD */ /*void zx_free_any(struct zx_ctx* c, struct zx_note_s* n, int free_strs); TBD */ int zx_date_time_to_secs(char* dt); int write2_or_append_lock_c_path(char* c_path, int len1, char* data1, int len2, char* data2, const char* which, int seeky, int flag); int zx_report_openssl_error(const char* logkey); void zx_fix_any_elem_dec(struct zx_ctx* c, struct zx_any_elem_s* x, char* nam, int namlen); struct zx_ns_s* zx_locate_ns_by_prefix(struct zx_ctx* c, int len, char* prefix); int zx_is_ns_prefix(struct zx_ns_s* ns, int len, char* prefix); struct zx_ns_s* zx_prefix_seen(struct zx_ctx* c, int len, char* prefix); struct zx_ns_s* zx_prefix_seen_whine(struct zx_ctx* c, int len, char* prefix, char* logkey, int mk_dummy_ns); struct zx_ns_s* zx_scan_xmlns(struct zx_ctx* c); void zx_pop_seen(struct zx_ns_s* ns); /* zxcrypto.c - Glue to OpenSSL low level */ struct zx_str* zx_raw_cipher(struct zx_ctx* c, char* algo, int encp, struct zx_str* key, int len, char* s, int iv_len, char* iv); struct zx_str* zx_rsa_pub_enc(struct zx_ctx* c, struct zx_str* plain, RSA* rsa_pkey, int pad); struct zx_str* zx_rsa_pub_dec(struct zx_ctx* c, struct zx_str* ciphered, RSA* rsa_pkey, int pad); struct zx_str* zx_rsa_priv_dec(struct zx_ctx* c, struct zx_str* ciphered, RSA* rsa_pkey, int pad); struct zx_str* zx_rsa_priv_enc(struct zx_ctx* c, struct zx_str* plain, RSA* rsa_pkey, int pad); /* Common Subexpression Elimination (CSE) for generated code. */ const struct zx_tok* zx_tok_by_ns(const struct zx_tok* zt, const struct zx_tok* lim, int len, char* name, struct zx_ns_s* ns); int zx_len_xmlns_if_not_seen(struct zx_ctx* c, struct zx_ns_s* ns, struct zx_ns_s** pop_seen); char* zx_enc_xmlns_if_not_seen(struct zx_ctx* c, char* p, struct zx_ns_s* ns, struct zx_ns_s** pop_seen); void zx_add_xmlns_if_not_seen(struct zx_ctx* c, struct zx_ns_s* ns, struct zx_ns_s** pop_seen); char* zx_enc_seen(char* p, struct zx_ns_s* ns); int zx_len_so_common(struct zx_ctx* c, struct zx_elem_s* x); int zx_len_wo_common(struct zx_ctx* c, struct zx_elem_s* x); char* zx_enc_unknown_attrs(char* p, struct zx_any_attr_s* aa); char* zx_enc_so_unknown_elems_and_content(struct zx_ctx* c, char* p, struct zx_elem_s* x); struct zx_str* zx_easy_enc_common(struct zx_ctx* c, char* p, char* buf, int len); int zx_attr_so_len(struct zx_str* attr, int name_size); char* zx_attr_so_enc(char* p, struct zx_str* attr, char* name, int name_len); int zx_attr_wo_len(struct zx_str* attr, int name_size); char* zx_attr_wo_enc(char* p, struct zx_str* attr, char* name, int name_len); void zx_dup_attr(struct zx_ctx* c, struct zx_str* attr); void zx_free_attr(struct zx_ctx* c, struct zx_str* attr, int free_strs); struct zx_str* zx_clone_attr(struct zx_ctx* c, struct zx_str* attr); void zx_free_elem_common(struct zx_ctx* c, struct zx_elem_s* x, int free_strs); struct zx_elem_s* zx_clone_elem_common(struct zx_ctx* c, struct zx_elem_s* x, int size, int dup_strs); void zx_dup_strs_common(struct zx_ctx* c, struct zx_elem_s* x); int zx_walk_so_unknown_attributes(struct zx_ctx* c, struct zx_elem_s* x, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx)); int zx_walk_so_unknown_elems_and_content(struct zx_ctx* c, struct zx_elem_s* x, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx)); struct zx_elem_s* zx_deep_clone_simple_elems(struct zx_ctx* c, struct zx_elem_s* x, int dup_strs); int zx_walk_so_simple_elems(struct zx_ctx* c, struct zx_elem_s* se, void* ctx, int (*callback)(struct zx_node_s* node, void* ctx)); void zx_free_simple_elems(struct zx_ctx* c, struct zx_elem_s* se, int free_strs); void zx_dup_strs_simple_elems(struct zx_ctx* c, struct zx_elem_s* se); void zx_prepare_dec_ctx(struct zx_ctx* c, struct zx_ns_s* ns_tab, char* start, char* lim); int zx_scan_data(struct zx_ctx* c, struct zx_elem_s* el); int zx_scan_pi_or_comment(struct zx_ctx* c); struct zx_str* zx_dec_unknown_attr(struct zx_ctx* c, struct zx_elem_s* el, char* name, char* data, int tok, int ctx_tok); char* zx_dec_attr_val(struct zx_ctx* c, char** name); void zx_xml_parse_err(struct zx_ctx* c, char quote, const char* func, const char* msg); int zx_len_inc_ns(struct zx_ctx* c, struct zx_ns_s** pop_seenp); void zx_add_inc_ns(struct zx_ctx* c, struct zx_ns_s** pop_seenp); char* zx_enc_inc_ns(struct zx_ctx* c, char* p, struct zx_ns_s** pop_seenp); #if 0 #define ZX_DEC_TAG_NOT_YET_CLOSED(x) (x).err |= ZXERR_TAG_NOT_CLOSED #define ZX_DEC_TAG_NOW_CLOSED(x) (x).err &= ~ZXERR_TAG_NOT_CLOSED #define ZX_DEC_TAG_MISMATCH_CLOSE(x) (x).err |= ZXERR_MISMATCH_CLOSE #else #define ZX_DEC_TAG_NOT_YET_CLOSED(x) #define ZX_DEC_TAG_NOW_CLOSED(x) #define ZX_DEC_TAG_MISMATCH_CLOSE(x) #endif #endif