OSDN Git Service

replace tray implementation.
[bbk/bchanl.git] / src / util.c
1 /*
2  * util.c
3  *
4  * Copyright (c) 2012 project bchan
5  *
6  * This software is provided 'as-is', without any express or implied
7  * warranty. In no event will the authors be held liable for any damages
8  * arising from the use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software. If you use this software
16  *    in a product, an acknowledgment in the product documentation would be
17  *    appreciated but is not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  *    misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source
23  *    distribution.
24  *
25  */
26
27 #include        <basic.h>
28 #include        <bstdio.h>
29 #include        <bstdlib.h>
30 #include        <tcode.h>
31 #include        <tstring.h>
32 #include        <errcode.h>
33 #include        <btron/hmi.h>
34
35 #include    "util.h"
36 #include        <tad/traydata_iterator.h>
37
38 #ifdef BCHANL_CONFIG_DEBUG
39 # define DP(arg) printf arg
40 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
41 #else
42 # define DP(arg) /**/
43 # define DP_ER(msg, err) /**/
44 #endif
45
46 EXPORT TCURL_CHECK_VALID_BBSURL tcurl_check_valid_bbsurl(CONST TC *url, W url_len)
47 {
48         TC scheme[] = {TK_h, TK_t, TK_t, TK_p, TK_COLN, TK_SLSH, TK_SLSH, TNULL};
49         TC *p;
50         W cmp;
51
52         cmp = tc_strncmp(url, scheme, 7);
53         if (cmp != 0) {
54                 return TCURL_CHECK_VALID_BBSURL_INVALID_SCHEME;
55         }
56         if (url_len == 7) {
57                 return TCURL_CHECK_VALID_BBSURL_INVALID_HOST;
58         }
59         p = tc_strchr(url+7, TK_SLSH);
60         if (p == NULL) {
61                 return TCURL_CHECK_VALID_BBSURL_INVALID_PATH;
62         }
63         if ((p+1) == (url+url_len)) {
64                 return TCURL_CHECK_VALID_BBSURL_INVALID_PATH;
65         }
66         if (p == (url+7)) {
67                 return TCURL_CHECK_VALID_BBSURL_INVALID_HOST;
68         }
69         if ((p+1) == (url+url_len)) {
70                 return TCURL_CHECK_VALID_BBSURL_INVALID_PATH;
71         }
72         p = tc_strchr(p+1, TK_SLSH);
73         if (p == NULL) {
74                 return TCURL_CHECK_VALID_BBSURL_NO_LAST_SLSH;
75         }
76         if ((p+1) != (url+url_len)) {
77                 return TCURL_CHECK_VALID_BBSURL_INVALID_PATH;
78         }
79
80         return TCURL_CHECK_VALID_BBSURL_OK;
81 }
82
83 EXPORT W tray_pushstring(TC *str, W len)
84 {
85         W err;
86         TRAYREC trayrec[2];
87         UB bin[4+24];
88         TADSEG *base = (TADSEG*)bin;
89         TEXTSEG *textseg = (TEXTSEG*)(bin + 4);
90
91         base->id = 0xFFE1;
92         base->len = 24;
93         textseg->view = (RECT){{0, 0, 0, 0}};
94         textseg->draw = (RECT){{0, 0, 0, 0}};
95         textseg->h_unit = -120;
96         textseg->v_unit = -120;
97         textseg->lang = 0x21;
98         textseg->bgpat = 0;
99
100         trayrec[0].id = 0xE1;
101         trayrec[0].len = 28;
102         trayrec[0].dt = bin;
103         trayrec[1].id = TR_TEXT;
104         trayrec[1].len = len * sizeof(TC);
105         trayrec[1].dt = (B*)str;
106
107         err = tpsh_dat(trayrec, 2, NULL);
108         if (err < 0) {
109                 DP_ER("tpsh_dat", err);
110         }
111         return err;
112 }
113
114 struct traydata_textiterator_t_ {
115         traydata_iterator_t base;
116 };
117 typedef struct traydata_textiterator_t_ traydata_textiterator_t;
118
119 LOCAL VOID traydata_textiterator_initialize(traydata_textiterator_t *iter, TRAYREC *rec, W recnum)
120 {
121         traydata_iterator_initialize(&iter->base, rec, recnum);
122 }
123
124 LOCAL Bool traydata_textiterator_getnext(traydata_textiterator_t *iter, TC *ch)
125 {
126         traydata_iterator_result result;
127         Bool cont;
128
129         for (;;) {
130                 cont = traydata_iterator_next(&iter->base, &result);
131                 if (cont == False) {
132                         break;
133                 }
134                 if (result.type == TRAYDATA_ITERATOR_RESULTTYPE_FIXED_SEGMENT) {
135                         *ch = result.val.ch;
136                         return True;
137                 }
138         }
139
140         return False;
141 }
142
143 LOCAL VOID traydata_textiterator_finalize(traydata_textiterator_t *iter)
144 {
145         traydata_iterator_finalize(&iter->base);
146 }
147
148 EXPORT W tray_popstring(TC *str, W len)
149 {
150         TRAYREC *data;
151         W size, recs, err, i;
152         traydata_textiterator_t iter;
153         Bool cont;
154         TC ch;
155
156         err = tpop_dat(NULL, 0, &size, -1, NULL);
157         if (err < 0) {
158                 DP_ER("tpop_dat: get size error", err);
159                 return err;
160         }
161         if (err == 0) {
162                 /* tray is empty */
163                 return 0;
164         }
165         data = (TRAYREC*)malloc(size);
166         if (data == NULL) {
167                 return ER_NOMEM;
168         }
169         recs = tpop_dat(data, size, NULL, -1, NULL);
170         if (recs < 0) {
171                 DP_ER("tpop_dat: get data error", recs);
172                 free(data);
173                 return recs;
174         }
175
176         traydata_textiterator_initialize(&iter, data, recs);
177         for (i = 0; i < len - 1;) {
178                 cont = traydata_textiterator_getnext(&iter, &ch);
179                 if (cont == False) {
180                         break;
181                 }
182                 if (ch == TK_NL) {
183                         break;
184                 }
185                 if (str != NULL) {
186                         str[i++] = ch;
187                 }
188         }
189         traydata_textiterator_finalize(&iter);
190         if (str != NULL) {
191                 str[i] = TNULL;
192         }
193
194         free(data);
195
196         return i;
197 }
198
199 EXPORT W tray_deletedata()
200 {
201         return tdel_dat();
202 }
203
204 EXPORT Bool tray_isempty()
205 {
206         W ret;
207         ret = tsel_dat(-1);
208         if (ret < 0) {
209                 DP_ER("tsel_dat", ret);
210         }
211         if (ret == 0) {
212                 return True;
213         }
214         return False;
215 }