/* * Copyright (c) 2011 Lingua-Systems Software GmbH * * This application uses Lingua-Systems' AutoUniConv software library. * * For more information on AutoUniConv visit * http://www.lingua-systems.com/unicode-converter/autouniconv-library/ */ /* * LICENSE TERMS * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ #include #include #include #include #define READ_BUFFER_SIZE 4096 typedef struct { size_t len; char *bytes; } rf_t; rf_t *read_file(FILE *); int main(int argc, char *argv[]) { FILE *fh = stdin; rf_t *rf = NULL; auc_bytes_t *b = NULL; /* Handle command line arguments */ if (argc == 2 && strcmp(argv[1], "-")) { if (!(fh = fopen(argv[1], "rb"))) { fprintf(stderr, "Error: %s: failed to open\n", argv[1]); return EXIT_FAILURE; } } else if (argc > 2) { fprintf(stderr, "usage: %s [input-file]\n", argv[0]); return EXIT_FAILURE; } /* Read input text from file/stdin */ rf = read_file(fh); /* Call AutoUniConv's auc_nconv() to automatically detect and recode * the input text to UTF-8 */ b = auc_nconv(rf->bytes, rf->len, AUC_UTF8, AUC_DEFAULT + AUC_WARN); if (! b) { fprintf(stderr, "Error: auc: %s\n", auc_strerror(auc_errno)); return EXIT_FAILURE; } /* Output UTF-8 text */ printf("%s", b->bytes); /* Cleanup auc_bytes_t structure */ auc_free_bytes_t(b); return EXIT_SUCCESS; } /* * Reads a file's content to memory */ rf_t *read_file(FILE *fp) { rf_t *rf = NULL; size_t read = 0; char buf[READ_BUFFER_SIZE]; if (!(rf = (rf_t *) malloc(sizeof(rf_t)))) { fputs("Error: Failed to allocate memory\n", stderr); exit(EXIT_FAILURE); } rf->bytes = NULL; rf->len = 0; while ((read = fread(buf, 1, READ_BUFFER_SIZE, fp))) { if (rf->bytes && rf->len + read + 1 <= read) { fputs("Error: Input file too large\n", stderr); exit(EXIT_FAILURE); } if (!(rf->bytes = realloc(rf->bytes, rf->len + read + 1))) { fputs("Error: Failed to allocate memory\n", stderr); exit(EXIT_FAILURE); } if (!(memcpy(rf->bytes + rf->len, buf, read))) { fputs("Error: Failed to copy content to memory\n", stderr); exit(EXIT_FAILURE); } rf->len += read; } if (!(feof(fp)) || ferror(fp)) { fputs("Error: Failed to read file\n", stderr); exit(EXIT_FAILURE); } if (! rf->bytes || ! rf->len) { fputs("Error: No content read\n", stderr); exit(EXIT_FAILURE); } rf->bytes[rf->len] = 0x0; /* NUL terminate byte sequence */ return rf; }