1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <iconv.h>
5 #include "datachunk.h"
6
DataChunk_new(QRencodeMode mode)7 DataChunk *DataChunk_new(QRencodeMode mode)
8 {
9 DataChunk *chunk;
10
11 chunk = (DataChunk *)calloc(1, sizeof(DataChunk));
12 if(chunk == NULL) return NULL;
13
14 chunk->mode = mode;
15
16 return chunk;
17 }
18
DataChunk_free(DataChunk * chunk)19 void DataChunk_free(DataChunk *chunk)
20 {
21 if(chunk) {
22 if(chunk->data) free(chunk->data);
23 free(chunk);
24 }
25 }
26
DataChunk_freeList(DataChunk * list)27 void DataChunk_freeList(DataChunk *list)
28 {
29 DataChunk *next;
30
31 while(list != NULL) {
32 next = list->next;
33 DataChunk_free(list);
34 list = next;
35 }
36 }
37
dumpNum(DataChunk * chunk)38 static void dumpNum(DataChunk *chunk)
39 {
40 printf("%s\n", chunk->data);
41 }
42
dumpAn(DataChunk * chunk)43 static void dumpAn(DataChunk *chunk)
44 {
45 printf("%s\n", chunk->data);
46 }
47
dump8(DataChunk * chunk)48 static void dump8(DataChunk *chunk)
49 {
50 int i, j;
51 unsigned char c;
52 int count = 0;
53 unsigned char buf[16];
54
55 for(i=0; i<chunk->size; i++) {
56 buf[count] = chunk->data[i];
57 c = chunk->data[i];
58 if(c >= ' ' && c <= '~') {
59 putchar(c);
60 } else {
61 putchar('.');
62 }
63 count++;
64
65 if(count >= 16) {
66 putchar(' ');
67 for(j=0; j<16; j++) {
68 printf(" %02x", buf[j]);
69 }
70 count = 0;
71 putchar('\n');
72 }
73 }
74 if(count > 0) {
75 for(i=0; i<16 - count; i++) {
76 putchar(' ');
77 }
78 putchar(' ');
79 for(j=0; j<count; j++) {
80 printf(" %02x", buf[j]);
81 }
82 count = 0;
83 putchar('\n');
84 }
85 }
86
dumpKanji(DataChunk * chunk)87 static void dumpKanji(DataChunk *chunk)
88 {
89 iconv_t conv;
90 char *inbuf, *outbuf, *outp;
91 size_t inbytes, outbytes, ret;
92
93 conv = iconv_open("UTF-8", "SHIFT_JIS");
94 inbytes = chunk->size;
95 inbuf = (char *)chunk->data;
96 outbytes = inbytes * 4 + 1;
97 outbuf = (char *)malloc(inbytes * 4 + 1);
98 outp = outbuf;
99 ret = iconv(conv, &inbuf, &inbytes, &outp, &outbytes);
100 if(ret == (size_t) -1) { perror(NULL); }
101 *outp = '\0';
102
103 printf("%s\n", outbuf);
104
105 iconv_close(conv);
106 free(outbuf);
107 }
108
dumpChunk(DataChunk * chunk)109 static void dumpChunk(DataChunk *chunk)
110 {
111 switch(chunk->mode) {
112 case QR_MODE_NUM:
113 printf("Numeric: %d bytes\n", chunk->size);
114 dumpNum(chunk);
115 break;
116 case QR_MODE_AN:
117 printf("AlphaNumeric: %d bytes\n", chunk->size);
118 dumpAn(chunk);
119 break;
120 case QR_MODE_8:
121 printf("8-bit data: %d bytes\n", chunk->size);
122 dump8(chunk);
123 break;
124 case QR_MODE_KANJI:
125 printf("Kanji: %d bytes\n", chunk->size);
126 dumpKanji(chunk);
127 break;
128 default:
129 printf("Invalid or reserved: %d bytes\n", chunk->size);
130 dump8(chunk);
131 break;
132 }
133 }
134
DataChunk_dumpChunkList(DataChunk * list)135 void DataChunk_dumpChunkList(DataChunk *list)
136 {
137 while(list != NULL) {
138 dumpChunk(list);
139 list = list->next;
140 }
141 }
142
DataChunk_totalSize(DataChunk * list)143 int DataChunk_totalSize(DataChunk *list)
144 {
145 int size = 0;
146
147 while(list != NULL) {
148 size += list->size;
149 list = list->next;
150 }
151
152 return size;
153 }
154
DataChunk_concatChunkList(DataChunk * list,int * retsize)155 unsigned char *DataChunk_concatChunkList(DataChunk *list, int *retsize)
156 {
157 int size, idx;
158 unsigned char *data;
159
160 size = DataChunk_totalSize(list);
161 if(size <= 0) return NULL;
162
163 data = (unsigned char *)malloc(size + 1);
164 idx = 0;
165 while(list != NULL) {
166 memcpy(&data[idx], list->data, list->size);
167 idx += list->size;
168 list = list->next;
169 }
170 data[size] = '\0';
171
172 *retsize = size;
173 return data;
174 }
175