4 * Copyright (c) 2013 project bchan
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.
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:
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.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
27 #include "tadfragment.h"
32 #include <coll/bytearray.h>
33 #include <coll/wordarray.h>
34 #include "tadlexer_le.h"
36 #ifdef BCHAN_CONFIG_DEBUG
37 # define DP(arg) printf arg
38 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
41 # define DP_ER(msg, err) /**/
45 # define DP_STATE(state) printf("%s\n", state)
47 # define DP_STATE(state) /**/
50 struct tadfragment_pos_iterator_t_ {
52 TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART,
53 TADFRAGMENT_POS_ITERATOR_STATE_READING_TLANG,
54 TADFRAGMENT_POS_ITERATOR_STATE_READING,
55 TADFRAGMENT_POS_ITERATOR_STATE_COMPLETED,
56 TADFRAGMENT_POS_ITERATOR_STATE_ERROR,
63 tadlexer_le_result *result;
66 } lexer_result_handling;
68 typedef struct tadfragment_pos_iterator_t_ tadfragment_pos_iterator_t;
70 struct tadfragment_pos_iterator_result_ {
72 TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT,
73 TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_ERROR,
77 typedef struct tadfragment_pos_iterator_result_ tadfragment_pos_iterator_result;
79 LOCAL W tadfragment_pos_iterator_input(tadfragment_pos_iterator_t *iterator, tadlexer_le_result *result, Bool *segstart)
86 switch (iterator->state) {
87 case TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART:
88 DP_STATE("BEFORE_SEGSTART");
89 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_READING;
92 case TADFRAGMENT_POS_ITERATOR_STATE_READING_TLANG:
93 DP_STATE("READING_TLANG");
94 if (result->type == TADLEXER_LE_RESULTTYPE_SEGMENT_END) {
95 fixed = tadlexer_le_result_is_fixedsegment(result);
97 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_ERROR;
101 if (result->val.ch == 0xFEFE) {
104 if ((result->val.ch & 0xFF00) != 0xFE00) {
105 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_ERROR;
109 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART;
112 case TADFRAGMENT_POS_ITERATOR_STATE_READING:
114 if (result->type != TADLEXER_LE_RESULTTYPE_SEGMENT_END) {
117 fixed = tadlexer_le_result_is_fixedsegment(result);
118 if ((fixed != False)&&(result->val.ch == 0xFEFE)) {
119 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_READING_TLANG;
122 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART;
124 case TADFRAGMENT_POS_ITERATOR_STATE_COMPLETED:
125 DP_STATE("COMPLETED");
127 case TADFRAGMENT_POS_ITERATOR_STATE_ERROR:
136 LOCAL Bool tadfragment_pos_iterator_next(tadfragment_pos_iterator_t *iterator, tadfragment_pos_iterator_result *result)
141 tadlexer_le_result *lexer_result;
143 for (; iterator->lexer_result_handling.pos < iterator->lexer_result_handling.len; ) {
144 pos = iterator->lexer_result_handling.pos++;
145 lexer_result = iterator->lexer_result_handling.result + pos;
146 err = tadfragment_pos_iterator_input(iterator, lexer_result, &segstart);
148 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_ERROR;
151 if (segstart != False) {
152 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT;
153 result->index = iterator->pos - 1;
158 for (; iterator->pos < iterator->len;) {
159 ch = iterator->data[iterator->pos++];
160 tadlexer_le_inputbyte(&iterator->lexer, ch, &lexer_result, &len);
161 iterator->lexer_result_handling.result = lexer_result;
162 iterator->lexer_result_handling.len = len;
163 iterator->lexer_result_handling.pos = 0;
165 for (; iterator->lexer_result_handling.pos < iterator->lexer_result_handling.len; ) {
166 pos = iterator->lexer_result_handling.pos++;
167 lexer_result = iterator->lexer_result_handling.result + pos;
168 err = tadfragment_pos_iterator_input(iterator, lexer_result, &segstart);
170 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_ERROR;
173 if (segstart != False) {
174 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT;
175 result->index = iterator->pos - 1;
181 if (iterator->state == TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART) {
182 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_COMPLETED;
183 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT;
184 result->index = iterator->len;
186 result->type = TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_ERROR;
192 LOCAL VOID tadfragment_pos_iterator_initialize(tadfragment_pos_iterator_t *iterator, UB *data, W len)
194 tadlexer_le_initialize(&iterator->lexer);
195 iterator->state = TADFRAGMENT_POS_ITERATOR_STATE_BEFORE_SEGSTART;
196 iterator->data = data;
199 iterator->lexer_result_handling.result = NULL;
200 iterator->lexer_result_handling.len = 0;
201 iterator->lexer_result_handling.pos = 0;
204 LOCAL VOID tadfragment_pos_iterator_finalize(tadfragment_pos_iterator_t *iterator)
206 tadlexer_le_finalize(&iterator->lexer);
209 LOCAL Bool tadfragment_verifydata(UB *data, W len)
211 tadfragment_pos_iterator_t iterator;
212 tadfragment_pos_iterator_result result;
213 Bool cont, ret = True;
215 tadfragment_pos_iterator_initialize(&iterator, data, len);
217 cont = tadfragment_pos_iterator_next(&iterator, &result);
221 if (result.type == TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT) {
227 tadfragment_pos_iterator_finalize(&iterator);
232 EXPORT UB* tadfragment_getbuffer(tadfragment_t *fragment)
234 return bytearray_getbuffer(&fragment->rawdata);
237 EXPORT W tadfragment_getsegmentlength(tadfragment_t *fragment)
239 return wordarray_getlength(&fragment->pos);
242 EXPORT W tadfragment_getbufferlength(tadfragment_t *fragment)
244 return bytearray_getlength(&fragment->rawdata);
247 EXPORT W tadfragment_pushback(tadfragment_t *fragment, UB *data, W len)
249 tadfragment_cursor_t cursor;
252 tadfragment_cursor_initialize(&cursor, fragment);
254 num = tadfragment_getsegmentlength(fragment);
255 tadfragment_cursor_move(&cursor, num);
257 err = tadfragment_cursor_insert(&cursor, data, len);
259 tadfragment_cursor_finalize(&cursor);
264 EXPORT W tadfragment_popback(tadfragment_t *fragment)
268 len = wordarray_getlength(&fragment->pos);
270 return -1; /* TODO */
273 wordarray_getat(&fragment->pos, len-1, &val);
274 size = bytearray_getlength(&fragment->rawdata);
276 for (i = 0; i < size - val; i++) {
277 bytearray_popback(&fragment->rawdata);
279 wordarray_popback(&fragment->pos);
284 EXPORT W tadfragment_initialize(tadfragment_t *fragment)
288 err = bytearray_initialize(&fragment->rawdata);
292 err = wordarray_initialize(&fragment->pos);
294 bytearray_finalize(&fragment->rawdata);
301 EXPORT VOID tadfragment_finalize(tadfragment_t *fragment)
303 wordarray_finalize(&fragment->pos);
304 bytearray_finalize(&fragment->rawdata);
307 EXPORT W tadfragment_cursor_move(tadfragment_cursor_t *cursor, W diff)
309 return wordarray_cursor_move(&cursor->base, diff);
312 EXPORT W tadfragment_cursor_erase(tadfragment_cursor_t *cursor, W len)
314 bytearray_cursor_t bytecursor;
316 W start_pos, end_pos, diff, val, count, err;
319 return -1; /* TODO */
322 isend = tadfragment_cursor_isend(cursor);
323 if (isend != False) {
324 return -1; /* TODO */
327 wordarray_cursor_getW(&cursor->base, &start_pos);
328 err = tadfragment_cursor_move(cursor, len);
330 diff = bytearray_getlength(&cursor->target->rawdata) - start_pos;
332 wordarray_cursor_getW(&cursor->base, &end_pos);
333 tadfragment_cursor_move(cursor, -len);
335 diff = end_pos - start_pos;
338 wordarray_cursor_erase(&cursor->base, len);
340 bytearray_cursor_initialize(&bytecursor, &cursor->target->rawdata);
341 bytearray_cursor_move(&bytecursor, start_pos);
342 bytearray_cursor_erase(&bytecursor, diff);
343 bytearray_cursor_finalize(&bytecursor);
347 err = wordarray_cursor_getW(&cursor->base, &val);
349 /* TODO: error or end position */
352 wordarray_cursor_setW(&cursor->base, val - diff);
353 wordarray_cursor_move(&cursor->base, 1);
356 wordarray_cursor_move(&cursor->base, -count);
361 LOCAL W tadfragment_cursor_getnextpos(tadfragment_cursor_t *cursor, W *pos)
366 err = tadfragment_cursor_move(cursor, 1);
370 isend = tadfragment_cursor_isend(cursor);
371 if (isend != False) {
372 *pos = bytearray_getlength(&cursor->target->rawdata);
373 tadfragment_cursor_move(cursor, -1);
377 err = wordarray_cursor_getW(&cursor->base, pos);
378 tadfragment_cursor_move(cursor, -1);
383 EXPORT W tadfragment_cursor_insert(tadfragment_cursor_t *cursor, UB *data, W len)
385 bytearray_cursor_t bytecursor;
386 tadfragment_pos_iterator_t iterator;
387 tadfragment_pos_iterator_result result;
388 Bool ok, cont, isend;
389 W offset, val, err, err2;
392 return -1; /* TODO */
398 ok = tadfragment_verifydata(data, len);
400 return -1; /* TODO */
403 isend = tadfragment_cursor_isend(cursor);
404 if (isend == False) {
405 err = wordarray_cursor_getW(&cursor->base, &offset);
411 offset = bytearray_getlength(&cursor->target->rawdata);
414 bytearray_cursor_initialize(&bytecursor, &cursor->target->rawdata);
415 bytearray_cursor_move(&bytecursor, offset);
416 err = bytearray_cursor_insert(&bytecursor, data, len);
417 bytearray_cursor_finalize(&bytecursor);
422 tadfragment_pos_iterator_initialize(&iterator, data, len);
424 cont = tadfragment_pos_iterator_next(&iterator, &result);
428 if (result.type == TADFRAGMENT_POS_ITERATOR_RESULT_TYPE_SEGMENT) {
429 val = result.index + offset;
430 err = wordarray_cursor_insert(&cursor->base, &val, 1);
434 wordarray_cursor_move(&cursor->base, 1);
437 tadfragment_pos_iterator_finalize(&iterator);
440 err2 = wordarray_cursor_getW(&cursor->base, &val);
442 /* TODO: error or end position */
445 wordarray_cursor_setW(&cursor->base, val + len);
446 wordarray_cursor_move(&cursor->base, 1);
452 EXPORT Bool tadfragment_cursor_isend(tadfragment_cursor_t *cursor)
454 return wordarray_cursor_isend(&cursor->base);
457 EXPORT W tadfragment_cursor_getdata(tadfragment_cursor_t *cursor, tadfragment_cursor_segment *p)
460 W offset, offset_next, err;
463 end = tadfragment_cursor_isend(cursor);
468 err = wordarray_cursor_getW(&cursor->base, &offset);
472 err = tadfragment_cursor_getnextpos(cursor, &offset_next);
477 p->p = bytearray_getbuffer(&cursor->target->rawdata) + offset;
478 p->len = offset_next - offset;
481 if ((ch & 0xFF80) == 0xFF80) {
482 p->type = TADFRAGMENT_CURSOR_SEGMENTTYPE_VARIABLE;
483 } else if ((ch & 0xFE00) == 0xFE00) {
484 p->type = TADFRAGMENT_CURSOR_SEGMENTTYPE_LANGCODE;
486 p->type = TADFRAGMENT_CURSOR_SEGMENTTYPE_CHAR;
492 EXPORT VOID tadfragment_cursor_initialize(tadfragment_cursor_t *cursor, tadfragment_t *fragment)
494 cursor->target = fragment;
495 wordarray_cursor_initialize(&cursor->base, &fragment->pos);
498 EXPORT VOID tadfragment_cursor_finalize(tadfragment_cursor_t *cursor)
500 wordarray_cursor_finalize(&cursor->base);