* of the decoder before upgrading to version 3 of the
* encoder!
+3.001_001
+ - Patches from Jarkko Hietaniemi to make Sereal pass test
+ on HP-UX, and other machines with endian or alignedness
+ issues. Thanks to H.Merijn Brand for assisting and providing
+ access to test machines.
+
3.001
- Production release 1 of protocol version 3
- Zlib support
}
}
},
- "release_status" : "stable",
+ "release_status" : "testing",
"resources" : {
"bugtracker" : {
"web" : "https://github.com/Sereal/Sereal/issues"
"url" : "git://github.com/Sereal/Sereal.git"
}
},
- "version" : "3.001"
+ "version" : "3.001_002"
}
resources:
bugtracker: https://github.com/Sereal/Sereal/issues
repository: git://github.com/Sereal/Sereal.git
-version: 3.001
+version: 3.001_002
$defines .= " -DNDEBUG";
}
+# TODO: This is identical with Decoder.
+if ($Config{osname} eq 'hpux' && not $Config{gccversion}) {
+ # HP-UX cc does not support inline.
+ # Or rather, it does, but it depends on the compiler flags,
+ # assumedly -AC99 instead of -Ae would work.
+ # But we cannot change the compiler config too much from
+ # the one that was used to compile Perl,
+ # so we just fake the inline away.
+ $defines .= " -Dinline= ";
+}
+
# from Compress::Snappy
require Devel::CheckLib;
my $ctz = Devel::CheckLib::check_lib(
return PERL_constant_NOTFOUND;
}
+static int
+constant_24 (pTHX_ const char *name, IV *iv_return) {
+ /* When generated this function returned values for the list of names given
+ here. However, subsequent manual editing may have added or removed some.
+ SRL_HDR_SHORT_BINARY_LOW SRL_MAGIC_STRING_UINT_BE SRL_MAGIC_STRING_UINT_LE
+ */
+ /* Offset 22 gives the best switch position. */
+ switch (name[22]) {
+ case 'B':
+ if (memEQ(name, "SRL_MAGIC_STRING_UINT_BE", 24)) {
+ /* ^ */
+#ifdef SRL_MAGIC_STRING_UINT_BE
+ *iv_return = SRL_MAGIC_STRING_UINT_BE;
+ return PERL_constant_ISIV;
+#else
+ return PERL_constant_NOTDEF;
+#endif
+ }
+ break;
+ case 'L':
+ if (memEQ(name, "SRL_MAGIC_STRING_UINT_LE", 24)) {
+ /* ^ */
+#ifdef SRL_MAGIC_STRING_UINT_LE
+ *iv_return = SRL_MAGIC_STRING_UINT_LE;
+ return PERL_constant_ISIV;
+#else
+ return PERL_constant_NOTDEF;
+#endif
+ }
+ break;
+ case 'O':
+ if (memEQ(name, "SRL_HDR_SHORT_BINARY_LOW", 24)) {
+ /* ^ */
+#ifdef SRL_HDR_SHORT_BINARY_LOW
+ *iv_return = SRL_HDR_SHORT_BINARY_LOW;
+ return PERL_constant_ISIV;
+#else
+ return PERL_constant_NOTDEF;
+#endif
+ }
+ break;
+ }
+ return PERL_constant_NOTFOUND;
+}
+
static int
constant_25 (pTHX_ const char *name, IV *iv_return) {
/* When generated this function returned values for the list of names given
SRL_HDR_SHORT_BINARY SRL_HDR_SHORT_BINARY_HIGH
SRL_HDR_SHORT_BINARY_LOW SRL_HDR_STR_UTF8 SRL_HDR_TRACK_FLAG
SRL_HDR_TRUE SRL_HDR_UNDEF SRL_HDR_VARINT SRL_HDR_WEAKEN
- SRL_HDR_ZIGZAG SRL_MAGIC_STRING_HIGHBIT_UINT_LE
- SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE SRL_MAGIC_STRING_UINT_LE
- SRL_MAGIC_STRLEN SRL_MASK_ARRAYREF_COUNT SRL_MASK_HASHREF_COUNT
+ SRL_HDR_ZIGZAG SRL_MAGIC_STRING_HIGHBIT_UINT_BE
+ SRL_MAGIC_STRING_HIGHBIT_UINT_LE
+ SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE
+ SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE SRL_MAGIC_STRING_UINT_BE
+ SRL_MAGIC_STRING_UINT_LE SRL_MAGIC_STRLEN
+ SRL_MASK_ARRAYREF_COUNT SRL_MASK_HASHREF_COUNT
SRL_MASK_SHORT_BINARY_LEN SRL_NEG_MIN_SIZE SRL_POS_MAX_SIZE
SRL_PROTOCOL_ENCODING_MASK SRL_PROTOCOL_ENCODING_RAW
SRL_PROTOCOL_ENCODING_SNAPPY
}
break;
case 24:
- /* Names all of length 24. */
- /* SRL_HDR_SHORT_BINARY_LOW SRL_MAGIC_STRING_UINT_LE */
- /* Offset 11 gives the best switch position. */
- switch (name[11]) {
- case 'R':
- if (memEQ(name, "SRL_HDR_SHORT_BINARY_LOW", 24)) {
- /* ^ */
-#ifdef SRL_HDR_SHORT_BINARY_LOW
- *iv_return = SRL_HDR_SHORT_BINARY_LOW;
- return PERL_constant_ISIV;
-#else
- return PERL_constant_NOTDEF;
-#endif
- }
- break;
- case 'T':
- if (memEQ(name, "SRL_MAGIC_STRING_UINT_LE", 24)) {
- /* ^ */
-#ifdef SRL_MAGIC_STRING_UINT_LE
- *iv_return = SRL_MAGIC_STRING_UINT_LE;
- return PERL_constant_ISIV;
-#else
- return PERL_constant_NOTDEF;
-#endif
- }
- break;
- }
+ return constant_24 (aTHX_ name, iv_return);
break;
case 25:
return constant_25 (aTHX_ name, iv_return);
}
break;
case 32:
- if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UINT_LE", 32)) {
+ /* Names all of length 32. */
+ /* SRL_MAGIC_STRING_HIGHBIT_UINT_BE SRL_MAGIC_STRING_HIGHBIT_UINT_LE */
+ /* Offset 30 gives the best switch position. */
+ switch (name[30]) {
+ case 'B':
+ if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UINT_BE", 32)) {
+ /* ^ */
+#ifdef SRL_MAGIC_STRING_HIGHBIT_UINT_BE
+ *iv_return = SRL_MAGIC_STRING_HIGHBIT_UINT_BE;
+ return PERL_constant_ISIV;
+#else
+ return PERL_constant_NOTDEF;
+#endif
+ }
+ break;
+ case 'L':
+ if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UINT_LE", 32)) {
+ /* ^ */
#ifdef SRL_MAGIC_STRING_HIGHBIT_UINT_LE
- *iv_return = SRL_MAGIC_STRING_HIGHBIT_UINT_LE;
- return PERL_constant_ISIV;
+ *iv_return = SRL_MAGIC_STRING_HIGHBIT_UINT_LE;
+ return PERL_constant_ISIV;
#else
- return PERL_constant_NOTDEF;
+ return PERL_constant_NOTDEF;
#endif
+ }
+ break;
}
break;
case 37:
- if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE", 37)) {
+ /* Names all of length 37. */
+ /* SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE
+ SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE */
+ /* Offset 35 gives the best switch position. */
+ switch (name[35]) {
+ case 'B':
+ if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE", 37)) {
+ /* ^ */
+#ifdef SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE
+ *iv_return = SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE;
+ return PERL_constant_ISIV;
+#else
+ return PERL_constant_NOTDEF;
+#endif
+ }
+ break;
+ case 'L':
+ if (memEQ(name, "SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE", 37)) {
+ /* ^ */
#ifdef SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE
- *iv_return = SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE;
- return PERL_constant_ISIV;
+ *iv_return = SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE;
+ return PERL_constant_ISIV;
#else
- return PERL_constant_NOTDEF;
+ return PERL_constant_NOTDEF;
#endif
+ }
+ break;
}
break;
case 40:
use Carp qw/croak/;
use XSLoader;
-our $VERSION = '3.001'; # Don't forget to update the TestCompat set for testing against installed decoders!
+our $VERSION = '3.001_002'; # Don't forget to update the TestCompat set for testing against installed decoders!
our $XS_VERSION = $VERSION; $VERSION= eval $VERSION;
# not for public consumption, just for testing.
BEGIN { @EXPORT_OK = qw(
SRL_MAGIC_STRLEN
SRL_MAGIC_STRING_UINT_LE
+ SRL_MAGIC_STRING_UINT_BE
SRL_MAGIC_STRING_HIGHBIT_UINT_LE
+ SRL_MAGIC_STRING_HIGHBIT_UINT_BE
SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE
+ SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE
SRL_PROTOCOL_VERSION
SRL_PROTOCOL_VERSION_BITS
SRL_PROTOCOL_VERSION_MASK
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1\r
#endif\r
\r
-#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)\r
+/* HP-UX runs on Itanium but has strict alignment. */\r
+#ifdef __hpux\r
+#undef MINIZ_USE_UNALIGNED_LOADS_AND_STORES\r
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0\r
+#endif\r
+\r
+#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ILP64__) || defined(__ia64__) || defined(__x86_64__)\r
// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).\r
#define MINIZ_HAS_64BIT_REGISTERS 1\r
#endif\r
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
+#elif defined(__hpux)
+
+#ifdef __LP64__
+#define __LITTLE_ENDIAN 12345678
+#define __BIG_ENDIAN 87654321
+#define int64_t long
+#else
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define int64_t long long
+#endif
+
+#define __BYTE_ORDER __BIG_ENDIAN /* HP-UX always */
+#define int32_t int
+#define int16_t short
+
+#endif
+
+#ifndef bswap_16
+#define bswap_16(x) \
+ (((uint16_t)(x) & 0xFF00) >> 8 | \
+ ((uint16_t)(x) & 0x00FF) << 8)
+#endif
+
+#ifndef bswap_32
+#define bswap_32(x) \
+ (((uint32_t)(x) & 0xFF000000) >> 24 | \
+ ((uint32_t)(x) & 0x00FF0000) >> 8 | \
+ ((uint32_t)(x) & 0x0000FF00) << 8 | \
+ ((uint32_t)(x) & 0x000000FF) << 24)
+#endif
+
+#ifndef bswap_64
+#define bswap_64(x) \
+ (((uint64_t)(x) & 0xFF00000000000000) >> 56 | \
+ ((uint64_t)(x) & 0x00FF000000000000) >> 40 | \
+ ((uint64_t)(x) & 0x0000FF0000000000) >> 24 | \
+ ((uint64_t)(x) & 0x000000FF00000000) >> 8 | \
+ ((uint64_t)(x) & 0x00000000FF000000) << 8 | \
+ ((uint64_t)(x) & 0x0000000000FF0000) << 24 | \
+ ((uint64_t)(x) & 0x000000000000FF00) << 40 | \
+ ((uint64_t)(x) & 0x00000000000000FF) << 56)
#endif
ptr->x = v;
}
+#elif defined(__hpux) /* strict architectures */
+
+/* For these platforms, there really are no unaligned loads/stores.
+ * Read/write everything as uint8_t. Smart compilers might recognize
+ * these patterns and generate something smart. */
+
+/* Possible future enhancement: see if the ptr is evenly divisible
+ * (as uintNN_t) by 2/4/8, and if so, do the cast-as-uintNN_t-ptr-
+ * and-deref-as-uintNN_t. Balancing act: adding the branch
+ * will slow things down, while reading/writing aligned might speed
+ * things up. */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+
+static INLINE uint16_t UNALIGNED_LOAD16(const void *p)
+{
+ return
+ (uint16_t)(((uint8_t*)p)[0]) << 8 |
+ (uint16_t)(((uint8_t*)p)[1]);
+}
+
+static INLINE uint32_t UNALIGNED_LOAD32(const void *p)
+{
+ return
+ (uint32_t)(((uint8_t*)p)[0]) << 24 |
+ (uint32_t)(((uint8_t*)p)[1]) << 16 |
+ (uint32_t)(((uint8_t*)p)[2]) << 8 |
+ (uint32_t)(((uint8_t*)p)[3]);
+}
+
+static INLINE uint64_t UNALIGNED_LOAD64(const void *p)
+{
+ return
+ (uint64_t)((uint8_t*)p)[0] << 56 |
+ (uint64_t)((uint8_t*)p)[1] << 48 |
+ (uint64_t)((uint8_t*)p)[2] << 40 |
+ (uint64_t)((uint8_t*)p)[3] << 32 |
+ (uint64_t)((uint8_t*)p)[4] << 24 |
+ (uint64_t)((uint8_t*)p)[5] << 16 |
+ (uint64_t)((uint8_t*)p)[5] << 8 |
+ (uint64_t)((uint8_t*)p)[7];
+}
+
+static INLINE void UNALIGNED_STORE16(void *p, uint16_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[0] = (v & 0xFF00) >> 8;
+ s[1] = (v & 0x00FF);
+}
+
+static INLINE void UNALIGNED_STORE32(void *p, uint32_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[0] = (v & 0xFF000000) >> 24;
+ s[1] = (v & 0x00FF0000) >> 16;
+ s[2] = (v & 0x0000FF00) >> 8;
+ s[3] = (v & 0x000000FF);
+}
+
+static INLINE void UNALIGNED_STORE64(void *p, uint64_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[0] = (v & 0xFF00000000000000) >> 56;
+ s[1] = (v & 0x00FF000000000000) >> 48;
+ s[2] = (v & 0x0000FF0000000000) >> 40;
+ s[3] = (v & 0x000000FF00000000) >> 32;
+ s[4] = (v & 0x00000000FF000000) >> 24;
+ s[5] = (v & 0x0000000000FF0000) >> 16;
+ s[6] = (v & 0x000000000000FF00) >> 8;
+ s[7] = (v & 0x00000000000000FF);
+}
+
+#endif /* #if __BYTE_ORDER == __BIG_ENDIAN */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+static INLINE uint16_t UNALIGNED_LOAD16(const void *p)
+{
+ return
+ (uint16_t)(((uint8_t*)p)[1]) << 8) |
+ (uint16_t)(((uint8_t*)p)[0]);
+}
+
+static INLINE uint32_t UNALIGNED_LOAD32(const void *p)
+{
+ return
+ (uint32_t)(((uint8_t*)p)[3]) << 24 |
+ (uint32_t)(((uint8_t*)p)[2]) << 16 |
+ (uint32_t)(((uint8_t*)p)[1]) << 8 |
+ (uint32_t)(((uint8_t*)p)[0]);
+}
+
+static INLINE uint64_t UNALIGNED_LOAD64(const void *p)
+{
+ return
+ (uint64_t)(((uint8_t*)p)[7]) << 56 |
+ (uint64_t)(((uint8_t*)p)[6]) << 48 |
+ (uint64_t)(((uint8_t*)p)[5]) << 40 |
+ (uint64_t)(((uint8_t*)p)[4]) << 32 |
+ (uint64_t)(((uint8_t*)p)[3]) << 24 |
+ (uint64_t)(((uint8_t*)p)[2]) << 16 |
+ (uint64_t)(((uint8_t*)p)[1]) << 8 |
+ (uint64_t)(((uint8_t*)p)[0]);
+}
+
+static INLINE void UNALIGNED_STORE16(void *p, uint16_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[1] = (v & 0xFF00) >> 8;
+ s[0] = (v & 0x00FF);
+}
+
+static INLINE void UNALIGNED_STORE32(void *p, uint32_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[3] = (v & 0xFF000000) >> 24;
+ s[2] = (v & 0x00FF0000) >> 16;
+ s[1] = (v & 0x0000FF00) >> 8;
+ s[0] = (v & 0x000000FF);
+}
+
+static INLINE void UNALIGNED_STORE64(void *p, uint64_t v)
+{
+ uint8_t* s = (uint8_t*)p;
+ s[7] = (v & 0xFF00000000000000) >> 56;
+ s[6] = (v & 0x00FF000000000000) >> 48;
+ s[5] = (v & 0x0000FF0000000000) >> 40;
+ s[4] = (v & 0x000000FF00000000) >> 32;
+ s[3] = (v & 0x00000000FF000000) >> 24;
+ s[2] = (v & 0x0000000000FF0000) >> 16;
+ s[1] = (v & 0x000000000000FF00) >> 8;
+ s[0] = (v & 0x00000000000000FF);
+}
+
+#endif /* #if __BYTE_ORDER == __LITTLE_ENDIAN */
+
#else /* !(x86 || powerpc) && !(arm && !(old arm architectures)) */
+/* pragma pack is available in gcc (though originally apparently by
+ * Microsoft) and in some other compilers (probably inspired by either
+ * the two big ones), but there is no good portable way to detect
+ * whether it's supported. The bad news: on platforms where it's not
+ * supported (unsupported pragmas are ignored) but which do require
+ * strict alignment, the below pragma pack trickery will fail.
+ * Therefore this option is the last and the default, and the platforms
+ * requiring strict alignment are detected earlier. */
+
#pragma pack(1)
struct una_u16 { uint16_t x; };
struct una_u32 { uint32_t x; };
ptr->x = v;
}
-#endif /* !(x86 || powerpc) && !(arm && !armv5 && !armv6) */
+#endif /* defining UNALIGNED_LOADNN and UNALIGNED_STORENN */
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* Internal debugging macros, used only in DEBUG mode */
#ifndef NDEBUG
-#define DEBUG_ASSERT_BUF_SPACE(enc, len) STMT_START { \
- if((BUF_SPACE(enc->buf) < (ptrdiff_t)(len))) { \
- warn("failed assertion check - pos: %ld [%p %p %p] %ld < %ld", \
- (long)BUF_POS_OFS(enc->buf), (enc)->buf.start, (enc)->buf.pos, (enc)->buf.end, (long)BUF_SPACE(enc->buf),(long)(len)); \
- } \
- assert(BUF_SPACE(enc->buf) >= (ptrdiff_t)(len)); \
+#define DEBUG_ASSERT_BUF_SPACE(enc, len) STMT_START { \
+ if((BUF_SPACE(enc->buf) < (ptrdiff_t)(len))) { \
+ warn("failed assertion check - pos: %ld [%p %p %p] %ld < %ld", \
+ (long)BUF_POS_OFS(enc->buf), (enc)->buf.start, \
+ (enc)->buf.pos, (enc)->buf.end, \
+ (long)BUF_SPACE(enc->buf),(long)(len)); \
+ } \
+ assert(BUF_SPACE(enc->buf) >= (ptrdiff_t)(len)); \
} STMT_END
#else
#define DEBUG_ASSERT_BUF_SPACE(enc, len) ((void)0)
#endif
#ifndef NDEBUG
-#define DEBUG_ASSERT_BUF_SANE(enc) STMT_START { \
- if(!(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end))){\
- warn("failed sanity assertion check - pos: %ld [%p %p %p] %ld", \
- (long)BUF_POS_OFS(enc->buf), (enc)->buf.start, (enc)->buf.pos, (enc)->buf.end, (long)BUF_SPACE(enc->buf)); \
- } \
- assert(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end));\
+#define DEBUG_ASSERT_BUF_SANE(enc) STMT_START { \
+ if(!(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end))){ \
+ warn("failed sanity assertion check - pos: %ld [%p %p %p] %ld", \
+ (long)BUF_POS_OFS(enc->buf), (enc)->buf.start, \
+ (enc)->buf.pos, (enc)->buf.end, (long)BUF_SPACE(enc->buf)); \
+ } \
+ assert(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end)); \
} STMT_END
#else
-#define DEBUG_ASSERT_BUF_SANE(enc) assert(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end))
+#define DEBUG_ASSERT_BUF_SANE(enc) \
+ assert(((enc)->buf.start <= (enc)->buf.pos) && ((enc)->buf.pos <= (enc)->buf.end))
#endif
/* Allocate a virgin buffer (but not the buffer struct) */
* freeing it. */
SRL_STATIC_INLINE srl_encoder_t *srl_dump_data_structure(pTHX_ srl_encoder_t *enc, SV *src, SV *user_header_src);
-#define SRL_GET_STR_DEDUPER_HV(enc) ( (enc)->string_deduper_hv == NULL \
+#define SRL_GET_STR_DEDUPER_HV(enc) ( (enc)->string_deduper_hv == NULL \
? srl_init_string_deduper_hv(aTHX_ enc) \
: (enc)->string_deduper_hv )
#define SRL_GET_STR_PTR_SEENHASH(enc) ( (enc)->str_seenhash == NULL \
- ? srl_init_string_hash(enc) \
+ ? srl_init_string_hash(enc) \
: (enc)->str_seenhash )
#define SRL_GET_REF_SEENHASH(enc) ( (enc)->ref_seenhash == NULL \
? srl_init_weak_hash(enc) \
: (enc)->weak_seenhash )
-#define SRL_GET_FREEZEOBJ_SVHASH(enc) ( (enc)->freezeobj_svhash == NULL \
- ? srl_init_freezeobj_svhash(enc) \
+#define SRL_GET_FREEZEOBJ_SVHASH(enc) ( (enc)->freezeobj_svhash == NULL \
+ ? srl_init_freezeobj_svhash(enc) \
: (enc)->freezeobj_svhash )
#ifndef MAX_CHARSET_NAME_LENGTH
srl_dump_nv(aTHX_ enc, src); \
} \
-#define CALL_SRL_DUMP_SV(enc, src) STMT_START { \
- if (!(src)) { \
- srl_buf_cat_char((enc), SRL_HDR_CANONICAL_UNDEF); /* is this right? */ \
- } \
- else \
- { \
- SvGETMAGIC(src); \
- svtype svt= SvTYPE((src)); \
- if (svt < SVt_PVMG && \
- SvREFCNT((src)) == 1 && \
- !SvROK((src)) \
- ) { \
- _SRL_IF_SIMPLE_DIRECT_DUMP_SV(enc, src, svt) \
- else { \
- srl_dump_sv(aTHX_ (enc), (src)); \
- } \
- } else { \
- srl_dump_sv(aTHX_ (enc), (src)); \
- } \
- } \
+#define CALL_SRL_DUMP_SV(enc, src) STMT_START { \
+ if (!(src)) { \
+ srl_buf_cat_char((enc), SRL_HDR_CANONICAL_UNDEF); /* is this right? */ \
+ } \
+ else \
+ { \
+ SvGETMAGIC(src); \
+ svtype svt= SvTYPE((src)); \
+ if (svt < SVt_PVMG && \
+ SvREFCNT((src)) == 1 && \
+ !SvROK((src)) \
+ ) { \
+ _SRL_IF_SIMPLE_DIRECT_DUMP_SV(enc, src, svt) \
+ else { \
+ srl_dump_sv(aTHX_ (enc), (src)); \
+ } \
+ } else { \
+ srl_dump_sv(aTHX_ (enc), (src)); \
+ } \
+ } \
} STMT_END
/* This is fired when we exit the Perl pseudo-block.
/* magic string, protocol version and encoding information */
#define SRL_MAGIC_STRLEN 4 /* Length of SRL_MAGIC_STRING */
+
#define SRL_MAGIC_STRING "=srl" /* Magic string for header. Every packet starts with this or "=\xF3rl",
* which is the high-bit-set-on-the-"s" equivalent. */
-#define SRL_MAGIC_STRING_HIGHBIT "=\xF3rl" /* Magic string for header, with high bit set for UTF8 sanity check. */
#define SRL_MAGIC_STRING_UINT_LE 0x6C72733D /* SRL_MAGIC_STRING as a little endian integer */
-#define SRL_MAGIC_STRING_HIGHBIT_UINT_LE 0x6C72F33D /* SRL_MAGIC_STRING as a little endian integer */
+#define SRL_MAGIC_STRING_UINT_BE 0x3D73726C /* SRL_MAGIC_STRING as a big endian integer */
+#define SRL_MAGIC_STRING_HIGHBIT "=\xF3rl" /* Magic string for header, with high bit set for UTF8 sanity check. */
+#define SRL_MAGIC_STRING_HIGHBIT_UINT_LE 0x6C72F33D /* SRL_MAGIC_STRING_HIGHBIT as a little endian integer */
+#define SRL_MAGIC_STRING_HIGHBIT_UINT_BE 0x3DF3726C /* SRL_MAGIC_STRING_HIGHBIT as a big endian integer */
#define SRL_MAGIC_STRING_HIGHBIT_UTF8 "=\xC3\xB3rl" /* Magic string for header, corrupted by accidental UTF8 encoding */
-#define SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE 0x72B3C33D /* first four bytes of SRL_MAGIC_STRING encoded as utf8 */
-
+#define SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_LE 0x72B3C33D /* first four bytes of SRL_MAGIC_STRING encoded as UTF8, little endian */
+#define SRL_MAGIC_STRING_HIGHBIT_UTF8_UINT_BE 0x3DC3B372 /* first four bytes of SRL_MAGIC_STRING encoded as UTF8, big endian */
#define SRL_PROTOCOL_VERSION ( 3 )
#define SRL_PROTOCOL_VERSION_BITS ( 4 ) /* how many bits we use for the version, the rest go to the encoding */
my ($dump, $undump);
my $ok= eval {
$dump = Sereal::Encoder::encode_sereal($_[0]);
- $undump= Sereal::Decoder::decode_sereal($dump);
+ $undump= Sereal::Decoder::decode_sereal($dump, $opt{decoder_options} || {});
1;
};
my $err = $@ || 'Zombie error';
read_files(sub{return 1})
},
'decode_sereal' => sub{
- read_files(sub { return( decode_sereal($_[0]) ); }, 'sereal')
+ read_files(sub { return( decode_sereal($_[0], $opt{decoder_options} || {} ) ); }, 'sereal')
},
'eval' => sub{
read_files(sub { return( eval $_[0] ); }, 'raw')
['sort_keys', { sort_keys => 1 }, 2 ],
['dedupe_strings', { dedupe_strings => 1 }, 2 ],
['freeze/thaw', { freeze_callbacks => 1 }, 2 ],
+ ['readonly', { set_readonly => 1 }, 2 ],
);
for my $opt (@variants) {
my ($name, $opts, $min_proto_v, $max_proto_v) = @$opt;