mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-11-03 21:46:32 +00:00
53 lines
1.6 KiB
C++
53 lines
1.6 KiB
C++
#include "nls.h"
|
|
#include "nls-cp1252.h"
|
|
#include "nls-sbcs.h"
|
|
|
|
#include <algorithm>
|
|
#include <stdexcept>
|
|
|
|
namespace raven {
|
|
|
|
const NativeSingleBytePage *native_single_byte_page(uint32_t code_page)
|
|
{
|
|
for (const auto &page : native_single_byte_pages)
|
|
if (page.id==code_page) return &page;
|
|
return nullptr;
|
|
}
|
|
|
|
std::u16string decode_single_byte(const NativeSingleBytePage &page,std::string_view text)
|
|
{
|
|
std::u16string result;
|
|
result.reserve(text.size());
|
|
for (const auto byte : text) result.push_back(char16_t(page.bytes[static_cast<unsigned char>(byte)]));
|
|
return result;
|
|
}
|
|
|
|
int encode_single_byte(const NativeSingleBytePage &page,char16_t character,bool exact)
|
|
{
|
|
const auto end=page.best_fit+page.best_fit_count;
|
|
const auto found=std::lower_bound(page.best_fit,end,uint16_t(character),
|
|
[](const std::array<uint16_t,2> &entry,uint16_t value) { return entry[0]<value; });
|
|
if (found==end || (*found)[0]!=character) return -1;
|
|
// A best fit is a byte that reads back as another character.
|
|
if (exact && page.bytes[(*found)[1]]!=character) return -1;
|
|
return (*found)[1];
|
|
}
|
|
|
|
std::string encode_ansi(std::u16string_view text,uint32_t code_page)
|
|
{
|
|
std::string result;
|
|
result.reserve(text.size());
|
|
if (const auto *page=native_single_byte_page(code_page)) {
|
|
for (const auto character : text) {
|
|
const auto byte=encode_single_byte(*page,character,false);
|
|
result.push_back(byte<0 ? '?' : static_cast<char>(byte));
|
|
}
|
|
return result;
|
|
}
|
|
if (code_page!=1252) throw std::runtime_error("unsupported native ANSI code page");
|
|
for (const auto character : text) result.push_back(static_cast<char>(native_cp1252[character]));
|
|
return result;
|
|
}
|
|
|
|
}
|