129 static constexpr int PAGE_DESCRIPTOR_BYTES = 12;
130 static constexpr int PAGE_TABLE_TAGS[] = { 65, 66, 45, 46, 47, 48, 41, 42, 74 };
131 static constexpr int PAGED_READ_ORDER[] = { 41, 42, 45, 46, 47, 48 };
133 auto recordStride = [
this](
int aTag ) -> uint32_t
137 case 41:
return m_version == 0x2017 ? 180 : 188;
139 case 45:
return m_version == 0x2017 ? 116 : 124;
140 case 46:
return m_version <= 0x2019 ? 32 : 40;
149 case 66:
return m_version <= 0x2022 ? 28 : 280;
158 for(
int tag = 2; tag <= 25; ++tag )
162 uint32_t fixedStride = 0;
165 fixedStride =
m_version <= 0x2022 ? 100 : 112;
167 fixedStride =
m_version <= 0x2024 ? 16 : 20;
173 if( fixedStride != 0 &&
static_cast<uint64_t
>( section.
count ) * fixedStride != section.
totalBytes )
178 const uint32_t stride =
m_version <= 0x2019 ? 20 : 36;
180 if(
static_cast<uint64_t
>( section.
count ) * stride != section.
totalBytes )
191 for(
int tag : { 26, 27 } )
202 uint64_t numPageDescriptors = 0;
204 for(
int tag : PAGE_TABLE_TAGS )
206 if( tag <
static_cast<int>(
m_sections.size() ) )
207 numPageDescriptors +=
m_sections[tag].totalBytes;
210 if( pageDirectory.
totalBytes !=
static_cast<uint64_t
>( pageDirectory.
count ) * PAGE_DESCRIPTOR_BYTES
211 || numPageDescriptors > pageDirectory.
count )
216 uint64_t descriptor =
217 pageDirectory.
physicalOffset + ( pageDirectory.
count - numPageDescriptors ) * PAGE_DESCRIPTOR_BYTES;
219 for(
int tag : PAGE_TABLE_TAGS )
221 if( tag >=
static_cast<int>(
m_sections.size() ) )
225 uint64_t records = 0;
227 for( uint32_t page = 0; page < section.
totalBytes; ++page )
229 if( descriptor + PAGE_DESCRIPTOR_BYTES >
m_data.size() )
232 records +=
m_cursor.U32At( descriptor + 8 );
233 descriptor += PAGE_DESCRIPTOR_BYTES;
236 if( records > UINT32_MAX )
250 for(
int tag : PAGED_READ_ORDER )
253 uint64_t bytes =
static_cast<uint64_t
>( section.
physicalCount ) * recordStride( tag );
255 if(
cursor + bytes >
m_data.size() || bytes > UINT32_MAX )
264 uint32_t liveRouteRules = 0;
265 uint32_t routeRuleStride = recordStride( 46 );
270 static_cast<uint64_t
>( routeRules.
physicalOffset ) +
static_cast<uint64_t
>(
index ) * routeRuleStride;
272 if(
m_cursor.U32At( offset ) < 0x80000000 &&
m_cursor.U32At( offset + 4 ) != 0 )
289 uint64_t routeRuleStateBytes =
static_cast<uint64_t
>( liveRouteRules ) * 4;
294 cursor += routeRuleStateBytes;
296 for(
int tag : { 51, 50, 52, 53, 54, 55, 56, 57 } )
310 for(
int tag = 58; tag <= 64; ++tag )
324 for(
int tag : { 65, 66 } )
327 uint64_t bytes =
static_cast<uint64_t
>( section.
physicalCount ) * recordStride( tag );
338 for(
int tag : { 67, 68 } )
353 const uint64_t layerBytes = 12 +
static_cast<uint64_t
>( layers.
totalBytes );
380 const uint64_t preferenceBytes = displayPreferences.
totalBytes - 4;
386 displayPreferences.
physicalBytes =
static_cast<uint32_t
>( preferenceBytes );
389 cursor += preferenceBytes;
391 for(
int tag = 72; tag <= 73 && tag < static_cast<int>(
m_sections.size() ); ++tag )
408 uint64_t bytes =
static_cast<uint64_t
>( section.
physicalCount ) * recordStride( 74 );
419 const uint32_t containerItemsOffset =
m_cursor.U32At(
m_data.size() - 4 );
422 || containerItemsOffset -
cursor < 15 )
425 static constexpr char POWER_SYS_TITLE[] =
"PowerSYS";
428 || !std::equal( std::begin( POWER_SYS_TITLE ), std::end( POWER_SYS_TITLE ) - 1,
429 m_data.begin() +
static_cast<std::ptrdiff_t
>(
cursor + 5 ) ) )
bool HasSdbMagic(const std::vector< uint8_t > &aData, uint8_t aMagic1)
Check the PADS SDB container magic, a leading 0x00 followed by a format-specific second byte.
void ValidateSdbFooter(const std::vector< uint8_t > &aData, size_t aFooterStart, const char *aGuid, size_t aGuidLen)
As CheckSdbFooter, throwing a bare IO_ERROR on failure.