void QueryableNetstringsDeserializer::read(const uint32_t id, string &s) {
            map<uint32_t, streampos>::iterator it = m_values.find(id);

            if (it != m_values.end()) {
                m_buffer.seekg(it->second);
                uint32_t stringLength = 0;
                m_buffer.read(reinterpret_cast<char *>(&stringLength), sizeof(uint32_t));
                stringLength = ntohl(stringLength);
                char *str = new char[stringLength+1];
                m_buffer.read(reinterpret_cast<char *>(str), static_cast<uint32_t>(stringLength));
                str[stringLength] = '\0';
                // It is absolutely necessary to specify the size of the serialized string, otherwise, s contains only data until the first '\0' is read.
                s = string(str, stringLength);
                OPENDAVINCI_CORE_DELETE_ARRAY(str);
            }
        }
        void ProtoDeserializerVisitor::read(const uint32_t &fourByteID, const uint8_t &oneByteID, const string &/*longName*/, const string &/*shortName*/, void *data, const uint32_t &size) {
            m_size -= readAndValidateKey( (oneByteID > 0 ? oneByteID : fourByteID) , ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read data.
            char *_data = new char[length];
            m_buffer.read(_data, length);
            m_size -= length;

            // Move data.
            memset(data, 0, size);
            memcpy(data, _data, (size < length ? size : length));
            OPENDAVINCI_CORE_DELETE_ARRAY(_data);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &id, void *data, const uint32_t &size) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read data.
            char *_data = new char[length];
            m_buffer.read(_data, length);
            m_size -= length;

            // Move data.
            memset(data, 0, size);
            memcpy(data, _data, (size < length ? size : length));
            OPENDAVINCI_CORE_DELETE_ARRAY(_data);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &fourByteID, const uint8_t &oneByteID, const string &/*longName*/, const string &/*shortName*/, string &v) {
            m_size -= readAndValidateKey( (oneByteID > 0 ? oneByteID : fourByteID) , ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read string.
            char *str = new char[length+1];
            m_buffer.read(str, length);
            m_size -= length;

            // Create string.
            str[length] = 0;
            v = string(str, length);
            OPENDAVINCI_CORE_DELETE_ARRAY(str);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &id, string &v) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read string.
            char *str = new char[length+1];
            m_buffer.read(str, length);
            m_size -= length;

            // Create string.
            str[length] = 0;
            v = string(str, length);
            OPENDAVINCI_CORE_DELETE_ARRAY(str);
        }