1b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
2b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License");
5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License.
6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at
7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *     http://www.apache.org/licenses/LICENSE-2.0
9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software
11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS,
12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and
14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License.
15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
16b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
17b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @file picowa.c
18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * word analysis PU - lexicon lookup and POS prediction
20b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
21b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
22b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * All rights reserved.
23b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
24b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * History:
25b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - 2009-04-20 -- initial version
26b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
27b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
28b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
29b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoos.h"
30b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodbg.h"
31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodata.h"
32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picowa.h"
33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoklex.h"
34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picokdt.h"
35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoktab.h"
36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" {
39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0
41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PU waStep states */
45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define WA_STEPSTATE_COLLECT  0
46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define WA_STEPSTATE_PROCESS  1
47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define WA_STEPSTATE_FEED     2
48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*  subobject    : WordAnaUnit
51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  shortcut     : wa
52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  context size : one item
53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct wa_subobj {
55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 procState; /* for next processing step decision */
56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* one item only */
58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 inBuf[PICOWA_MAXITEMSIZE]; /* internal input buffer */
59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 inBufSize; /* actually allocated size */
60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 inLen; /* length of item in inBuf, 0 for empty buf */
61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 outBuf[PICOWA_MAXITEMSIZE]; /* internal output buffer */
63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outBufSize; /* actually allocated size */
64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outLen; /* length of item in outBuf, 0 for empty buf */
65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* lex knowledge base */
67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoklex_Lex lex;
68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* ulex knowledge bases */
70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 numUlex;
71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoklex_Lex ulex[PICOKNOW_MAX_NUM_ULEX];
72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* tab knowledge base */
74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoktab_Pos tabpos;
75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* dtposp knowledge base */
77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picokdt_DtPosP dtposp;
78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} wa_subobj_t;
79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
81e9f72c8954f29f10cb4feb16d328a1b5c1fd7169Jean-Michel Trivistatic pico_status_t waInitialize(register picodata_ProcessingUnit this, picoos_int32 resetMode) {
82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i;
83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoklex_Lex ulex;
84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa_subobj_t * wa;
85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoknow_kb_id_t ulexKbIds[PICOKNOW_MAX_NUM_ULEX] = PICOKNOW_KBID_ULEX_ARRAY;
87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("calling"));
89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return (picodata_step_result_t) picoos_emRaiseException(this->common->em,
92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       PICO_ERR_NULLPTR_ACCESS, NULL, NULL);
93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa = (wa_subobj_t *) this->subObj;
95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->procState = WA_STEPSTATE_COLLECT;
96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->inBufSize = PICOWA_MAXITEMSIZE;
97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->inLen = 0;
98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->outBufSize = PICOWA_MAXITEMSIZE;
99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->outLen = 0;
100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
101e9f72c8954f29f10cb4feb16d328a1b5c1fd7169Jean-Michel Trivi    if (resetMode == PICO_RESET_SOFT) {
1027bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /*following initializations needed only at startup or after a full reset*/
1037bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        return PICO_OK;
1047bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    }
105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* kb lex */
106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->lex = picoklex_getLex(this->voice->kbArray[PICOKNOW_KBID_LEX_MAIN]);
107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (wa->lex == NULL) {
108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("got lex"));
112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* kb ulex[] */
114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->numUlex = 0;
115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0; i<PICOKNOW_MAX_NUM_ULEX; i++) {
116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ulex = picoklex_getLex(this->voice->kbArray[ulexKbIds[i]]);
117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (NULL != ulex) {
118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            wa->ulex[wa->numUlex++] = ulex;
119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("got %i user lexica", wa->numUlex));
122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* kb tabpos */
124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->tabpos =
125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoktab_getPos(this->voice->kbArray[PICOKNOW_KBID_TAB_POS]);
126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (wa->tabpos == NULL) {
127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("got tabpos"));
131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* kb dtposp */
133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa->dtposp = picokdt_getDtPosP(this->voice->kbArray[PICOKNOW_KBID_DT_POSP]);
134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (wa->dtposp == NULL) {
135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("got dtposp"));
139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picodata_step_result_t waStep(register picodata_ProcessingUnit this,
143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                     picoos_int16 mode,
144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                     picoos_uint16 *numBytesOutput);
145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t waTerminate(register picodata_ProcessingUnit this) {
147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t waSubObjDeallocate(register picodata_ProcessingUnit this,
151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        picoos_MemoryManager mm) {
152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &this->subObj);
154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    mm = mm;        /* avoid warning "var not used in this function"*/
156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicodata_ProcessingUnit picowa_newWordAnaUnit(picoos_MemoryManager mm,
161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              picoos_Common common,
162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              picodata_CharBuffer cbIn,
163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              picodata_CharBuffer cbOut,
164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              picorsrc_Voice voice) {
165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picodata_ProcessingUnit this;
166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this = picodata_newProcessingUnit(mm, common, cbIn, cbOut, voice);
168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this == NULL) {
169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->initialize = waInitialize;
173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("set this->step to waStep"));
174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->step = waStep;
175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->terminate = waTerminate;
176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = waSubObjDeallocate;
177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(mm, sizeof(wa_subobj_t));
178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this->subObj == NULL) {
179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *)&this);
180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1847bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    waInitialize(this, PICO_RESET_FULL);
185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ***********************************************************************/
189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*                       WORDGRAPH proc functions                        */
190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ***********************************************************************/
191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 waClassifyPos(register picodata_ProcessingUnit this,
193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  register wa_subobj_t *wa,
194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 *graph,
195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint16 graphlen) {
196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picokdt_classify_result_t dtres;
197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 specchar;
198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i;
199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("graphlen %d", graphlen));
201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* check existence of special char (e.g. hyphen) in graph:
203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       for now, check existence of hard-coded ascii hyphen,
204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       ie. preproc needs to match all UTF8 hyphens to the ascii
205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       hyphen. */
206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*  @todo : consider specifying special char(s) in lingware. */
207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    specchar = FALSE;
208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((i < graphlen) && (!specchar)) {
210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (graph[i++] == '-') {
211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            specchar = TRUE;
212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* construct input vector, which is set in dtposp */
216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!picokdt_dtPosPconstructInVec(wa->dtposp, graph, graphlen, specchar)) {
217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* error constructing invec */
218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_WARN(("problem with invec"));
219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(this->common->em, PICO_WARN_INVECTOR, NULL, NULL);
220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_ITEMINFO1_ERR;
221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* classify */
224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!picokdt_dtPosPclassify(wa->dtposp)) {
225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* error doing classification */
226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_WARN(("problem classifying"));
227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION,
228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                              NULL, NULL);
229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_ITEMINFO1_ERR;
230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* decompose */
233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!picokdt_dtPosPdecomposeOutClass(wa->dtposp, &dtres)) {
234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* error decomposing */
235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_WARN(("problem decomposing"));
236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(this->common->em, PICO_WARN_OUTVECTOR,
237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                              NULL, NULL);
238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_ITEMINFO1_ERR;
239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (dtres.set) {
242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("class %d", dtres.class));
243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return (picoos_uint8)dtres.class;
244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_WARN(("result not set"));
246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION,
247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                              NULL, NULL);
248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_ITEMINFO1_ERR;
249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t waProcessWordgraph(register picodata_ProcessingUnit this,
254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        register wa_subobj_t *wa /*inout*/,
255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        picodata_itemhead_t *head /*inout*/,
256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        const picoos_uint8 *content) {
257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pico_status_t status;
258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoklex_lexl_result_t lexres;
259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 posbuf[PICOKTAB_MAXNRPOS_IN_COMB];
260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i;
261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 foundIndex;
262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool found;
263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("type %c, len %d", head->type, head->len));
266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* do lookup
268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       if no entry found:
269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         do POS prediction:     -> WORDGRAPH(POSes,NA)graph
270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       else:
271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         if incl-phone:
272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen           N entries possible  -> WORDINDEX(POSes,NA)POS1|ind1...POSN|indN
273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen           (N in {1,...,PICOKLEX_MAX_NRRES}, now up to 4)
274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         else:
275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen           no phone, one entry  -> WORDGRAPH(POS,NA)graph
276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    */
277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    found = FALSE;
279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (!found && (i < wa->numUlex)) {
281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        found = picoklex_lexLookup(wa->ulex[i], content, head->len, &lexres);
282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* note that if found, i will be incremented nevertheless, so i >= 1 */
285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (found) {
286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        foundIndex = i;
287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        foundIndex = 0;
289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!found && !picoklex_lexLookup(wa->lex, content, head->len, &lexres)) {
291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* no lex entry found, WORDGRAPH(POS,NA)graph */
292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (PICO_OK == picodata_copy_item(wa->inBuf, wa->inLen,
293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          wa->outBuf, wa->outBufSize,
294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          &wa->outLen)) {
295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            wa->inLen = 0;
296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* predict and modify pos in info1 */
297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (PICO_OK != picodata_set_iteminfo1(wa->outBuf, wa->outLen,
298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   waClassifyPos(this, wa, content, head->len))) {
299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return picoos_emRaiseException(this->common->em,
300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               PICO_EXC_BUF_OVERFLOW,NULL,NULL);
301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {    /* at least one entry found */
305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("at least one entry found in lexicon %i",foundIndex));
306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (lexres.phonfound) {    /* incl. ind-phone and possibly multi-ent. */
307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (lexres.nrres > PICOKLEX_MAX_NRRES) {
308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* not possible with system lexicon, needs to be
309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                   ensured for user lex too */
310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_emRaiseWarning(this->common->em, PICO_WARN_FALLBACK,NULL,
311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        (picoos_char *)"using %d lexicon lookup results",
312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICOKLEX_MAX_NRRES);
313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                lexres.nrres = PICOKLEX_MAX_NRRES;
314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            head->type = PICODATA_ITEM_WORDINDEX;
316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (lexres.nrres == 1) {
317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                head->info1 = lexres.posind[0];
318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* more than one result, POSgroup info needs to be
320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                   determined for later POS disambiguation */
321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                for (i = 0; i < lexres.nrres; i++) {
322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    posbuf[i] = lexres.posind[i * PICOKLEX_POSIND_SIZE];
323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                head->info1 = picoktab_getPosGroup(wa->tabpos, posbuf,
325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                   lexres.nrres);
326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            head->info2 = foundIndex;
328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            head->len = lexres.posindlen;
329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((status = picodata_put_itemparts(head, lexres.posind,
330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                 lexres.posindlen,
331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                 wa->outBuf, wa->outBufSize,
332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                 &wa->outLen)) == PICO_OK) {
333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                wa->inLen = 0;
334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return picoos_emRaiseException(this->common->em, status,
336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               NULL, NULL);
337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {    /* no phone, :G2P, one entry: WORDGRAPH(POS,NA)graph */
340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (PICO_OK == picodata_copy_item(wa->inBuf, wa->inLen,
341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              wa->outBuf, wa->outBufSize,
342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                              &wa->outLen)) {
343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                wa->inLen = 0;
344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* set lex pos in info1 */
345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (PICO_OK != picodata_set_iteminfo1(wa->outBuf, wa->outLen,
346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                      lexres.posind[0])) {
347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return picoos_emRaiseException(this->common->em,
348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                   PICO_EXC_BUF_OVERFLOW,
349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                   NULL, NULL);
350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ***********************************************************************/
359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*                          waStep function                              */
360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ***********************************************************************/
361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   collect into internal buffer, process, and then feed to output buffer
364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   init state: COLLECT      ext      ext
366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   state transitions:       in IN OUTout
367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   COLLECT | getOneItem  ->-1 +1  0  0   | (ATOMIC) -> PROCESS (got item)
368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   COLLECT | getOneItem  -> 0  0  0  0   | IDLE                (got no item)
369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   PROCESS | procOneItem -> 0 -1 +1  0   | (ATOMIC) -> FEED    (proc'ed item)
371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   PROCESS | procOneItem -> 0 -1  0  0   | BUSY     -> COLLECT (item skipped)
372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   FEED    | putOneItem  -> 0  0 -1 +1   | BUSY     -> COLLECT (put item)
374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   FEED    | putOneItem  -> 0  0  1  0   | OUT_FULL            (put no item)
375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picodata_step_result_t waStep(register picodata_ProcessingUnit this,
378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                     picoos_int16 mode,
379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                     picoos_uint16 * numBytesOutput) {
380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    register wa_subobj_t *wa;
381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pico_status_t rv = PICO_OK;
382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_PU_ERROR;
385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wa = (wa_subobj_t *) this->subObj;
387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    mode = mode;        /* avoid warning "var not used in this function"*/
388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *numBytesOutput = 0;
389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (1) { /* exit via return */
390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("doing state %i, inLen: %d, outLen: %d",
391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                       wa->procState, wa->inLen, wa->outLen));
392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (wa->procState) {
394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* collect state: get item from charBuf and store in
395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             * internal inBuf
396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             */
397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case WA_STEPSTATE_COLLECT:
398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (wa->inLen == 0) { /* is input buffer empty? */
399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_uint16 blen;
400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* try to get one item */
401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    rv = picodata_cbGetItem(this->cbIn, wa->inBuf,
402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            wa->inBufSize, &blen);
403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("after getting item, status: %d", rv));
404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (PICO_OK == rv) {
405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* we now have one item */
406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        wa->inLen = blen;
407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        wa->procState = WA_STEPSTATE_PROCESS;
408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* uncomment next line to split into two steps */
409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* return PICODATA_PU_ATOMIC; */
410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    } else if (PICO_EOF == rv) {
411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* there was no item in the char buffer */
412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return PICODATA_PU_IDLE;
413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    } else if ((PICO_EXC_BUF_UNDERFLOW == rv)
414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                               || (PICO_EXC_BUF_OVERFLOW == rv)) {
415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_ERROR(("problem getting item"));
416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_emRaiseException(this->common->em, rv,
417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                NULL, NULL);
418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return PICODATA_PU_ERROR;
419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    } else {
420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_ERROR(("problem getting item, unhandled"));
421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_emRaiseException(this->common->em, rv,
422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                NULL, NULL);
423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return PICODATA_PU_ERROR;
424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else { /* there already is an item in the input buffer */
426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_WARN(("item already in input buffer"));
427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_emRaiseWarning(this->common->em,
428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          PICO_WARN_PU_IRREG_ITEM, NULL, NULL);
429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->procState = WA_STEPSTATE_PROCESS;
430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* uncomment next to split into two steps */
431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* return PICODATA_PU_ATOMIC; */
432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* process state: process item in internal inBuf and put
437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             * result in internal outBuf
438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             */
439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case WA_STEPSTATE_PROCESS:
440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* ensure there is an item in inBuf and it is valid */
442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if ((wa->inLen > 0) && picodata_is_valid_item(wa->inBuf,
443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                              wa->inLen)) {
444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picodata_itemhead_t ihead;
445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_uint8 *icontent;
446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    pico_status_t rvP = PICO_OK;
447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    rv = picodata_get_iteminfo(wa->inBuf, wa->inLen, &ihead,
449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               &icontent);
450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (PICO_OK == rv) {
451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        switch (ihead.type) {
453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            case PICODATA_ITEM_WORDGRAPH:
454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                if (0 < ihead.len) {
456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    rvP = waProcessWordgraph(this, wa, &ihead,
457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             icontent);
458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                } else {
459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    /* else ignore empty WORDGRAPH */
460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    wa->inLen = 0;
461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    wa->procState = WA_STEPSTATE_COLLECT;
462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    return PICODATA_PU_BUSY;
463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                }
464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                break;
465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            case PICODATA_ITEM_OTHER:
466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                /* skip item */
467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                rvP = PICO_WARN_PU_DISCARD_BUF;
468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                break;
469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            default:
470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                /* copy item unmodified */
471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                rvP = picodata_copy_item(wa->inBuf,
472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                         wa->inLen, wa->outBuf,
473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                         wa->outBufSize, &wa->outLen);
474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                break;
475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        if (PICO_OK == rvP) {
478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            wa->inLen = 0;
479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            wa->procState = WA_STEPSTATE_FEED;
480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* uncomment next to split into two steps */
481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* return PICODATA_PU_ATOMIC; */
482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else if (PICO_WARN_PU_DISCARD_BUF == rvP) {
483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* discard input buffer and get a new item */
484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODBG_INFO(("skipping OTHER item"));
485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*                            picoos_emRaiseWarning(this->common->em,
486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                  PICO_WARN_PU_DISCARD_BUF, NULL, NULL);
487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            wa->inLen = 0;
489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            wa->procState = WA_STEPSTATE_COLLECT;
490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            return PICODATA_PU_BUSY;
491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else {
492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* PICO_EXC_BUF_OVERFLOW   <- overflow in outbuf
493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                               PICO_ERR_OTHER          <- no valid item in inbuf
494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                               or return from processWordgraph
495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            */
496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODBG_ERROR(("problem processing item", rvP));
497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picoos_emRaiseException(this->common->em, rvP,
498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                    NULL, NULL);
499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            return PICODATA_PU_ERROR;
500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    } else {    /* could not get iteminfo */
503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* PICO_EXC_BUF_OVERFLOW   <- overflow in outbuf
504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                           PICO_ERR_OTHER          <- no valid item in inbuf
505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        */
506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_ERROR(("problem getting item info, "
507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       "discard buffer content"));
508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        wa->inLen = 0;
509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        wa->procState = WA_STEPSTATE_COLLECT;
510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_emRaiseException(this->common->em, rv,
511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                NULL, NULL);
512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return PICODATA_PU_ERROR;
513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (wa->inLen == 0) {    /* no item in inBuf */
516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_INFO(("no item in inBuf"));
517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* wa->inLen = 0;*/
518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->procState = WA_STEPSTATE_COLLECT;
519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_BUSY;
520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {    /* no valid item in inBuf */
522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* bad state/item, discard buffer content */
523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_WARN(("no valid item, discard buffer content"));
524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_emRaiseWarning(this->common->em,
525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          PICO_WARN_PU_IRREG_ITEM, NULL, NULL);
526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_emRaiseWarning(this->common->em,
527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          PICO_WARN_PU_DISCARD_BUF, NULL, NULL);
528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->inLen = 0;
529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->procState = WA_STEPSTATE_COLLECT;
530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_BUSY;
531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* feed state: copy item in internal outBuf to output charBuf */
536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case WA_STEPSTATE_FEED:
537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* check that item fits in cb should not be needed */
539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                rv = picodata_cbPutItem(this->cbOut, wa->outBuf,
540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        wa->outLen, numBytesOutput);
541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   (picoos_uint8 *)"wana: ", wa->outBuf,
544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   wa->outLen);
545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("put item, status: %d", rv));
547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (PICO_OK == rv) {
548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->outLen = 0;
549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->procState = WA_STEPSTATE_COLLECT;
550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_BUSY;
551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (PICO_EXC_BUF_OVERFLOW == rv) {
552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_INFO(("feeding, overflow, PICODATA_PU_OUT_FULL"));
553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_OUT_FULL;
554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if ((PICO_EXC_BUF_UNDERFLOW == rv)
555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                           || (PICO_ERR_OTHER == rv)) {
556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_WARN(("feeding problem, discarding item"));
557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->outLen = 0;
558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    wa->procState = WA_STEPSTATE_COLLECT;
559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_emRaiseWarning(this->common->em, rv, NULL,NULL);
560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_BUSY;
561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } /* switch */
568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } /* while */
570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* should be never reached */
572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_ERROR(("reached end of function"));
573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_emRaiseException(this->common->em, PICO_ERR_OTHER, NULL, NULL);
574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICODATA_PU_ERROR;
575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* end */
583