Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 37 additions & 23 deletions src/embedded_data.cc
Original file line number Diff line number Diff line change
@@ -1,33 +1,47 @@
#include "embedded_data.h"
#include <vector>
#include <array>

namespace node {
std::string ToOctalString(const uint8_t ch) {
// We can print most printable characters directly. The exceptions are '\'
// (escape characters), " (would end the string), and ? (trigraphs). The
// latter may be overly conservative: we compile with C++17 which doesn't
// support trigraphs.
if (ch >= ' ' && ch <= '~' && ch != '\\' && ch != '"' && ch != '?') {
return std::string(1, static_cast<char>(ch));
namespace {

struct OctalStr {
char data[5] = {0};

constexpr OctalStr() = default;
explicit constexpr OctalStr(uint8_t ch) {
// We can print most printable characters directly. The exceptions are '\'
// (escape characters), " (would end the string), and ? (trigraphs). The
// latter may be overly conservative: we compile with C++20 which doesn't
// support trigraphs.
if (ch >= ' ' && ch <= '~' && ch != '\\' && ch != '"' && ch != '?') {
data[0] = static_cast<char>(ch);
} else {
data[0] = '\\';
data[1] = '0' + ((ch >> 6) & 7);
data[2] = '0' + ((ch >> 3) & 7);
data[3] = '0' + (ch & 7);
}
}
// All other characters are blindly output as octal.
const char c0 = '0' + ((ch >> 6) & 7);
const char c1 = '0' + ((ch >> 3) & 7);
const char c2 = '0' + (ch & 7);
return std::string("\\") + c0 + c1 + c2;
}

std::vector<std::string> GetOctalTable() {
size_t size = 1 << 8;
std::vector<std::string> code_table(size);
for (size_t i = 0; i < size; ++i) {
code_table[i] = ToOctalString(static_cast<uint8_t>(i));
constexpr std::string_view view() const {
return {data, data[1] == '\0' ? 1u : 4u};
}
};

constexpr auto MakeOctalTable() {
std::array<OctalStr, 256> table{};
for (unsigned i = 0; i < 256; ++i) {
table[i] = OctalStr(static_cast<uint8_t>(i));
}
return code_table;
return table;
}

const std::string& GetOctalCode(uint8_t index) {
static std::vector<std::string> table = GetOctalTable();
return table[index];
constexpr auto octal_table = MakeOctalTable();

} // namespace

std::string_view GetOctalCode(uint8_t index) {
return octal_table[index].view();
}

} // namespace node
4 changes: 2 additions & 2 deletions src/embedded_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
#define SRC_EMBEDDED_DATA_H_

#include <cinttypes>
#include <string>
#include <string_view>

// This file must not depend on node.h or other code that depends on
// the full Node.js implementation because it is used during the
// compilation of the Node.js implementation itself (especially js2c).

namespace node {

const std::string& GetOctalCode(uint8_t index);
std::string_view GetOctalCode(uint8_t index);

} // namespace node

Expand Down
4 changes: 2 additions & 2 deletions tools/js2c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,8 @@ Fragment GetDefinitionImpl(const std::vector<char>& code,
i,
ch);
}
const std::string& str = GetOctalCode(ch);
memcpy(result.data() + cur, str.c_str(), str.size());
std::string_view str = GetOctalCode(ch);
memcpy(result.data() + cur, str.data(), str.size());
cur += str.size();
}
}
Expand Down
Loading