xref: /haiku/src/tools/data_to_source.cpp (revision cda5b8808fd0262f0fac472f6cfa809f846a83cf)
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