File Coverage

Rhash.xs
Criterion Covered Total %
statement 50 71 70.4
branch 18 34 52.9
condition n/a
subroutine n/a
pod n/a
total 68 105 64.7


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6             #include
7              
8             typedef unsigned long long ulonglong;
9              
10             /* helper macros and functions */
11             #define BASE32_LENGTH(size) (((size) * 8 + 4) / 5)
12             #define BASE64_LENGTH(size) ((((size) + 2) / 3) * 4)
13              
14 39           void verify_single_bit_hash_id(unsigned hash_id, CV* cv)
15             {
16             const char* error;
17             const GV *gv;
18             const char *func_name;
19              
20 39 50         if(0 == (hash_id & RHASH_ALL_HASHES)) {
21 0           error = "%s: unsupported hash_id = 0x%x";
22 39 50         } else if(0 != (hash_id & (hash_id - 1))) {
23 0           error = "%s: hash_id is not a single bit: 0x%x";
24             } else {
25 39           return; /* success */
26             }
27              
28 0           gv = CvGV(cv);
29 0 0         func_name = (gv ? GvNAME(gv) : "Rhash");
30 0           croak(error, func_name, hash_id);
31             }
32              
33             /* allocate a perl string scalar variable, containing str_len + 1 bytes */
34 9           SV * allocate_string_buffer(STRLEN str_len)
35             {
36 9           SV * sv = newSV(str_len); /* allocates (str_len + 1) bytes */
37 9           SvPOK_only(sv);
38 9           SvCUR_set(sv, str_len);
39 9           return sv;
40             }
41              
42             MODULE = Crypt::Rhash PACKAGE = Crypt::Rhash
43              
44             ##############################################################################
45             # Initialize LibRHash in the module bootstrap function
46              
47             BOOT:
48 3           rhash_library_init();
49              
50             ##############################################################################
51             # perl bindings for Hi-level functions
52              
53             SV *
54             rhash_msg_wrapper(hash_id, message)
55             unsigned hash_id
56             PROTOTYPE: $$
57             PREINIT:
58             STRLEN length;
59             unsigned char out[264];
60             int res;
61             INPUT:
62             char* message = SvPV(ST(1), length);
63             CODE:
64 1           verify_single_bit_hash_id(hash_id, cv);
65 1           res = rhash_msg(hash_id, message, length, out);
66 1 50         if(res < 0) {
67 0           croak("%s: %s", "rhash_msg_wrapper", strerror(errno));
68             }
69 1           RETVAL = newSVpv((char*)out, rhash_get_digest_size(hash_id));
70             OUTPUT:
71             RETVAL
72              
73             SV *
74             rhash_file_wrapper(hash_id, filepath)
75             unsigned hash_id
76             char * filepath
77             PROTOTYPE: $$
78             PREINIT:
79             int res;
80             unsigned char out[264];
81             CODE:
82 0           verify_single_bit_hash_id(hash_id, cv);
83 0           res = rhash_file(hash_id, filepath, out);
84 0 0         if(res < 0) {
85 0           croak("%s: %s: %s", "rhash_file", filepath, strerror(errno));
86             }
87 0           RETVAL = newSVpv((char*)out, rhash_get_digest_size(hash_id));
88             OUTPUT:
89             RETVAL
90              
91             ##############################################################################
92             # perl bindings for Low-level functions
93              
94             struct rhash_context *
95             rhash_init_multi_wrapper(AV* array)
96             PROTOTYPE: $
97             PREINIT:
98             unsigned hash_ids[64];
99 5           size_t length = 0;
100             int i;
101             CODE:
102 72 100         for (i = 0; i <= av_len(array); i++) {
103 67           SV** elem = av_fetch(array, i, 0);
104 67 50         if (elem != NULL) {
105 67 50         if (length >= (sizeof(hash_ids)/sizeof(*hash_ids)))
106 0           croak("too many hash identifiers passed");
107 67           hash_ids[length] = (unsigned)SvNV(*elem);
108 67           length++;
109             }
110             }
111 5 50         if (length == 0)
112 0           croak("at least one hash identifier must be passed");
113 5           RETVAL = rhash_init_multi(length, hash_ids);
114             OUTPUT:
115             RETVAL
116              
117             int
118             rhash_update(ctx, message)
119             struct rhash_context * ctx
120             PROTOTYPE: $$
121             PREINIT:
122             STRLEN length;
123             INPUT:
124             char* message = SvPV(ST(1), length);
125             CODE:
126 7           RETVAL = rhash_update(ctx, message, length);
127             OUTPUT:
128             RETVAL
129              
130             int
131             rhash_final(ctx)
132             struct rhash_context * ctx
133             PROTOTYPE: $
134             CODE:
135 3           RETVAL = rhash_final(ctx, 0);
136             OUTPUT:
137             RETVAL
138              
139             void
140             rhash_reset(ctx)
141             struct rhash_context * ctx
142             PROTOTYPE: $
143              
144             void
145             rhash_free(ctx)
146             struct rhash_context * ctx
147             PROTOTYPE: $
148              
149             SV *
150             rhash_print_wrapper(ctx, hash_id, flags = 0)
151             struct rhash_context * ctx
152             unsigned hash_id
153             int flags
154             PROTOTYPE: $$;$
155             PREINIT:
156             int len;
157             char out[264];
158             CODE:
159 43 100         if(hash_id != 0) verify_single_bit_hash_id(hash_id, cv);
160              
161 43           len = rhash_print(out, ctx, hash_id, flags);
162              
163             /* set exact length to support raw output (RHPR_RAW) */
164 43           RETVAL = newSVpv(out, len);
165             OUTPUT:
166             RETVAL
167              
168             SV *
169             rhash_print_magnet_wrapper(ctx, filename, hash_mask)
170             struct rhash_context * ctx
171             SV * filename
172             SV * hash_mask
173             PROTOTYPE: $;$$
174             PREINIT:
175             /* process undefined values */
176 4 100         char * name = (SvOK(filename) ? SvPV_nolen(filename) : 0);
177 4 100         unsigned mask = (SvOK(hash_mask) ? (unsigned)SvUV(hash_mask) : RHASH_ALL_HASHES);
    50          
178             size_t buf_size;
179             CODE:
180             /* allocate a string buffer and print magnet link into it */
181 4           buf_size = rhash_print_magnet(0, name, ctx, mask, RHPR_FILESIZE);
182 4           RETVAL = allocate_string_buffer(buf_size - 1);
183 4           rhash_print_magnet(SvPVX(RETVAL), name, ctx, mask, RHPR_FILESIZE);
184              
185             /* note: length(RETVAL) = (buf_size - 1),
186             * so the following call is not required:
187             * SvCUR_set(RETVAL, strlen(SvPVX(RETVAL))); */
188             OUTPUT:
189             RETVAL
190              
191             unsigned
192             rhash_get_hash_id(ctx)
193             struct rhash_context * ctx
194             PROTOTYPE: $
195             CODE:
196 1 50         RETVAL = ctx->hash_id;
197             OUTPUT:
198             RETVAL
199              
200             ulonglong
201             rhash_get_hashed_length(ctx)
202             struct rhash_context * ctx
203             PROTOTYPE: $
204             CODE:
205 2 100         RETVAL = ctx->msg_size;
206             OUTPUT:
207             RETVAL
208              
209             ##############################################################################
210             # Information functions
211              
212             int
213             count()
214             CODE:
215 1           RETVAL = rhash_count();
216             OUTPUT:
217             RETVAL
218              
219             SV *
220             librhash_version_string()
221             PREINIT:
222             unsigned version;
223             CODE:
224 1           version = rhash_get_version();
225 1           RETVAL = allocate_string_buffer(20);
226 1           sprintf(SvPVX(RETVAL), "%u.%u.%u", (version >> 24) & 255, (version >> 16) & 255, (version >> 8) & 255);
227 1           SvCUR_set(RETVAL, strlen(SvPVX(RETVAL)));
228             OUTPUT:
229             RETVAL
230              
231             int
232             librhash_version()
233             CODE:
234 0 0         RETVAL = rhash_get_version();
235             OUTPUT:
236             RETVAL
237              
238             int
239             is_base32(hash_id)
240             unsigned hash_id
241             PROTOTYPE: $
242             CODE:
243 3           RETVAL = rhash_is_base32(hash_id);
244             OUTPUT:
245             RETVAL
246              
247             int
248             get_digest_size(hash_id)
249             unsigned hash_id
250             PROTOTYPE: $
251             CODE:
252 1           RETVAL = rhash_get_digest_size(hash_id);
253             OUTPUT:
254             RETVAL
255              
256             int
257             get_hash_length(hash_id)
258             unsigned hash_id
259             PROTOTYPE: $
260             CODE:
261 1           RETVAL = rhash_get_hash_length(hash_id);
262             OUTPUT:
263             RETVAL
264              
265             const char *
266             get_name(hash_id)
267             unsigned hash_id
268             PROTOTYPE: $
269             CODE:
270 1           RETVAL = rhash_get_name(hash_id);
271             OUTPUT:
272             RETVAL
273              
274             ##############################################################################
275             # Hash printing functions
276              
277             ##############################################################################
278             # Hash conversion functions
279              
280             SV *
281             raw2hex(bytes)
282             PROTOTYPE: $
283             PREINIT:
284             STRLEN size;
285             INPUT:
286             unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
287             CODE:
288 2           RETVAL = allocate_string_buffer(size * 2);
289 2           rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_HEX);
290             OUTPUT:
291             RETVAL
292              
293             SV *
294             raw2base32(bytes)
295             PROTOTYPE: $
296             PREINIT:
297             STRLEN size;
298             INPUT:
299             unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
300             CODE:
301 1           RETVAL = allocate_string_buffer(BASE32_LENGTH(size));
302 1           rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_BASE32);
303             OUTPUT:
304             RETVAL
305              
306             SV *
307             raw2base64(bytes)
308             PROTOTYPE: $
309             PREINIT:
310             STRLEN size;
311             INPUT:
312             unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
313             CODE:
314 1           RETVAL = allocate_string_buffer(BASE64_LENGTH(size));
315 1           rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_BASE64);
316             OUTPUT:
317             RETVAL
318              
319             ##############################################################################
320             # BTIH / BitTorrent support functions
321              
322             void
323             rhash_bt_add_filename(ctx, filename, filesize)
324             struct rhash_context * ctx
325             char * filename
326             ulonglong filesize
327             PROTOTYPE: $$$
328             CODE:
329 0           rhash_torrent_add_file(ctx, filename, filesize);
330              
331             void
332             rhash_bt_set_piece_length(ctx, piece_length)
333             struct rhash_context * ctx
334             unsigned piece_length
335             PROTOTYPE: $$
336             CODE:
337 0           rhash_torrent_set_piece_length(ctx, piece_length);
338              
339             void
340             rhash_bt_set_private(ctx)
341             struct rhash_context * ctx
342             PROTOTYPE: $
343             CODE:
344 0           rhash_torrent_set_options(ctx, RHASH_TORRENT_OPT_PRIVATE);
345              
346             SV *
347             rhash_bt_get_torrent_text(ctx)
348             struct rhash_context * ctx
349             PROTOTYPE: $
350             PREINIT:
351             const rhash_str* text;
352             CODE:
353 0           text = rhash_torrent_generate_content(ctx);
354 0 0         if(!text) {
355 0           XSRETURN_UNDEF;
356             }
357 0           RETVAL = newSVpv(text->str, text->length);
358             OUTPUT:
359             RETVAL