1 /* 2 * Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include <errno.h> 7 #include <fcntl.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/stat.h> 12 #include <unistd.h> 13 14 15 void 16 write_string(int fd, const char* data) 17 { 18 int len = strlen(data); 19 if (len == 0) 20 return; 21 22 ssize_t written = write(fd, data, len); 23 if (written < 0) { 24 fprintf(stderr, "Error: Failed to write to output file: %s\n", 25 strerror(errno)); 26 exit(1); 27 } 28 } 29 30 31 int 32 main(int argc, const char* const* argv) 33 { 34 if (argc != 5) { 35 fprintf(stderr, 36 "Usage: %s <data var name> <size var name> <input> <output>\n", 37 argv[0]); 38 exit(1); 39 } 40 const char* dataVarName = argv[1]; 41 const char* sizeVarName = argv[2]; 42 const char* inFileName = argv[3]; 43 const char* outFileName = argv[4]; 44 45 // open files 46 int inFD = open(inFileName, O_RDONLY); 47 if (inFD < 0) { 48 fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n", 49 inFileName, strerror(errno)); 50 exit(1); 51 } 52 53 int outFD = open(outFileName, O_WRONLY | O_CREAT | O_TRUNC, 54 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 55 if (outFD < 0) { 56 fprintf(stderr, "Error: Failed to open output file \"%s\": %s\n", 57 outFileName, strerror(errno)); 58 exit(1); 59 } 60 61 const int kCharsPerLine = 15; 62 const int kBufferSize = 16 * 1024; 63 unsigned char buffer[kBufferSize]; 64 char lineBuffer[128]; 65 66 sprintf(lineBuffer, "#include <stddef.h>\n"); 67 write_string(outFD, lineBuffer); 68 sprintf(lineBuffer, "const unsigned char %s[] = {\n", dataVarName); 69 write_string(outFD, lineBuffer); 70 71 off_t offset = 0; 72 char* lineBufferEnd = lineBuffer; 73 *lineBufferEnd = '\0'; 74 while (true) { 75 // read a buffer 76 ssize_t bytesRead = read(inFD, buffer, kBufferSize); 77 if (bytesRead < 0) { 78 fprintf(stderr, "Error: Failed to read from input file: %s\n", 79 strerror(errno)); 80 exit(1); 81 } 82 if (bytesRead == 0) 83 break; 84 85 // write lines 86 for (int i = 0; i < bytesRead; i++, offset++) { 87 if (offset % kCharsPerLine == 0) { 88 if (offset > 0) { 89 // line is full -- flush it 90 strcpy(lineBufferEnd, ",\n"); 91 write_string(outFD, lineBuffer); 92 lineBufferEnd = lineBuffer; 93 *lineBufferEnd = '\0'; 94 } 95 96 sprintf(lineBufferEnd, "\t%u", (unsigned)buffer[i]); 97 } else 98 sprintf(lineBufferEnd, ", %u", (unsigned)buffer[i]); 99 100 lineBufferEnd += strlen(lineBufferEnd); 101 } 102 } 103 104 // flush the line buffer 105 if (lineBufferEnd != lineBuffer) { 106 strcpy(lineBufferEnd, ",\n"); 107 write_string(outFD, lineBuffer); 108 } 109 110 // close the braces and write the size variable 111 sprintf(lineBuffer, "};\nconst size_t %s = sizeof(%s);\n", sizeVarName, 112 dataVarName); 113 write_string(outFD, lineBuffer); 114 115 close(inFD); 116 close(outFD); 117 118 return 0; 119 } 120