parseIndx static method
Implementation
static void parseIndx(
MobiPdbRecord indxRecord, MobiIndx indx, MobiTagx tagx, MobiOrdt ordt) {
MobiBuffer buf = MobiBuffer(indxRecord.data!, 0);
final indxMagic = buf.getString(4);
final headerLength = buf.getInt32();
if (indxMagic != "INDX" ||
headerLength == 0 ||
headerLength > indxRecord.size!) {
throw MobiInvalidDataException("Corrputed Indx Record");
}
buf.seek(4);
final type = buf.getInt32();
buf.seek(4);
final idxtOffset = buf.getInt32();
final entriesCount = buf.getInt32();
if (entriesCount > indxRecordMaxCnt) {
throw MobiInvalidDataException("Too Many Entries in Indx Record");
}
if (buf.matchMagicOffset("TAGX", headerLength) &&
indx.totalEntriesCount == 0) {
buf.maxlen = headerLength;
MobiEncoding encoding = MobiEncoding.UTF8;
var encodingValue = buf.getInt32();
if (encodingValue == mobiNotSet) {
encoding = MobiEncoding.CP1252;
} else {
encoding = MobiEncoding.fromValue(encodingValue);
}
buf.seek(4);
final totalEntriesCount = buf.getInt32();
if (totalEntriesCount > indxTotalMaxCnt) {
throw MobiInvalidDataException("Too Many Entries in Indx Record");
}
var ordtOffset = buf.getInt32();
if (ordtOffset + ordtRecordMaxCnt + 4 > indxRecord.size!) {
ordtOffset = 0;
}
var ligtOffset = buf.getInt32();
var ligtEntriesCount = buf.getInt32();
if (ligtOffset + 4 * ligtEntriesCount + 4 > indxRecord.size!) {
ligtOffset = 0;
ligtEntriesCount = 0;
}
final cncxRecordsCount = buf.getInt32();
if (cncxRecordsCount > cncxRecordMaxCnt) {
throw MobiInvalidDataException("Too Many Entries in CNCX Record");
}
var ordtType = 0;
var ordtEntriesCount = 0;
var ordt1Offset = 0;
var ordt2Offset = 0;
var indexNameOffset = 0;
var indexNameLength = 0;
if (headerLength >= 180) {
buf.setPos(164);
ordtType = buf.getInt32();
ordtEntriesCount = buf.getInt32();
ordt1Offset = buf.getInt32();
ordt2Offset = buf.getInt32();
final entrySize = (ordtType == 0) ? 1 : 2;
if (ordt1Offset + entrySize * ordtEntriesCount > indxRecord.size! ||
ordt2Offset + 2 * ordtEntriesCount > indxRecord.size!) {
ordtEntriesCount = 0;
ordt1Offset = 0;
ordt2Offset = 0;
}
indexNameOffset = buf.getInt32();
indexNameLength = buf.getInt32();
}
buf.maxlen = indxRecord.size!;
buf.setPos(headerLength);
parseTagx(buf, tagx);
if (ordtEntriesCount > 0) {
ordt.offsetsCount = ordtEntriesCount;
ordt.type = ordtType;
ordt.ordt1Pos = ordt1Offset;
ordt.ordt2Pos = ordt2Offset;
parseOrdt(buf, ordt);
}
if (indexNameOffset > 0 && indexNameLength > 0) {
if (indexNameLength <= headerLength - indexNameOffset &&
indexNameLength < indxNameSizeMax) {
buf.setPos(indexNameOffset);
final name = buf.getString(indexNameLength);
indx.orthIndexName = name;
}
}
indx.encoding = encoding;
indx.type = type;
indx.entriesCount = entriesCount;
indx.totalEntriesCount = totalEntriesCount;
if (ligtEntriesCount != 0 && buf.matchMagicOffset("LIGT", ligtOffset)) {
ligtOffset = 0;
ligtEntriesCount = 0;
}
indx.ligtOffset = ligtOffset;
indx.ligtEntriesCount = ligtEntriesCount;
indx.ordtOffset = ordtOffset;
indx.cncxRecordsCount = cncxRecordsCount;
} else {
if (idxtOffset == 0) {
throw MobiInvalidDataException("Missing IDXT offset");
}
if (idxtOffset + 2 * entriesCount + 4 > indxRecord.size!) {
throw MobiInvalidDataException("IDXT Record Too Long");
}
buf.setPos(idxtOffset);
MobiIdxt idxt = MobiIdxt();
parseIdxt(buf, idxt, entriesCount);
if (entriesCount > 0) {
int i = 0;
indx.entries = List.generate(entriesCount, (int i) => MobiIndexEntry());
while (i < entriesCount) {
parseIndexEntry(indx, idxt, tagx, ordt, buf, i);
i++;
}
indx.entriesCount += entriesCount;
}
}
}