parse static method
Implementation
static UPdfCMap parse(Uint8List bytes, {bool vertical = false}) {
final List<UPdfCodespace> codespaces = <UPdfCodespace>[];
final Map<int, int> singles = <int, int>{};
final List<UPdfCidRange> ranges = <UPdfCidRange>[];
final UDocCursor cursor = UDocCursor(bytes);
final List<Object?> stack = <Object?>[];
int guard = 0;
while (!cursor.isEmpty && guard < 2000000) {
guard++;
UPdfSyntax.skipWhitespace(cursor);
if (cursor.isEmpty) break;
final int byte = cursor.peek;
if (byte == 0x3C && cursor.peekAt(1) != 0x3C) {
stack.add(UPdfSyntax.readHexString(cursor));
continue;
}
if (byte == 0x2F || byte == 0x5B || byte == 0x28 || (byte == 0x3C && cursor.peekAt(1) == 0x3C) || UPdfSyntax.isDigit(byte) || byte == 0x2D || byte == 0x2E) {
stack.add(UPdfSyntax.parseObject(cursor));
continue;
}
final String keyword = UPdfSyntax.readKeyword(cursor);
if (keyword.isEmpty) {
cursor.skip(1);
continue;
}
switch (keyword) {
case "endcodespacerange":
for (int i = 0; i + 1 < stack.length; i += 2) {
final Object? low = stack[i];
final Object? high = stack[i + 1];
if (low is UPdfString && high is UPdfString) codespaces.add(UPdfCodespace(low.bytes.length, _toInt(low.bytes), _toInt(high.bytes)));
}
stack.clear();
break;
case "endcidrange":
case "endbfrange":
for (int i = 0; i + 2 < stack.length; i += 3) {
final Object? low = stack[i];
final Object? high = stack[i + 1];
final Object? value = stack[i + 2];
if (low is! UPdfString || high is! UPdfString) continue;
if (value is num) {
ranges.add(UPdfCidRange(_toInt(low.bytes), _toInt(high.bytes), value.toInt()));
} else if (value is UPdfString) {
ranges.add(UPdfCidRange(_toInt(low.bytes), _toInt(high.bytes), _toInt(value.bytes)));
} else if (value is List<Object?>) {
final int start = _toInt(low.bytes);
for (int j = 0; j < value.length; j++) {
final Object? entry = value[j];
if (entry is UPdfString) singles[start + j] = _toInt(entry.bytes);
}
}
}
stack.clear();
break;
case "endcidchar":
case "endbfchar":
for (int i = 0; i + 1 < stack.length; i += 2) {
final Object? code = stack[i];
final Object? value = stack[i + 1];
if (code is! UPdfString) continue;
if (value is num) {
singles[_toInt(code.bytes)] = value.toInt();
} else if (value is UPdfString) {
singles[_toInt(code.bytes)] = _toInt(value.bytes);
}
}
stack.clear();
break;
case "begincodespacerange":
case "begincidrange":
case "beginbfrange":
case "begincidchar":
case "beginbfchar":
stack.clear();
break;
default:
if (stack.length > 3000) stack.clear();
break;
}
}
if (codespaces.isEmpty) codespaces.add(const UPdfCodespace(2, 0, 0xFFFF));
return UPdfCMap(codespaces: codespaces, singles: singles, ranges: ranges, vertical: vertical);
}