xref: /haiku/src/tools/data_to_source.cpp (revision 669e389c33cbdfc134da6943c84cc6dbb92f5b54)
11485d7a2SIngo Weinhold /*
21485d7a2SIngo Weinhold  * Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
31485d7a2SIngo Weinhold  * All rights reserved. Distributed under the terms of the MIT License.
41485d7a2SIngo Weinhold  */
51485d7a2SIngo Weinhold 
61485d7a2SIngo Weinhold #include <errno.h>
71485d7a2SIngo Weinhold #include <fcntl.h>
81485d7a2SIngo Weinhold #include <stdio.h>
91485d7a2SIngo Weinhold #include <stdlib.h>
101485d7a2SIngo Weinhold #include <string.h>
116fc59c0fSFrançois Revol #include <sys/stat.h>
121485d7a2SIngo Weinhold #include <unistd.h>
131485d7a2SIngo Weinhold 
141485d7a2SIngo Weinhold 
151485d7a2SIngo Weinhold void
write_string(int fd,const char * data)161485d7a2SIngo Weinhold write_string(int fd, const char* data)
171485d7a2SIngo Weinhold {
181485d7a2SIngo Weinhold 	int len = strlen(data);
191485d7a2SIngo Weinhold 	if (len == 0)
201485d7a2SIngo Weinhold 		return;
211485d7a2SIngo Weinhold 
221485d7a2SIngo Weinhold 	ssize_t written = write(fd, data, len);
231485d7a2SIngo Weinhold 	if (written < 0) {
241485d7a2SIngo Weinhold 		fprintf(stderr, "Error: Failed to write to output file: %s\n",
251485d7a2SIngo Weinhold 			strerror(errno));
261485d7a2SIngo Weinhold 		exit(1);
271485d7a2SIngo Weinhold 	}
281485d7a2SIngo Weinhold }
291485d7a2SIngo Weinhold 
301485d7a2SIngo Weinhold 
311485d7a2SIngo Weinhold int
main(int argc,const char * const * argv)321485d7a2SIngo Weinhold main(int argc, const char* const* argv)
331485d7a2SIngo Weinhold {
341485d7a2SIngo Weinhold 	if (argc != 5) {
351485d7a2SIngo Weinhold 		fprintf(stderr,
361485d7a2SIngo Weinhold 			"Usage: %s <data var name> <size var name> <input> <output>\n",
371485d7a2SIngo Weinhold 			argv[0]);
381485d7a2SIngo Weinhold 		exit(1);
391485d7a2SIngo Weinhold 	}
401485d7a2SIngo Weinhold 	const char* dataVarName = argv[1];
411485d7a2SIngo Weinhold 	const char* sizeVarName = argv[2];
421485d7a2SIngo Weinhold 	const char* inFileName = argv[3];
431485d7a2SIngo Weinhold 	const char* outFileName = argv[4];
441485d7a2SIngo Weinhold 
451485d7a2SIngo Weinhold 	// open files
461485d7a2SIngo Weinhold 	int inFD = open(inFileName, O_RDONLY);
471485d7a2SIngo Weinhold 	if (inFD < 0) {
481485d7a2SIngo Weinhold 		fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n",
491485d7a2SIngo Weinhold 			inFileName, strerror(errno));
501485d7a2SIngo Weinhold 		exit(1);
511485d7a2SIngo Weinhold 	}
521485d7a2SIngo Weinhold 
531485d7a2SIngo Weinhold 	int outFD = open(outFileName, O_WRONLY | O_CREAT | O_TRUNC,
541485d7a2SIngo Weinhold 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
551485d7a2SIngo Weinhold 	if (outFD < 0) {
561485d7a2SIngo Weinhold 		fprintf(stderr, "Error: Failed to open output file \"%s\": %s\n",
571485d7a2SIngo Weinhold 			outFileName, strerror(errno));
581485d7a2SIngo Weinhold 		exit(1);
591485d7a2SIngo Weinhold 	}
601485d7a2SIngo Weinhold 
611485d7a2SIngo Weinhold 	const int kCharsPerLine = 15;
621485d7a2SIngo Weinhold 	const int kBufferSize = 16 * 1024;
631485d7a2SIngo Weinhold 	unsigned char buffer[kBufferSize];
641485d7a2SIngo Weinhold 	char lineBuffer[128];
651485d7a2SIngo Weinhold 
66*669e389cSPaweł Dziepak 	sprintf(lineBuffer, "#include <stddef.h>\n");
67*669e389cSPaweł Dziepak 	write_string(outFD, lineBuffer);
68*669e389cSPaweł Dziepak 	sprintf(lineBuffer, "const unsigned char %s[] = {\n", dataVarName);
691485d7a2SIngo Weinhold 	write_string(outFD, lineBuffer);
701485d7a2SIngo Weinhold 
711485d7a2SIngo Weinhold 	off_t offset = 0;
721485d7a2SIngo Weinhold 	char* lineBufferEnd = lineBuffer;
731485d7a2SIngo Weinhold 	*lineBufferEnd = '\0';
741485d7a2SIngo Weinhold 	while (true) {
751485d7a2SIngo Weinhold 		// read a buffer
761485d7a2SIngo Weinhold 		ssize_t bytesRead = read(inFD, buffer, kBufferSize);
771485d7a2SIngo Weinhold 		if (bytesRead < 0) {
781485d7a2SIngo Weinhold 			fprintf(stderr, "Error: Failed to read from input file: %s\n",
791485d7a2SIngo Weinhold 				strerror(errno));
801485d7a2SIngo Weinhold 			exit(1);
811485d7a2SIngo Weinhold 		}
821485d7a2SIngo Weinhold 		if (bytesRead == 0)
831485d7a2SIngo Weinhold 			break;
841485d7a2SIngo Weinhold 
851485d7a2SIngo Weinhold 		// write lines
861485d7a2SIngo Weinhold 		for (int i = 0; i < bytesRead; i++, offset++) {
871485d7a2SIngo Weinhold 			if (offset % kCharsPerLine == 0) {
881485d7a2SIngo Weinhold 				if (offset > 0) {
891485d7a2SIngo Weinhold 					// line is full -- flush it
901485d7a2SIngo Weinhold 					strcpy(lineBufferEnd, ",\n");
911485d7a2SIngo Weinhold 					write_string(outFD, lineBuffer);
921485d7a2SIngo Weinhold 					lineBufferEnd = lineBuffer;
931485d7a2SIngo Weinhold 					*lineBufferEnd = '\0';
941485d7a2SIngo Weinhold 				}
951485d7a2SIngo Weinhold 
961485d7a2SIngo Weinhold 				sprintf(lineBufferEnd, "\t%u", (unsigned)buffer[i]);
971485d7a2SIngo Weinhold 			} else
981485d7a2SIngo Weinhold 				sprintf(lineBufferEnd, ", %u", (unsigned)buffer[i]);
991485d7a2SIngo Weinhold 
1001485d7a2SIngo Weinhold 			lineBufferEnd += strlen(lineBufferEnd);
1011485d7a2SIngo Weinhold 		}
1021485d7a2SIngo Weinhold 	}
1031485d7a2SIngo Weinhold 
1041485d7a2SIngo Weinhold 	// flush the line buffer
1051485d7a2SIngo Weinhold 	if (lineBufferEnd != lineBuffer) {
1061485d7a2SIngo Weinhold 		strcpy(lineBufferEnd, ",\n");
1071485d7a2SIngo Weinhold 		write_string(outFD, lineBuffer);
1081485d7a2SIngo Weinhold 	}
1091485d7a2SIngo Weinhold 
1101485d7a2SIngo Weinhold 	// close the braces and write the size variable
111*669e389cSPaweł Dziepak 	sprintf(lineBuffer, "};\nconst size_t %s = sizeof(%s);\n", sizeVarName,
112*669e389cSPaweł Dziepak 		dataVarName);
1131485d7a2SIngo Weinhold 	write_string(outFD, lineBuffer);
1141485d7a2SIngo Weinhold 
1151485d7a2SIngo Weinhold 	close(inFD);
1161485d7a2SIngo Weinhold 	close(outFD);
1171485d7a2SIngo Weinhold 
1181485d7a2SIngo Weinhold 	return 0;
1191485d7a2SIngo Weinhold }
120