static void parseClass (tokenInfo *const token) { Assert (isKeyword (token, KEYWORD_class)); readToken (token); if (isType (token, TOKEN_IDENTIFIER)) { #ifndef TYPE_REFERENCE_TOOL makeEiffelClassTag (token); readToken (token); #else vStringCopy (token->className, token->string); vStringUpper (token->className); if (PrintClass) puts (vStringValue (token->className)); if (! PrintReferences) exit (0); readToken (token); #endif } do { if (isType (token, TOKEN_OPEN_BRACKET)) parseGeneric (token, TRUE); else if (! isType (token, TOKEN_KEYWORD)) readToken (token); else switch (token->keyword) { case KEYWORD_inherit: parseInherit (token); break; case KEYWORD_feature: parseFeatureClauses (token); break; default: readToken (token); break; } } while (! isKeyword (token, KEYWORD_end)); }
/** @see BencSerializer.h */ static int32_t parseDictionary(const struct Reader* reader, const struct Allocator* allocator, Dict* output) { uint8_t nextChar; readUntil('{', reader); String* key; Object* value; struct Dict_Entry* entryPointer; struct Dict_Entry* lastEntryPointer = NULL; int ret = 0; for (;;) { while (!ret) { ret = reader->read(&nextChar, 0, reader); switch (nextChar) { case '"': break; case '}': reader->skip(1, reader); *output = lastEntryPointer; return 0; case '/': parseComment(reader); continue; default: reader->skip(1, reader); continue; } break; } if (ret) { printf("Unterminated dictionary\n"); return OUT_OF_CONTENT_TO_READ; } // Get key and value. if ((ret = parseString(reader, allocator, &key)) != 0) { return ret; } readUntil(':', reader); if ((ret = parseGeneric(reader, allocator, &value)) != 0) { return ret; } /* Allocate the entry. */ entryPointer = allocator->malloc(sizeof(struct Dict_Entry), allocator); entryPointer->next = lastEntryPointer; entryPointer->key = key; entryPointer->val = value; lastEntryPointer = entryPointer; } }
static void parseClass (tokenInfo *const token) { Assert (isKeyword (token, KEYWORD_class)); readToken (token); if (isType (token, TOKEN_IDENTIFIER)) { makeEiffelClassTag (token); readToken (token); } do { if (isType (token, TOKEN_OPEN_BRACKET)) parseGeneric (token, TRUE); else if (! isType (token, TOKEN_KEYWORD)) readToken (token); else switch (token->keyword) { case KEYWORD_inherit: parseInherit (token); break; case KEYWORD_feature: parseFeatureClauses (token); break; case KEYWORD_convert: parseConvert (token); break; default: readToken (token); break; } } while (! isKeyword (token, KEYWORD_end) && ! isType (token, TOKEN_EOF)); }
ParsedElement Animxmlparser::parseWp() { ParsedElement parsedElement; parsedElement.type = XML_WPACKET_RX; parseGeneric(parsedElement); return parsedElement; }
ParsedElement Animxmlparser::parseP () { ParsedElement parsedElement; parsedElement.isWpacket = false; parsedElement.type = XML_PACKET_RX; parseGeneric (parsedElement); return parsedElement; }
/** @see BencSerializer.h */ static int32_t parseList(const struct Reader* reader, const struct Allocator* allocator, List* output) { #define OUT_OF_CONTENT_TO_READ -2 #define UNPARSABLE -3 char nextChar; if (reader->read(&nextChar, 1, reader) != 0) { return OUT_OF_CONTENT_TO_READ; } if (nextChar != 'l') { return UNPARSABLE; } Object* element; struct List_Item* thisEntry = NULL; struct List_Item** lastEntryPointer = output; int ret; if (reader->read(&nextChar, 0, reader) != 0) { return OUT_OF_CONTENT_TO_READ; } *lastEntryPointer = NULL; while (nextChar != 'e') { ret = parseGeneric(reader, allocator, &element); if (ret != 0) { return ret; } thisEntry = Allocator_malloc(allocator, sizeof(struct List_Item)); thisEntry->elem = element; /* Read backwards so that the list reads out forward. */ *lastEntryPointer = thisEntry; lastEntryPointer = &(thisEntry->next); if (reader->read(&nextChar, 0, reader) != 0) { return OUT_OF_CONTENT_TO_READ; } } if (thisEntry) { thisEntry->next = NULL; } /* move the pointer to after the 'e' at the end of the list. */ reader->skip(1, reader); return 0; #undef OUT_OF_CONTENT_TO_READ #undef UNPARSABLE }
static void parseType (tokenInfo *const token) { boolean bitType; Assert (isType (token, TOKEN_IDENTIFIER)); #ifdef TYPE_REFERENCE_TOOL reportType (token); #endif bitType = (boolean)(strcmp ("BIT", vStringValue (token->string)) == 0); readToken (token); if (bitType && isType (token, TOKEN_NUMERIC)) readToken (token); else if (isType (token, TOKEN_OPEN_BRACKET)) parseGeneric (token, FALSE); }
static boolean parseType (tokenInfo *const token) { tokenInfo* const id = newToken (); copyToken (id, token); readToken (token); if (isType (token, TOKEN_COLON)) /* check for "{entity: TYPE}" */ { readToken (id); readToken (token); } if (isKeyword (id, KEYWORD_like)) { if (isType (token, TOKEN_IDENTIFIER) || isKeyword (token, KEYWORD_Current)) readToken (token); } else { if (isKeyword (id, KEYWORD_attached) || isKeyword (id, KEYWORD_detachable) || isKeyword (id, KEYWORD_expanded)) { copyToken (id, token); readToken (token); } if (isType (id, TOKEN_IDENTIFIER)) { #ifdef TYPE_REFERENCE_TOOL reportType (id); #endif if (isType (token, TOKEN_OPEN_BRACKET)) parseGeneric (token, FALSE); else if ((strcmp ("BIT", vStringValue (id->string)) == 0)) readToken (token); /* read token after number of bits */ } } deleteToken (id); return TRUE; }
/** @see BencSerializer.h */ static int32_t parseList(const struct Reader* reader, const struct Allocator* allocator, List* output) { char nextChar; readUntil('[', reader); Object* element; struct List_Item* thisEntry = NULL; struct List_Item** lastEntryPointer = output; int ret; for (;;) { for (;;) { if (reader->read(&nextChar, 0, reader) != 0) { printf("Unterminated list\n"); return OUT_OF_CONTENT_TO_READ; } if (nextChar == '/') { if ((ret = parseComment(reader)) != 0) { return ret; } continue; } switch (nextChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '[': case '{': case '"': break; case ']': reader->skip(1, reader); return 0; default: // FIXME: silently skipping anything we don't understand // might not be the best idea reader->skip(1, reader); continue; } break; } if ((ret = parseGeneric(reader, allocator, &element)) != 0) { return ret; } thisEntry = allocator->malloc(sizeof(struct List_Item), allocator); thisEntry->elem = element; thisEntry->next = NULL; // Read backwards so that the list reads out forward. *lastEntryPointer = thisEntry; lastEntryPointer = &(thisEntry->next); } }
/** @see BencSerializer.h */ static int32_t parseDictionary(const struct Reader* reader, const struct Allocator* allocator, Dict* output) { #define OUT_OF_CONTENT_TO_READ -2 #define UNPARSABLE -3 char nextChar; if (reader->read(&nextChar, 1, reader) < 0) { return OUT_OF_CONTENT_TO_READ; } if (nextChar != 'd') { /* Not a dictionary. */ return UNPARSABLE; } String* key; Object* value; struct Dict_Entry* entryPointer; struct Dict_Entry* lastEntryPointer = NULL; int ret; for (;;) { /* Peek at the next char. */ if (reader->read(&nextChar, 0, reader) < 0) { /* Ran over read buffer. */ return OUT_OF_CONTENT_TO_READ; } if (nextChar == 'e') { /* Got to the end. */ break; } /* Get key and value. */ ret = parseString(reader, allocator, &key); if (ret != 0) { return ret; } ret = parseGeneric(reader, allocator, &value); if (ret != 0) { return ret; } /* Allocate the entry. */ entryPointer = Allocator_malloc(allocator, sizeof(struct Dict_Entry)); entryPointer->next = lastEntryPointer; entryPointer->key = key; entryPointer->val = value; lastEntryPointer = entryPointer; } /* We got an 'e', leave the pointer on the next char after it. */ reader->skip(1, reader); *output = lastEntryPointer; return 0; #undef OUT_OF_CONTENT_TO_READ #undef UNPARSABLE }
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; }