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, "unsigned char %s[] = {\n", dataVarName); 67 write_string(outFD, lineBuffer); 68 69 off_t dataSize = 0; 70 off_t offset = 0; 71 char* lineBufferEnd = lineBuffer; 72 *lineBufferEnd = '\0'; 73 while (true) { 74 // read a buffer 75 ssize_t bytesRead = read(inFD, buffer, kBufferSize); 76 if (bytesRead < 0) { 77 fprintf(stderr, "Error: Failed to read from input file: %s\n", 78 strerror(errno)); 79 exit(1); 80 } 81 if (bytesRead == 0) 82 break; 83 84 dataSize += bytesRead; 85 86 // write lines 87 for (int i = 0; i < bytesRead; i++, offset++) { 88 if (offset % kCharsPerLine == 0) { 89 if (offset > 0) { 90 // line is full -- flush it 91 strcpy(lineBufferEnd, ",\n"); 92 write_string(outFD, lineBuffer); 93 lineBufferEnd = lineBuffer; 94 *lineBufferEnd = '\0'; 95 } 96 97 sprintf(lineBufferEnd, "\t%u", (unsigned)buffer[i]); 98 } else 99 sprintf(lineBufferEnd, ", %u", (unsigned)buffer[i]); 100 101 lineBufferEnd += strlen(lineBufferEnd); 102 } 103 } 104 105 // flush the line buffer 106 if (lineBufferEnd != lineBuffer) { 107 strcpy(lineBufferEnd, ",\n"); 108 write_string(outFD, lineBuffer); 109 } 110 111 // close the braces and write the size variable 112 sprintf(lineBuffer, "};\nlong long %s = %lldLL;\n", sizeVarName, 113 dataSize); 114 write_string(outFD, lineBuffer); 115 116 close(inFD); 117 close(outFD); 118 119 return 0; 120 } 121