1 #ifndef SRL_ENC_H_ 2 #define SRL_ENC_H_ 3 4 #include "EXTERN.h" 5 #include "perl.h" 6 7 /* General 'config' constants */ 8 #ifdef MEMDEBUG 9 # define INITIALIZATION_SIZE 1 10 #else 11 # define INITIALIZATION_SIZE 64 12 #endif 13 14 #include "srl_inline.h" 15 #include "srl_buffer_types.h" 16 17 typedef struct PTABLE * ptable_ptr; 18 typedef struct { 19 srl_buffer_t buf; 20 srl_buffer_t tmp_buf; /* temporary buffer for swapping */ 21 22 U32 operational_flags; /* flags that pertain to one encode run (rather than being options): See SRL_OF_* defines */ 23 U32 flags; /* flag-like options: See SRL_F_* defines */ 24 U32 protocol_version; /* The version of the Sereal protocol to emit. */ 25 UV max_recursion_depth; /* Configurable limit on the number of recursive calls we're willing to make */ 26 27 UV recursion_depth; /* current Perl-ref recursion depth */ 28 ptable_ptr ref_seenhash; /* ptr table for avoiding circular refs */ 29 ptable_ptr weak_seenhash; /* ptr table for avoiding dangling weakrefs */ 30 ptable_ptr str_seenhash; /* ptr table for issuing COPY commands based on PTRS (used for classnames and keys) 31 * for now this is also coopted to track which objects we have dumped as objects, 32 * and to ensure we only output a given object once. 33 * Possibly this should be replaced with freezeobj_svhash, but this works fine. 34 */ 35 ptable_ptr freezeobj_svhash; /* ptr table for tracking objects and their frozen replacments via FREEZE */ 36 HV *string_deduper_hv; /* track strings we have seen before, by content */ 37 38 void *snappy_workmem; /* lazily allocated if and only if using Snappy */ 39 IV compress_threshold; /* do not compress things smaller than this even if compression enabled */ 40 IV compress_level; /* For ZLIB and ZSTD, the compression level */ 41 42 /* only used if SRL_F_ENABLE_FREEZE_SUPPORT is set. */ 43 SV *sereal_string_sv; /* SV that says "Sereal" for FREEZE support */ 44 SV *scratch_sv; /* SV used by encoder for scratch operations */ 45 } srl_encoder_t; 46 47 typedef struct { 48 SV *sv; 49 U32 hash; 50 } sv_with_hash; 51 52 typedef struct { 53 union { 54 SV *sv; 55 } key; 56 union { 57 HE *he; 58 SV *sv; 59 } val; 60 } HE_SV; 61 62 /* constructor from options */ 63 srl_encoder_t *srl_build_encoder_struct(pTHX_ HV *opt, sv_with_hash *options); 64 65 /* clone; "constructor from prototype" */ 66 srl_encoder_t *srl_build_encoder_struct_alike(pTHX_ srl_encoder_t *proto); 67 68 void srl_clear_encoder(pTHX_ srl_encoder_t *enc); 69 70 /* Explicit destructor */ 71 void srl_destroy_encoder(pTHX_ srl_encoder_t *enc); 72 73 /* Write Sereal packet header to output buffer */ 74 void srl_write_header(pTHX_ srl_encoder_t *enc, SV *user_header_src, const U32 compress_flags); 75 /* Start dumping a top-level SV */ 76 SV *srl_dump_data_structure_mortal_sv(pTHX_ srl_encoder_t *enc, SV *src, SV *user_header_src, const U32 flags); 77 78 79 /* define option bits in srl_encoder_t's flags member */ 80 81 /* Will default to "on". If set, hash keys will be shared using COPY. 82 * Corresponds to the inverse of constructor option "no_shared_hashkeys" */ 83 #define SRL_F_SHARED_HASHKEYS 0x00001UL 84 /* If set, then we're using the OO interface and we shouldn't destroy the 85 * encoder struct during SAVEDESTRUCTOR_X time */ 86 #define SRL_F_REUSE_ENCODER 0x00002UL 87 /* If set in flags, then we rather croak than serialize an object. 88 * Corresponds to the 'croak_on_bless' option to the Perl constructor. */ 89 #define SRL_F_CROAK_ON_BLESS 0x00004UL 90 /* If set in flags, then we will emit <undef> for all data types 91 * that aren't supported. Corresponds to the 'undef_unknown' option. */ 92 #define SRL_F_UNDEF_UNKNOWN 0x00008UL 93 /* If set in flags, then we will stringify (SvPV) all data types 94 * that aren't supported. Corresponds to the 'stringify_unknown' option. */ 95 #define SRL_F_STRINGIFY_UNKNOWN 0x00010UL 96 /* If set in flags, then we warn() when trying to serialize an unsupported 97 * data structure. Applies only if stringify_unknown or undef_unknown are 98 * set since we otherwise croak. Corresponds to the 'warn_unknown' option. */ 99 #define SRL_F_WARN_UNKNOWN 0x00020UL 100 101 /* WARNING: 102 * #define SRL_F_COMPRESS_SNAPPY 0x00040UL 103 * #define SRL_F_COMPRESS_SNAPPY_INCREMENTAL 0x00080UL 104 * #define SRL_F_COMPRESS_ZLIB 0x00100UL 105 * are moved to srl_compress.h 106 * note that there is SRL_F_COMPRESS_ZSTD defined below 107 */ 108 109 /* Only meaningful if SRL_F_WARN_UNKNOWN also set. If this one is set, then we don't warn 110 * if the unsupported item has string overloading. */ 111 #define SRL_F_NOWARN_UNKNOWN_OVERLOAD 0x00200UL 112 113 /* Only meaningful if SRL_F_WARN_UNKNOWN also set. If this one is set, then we don't warn 114 * if the unsupported item has string overloading. */ 115 #define SRL_F_SORT_KEYS 0x00400UL 116 117 /* If set, use a hash to emit COPY() tags for all duplicated strings 118 * (slow, but great compression) */ 119 #define SRL_F_DEDUPE_STRINGS 0x00800UL 120 121 /* Like SRL_F_DEDUPE_STRINGS but emits ALIAS() instead of COPY() for 122 * non-class-name, non-hash-key strings that are deduped. If set, 123 * supersedes SRL_F_DEDUPE_STRINGS. */ 124 #define SRL_F_ALIASED_DEDUPE_STRINGS 0x01000UL 125 126 /* If set in flags, then we serialize objects without class information. 127 * Corresponds to the 'no_bless_objects' flag found in the Decoder. */ 128 #define SRL_F_NO_BLESS_OBJECTS 0x02000UL 129 130 /* If set in flags, then support calling FREEZE method on objects. */ 131 #define SRL_F_ENABLE_FREEZE_SUPPORT 0x04000UL 132 133 /* if set in flags, then do not use ARRAYREF or HASHREF ever */ 134 #define SRL_F_CANONICAL_REFS 0x08000UL 135 136 #define SRL_F_SORT_KEYS_PERL 0x10000UL 137 #define SRL_F_SORT_KEYS_PERL_REV 0x20000UL 138 139 /* WARNING: 140 * SRL_F_COMPRESS_ZSTD is defined in srl_compress.h 141 * #define SRL_F_COMPRESS_ZSTD 0x40000UL 142 */ 143 144 /* ==================================================================== 145 * oper flags 146 */ 147 /* Set while the encoder is in active use / dirty */ 148 #define SRL_OF_ENCODER_DIRTY 1UL 149 150 #define SRL_ENC_HAVE_OPTION(enc, flag_num) ((enc)->flags & (flag_num)) 151 #define SRL_ENC_SET_OPTION(enc, flag_num) STMT_START {(enc)->flags |= (flag_num);}STMT_END 152 #define SRL_ENC_RESET_OPTION(enc, flag_num) STMT_START {(enc)->flags &= ~(flag_num);}STMT_END 153 154 #define SRL_ENC_HAVE_OPER_FLAG(enc, flag_num) ((enc)->operational_flags & (flag_num)) 155 #define SRL_ENC_SET_OPER_FLAG(enc, flag_num) STMT_START {(enc)->operational_flags |= (flag_num);}STMT_END 156 #define SRL_ENC_RESET_OPER_FLAG(enc, flag_num) STMT_START {(enc)->operational_flags &= ~(flag_num);}STMT_END 157 158 #define SRL_ENC_SV_COPY_ALWAYS 0x00000000UL 159 #define SRL_ENC_SV_REUSE_MAYBE 0x00000001UL 160 161 #define SRL_UNSUPPORTED_SvTYPE(svt) ( \ 162 /* svt == SVt_INVLIST || */ \ 163 svt == SVt_PVGV || \ 164 svt == SVt_PVCV || \ 165 svt == SVt_PVFM || \ 166 svt == SVt_PVIO || \ 167 0 ) 168 169 /* by default we do not allow people to build with support for SRL_HDR_LONG_DOUBLE */ 170 #if defined(SRL_ALLOW_LONG_DOUBLE) && defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) 171 #define SRL_DO_LONG_DOUBLE 1 172 #else 173 #define SRL_DO_LONG_DOUBLE 0 174 #endif 175 176 /* Options Parsing related code */ 177 #define SRL_INIT_OPTION(idx, str) STMT_START { \ 178 MY_CXT.options[idx].sv = newSVpvn((str ""), (sizeof(str) - 1)); \ 179 PERL_HASH(MY_CXT.options[idx].hash, (str ""), (sizeof(str) - 1)); \ 180 } STMT_END 181 182 #define SRL_ENC_OPT_STR_ALIASED_DEDUPE_STRINGS "aliased_dedupe_strings" 183 #define SRL_ENC_OPT_IDX_ALIASED_DEDUPE_STRINGS 0 184 185 #define SRL_ENC_OPT_STR_CANONICAL "canonical" 186 #define SRL_ENC_OPT_IDX_CANONICAL 1 187 188 #define SRL_ENC_OPT_STR_CANONICAL_REFS "canonical_refs" 189 #define SRL_ENC_OPT_IDX_CANONICAL_REFS 2 190 191 #define SRL_ENC_OPT_STR_COMPRESS "compress" 192 #define SRL_ENC_OPT_IDX_COMPRESS 3 193 194 #define SRL_ENC_OPT_STR_COMPRESS_LEVEL "compress_level" 195 #define SRL_ENC_OPT_IDX_COMPRESS_LEVEL 4 196 197 #define SRL_ENC_OPT_STR_COMPRESS_THRESHOLD "compress_threshold" 198 #define SRL_ENC_OPT_IDX_COMPRESS_THRESHOLD 5 199 200 #define SRL_ENC_OPT_STR_CROAK_ON_BLESS "croak_on_bless" 201 #define SRL_ENC_OPT_IDX_CROAK_ON_BLESS 6 202 203 #define SRL_ENC_OPT_STR_DEDUPE_STRINGS "dedupe_strings" 204 #define SRL_ENC_OPT_IDX_DEDUPE_STRINGS 7 205 206 #define SRL_ENC_OPT_STR_FREEZE_CALLBACKS "freeze_callbacks" 207 #define SRL_ENC_OPT_IDX_FREEZE_CALLBACKS 8 208 209 #define SRL_ENC_OPT_STR_MAX_RECURSION_DEPTH "max_recursion_depth" 210 #define SRL_ENC_OPT_IDX_MAX_RECURSION_DEPTH 9 211 212 #define SRL_ENC_OPT_STR_NO_BLESS_OBJECTS "no_bless_objects" 213 #define SRL_ENC_OPT_IDX_NO_BLESS_OBJECTS 10 214 215 #define SRL_ENC_OPT_STR_NO_SHARED_HASHKEYS "no_shared_hashkeys" 216 #define SRL_ENC_OPT_IDX_NO_SHARED_HASHKEYS 11 217 218 #define SRL_ENC_OPT_STR_PROTOCOL_VERSION "protocol_version" 219 #define SRL_ENC_OPT_IDX_PROTOCOL_VERSION 12 220 221 #define SRL_ENC_OPT_STR_SNAPPY "snappy" 222 #define SRL_ENC_OPT_IDX_SNAPPY 13 223 224 #define SRL_ENC_OPT_STR_SNAPPY_INCR "snappy_incr" 225 #define SRL_ENC_OPT_IDX_SNAPPY_INCR 14 226 227 #define SRL_ENC_OPT_STR_SNAPPY_THRESHOLD "snappy_threshold" 228 #define SRL_ENC_OPT_IDX_SNAPPY_THRESHOLD 15 229 230 #define SRL_ENC_OPT_STR_SORT_KEYS "sort_keys" 231 #define SRL_ENC_OPT_IDX_SORT_KEYS 16 232 233 #define SRL_ENC_OPT_STR_STRINGIFY_UNKNOWN "stringify_unknown" 234 #define SRL_ENC_OPT_IDX_STRINGIFY_UNKNOWN 17 235 236 #define SRL_ENC_OPT_STR_UNDEF_UNKNOWN "undef_unknown" 237 #define SRL_ENC_OPT_IDX_UNDEF_UNKNOWN 18 238 239 #define SRL_ENC_OPT_STR_USE_PROTOCOL_V1 "use_protocol_v1" 240 #define SRL_ENC_OPT_IDX_USE_PROTOCOL_V1 19 241 242 #define SRL_ENC_OPT_STR_WARN_UNKNOWN "warn_unknown" 243 #define SRL_ENC_OPT_IDX_WARN_UNKNOWN 20 244 245 #define SRL_ENC_OPT_COUNT 21 246 247 #endif 248