parseIndx static method

void parseIndx(
  1. MobiPdbRecord indxRecord,
  2. MobiIndx indx,
  3. MobiTagx tagx,
  4. MobiOrdt ordt,
)

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;
    }
  }
}