File Coverage

proto.c
Criterion Covered Total %
statement 52 62 83.8
branch 9 18 50.0
condition n/a
subroutine n/a
pod n/a
total 61 80 76.2


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5             #define NEED_newSVpvn_flags_GLOBAL
6             #include "ppport.h"
7              
8             #include
9             #include "define.h"
10             #include "type.h"
11              
12             /* Int */
13 504           int32_t unpack_int(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos)
14             {
15 504 50         if (UNLIKELY(len - *pos < 4))
16 0           croak("unpack_int: input too short. Data corrupted?");
17 504           int32_t result = (int32_t)ntohl(*(uint32_t*)(input+*pos));
18 504           *pos += 4;
19 504           return result;
20             }
21              
22 244           STRLEN pack_int(pTHX_ SV *dest, int32_t number)
23             {
24             union {
25             int32_t number;
26             unsigned char bytes[4];
27             } int_or_bytes;
28 244           int_or_bytes.number = htonl(number);
29 244           sv_catpvn(dest, (char*)int_or_bytes.bytes, 4);
30 244           return SvCUR(dest)-4;
31             }
32              
33 45           void set_packed_int(pTHX_ SV *dest, STRLEN pos, int32_t number)
34             {
35             STRLEN len;
36             char *ptr;
37             union {
38             int32_t number;
39             unsigned char bytes[4];
40             } int_or_bytes;
41 45           int_or_bytes.number = htonl(number);
42 45           ptr = SvPV(dest, len);
43             assert(pos <= len-4);
44 45           memcpy(ptr+pos, int_or_bytes.bytes, 4);
45 45           }
46              
47             /* Short */
48 1298           int unpack_short_nocroak(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, uint16_t *out)
49             {
50 1298 50         if (UNLIKELY(len - *pos < 2))
51 0           return -1;
52 1298           *out = ntohs(*(uint16_t*)(input+*pos));
53 1298           *pos += 2;
54 1298           return 0;
55             }
56              
57 943           uint16_t unpack_short(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos)
58             {
59             uint16_t out;
60 943 50         if (UNLIKELY(unpack_short_nocroak(aTHX_ input, len, pos, &out) != 0))
61 0           croak("unpack_short: invalid input");
62 943           return out;
63             }
64              
65 96           void pack_short(pTHX_ SV *dest, uint16_t number)
66             {
67             union {
68             uint16_t number;
69             unsigned char bytes[2];
70             } short_or_bytes;
71 96           short_or_bytes.number = htons(number);
72 96           sv_catpvn(dest, (char*)short_or_bytes.bytes, 2);
73 96           }
74              
75             /* Bytes */
76 282           int unpack_bytes(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, unsigned char **output, STRLEN *outlen)
77             {
78 282           int32_t bytes_length = unpack_int(aTHX_ input, len, pos);
79 282 100         if (bytes_length < 0) {
80 17           return 1;
81             }
82              
83 265 50         if (UNLIKELY(len - *pos < bytes_length))
84 0           croak("unpack_bytes: input too short. Data corrupted?");
85              
86 265           *output = input + *pos;
87 265           *outlen = bytes_length;
88 265           *pos += bytes_length;
89              
90 265           return 0;
91             }
92              
93 0           SV *unpack_bytes_sv(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos)
94             {
95             unsigned char *bytes;
96             STRLEN bytes_len;
97              
98 0 0         if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) == 0) {
99 0           return newSVpvn((char*)bytes, bytes_len);
100             } else {
101 0           return &PL_sv_undef;
102             }
103             }
104              
105             /* String */
106 943           int unpack_string_nocroak(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, char **output, STRLEN *outlen)
107             {
108 943           uint16_t string_length = unpack_short(aTHX_ input, len, pos);
109              
110 943 50         if (UNLIKELY(len - *pos < string_length))
111 0           return -1;
112              
113 943           *output = (char*)(input + *pos);
114 943           *outlen = string_length;
115 943           *pos += string_length;
116              
117 943           return 0;
118             }
119              
120 933           void unpack_string(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, char **output, STRLEN *outlen)
121             {
122 933 50         if (UNLIKELY(unpack_string_nocroak(aTHX_ input, len, pos, output, outlen)) != 0)
123 0           croak("unpack_string: input invalid");
124 933           }
125              
126 622           SV *unpack_string_sv(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos)
127             {
128             char *string;
129             STRLEN str_len;
130 622           unpack_string(aTHX_ input, len, pos, &string, &str_len);
131 622           return newSVpvn_utf8(string, str_len, 1);
132             }
133              
134 311           SV *unpack_string_sv_hash(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, U32 *hashout)
135             {
136             char *string;
137             STRLEN str_len;
138 311           unpack_string(aTHX_ input, len, pos, &string, &str_len);
139 311 50         PERL_HASH((*hashout), string, str_len);
140 311           return newSVpvn_utf8(string, str_len, 1);
141             }