void put_constants() { ser_u32(constants.size()); for (const auto &cnst : constants) { ser_type(cnst->type); switch (cnst->type) { case TC::NIL: break; case TC::BLN: ser_u8(cnst->u.as_bool); break; case TC::INT: ser_u64(cnst->u.as_int); break; case TC::FLT: ser_f64(cnst->u.as_float); break; case TC::STR: ser_str(*(cnst->u.as_str)); break; case TC::SYM: ser_str(*(cnst->u.as_str)); break; } } }
size_t serialize(gu::byte_t* buf, size_t buflen, size_t offset) const { if (buflen < offset + str_size_) { gu_throw_error (EMSGSIZE) << str_size_ << " > " << (buflen-offset); } std::string ser_str(str_); ser_str.resize(str_size_, '\0'); (void)std::copy(ser_str.data(), ser_str.data() + ser_str.size(), buf + offset); return offset + str_size_; }
static cstring *ser_wallet_root(const struct wallet *wlt) { cstring *rs = cstr_new_sz(8); ser_u32(rs, wlt->version); ser_bytes(rs, &wlt->chain->netmagic[0], 4); const uint32_t n_settings = 1; ser_varlen(rs, n_settings); ser_str(rs, "def_acct", 64); ser_varstr(rs, wlt->def_acct); return rs; }
cstring *ser_msg_version(const struct msg_version *mv) { cstring *s = cstr_new_sz(256); ser_u32(s, mv->nVersion); ser_u64(s, mv->nServices); ser_s64(s, mv->nTime); ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrTo); ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrFrom); ser_u64(s, mv->nonce); ser_str(s, mv->strSubVer, sizeof(mv->strSubVer)); ser_u32(s, mv->nStartingHeight); return s; }
void test_serialize() { char hex0[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"; char hex1[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c2"; char hex2[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c3"; uint8_t* hash0 = malloc(32); uint8_t* hash1 = malloc(32); uint8_t* hash2 = malloc(32); memcpy(hash0, utils_hex_to_uint8(hex0), 32); memcpy(hash1, utils_hex_to_uint8(hex1), 32); memcpy(hash2, utils_hex_to_uint8(hex2), 32); vector* vec = vector_new(5, free); vector_add(vec, hash0); vector_add(vec, hash1); vector_add(vec, hash2); cstring* s = cstr_new_sz(200); ser_u256_vector(s, vec); vector_free(vec, true); vector* vec2 = vector_new(0, NULL); struct const_buffer buf = {s->str, s->len}; deser_u256_vector(&vec2, &buf); vector_free(vec2, true); cstr_free(s, true); cstring* s2 = cstr_new_sz(200); ser_u16(s2, 0xAAFF); ser_u32(s2, 0xDDBBAAFF); ser_u64(s2, 0x99FF99FFDDBBAAFF); ser_varlen(s2, 10); ser_varlen(s2, 1000); ser_varlen(s2, 100000000); ser_str(s2, "test", 4); cstring* s3 = cstr_new("foo"); ser_varstr(s2, s3); cstr_free(s3, true); // ser_varlen(s2, (uint64_t)0x9999999999999999); // uint64 varlen is not supported right now struct const_buffer buf2 = {s2->str, s2->len}; uint16_t num0; deser_u16(&num0, &buf2); assert(num0 == 43775); //0xAAFF uint32_t num1; deser_u32(&num1, &buf2); assert(num1 == 3720063743); //0xDDBBAAFF uint64_t num2; deser_u64(&num2, &buf2); assert(num2 == 0x99FF99FFDDBBAAFF); //0x99FF99FFDDBBAAFF uint32_t num3; deser_varlen(&num3, &buf2); assert(num3 == 10); deser_varlen(&num3, &buf2); assert(num3 == 1000); deser_varlen(&num3, &buf2); assert(num3 == 100000000); char strbuf[255]; deser_str(strbuf, &buf2, 255); assert(strncmp(strbuf, "test", 4) == 0); cstring* deser_test = cstr_new_sz(0); deser_varstr(&deser_test, &buf2); assert(strncmp(deser_test->str, "foo", 3) == 0); cstr_free(deser_test, true); cstr_free(s2, true); }
ShapeParser::ShapeParseResult ShapeParser::serialized(const XMLNode& node, ParserState& S) { auto filename = S.map_asset_filepath(S.def_storage.prop_string(node, "filename")); int submesh_index = S.def_storage.prop_int(node, "shapeIndex"); bool flipNormals = S.def_storage.prop_bool(node, "flipNormals", false); bool faceNormals = S.def_storage.prop_bool(node, "faceNormals", false); float maxSmoothAngle = S.def_storage.prop_float(node, "maxSmoothAngle", 0.0f); auto name = boost::filesystem::path(filename).stem().string(); auto compiled_tar_folder = S.scene.getFileManager()->getCompiledMeshPath("") + name + "/"; auto get_compiled_submesh_filename = [&](size_t i) { return compiled_tar_folder + std::to_string(i) + ".xmsh"; }; if (!boost::filesystem::exists(compiled_tar_folder) || !boost::filesystem::exists(get_compiled_submesh_filename(0))) { boost::filesystem::create_directory(compiled_tar_folder); enum DataPresentFlag : uint32_t { VertexNormals = 0x0001, TextureCoords = 0x0002, VertexColors = 0x0008, UseFaceNormals = 0x0010, SinglePrecision = 0x1000, DoublePrecision = 0x2000, }; struct inflateStream { std::ifstream& m_childStream; size_t str_length; z_stream m_inflateStream; uint8_t m_inflateBuffer[32768]; inflateStream(std::ifstream& str) :m_childStream(str) { size_t pos = m_childStream.tellg(); m_childStream.seekg(0, m_childStream.end); str_length = m_childStream.tellg(); m_childStream.seekg(pos, m_childStream.beg); m_inflateStream.zalloc = Z_NULL; m_inflateStream.zfree = Z_NULL; m_inflateStream.opaque = Z_NULL; m_inflateStream.avail_in = 0; m_inflateStream.next_in = Z_NULL; int windowBits = 15; auto retval = inflateInit2(&m_inflateStream, windowBits); if (retval != Z_OK) std::cout << "erro, ret : " << retval << std::endl; } void read(void *ptr, size_t size) { uint8_t *targetPtr = (uint8_t *)ptr; while (size > 0) { if (m_inflateStream.avail_in == 0) { size_t remaining = str_length - m_childStream.tellg(); m_inflateStream.next_in = m_inflateBuffer; m_inflateStream.avail_in = (uInt)std::min(remaining, sizeof(m_inflateBuffer)); if (m_inflateStream.avail_in == 0) std::cout << "more bytes req : " << size << std::endl; m_childStream.read((char*)m_inflateBuffer, m_inflateStream.avail_in); } m_inflateStream.avail_out = (uInt)size; m_inflateStream.next_out = targetPtr; int retval = inflate(&m_inflateStream, Z_NO_FLUSH); switch (retval) { case Z_STREAM_ERROR: throw std::runtime_error("inflate(): stream error!"); case Z_NEED_DICT: throw std::runtime_error("inflate(): need dictionary!"); case Z_DATA_ERROR: throw std::runtime_error("inflate(): data error!"); case Z_MEM_ERROR: throw std::runtime_error("inflate(): memory error!"); }; size_t outputSize = size - (size_t)m_inflateStream.avail_out; targetPtr += outputSize; size -= outputSize; if (size > 0 && retval == Z_STREAM_END) throw std::runtime_error("inflate(): attempting to read past the end of the stream!"); } } }; std::ifstream ser_str(filename, std::ios::binary); uint16_t magic_maj, version_maj; ser_str.read((char*)&magic_maj, 2); if (magic_maj != 1052) throw std::runtime_error("corrupt file"); ser_str.read((char*)&version_maj, 2); ser_str.seekg(-4, ser_str.end); uint32_t n_meshes; ser_str.read((char*)&n_meshes, sizeof(n_meshes)); ser_str.seekg(-(sizeof(uint32_t) + (version_maj == 4 ? sizeof(uint64_t) : sizeof(uint32_t)) * n_meshes), ser_str.end); std::vector<uint64_t> mesh_offsets(n_meshes); if (version_maj == 4) ser_str.read((char*)mesh_offsets.data(), n_meshes * sizeof(uint64_t)); else { auto q = std::vector<uint32_t>(n_meshes); ser_str.read((char*)q.data(), n_meshes * sizeof(uint32_t)); for (size_t i = 0; i < n_meshes; i++) mesh_offsets[i] = q[i]; } for (size_t num_submesh = 0; num_submesh < n_meshes; num_submesh++) { ser_str.seekg(mesh_offsets[num_submesh], ser_str.beg); uint16_t magic, version; ser_str.read((char*)&magic, 2); if (magic == 0) break; ser_str.read((char*)&version, 2); if (version != 3 && version != 4) throw std::runtime_error("invalid version in serialized mesh file"); inflateStream comp_str(ser_str); DataPresentFlag flag; comp_str.read(&flag, sizeof(flag)); std::string name = "default"; if (version == 4) { name = ""; char last_read; do { comp_str.read(&last_read, sizeof(last_read)); name += last_read; } while (last_read != 0); } uint64_t nVertices, nTriangles; comp_str.read(&nVertices, sizeof(nVertices)); comp_str.read(&nTriangles, sizeof(nTriangles)); std::vector<Vec3f> positions(nVertices), normals(nVertices), colors(nVertices); std::vector<Vec2f> uvcoords(nVertices); std::vector<uint32_t> indices(nTriangles * 3); bool isSingle = true; auto read_n_vector = [&](int dim, float* buffer) { if (isSingle) comp_str.read((char*)buffer, sizeof(float) * dim * nVertices); else { double* double_storage = (double*)alloca(dim * sizeof(double)); for (size_t i = 0; i < nVertices; i++) { comp_str.read((char*)double_storage, dim * sizeof(double)); for (int j = 0; j < dim; j++) buffer[i * dim + j] = float(double_storage[j]); } } }; read_n_vector(3, (float*)positions.data()); if ((flag & DataPresentFlag::VertexNormals) == DataPresentFlag::VertexNormals) read_n_vector(3, (float*)normals.data()); if ((flag & DataPresentFlag::TextureCoords) == DataPresentFlag::TextureCoords) read_n_vector(2, (float*)uvcoords.data()); else std::fill(uvcoords.begin(), uvcoords.end(), Vec2f(0.0f)); if ((flag & DataPresentFlag::VertexColors) == DataPresentFlag::VertexColors) read_n_vector(3, (float*)colors.data()); comp_str.read((char*)indices.data(), sizeof(uint32_t) * nTriangles * 3); for (size_t i = 0; i < nTriangles * 3; i += 3) std::swap(indices[i + 0], indices[i + 2]); auto compiled_submesh_filename = get_compiled_submesh_filename(num_submesh); FileOutputStream fOut(compiled_submesh_filename); fOut << (unsigned int)MeshCompileType::Static; auto mat = Material(name.size() > 60 ? name.substr(0, 60) : name); mat.bsdf = CreateAggregate<BSDFALL>(diffuse()); Mesh::CompileMesh(positions.data(), (int)positions.size(), normals.data(), uvcoords.data(), indices.data(), (int)indices.size(), mat, 0.0f, fOut, flipNormals, faceNormals, maxSmoothAngle); fOut.Close(); } ser_str.close(); } auto obj = S.scene.CreateNode(get_compiled_submesh_filename(submesh_index)); parseGeneric(obj, node, S); return obj; }