MCPcopy Create free account
hub / github.com/OpenLoco/OpenLoco / findAndPreLoadObject

Function findAndPreLoadObject

src/OpenLoco/src/Objects/ObjectManager.cpp:423–483  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

421 };
422
423 static std::optional<PreLoadedObject> findAndPreLoadObject(const ObjectHeader& header)
424 {
425 auto installedObject = findObjectInIndex(header);
426 if (!installedObject.has_value())
427 {
428 return std::nullopt;
429 }
430
431 const auto filePath = fs::u8path(installedObject->_filepath);
432
433 FileStream fs(filePath, StreamMode::read);
434 SawyerStreamReader stream(fs);
435 PreLoadedObject preLoadObj{};
436 stream.read(&preLoadObj.header, sizeof(preLoadObj.header));
437 if (preLoadObj.header != header)
438 {
439 // Something wrong has happened and installed object does not match index
440 // Vanilla continued to search for subsequent matching installed headers.
441 Logging::error("Mismatch between installed object header and object file header!");
442 return std::nullopt;
443 }
444
445 // Vanilla would branch and perform more efficient readChunk if size was known from installedObject.ObjectHeader2
446 std::span<const std::byte> data;
447 try
448 {
449 data = stream.readChunk();
450 }
451 catch (const Exception::RuntimeError&)
452 {
453 // Something wrong has happened and installed object checksum is broken
454 Logging::error("Data could not be read!");
455 return std::nullopt;
456 }
457 if (!computeObjectChecksum(preLoadObj.header, data))
458 {
459 // Something wrong has happened and installed object checksum is broken
460 Logging::error("Mismatch between installed object header checksum and object file checksum!");
461 return std::nullopt;
462 }
463
464 // Copy the object into Loco freeable memory (required for when load loads the object)
465 preLoadObj.object = reinterpret_cast<Object*>(malloc(data.size()));
466 if (preLoadObj.object == nullptr)
467 {
468 return std::nullopt;
469 }
470 std::copy(std::begin(data), std::end(data), reinterpret_cast<std::byte*>(preLoadObj.object));
471
472 preLoadObj.objectData = std::span<std::byte>(reinterpret_cast<std::byte*>(preLoadObj.object), data.size());
473
474 if (!callObjectValidate(preLoadObj.header.getType(), *preLoadObj.object))
475 {
476 free(preLoadObj.object);
477 // Object failed validation
478 Logging::error("Object {} in index failed validation! (This should not be possible)", header.getName());
479 return std::nullopt;
480 }

Callers 2

loadTemporaryObjectFunction · 0.85
loadFunction · 0.85

Calls 11

findObjectInIndexFunction · 0.85
errorFunction · 0.85
computeObjectChecksumFunction · 0.85
beginFunction · 0.85
endFunction · 0.85
callObjectValidateFunction · 0.85
readChunkMethod · 0.80
getNameMethod · 0.80
readMethod · 0.45
sizeMethod · 0.45
getTypeMethod · 0.45

Tested by

no test coverage detected