std::vector<ActiveRelationshipTableEntry> BinaryParse::activeArtObject(UInt32 dataLength, void* binaryData) { std::vector<ActiveRelationshipTableEntry> controls; UInt8* data = reinterpret_cast<UInt8*>(binaryData); struct EsifDataBinaryArtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); validateData(dataLength); UIntN rows = countArtRows(dataLength, data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(binaryData); data += sizeof(esif_data_variant); //Ignore revision field currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the ART has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source( reinterpret_cast<const char*>(&(currentRow->sourceDevice)) + sizeof(union esif_data_variant), currentRow->sourceDevice.string.length); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::string target( reinterpret_cast<const char*>(&(currentRow->targetDevice)) + sizeof(union esif_data_variant), currentRow->targetDevice.string.length); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::vector <UInt32> acEntries; acEntries.push_back(static_cast<UInt32>(currentRow->ac0MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac1MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac2MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac3MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac4MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac5MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac6MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac7MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac8MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac9MaxFanSpeed.integer.value)); ActiveRelationshipTableEntry temp( normalizeAcpiScope(source), normalizeAcpiScope(target), static_cast<UInt32>(currentRow->weight.integer.value), acEntries); controls.push_back(temp); // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryArtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); } return controls; }
ActiveRelationshipTable ActiveRelationshipTable::createArtFromDptfBuffer(const DptfBuffer& buffer) { std::vector<std::shared_ptr<RelationshipTableEntryBase>> entries; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); struct EsifDataBinaryArtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); if (buffer.size() == 0) { throw dptf_exception("There is no data to process."); } UIntN rows = countArtRows(buffer.size(), data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(buffer.get()); data += sizeof(esif_data_variant); // Ignore revision field currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the ART has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source = TableStringParser::getDeviceString((currentRow->sourceDevice)); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::string target = TableStringParser::getDeviceString((currentRow->targetDevice)); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::vector<UInt32> acEntries; acEntries.push_back(static_cast<UInt32>(currentRow->ac0MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac1MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac2MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac3MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac4MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac5MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac6MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac7MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac8MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac9MaxFanSpeed.integer.value)); auto newArtEntry = std::make_shared<ActiveRelationshipTableEntry>( BinaryParse::normalizeAcpiScope(source), BinaryParse::normalizeAcpiScope(target), static_cast<UInt32>(currentRow->weight.integer.value), acEntries); if (newArtEntry) { // Check for duplicate entries. Don't add entry if previous entry exists with same target/source pair Bool isDuplicateEntry = false; for (auto e = entries.begin(); e != entries.end(); e++) { auto artEntry = std::dynamic_pointer_cast<ActiveRelationshipTableEntry>(*e); if (artEntry && newArtEntry->isSameAs(*artEntry)) { isDuplicateEntry = true; break; } } if (isDuplicateEntry == false) { entries.push_back(newArtEntry); } } // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryArtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); } return ActiveRelationshipTable(entries); }