1/*
2 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/**
17 * @file picoapi.c
18 *
19 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
20 * All rights reserved.
21 *
22 * History:
23 * - 2009-04-20 -- initial version
24 */
25#include "picodefs.h"
26#include "picoos.h"
27#include "picodbg.h"
28#include "picorsrc.h"
29#include "picoctrl.h"
30#include "picoapi.h"
31#include "picoapid.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/* ****************************************************************************/
38/* System-level API functions                                                 */
39/* ****************************************************************************/
40
41#define MAGIC_MASK 0x5069636F  /* Pico */
42
43#define SET_MAGIC_NUMBER(sys) \
44    (sys)->magic = ((picoos_uint32) (sys)) ^ MAGIC_MASK
45
46#define CHECK_MAGIC_NUMBER(sys) \
47    ((sys)->magic == (((picoos_uint32) (sys)) ^ MAGIC_MASK))
48
49
50
51/* *** Auxiliary routines (may also be called from picoextapi.c) **************/
52
53
54int is_valid_system_handle(pico_System system)
55{
56    return (system != NULL) && CHECK_MAGIC_NUMBER(system);
57}
58
59
60picoos_Common pico_sysGetCommon(pico_System this)
61{
62    if (this != NULL) {
63        return this->common;
64    } else {
65        return NULL;
66    }
67}
68
69
70
71/* *** System initialization and termination functions ************************/
72pico_Status pico_initialize_priv(
73        void *memory,
74        const pico_Uint32 size,
75        pico_Int16 enableMemProt,
76        pico_System *system
77        )
78{
79    pico_Status status = PICO_OK;
80
81    PICODBG_INITIALIZE(PICODBG_LOG_LEVEL_INFO);
82    PICODBG_ENABLE_COLORS(0);
83    /*PICODBG_SET_OUTPUT_FORMAT((PICODBG_SHOW_LEVEL | PICODBG_SHOW_SRCNAME));*/
84
85    if (memory == NULL) {
86        status = PICO_ERR_NULLPTR_ACCESS;
87    } else if (size == 0) {
88        status = PICO_ERR_INVALID_ARGUMENT;
89    } else if (system == NULL) {
90        status = PICO_ERR_NULLPTR_ACCESS;
91    } else {
92        byte_ptr_t rest_mem;
93        picoos_uint32 rest_mem_size;
94        pico_System sys;
95        picoos_MemoryManager sysMM;
96        picoos_ExceptionManager sysEM;
97
98        sys = (pico_System) picoos_raw_malloc(memory, size, sizeof(pico_system_t),
99                &rest_mem, &rest_mem_size);
100        if (sys != NULL) {
101            sysMM = picoos_newMemoryManager(rest_mem, rest_mem_size, enableMemProt ? TRUE : FALSE);
102            if (sysMM != NULL) {
103                sysEM = picoos_newExceptionManager(sysMM);
104                sys->common = picoos_newCommon(sysMM);
105                sys->rm = picorsrc_newResourceManager(sysMM, sys->common);
106                if ((sysEM != NULL) && (sys->common != NULL) && (sys->rm != NULL)) {
107                    sys->common->em = sysEM;
108                    sys->common->mm = sysMM;
109                    sys->engine = NULL;
110
111                    picorsrc_createDefaultResource(sys->rm /*,&defaultResource */);
112
113                    SET_MAGIC_NUMBER(sys);
114                    status = PICO_OK;
115                } else {
116                    status = PICO_EXC_OUT_OF_MEM;
117                }
118            } else {
119                status = PICO_EXC_OUT_OF_MEM;
120            }
121        } else {
122            status = PICO_EXC_OUT_OF_MEM;
123        }
124        *system = sys;
125    }
126
127    if (status != PICO_OK) {
128        if (system != NULL) {
129            *system = NULL;
130        }
131        PICODBG_TERMINATE();
132    }
133
134    return status;
135}
136/**
137 * pico_initialize : initializes the pico system private memory
138 * @param    memory : pointer to a free and already allocated memory area
139 * @param    size : size of the memory area
140 * @param    system : pointer to a pico_System struct
141 * @return  PICO_OK : successful init, !PICO_OK : error on allocating private memory
142 * @callgraph
143 * @callergraph
144*/
145PICO_FUNC pico_initialize(
146        void *memory,
147        const pico_Uint32 size,
148        pico_System *system
149        )
150{
151    return pico_initialize_priv(memory, size, /*enableMemProt*/ FALSE, system);
152}
153
154/**
155 * pico_terminate : deallocates the pico system private memory
156 * @param    system : pointer to a pico_System struct
157 * @return  PICO_OK : successful de-init, !PICO_OK : error on de-allocating private memory
158 * @callgraph
159 * @callergraph
160*/
161PICO_FUNC pico_terminate(
162        pico_System *system
163        )
164{
165    pico_Status status = PICO_OK;
166
167    if ((system == NULL) || !is_valid_system_handle(*system)) {
168        status = PICO_ERR_INVALID_HANDLE;
169    } else {
170        pico_System sys = *system;
171
172        /* close engine(s) */
173        picoctrl_disposeEngine(sys->common->mm, sys->rm, &sys->engine);
174
175        /* close all resources */
176        picorsrc_disposeResourceManager(sys->common->mm, &sys->rm);
177
178        sys->magic ^= 0xFFFEFDFC;
179        *system = NULL;
180    }
181
182    PICODBG_TERMINATE();
183
184    return status;
185}
186
187
188
189/* *** System status and error/warning message retrieval function *************/
190
191/**
192 * pico_getSystemStatusMessage : Returns a description of the system status or errors
193 * @param    system : pointer to a pico_System struct
194 * @param    errCode : pico_System error code
195 * @param    outMessage : memory area where to return a string
196 * @return  PICO_OK : successful
197 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
198 * @callgraph
199 * @callergraph
200*/
201PICO_FUNC pico_getSystemStatusMessage(
202        pico_System system,
203        pico_Status errCode,
204        pico_Retstring outMessage
205        )
206{
207    pico_Status status = PICO_OK;
208
209    if (!is_valid_system_handle(system)) {
210        status = PICO_ERR_INVALID_HANDLE;
211        if (outMessage != NULL) {
212            picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
213        }
214    } else if (outMessage == NULL) {
215        status = PICO_ERR_NULLPTR_ACCESS;
216    } else {
217        if (picoos_emGetExceptionCode(system->common->em) == PICO_OK) {
218            if (errCode == PICO_OK) {
219                picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "system ok", PICO_RETSTRINGSIZE);
220            } else {
221                /* exceptionManager was not informed yet; produce default message */
222                picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
223            }
224        } else {
225            picoos_emGetExceptionMessage(system->common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
226        }
227    }
228
229    return status;
230}
231
232/**
233 * pico_getSystemStatusMessage : Returns the number of warnings
234 * @param    system : pointer to a pico_System struct
235 * @param    *outNrOfWarnings : pointer to location to receive number of warnings
236 * @return  PICO_OK : successful
237 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
238 * @callgraph
239 * @callergraph
240*/
241PICO_FUNC pico_getNrSystemWarnings(
242        pico_System system,
243        pico_Int32 *outNrOfWarnings
244        )
245{
246    pico_Status status = PICO_OK;
247
248    if (!is_valid_system_handle(system)) {
249        status = PICO_ERR_INVALID_HANDLE;
250        if (outNrOfWarnings != NULL) {
251            *outNrOfWarnings = 0;
252        }
253    } else if (outNrOfWarnings == NULL) {
254        status = PICO_ERR_NULLPTR_ACCESS;
255    } else {
256        *outNrOfWarnings = picoos_emGetNumOfWarnings(system->common->em);
257    }
258
259    return status;
260}
261
262/**
263 * pico_getSystemWarning : Returns a description of a warning
264 * @param    system : pointer to a pico_System struct
265 * @param    warningIndex : warning index
266 * @param    *outCode : pointer to receive the warning code
267 * @param    outMessage : pointer to receive the output message
268 * @return  PICO_OK : successful
269 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
270 * @callgraph
271 * @callergraph
272*/
273PICO_FUNC pico_getSystemWarning(
274        pico_System system,
275        const pico_Int32 warningIndex,
276        pico_Status *outCode,
277        pico_Retstring outMessage
278        )
279{
280    pico_Status status = PICO_OK;
281
282    if (!is_valid_system_handle(system)) {
283        status = PICO_ERR_INVALID_HANDLE;
284        if (outMessage != NULL) {
285            picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
286        }
287    } else if (warningIndex < 0) {
288        status = PICO_ERR_INDEX_OUT_OF_RANGE;
289    } else if ((outCode == NULL) || (outMessage == NULL)) {
290        status = PICO_ERR_NULLPTR_ACCESS;
291    } else {
292        *outCode = picoos_emGetWarningCode(system->common->em, warningIndex);
293        picoos_emGetWarningMessage(system->common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
294    }
295
296    return status;
297}
298
299
300
301/* *** Resource loading and unloading functions *******************************/
302
303/**
304 * pico_loadResource : Loads a resource file into the Pico system
305 * @param    system : pointer to a pico_System struct
306 * @param    *lingwareFileName : lingware resource file name
307 * @param    *outLingware : pointer to receive the loaded lingware resource memory area address
308 * @return  PICO_OK : successful
309 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
310 * @callgraph
311 * @callergraph
312*/
313PICO_FUNC pico_loadResource(
314        pico_System system,
315        const pico_Char *lingwareFileName,
316        pico_Resource *outLingware
317        )
318{
319    pico_Status status = PICO_OK;
320
321    if (!is_valid_system_handle(system)) {
322        status = PICO_ERR_INVALID_HANDLE;
323    } else if ((lingwareFileName == NULL) || (outLingware == NULL)) {
324        status = PICO_ERR_NULLPTR_ACCESS;
325    } else {
326        PICODBG_DEBUG(("memory usage before resource loading"));
327        picoos_showMemUsage(system->common->mm, FALSE, TRUE);
328        picoos_emReset(system->common->em);
329        status = picorsrc_loadResource(system->rm, (picoos_char *) lingwareFileName, (picorsrc_Resource *) outLingware);
330        PICODBG_DEBUG(("memory used to load resource %s", lingwareFileName));
331        picoos_showMemUsage(system->common->mm, TRUE, FALSE);
332    }
333
334    return status;
335}
336
337/**
338 * pico_unloadResource : unLoads a resource file from the Pico system
339 * @param    system : pointer to a pico_System struct
340 * @param    *inoutLingware : pointer to the loaded lingware resource memory area address
341 * @return  PICO_OK : successful
342 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
343 * @callgraph
344 * @callergraph
345*/
346PICO_FUNC pico_unloadResource(
347        pico_System system,
348        pico_Resource *inoutLingware
349        )
350{
351    pico_Status status = PICO_OK;
352
353    if (!is_valid_system_handle(system)) {
354        status = PICO_ERR_INVALID_HANDLE;
355    } else if (inoutLingware == NULL) {
356        status = PICO_ERR_NULLPTR_ACCESS;
357    } else if (!picoctrl_isValidResourceHandle(*((picorsrc_Resource *) inoutLingware))) {
358        status = PICO_ERR_INVALID_HANDLE;
359    } else {
360        PICODBG_DEBUG(("memory usage before resource unloading"));
361        picoos_showMemUsage(system->common->mm, FALSE, TRUE);
362        picoos_emReset(system->common->em);
363        status = picorsrc_unloadResource(system->rm, (picorsrc_Resource *) inoutLingware);
364        PICODBG_DEBUG(("memory released by resource unloading"));
365        picoos_showMemUsage(system->common->mm, TRUE, FALSE);
366    }
367
368    return status;
369}
370
371/* *** Resource inspection functions *******************************/
372/**
373 * pico_getResourceName : Gets a resource name
374 * @param    system : pointer to a pico_System struct
375 * @param    resource : pointer to the loaded resource memory area address
376 * @param    outName : pointer to the area to receuive the resource name
377 * @return  PICO_OK : successful
378 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
379 * @callgraph
380 * @callergraph
381*/
382PICO_FUNC pico_getResourceName(
383        pico_System system,
384        pico_Resource resource,
385        pico_Retstring outName) {
386
387    if (!is_valid_system_handle(system)) {
388        return PICO_ERR_INVALID_HANDLE;
389    } else if (NULL == outName) {
390        return PICO_ERR_NULLPTR_ACCESS;
391    }
392    return picorsrc_rsrcGetName((picorsrc_Resource)resource, (picoos_char *) outName, PICO_RETSTRINGSIZE);
393}
394
395
396/* *** Voice definition functions *********************************************/
397
398/**
399 * pico_createVoiceDefinition : Creates a voice definition
400 * @param    system : pointer to a pico_System struct
401 * @param    *voiceName : pointer to the area to receive the voice definition
402 * @return  PICO_OK : successful
403 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
404 * @callgraph
405 * @callergraph
406*/
407PICO_FUNC pico_createVoiceDefinition(
408        pico_System system,
409        const pico_Char *voiceName
410        )
411{
412    pico_Status status = PICO_OK;
413
414    if (!is_valid_system_handle(system)) {
415        status = PICO_ERR_INVALID_HANDLE;
416    } else if (voiceName == NULL) {
417        status = PICO_ERR_NULLPTR_ACCESS;
418    } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
419        status = PICO_ERR_INVALID_ARGUMENT;
420    } else {
421        picoos_emReset(system->common->em);
422        status = picorsrc_createVoiceDefinition(system->rm, (picoos_char *) voiceName);
423    }
424
425    return status;
426}
427
428/**
429 * pico_addResourceToVoiceDefinition : Adds a mapping pair to a voice definition
430 * @param    system : pointer to a pico_System struct
431 * @param    *voiceName : pointer to the area containing the voice definition
432 * @param    *resourceName : pointer to the area containing the resource name
433 * @return  PICO_OK : successful
434 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
435 * @callgraph
436 * @callergraph
437*/
438PICO_FUNC pico_addResourceToVoiceDefinition(
439        pico_System system,
440        const pico_Char *voiceName,
441        const pico_Char *resourceName
442        )
443{
444    pico_Status status = PICO_OK;
445
446    if (!is_valid_system_handle(system)) {
447        status = PICO_ERR_INVALID_HANDLE;
448    } else if (voiceName == NULL) {
449        status = PICO_ERR_NULLPTR_ACCESS;
450    } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
451        status = PICO_ERR_INVALID_ARGUMENT;
452    } else if (resourceName == NULL) {
453        status = PICO_ERR_NULLPTR_ACCESS;
454    } else if (picoos_strlen((picoos_char *) resourceName) == 0) {
455        status = PICO_ERR_INVALID_ARGUMENT;
456    } else {
457        picoos_emReset(system->common->em);
458        status = picorsrc_addResourceToVoiceDefinition(system->rm, (picoos_char *) voiceName, (picoos_char *) resourceName);
459    }
460
461    return status;
462}
463
464/**
465 * pico_releaseVoiceDefinition : Releases a voice definition
466 * @param    system : pointer to a pico_System struct
467 * @param    *voiceName : pointer to the area containing the voice definition
468 * @return  PICO_OK : successful
469 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
470 * @callgraph
471 * @callergraph
472*/
473PICO_FUNC pico_releaseVoiceDefinition(
474        pico_System system,
475        const pico_Char *voiceName
476        )
477{
478    pico_Status status = PICO_OK;
479
480    if (!is_valid_system_handle(system)) {
481        status = PICO_ERR_INVALID_HANDLE;
482    } else if (voiceName == NULL) {
483        status = PICO_ERR_NULLPTR_ACCESS;
484    } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
485        status = PICO_ERR_INVALID_ARGUMENT;
486    } else {
487        picoos_emReset(system->common->em);
488        status = picorsrc_releaseVoiceDefinition(system->rm, (picoos_char *) voiceName);
489    }
490
491    return status;
492}
493
494
495
496/* *** Engine creation and deletion functions *********************************/
497
498/**
499 * pico_newEngine : Creates and initializes a new Pico engine
500 * @param    system : pointer to a pico_System struct
501 * @param    *voiceName : pointer to the area containing the voice definition
502 * @param    *outEngine : pointer to the Pico engine handle
503 * @return  PICO_OK : successful
504 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
505 * @callgraph
506 * @callergraph
507*/
508PICO_FUNC pico_newEngine(
509        pico_System system,
510        const pico_Char *voiceName,
511        pico_Engine *outEngine
512        )
513{
514    pico_Status status = PICO_OK;
515
516    PICODBG_DEBUG(("creating engine for voice '%s'", (picoos_char *) voiceName));
517
518    if (!is_valid_system_handle(system)) {
519        status = PICO_ERR_INVALID_HANDLE;
520    } else if (voiceName == NULL) {
521        status = PICO_ERR_NULLPTR_ACCESS;
522    } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
523        status = PICO_ERR_INVALID_ARGUMENT;
524    } else if (outEngine == NULL) {
525        status = PICO_ERR_NULLPTR_ACCESS;
526    } else {
527        picoos_emReset(system->common->em);
528        if (system->engine == NULL) {
529            *outEngine = (pico_Engine) picoctrl_newEngine(system->common->mm, system->rm, voiceName);
530            if (*outEngine != NULL) {
531                system->engine = (picoctrl_Engine) *outEngine;
532            } else {
533                status = picoos_emRaiseException(system->common->em, PICO_EXC_OUT_OF_MEM,
534                            (picoos_char *) "out of memory creating new engine", NULL);
535            }
536        } else {
537            status = picoos_emRaiseException(system->common->em, PICO_EXC_MAX_NUM_EXCEED,
538                        NULL, (picoos_char *) "no more than %i engines", 1);
539        }
540    }
541
542    return status;
543}
544
545/**
546 * pico_disposeEngine : Disposes a Pico engine
547 * @param    system : pointer to a pico_System struct
548 * @param    *inoutEngine : pointer to the Pico engine handle
549 * @return  PICO_OK : successful
550 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
551 * @callgraph
552 * @callergraph
553*/
554PICO_FUNC pico_disposeEngine(
555        pico_System system,
556        pico_Engine *inoutEngine
557        )
558{
559    pico_Status status = PICO_OK;
560
561    if (!is_valid_system_handle(system)) {
562        status = PICO_ERR_INVALID_HANDLE;
563    } else if (inoutEngine == NULL) {
564        status = PICO_ERR_NULLPTR_ACCESS;
565    } else if (!picoctrl_isValidEngineHandle(*((picoctrl_Engine *) inoutEngine))) {
566        status = PICO_ERR_INVALID_HANDLE;
567    } else {
568        picoos_emReset(system->common->em);
569        picoctrl_disposeEngine(system->common->mm, system->rm, (picoctrl_Engine *) inoutEngine);
570        system->engine = NULL;
571        status = picoos_emGetExceptionCode(system->common->em);
572    }
573
574    return status;
575}
576
577
578
579/* ****************************************************************************/
580/* Engine-level API functions                                                 */
581/* ****************************************************************************/
582
583/**
584 * pico_putTextUtf8 : Puts UTF8 text into Pico text input buffer
585 * @param    engine : pointer to a Pico engine handle
586 * @param    *text : pointer to the text buffer
587 * @param    textSize : text buffer size
588 * @param    *bytesPut : pointer to variable to receive the number of bytes put
589 * @return  PICO_OK : successful
590 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
591 * @callgraph
592 * @callergraph
593 */
594PICO_FUNC pico_putTextUtf8(
595        pico_Engine engine,
596        const pico_Char *text,
597        const pico_Int16 textSize,
598        pico_Int16 *bytesPut)
599{
600    pico_Status status = PICO_OK;
601
602    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
603        status = PICO_ERR_INVALID_HANDLE;
604    } else if (text == NULL) {
605        status = PICO_ERR_NULLPTR_ACCESS;
606    } else if (textSize < 0) {
607        status = PICO_ERR_INVALID_ARGUMENT;
608    } else if (bytesPut == NULL) {
609        status = PICO_ERR_NULLPTR_ACCESS;
610    } else {
611        picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
612        status = picoctrl_engFeedText((picoctrl_Engine) engine, (picoos_char *)text, textSize, bytesPut);
613    }
614
615    return status;
616}
617
618/**
619 * pico_getData : Gets speech data from the engine.
620 * @param    engine : pointer to a Pico engine handle
621 * @param    *buffer : pointer to output buffer
622 * @param    bufferSize : out buffer size
623 * @param    *bytesReceived : pointer to a variable to receive the number of bytes received
624 * @param    *outDataType : pointer to a variable to receive the type of buffer received
625 * @return  PICO_OK : successful
626 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
627 * @callgraph
628 * @callergraph
629*/
630PICO_FUNC pico_getData(
631        pico_Engine engine,
632        void *buffer,
633        const pico_Int16 bufferSize,
634        pico_Int16 *bytesReceived,
635        pico_Int16 *outDataType
636        )
637{
638    pico_Status status = PICO_OK;
639
640    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
641        status = PICO_STEP_ERROR;
642    } else if (buffer == NULL) {
643        status = PICO_STEP_ERROR;
644    } else if (bufferSize < 0) {
645        status = PICO_STEP_ERROR;
646    } else if (bytesReceived == NULL) {
647        status = PICO_STEP_ERROR;
648    } else {
649        picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
650        status = picoctrl_engFetchOutputItemBytes((picoctrl_Engine) engine, (picoos_char *)buffer, bufferSize, bytesReceived);
651        if ((status != PICO_STEP_IDLE) && (status != PICO_STEP_BUSY)) {
652            status = PICO_STEP_ERROR;
653        }
654    }
655
656    *outDataType = PICO_DATA_PCM_16BIT;
657    return status;
658}
659
660/**
661 * pico_resetEngine : Resets the engine
662 * @param    engine : pointer to a Pico engine handle
663 * @param resetMode : reset mode; one of PICO_RESET_FULL or PICO_RESET_SOFT
664 * @return  PICO_OK : successful
665 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
666 * @callgraph
667 * @callergraph
668*/
669PICO_FUNC pico_resetEngine(
670        pico_Engine engine,
671        pico_Int32 resetMode)
672{
673    pico_Status status = PICO_OK;
674
675    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
676        status = PICO_ERR_INVALID_HANDLE;
677    } else {
678        picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
679
680        resetMode = (PICO_RESET_SOFT == resetMode) ? PICO_RESET_SOFT : PICO_RESET_FULL;
681
682        status = picoctrl_engReset((picoctrl_Engine) engine, (picoos_int32)resetMode);
683    }
684
685    return status;
686}
687
688/**
689 * pico_getEngineStatusMessage : Returns the engine status or error description
690 * @param    engine : pointer to a Pico engine handle
691 * @param    errCode : error code
692 * @param    outMessage : pointer to a memory area to receive the output message
693 * @return  PICO_OK : successful
694 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
695 * @callgraph
696 * @callergraph
697*/
698PICO_FUNC pico_getEngineStatusMessage(
699        pico_Engine engine,
700        pico_Status errCode,
701        pico_Retstring outMessage
702        )
703{
704    pico_Status status = PICO_OK;
705
706    PICODBG_DEBUG(("got error code %i", errCode));
707
708    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
709        status = PICO_ERR_INVALID_HANDLE;
710        if (outMessage != NULL) {
711            picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
712        }
713    } else if (outMessage == NULL) {
714        status = PICO_ERR_NULLPTR_ACCESS;
715    } else {
716        picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
717        if (picoos_emGetExceptionCode(common->em) == PICO_OK) {
718            if (errCode == PICO_OK) {
719                picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "engine ok", PICO_RETSTRINGSIZE);
720            } else {
721                /* exceptionManager was not informed yet; produce default message */
722                picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
723            }
724        } else {
725            picoos_emGetExceptionMessage(common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
726        }
727    }
728
729    return status;
730}
731
732/**
733 * pico_getNrEngineWarnings : Returns the number of warnings
734 * @param    engine : pointer to a Pico engine handle
735 * @param    *outNrOfWarnings: pointer to a variable to receive the number of warnings
736 * @return  PICO_OK : successful
737 * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
738 * @callgraph
739 * @callergraph
740*/
741PICO_FUNC pico_getNrEngineWarnings(
742        pico_Engine engine,
743        pico_Int32 *outNrOfWarnings
744        )
745{
746    pico_Status status = PICO_OK;
747
748    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
749        status = PICO_ERR_INVALID_HANDLE;
750        if (outNrOfWarnings != NULL) {
751            *outNrOfWarnings = 0;
752        }
753    } else if (outNrOfWarnings == NULL) {
754        status = PICO_ERR_NULLPTR_ACCESS;
755    } else {
756        picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
757        *outNrOfWarnings = picoos_emGetNumOfWarnings(common->em);
758    }
759
760    return status;
761}
762
763/**
764     * pico_getEngineWarning : Returns a description of a warning
765     * @param    engine : pointer to a Pico engine handle
766     * @param    warningIndex : warning index
767     * @param    *outCode: pointer to a variable to receive the warning code
768     * @param    outMessage: pointer to a memory area to receive the warning description
769     * @return  PICO_OK : successful
770     * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
771     * @callgraph
772     * @callergraph
773*/
774PICO_FUNC pico_getEngineWarning(
775        pico_Engine engine,
776        const pico_Int32 warningIndex,
777        pico_Status *outCode,
778        pico_Retstring outMessage
779        )
780{
781    pico_Status status = PICO_OK;
782
783    if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
784        status = PICO_ERR_INVALID_HANDLE;
785        if (outMessage != NULL) {
786            picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
787        }
788    } else if (warningIndex < 0) {
789        status = PICO_ERR_INDEX_OUT_OF_RANGE;
790    } else if ((outCode == NULL) || (outMessage == NULL)) {
791        status = PICO_ERR_NULLPTR_ACCESS;
792    } else {
793        picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
794        *outCode = picoos_emGetWarningCode(common->em, warningIndex);
795        picoos_emGetWarningMessage(common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
796    }
797
798    return status;
799}
800
801#ifdef __cplusplus
802}
803#endif
804
805
806/* end */
807