#pragma once #include #include #include namespace saw { namespace encode { struct Minecraft {}; struct VarIntTransport {}; } template class data { private: ring_buffer buffer_; public: data() = default; data(std::size_t size): buffer_{size} {} buffer& get_buffer(){ return buffer_; } }; namespace mc { namespace impl { union minecraft_signed_four_conversion { int32_t s; uint32_t u; }; union minecraft_signed_eight_conversion { int64_t s; uint64_t u; }; template class minecraft_encode { static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); }; template class minecraft_encode{ static error_or encode(const data& from, buffer& to){ uint8_t encode_index = 0; minecraft_signed_four_conversion value; value.s = from.get(); /** * VarInt max length is 5 bytes */ std::array encode_data; do { uint8_t step = static_cast(value.u & 0x7F); value.u = value.u >> 7; if(value.u != 0){ step |= 0x80; } encode_data[encode_index] = step; ++encode_index; }while(value.u != 0); auto err = buffer.push(encode_data[0], encode_index); if (!err.template is_type()) { return err; } return no_error(); } }; template class minecraft_decode { static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); }; template class minecraft_decode{ static error_or decode(buffer& from, data& to){ uint8_t num_reads = 0; minecraft_signed_four_conversion value; value.u = 0; uint8_t read{}; do { auto err = from.pop(read); if( !err.template is_type() ){ return err; } value.u |= ((read & 0x7F) << (7*num_reads)); ++num_reads; if(num_reads > 5){ return make_error(); } } while( (read & 0x80) != 0); to.set(value.s); return no_error(); } }; } } namespace mc { } }