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 <unistd.h> 12 13 14 void 15 write_string(int fd, const char* data) 16 { 17 int len = strlen(data); 18 if (len == 0) 19 return; 20 21 ssize_t written = write(fd, data, len); 22 if (written < 0) { 23 fprintf(stderr, "Error: Failed to write to output file: %s\n", 24 strerror(errno)); 25 exit(1); 26 } 27 } 28 29 30 int 31 main(int argc, const char* const* argv) 32 { 33 if (argc != 5) { 34 fprintf(stderr, 35 "Usage: %s <data var name> <size var name> <input> <output>\n", 36 argv[0]); 37 exit(1); 38 } 39 const char* dataVarName = argv[1]; 40 const char* sizeVarName = argv[2]; 41 const char* inFileName = argv[3]; 42 const char* outFileName = argv[4]; 43 44 // open files 45 int inFD = open(inFileName, O_RDONLY); 46 if (inFD < 0) { 47 fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n", 48 inFileName, strerror(errno)); 49 exit(1); 50 } 51 52 int outFD = open(outFileName, O_WRONLY | O_CREAT | O_TRUNC, 53 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 54 if (outFD < 0) { 55 fprintf(stderr, "Error: Failed to open output file \"%s\": %s\n", 56 outFileName, strerror(errno)); 57 exit(1); 58 } 59 60 const int kCharsPerLine = 15; 61 const int kBufferSize = 16 * 1024; 62 unsigned char buffer[kBufferSize]; 63 char lineBuffer[128]; 64 65 sprintf(lineBuffer, "unsigned char %s[] = {\n", dataVarName); 66 write_string(outFD, lineBuffer); 67 68 off_t dataSize = 0; 69 off_t offset = 0; 70 char* lineBufferEnd = lineBuffer; 71 *lineBufferEnd = '\0'; 72 while (true) { 73 // read a buffer 74 ssize_t bytesRead = read(inFD, buffer, kBufferSize); 75 if (bytesRead < 0) { 76 fprintf(stderr, "Error: Failed to read from input file: %s\n", 77 strerror(errno)); 78 exit(1); 79 } 80 if (bytesRead == 0) 81 break; 82 83 dataSize += bytesRead; 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, "};\nlong long %s = %lldLL;\n", sizeVarName, 112 dataSize); 113 write_string(outFD, lineBuffer); 114 115 close(inFD); 116 close(outFD); 117 118 return 0; 119 } 120