xref: /haiku/src/tools/data_to_source.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
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 		(long long)dataSize);
114 	write_string(outFD, lineBuffer);
115 
116 	close(inFD);
117 	close(outFD);
118 
119 	return 0;
120 }
121