1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2 of the License, or
6    (at your option) any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17 
18 #include "udm_config.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include "udm_common.h"
24 #include "udm_utils.h"
25 #include "udm_textlist.h"
26 #include "udm_unicode.h"
27 #include "udm_word.h"
28 
29 
30 static inline udm_rc_t
UdmTextListRealloc(UDM_TEXTLIST * tlist)31 UdmTextListRealloc(UDM_TEXTLIST *tlist)
32 {
33   if (tlist->nitems >= tlist->mitems)
34   {
35     tlist->mitems+= 16*1024;
36     tlist->Item= (UDM_TEXTITEM*) UdmRealloc(tlist->Item,
37                                             tlist->mitems * sizeof(UDM_TEXTITEM));
38     if (!tlist->Item)
39     {
40       tlist->nitems= 0;
41       tlist->mitems= 0;
42       return UDM_ERROR;
43     }
44   }
45   return UDM_OK;
46 }
47 
48 
49 UDM_API(void)
UdmTextListAdd(UDM_TEXTLIST * tlist,const UDM_TEXTITEM * item)50 UdmTextListAdd(UDM_TEXTLIST *tlist, const UDM_TEXTITEM *item)
51 {
52   if(!item->str)return;
53 
54   if (UDM_OK != UdmTextListRealloc(tlist))
55     return; /* TODO34: return error code  */
56 
57   tlist->Item[tlist->nitems].str = (char*)UdmStrdup(item->str);
58   tlist->Item[tlist->nitems].href = item->href ? (char*)UdmStrdup(item->href) : NULL;
59   tlist->Item[tlist->nitems].section_name = item->section_name ? (char*)UdmStrdup(item->section_name) : NULL;
60   tlist->Item[tlist->nitems].Param= item->Param;
61   tlist->nitems++;
62   return;
63 }
64 
65 
66 UDM_API(void)
UdmTextListAddConst(UDM_TEXTLIST * tlist,const UDM_CONST_TEXTITEM * item,const UDM_TEXT_PARAM * TextParam)67 UdmTextListAddConst(UDM_TEXTLIST *tlist,
68                     const UDM_CONST_TEXTITEM *item,
69                     const UDM_TEXT_PARAM *TextParam)
70 {
71   UDM_TEXTITEM *I;
72   /*
73   if (!item->str)
74     return;
75   */
76   if (UDM_OK != UdmTextListRealloc(tlist))
77     return; /* TODO34: return error code  */
78 
79   I= &tlist->Item[tlist->nitems];
80   I->str= UdmConstStrDup(&item->text);
81   I->href= item->href.str ? UdmConstStrDup(&item->href) : NULL;
82   I->section_name= item->section_name.str ? UdmConstStrDup(&item->section_name) : NULL;
83   I->Param= *TextParam;
84   tlist->nitems++;
85   return;
86 }
87 
88 
89 UDM_API(void)
UdmTextListAppend(UDM_TEXTLIST * tlist,const UDM_TEXTITEM * item)90 UdmTextListAppend(UDM_TEXTLIST * tlist,
91                                           const UDM_TEXTITEM *item)
92 {
93   size_t oldlen, newlen;
94   UDM_TEXTITEM *I;
95 
96   if(!item->str)return;
97 
98   if (item->href || !tlist->nitems)
99   {
100     UdmTextListAdd(tlist, item);
101     return;
102   }
103 
104   I= &tlist->Item[tlist->nitems-1];
105 
106   oldlen= strlen(I->str);
107   newlen= oldlen + strlen(item->str) + 1;
108   I->str= (char*)UdmRealloc(I->str, newlen);
109   strcpy(I->str + oldlen, item->str);
110   return;
111 }
112 
113 
114 UDM_API(void)
UdmTextListFree(UDM_TEXTLIST * tlist)115 UdmTextListFree(UDM_TEXTLIST *tlist)
116 {
117   size_t i;
118 
119   for(i=0;i<tlist->nitems;i++)
120   {
121     UDM_FREE(tlist->Item[i].str);
122     UDM_FREE(tlist->Item[i].href);
123     UDM_FREE(tlist->Item[i].section_name);
124   }
125   UDM_FREE(tlist->Item);
126   tlist->nitems= 0;
127   tlist->mitems= 0;
128 }
129 
130 
131 UDM_API(void)
UdmTextListInit(UDM_TEXTLIST * tlist)132 UdmTextListInit(UDM_TEXTLIST *tlist)
133 {
134   bzero(tlist, sizeof(UDM_TEXTLIST));
135 }
136 
137 
138 static udm_rc_t
UdmParseTextListItem(const UDM_TEXTITEM * text,UDM_WORD_SCANNER * scanner,int cnvflags,UDM_CONSTWORDLIST * CWL)139 UdmParseTextListItem(const UDM_TEXTITEM *text,
140                      UDM_WORD_SCANNER *scanner,
141                      int cnvflags,
142                      UDM_CONSTWORDLIST *CWL)
143 {
144   /*fprintf(stderr, "flags=%d text=%s\n", cnvflags, text->str);*/
145   if (text->Param.flags & UDM_TEXTLIST_FLAG_HTML)
146     cnvflags|= UDM_RECODE_HTML_IN;
147   return UdmConstWordListAddString(scanner, cnvflags, CWL, text->Param.secno,
148                                    text->str, strlen(text->str)); /* TODO34: strlen */
149 }
150 
151 
152 udm_rc_t
UdmTextListToConstWordList(const UDM_TEXTLIST * TextList,UDM_UNIDATA * unidata,UDM_CHARSET * cs,int cnvflags,UDM_CONSTWORDLIST * CWL)153 UdmTextListToConstWordList(const UDM_TEXTLIST *TextList,
154                            UDM_UNIDATA *unidata, UDM_CHARSET *cs, int cnvflags,
155                            UDM_CONSTWORDLIST *CWL)
156 {
157   size_t i;
158   UDM_WORD_SCANNER scanner;
159   if (!cs->cset->getword)
160     return UDM_OK;
161   UdmWordScannerInit(&scanner, unidata, cs);
162   for (i= 0; i < TextList->nitems; i++)
163   {
164     UDM_TEXTITEM *Item= &TextList->Item[i];
165     if (Item->Param.secno)
166       UdmParseTextListItem(&TextList->Item[i], &scanner, cnvflags, CWL); /* TODO34: check rc */
167   }
168   return UDM_OK;
169 }
170 
171 
172 udm_rc_t
UdmTextItemNormalizeDecimal(UDM_TEXTITEM * Item)173 UdmTextItemNormalizeDecimal(UDM_TEXTITEM *Item) /* TODO34: recognize multiple decimal entries */
174 {
175   char decimal[128];
176   UdmNormalizeDecimal(decimal, sizeof(decimal), Item->str);
177   UdmFree(Item->str);
178   Item->str= UdmStrdup(decimal);
179   return UDM_OK;
180 }
181 
182 
183 void
UdmTextParamInit(UDM_TEXT_PARAM * Param,udm_textlist_flag_t flags,udm_secno_t secno)184 UdmTextParamInit(UDM_TEXT_PARAM *Param,
185                  udm_textlist_flag_t flags, udm_secno_t secno)
186 {
187   Param->flags= flags;
188   Param->secno= secno;
189 }
190 
191 void
UdmTextItemInit(UDM_TEXTITEM * Item,udm_textlist_flag_t flags)192 UdmTextItemInit(UDM_TEXTITEM *Item, udm_textlist_flag_t flags)
193 {
194   bzero(Item, sizeof(*Item));
195   Item->Param.flags= flags;
196 }
197 
198 
199 void
UdmConstTextItemInit(UDM_CONST_TEXTITEM * Item)200 UdmConstTextItemInit(UDM_CONST_TEXTITEM *Item)
201 {
202   bzero(Item, sizeof(*Item));
203 }
204