// ------------------------------------------------------------------------------------------------ int ParseTokenAsInt(const Token& t, const char*& err_out) { err_out = NULL; if (t.Type() != TokenType_DATA) { err_out = "expected TOK_DATA token"; return 0; } if(t.IsBinary()) { const char* data = t.begin(); if (data[0] != 'I') { err_out = "failed to parse I(nt), unexpected data type (binary)"; return 0; } BE_NCONST int32_t ival = SafeParse<int32_t>(data+1, t.end()); AI_SWAP4(ival); return static_cast<int>(ival); } ai_assert(static_cast<size_t>(t.end() - t.begin()) > 0); const char* out; const int intval = strtol10(t.begin(),&out); if (out != t.end()) { err_out = "failed to parse ID"; return 0; } return intval; }
// ------------------------------------------------------------------------------------------------ // read an array of ints void ParseVectorDataArray(std::vector<int>& out, const Element& el) { out.resize( 0 ); const TokenList& tok = el.Tokens(); if(tok.empty()) { ParseError("unexpected empty element",&el); } if(tok[0]->IsBinary()) { const char* data = tok[0]->begin(), *end = tok[0]->end(); char type; uint32_t count; ReadBinaryDataArrayHead(data, end, type, count, el); if(!count) { return; } if (type != 'i') { ParseError("expected int array (binary)",&el); } std::vector<char> buff; ReadBinaryDataArray(type, count, data, end, buff, el); ai_assert(data == end); ai_assert(buff.size() == count * 4); out.reserve(count); const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]); for (unsigned int i = 0; i < count; ++i, ++ip) { BE_NCONST int32_t val = *ip; AI_SWAP4(val); out.push_back(val); } return; } const size_t dim = ParseTokenAsDim(*tok[0]); // see notes in ParseVectorDataArray() out.reserve(dim); const Scope& scope = GetRequiredScope(el); const Element& a = GetRequiredElement(scope,"a",&el); for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { const int ival = ParseTokenAsInt(**it++); out.push_back(ival); } }
// ------------------------------------------------------------------------------------------------ uint32_t ReadWord(const char* input, const char*& cursor, const char* end) { if(Offset(cursor, end) < 4) { TokenizeError("cannot ReadWord, out of bounds",input, cursor); } uint32_t word = *reinterpret_cast<const uint32_t*>(cursor); AI_SWAP4(word); cursor += 4; return word; }
// ------------------------------------------------------------------------------------------------ uint32_t ReadWord(const char* input, const char*& cursor, const char* end) { const size_t k_to_read = sizeof( uint32_t ); if(Offset(cursor, end) < k_to_read ) { TokenizeError("cannot ReadWord, out of bounds",input, cursor); } uint32_t word; ::memcpy(&word, cursor, 4); AI_SWAP4(word); cursor += k_to_read; return word; }
// ------------------------------------------------------------------------------------------------ std::string ParseTokenAsString(const Token& t, const char*& err_out) { err_out = NULL; if (t.Type() != TokenType_DATA) { err_out = "expected TOK_DATA token"; return ""; } if(t.IsBinary()) { const char* data = t.begin(); if (data[0] != 'S') { err_out = "failed to parse S(tring), unexpected data type (binary)"; return ""; } // read string length BE_NCONST int32_t len = SafeParse<int32_t>(data+1, t.end()); AI_SWAP4(len); ai_assert(t.end() - data == 5 + len); return std::string(data + 5, len); } const size_t length = static_cast<size_t>(t.end() - t.begin()); if(length < 2) { err_out = "token is too short to hold a string"; return ""; } const char* s = t.begin(), *e = t.end() - 1; if (*s != '\"' || *e != '\"') { err_out = "expected double quoted string"; return ""; } return std::string(s+1,length-2); }