Skip to content

Commit

Permalink
Add open_file_skipping_BOM function to RC::File
Browse files Browse the repository at this point in the history
  • Loading branch information
narknon committed Jun 17, 2024
1 parent d5eb2f5 commit a0359bf
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions deps/first/File/include/File/File.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ namespace RC::File
OverwriteExistingFile = OverwriteExistingFile::No,
CreateIfNonExistent = CreateIfNonExistent::No) -> Handle;

RC_FILE_API auto open_file_skip_BOM(const std::wstring& filename) -> StreamType;

RC_FILE_API auto delete_file(const std::filesystem::path& file_path_and_name) -> void;
} // namespace RC::File
54 changes: 53 additions & 1 deletion deps/first/File/src/File.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <codecvt>
#include <fstream>
#include <File/File.hpp>

namespace RC::File
Expand All @@ -22,8 +24,58 @@ namespace RC::File
return construct_handle(file_path_and_name, open_properties);
}

// BOM sequences
const std::string BOM_UTF8 = "\xEF\xBB\xBF";
const std::wstring BOM_UTF16_LE = L"\xFEFF";
const std::wstring BOM_UTF16_BE = L"\xFFFE";

// Function to check for BOM and reopen the file as a wide stream
auto open_file_skip_BOM(const std::wstring& filename) -> StreamType
{
std::ifstream file(filename, std::ios::binary);
if (!file.is_open())
{
throw std::runtime_error("Failed to open the file.");
}

char bom[3] = {0};
file.read(bom, 3);
if (std::string(bom, 3) == BOM_UTF8)
{
// UTF-8 BOM detected
file.close();
StreamType wfile(filename);
wfile.seekg(3, std::ios::beg); // Skip BOM
return wfile;
}
else
{
// Check for wide BOM
wchar_t wbom;
file.seekg(0, std::ios::beg); // Rewind to start
file.read(reinterpret_cast<char*>(&wbom), sizeof(wchar_t));
file.close();
if (wbom == BOM_UTF16_LE[0] || wbom == BOM_UTF16_BE[0])
{
StreamType wfile(filename);
#pragma warning(disable : 4996)
std::locale loc(wfile.getloc(), new std::codecvt_utf8_utf16<wchar_t>);
#pragma warning(default : 4996)
wfile.imbue(loc);
wfile.seekg(sizeof(wchar_t), std::ios::beg); // Skip BOM
return wfile;
}
else
{
// No BOM detected
file.close();
return StreamType(filename);
}
}
}

auto delete_file(const std::filesystem::path& file_path_and_name) -> void
{
Handle::FileType::delete_file(file_path_and_name);
}
} // namespace RC::File
} // namespace RC::File

0 comments on commit a0359bf

Please sign in to comment.