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