File Coverage

Rhash.xs
Criterion Covered Total %
statement 37 55 67.2
branch 15 30 50.0
condition n/a
subroutine n/a
pod n/a
total 52 85 61.1


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