6f1a1a274e
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
175 lines
2.9 KiB
C
175 lines
2.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <iconv.h>
|
|
#include "datachunk.h"
|
|
|
|
DataChunk *DataChunk_new(QRencodeMode mode)
|
|
{
|
|
DataChunk *chunk;
|
|
|
|
chunk = (DataChunk *)calloc(1, sizeof(DataChunk));
|
|
if(chunk == NULL) return NULL;
|
|
|
|
chunk->mode = mode;
|
|
|
|
return chunk;
|
|
}
|
|
|
|
void DataChunk_free(DataChunk *chunk)
|
|
{
|
|
if(chunk) {
|
|
if(chunk->data) free(chunk->data);
|
|
free(chunk);
|
|
}
|
|
}
|
|
|
|
void DataChunk_freeList(DataChunk *list)
|
|
{
|
|
DataChunk *next;
|
|
|
|
while(list != NULL) {
|
|
next = list->next;
|
|
DataChunk_free(list);
|
|
list = next;
|
|
}
|
|
}
|
|
|
|
static void dumpNum(DataChunk *chunk)
|
|
{
|
|
printf("%s\n", chunk->data);
|
|
}
|
|
|
|
static void dumpAn(DataChunk *chunk)
|
|
{
|
|
printf("%s\n", chunk->data);
|
|
}
|
|
|
|
static void dump8(DataChunk *chunk)
|
|
{
|
|
int i, j;
|
|
unsigned char c;
|
|
int count = 0;
|
|
unsigned char buf[16];
|
|
|
|
for(i=0; i<chunk->size; i++) {
|
|
buf[count] = chunk->data[i];
|
|
c = chunk->data[i];
|
|
if(c >= ' ' && c <= '~') {
|
|
putchar(c);
|
|
} else {
|
|
putchar('.');
|
|
}
|
|
count++;
|
|
|
|
if(count >= 16) {
|
|
putchar(' ');
|
|
for(j=0; j<16; j++) {
|
|
printf(" %02x", buf[j]);
|
|
}
|
|
count = 0;
|
|
putchar('\n');
|
|
}
|
|
}
|
|
if(count > 0) {
|
|
for(i=0; i<16 - count; i++) {
|
|
putchar(' ');
|
|
}
|
|
putchar(' ');
|
|
for(j=0; j<count; j++) {
|
|
printf(" %02x", buf[j]);
|
|
}
|
|
count = 0;
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
static void dumpKanji(DataChunk *chunk)
|
|
{
|
|
iconv_t conv;
|
|
char *inbuf, *outbuf, *outp;
|
|
size_t inbytes, outbytes, ret;
|
|
|
|
conv = iconv_open("UTF-8", "SHIFT_JIS");
|
|
inbytes = chunk->size;
|
|
inbuf = (char *)chunk->data;
|
|
outbytes = inbytes * 4 + 1;
|
|
outbuf = (char *)malloc(inbytes * 4 + 1);
|
|
outp = outbuf;
|
|
ret = iconv(conv, &inbuf, &inbytes, &outp, &outbytes);
|
|
if(ret == (size_t) -1) { perror(NULL); }
|
|
*outp = '\0';
|
|
|
|
printf("%s\n", outbuf);
|
|
|
|
iconv_close(conv);
|
|
free(outbuf);
|
|
}
|
|
|
|
static void dumpChunk(DataChunk *chunk)
|
|
{
|
|
switch(chunk->mode) {
|
|
case QR_MODE_NUM:
|
|
printf("Numeric: %d bytes\n", chunk->size);
|
|
dumpNum(chunk);
|
|
break;
|
|
case QR_MODE_AN:
|
|
printf("AlphaNumeric: %d bytes\n", chunk->size);
|
|
dumpAn(chunk);
|
|
break;
|
|
case QR_MODE_8:
|
|
printf("8-bit data: %d bytes\n", chunk->size);
|
|
dump8(chunk);
|
|
break;
|
|
case QR_MODE_KANJI:
|
|
printf("Kanji: %d bytes\n", chunk->size);
|
|
dumpKanji(chunk);
|
|
break;
|
|
default:
|
|
printf("Invalid or reserved: %d bytes\n", chunk->size);
|
|
dump8(chunk);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DataChunk_dumpChunkList(DataChunk *list)
|
|
{
|
|
while(list != NULL) {
|
|
dumpChunk(list);
|
|
list = list->next;
|
|
}
|
|
}
|
|
|
|
int DataChunk_totalSize(DataChunk *list)
|
|
{
|
|
int size = 0;
|
|
|
|
while(list != NULL) {
|
|
size += list->size;
|
|
list = list->next;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
unsigned char *DataChunk_concatChunkList(DataChunk *list, int *retsize)
|
|
{
|
|
int size, idx;
|
|
unsigned char *data;
|
|
|
|
size = DataChunk_totalSize(list);
|
|
if(size <= 0) return NULL;
|
|
|
|
data = (unsigned char *)malloc(size + 1);
|
|
idx = 0;
|
|
while(list != NULL) {
|
|
memcpy(&data[idx], list->data, list->size);
|
|
idx += list->size;
|
|
list = list->next;
|
|
}
|
|
data[size] = '\0';
|
|
|
|
*retsize = size;
|
|
return data;
|
|
}
|