blob: c3ab50ef92e4bbc3312eae3c99f99f05866eb6e8 [file] [log] [blame] [edit]
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "support/rs_std/char.h"
#include <cstddef>
#include <cstdint>
#include "absl/log/check.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "support/rs_std/str_ref.h"
namespace rs_std {
namespace {
static constexpr uint8_t kContFlag = 0b10000000;
} // namespace
StrRef char_::encode_utf8(absl::Span<uint8_t> output_buffer) const {
size_t len = len_utf8();
CHECK_LE(len, output_buffer.size());
switch (len) {
case 1: {
output_buffer[0] = static_cast<uint8_t>(value_);
break;
}
case 2: {
output_buffer[0] =
static_cast<uint8_t>((value_ >> 6) & 0x1f) | 0b11000000;
output_buffer[1] = static_cast<uint8_t>(value_ & 0x3f) | kContFlag;
break;
}
case 3: {
output_buffer[0] =
static_cast<uint8_t>((value_ >> 12) & 0x0f) | 0b11100000;
output_buffer[1] = static_cast<uint8_t>((value_ >> 6) & 0x3f) | kContFlag;
output_buffer[2] = static_cast<uint8_t>(value_ & 0x3f) | kContFlag;
break;
}
case 4: {
output_buffer[0] =
static_cast<uint8_t>((value_ >> 18) & 0x07) | 0b11110000;
output_buffer[1] =
static_cast<uint8_t>((value_ >> 12) & 0x3f) | kContFlag;
output_buffer[2] = static_cast<uint8_t>((value_ >> 6) & 0x3f) | kContFlag;
output_buffer[3] = static_cast<uint8_t>(value_ & 0x3f) | kContFlag;
break;
}
}
// NOTE: sadly, this reinterpret_cast from `uint8_t*` to `const char*` is
// required and prevents this function from being constexpr.
return StrRef::FromUtf8Unchecked(absl::string_view(
reinterpret_cast<const char*>(output_buffer.data()), len));
}
} // namespace rs_std