Skip to content

Commit

Permalink
introduce List2
Browse files Browse the repository at this point in the history
  • Loading branch information
moonshadow565 committed Apr 18, 2020
1 parent 50a8838 commit c0ee011
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 27 deletions.
15 changes: 14 additions & 1 deletion src/ritobin/bin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace ritobin {
STRING = 16,
HASH = 17,
LIST = 18,
LIST2 = 19,
POINTER = 19 + 1,
EMBED = 20 + 1,
LINK = 21 + 1,
Expand All @@ -40,6 +41,10 @@ namespace ritobin {
FLAG = 24 + 1,
};

inline constexpr bool is_container(Type type) noexcept {
return type == Type::MAP || type == Type::LIST || type == Type::LIST2 || type == Type::OPTION;
}

struct FNV1a {
private:
uint32_t hash_ = 0;
Expand Down Expand Up @@ -206,6 +211,13 @@ namespace ritobin {
ElementList items;
};

struct List2 {
static inline constexpr Type type = Type::LIST2;
static inline constexpr char type_name[] = "list2";
Type valueType;
ElementList items;
};

struct Pointer {
static inline constexpr Type type = Type::POINTER;
static inline constexpr char type_name[] = "pointer";
Expand Down Expand Up @@ -267,6 +279,7 @@ namespace ritobin {
String,
Hash,
List,
List2,
Pointer,
Embed,
Link,
Expand Down Expand Up @@ -348,4 +361,4 @@ namespace ritobin {
};
}

#endif // RITOBIN_HPP
#endif // RITOBIN_HPP
34 changes: 19 additions & 15 deletions src/ritobin/binary_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,10 @@ namespace ritobin {
if (!read(raw)) {
return false;
}
if (raw == 0x81) {
raw = 0x80;
}
if (raw & 0x80) {
raw &= 0x7F;
raw += 18;
}
if (raw == 19) {
return false;
}
value = static_cast<Type>(raw);
return value <= Type::FLAG;
}
Expand Down Expand Up @@ -233,9 +227,7 @@ namespace ritobin {
bool read_value_visit(Option& value) noexcept {
uint8_t count = 0;
bin_assert(reader.read(value.valueType));
bin_assert(value.valueType != Type::MAP);
bin_assert(value.valueType != Type::LIST);
bin_assert(value.valueType != Type::OPTION);
bin_assert(!is_container(value.valueType));
bin_assert(reader.read(count));
if (count != 0) {
auto& [item] = value.items.emplace_back();
Expand All @@ -248,9 +240,23 @@ namespace ritobin {
uint32_t size = 0;
uint32_t count = 0;
bin_assert(reader.read(value.valueType));
bin_assert(value.valueType != Type::MAP);
bin_assert(value.valueType != Type::LIST);
bin_assert(value.valueType != Type::OPTION);
bin_assert(!is_container(value.valueType));
bin_assert(reader.read(size));
size_t position = reader.position();
bin_assert(reader.read(count));
for (size_t i = 0; i != count; i++) {
auto& [item] = value.items.emplace_back();
bin_assert(read_value_of(item, value.valueType));
}
bin_assert(reader.position() == position + size);
return true;
}

bool read_value_visit(List2& value) noexcept {
uint32_t size = 0;
uint32_t count = 0;
bin_assert(reader.read(value.valueType));
bin_assert(!is_container(value.valueType));
bin_assert(reader.read(size));
size_t position = reader.position();
bin_assert(reader.read(count));
Expand All @@ -268,9 +274,7 @@ namespace ritobin {
bin_assert(reader.read(value.keyType));
bin_assert(value.keyType <= Type::HASH);
bin_assert(reader.read(value.valueType));
bin_assert(value.valueType != Type::MAP);
bin_assert(value.valueType != Type::LIST);
bin_assert(value.valueType != Type::OPTION);
bin_assert(!is_container(value.valueType));
bin_assert(reader.read(size));
size_t position = reader.position();
bin_assert(reader.read(count));
Expand Down
21 changes: 15 additions & 6 deletions src/ritobin/binary_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,20 @@ namespace ritobin {
}

bool write_value_visit(List const& value) noexcept {
bin_assert(value.valueType != Type::MAP);
bin_assert(value.valueType != Type::LIST);
bin_assert(value.valueType != Type::OPTION);
bin_assert(!is_container(value.valueType));
writer.write(value.valueType);
size_t position = writer.position();
writer.write(uint32_t{ 0 });
writer.write(static_cast<uint32_t>(value.items.size()));
for (auto const& [item] : value.items) {
bin_assert(write_value(item, value.valueType));
}
writer.write_at(position, writer.position() - position - 4);
return true;
}

bool write_value_visit(List2 const& value) noexcept {
bin_assert(!is_container(value.valueType));
writer.write(value.valueType);
size_t position = writer.position();
writer.write(uint32_t{ 0 });
Expand All @@ -214,9 +225,7 @@ namespace ritobin {

bool write_value_visit(Map const& value) noexcept {
bin_assert(value.keyType <= Type::HASH);
bin_assert(value.valueType != Type::MAP);
bin_assert(value.valueType != Type::LIST);
bin_assert(value.valueType != Type::OPTION);
bin_assert(!is_container(value.valueType));
writer.write(value.keyType);
writer.write(value.valueType);
size_t position = writer.position();
Expand Down
10 changes: 5 additions & 5 deletions src/ritobin/numconv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
#include <string>

#ifndef MSVC
inline bool to_num(std::string_view str, float& num, int base = 10) noexcept {
inline bool to_num(std::string_view str, float& num) noexcept {
auto copy = std::string(str.begin(), str.end());
return sscanf(copy.c_str(), "%g", &num) == 1;
}

inline bool from_num(std::string& str, float const& num, int base = 10) noexcept {
inline bool from_num(std::string& str, float const& num) noexcept {
char buffer[64] = {};
auto const size = sprintf(buffer, "%g", num);
auto const size = sprintf(buffer, "%.9g", num);
str = std::string(buffer, buffer + size);
return false;
}
#endif

template<typename T>
inline bool to_num(std::string_view str, T& num, int base = 10) noexcept {
auto const [p, ec] = std::from_chars(str.data(), str.data() + str.size(), num);
auto const [p, ec] = std::from_chars(str.data(), str.data() + str.size(), num, base);
if (ec == std::errc{} && p == str.data() + str.size()) {
return true;
}
Expand All @@ -30,7 +30,7 @@ inline bool to_num(std::string_view str, T& num, int base = 10) noexcept {
template<typename T>
inline bool from_num(std::string& str, T const& num, int base = 10) noexcept {
char buffer[256] = {};
auto const [p, ec] = std::to_chars(buffer, buffer + sizeof(buffer), num, 16);
auto const [p, ec] = std::to_chars(buffer, buffer + sizeof(buffer), num, base);
if (ec == std::errc{}) {
str = std::string(buffer, p);
return true;
Expand Down
22 changes: 22 additions & 0 deletions src/ritobin/text_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,21 @@ namespace ritobin {
List result = {};
bin_assert(reader.read_symbol<'['>());
bin_assert(reader.read_typename(result.valueType));
bin_assert(!is_container(result.valueType));
bin_assert(reader.read_symbol<']'>());
value = result;
} else if (type == Type::LIST2) {
List2 result = {};
bin_assert(reader.read_symbol<'['>());
bin_assert(reader.read_typename(result.valueType));
bin_assert(!is_container(result.valueType));
bin_assert(reader.read_symbol<']'>());
value = result;
} else if (type == Type::OPTION) {
Option result = {};
bin_assert(reader.read_symbol<'['>());
bin_assert(reader.read_typename(result.valueType));
bin_assert(!is_container(result.valueType));
bin_assert(reader.read_symbol<']'>());
value = result;
} else if (type == Type::MAP) {
Expand All @@ -383,6 +392,7 @@ namespace ritobin {
bin_assert(reader.read_typename(result.keyType));
bin_assert(reader.read_symbol<','>());
bin_assert(reader.read_typename(result.valueType));
bin_assert(!is_container(result.valueType));
bin_assert(reader.read_symbol<']'>());
value = result;
} else {
Expand All @@ -407,6 +417,18 @@ namespace ritobin {
return true;
}

bool read_value_visit(List2& value) noexcept {
bool end = false;
bin_assert(reader.read_nested_begin(end));
while (!end) {
auto list_item = ValueHelper::from_type(value.valueType);
bin_assert(read_value(list_item));
bin_assert(reader.read_nested_separator_or_end(end));
value.items.emplace_back(Element{ std::move(list_item) });
}
return true;
}

bool read_value_visit(Option& value) noexcept {
bool end = false;
bin_assert(reader.read_nested_begin(end));
Expand Down
11 changes: 11 additions & 0 deletions src/ritobin/text_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,13 @@ namespace ritobin {
writer.write_raw("]");
}

void write_type_visit(List2 const& value) noexcept {
writer.write(value.type);
writer.write_raw("[");
writer.write(value.valueType);
writer.write_raw("]");
}

void write_type_visit(Option const& value) noexcept {
writer.write(value.type);
writer.write_raw("[");
Expand Down Expand Up @@ -287,6 +294,10 @@ namespace ritobin {
write_items(value.items);
}

void write_value_visit(List2 const& value) noexcept {
write_items(value.items);
}

void write_value_visit(Option const& value) noexcept {
write_items(value.items);
}
Expand Down

0 comments on commit c0ee011

Please sign in to comment.