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 picoktab.c
18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * symbol tables needed at runtime
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 "picoknow.h"
32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picobase.h"
33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoktab.h"
34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodata.h"
35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" {
38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0
40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** @todo : the following would be better part of a knowledge base.
45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Make sure it is consistent with the phoneme symbol table used in the lingware */
46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PLANE_PHONEMES */
48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PLANE_POS */
50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PLANE_PB_STRENGTHS */
52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PLANE_ACCENTS */
54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* PLANE_INTERN */
56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOKTAB_TMPID_PHONSTART      '\x26'  /* 38  '&' */
57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOKTAB_TMPID_PHONTERM       '\x23'  /* 35  '#' */
58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* fixed ids */
62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabIdsInitialize(register picoknow_KnowledgeBase this,
66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       picoos_Common common)
67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoktab_FixedIds ids;
69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("start"));
71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ids = (picoktab_FixedIds) this->subObj;
77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ids->phonStartId = PICOKTAB_TMPID_PHONSTART;
79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ids->phonTermId = PICOKTAB_TMPID_PHONTERM;
80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
81b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabIdsSubObjDeallocate(register picoknow_KnowledgeBase this,
85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                             picoos_MemoryManager mm)
86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *) &this->subObj);
89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoktab_specializeIdsKnowledgeBase(picoknow_KnowledgeBase this,
94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                  picoos_Common common)
95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = ktabIdsSubObjDeallocate;
101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(common->mm, sizeof(picoktab_fixed_ids_t));
102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this->subObj) {
103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ktabIdsInitialize(this, common);
107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoktab_FixedIds picoktab_getFixedIds(picoknow_KnowledgeBase this)
110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((NULL == this) ? NULL : ((picoktab_FixedIds) this->subObj));
112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoktab_FixedIds picoktab_newFixedIds(picoos_MemoryManager mm)
116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoktab_FixedIds this = (picoktab_FixedIds) picoos_allocate(mm,sizeof(*this));
118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* initialize */
120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoktab_disposeFixedIds(picoos_MemoryManager mm, picoktab_FixedIds * this)
126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*this)) {
128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* terminate */
129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm,(void *)this);
130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Graphs */
137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* overview binary file format for graphs kb:
140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    graphs-kb = NROFSENTRIES SIZEOFSENTRY ofstable graphs
142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    NROFSENTRIES  : 2 bytes, number of entries in offset table
144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    SIZEOFSENTRY  : 1 byte,  size of one entry in offset table
145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ofstable = {OFFSET}=NROFSENTRIES (contains NROFSENTRIES entries of OFFSET)
147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    OFFSET: SIZEOFSENTRY bytes, offset to baseaddress of graphs-kb to entry in graphs
149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    graphs = {graph}=NROFSENTRIES (contains NROFSENTRIES entries of graph)
151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    graph = PROPSET FROM TO [TOKENTYPE] [TOKENSUBTYPE] [VALUE] [LOWERCASE] [GRAPHSUBS1] [GRAPHSUBS2]
153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    FROM          : 1..4 unsigned bytes, UTF8 character without terminating 0
155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    TO            : 1..4 unsigned bytes, UTF8 character without terminating 0
156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PROPSET       : 1 unsigned byte, least significant bit : has TO field
157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has TOKENTYPE
158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has TOKENSUBTYPE
159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has VALUE
160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has LOWERCASE
161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has GRAPHSUBS1
162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has GRAPHSUBS2
163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                             next bit : has PUNC
164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    TOKENTYPE    : 1 unsigned byte
166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    TOKENSUBTYPE : 1 unsigned byte
167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    VALUE        : 1 unsigned byte
168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    LOWERCASE    : 1..4 unsigned bytes, UTF8 character without terminating 0
169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    GRAPHSUBS1   : 1..4 unsigned bytes, UTF8 character without terminating 0
170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    GRAPHSUBS2   : 1..4 unsigned bytes, UTF8 character without terminating 0
171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PUNC         : 1 unsigned byte
172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint32 ktab_propOffset (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uint32 prop);
175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_GRAPHS_NR_OFFSET     0
177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_GRAPHS_SIZE_OFFSET   2
178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_GRAPHS_OFFSET_TABLE  3
179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_GRAPHS_GRAPH_TABLE   0
180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* bitmasks to extract the grapheme properties info from the property set */
182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_TO            ((picoos_uint8)'\x01')
183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_TOKENTYPE     ((picoos_uint8)'\x02')
184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_TOKENSUBTYPE  ((picoos_uint8)'\x04')
185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_VALUE         ((picoos_uint8)'\x08')
186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_LOWERCASE     ((picoos_uint8)'\x010')
187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_GRAPHSUBS1    ((picoos_uint8)'\x020')
188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_GRAPHSUBS2    ((picoos_uint8)'\x040')
189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_GRAPH_PROPSET_PUNCT         ((picoos_uint8)'\x080')
190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabgraphs_subobj *ktabgraphs_SubObj;
193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabgraphs_subobj {
195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 nrOffset;
196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 sizeOffset;
197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * offsetTable;
199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * graphTable;
200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} ktabgraphs_subobj_t;
201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabGraphsInitialize(register picoknow_KnowledgeBase this,
205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          picoos_Common common) {
206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs_subobj_t * ktabgraphs;
207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("start"));
209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs = (ktabgraphs_subobj_t *) this->subObj;
215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs->nrOffset = ((int)(this->base[KTAB_START_GRAPHS_NR_OFFSET])) + 256*(int)(this->base[KTAB_START_GRAPHS_NR_OFFSET+1]);
216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs->sizeOffset  = (int)(this->base[KTAB_START_GRAPHS_SIZE_OFFSET]);
217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs->offsetTable = &(this->base[KTAB_START_GRAPHS_OFFSET_TABLE]);
218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs->graphTable  = &(this->base[KTAB_START_GRAPHS_GRAPH_TABLE]);
219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabGraphsSubObjDeallocate(register picoknow_KnowledgeBase this,
223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                picoos_MemoryManager mm) {
224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *) &this->subObj);
226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoktab_specializeGraphsKnowledgeBase(picoknow_KnowledgeBase this,
232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                     picoos_Common common) {
233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = ktabGraphsSubObjDeallocate;
238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(common->mm, sizeof(ktabgraphs_subobj_t));
239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this->subObj) {
240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ktabGraphsInitialize(this, common);
244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoktab_Graphs picoktab_getGraphs(picoknow_KnowledgeBase this) {
248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return (picoktab_Graphs) this->subObj;
252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Graphs methods */
257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasVowellikeProp(const picoktab_Graphs this,
259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       const picoos_uint8 *graph,
260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       const picoos_uint8 graphlenmax) {
261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint8 ui8App;
263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 graphsOffset;
264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ui8App = graphlenmax;        /* avoid warning "var not used in this function"*/
267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  graphsOffset = picoktab_graphOffset (this, (picoos_uchar *)graph);
269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  return g->graphTable[graphsOffset + ktab_propOffset (this, graphsOffset, KTAB_GRAPH_PROPSET_TOKENTYPE)] == PICODATA_ITEMINFO1_TOKTYPE_LETTERV;
270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void ktab_getStrProp (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uint32 propOffset, picoos_uchar * str)
274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 i, l;
277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  i = 0;
279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  l = picobase_det_utf8_length(g->graphTable[graphsOffset+propOffset]);
280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  while (i<l) {
281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    str[i] = g->graphTable[graphsOffset+propOffset+i];
282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i++;
283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  str[l] = 0;
285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint32 ktab_propOffset(const picoktab_Graphs this,
289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 graphsOffset, picoos_uint32 prop)
290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Returns offset of property 'prop' inside the graph with offset 'graphsOffset' in graphs table;
291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen If the property is found, a value > 0 is returned otherwise 0 */
292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n = 0;
294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs_subobj_t * g = (ktabgraphs_SubObj) this;
295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((g->graphTable[graphsOffset] & prop) == prop) {
297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        n = n + 1; /* overread PROPSET field */
298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        n = n + picobase_det_utf8_length(g->graphTable[graphsOffset+n]); /* overread FROM field */
299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_TO) {
300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_TO)
301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_TO) {
302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + picobase_det_utf8_length(g->graphTable[graphsOffset+n]); /* overread TO field */
303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_TOKENTYPE) {
308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_TOKENTYPE)
309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_TOKENTYPE) {
310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + 1; /* overread TOKENTYPE field */
311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_TOKENSUBTYPE) {
316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_TOKENSUBTYPE)
317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_TOKENSUBTYPE) {
318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + 1; /* overread stokentype field */
319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_VALUE) {
324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_VALUE)
325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_VALUE) {
326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + 1; /* overread value field */
327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_LOWERCASE) {
332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_LOWERCASE)
333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_LOWERCASE) {
334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + picobase_det_utf8_length(g->graphTable[graphsOffset+n]); /* overread lowercase field */
335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_GRAPHSUBS1) {
340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_GRAPHSUBS1)
341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_GRAPHSUBS1) {
342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + picobase_det_utf8_length(g->graphTable[graphsOffset+n]); /* overread graphsubs1 field */
343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_GRAPHSUBS2) {
348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_GRAPHSUBS2)
349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_GRAPHSUBS2) {
350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + picobase_det_utf8_length(g->graphTable[graphsOffset+n]); /* overread graphsubs2 field */
351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (prop > KTAB_GRAPH_PROPSET_PUNCT) {
356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((g->graphTable[graphsOffset] & KTAB_GRAPH_PROPSET_PUNCT)
357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    == KTAB_GRAPH_PROPSET_PUNCT) {
358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = n + 1; /* overread value field */
359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return n;
362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return n;
366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint32 picoktab_graphOffset (const picoktab_Graphs this, picoos_uchar * utf8graph)
370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picoos_int32 a, b, m;
372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picoos_uint32 graphsOffset;
373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picoos_uint32 propOffset;
374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picobase_utf8char from;
375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picobase_utf8char to;
376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picoos_bool utfGEfrom;
377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   picoos_bool utfLEto;
378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   if (g->nrOffset > 0) {
380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     a = 0;
381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     b = g->nrOffset-1;
382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     do  {
383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       m = (a+b) / 2;
384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       /* get offset to graph[m] */
386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       if (g->sizeOffset == 1) {
387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         graphsOffset = g->offsetTable[g->sizeOffset*m];
388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       else {
390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         graphsOffset =     g->offsetTable[g->sizeOffset*m    ] +
391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        256*g->offsetTable[g->sizeOffset*m + 1];
392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         /* PICODBG_DEBUG(("picoktab_graphOffset: %i %i %i %i", m, g->offsetTable[g->sizeOffset*m], g->offsetTable[g->sizeOffset*m + 1], graphsOffset));
393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         */
394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       /* get FROM and TO field of graph[m] */
397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       ktab_getStrProp(this, graphsOffset, 1, from);
398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_TO);
399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       if (propOffset > 0) {
400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         ktab_getStrProp(this, graphsOffset, propOffset, to);
401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       else {
403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         picoos_strcpy((picoos_char *)to, (picoos_char *)from);
404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       /* PICODBG_DEBUG(("picoktab_graphOffset: %i %i %i '%s' '%s' '%s'", a, m, b, from, utf8graph, to));
407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       */
408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       utfGEfrom = picoos_strcmp((picoos_char *)utf8graph, (picoos_char *)from) >= 0;
409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       utfLEto = picoos_strcmp((picoos_char *)utf8graph, (picoos_char *)to) <= 0;
410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       if (utfGEfrom && utfLEto) {
412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         /* PICODBG_DEBUG(("picoktab_graphOffset: utf char '%s' found", utf8graph));
413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          */
414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         return graphsOffset;
415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       if (!utfGEfrom) {
417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         b = m-1;
418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       else if (!utfLEto) {
420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         a = m+1;
421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       }
422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     } while (a<=b);
423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   }
424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   PICODBG_DEBUG(("picoktab_graphOffset: utf char '%s' not found", utf8graph));
425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   return 0;
426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getIntPropTokenType (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uint8 * stokenType)
432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_TOKENTYPE);
437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *stokenType = (picoos_uint8)(g->graphTable[graphsOffset+propOffset]);
439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getIntPropTokenSubType (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_int8 * stokenSubType)
448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_TOKENSUBTYPE);
453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *stokenSubType = (picoos_int8)(g->graphTable[graphsOffset+propOffset]);
455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getIntPropValue (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uint32 * value)
463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_VALUE);
468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *value = (picoos_uint32)(g->graphTable[graphsOffset+propOffset]);
470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getIntPropPunct (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uint8 * info1, picoos_uint8 * info2)
479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  ktabgraphs_subobj_t * g = (ktabgraphs_SubObj)this;
482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_PUNCT);
484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      if (g->graphTable[graphsOffset+propOffset] == 2) {
486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          *info1 = PICODATA_ITEMINFO1_PUNC_SENTEND;
487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      }
488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      else {
489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          *info1 = PICODATA_ITEMINFO1_PUNC_PHRASEEND;
490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      }
491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (g->graphTable[graphsOffset+1] == '.') {
492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *info2 = PICODATA_ITEMINFO2_PUNC_SENT_T;
493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    else if (g->graphTable[graphsOffset+1] == '?') {
495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *info2 = PICODATA_ITEMINFO2_PUNC_SENT_Q;
496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    else if (g->graphTable[graphsOffset+1] == '!') {
498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *info2 = PICODATA_ITEMINFO2_PUNC_SENT_E;
499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    else {
501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *info2 = PICODATA_ITEMINFO2_PUNC_PHRASE;
502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getStrPropLowercase (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uchar * lowercase)
512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_LOWERCASE);
516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktab_getStrProp(this, graphsOffset, propOffset, lowercase);
518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getStrPropGraphsubs1 (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uchar * graphsubs1)
527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_GRAPHSUBS1);
531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktab_getStrProp(this, graphsOffset, propOffset, graphsubs1);
533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool  picoktab_getStrPropGraphsubs2 (const picoktab_Graphs this, picoos_uint32 graphsOffset, picoos_uchar * graphsubs2)
542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 propOffset;
544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  propOffset = ktab_propOffset(this, graphsOffset, KTAB_GRAPH_PROPSET_GRAPHSUBS2);
546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  if (propOffset > 0) {
547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktab_getStrProp(this, graphsOffset, propOffset, graphsubs2);
548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  else {
551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return FALSE;
552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* used for tools */
556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void ktab_getUtf8 (picoos_uchar ** pos, picoos_uchar * to)
558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  picoos_uint32 l;
560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  l = picobase_det_utf8_length(**pos);
561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  while (l>0) {
562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *(to++) = *((*pos)++);
563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    l--;
564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  }
565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  *to = 0;
566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint16 picoktab_graphsGetNumEntries(const picoktab_Graphs this)
569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs_subobj_t * g = (ktabgraphs_SubObj) this;
571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return g->nrOffset;
572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoktab_graphsGetGraphInfo(const picoktab_Graphs this,
575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 graphIndex, picoos_uchar * from, picoos_uchar * to,
576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 * propset,
577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 * stokenType, picoos_uint8 * stokenSubType,
578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 * value, picoos_uchar * lowercase,
579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uchar * graphsubs1, picoos_uchar * graphsubs2,
580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 * punct) {
581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabgraphs_subobj_t * g = (ktabgraphs_SubObj) this;
582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 graphsOffset;
583b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * pos;
584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* calculate offset of graph[graphIndex] */
586b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (g->sizeOffset == 1) {
587b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        graphsOffset = g->offsetTable[graphIndex];
588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        graphsOffset = g->offsetTable[2 * graphIndex]
590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                + (g->offsetTable[2 * graphIndex + 1] << 8);
591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pos = &(g->graphTable[graphsOffset]);
593b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *propset = *pos;
594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
595b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pos++; /* advance to FROM */
596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktab_getUtf8(&pos, from); /* get FROM and advance */
597b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_TO) {
598b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ktab_getUtf8(&pos, to); /* get TO and advance */
599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
600b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_strcpy((picoos_char *)to, (picoos_char *)from);
601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
602b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_TOKENTYPE) {
603b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*stokenType) = *(pos++); /* get TOKENTYPE and advance */
604b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
605b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*stokenType) = -1;
606b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
607b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_TOKENSUBTYPE) {
608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*stokenSubType) = *(pos++); /* get TOKENSUBTYPE and advance */
609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
610b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*stokenSubType) = -1;
611b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
612b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_VALUE) {
613b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*value) = *(pos++); /* get VALUE and advance */
614b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
615b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*value) = -1;
616b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
617b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_LOWERCASE) {
618b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ktab_getUtf8(&pos, lowercase); /* get LOWERCASE and advance */
619b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
620b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        lowercase[0] = NULLC;
621b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_GRAPHSUBS1) {
623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ktab_getUtf8(&pos, graphsubs1); /* get GRAPHSUBS1 and advance */
624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
625b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        graphsubs1[0] = NULLC;
626b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
627b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_GRAPHSUBS2) {
628b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ktab_getUtf8(&pos, graphsubs2); /* get GRAPHSUBS2 and advance */
629b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
630b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        graphsubs2[0] = NULLC;
631b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
632b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*propset) & KTAB_GRAPH_PROPSET_PUNCT) {
633b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*punct) = *(pos++); /* get PUNCT and advance */
634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*punct) = -1;
636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
637b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
638b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
640b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Phones */
641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
643b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* overview binary file format for phones kb:
644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    phones-kb = specids propertytable
646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    specids = PRIMSTRESSID1 SECSTRESSID1 SYLLBOUNDID1 PAUSEID1 WORDBOUNDID1
648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen              RESERVE1 RESERVE1 RESERVE1
649b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    propertytable = {PHONEPROP2}=256
651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PRIMSTRESSID1: one byte, ID of primary stress
653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    SECSTRESSID1: one byte, ID of secondary stress
654b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    SYLLBOUNDID1: one byte, ID of syllable boundary
655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PAUSEID1: one byte, ID of pause
656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    RESERVE1: reserved for future use
657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PHONEPROP2: one byte, max. of 256 phones directly access this table
659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                to check a property for a phone; binary properties
660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                encoded (1 bit per prop)
661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       least significant bit: vowel
662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    next bit: diphth
663b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    next bit: glott
664b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    next bit: nonsyllvowel
665b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    next bit: syllcons
666b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       3 bits spare
667b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
668b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
669b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_SPECIDS   0
670b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_IND_PRIMSTRESS  0
671b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_IND_SECSTRESS   1
672b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_IND_SYLLBOUND   2
673b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_IND_PAUSE       3
674b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_IND_WORDBOUND   4
675b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
676b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_START_PROPS     8
677b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
678b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
679b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabphones_subobj *ktabphones_SubObj;
680b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
681b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabphones_subobj {
682b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *specids;
683b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *props;
684b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} ktabphones_subobj_t;
685b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
686b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
687b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* bitmasks to extract the property info from props */
688b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_PPROP_VOWEL        '\x01'
689b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_PPROP_DIPHTH       '\x02'
690b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_PPROP_GLOTT        '\x04'
691b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_PPROP_NONSYLLVOWEL '\x08'
692b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define KTAB_PPROP_SYLLCONS     '\x10'
693b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
694b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
695b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabPhonesInitialize(register picoknow_KnowledgeBase this,
696b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          picoos_Common common) {
697b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabphones_subobj_t * ktabphones;
698b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
699b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("start"));
700b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
701b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
702b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
703b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
704b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
705b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabphones = (ktabphones_subobj_t *) this->subObj;
706b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabphones->specids = &(this->base[KTAB_START_SPECIDS]);
707b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabphones->props   = &(this->base[KTAB_START_PROPS]);
708b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
709b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
710b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
711b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabPhonesSubObjDeallocate(register picoknow_KnowledgeBase this,
712b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                picoos_MemoryManager mm) {
713b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
714b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *) &this->subObj);
715b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
716b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
717b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
718b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
719b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoktab_specializePhonesKnowledgeBase(picoknow_KnowledgeBase this,
720b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                     picoos_Common common) {
721b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
722b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
723b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
724b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
725b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = ktabPhonesSubObjDeallocate;
726b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(common->mm, sizeof(ktabphones_subobj_t));
727b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this->subObj) {
728b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
729b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
730b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
731b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ktabPhonesInitialize(this, common);
732b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
733b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
734b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoktab_Phones picoktab_getPhones(picoknow_KnowledgeBase this) {
735b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
736b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
737b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
738b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return (picoktab_Phones) this->subObj;
739b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
740b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
741b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
742b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
743b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Phones methods */
744b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
745b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasVowelProp(const picoktab_Phones this,
746b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   const picoos_uint8 ch) {
747b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (KTAB_PPROP_VOWEL & ((ktabphones_SubObj)this)->props[ch]);
748b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
749b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasDiphthProp(const picoktab_Phones this,
750b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    const picoos_uint8 ch) {
751b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (KTAB_PPROP_DIPHTH & ((ktabphones_SubObj)this)->props[ch]);
752b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
753b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasGlottProp(const picoktab_Phones this,
754b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   const picoos_uint8 ch) {
755b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (KTAB_PPROP_GLOTT & ((ktabphones_SubObj)this)->props[ch]);
756b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
757b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasNonsyllvowelProp(const picoktab_Phones this,
758b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                          const picoos_uint8 ch) {
759b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (KTAB_PPROP_NONSYLLVOWEL & ((ktabphones_SubObj)this)->props[ch]);
760b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
761b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_hasSyllconsProp(const picoktab_Phones this,
762b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                      const picoos_uint8 ch) {
763b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (KTAB_PPROP_SYLLCONS & ((ktabphones_SubObj)this)->props[ch]);
764b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
765b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
766b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isSyllCarrier(const picoktab_Phones this,
767b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    const picoos_uint8 ch) {
768b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 props;
769b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    props = ((ktabphones_SubObj)this)->props[ch];
770b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (((KTAB_PPROP_VOWEL & props) &&
771b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             !(KTAB_PPROP_NONSYLLVOWEL & props))
772b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            || (KTAB_PPROP_SYLLCONS & props));
773b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
774b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
775b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isPrimstress(const picoktab_Phones this,
776b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                   const picoos_uint8 ch) {
777b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (ch == ((ktabphones_SubObj)this)->specids[KTAB_IND_PRIMSTRESS]);
778b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
779b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isSecstress(const picoktab_Phones this,
780b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 ch) {
781b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (ch == ((ktabphones_SubObj)this)->specids[KTAB_IND_SECSTRESS]);
782b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
783b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isSyllbound(const picoktab_Phones this,
784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 ch) {
785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (ch == ((ktabphones_SubObj)this)->specids[KTAB_IND_SYLLBOUND]);
786b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isWordbound(const picoktab_Phones this,
788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 ch) {
789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (ch == ((ktabphones_SubObj)this)->specids[KTAB_IND_WORDBOUND]);
790b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isPause(const picoktab_Phones this,
792b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                              const picoos_uint8 ch) {
793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (ch == ((ktabphones_SubObj)this)->specids[KTAB_IND_PAUSE]);
794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
796b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getPrimstressID(const picoktab_Phones this) {
797b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((ktabphones_SubObj)this)->specids[KTAB_IND_PRIMSTRESS];
798b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getSecstressID(const picoktab_Phones this) {
800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((ktabphones_SubObj)this)->specids[KTAB_IND_SECSTRESS];
801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
802b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getSyllboundID(const picoktab_Phones this) {
803b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((ktabphones_SubObj)this)->specids[KTAB_IND_SYLLBOUND];
804b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getWordboundID(const picoktab_Phones this) {
806b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((ktabphones_SubObj)this)->specids[KTAB_IND_WORDBOUND];
807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getPauseID(const picoktab_Phones this) {
809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((ktabphones_SubObj)this)->specids[KTAB_IND_PAUSE];
810b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
812b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
813b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Pos */
814b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************/
815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* overview binary file format for pos kb:
817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
818b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pos-kb = header posids
819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    header = {COUNT2 OFFS2}=8
820b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    posids = {POSID1 {PARTID1}0:8}1:
821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    where POSID1 is the value of the (combined) part-of-speech symbol,
823b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    and {PARTID1} are the symbol values of its components (empty if it
824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    is not a combined symbol). The {PARTID1} list is sorted.
825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    Part-of-speech symbols with equal number of components are grouped
826b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    together.
827b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    The header contains information about these groups:
829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    COUNT2 specifies the number of elements in the group, and OFFS2
831b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    specifies the offset (relative to the beginning of the kb) where
832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    the group data starts, i.e.:
833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    25   32  -> 25 not-combined elements, starting at offset 32
835b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    44   57  -> 44 elements composed of 2 symbols, starting at offset 57
836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    23  189  -> 23 elements composed of 3 symbols, starting at offset 189
837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ...
838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    Currently, each symbol may be composed of up to 8 other symbols.
840b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    Therefore, the header has 8 entries, too. The header starts with
841b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    the unique POS list, and then in increasing order, 2 symbols, 3
842b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    symbols,...
843b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
844b190149a69b110e6719ce0a41877a683f8db7ae7Charles ChenZur Anschauung die ge-printf-te Version:
845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 25   32
847b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 44   57
848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 23  189
849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 12  281
850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  4  341
851b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  1  365
852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  0    0
853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen  0    0
854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 33 |
855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 34 |
856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 35 |
857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 60 |
858b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen etc.
859b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 36 |  35  60
860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 50 |  35  95
861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 51 |  35  97
862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 58 |  35 120
863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 59 |  35 131
864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 61 |  60  75
865b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 63 |  60  95
866b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 64 |  60  97
867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen etc.
868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 42 |  35  60 117
869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 44 |  35  60 131
870b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 45 |  35  73  97
871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 48 |  35  84  97
872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 54 |  35  97 131
873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 56 |  35 113 120
874b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 57 |  35 117 120
875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 62 |  60  84 122
876b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen etc.
877b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
878b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabpos_subobj *ktabpos_SubObj;
880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct ktabpos_subobj {
882b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 nrcomb[PICOKTAB_MAXNRPOS_IN_COMB];
883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *nrcombstart[PICOKTAB_MAXNRPOS_IN_COMB];
884b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} ktabpos_subobj_t;
885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
887b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabPosInitialize(register picoknow_KnowledgeBase this,
888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       picoos_Common common) {
889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos_subobj_t *ktabpos;
890b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 osprev;
891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 os, pos;
892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i;
893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("start"));
895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos = (ktabpos_subobj_t *)this->subObj;
901b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    os = 0;
903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0, pos = 0; i < PICOKTAB_MAXNRPOS_IN_COMB; i++, pos += 4) {
904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ktabpos->nrcomb[i] = ((picoos_uint16)(this->base[pos+1])) << 8 |
905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            this->base[pos];
906b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (ktabpos->nrcomb[i] > 0) {
907b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            osprev = os;
908b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            os = ((picoos_uint16)(this->base[pos+3])) << 8 | this->base[pos+2];
909b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ktabpos->nrcombstart[i] = &(this->base[os]);
910b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_TRACE(("i %d, pos %d, nr %d, osprev %d, os %d", i, pos,
911b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                           ktabpos->nrcomb[i], osprev, os));
912b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (osprev >= os) {
913b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* cannot be, in a valid kb */
914b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return picoos_emRaiseException(common->em,
915b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               PICO_EXC_FILE_CORRUPT,
916b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               NULL, NULL);
917b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
918b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
919b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (i == 0) {
920b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* cannot be, in a valid kb */
921b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return picoos_emRaiseException(common->em,
922b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               PICO_EXC_FILE_CORRUPT,
923b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                               NULL, NULL);
924b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
925b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ktabpos->nrcombstart[i] = NULL;
926b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
927b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
928b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
929b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
930b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
931b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t ktabPosSubObjDeallocate(register picoknow_KnowledgeBase this,
932b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                             picoos_MemoryManager mm) {
933b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
934b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *) &this->subObj);
935b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
936b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
937b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
938b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
939b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoktab_specializePosKnowledgeBase(picoknow_KnowledgeBase this,
940b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                  picoos_Common common) {
941b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
942b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
943b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
944b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
945b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = ktabPosSubObjDeallocate;
946b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(common->mm, sizeof(ktabpos_subobj_t));
947b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this->subObj) {
948b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
949b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       NULL, NULL);
950b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
951b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ktabPosInitialize(this, common);
952b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
953b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
954b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoktab_Pos picoktab_getPos(picoknow_KnowledgeBase this) {
955b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this) {
956b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
957b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
958b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return (picoktab_Pos) this->subObj;
959b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
960b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
961b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
962b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
963b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Pos methods */
964b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
965b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int16 ktab_isEqualPosGroup(const picoos_uint8 *grp1,
966b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                         const picoos_uint8 *grp2,
967b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                         picoos_uint8 len)
968b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
969b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* if both, grp1 and grp2 would be sorted in ascending order
970b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       we could implement a function picoktab_comparePosGroup in
971b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       a similar manner as strcmp */
972b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
973b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i, j, equal;
974b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
975b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    equal = 1;
976b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
977b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
978b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (equal && (i < len)) {
979b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* search grp1[i] in grp2 */
980b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        j = 0;
981b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while ((j < len) && (grp1[i] != grp2[j])) {
982b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            j++;
983b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
984b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        equal = (j < len);
985b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
986b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
987b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
988b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return equal;
989b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
990b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
991b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
992b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isUniquePos(const picoktab_Pos this,
993b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 pos) {
994b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos_subobj_t *ktabpos;
995b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i;
996b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
997b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* speed-up possible with e.g. binary search */
998b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
999b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos = (ktabpos_subobj_t *)this;
1000b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_TRACE(("pos %d, nrcombinations %d", pos, ktabpos->nrcomb[0]));
1001b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
1002b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((i < ktabpos->nrcomb[0]) && (pos > ktabpos->nrcombstart[0][i])) {
1003b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_TRACE(("compare with pos %d at position %d",
1004b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                       ktabpos->nrcombstart[0][i], pos, i));
1005b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
1006b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1007b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return ((i < ktabpos->nrcomb[0]) && (pos == ktabpos->nrcombstart[0][i]));
1008b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1009b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1010b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1011b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoktab_isPartOfPosGroup(const picoktab_Pos this,
1012b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       const picoos_uint8 pos,
1013b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                       const picoos_uint8 posgroup)
1014b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1015b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos_subobj_t *ktabpos;
1016b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *grp;
1017b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i, j, n, s, grplen;
1018b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *e;
1019b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 found;
1020b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1021b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos = (ktabpos_subobj_t *) this;
1022b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1023b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    grp = NULL;
1024b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    found = FALSE;
1025b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    grplen = 0;
1026b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1027b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* currently, a linear search is required to find 'posgroup'; the
1028b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       knowledge base should be extended to allow for a faster search */
1029b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1030b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* treat case i==0, grplen==0, ie. pos == posgroup */
1031b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (pos == posgroup) {
1032b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        found = TRUE;
1033b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1034b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1035b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 1;
1036b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((grp == NULL) && (i < PICOKTAB_MAXNRPOS_IN_COMB)) {
1037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        n = ktabpos->nrcomb[i];       /* number of entries */
1038b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        e = ktabpos->nrcombstart[i];  /* ptr to first entry */
1039b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        s = i + 2;                    /* size of an entry in bytes */
1040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* was with while starting at 0:
1041b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        s = i > 0 ? i + 2 : 1;
1042b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        */
1043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        j = 0;
1044b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while ((grp == NULL) && (j < n)) {
1045b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (posgroup == e[0]) {
1046b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                grp = e + 1;
1047b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                grplen = s - 1;
1048b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1049b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            e += s;
1050b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            j++;
1051b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1052b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
1053b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* test if 'pos' is contained in the components of 'posgroup' */
1056b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (grp != NULL) {
1057b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        for (i = 0; !found && (i < grplen); i++) {
1058b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (pos == grp[i]) {
1059b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                found = TRUE;
1060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1061b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1063b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* just a way to test picoktab_getPosGroup */
1064b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /*
1065b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_ASSERT(picoktab_getPosGroup(this, grp, grplen) == posgroup);
1066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        */
1067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1068b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1069b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return found;
1070b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1071b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1072b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1073b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoktab_getPosGroup(const picoktab_Pos this,
1074b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 *poslist,
1075b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                  const picoos_uint8 poslistlen)
1076b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1077b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 poscomb;
1078b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos_subobj_t *ktabpos;
1079b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i, j, n, s;
1080b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *e;
1081b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1082b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    ktabpos = (ktabpos_subobj_t *) this;
1083b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    poscomb = 0;
1084b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((poslistlen > 0) && (poslistlen <= PICOKTAB_MAXNRPOS_IN_COMB)) {
1086b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i = poslistlen - 1;
1087b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (i > 0) {
1088b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            n = ktabpos->nrcomb[i];       /* number of entries */
1089b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            e = ktabpos->nrcombstart[i];  /* ptr to first entry */
1090b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            s = i + 2;                    /* size of an entry in bytes */
1091b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            j = 0;
1092b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            while (!poscomb && (j < n)) {
1093b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (ktab_isEqualPosGroup(poslist, e + 1, poslistlen)) {
1094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    poscomb = *e;
1095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                e += s;
1097b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                j++;
1098b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1099b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (!poscomb) {
1100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* combination not found; shouldn't occur if lingware OK! */
1101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* contingency solution: take first */
1102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_WARN(("dynamically created POS combination not found in table; taking first (%i)",poslist[0]));
1103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                poscomb = poslist[0];
1104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {  /* not a composed POS */
1106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            poscomb = poslist[0];
1107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return poscomb;
1111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
1114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
1116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* end */
1119