static void generateJSONString(Error& error, const HOutputStream& out, const UTF8& s) { UTF16Buffer sb(2 + s.length() + 1); sb << '"'; if (error) return; for (const Chr8* p = s.ptr(); (*p) != '\0'; p++) { Chr8 c = *p; switch (c) { case '\"' : sb << '\\' << '\"'; break; case '\\' : sb << '\\' << '\\'; break; case '/' : sb << '\\' << '/'; break; case '\b' : sb << '\\' << 'b'; break; case '\f' : sb << '\\' << 'f'; break; case '\n' : sb << '\\' << 'n'; break; case '\r' : sb << '\\' << 'r'; break; case '\t' : sb << '\\' << 't'; break; default: if (c >= 0x20) { sb << c; } else { sb << UTF8("\\u00") << UTF8::format("%.2X",UInt32(c)); } break; } } sb << '"'; out->twrite(error, UTF8(sb)); };
int wmain(int argc, Chr16** argv) { Lock::setupGlobalLock(); Error error; LogStdout log; class Fatal {}; try { loginfo("Tomazos Resource Compiler 1.0 (c) Andrew Tomazos 2009"); if (argc != 3) { error.what(L"Usage: ResourceCompiler <ResourceDir> <Out.cpp>"); throw Fatal(); } UTF16 sSourceDirPath = argv[1]; UTF16 sOutPath = argv[2]; Path sourceDir(error, sSourceDirPath); if (error) throw Fatal(); UTF16 sFullSourceDirPath = UTF16(sourceDir); if (!sFullSourceDirPath.endsWith(L"\\")) sFullSourceDirPath = sFullSourceDirPath + L"\\"; UTF16List fps; sourceDir.walk(ResourceCompilerWalker(fps)); loginfo("Found %d files", fps.size()); TreeMap<UTF16, Blob> data; { UTF16List::Iterator it(fps); UTF16 sFullFilePath; while (it(sFullFilePath)) { if (!sFullFilePath.startsWith(sFullSourceDirPath)) { Check(); throw Fatal(); } UTF16 sRelFilePath = sFullFilePath.suffix(sFullFilePath.length() - sFullSourceDirPath.length()); Path file(error, sFullFilePath); if (error) throw Fatal(); HInputStream fis; file.readFile(error, fis); if (error) throw Fatal(); Blob sFileContent = fis->slurp(error); if (error) throw Fatal(); loginfo("Found %s (%d bytes)", sRelFilePath.ptr(), sFileContent.length()); data.add(sRelFilePath, sFileContent); } } Path outPath(error, sOutPath); if (error) throw Fatal(); HOutputStream hOut; outPath.overwriteFile(error, hOut); if (error) throw Fatal(); #define ResLine(x) { hOut->twrite(error, UTF8(x)); if (error) throw Fatal(); hOut->twrite(error, UTF8("\r\n")); if (error) throw Fatal(); } #define ResLineF(...) { ResLine(UTF8::format(__VA_ARGS__)); } ResLine("#include \"Runtime.h\""); ResLine(""); ResLine("void ResourceManager::setup()"); ResLine("{"); { TreeMap<UTF16, Blob>::Iterator it(data); UTF16 sPath; Blob bData; int iCount = 0; int iNumResources = data.size(); while (it(sPath, bData)) { iCount++; UTF8 sId = UTF8::format("s_res_data_%d", iCount); ResLineF(" static UInt8 %s[] = { ", sId.ptr()); for (int i = 0; i < bData.length(); i++) { if (i % 16 == 0) { hOut->twrite(error, UTF8(" ")); if (error) throw Fatal(); } hOut->twrite(error, UTF8::format("0x%.2X", UInt32(bData.idx<UInt8>(i)))); if (error) throw Fatal(); if (i != bData.length() - 1) { hOut->twrite(error, UTF8(", ")); if (error) throw Fatal(); } if (i % 16 == 15 || i == bData.length() - 1) ResLine(""); } ResLineF(" };"); ResLine(""); ResLineF(" ResourceManager::instance()->set(%s, %s, %d);", stringToCStringLiteral(sPath).ptr(), sId.ptr(), bData.length()); if (iCount != iNumResources) ResLine(""); } } ResLine("}"); #undef ResLine return 0; } catch (Fatal&) { if (error) logerr("%s", UTF16(error).ptr()); return 1; } }