File Coverage

Pepper.xs
Criterion Covered Total %
statement 2 185 1.0
branch 2 138 1.4
condition n/a
subroutine n/a
pod n/a
total 4 323 1.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              
6             #include "ppport.h"
7              
8             /* Include Pepper library headers */
9             #include "peppertypes.h"
10             #include "pepperenums.h"
11             #include "peppererrors.h"
12             #include "pepper.h"
13              
14             /* Callback support structure */
15             typedef struct {
16             SV* callback_cv; /* Perl callback coderef */
17             SV* userdata; /* Perl user data */
18             } PepperCallbackData;
19              
20             /* Callback wrapper function that gets called by C library */
21             void CALLING_CONVENTION
22 0           pepper_callback_wrapper(
23             PEPCallbackEvent eEvent,
24             PEPCallbackOption eOption,
25             PEPHandle hInstance,
26             PEPHandle hOutputOptions,
27             PEPHandle hInputOptions,
28             void* pUserData
29             ) {
30             dTHX; /* Get thread context */
31 0           dSP; /* Stack pointer declaration */
32              
33 0           PepperCallbackData* callbackData = (PepperCallbackData*)pUserData;
34 0 0         if(!callbackData || !callbackData->callback_cv) {
    0          
35 0           return;
36             }
37              
38 0           ENTER;
39 0           SAVETMPS;
40              
41 0 0         PUSHMARK(SP);
42              
43             /* Push arguments onto Perl stack */
44 0 0         mXPUSHi(eEvent);
45 0 0         mXPUSHi(eOption);
46              
47             /* Convert handles to Perl SVs */
48 0 0         if(hInstance != pepInvalidHandle) {
49 0           SV* handle_sv = sv_2mortal(newSViv(PTR2IV(hInstance)));
50 0 0         XPUSHs(handle_sv);
51             } else {
52 0 0         XPUSHs(&PL_sv_undef);
53             }
54              
55 0 0         if(hOutputOptions != pepInvalidHandle) {
56 0           SV* handle_sv = sv_2mortal(newSViv(PTR2IV(hOutputOptions)));
57 0 0         XPUSHs(handle_sv);
58             } else {
59 0 0         XPUSHs(&PL_sv_undef);
60             }
61              
62 0 0         if(hInputOptions != pepInvalidHandle) {
63 0           SV* handle_sv = sv_2mortal(newSViv(PTR2IV(hInputOptions)));
64 0 0         XPUSHs(handle_sv);
65             } else {
66 0 0         XPUSHs(&PL_sv_undef);
67             }
68              
69             /* Push user data */
70 0 0         if(callbackData->userdata) {
71 0 0         XPUSHs(callbackData->userdata);
72             } else {
73 0 0         XPUSHs(&PL_sv_undef);
74             }
75              
76 0           PUTBACK;
77              
78             /* Call the Perl callback */
79 0           call_sv(callbackData->callback_cv, G_DISCARD | G_EVAL);
80              
81 0 0         FREETMPS;
82 0           LEAVE;
83             }
84              
85             MODULE = Lib::Pepper PACKAGE = Lib::Pepper
86              
87             PROTOTYPES: ENABLE
88              
89             ###############################################################################
90             # LIBRARY MANAGEMENT
91             ###############################################################################
92              
93             void
94             pepInitialize(pepcoreLibraryPath, configStructure, licenseStructure)
95             const char* pepcoreLibraryPath
96             SV* configStructure
97             SV* licenseStructure
98             PPCODE:
99             {
100             PEPFunctionResult result;
101 0           PEPHandle terminalTypeOptionList = pepInvalidHandle;
102 0 0         const char* configStr = (SvOK(configStructure) && SvPOK(configStructure)) ? SvPV_nolen(configStructure) : NULL;
    0          
103 0 0         const char* licenseStr = (SvOK(licenseStructure) && SvPOK(licenseStructure)) ? SvPV_nolen(licenseStructure) : NULL;
    0          
104              
105 0           result = pepInitialize(pepcoreLibraryPath, configStr, licenseStr, NULL, NULL, &terminalTypeOptionList);
106              
107 0 0         EXTEND(SP, 2);
108 0           mPUSHi(result);
109 0 0         if(terminalTypeOptionList != pepInvalidHandle) {
110 0           mPUSHi(PTR2IV(terminalTypeOptionList));
111             } else {
112 0           PUSHs(&PL_sv_undef);
113             }
114             }
115              
116             PEPFunctionResult
117             pepFinalize()
118              
119             void
120             pepVersion()
121             PPCODE:
122             {
123             PEPFunctionResult result;
124 0           int64_t major = 0, minor = 0, service = 0, revision = 0, api = 0;
125 0           int64_t osArch = 0, releaseType = 0, configType = 0;
126              
127 0           result = pepVersion(&major, &minor, &service, &revision, &api, &osArch, &releaseType, &configType);
128              
129 0 0         EXTEND(SP, 9);
130 0           mPUSHi(result);
131 0           mPUSHi(major);
132 0           mPUSHi(minor);
133 0           mPUSHi(service);
134 0           mPUSHi(revision);
135 0           mPUSHi(api);
136 0           mPUSHi(osArch);
137 0           mPUSHi(releaseType);
138 0           mPUSHi(configType);
139             }
140              
141             ###############################################################################
142             # INSTANCE MANAGEMENT
143             ###############################################################################
144              
145             void
146             pepCreateInstance(terminalType, instanceId)
147             int64_t terminalType
148             int64_t instanceId
149             PPCODE:
150             {
151             PEPFunctionResult result;
152 0           PEPHandle instance = pepInvalidHandle;
153              
154 0           result = pepCreateInstance(terminalType, instanceId, &instance);
155              
156 0 0         EXTEND(SP, 2);
157 0           mPUSHi(result);
158 0 0         if(instance != pepInvalidHandle) {
159 0           mPUSHi(PTR2IV(instance));
160             } else {
161 0           PUSHs(&PL_sv_undef);
162             }
163             }
164              
165             PEPFunctionResult
166             pepFreeInstance(hInstance)
167             PEPHandle hInstance
168              
169             ###############################################################################
170             # CONFIGURATION
171             ###############################################################################
172              
173             void
174             pepConfigureWithCallback(hInstance, hInputOptions, callback_cv, userdata_sv)
175             PEPHandle hInstance
176             PEPHandle hInputOptions
177             SV* callback_cv
178             SV* userdata_sv
179             PPCODE:
180             {
181             PEPFunctionResult result;
182 0           PEPHandle outputOptions = pepInvalidHandle;
183 0           PepperCallbackData* callbackData = NULL;
184              
185             /* Validate callback */
186 0 0         if(!SvROK(callback_cv) || SvTYPE(SvRV(callback_cv)) != SVt_PVCV) {
    0          
187 0           croak("pepConfigureWithCallback: callback must be a code reference");
188             }
189              
190             /* Allocate callback data structure */
191 0           callbackData = (PepperCallbackData*)malloc(sizeof(PepperCallbackData));
192 0 0         if(!callbackData) {
193 0           croak("pepConfigureWithCallback: out of memory");
194             }
195              
196             /* Store callback and user data with reference counting */
197 0           callbackData->callback_cv = SvREFCNT_inc(callback_cv);
198 0 0         callbackData->userdata = SvOK(userdata_sv) ? SvREFCNT_inc(userdata_sv) : NULL;
199              
200             /* Call pepConfigure with our wrapper */
201 0           result = pepConfigure(hInstance, pepper_callback_wrapper, callbackData, hInputOptions, &outputOptions);
202              
203             /* Note: callbackData memory management needs improvement - currently leaking */
204              
205 0 0         EXTEND(SP, 2);
206 0           mPUSHi(result);
207 0 0         if(outputOptions != pepInvalidHandle) {
208 0           mPUSHi(PTR2IV(outputOptions));
209             } else {
210 0           PUSHs(&PL_sv_undef);
211             }
212             }
213              
214             ###############################################################################
215             # OPERATION WORKFLOW (4-step process)
216             ###############################################################################
217              
218             void
219             pepPrepareOperation(hInstance, eOperation, hInputOptions)
220             PEPHandle hInstance
221             PEPOperation eOperation
222             PEPHandle hInputOptions
223             PPCODE:
224             {
225             PEPFunctionResult result;
226 0           PEPHandle operation = pepInvalidHandle;
227 0           PEPHandle outputOptions = pepInvalidHandle;
228              
229 0           result = pepPrepareOperation(hInstance, eOperation, hInputOptions, &operation, &outputOptions);
230              
231 0 0         EXTEND(SP, 3);
232 0           mPUSHi(result);
233 0 0         if(operation != pepInvalidHandle) {
234 0           mPUSHi(PTR2IV(operation));
235             } else {
236 0           PUSHs(&PL_sv_undef);
237             }
238 0 0         if(outputOptions != pepInvalidHandle) {
239 0           mPUSHi(PTR2IV(outputOptions));
240             } else {
241 0           PUSHs(&PL_sv_undef);
242             }
243             }
244              
245             void
246             pepStartOperation(hInstance, eOperation, hInputOptions)
247             PEPHandle hInstance
248             PEPOperation eOperation
249             PEPHandle hInputOptions
250             PPCODE:
251             {
252             PEPFunctionResult result;
253 0           PEPHandle operation = pepInvalidHandle;
254 0           PEPHandle outputOptions = pepInvalidHandle;
255              
256 0           result = pepStartOperation(hInstance, eOperation, hInputOptions, &operation, &outputOptions);
257              
258 0 0         EXTEND(SP, 3);
259 0           mPUSHi(result);
260 0 0         if(operation != pepInvalidHandle) {
261 0           mPUSHi(PTR2IV(operation));
262             } else {
263 0           PUSHs(&PL_sv_undef);
264             }
265 0 0         if(outputOptions != pepInvalidHandle) {
266 0           mPUSHi(PTR2IV(outputOptions));
267             } else {
268 0           PUSHs(&PL_sv_undef);
269             }
270             }
271              
272             void
273             pepExecuteOperation(hInstance, eOperation, hInputOptions)
274             PEPHandle hInstance
275             PEPOperation eOperation
276             PEPHandle hInputOptions
277             PPCODE:
278             {
279             PEPFunctionResult result;
280 0           PEPHandle operation = pepInvalidHandle;
281 0           PEPHandle outputOptions = pepInvalidHandle;
282              
283 0           result = pepExecuteOperation(hInstance, eOperation, hInputOptions, &operation, &outputOptions);
284              
285 0 0         EXTEND(SP, 3);
286 0           mPUSHi(result);
287 0 0         if(operation != pepInvalidHandle) {
288 0           mPUSHi(PTR2IV(operation));
289             } else {
290 0           PUSHs(&PL_sv_undef);
291             }
292 0 0         if(outputOptions != pepInvalidHandle) {
293 0           mPUSHi(PTR2IV(outputOptions));
294             } else {
295 0           PUSHs(&PL_sv_undef);
296             }
297             }
298              
299             void
300             pepFinalizeOperation(hInstance, eOperation, hInputOptions)
301             PEPHandle hInstance
302             PEPOperation eOperation
303             PEPHandle hInputOptions
304             PPCODE:
305             {
306             PEPFunctionResult result;
307 0           PEPHandle operation = pepInvalidHandle;
308 0           PEPHandle outputOptions = pepInvalidHandle;
309              
310 0           result = pepFinalizeOperation(hInstance, eOperation, hInputOptions, &operation, &outputOptions);
311              
312 0 0         EXTEND(SP, 3);
313 0           mPUSHi(result);
314 0 0         if(operation != pepInvalidHandle) {
315 0           mPUSHi(PTR2IV(operation));
316             } else {
317 0           PUSHs(&PL_sv_undef);
318             }
319 0 0         if(outputOptions != pepInvalidHandle) {
320 0           mPUSHi(PTR2IV(outputOptions));
321             } else {
322 0           PUSHs(&PL_sv_undef);
323             }
324             }
325              
326             ###############################################################################
327             # OPERATION STATUS
328             ###############################################################################
329              
330             void
331             pepOperationStatus(hInstance, hOperation, bWaitForCompletion)
332             PEPHandle hInstance
333             PEPHandle hOperation
334             PEPBool bWaitForCompletion
335             PPCODE:
336             {
337             PEPFunctionResult result;
338 0           PEPBool status = pepFalse;
339              
340 0           result = pepOperationStatus(hInstance, hOperation, bWaitForCompletion, &status);
341              
342 0 0         EXTEND(SP, 2);
343 0           mPUSHi(result);
344 0           mPUSHi(status);
345             }
346              
347             ###############################################################################
348             # UTILITY AND AUXILIARY
349             ###############################################################################
350              
351             void
352             pepUtility(hInstance, hInputOptions)
353             PEPHandle hInstance
354             PEPHandle hInputOptions
355             PPCODE:
356             {
357             PEPFunctionResult result;
358 0           PEPHandle outputOptions = pepInvalidHandle;
359              
360 0           result = pepUtility(hInstance, hInputOptions, &outputOptions);
361              
362 0 0         EXTEND(SP, 2);
363 0           mPUSHi(result);
364 0 0         if(outputOptions != pepInvalidHandle) {
365 0           mPUSHi(PTR2IV(outputOptions));
366             } else {
367 0           PUSHs(&PL_sv_undef);
368             }
369             }
370              
371             void
372             pepAuxiliary(hInstance, hInputOptions)
373             PEPHandle hInstance
374             PEPHandle hInputOptions
375             PPCODE:
376             {
377             PEPFunctionResult result;
378 0           PEPHandle operation = pepInvalidHandle;
379 0           PEPHandle outputOptions = pepInvalidHandle;
380              
381 0           result = pepAuxiliary(hInstance, hInputOptions, &operation, &outputOptions);
382              
383 0 0         EXTEND(SP, 3);
384 0           mPUSHi(result);
385 0 0         if(operation != pepInvalidHandle) {
386 0           mPUSHi(PTR2IV(operation));
387             } else {
388 0           PUSHs(&PL_sv_undef);
389             }
390 0 0         if(outputOptions != pepInvalidHandle) {
391 0           mPUSHi(PTR2IV(outputOptions));
392             } else {
393 0           PUSHs(&PL_sv_undef);
394             }
395             }
396              
397             ###############################################################################
398             # LICENSE
399             ###############################################################################
400              
401             void
402             pepDownloadLicense(hInputOptions)
403             PEPHandle hInputOptions
404             PPCODE:
405             {
406             PEPFunctionResult result;
407 0           PEPHandle outputOptions = pepInvalidHandle;
408              
409 0           result = pepDownloadLicense(hInputOptions, &outputOptions);
410              
411 0 0         EXTEND(SP, 2);
412 0           mPUSHi(result);
413 0 0         if(outputOptions != pepInvalidHandle) {
414 0           mPUSHi(PTR2IV(outputOptions));
415             } else {
416 0           PUSHs(&PL_sv_undef);
417             }
418             }
419              
420             ###############################################################################
421             # OPTION LIST MANAGEMENT
422             ###############################################################################
423              
424             void
425             pepOptionListCreate()
426             PPCODE:
427             {
428             PEPFunctionResult result;
429 0           PEPHandle list = pepInvalidHandle;
430              
431 0           result = pepOptionListCreate(&list);
432              
433 0 0         EXTEND(SP, 2);
434 0           mPUSHi(result);
435 0 0         if(list != pepInvalidHandle) {
436 0           mPUSHi(PTR2IV(list));
437             } else {
438 0           PUSHs(&PL_sv_undef);
439             }
440             }
441              
442             void
443             pepOptionListGetStringElement(hOptionList, pKey)
444             PEPHandle hOptionList
445             const char* pKey
446             PPCODE:
447             {
448             PEPFunctionResult result;
449 0           const char* value = NULL;
450              
451 0           result = pepOptionListGetStringElement(hOptionList, pKey, &value);
452              
453 0 0         EXTEND(SP, 2);
454 0           mPUSHi(result);
455 0 0         if(result >= pepFunctionResult_Success && value) {
    0          
456 0           mPUSHp(value, strlen(value));
457             } else {
458 0           PUSHs(&PL_sv_undef);
459             }
460             }
461              
462             void
463             pepOptionListGetIntElement(hOptionList, pKey)
464             PEPHandle hOptionList
465             const char* pKey
466             PPCODE:
467             {
468             PEPFunctionResult result;
469 0           int64_t value = 0;
470              
471 0           result = pepOptionListGetIntElement(hOptionList, pKey, &value);
472              
473 0 0         EXTEND(SP, 2);
474 0           mPUSHi(result);
475 0 0         if(result >= pepFunctionResult_Success) {
476 0           mPUSHi(value);
477             } else {
478 0           PUSHs(&PL_sv_undef);
479             }
480             }
481              
482             void
483             pepOptionListGetChildOptionListElement(hOptionList, pKey)
484             PEPHandle hOptionList
485             const char* pKey
486             PPCODE:
487             {
488             PEPFunctionResult result;
489 0           PEPHandle childHandle = pepInvalidHandle;
490              
491 0           result = pepOptionListGetChildOptionListElement(hOptionList, pKey, &childHandle);
492              
493 0 0         EXTEND(SP, 2);
494 0           mPUSHi(result);
495 0 0         if(result >= pepFunctionResult_Success && childHandle != pepInvalidHandle) {
    0          
496 0           mPUSHi(PTR2IV(childHandle));
497             } else {
498 0           PUSHs(&PL_sv_undef);
499             }
500             }
501              
502             PEPFunctionResult
503             pepOptionListAddStringElement(hOptionList, pKey, pValue)
504             PEPHandle hOptionList
505             const char* pKey
506             const char* pValue
507              
508             PEPFunctionResult
509             pepOptionListAddIntElement(hOptionList, pKey, value)
510             PEPHandle hOptionList
511             const char* pKey
512             int64_t value
513              
514             PEPFunctionResult
515             pepOptionListAddChildOptionListElement(hOptionList, pKey, hChildOptionList)
516             PEPHandle hOptionList
517             const char* pKey
518             PEPHandle hChildOptionList
519              
520             void
521             pepOptionListGetElementList(hOptionList)
522             PEPHandle hOptionList
523             PPCODE:
524             {
525             PEPFunctionResult result;
526 0           const char* elementList = NULL;
527              
528 0           result = pepOptionListGetElementList(hOptionList, &elementList);
529              
530 0 0         EXTEND(SP, 2);
531 0           mPUSHi(result);
532 0 0         if(result >= pepFunctionResult_Success && elementList) {
    0          
533 0           mPUSHp(elementList, strlen(elementList));
534             } else {
535 0           PUSHs(&PL_sv_undef);
536             }
537             }
538              
539             ###############################################################################
540             # HELPER FUNCTIONS
541             ###############################################################################
542              
543             int
544             isValidHandle(handle)
545             PEPHandle handle
546             CODE:
547 2 50         RETVAL = (handle != pepInvalidHandle);
548             OUTPUT:
549             RETVAL
550              
551             int
552             isSuccess(result)
553             PEPFunctionResult result
554             CODE:
555 1 50         RETVAL = (result >= pepFunctionResult_Success);
556             OUTPUT:
557             RETVAL
558              
559             int
560             isFailure(result)
561             PEPFunctionResult result
562             CODE:
563 0 0         RETVAL = (result < pepFunctionResult_Success);
564             OUTPUT:
565             RETVAL
566