-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhost-util.cpp
More file actions
95 lines (82 loc) · 2.73 KB
/
Copy pathhost-util.cpp
File metadata and controls
95 lines (82 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "host-util.hpp"
#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <unicode/ucnv.h>
#include <unicode/unistr.h>
using namespace cmcpp;
void trap(const char *msg)
{
throw new std::runtime_error(msg);
}
const char *const LATIN1 = "ISO-8859-1";
const char *const UTF8 = "UTF-8";
const char *const UTF16 = "UTF-16-LE";
const char *encodingToICU(const Encoding encoding)
{
switch (encoding)
{
case Encoding::Latin1:
return LATIN1;
case Encoding::Utf8:
return UTF8;
case Encoding::Utf16:
return UTF16;
default:
return "";
}
}
std::pair<void *, size_t> convert(void *dest, uint32_t dest_byte_len, const void *src, uint32_t src_byte_len, Encoding from_encoding, Encoding to_encoding)
{
if (from_encoding == to_encoding)
{
assert(dest_byte_len >= src_byte_len);
if (src_byte_len > 0)
{
std::memcpy(dest, src, src_byte_len);
return std::make_pair(dest, src_byte_len);
}
return std::make_pair(nullptr, 0);
}
UErrorCode status = U_ZERO_ERROR;
const char *sourceEncoding = encodingToICU(from_encoding);
const char *targetEncoding = encodingToICU(to_encoding);
// Create a converter for the source encoding
UConverter *sourceConverter = ucnv_open(sourceEncoding, &status);
if (U_FAILURE(status))
{
std::cerr << "Error opening source converter: " << u_errorName(status) << std::endl;
return std::make_pair(nullptr, 0);
}
// Create a converter for the target encoding
UConverter *targetConverter = ucnv_open(targetEncoding, &status);
if (U_FAILURE(status))
{
std::cerr << "Error opening target converter: " << u_errorName(status) << std::endl;
ucnv_close(sourceConverter);
return std::make_pair(nullptr, 0);
}
// Convert source string to UnicodeString
icu::UnicodeString unicodeString((const char *)src, src_byte_len, sourceConverter, status);
if (U_FAILURE(status))
{
std::cerr << "Error converting to UnicodeString: " << u_errorName(status) << std::endl;
ucnv_close(sourceConverter);
ucnv_close(targetConverter);
return std::make_pair(nullptr, 0);
}
status = U_ZERO_ERROR;
auto targetLength = unicodeString.extract((char *)dest, dest_byte_len, targetConverter, status);
if (U_FAILURE(status))
{
std::cerr << "Error extracting target string: " << u_errorName(status) << std::endl;
ucnv_close(sourceConverter);
ucnv_close(targetConverter);
return std::make_pair(nullptr, 0);
}
auto retVal = std::make_pair(dest, targetLength);
ucnv_close(sourceConverter);
ucnv_close(targetConverter);
return retVal;
}