-
Notifications
You must be signed in to change notification settings - Fork 320
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add buffer.transcode for nodejs_compat
- Loading branch information
Showing
8 changed files
with
329 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
#include "i18n.h" | ||
|
||
#include <kj/common.h> | ||
#include <kj/debug.h> | ||
#include <kj/one-of.h> | ||
|
||
#include <jsg/exception.h> | ||
#include <workerd/api/trace.h> | ||
|
||
#include <string> | ||
|
||
namespace workerd::api::node { | ||
|
||
namespace i18n { | ||
|
||
namespace { | ||
|
||
const char* getEncodingName(Encoding input) { | ||
switch (input) { | ||
case Encoding::ASCII: | ||
return "us-ascii"; | ||
case Encoding::LATIN1: | ||
return "iso8859-1"; | ||
case Encoding::UCS2: | ||
return "utf16le"; | ||
case Encoding::UTF8: | ||
return "utf-8"; | ||
default: | ||
KJ_UNREACHABLE; | ||
} | ||
} | ||
|
||
typedef TranscodeResult (*TranscodeImpl)(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, | ||
Encoding toEncoding); | ||
|
||
TranscodeResult TranscodeDefault(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, | ||
Encoding toEncoding) { | ||
Converter to(toEncoding); | ||
std::string substitude(to.minSize(), '?'); | ||
to.setSubstitudeChars(substitude); | ||
|
||
Converter from(fromEncoding); | ||
|
||
auto limit = source.size() + to.maxSize(); | ||
KJ_STACK_ARRAY(kj::byte, out, limit, 0, limit); | ||
char* target = out.asChars().begin(); | ||
const char* source_ = source.asChars().begin(); | ||
UErrorCode status{}; | ||
ucnv_convertEx(to.conv(), from.conv(), &target, target + limit, &source_, source_ + source.size(), | ||
nullptr, nullptr, nullptr, nullptr, true, true, &status); | ||
|
||
if (U_SUCCESS(status)) { | ||
return out.slice(0, target - out.asChars().begin()).attach(); | ||
} | ||
|
||
return status; | ||
} | ||
|
||
TranscodeResult TranscodeToUCS2(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, | ||
Encoding toEncoding) { | ||
UErrorCode status{}; | ||
const size_t length_in_chars = source.size() * sizeof(UChar); | ||
Converter from(fromEncoding); | ||
KJ_STACK_ARRAY(UChar, out, source.size(), 0, source.size()); | ||
const auto source_ = source.asChars().begin(); | ||
ucnv_toUChars(from.conv(), out.begin(), length_in_chars, source_, source.size(), &status); | ||
|
||
if (U_SUCCESS(status)) { | ||
return out.asBytes().attach(); | ||
} | ||
return status; | ||
} | ||
|
||
TranscodeResult TranscodeFromUCS2(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, | ||
Encoding toEncoding) { | ||
UErrorCode status{}; | ||
const size_t length_in_chars = source.size() * sizeof(UChar); | ||
// Transcode from UCS2. | ||
Converter to(toEncoding); | ||
// KJ_STACK_ARRAY(kj::byte, dest, length_in_chars, 0, length_in_chars); | ||
// dest.copyFrom(source.asConst().slice(0, length_in_chars)); | ||
|
||
// const uint32_t len = ucnv_fromUChars(to.conv(), dest.begin(), length_in_chars, | ||
*sourcebuf, length_in_chars, status); | ||
|
||
if (U_SUCCESS(status)) { | ||
return out.asBytes().attach(); | ||
} | ||
return status; | ||
} | ||
|
||
TranscodeResult TranscodeUcs2FromUtf8(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, Encoding toEncoding) { | ||
|
||
} | ||
|
||
TranscodeResult TranscodeUtf8FromUcs2(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, Encoding toEncoding) { | ||
|
||
} | ||
|
||
} // namespace | ||
|
||
Converter::Converter(Encoding encoding, std::string_view substitude) { | ||
UErrorCode status = U_ZERO_ERROR; | ||
auto name = getEncodingName(encoding); | ||
auto conv = ucnv_open(name, &status); | ||
KJ_ASSERT(U_SUCCESS(status)); | ||
conv_.reset(conv); | ||
setSubstitudeChars(substitude); | ||
} | ||
|
||
Converter::Converter(UConverter* converter, std::string_view substitude) : conv_(converter) { | ||
setSubstitudeChars(substitude); | ||
} | ||
|
||
kj::Array<kj::byte> transcode(kj::ArrayPtr<kj::byte> source, Encoding fromEncoding, | ||
Encoding toEncoding) { | ||
TranscodeImpl transcode_function = &TranscodeDefault; | ||
switch (fromEncoding) { | ||
case Encoding::ASCII: | ||
case Encoding::LATIN1: | ||
if (toEncoding == Encoding::UCS2) { | ||
transcode_function = &TranscodeToUCS2; | ||
} | ||
break; | ||
case Encoding::UTF8: | ||
if (toEncoding == Encoding::UCS2) { | ||
transcode_function = &TranscodeUcs2FromUtf8; | ||
} | ||
break; | ||
case Encoding::UCS2: | ||
switch (toEncoding) { | ||
case Encoding::UCS2: | ||
transcode_function = &TranscodeDefault; | ||
break; | ||
case Encoding::UTF8: | ||
transcode_function = &TranscodeUtf8FromUcs2; | ||
break; | ||
default: | ||
transcode_function = &TranscodeFromUCS2; | ||
} | ||
default: | ||
KJ_UNREACHABLE; | ||
} | ||
|
||
auto result = transcode_function(source, fromEncoding, toEncoding); | ||
KJ_SWITCH_ONEOF(result) { | ||
KJ_CASE_ONEOF(value, UErrorCode) { | ||
JSG_FAIL_REQUIRE(Error, "Unable to transcode Buffer"); | ||
} | ||
KJ_CASE_ONEOF(v, kj::Array<kj::byte>) { | ||
return kj::mv(v); | ||
} | ||
} | ||
KJ_UNREACHABLE; | ||
} | ||
|
||
} // namespace i18n | ||
|
||
} // namespace workerd::api::node |
Oops, something went wrong.