-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f18ca08
commit b82be3f
Showing
4 changed files
with
514 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,329 @@ | ||
// Code generated by vktl/cmd/tlgen2; DO NOT EDIT. | ||
#include "basictl.h" | ||
|
||
#define TLGEN2_UNLIKELY(x) \ | ||
(x) // __builtin_expect((x), 0) // could improve performance on your platform | ||
#define TLGEN2_NOINLINE // __attribute__ ((noinline)) // could improve performance on your platform | ||
|
||
namespace basictl { | ||
tl_istream::tl_istream(tl_istream_interface *provider) : provider(provider) {} | ||
|
||
tl_istream::~tl_istream() { | ||
this->last_release(); | ||
} | ||
|
||
bool tl_istream::nat_read(uint32_t &value) { return fetch_data(&value, 4); } | ||
|
||
bool tl_istream::nat_read_exact_tag(uint32_t tag) { | ||
uint32_t actual_tag = 0; | ||
if (TLGEN2_UNLIKELY(!nat_read(actual_tag))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(tag != actual_tag)) { | ||
return set_error_expected_tag(); | ||
} | ||
return true; | ||
} | ||
|
||
bool tl_istream::int_read(int32_t &value) { return fetch_data(&value, 4); } | ||
|
||
bool tl_istream::long_read(int64_t &value) { return fetch_data(&value, 8); } | ||
|
||
bool tl_istream::float_read(float &value) { return fetch_data(&value, 4); } | ||
|
||
bool tl_istream::double_read(double &value) { return fetch_data(&value, 8); } | ||
|
||
bool tl_istream::bool_read(bool &value, uint32_t f, uint32_t t) { | ||
uint32_t tag = 0; | ||
if (TLGEN2_UNLIKELY(!nat_read(tag))) { | ||
return false; | ||
} | ||
if (tag == t) { | ||
value = true; | ||
return true; | ||
} | ||
if (TLGEN2_UNLIKELY(tag != f)) { | ||
set_error_bool_tag(); | ||
} | ||
value = false; | ||
return true; | ||
} | ||
|
||
bool tl_istream::string_read(std::string &value) { | ||
if (TLGEN2_UNLIKELY(!ensure_byte())) { | ||
return false; | ||
} | ||
auto len = size_t(static_cast<unsigned char>(*ptr)); | ||
if (TLGEN2_UNLIKELY(len >= TL_BIG_STRING_MARKER)) { | ||
if (TLGEN2_UNLIKELY(len > TL_BIG_STRING_MARKER)) { | ||
return set_error("TODO - huge string"); | ||
} | ||
uint32_t len32 = 0; | ||
if (TLGEN2_UNLIKELY(!nat_read(len32))) { | ||
return false; | ||
} | ||
len = len32 >> 8U; | ||
value.clear(); | ||
if (TLGEN2_UNLIKELY(!fetch_data_append(value, len))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!fetch_pad((-len) & 3))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
auto pad = ((-(len + 1)) & 3); | ||
auto fullLen = 1 + len + pad; | ||
if (TLGEN2_UNLIKELY(ptr + fullLen > end_block)) { | ||
ptr += 1; | ||
value.clear(); | ||
if (TLGEN2_UNLIKELY(!fetch_data_append(value, len))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!fetch_pad(pad))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
// fast path for short strings that fully fit in buffer | ||
uint32_t x = 0; | ||
std::memcpy(&x, ptr + fullLen - 4, 4); | ||
if (TLGEN2_UNLIKELY((x & ~(0xFFFFFFFFU >> (8 * pad))) != 0)) { | ||
return set_error_string_padding(); | ||
} | ||
value.assign(ptr + 1, len); | ||
ptr += fullLen; | ||
return true; | ||
} | ||
|
||
void tl_istream::last_release() { | ||
provider->release_buffer(ptr - start_block); | ||
start_block = ptr; | ||
} | ||
|
||
bool tl_istream::has_error() { | ||
return hasError; | ||
} | ||
|
||
bool tl_istream::set_error(const char *e) { | ||
hasError = true; | ||
return false; | ||
} // TODO - set error field | ||
|
||
bool tl_istream::set_error_eof() { return set_error("EOF"); } | ||
|
||
bool tl_istream::set_error_sequence_length() { return set_error("sequence_length"); } | ||
|
||
bool tl_istream::set_error_string_padding() { return set_error("string_padding"); } | ||
|
||
bool tl_istream::set_error_bool_tag() { return set_error("bool_tag"); } | ||
|
||
bool tl_istream::set_error_expected_tag() { return set_error("expected_tag"); } | ||
|
||
bool tl_istream::set_error_union_tag() { return set_error("union_tag"); } | ||
|
||
void tl_istream::grow_buffer() { | ||
ptr = end_block; | ||
provider->release_buffer(ptr - start_block); | ||
auto new_buffer = provider->get_buffer(); | ||
ptr = reinterpret_cast<const char *>(new_buffer.data()); | ||
start_block = ptr; | ||
end_block = ptr + new_buffer.size(); | ||
} | ||
|
||
bool tl_istream::ensure_byte() { | ||
if (TLGEN2_UNLIKELY(ptr >= end_block)) { | ||
// assert(ptr <= end) | ||
grow_buffer(); | ||
// assert(ptr <= end) | ||
if (TLGEN2_UNLIKELY(ptr == end_block)) { | ||
return set_error_eof(); | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
bool tl_istream::fetch_data(void *vdata, size_t size) { | ||
char *data = reinterpret_cast<char *>(vdata); | ||
if (TLGEN2_UNLIKELY(ptr + size > end_block)) { | ||
return fetch_data2(vdata, size); | ||
} | ||
std::memcpy(data, ptr, size); | ||
ptr += size; | ||
return true; | ||
} | ||
|
||
bool tl_istream::fetch_data2(void *vdata, size_t size) { | ||
char *data = reinterpret_cast<char *>(vdata); | ||
for (; TLGEN2_UNLIKELY(ptr + size > end_block);) { | ||
// assert(ptr <= end) | ||
std::memcpy(data, ptr, end_block - ptr); | ||
data += end_block - ptr; | ||
size -= end_block - ptr; | ||
grow_buffer(); | ||
// assert(ptr <= end) | ||
if (TLGEN2_UNLIKELY(ptr == end_block)) { | ||
return set_error_eof(); | ||
} | ||
} | ||
std::memcpy(data, ptr, size); | ||
ptr += size; | ||
return true; | ||
} | ||
|
||
bool tl_istream::fetch_data_append(std::string &value, size_t size) { | ||
for (; TLGEN2_UNLIKELY(ptr + size > end_block);) { | ||
// assert(ptr <= end) | ||
value.append(ptr, end_block - ptr); | ||
size -= end_block - ptr; | ||
grow_buffer(); | ||
// assert(ptr <= end) | ||
if (TLGEN2_UNLIKELY(ptr == end_block)) { | ||
return set_error_eof(); | ||
} | ||
} | ||
value.append(ptr, size); | ||
ptr += size; | ||
return true; | ||
} | ||
|
||
bool tl_istream::fetch_pad(size_t len) { | ||
uint32_t x = 0; | ||
if (TLGEN2_UNLIKELY(!fetch_data(&x, len))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(x != 0)) { | ||
return set_error_string_padding(); | ||
} | ||
return true; | ||
} | ||
|
||
|
||
tl_ostream::tl_ostream(tl_ostream_interface *provider) { | ||
this->provider = provider; | ||
} | ||
|
||
tl_ostream::~tl_ostream() { | ||
this->last_release(); | ||
} | ||
|
||
bool tl_ostream::nat_write(uint32_t value) { return store_data(&value, 4); } | ||
|
||
bool tl_ostream::int_write(int32_t value) { return store_data(&value, 4); } | ||
|
||
bool tl_ostream::long_write(int64_t value) { return store_data(&value, 8); } | ||
|
||
bool tl_ostream::float_write(float value) { return store_data(&value, 4); } | ||
|
||
bool tl_ostream::double_write(double value) { return store_data(&value, 8); } | ||
|
||
bool tl_ostream::string_write(const std::string &value) { | ||
auto len = value.size(); | ||
if (TLGEN2_UNLIKELY(len > TL_MAX_TINY_STRING_LEN)) { | ||
if (TLGEN2_UNLIKELY(len > TL_BIG_STRING_LEN)) { | ||
return set_error("TODO - huge string"); | ||
} | ||
uint32_t p = (len << 8U) | TL_BIG_STRING_MARKER; | ||
if (TLGEN2_UNLIKELY(!store_data(&p, 4))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!store_data(value.data(), value.size()))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!store_pad((-len) & 3))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
auto pad = ((-(len + 1)) & 3); | ||
auto fullLen = 1 + len + pad; | ||
if (TLGEN2_UNLIKELY(ptr + fullLen > end_block)) { | ||
auto p = static_cast<unsigned char>(len); | ||
if (TLGEN2_UNLIKELY(!store_data(&p, 1))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!store_data(value.data(), value.size()))) { | ||
return false; | ||
} | ||
if (TLGEN2_UNLIKELY(!store_pad(pad))) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
// fast path for short strings that fully fit in buffer | ||
uint32_t x = 0; | ||
std::memcpy(ptr + fullLen - 4, &x, 4); // padding first | ||
*ptr = static_cast<char>(len); | ||
std::memcpy(ptr + 1, value.data(), len); | ||
ptr += fullLen; | ||
return true; | ||
} | ||
|
||
void tl_ostream::last_release() { | ||
provider->release_buffer(ptr - start_block); | ||
start_block = ptr; | ||
} | ||
|
||
bool tl_ostream::has_error() { | ||
return hasError; | ||
} | ||
|
||
bool tl_ostream::set_error(const char *e) { | ||
hasError = true; | ||
return false; | ||
} // TODO - set error field | ||
|
||
bool tl_ostream::set_error_eof() { return set_error("EOF"); } | ||
|
||
bool tl_ostream::set_error_sequence_length() { return set_error("sequence_length"); } | ||
|
||
void tl_ostream::grow_buffer() { | ||
ptr = end_block; | ||
provider->release_buffer(ptr - start_block); | ||
auto new_buffer = provider->get_buffer(); | ||
ptr = reinterpret_cast<char *>(new_buffer.data()); | ||
start_block = ptr; | ||
end_block = ptr + new_buffer.size(); | ||
} | ||
|
||
bool tl_ostream::store_data(const void *vdata, size_t size) { | ||
const char *data = reinterpret_cast<const char *>(vdata); | ||
for (; TLGEN2_UNLIKELY(ptr + size > end_block);) { | ||
// assert(ptr <= end) | ||
std::memcpy(ptr, data, end_block - ptr); | ||
data += end_block - ptr; | ||
size -= end_block - ptr; | ||
grow_buffer(); | ||
// assert(ptr <= end) | ||
if (TLGEN2_UNLIKELY(ptr == end_block)) { | ||
return set_error_eof(); | ||
} | ||
} | ||
std::memcpy(ptr, data, size); | ||
ptr += size; | ||
return true; | ||
} | ||
|
||
bool tl_ostream::store_pad(size_t size) { | ||
for (; TLGEN2_UNLIKELY(ptr + size > end_block);) { | ||
// assert(ptr <= end) | ||
std::memset(ptr, 0, end_block - ptr); | ||
size -= end_block - ptr; | ||
grow_buffer(); | ||
// assert(ptr <= end) | ||
if (TLGEN2_UNLIKELY(ptr == end_block)) { | ||
return set_error_eof(); | ||
} | ||
} | ||
if (size != 0) { | ||
ptr[0] = 0; | ||
ptr[size - 1] = 0; | ||
ptr[size / 2] = 0; | ||
ptr += size; | ||
} | ||
return true; | ||
} | ||
} // namespace basictl | ||
|
||
#undef TLGEN2_NOINLINE | ||
#undef TLGEN2_UNLIKELY |
Oops, something went wrong.