------------------------------------------------------------------------------------------------
| 303 | |
| 304 | // ------------------------------------------------------------------------------------------------ |
| 305 | bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const char *input, const char *&cursor, const char *end, bool const is64bits) { |
| 306 | // the first word contains the offset at which this block ends |
| 307 | const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); |
| 308 | |
| 309 | // we may get 0 if reading reached the end of the file - |
| 310 | // fbx files have a mysterious extra footer which I don't know |
| 311 | // how to extract any information from, but at least it always |
| 312 | // starts with a 0. |
| 313 | if(!end_offset) { |
| 314 | return false; |
| 315 | } |
| 316 | |
| 317 | if(end_offset > Offset(input, end)) { |
| 318 | TokenizeError("block offset is out of range",input, cursor); |
| 319 | } |
| 320 | else if(end_offset < Offset(input, cursor)) { |
| 321 | TokenizeError("block offset is negative out of range",input, cursor); |
| 322 | } |
| 323 | |
| 324 | // the second data word contains the number of properties in the scope |
| 325 | const uint64_t prop_count = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); |
| 326 | |
| 327 | // the third data word contains the length of the property list |
| 328 | const uint64_t prop_length = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); |
| 329 | |
| 330 | // now comes the name of the scope/key |
| 331 | const char* sbeg, *send; |
| 332 | ReadString(sbeg, send, input, cursor, end); |
| 333 | |
| 334 | output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) )); |
| 335 | |
| 336 | // now come the individual properties |
| 337 | const char* begin_cursor = cursor; |
| 338 | |
| 339 | if ((begin_cursor + prop_length) > end) { |
| 340 | TokenizeError("property length out of bounds reading length ", input, cursor); |
| 341 | } |
| 342 | |
| 343 | for (unsigned int i = 0; i < prop_count; ++i) { |
| 344 | ReadData(sbeg, send, input, cursor, begin_cursor + prop_length); |
| 345 | |
| 346 | output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) )); |
| 347 | |
| 348 | if(i != prop_count-1) { |
| 349 | output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) )); |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | if (Offset(begin_cursor, cursor) != prop_length) { |
| 354 | TokenizeError("property length not reached, something is wrong",input, cursor); |
| 355 | } |
| 356 | |
| 357 | // at the end of each nested block, there is a NUL record to indicate |
| 358 | // that the sub-scope exists (i.e. to distinguish between P: and P : {}) |
| 359 | // this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit. |
| 360 | const size_t sentinel_block_length = is64bits ? (sizeof(uint64_t)* 3 + 1) : (sizeof(uint32_t)* 3 + 1); |
| 361 | |
| 362 | if (Offset(input, cursor) < end_offset) { |
no test coverage detected