Files
FreeRDP/client/SDL3/dialogs/res/convert_res_to_c.cpp
akallabeth 8281186a6d [client,sdl] create a copy for SDL3
* Copy SDL2 client to SDL3 as the new version is not API compatible
* Move existing SDL2 client to SDL2 directory
* Move fonts from SDL client to resources folder in top level directory
2024-05-16 18:27:11 +02:00

191 lines
5.1 KiB
C++

/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2023 Armin Novak <armin.novak@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <fstream>
#include <algorithm>
#include <iomanip>
#include <iostream>
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#else
#error Could not find system header "<filesystem>" or "<experimental/filesystem>"
#endif
static void usage(const char* prg)
{
std::cerr << prg << " <file> <type> <class name> <dst path>" << std::endl;
}
static int write_comment_header(std::ostream& out, const fs::path& prg, const std::string& fname)
{
out << "/* AUTOGENERATED file, do not edit" << std::endl
<< " *" << std::endl
<< " * generated by '" << prg.filename() << "'" << std::endl
<< " *" << std::endl
<< " * contains the converted file '" << fname << "'" << std::endl
<< " */" << std::endl
<< std::endl;
return 0;
}
static int write_cpp_header(std::ostream& out, const fs::path& prg, const fs::path& file,
const std::string& name, const std::string& type)
{
auto fname = file.filename().string();
auto rc = write_comment_header(out, prg, fname);
if (rc != 0)
return rc;
out << "#include <vector>" << std::endl
<< "#include \"" << name << ".hpp\"" << std::endl
<< std::endl
<< "std::string " << name << "::name() {" << std::endl
<< "return \"" << fname << "\";" << std::endl
<< "}" << std::endl
<< "std::string " << name << "::type() {" << std::endl
<< "return \"" << type << "\";" << std::endl
<< "}" << std::endl
<< std::endl
<< "const SDLResourceFile " << name << "::_initializer(type(), name(), init());"
<< std::endl
<< std::endl
<< "std::vector<unsigned char> " << name << "::init() {" << std::endl
<< "static const unsigned char data[] = {" << std::endl;
return 0;
}
static int readwrite(std::ofstream& out, std::ifstream& ifs)
{
size_t pos = 0;
char c = 0;
std::ios backup(nullptr);
backup.copyfmt(out);
while (ifs.read(&c, 1) && ifs.good())
{
unsigned val = c & 0xff;
out << "0x" << std::hex << std::setfill('0') << std::setw(2) << val;
if (ifs.peek() != EOF)
out << ",";
if ((pos++ % 16) == 15)
out << std::endl;
}
out.copyfmt(backup);
return 0;
}
static int write_cpp_trailer(std::ostream& out)
{
out << std::endl;
out << "};" << std::endl;
out << std::endl;
out << "return std::vector<unsigned char>(data, data + sizeof(data));" << std::endl;
out << "}" << std::endl;
return 0;
}
static int write_hpp_header(const fs::path& prg, const fs::path& file, const std::string& name,
const std::string& fname)
{
std::ofstream out(file, std::ios::out);
if (!out.is_open())
{
std::cerr << "Failed to open output file '" << file << "'" << std::endl;
return -1;
}
auto rc = write_comment_header(out, prg, fname);
if (rc != 0)
return rc;
out << "#pragma once" << std::endl
<< std::endl
<< "#include <vector>" << std::endl
<< "#include <string>" << std::endl
<< "#include \"sdl_resource_file.hpp\"" << std::endl
<< std::endl
<< "class " << name << " {" << std::endl
<< "public:" << std::endl
<< name << "() = delete;" << std::endl
<< std::endl
<< "static std::string name();" << std::endl
<< "static std::string type();" << std::endl
<< std::endl
<< "private:" << std::endl
<< "static std::vector<unsigned char> init();" << std::endl
<< "static const SDLResourceFile _initializer;" << std::endl
<< std::endl
<< "};" << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
fs::path prg(argv[0]);
if (argc != 5)
{
usage(argv[0]);
return -1;
}
fs::path file(argv[1]);
std::string etype = argv[2];
std::string cname = argv[3];
fs::path dst(argv[4]);
fs::path hdr(argv[4]);
dst /= cname + ".cpp";
hdr /= cname + ".hpp";
std::ofstream out;
out.open(dst);
if (!out.is_open())
{
std::cerr << "Failed to open output file '" << dst << "'" << std::endl;
return -2;
}
std::ifstream ifs(file, std::ios::in | std::ios::binary);
if (!ifs.is_open())
{
std::cerr << "Failed to open input file '" << file << "'" << std::endl;
return -3;
}
auto rc = write_cpp_header(out, prg, file, cname, etype);
if (rc != 0)
return -1;
rc = readwrite(out, ifs);
if (rc != 0)
return rc;
rc = write_cpp_trailer(out);
if (rc != 0)
return rc;
return write_hpp_header(prg, hdr, cname, file.filename().string());
}