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
write_string(int fd,const char * data)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
main(int argc,const char * const * argv)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