|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #include "easyxs/init.h"  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #include   | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #include "cbor_free_encode.h"  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define TAGGED_CLASS    "CBOR::Free::Tagged"  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define IS_SCALAR_REFERENCE(value) SvTYPE(SvRV(value)) <= SVt_PVMG  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char NUL = 0;  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_NULL_U8  = CBOR_NULL;  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_FALSE_U8 = CBOR_FALSE;  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_TRUE_U8  = CBOR_TRUE;  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_INF_SHORT[3] = { 0xf9, 0x7c, 0x00 };  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_NAN_SHORT[3] = { 0xf9, 0x7e, 0x00 };  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static const unsigned char CBOR_NEGINF_SHORT[3] = { 0xf9, 0xfc, 0x00 };  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static HV *tagged_stash = NULL;  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // Perl 5.18 and below appear not to set SvUTF8 if HeUTF8.  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // This macro corrects for that:  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #if PERL_VERSION < 20  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #define CBF_HeSVKEY_force(h_entry, sv) \  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sv = HeSVKEY_force(h_entry); \  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (HeUTF8(h_entry)) SvUTF8_on(sv);  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #else  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #define CBF_HeSVKEY_force(h_entry, sv) \  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sv = HeSVKEY_force(h_entry);  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #endif  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define UTF8_DOWNGRADE_OR_CROAK(encode_state, sv) \  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (!sv_utf8_downgrade(sv, true)) { \  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _croak_wide_character( aTHX_ encode_state, sv ); \  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define UTF8_DOWNGRADE_IF_NEEDED(encode_state, to_encode) \  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (SvUTF8(to_encode)) { \  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         UTF8_DOWNGRADE_OR_CROAK(encode_state, to_encode); \  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define STORE_PLAIN_HASH_KEY(encode_state, h_entry, key, key_length, major_type) \  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key = HePV(h_entry, key_length); \  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _init_length_buffer( aTHX_ key_length, major_type, encode_state ); \  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _COPY_INTO_ENCODE( encode_state, (unsigned char *) key, key_length );  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define STORE_SORTABLE_HASH_KEY(sortables_entry, h_entry, key, key_length, key_is_utf8) \  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key = HePV(h_entry, key_length); \  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.is_utf8 = key_is_utf8; \  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.buffer = key; \  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.length = key_length;  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define STORE_UPGRADED_SORTABLE_HASH_KEY(sortables_entry, h_entry) \  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV* key_sv; \  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CBF_HeSVKEY_force(h_entry, key_sv); \  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sv_utf8_upgrade(key_sv); \  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.is_utf8 = true; \  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.buffer = SvPV(key_sv, sortables_entry.length);  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define STORE_DOWNGRADED_SORTABLE_HASH_KEY(sortables_entry, h_entry, key_is_utf8) \  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV* key_sv; \  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CBF_HeSVKEY_force(h_entry, key_sv); \  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     UTF8_DOWNGRADE_OR_CROAK(encode_state, key_sv); \  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.is_utf8 = key_is_utf8; \  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sortables_entry.buffer = SvPV(key_sv, sortables_entry.length);  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 //----------------------------------------------------------------------  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // These encode num as big-endian into buffer.  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // Importantly, on big-endian systems this is just a memcpy,  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // while on little-endian systems it’s a bswap.  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _u16_to_buffer( UV num, uint8_t *buffer ) {  | 
| 
75
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 8;  | 
| 
76
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num;  | 
| 
77
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _u32_to_buffer( UV num, unsigned char *buffer ) {  | 
| 
80
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 24;  | 
| 
81
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 16;  | 
| 
82
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 8;  | 
| 
83
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num;  | 
| 
84
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _u64_to_buffer( UV num, unsigned char *buffer ) {  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #if IS_64_BIT  | 
| 
88
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 56;  | 
| 
89
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 48;  | 
| 
90
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 40;  | 
| 
91
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 32;  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #endif  | 
| 
93
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 24;  | 
| 
94
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 16;  | 
| 
95
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num >> 8;  | 
| 
96
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *(buffer++) = num;  | 
| 
97
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 //----------------------------------------------------------------------  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // Croakers  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _croak_unrecognized(pTHX_ encode_ctx *encode_state, SV *value) {  | 
| 
103
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     char * words[3] = { "Unrecognized", SvPV_nolen(value), NULL };  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cbf_encode_ctx_free_all(encode_state);  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _die( G_DISCARD, words );  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
110
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _croak_wide_character(pTHX_ encode_ctx *encode_state, SV *value) {  | 
| 
111
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV* args[2] = {  | 
| 
112
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         newSVpvs("WideCharacter"),  | 
| 
113
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         newSVsv(value),  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cbf_encode_ctx_free_all(encode_state);  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cbf_die_with_arguments( aTHX_ 2, args );  | 
| 
119
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // This has to be a macro because _croak() needs a string literal.  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define _croak_encode(encode_state, str) \  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cbf_encode_ctx_free_all(encode_state); \  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _croak(str);  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 //----------------------------------------------------------------------  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // NOTE: Contrary to JSON’s “canonical” order, for canonical CBOR  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // keys are only byte-sorted if their lengths are identical. Thus,  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // “z” sorts EARLIER than “aa”. (cf. section 3.9 of the RFC)  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #define _SORT(x) ((struct sortable_hash_entry *)x)  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 int _sort_map_keys( const void* a, const void* b ) {  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // The CBOR RFC defines canonical sorting such that the  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // *encoded* keys are what gets sorted; however, it’s easier to  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // anticipate the sort order algorithmically rather than to  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // create the encoded keys *then* sort those. Since Perl hash keys  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // are always strings (either with or without the UTF8 flag), we  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // only have 2 CBOR types to deal with (text & binary strings) and  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // can sort accordingly.  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return (  | 
| 
145
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _SORT(a)->is_utf8 < _SORT(b)->is_utf8 ? -1  | 
| 
146
 | 
68
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : _SORT(a)->is_utf8 > _SORT(b)->is_utf8 ? 1  | 
| 
147
 | 
62
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : _SORT(a)->length < _SORT(b)->length ? -1  | 
| 
148
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : _SORT(a)->length > _SORT(b)->length ? 1  | 
| 
149
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : memcmp( _SORT(a)->buffer, _SORT(b)->buffer, _SORT(a)->length )  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 //----------------------------------------------------------------------  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline HV *_get_tagged_stash() {  | 
| 
156
 | 
114
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (!tagged_stash) {  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         dTHX;  | 
| 
158
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         tagged_stash = gv_stashpv(TAGGED_CLASS, 1);  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return tagged_stash;  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
44743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _COPY_INTO_ENCODE( encode_ctx *encode_state, const unsigned char *hdr, STRLEN len) {  | 
| 
165
 | 
44743
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( (len + encode_state->len) > encode_state->buflen ) {  | 
| 
166
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         Renew( encode_state->buffer, encode_state->buflen + len + ENCODE_ALLOC_CHUNK_SIZE, char );  | 
| 
167
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state->buflen += len + ENCODE_ALLOC_CHUNK_SIZE;  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
44743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Copy( hdr, encode_state->buffer + encode_state->len, len, char );  | 
| 
171
 | 
44743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state->len += len;  | 
| 
172
 | 
44743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // TODO? This could be a macro … it’d just be kind of unwieldy as such.  | 
| 
175
 | 
23362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _init_length_buffer( pTHX_ UV num, enum CBOR_TYPE major_type, encode_ctx *encode_state ) {  | 
| 
176
 | 
23362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     uint8_t* control_byte_p = (void *) encode_state->scratch;  | 
| 
177
 | 
23362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *control_byte_p = major_type << CONTROL_BYTE_MAJOR_TYPE_SHIFT;  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
23362
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( num < CBOR_LENGTH_SMALL ) {  | 
| 
180
 | 
6465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         *control_byte_p |= (uint8_t) num;  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
182
 | 
6465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 1);  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
184
 | 
16897
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if ( num <= 0xff ) {  | 
| 
185
 | 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         *control_byte_p |= CBOR_LENGTH_SMALL;  | 
| 
186
 | 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state->scratch[1] = (uint8_t) num;  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 2);  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
190
 | 
16221
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if ( num <= 0xffff ) {  | 
| 
191
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         *control_byte_p |= CBOR_LENGTH_MEDIUM;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _u16_to_buffer( num, 1 + encode_state->scratch );  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
15901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 3);  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
197
 | 
320
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if ( num <= 0xffffffffU ) {  | 
| 
198
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         *control_byte_p |= CBOR_LENGTH_LARGE;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _u32_to_buffer( num, 1 + encode_state->scratch );  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 5);  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
205
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         *control_byte_p |= CBOR_LENGTH_HUGE;  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
207
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _u64_to_buffer( num, 1 + encode_state->scratch );  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 9);  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
211
 | 
23362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 void _encode( pTHX_ SV *value, encode_ctx *encode_state );  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_tag( pTHX_ IV tagnum, SV *value, encode_ctx *encode_state );  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 // Return indicates to encode the actual value.  | 
| 
217
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 bool _check_reference( pTHX_ SV *varref, encode_ctx *encode_state ) {  | 
| 
218
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( SvREFCNT(varref) > 1 ) {  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         void *this_ref;  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
221
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         IV r = 0;  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
223
 | 
24
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         while ( (this_ref = encode_state->reftracker[r++]) ) {  | 
| 
224
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (this_ref == varref) {  | 
| 
225
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _init_length_buffer( aTHX_ CBOR_TAG_SHAREDREF, CBOR_TYPE_TAG, encode_state );  | 
| 
226
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _init_length_buffer( aTHX_ r - 1, CBOR_TYPE_UINT, encode_state );  | 
| 
227
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 return false;  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
231
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         Renew( encode_state->reftracker, 1 + r, void * );  | 
| 
232
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state->reftracker[r - 1] = varref;  | 
| 
233
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state->reftracker[r] = NULL;  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
235
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _init_length_buffer( aTHX_ CBOR_TAG_SHAREABLE, CBOR_TYPE_TAG, encode_state );  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return true;  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline I32 _magic_safe_hv_iterinit( pTHX_ HV* hash ) {  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     I32 count;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
61
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (SvMAGICAL(hash)) {  | 
| 
245
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         count = 0;  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
247
 | 
1767
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         while (hv_iternext(hash)) count++;  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
249
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         hv_iterinit(hash);  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
252
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         count = hv_iterinit(hash);  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return count;  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_string_sv( pTHX_ encode_ctx* encode_state, SV* value ) {  | 
| 
259
 | 
1235
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     char *val = SvPOK(value) ? SvPVX(value) : SvPV_nolen(value);  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
261
 | 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     STRLEN len = SvCUR(value);  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bool encode_as_text = !!SvUTF8(value);  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     /*  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (!encode_as_text) {  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         STRLEN i;  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         for (i=0; i
 | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (val[i] & 0x80) break;  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         // Encode as text if there were no high-bit octets.  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_as_text = (i == len);  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     */  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
1235
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _init_length_buffer( aTHX_  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         len,  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (encode_as_text ? CBOR_TYPE_UTF8 : CBOR_TYPE_BINARY),  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
283
 | 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _COPY_INTO_ENCODE( encode_state, (unsigned char *) val, len );  | 
| 
284
 | 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
286
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_string_unicode( pTHX_ encode_ctx* encode_state, SV* value ) {  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV *to_encode;  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
289
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (SvUTF8(value)) {  | 
| 
290
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         to_encode = value;  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
293
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         to_encode = newSVsv(value);  | 
| 
294
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sv_2mortal(to_encode);  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sv_utf8_upgrade(to_encode);  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
299
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode_string_sv( aTHX_ encode_state, to_encode );  | 
| 
300
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
302
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_string_utf8( pTHX_ encode_ctx* encode_state, SV* value ) {  | 
| 
303
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV *to_encode = newSVsv(value);  | 
| 
304
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sv_2mortal(to_encode);  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
306
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     UTF8_DOWNGRADE_IF_NEEDED(encode_state, to_encode);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
308
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SvUTF8_on(to_encode);  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode_string_sv( aTHX_ encode_state, to_encode );  | 
| 
311
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
313
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_string_octets( pTHX_ encode_ctx* encode_state, SV* value ) {  | 
| 
314
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV *to_encode = newSVsv(value);  | 
| 
315
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sv_2mortal(to_encode);  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
317
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     UTF8_DOWNGRADE_IF_NEEDED(encode_state, to_encode);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode_string_sv( aTHX_ encode_state, to_encode );  | 
| 
320
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
322
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _upgrade_and_store_hash_key( pTHX_ HE* h_entry, encode_ctx *encode_state ) {  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV* key_sv;  | 
| 
324
 | 
152
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CBF_HeSVKEY_force(h_entry, key_sv);  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sv_utf8_upgrade(key_sv);  | 
| 
326
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode_string_sv( aTHX_ encode_state, key_sv );  | 
| 
327
 | 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
329
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _downgrade_and_store_hash_key( pTHX_ HE* h_entry, encode_ctx *encode_state, enum CBOR_TYPE string_type ) {  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SV* key_sv;  | 
| 
331
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CBF_HeSVKEY_force(h_entry, key_sv);  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
332
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     UTF8_DOWNGRADE_OR_CROAK(encode_state, key_sv);  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // We can do this without altering h_entry itself because  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // key_sv is just a mortal copy of the key.  | 
| 
336
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (string_type == CBOR_TYPE_UTF8) SvUTF8_on(key_sv);  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode_string_sv( aTHX_ encode_state, key_sv );  | 
| 
339
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
341
 | 
20531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 void _encode( pTHX_ SV *value, encode_ctx *encode_state ) {  | 
| 
342
 | 
20531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ++encode_state->recurse_count;  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
344
 | 
20531
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (encode_state->recurse_count > MAX_ENCODE_RECURSE) {  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         // call_pv() killed the process in Win32; this seems to fix that.  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         static char * words[] = { NULL };  | 
| 
348
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         call_argv("CBOR::Free::_die_recursion", G_EVAL|G_DISCARD, words);  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _croak_encode( encode_state, NULL );  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
20529
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     SvGETMAGIC(value);  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
355
 | 
20529
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (!SvROK(value)) {  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
20094
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (SvIOK(value)) {  | 
| 
358
 | 
18755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             IV val = SvIVX(value);  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             // In testing, Perl’s (0 + ~0) evaluated as < 0 here,  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             // but the SvUOK() check fixes that.  | 
| 
362
 | 
18755
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (val < 0 && !SvUOK(value)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
363
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _init_length_buffer( aTHX_ -(++val), CBOR_TYPE_NEGINT, encode_state );  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 // NB: SvUOK doesn’t work to identify nonnegatives … ?  | 
| 
367
 | 
18755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _init_length_buffer( aTHX_ val, CBOR_TYPE_UINT, encode_state );  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
370
 | 
1339
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else if (SvNOK(value)) {  | 
| 
371
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             NV val_nv = SvNVX(value);  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
373
 | 
27
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (Perl_isnan(val_nv)) {  | 
| 
374
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _COPY_INTO_ENCODE(encode_state, CBOR_NAN_SHORT, 3);  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
376
 | 
24
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else if (Perl_isinf(val_nv)) {  | 
| 
377
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 if (val_nv > 0) {  | 
| 
378
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _COPY_INTO_ENCODE(encode_state, CBOR_INF_SHORT, 3);  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
381
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _COPY_INTO_ENCODE(encode_state, CBOR_NEGINF_SHORT, 3);  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 // Typecast to a double to accommodate long-double perls.  | 
| 
387
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 double val = (double) val_nv;  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
389
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 char *valptr = (char *) &val;  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #if IS_LITTLE_ENDIAN  | 
| 
392
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[0] = CBOR_DOUBLE;  | 
| 
393
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[1] = valptr[7];  | 
| 
394
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[2] = valptr[6];  | 
| 
395
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[3] = valptr[5];  | 
| 
396
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[4] = valptr[4];  | 
| 
397
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[5] = valptr[3];  | 
| 
398
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[6] = valptr[2];  | 
| 
399
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[7] = valptr[1];  | 
| 
400
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state->scratch[8] = valptr[0];  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
402
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _COPY_INTO_ENCODE(encode_state, encode_state->scratch, 9);  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #else  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 unsigned char bytes[9] = { CBOR_DOUBLE, valptr[0], valptr[1], valptr[2], valptr[3], valptr[4], valptr[5], valptr[6], valptr[7] };  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _COPY_INTO_ENCODE(encode_state, bytes, 9);  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #endif  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
409
 | 
1312
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else if (!SvOK(value)) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
410
 | 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _COPY_INTO_ENCODE(encode_state, &CBOR_NULL_U8, 1);  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
413
 | 
1087
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             switch (encode_state->string_encode_mode) {  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 case CBF_STRING_ENCODE_SV:  | 
| 
415
 | 
1055
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode_string_sv( aTHX_ encode_state, value );  | 
| 
416
 | 
1055
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     break;  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 case CBF_STRING_ENCODE_UNICODE:  | 
| 
418
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode_string_unicode( aTHX_ encode_state, value );  | 
| 
419
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     break;  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 case CBF_STRING_ENCODE_UTF8:  | 
| 
421
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode_string_utf8( aTHX_ encode_state, value );  | 
| 
422
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     break;  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 case CBF_STRING_ENCODE_OCTETS:  | 
| 
424
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode_string_octets( aTHX_ encode_state, value );  | 
| 
425
 | 
20090
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     break;  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 default:  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     assert(0);  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
432
 | 
435
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if (sv_isobject(value)) {  | 
| 
433
 | 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         HV *stash = SvSTASH( SvRV(value) );  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
435
 | 
114
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (_get_tagged_stash() == stash) {  | 
| 
436
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             AV *array = (AV *)SvRV(value);  | 
| 
437
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             SV **tag = av_fetch(array, 0, 0);  | 
| 
438
 | 
105
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             IV tagnum = SvIV(*tag);  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _encode_tag( aTHX_ tagnum, *(av_fetch(array, 1, 0)), encode_state );  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
442
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else if (cbf_get_boolean_stash() == stash) {  | 
| 
443
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _COPY_INTO_ENCODE(  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 encode_state,  | 
| 
445
 | 
8
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 SvTRUE(SvRV(value)) ? &CBOR_TRUE_U8 : &CBOR_FALSE_U8,  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 1  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         // TODO: Support TO_JSON() or TO_CBOR() method?  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
452
 | 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else _croak_unrecognized(aTHX_ encode_state, value);  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
454
 | 
321
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if (SVt_PVAV == SvTYPE(SvRV(value))) {  | 
| 
455
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         AV *array = (AV *)SvRV(value);  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
457
 | 
245
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (!encode_state->reftracker || _check_reference( aTHX_ (SV *)array, encode_state )) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             SSize_t len;  | 
| 
459
 | 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             len = 1 + av_len(array);  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
461
 | 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _init_length_buffer( aTHX_ len, CBOR_TYPE_ARRAY, encode_state );  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             SSize_t i;  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             SV **cur;  | 
| 
466
 | 
410
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             for (i=0; i
 | 
| 
467
 | 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 cur = av_fetch(array, i, 0);  | 
| 
468
 | 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 _encode( aTHX_ *cur, encode_state );  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
472
 | 
76
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if (SVt_PVHV == SvTYPE(SvRV(value))) {  | 
| 
473
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         HV *hash = (HV *)SvRV(value);  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
475
 | 
63
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (!encode_state->reftracker || _check_reference( aTHX_ (SV *)hash, encode_state)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             char *key;  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             STRLEN key_length;  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             HE* h_entry;  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             bool heutf8;  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
482
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             I32 keyscount = _magic_safe_hv_iterinit(aTHX_ hash);  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
484
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _init_length_buffer( aTHX_ keyscount, CBOR_TYPE_MAP, encode_state );  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
61
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (encode_state->is_canonical) {  | 
| 
487
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 I32 curkey = 0;  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
489
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 struct sortable_hash_entry sortables[keyscount];  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
491
 | 
60
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 while ( (h_entry = hv_iternext(hash)) ) {  | 
| 
492
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     heutf8 = HeUTF8(h_entry);  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     switch (encode_state->string_encode_mode) {  | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_SV:  | 
| 
496
 | 
26
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (heutf8 || !CBF_HeUTF8(h_entry)) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
497
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_SORTABLE_HASH_KEY( sortables[curkey], h_entry, key, key_length, heutf8 );  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
500
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_UPGRADED_SORTABLE_HASH_KEY(sortables[curkey], h_entry);  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
503
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_UNICODE:  | 
| 
506
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (heutf8) {  | 
| 
507
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_SORTABLE_HASH_KEY( sortables[curkey], h_entry, key, key_length, true );  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
510
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_UPGRADED_SORTABLE_HASH_KEY(sortables[curkey], h_entry);  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
512
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_UTF8:  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_OCTETS:  | 
| 
516
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (heutf8) {  | 
| 
517
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_DOWNGRADED_SORTABLE_HASH_KEY(sortables[curkey], h_entry, encode_state->string_encode_mode == CBF_STRING_ENCODE_UTF8);  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
520
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_SORTABLE_HASH_KEY( sortables[curkey], h_entry, key, key_length, encode_state->string_encode_mode == CBF_STRING_ENCODE_UTF8 );  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
522
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         default:  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             assert(0);  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
528
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     sortables[curkey].value = hv_iterval(hash, h_entry);  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
530
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     curkey++;  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 qsort(sortables, keyscount, sizeof(struct sortable_hash_entry), _sort_map_keys);  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
535
 | 
56
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 for (curkey=0; curkey < keyscount; ++curkey) {  | 
| 
536
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _init_length_buffer( aTHX_ sortables[curkey].length, sortables[curkey].is_utf8 ? CBOR_TYPE_UTF8 : CBOR_TYPE_BINARY, encode_state );  | 
| 
537
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _COPY_INTO_ENCODE( encode_state, (unsigned char *) sortables[curkey].buffer, sortables[curkey].length );  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode( aTHX_ sortables[curkey].value, encode_state );  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
543
 | 
3108
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 while ( (h_entry = hv_iternext(hash)) ) {  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     /*  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     fprintf(stderr, "HeSVKEY: %p\n", HeSVKEY(h_entry));  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     fprintf(stderr, "HeUTF8: %d\n", HeUTF8(h_entry));  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     fprintf(stderr, "CBF_HeUTF8: %d\n", CBF_HeUTF8(h_entry));  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     */  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
3053
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     switch (encode_state->string_encode_mode) {  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_SV:  | 
| 
553
 | 
2635
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (HeUTF8(h_entry) || !CBF_HeUTF8(h_entry)) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
2621
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_PLAIN_HASH_KEY( encode_state, h_entry, key, key_length, HeUTF8(h_entry) ? CBOR_TYPE_UTF8 : CBOR_TYPE_BINARY );  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
557
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 _upgrade_and_store_hash_key( aTHX_ h_entry, encode_state);  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
559
 | 
2635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_UNICODE:  | 
| 
562
 | 
140
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (HeUTF8(h_entry)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_PLAIN_HASH_KEY( encode_state, h_entry, key, key_length, CBOR_TYPE_UTF8 );  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
566
 | 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 _upgrade_and_store_hash_key( aTHX_ h_entry, encode_state);  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
569
 | 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_UTF8:  | 
| 
572
 | 
139
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (HeUTF8(h_entry)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 _downgrade_and_store_hash_key( aTHX_ h_entry, encode_state, CBOR_TYPE_UTF8 );  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
576
 | 
137
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_PLAIN_HASH_KEY( encode_state, h_entry, key, key_length, CBOR_TYPE_UTF8 );  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         case CBF_STRING_ENCODE_OCTETS:  | 
| 
582
 | 
139
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             if (HeUTF8(h_entry)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 _downgrade_and_store_hash_key( aTHX_ h_entry, encode_state, CBOR_TYPE_BINARY );  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             else {  | 
| 
586
 | 
137
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 STORE_PLAIN_HASH_KEY( encode_state, h_entry, key, key_length, CBOR_TYPE_BINARY );  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             }  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             break;  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         default:  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             assert(0);  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
3049
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     _encode( aTHX_ hv_iterval(hash, h_entry), encode_state );  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
600
 | 
25
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else if (encode_state->encode_scalar_refs && IS_SCALAR_REFERENCE(value)) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
601
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         SV *referent = SvRV(value);  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (!encode_state->reftracker || _check_reference( aTHX_ referent, encode_state)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
604
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             _encode_tag( aTHX_ CBOR_TAG_INDIRECTION, referent, encode_state );  | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
608
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _croak_unrecognized(aTHX_ encode_state, value);  | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
611
 | 
20318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     --encode_state->recurse_count;  | 
| 
612
 | 
20318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
614
 | 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 static inline void _encode_tag( pTHX_ IV tagnum, SV *value, encode_ctx *encode_state ) {  | 
| 
615
 | 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _init_length_buffer( aTHX_ tagnum, CBOR_TYPE_TAG, encode_state );  | 
| 
616
 | 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode( aTHX_ value, encode_state );  | 
| 
617
 | 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 //----------------------------------------------------------------------  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 encode_ctx cbf_encode_ctx_create(uint8_t flags, enum cbf_string_encode_mode string_encode_mode) {  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_ctx encode_state;  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
624
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.buffer = NULL;  | 
| 
625
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Newx( encode_state.buffer, ENCODE_ALLOC_CHUNK_SIZE, char );  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
627
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.buflen = ENCODE_ALLOC_CHUNK_SIZE;  | 
| 
628
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.len = 0;  | 
| 
629
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.recurse_count = 0;  | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
631
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.is_canonical = !!(flags & ENCODE_FLAG_CANONICAL);  | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
633
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.text_keys = !!(flags & ENCODE_FLAG_TEXT_KEYS);  | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
635
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.encode_scalar_refs = !!(flags & ENCODE_FLAG_SCALAR_REFS);  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
637
 | 
16967
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (flags & ENCODE_FLAG_PRESERVE_REFS) {  | 
| 
638
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         Newxz( encode_state.reftracker, 1, void * );  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
641
 | 
16965
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         encode_state.reftracker = NULL;  | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
644
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     encode_state.string_encode_mode = string_encode_mode;  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
646
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return encode_state;  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
649
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 void cbf_encode_ctx_free_reftracker(encode_ctx* encode_state) {  | 
| 
650
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Safefree( encode_state->reftracker );  | 
| 
651
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
653
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 void cbf_encode_ctx_free_all(encode_ctx* encode_state) {  | 
| 
654
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cbf_encode_ctx_free_reftracker(encode_state);  | 
| 
655
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Safefree( encode_state->buffer );  | 
| 
656
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 SV *cbf_encode( pTHX_ SV *value, encode_ctx *encode_state, SV *RETVAL ) {  | 
| 
659
 | 
16967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _encode(aTHX_ value, encode_state);  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     // Ensure that there’s a trailing NUL:  | 
| 
662
 | 
16951
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _COPY_INTO_ENCODE( encode_state, &NUL, 1 );  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
16951
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return RETVAL;  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  |