]> git.sur5r.net Git - glabels/blob - glabels2/qrencode-3.1.0/tests/test_qrinput.c
2009-09-22 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / qrencode-3.1.0 / tests / test_qrinput.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4 #include "common.h"
5 #include "../qrinput.h"
6 #include "../qrencode_inner.h"
7 #include "../split.h"
8
9 void test_encodeKanji(void)
10 {
11         QRinput *stream;
12         unsigned char str[4]= {0x93, 0x5f,0xe4, 0xaa};
13         unsigned char *buf;
14         char correct[] = "10000000001001101100111111101010101010";
15         BitStream *bstream;
16
17         testStart("Encoding kanji stream.");
18         buf = (unsigned char *)malloc(4);
19         memcpy(buf, str, 4);
20         stream = QRinput_new();
21         QRinput_append(stream, QR_MODE_KANJI, 4, buf);
22         bstream = QRinput_mergeBitStream(stream);
23         testEnd(cmpBin(correct, bstream));
24         QRinput_free(stream);
25         BitStream_free(bstream);
26         free(buf);
27 }
28
29 void test_encode8(void)
30 {
31         QRinput *stream;
32         char str[] = "AC-42";
33         char correct[] = "0100000001010100000101000011001011010011010000110010";
34         BitStream *bstream;
35
36         testStart("Encoding 8bit stream.");
37         stream = QRinput_new();
38         QRinput_append(stream, QR_MODE_8, 5, (unsigned char *)str);
39         bstream = QRinput_mergeBitStream(stream);
40         testEnd(cmpBin(correct, bstream));
41         QRinput_free(stream);
42         BitStream_free(bstream);
43 }
44
45 void test_encode8_versionup(void)
46 {
47         QRinput *stream;
48         BitStream *bstream;
49         char *str;
50         int version;
51
52         testStart("Encoding 8bit stream. (auto-version up test)");
53         str = (char *)malloc(2900);
54         memset(str, 0xff, 2900);
55         stream = QRinput_new();
56         QRinput_append(stream, QR_MODE_8, 2900, (unsigned char *)str);
57         bstream = QRinput_mergeBitStream(stream);
58         version = QRinput_getVersion(stream);
59         assert_equal(version, 40, "Version is %d (40 expected).\n", version);
60         testFinish();
61         QRinput_free(stream);
62         BitStream_free(bstream);
63         free(str);
64 }
65
66 void test_encodeAn(void)
67 {
68         QRinput *stream;
69         char str[] = "AC-42";
70         char correct[] = "00100000001010011100111011100111001000010";
71         BitStream *bstream;
72
73         testStart("Encoding alphabet-numeric stream.");
74         stream = QRinput_new();
75         QRinput_append(stream, QR_MODE_AN, 5, (unsigned char *)str);
76         bstream = QRinput_mergeBitStream(stream);
77         testEnd(cmpBin(correct, bstream));
78         QRinput_free(stream);
79         BitStream_free(bstream);
80 }
81
82 void test_encodeAn2(void)
83 {
84         QRinput *stream;
85         char str[] = "!,;$%";
86         int ret;
87
88         testStart("Encoding INVALID alphabet-numeric stream.");
89         stream = QRinput_new();
90         ret = QRinput_append(stream, QR_MODE_AN, 5, (unsigned char *)str);
91         testEnd(!ret);
92         QRinput_free(stream);
93 }
94
95 void test_encodeNumeric(void)
96 {
97         QRinput *stream;
98         char num[9] = "01234567";
99         char correct[] = "00010000001000000000110001010110011000011";
100         BitStream *bstream;
101
102         testStart("Encoding numeric stream. (8 digits)");
103         stream = QRinput_new();
104         QRinput_append(stream, QR_MODE_NUM, 8, (unsigned char *)num);
105         bstream = QRinput_mergeBitStream(stream);
106         testEnd(cmpBin(correct, bstream));
107         QRinput_free(stream);
108         BitStream_free(bstream);
109 }
110
111 void test_encodeNumeric_versionup(void)
112 {
113         QRinput *stream;
114         BitStream *bstream;
115         char *str;
116         int version;
117
118         testStart("Encoding numeric stream. (auto-version up test)");
119         str = (char *)malloc(1050);
120         memset(str, '1', 1050);
121         stream = QRinput_new2(0, QR_ECLEVEL_L);
122         QRinput_append(stream, QR_MODE_NUM, 1050, (unsigned char *)str);
123         bstream = QRinput_mergeBitStream(stream);
124         version = QRinput_getVersion(stream);
125         assert_equal(version, 14, "Version is %d (14 expected).", version);
126         testFinish();
127         QRinput_free(stream);
128         BitStream_free(bstream);
129         free(str);
130 }
131
132 void test_encodeNumericPadded(void)
133 {
134         QRinput *stream;
135         char num[9] = "01234567";
136         char *correct;
137         char *correctHead = "000100000010000000001100010101100110000110000000";
138         BitStream *bstream;
139         int flag, i;
140
141         testStart("Encoding numeric stream. (8 digits)(padded)");
142         stream = QRinput_new();
143         QRinput_append(stream, QR_MODE_NUM, 8, (unsigned char *)num);
144         bstream = QRinput_getBitStream(stream);
145         correct = (char *)malloc(19 * 8 + 1);
146         correct[0] = '\0';
147         strcat(correct, correctHead);
148         for(i=0; i<13; i++) {
149                 strcat(correct, (i&1)?"00010001":"11101100");
150         }
151         flag = cmpBin(correct, bstream);
152         testEnd(flag);
153
154         free(correct);
155         QRinput_free(stream);
156         BitStream_free(bstream);
157 }
158
159 void test_encodeNumericPadded2(void)
160 {
161         QRinput *stream;
162         char num[8] = "0123456";
163         char *correct;
164         char *correctHead = "000100000001110000001100010101100101100000000000";
165         BitStream *bstream;
166         int flag, i;
167
168         testStart("Encoding numeric stream. (7 digits)(padded)");
169         stream = QRinput_new();
170         QRinput_append(stream, QR_MODE_NUM, 7, (unsigned char *)num);
171         bstream = QRinput_getBitStream(stream);
172         correct = (char *)malloc(19 * 8 + 1);
173         correct[0] = '\0';
174         strcat(correct, correctHead);
175         for(i=0; i<13; i++) {
176                 strcat(correct, (i&1)?"00010001":"11101100");
177         }
178         flag = cmpBin(correct, bstream);
179         testEnd(flag);
180
181         free(correct);
182         QRinput_free(stream);
183         BitStream_free(bstream);
184 }
185
186 void test_padding(void)
187 {
188         QRinput *input;
189         BitStream *bstream;
190         int i, size;
191         char data[] = "0123456789ABCDeFG";
192         unsigned char c;
193
194         testStart("Padding bit check. (less than 5 bits)");
195         input = QRinput_new2(0, QR_ECLEVEL_L);
196         QRinput_append(input, QR_MODE_8, 17, (unsigned char *)data);
197         bstream = QRinput_getBitStream(input);
198         size = BitStream_size(bstream);
199         assert_equal(size, 152, "# of bit is incorrect (%d != 152).\n", size);
200         c = 0;
201         for(i=0; i<4; i++) {
202                 c += bstream->data[size - i - 1];
203         }
204         assert_zero(c, "Padding bits are not zero.");
205         testFinish();
206
207         QRinput_free(input);
208         BitStream_free(bstream);
209 }
210
211 void test_padding2(void)
212 {
213         QRinput *input;
214         BitStream *bstream;
215         int i, size, ret;
216         char data[] = "0123456789ABCDeF";
217         char correct[153];
218         unsigned char c;
219
220         testStart("Padding bit check. (1 or 2 padding bytes)");
221
222         /* 16 byte data (4 bit terminator and 1 byte padding) */
223         memset(correct, 0, 153);
224         memcpy(correct, "010000010000", 12);
225         for(size=0; size<16; size++) {
226                 c = 0x80;
227                 for(i=0; i<8; i++) {
228                         correct[size * 8 + i + 12] = (data[size]&c)?'1':'0';
229                         c = c >> 1;
230                 }
231         }
232         memcpy(correct + 140, "000011101100", 12);
233
234         input = QRinput_new2(1, QR_ECLEVEL_L);
235         QRinput_append(input, QR_MODE_8, 16, (unsigned char *)data);
236         bstream = QRinput_getBitStream(input);
237         size = BitStream_size(bstream);
238         assert_equal(size, 152, "16byte: # of bit is incorrect (%d != 152).\n", size);
239         ret = ncmpBin(correct, bstream, 152);
240         assert_zero(ret, "Padding bits incorrect.\n");
241
242         QRinput_free(input);
243         BitStream_free(bstream);
244
245         /* 15 byte data (4 bit terminator and 2 byte paddings) */
246
247         memcpy(correct, "010000001111", 12);
248         memcpy(correct + 132, "00001110110000010001", 20);
249
250         input = QRinput_new2(1, QR_ECLEVEL_L);
251         QRinput_append(input, QR_MODE_8, 15, (unsigned char *)data);
252         bstream = QRinput_getBitStream(input);
253         size = BitStream_size(bstream);
254         assert_equal(size, 152, "15byte: # of bit is incorrect (%d != 152).\n", size);
255         ret = ncmpBin(correct, bstream, 152);
256         assert_zero(ret, "Padding bits incorrect.\n");
257
258         testFinish();
259
260         QRinput_free(input);
261         BitStream_free(bstream);
262 }
263
264 void test_encodeNumeric2(void)
265 {
266         QRinput *stream;
267         char num[] = "0123456789012345";
268         char correct[] = "00010000010000000000110001010110011010100110111000010100111010100101";
269         BitStream *bstream;
270
271         testStart("Encoding numeric stream. (16 digits)");
272         stream = QRinput_new();
273         QRinput_append(stream, QR_MODE_NUM, 16, (unsigned char *)num);
274         bstream = QRinput_mergeBitStream(stream);
275         testEnd(cmpBin(correct, bstream));
276         QRinput_free(stream);
277         BitStream_free(bstream);
278 }
279
280 void test_encodeNumeric3(void)
281 {
282         QRinput *stream;
283         char num[9] = "0123456";
284         char correct[] = "0001""0000000111""0000001100""0101011001""0110";
285         BitStream *bstream;
286
287         testStart("Encoding numeric stream. (7 digits)");
288         stream = QRinput_new();
289         QRinput_append(stream, QR_MODE_NUM, 7, (unsigned char *)num);
290         bstream = QRinput_mergeBitStream(stream);
291         testEnd(cmpBin(correct, bstream));
292         QRinput_free(stream);
293         BitStream_free(bstream);
294 }
295
296 void test_encodeTooLong(void)
297 {
298         QRinput *stream;
299         unsigned char *data;
300         BitStream *bstream;
301
302         data = (unsigned char *)malloc(4297);
303         memset(data, 'A', 4297);
304
305         testStart("Encoding long string. (4297 bytes of alphanumeric)");
306         stream = QRinput_new();
307         QRinput_append(stream, QR_MODE_AN, 4297, data);
308         bstream = QRinput_mergeBitStream(stream);
309         testEndExp(bstream == NULL);
310         QRinput_free(stream);
311         if(bstream != NULL) {
312                 BitStream_free(bstream);
313         }
314         free(data);
315 }
316
317 void test_encodeAnNum(void)
318 {
319         QRinput *input;
320         BitStream *bstream;
321
322         testStart("Bit length check of alpha-numeric stream. (11 + 12)");
323         input = QRinput_new();
324         QRinput_append(input, QR_MODE_AN, 11, (unsigned char *)"ABCDEFGHIJK");
325         QRinput_append(input, QR_MODE_NUM, 12, (unsigned char *)"123456789012");
326         bstream = QRinput_mergeBitStream(input);
327         testEndExp(BitStream_size(bstream) == 128);
328         QRinput_free(input);
329         BitStream_free(bstream);
330
331         testStart("Bit length check of alphabet stream. (23)");
332         input = QRinput_new();
333         QRinput_append(input, QR_MODE_AN, 23, (unsigned char *)"ABCDEFGHIJK123456789012");
334         bstream = QRinput_mergeBitStream(input);
335         testEndExp(BitStream_size(bstream) == 140);
336         QRinput_free(input);
337         BitStream_free(bstream);
338 }
339
340 void test_struct_listop(void)
341 {
342         QRinput_Struct *s;
343         QRinput *inputs[5];
344         QRinput_InputList *l;
345         int i, ret;
346
347         testStart("QRinput_Struct list operation test.");
348         s = QRinput_Struct_new();
349         QRinput_Struct_setParity(s, 10);
350         assert_nonnull(s, "QRinput_Struct_new() failed.");
351         assert_equal(s->parity, 10, "QRinput_Struct_setParity() failed.");
352
353         for(i=0; i<5; i++) {
354                 inputs[i] = QRinput_new();
355                 QRinput_append(inputs[i], QR_MODE_AN, 5, (unsigned char *)"ABCDE");
356                 ret = QRinput_Struct_appendInput(s, inputs[i]);
357         }
358         assert_equal(ret, 5, "QRinput_Struct_appendInput() returns wrong num?");
359         assert_equal(s->size, 5, "QRiput_Struct.size counts wrong number.");
360
361         l = s->head;
362         i = 0;
363         while(l != NULL) {
364                 assert_equal(l->input, inputs[i], "QRinput_Struct input list order would be wrong?");
365                 l = l->next;
366                 i++;
367         }
368
369         QRinput_Struct_free(s);
370         testFinish();
371 }
372
373 void test_insertStructuredAppendHeader(void)
374 {
375         QRinput *stream;
376         char correct[] = "0011000011111010010101000000000101000001";
377         BitStream *bstream;
378         int ret;
379
380         testStart("Insert a structured-append header");
381         stream = QRinput_new();
382         QRinput_append(stream, QR_MODE_8, 1, (unsigned char *)"A");
383         ret = QRinput_insertStructuredAppendHeader(stream, 16, 1, 0xa5);
384         assert_zero(ret, "QRinput_insertStructuredAppendHeader() returns nonzero.\n");
385         bstream = QRinput_mergeBitStream(stream);
386         assert_nonnull(bstream->data, "Bstream->data is null.");
387         assert_zero(cmpBin(correct, bstream), "bitstream is wrong.");
388         testFinish();
389
390         QRinput_free(stream);
391         BitStream_free(bstream);
392 }
393
394 void test_insertStructuredAppendHeader_error(void)
395 {
396         QRinput *stream;
397         int ret;
398
399         testStart("Insert a structured-append header (errors expected)");
400         stream = QRinput_new();
401         QRinput_append(stream, QR_MODE_8, 1, (unsigned char *)"A");
402         ret = QRinput_insertStructuredAppendHeader(stream, 17, 1, 0xa5);
403         assert_equal(-1, ret, "QRinput_insertStructuredAppendHeader() returns 0.");
404         assert_equal(EINVAL, errno, "errno is not set correctly (%d returned).", errno);
405         ret = QRinput_insertStructuredAppendHeader(stream, 16, 17, 0xa5);
406         assert_equal(-1, ret, "QRinput_insertStructuredAppendHeader() returns 0.");
407         assert_equal(EINVAL, errno, "errno is not set correctly (%d returned).", errno);
408         ret = QRinput_insertStructuredAppendHeader(stream, 16, 0, 0xa5);
409         assert_equal(-1, ret, "QRinput_insertStructuredAppendHeader() returns 0.");
410         assert_equal(EINVAL, errno, "errno is not set correctly (%d returned).", errno);
411         testFinish();
412
413         QRinput_free(stream);
414 }
415
416 void test_struct_insertStructuredAppendHeaders(void)
417 {
418         QRinput *input;
419         QRinput_Struct *s;
420         QRinput_InputList *p;
421         int i;
422
423         testStart("Insert structured-append headers to a QRinput_Struct.");
424         s = QRinput_Struct_new();
425         for(i=0; i<10; i++) {
426                 input = QRinput_new();
427                 QRinput_append(input, QR_MODE_8, 1, (unsigned char *)"A");
428                 QRinput_Struct_appendInput(s, input);
429         }
430         QRinput_Struct_insertStructuredAppendHeaders(s);
431         p = s->head;
432         i = 1;
433         while(p != NULL) {
434                 assert_equal(p->input->head->mode, QR_MODE_STRUCTURE, "a structured-append header is not inserted.");
435                 assert_equal(p->input->head->data[0], 10, "size of the structured-header is wrong: #%d, %d should be %d\n", i, p->input->head->data[0], 10);
436                 assert_equal(p->input->head->data[1], i, "index of the structured-header is wrong: #%d, %d should be %d\n", i, p->input->head->data[1], i);
437                 assert_equal(p->input->head->data[2], 0, "parity of the structured-header is wrong: #%d\n", i);
438                 p = p->next;
439                 i++;
440         }
441         testFinish();
442         QRinput_Struct_free(s);
443 }
444
445 static int check_lengthOfCode(QRencodeMode mode, char *data, int size, int version)
446 {
447         QRinput *input;
448         BitStream *b;
449         int bits;
450         int bytes;
451
452         input = QRinput_new();
453         QRinput_setVersion(input, version);
454         QRinput_append(input, mode, size, (unsigned char *)data);
455         b = QRinput_mergeBitStream(input);
456         bits = BitStream_size(b);
457         bytes = QRinput_lengthOfCode(mode, version, bits);
458         QRinput_free(input);
459         BitStream_free(b);
460
461         return bytes;
462 }
463
464 void test_lengthOfCode_num(void)
465 {
466         int i, bytes;
467         char *data;
468
469         data = (char *)malloc(8000);
470         for(i=0; i<8000; i++) {
471                 data[i] = '0' + i % 10;
472         }
473
474         testStart("Checking length of code (numeric)");
475         for(i=1; i<=9; i++) {
476                 bytes = check_lengthOfCode(QR_MODE_NUM, data, i, 1);
477                 assert_equal(i, bytes, "lengthOfCode failed. (QR_MODE_NUM, version:1, size:%d)\n", i);
478         }
479         for(i=1023; i<=1025; i++) {
480                 bytes = check_lengthOfCode(QR_MODE_NUM, data, i, 1);
481                 assert_equal(1023, bytes, "lengthOfCode failed. (QR_MODE_NUM, version:1, size:%d)\n", i);
482         }
483         testFinish();
484         free(data);
485 }
486
487 void test_lengthOfCode_kanji(void)
488 {
489         int i, bytes;
490         unsigned char str[4]= {0x93, 0x5f,0xe4, 0xaa};
491
492         testStart("Checking length of code (kanji)");
493         for(i=2; i<=4; i+=2) {
494                 bytes = check_lengthOfCode(QR_MODE_KANJI, (char *)str, i, 1);
495                 assert_equal(i, bytes, "lengthOfCode failed. (QR_MODE_KANJI, version:1, size:%d)\n", i);
496         }
497         testFinish();
498 }
499
500 void test_struct_split_example(void)
501 {
502         QRinput *input;
503         QRinput_Struct *s;
504         QRinput_InputList *e;
505         QRinput_List *l;
506         const char *str[4] = { "an example ", "of four Str", "uctured Appe", "nd symbols,"};
507         int i;
508         BitStream *bstream;
509
510         testStart("Testing the example of structured-append symbols");
511         s = QRinput_Struct_new();
512         for(i=0; i<4; i++) {
513                 input = QRinput_new2(1, QR_ECLEVEL_M);
514                 QRinput_append(input, QR_MODE_8, strlen(str[i]), (unsigned char *)str[i]);
515                 QRinput_Struct_appendInput(s, input);
516         }
517         QRinput_Struct_insertStructuredAppendHeaders(s);
518         e = s->head;
519         i = 0;
520         while(e != NULL) {
521                 bstream = QRinput_mergeBitStream(e->input);
522                 BitStream_free(bstream);
523                 l = e->input->head->next;
524                 assert_equal(l->mode, QR_MODE_8, "#%d: wrong mode (%d).\n", i, l->mode);
525                 assert_equal(e->input->level, QR_ECLEVEL_M, "#%d: wrong level (%d).\n", i, e->input->level);
526
527                 e = e->next;
528                 i++;
529         }
530         testFinish();
531         QRinput_Struct_free(s);
532 }
533
534 void test_struct_split_tooLarge(void)
535 {
536         QRinput *input;
537         QRinput_Struct *s;
538         char *str;
539         int errsv;
540
541         testStart("Testing structured-append symbols. (too large data)");
542         str = (char *)malloc(128);
543         memset(str, 'a', 128);
544         input = QRinput_new2(1, QR_ECLEVEL_H);
545         QRinput_append(input, QR_MODE_8, 128, (unsigned char *)str);
546         s = QRinput_splitQRinputToStruct(input);
547         errsv = errno;
548         assert_null(s, "returns non-null.");
549         assert_equal(errsv, ERANGE, "did not return ERANGE.");
550         testFinish();
551         if(s != NULL) QRinput_Struct_free(s);
552         QRinput_free(input);
553         free(str);
554 }
555
556 void test_struct_split_invalidVersion(void)
557 {
558         QRinput *input;
559         QRinput_Struct *s;
560         char *str;
561         int errsv;
562
563         testStart("Testing structured-append symbols. (invalid version 0)");
564         str = (char *)malloc(128);
565         memset(str, 'a', 128);
566         input = QRinput_new2(0, QR_ECLEVEL_H);
567         QRinput_append(input, QR_MODE_8, 128, (unsigned char *)str);
568         s = QRinput_splitQRinputToStruct(input);
569         errsv = errno;
570         assert_null(s, "returns non-null.");
571         assert_equal(errsv, ERANGE, "did not return ERANGE.");
572         testFinish();
573         if(s != NULL) QRinput_Struct_free(s);
574         QRinput_free(input);
575         free(str);
576 }
577
578 void test_splitentry(void)
579 {
580         QRinput *i1, *i2;
581         QRinput_List *e;
582         const char *str = "abcdefghij";
583         int size1, size2, i;
584         unsigned char *d1, *d2;
585
586         testStart("Testing QRinput_splitEntry. (next == NULL)");
587         i1 = QRinput_new();
588         QRinput_append(i1, QR_MODE_8, strlen(str), (unsigned char *)str);
589
590         i2 = QRinput_dup(i1);
591         e = i2->head;
592
593         e = i2->head;
594         QRinput_splitEntry(e, 4);
595
596         size1 = size2 = 0;
597         e = i1->head;
598         while(e != NULL) {
599                 size1 += e->size;
600                 e = e->next;
601         }
602         e = i2->head;
603         while(e != NULL) {
604                 size2 += e->size;
605                 e = e->next;
606         }
607
608         d1 = (unsigned char *)malloc(size1);
609         e = i1->head;
610         i = 0;
611         while(e != NULL) {
612                 memcpy(&d1[i], e->data, e->size);
613                 i += e->size;
614                 e = e->next;
615         }
616         d2 = (unsigned char *)malloc(size2);
617         e = i2->head;
618         i = 0;
619         while(e != NULL) {
620                 memcpy(&d2[i], e->data, e->size);
621                 i += e->size;
622                 e = e->next;
623         }
624
625         assert_equal(size1, size2, "sizes are different. (%d:%d)\n", size1, size2);
626         assert_equal(i2->head->size, 4, "split failed (first half)");
627         assert_equal(i2->head->next->size, 6, "split failed(second half)");
628         assert_zero(memcmp(d1, d2, size1), "strings are different.");
629         QRinput_free(i1);
630         QRinput_free(i2);
631         free(d1);
632         free(d2);
633
634         testFinish();
635 }
636
637 void test_splitentry2(void)
638 {
639         QRinput *i1, *i2;
640         QRinput_List *e;
641         const char *str = "abcdefghij";
642         int size1, size2, i;
643         unsigned char *d1, *d2;
644
645         testStart("Testing QRinput_splitEntry. (next != NULL)");
646         i1 = QRinput_new();
647         QRinput_append(i1, QR_MODE_8, strlen(str), (unsigned char *)str);
648         QRinput_append(i1, QR_MODE_8, strlen(str), (unsigned char *)str);
649
650         i2 = QRinput_dup(i1);
651         e = i2->head;
652
653         e = i2->head;
654         QRinput_splitEntry(e, 4);
655
656         size1 = size2 = 0;
657         e = i1->head;
658         while(e != NULL) {
659                 size1 += e->size;
660                 e = e->next;
661         }
662         e = i2->head;
663         while(e != NULL) {
664                 size2 += e->size;
665                 e = e->next;
666         }
667
668         d1 = (unsigned char *)malloc(size1);
669         e = i1->head;
670         i = 0;
671         while(e != NULL) {
672                 memcpy(&d1[i], e->data, e->size);
673                 i += e->size;
674                 e = e->next;
675         }
676         d2 = (unsigned char *)malloc(size2);
677         e = i2->head;
678         i = 0;
679         while(e != NULL) {
680                 memcpy(&d2[i], e->data, e->size);
681                 i += e->size;
682                 e = e->next;
683         }
684
685         assert_equal(size1, size2, "sizes are different. (%d:%d)\n", size1, size2);
686         assert_equal(i2->head->size, 4, "split failed (first half)");
687         assert_equal(i2->head->next->size, 6, "split failed(second half)");
688         assert_zero(memcmp(d1, d2, size1), "strings are different.");
689         QRinput_free(i1);
690         QRinput_free(i2);
691         free(d1);
692         free(d2);
693
694         testFinish();
695 }
696
697 void test_splitentry3(void)
698 {
699         QRinput *input;
700         QRinput_Struct *s;
701         QRinput_List *e00, *e01, *e10, *e11;
702         QRinput_InputList *list;
703         const char *str = "abcdefghijklmno";
704
705         testStart("Testing QRinput_splitEntry. (does not split an entry)");
706         /* version 1 symbol contains 152 bit (19 byte) data.
707          * 20 bits for a structured-append header, so 132 bits can be used.
708          * 15 bytes of 8-bit data is suitable for the symbol.
709          * (mode(4) + length(8) + data(120) == 132.)
710          */
711         input = QRinput_new2(1, QR_ECLEVEL_L);
712         QRinput_append(input, QR_MODE_8, strlen(str), (unsigned char *)str);
713         QRinput_append(input, QR_MODE_8, strlen(str), (unsigned char *)str);
714         s = QRinput_splitQRinputToStruct(input);
715         list = s->head;
716         e00 = list->input->head;
717         e01 = e00->next;
718         list = list->next;
719         e10 = list->input->head;
720         e11 = e00->next;
721         
722         assert_equal(e00->mode, QR_MODE_STRUCTURE, "Structure header is missing?");
723         assert_equal(e01->mode, QR_MODE_8, "no data?!");
724         assert_null(e01->next, "Input list is not terminated!\n");
725         assert_equal(e10->mode, QR_MODE_STRUCTURE, "Structure header is missing?");
726         assert_equal(e11->mode, QR_MODE_8, "no data?!");
727         assert_null(e11->next, "Input list is not terminated!\n");
728
729         QRinput_free(input);
730         QRinput_Struct_free(s);
731         testFinish();
732 }
733
734 void test_parity(void)
735 {
736         QRinput *input;
737         QRinput_Struct *s;
738         const char *text = "an example of four Structured Append symbols,";
739         const char *str[4] = {
740                 "an example ",
741                 "of four Str",
742                 "uctured Appe",
743                 "nd symbols,"};
744         unsigned char p1, p2;
745         int i, len;
746
747         testStart("Testing parity calc.");
748         s = QRinput_Struct_new();
749         for(i=0; i<4; i++) {
750                 input = QRinput_new2(1, QR_ECLEVEL_M);
751                 QRinput_append(input, QR_MODE_8, strlen(str[i]), (unsigned char *)str[i]);
752                 QRinput_Struct_appendInput(s, input);
753         }
754         QRinput_Struct_insertStructuredAppendHeaders(s);
755         p1 = s->parity;
756
757         p2 = 0;
758         len = strlen(text);
759         for(i=0; i<len; i++) {
760                 p2 ^= text[i];
761         }
762         assert_equal(p1, p2, "Parity numbers didn't match. (%02x should be %02x).\n", p1, p2);
763         testFinish();
764         QRinput_Struct_free(s);
765 }
766
767 void test_parity2(void)
768 {
769         QRinput *input;
770         QRinput_Struct *s;
771         const char *text = "an example of four Structured Append symbols,";
772         unsigned char p1, p2;
773         int i, len;
774
775         testStart("Testing parity calc.(split)");
776         input = QRinput_new2(1, QR_ECLEVEL_L);
777         QRinput_append(input, QR_MODE_8, strlen(text), (unsigned char *)text);
778         s = QRinput_splitQRinputToStruct(input);
779         p1 = s->parity;
780
781         p2 = 0;
782         len = strlen(text);
783         for(i=0; i<len; i++) {
784                 p2 ^= text[i];
785         }
786         assert_equal(p1, p2, "Parity numbers didn't match. (%02x should be %02x).\n", p1, p2);
787         testFinish();
788         QRinput_free(input);
789         QRinput_Struct_free(s);
790 }
791
792 void test_null_free(void)
793 {
794         testStart("Testing free NULL pointers");
795         assert_nothing(QRinput_free(NULL), "Check QRinput_free(NULL).\n");
796         assert_nothing(QRinput_Struct_free(NULL), "Check QRinput_Struct_free(NULL).\n");
797         testFinish();
798 }
799
800 int main(int argc, char **argv)
801 {
802         test_encodeNumeric();
803         test_encodeNumeric2();
804         test_encodeNumeric3();
805         test_encodeNumeric_versionup();
806         test_encode8();
807         test_encode8_versionup();
808         test_encodeTooLong();
809         test_encodeAn();
810         test_encodeAn2();
811         test_encodeKanji();
812         test_encodeNumericPadded();
813         test_encodeNumericPadded2();
814         test_encodeAnNum();
815         test_padding();
816         test_padding2();
817         test_struct_listop();
818         test_insertStructuredAppendHeader();
819         test_insertStructuredAppendHeader_error();
820         test_struct_insertStructuredAppendHeaders();
821         test_lengthOfCode_num();
822         test_splitentry();
823         test_splitentry2();
824         test_splitentry3();
825         test_struct_split_example();
826         test_struct_split_tooLarge();
827         test_struct_split_invalidVersion();
828         test_parity();
829         test_parity2();
830         test_null_free();
831
832         report();
833
834         return 0;
835 }