parseToUnicode static method

Map<int, String> parseToUnicode(
  1. Uint8List bytes
)

Implementation

static Map<int, String> parseToUnicode(Uint8List bytes) {
  final Map<int, String> map = <int, String>{};
  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 == 0x5B || byte == 0x2F || UPdfSyntax.isDigit(byte) || byte == 0x2D) {
      stack.add(UPdfSyntax.parseObject(cursor));
      continue;
    }
    final String keyword = UPdfSyntax.readKeyword(cursor);
    if (keyword.isEmpty) {
      cursor.skip(1);
      continue;
    }
    if (keyword == "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 && value is UPdfString) map[_toInt(code.bytes)] = _utf16(value.bytes);
      }
      stack.clear();
    } else if (keyword == "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;
        final int start = _toInt(low.bytes);
        final int end = _toInt(high.bytes);
        if (value is UPdfString) {
          final String base = _utf16(value.bytes);
          for (int code = start; code <= end && code - start < 65536; code++) {
            if (base.isEmpty) continue;
            final int lastUnit = base.codeUnitAt(base.length - 1) + (code - start);
            map[code] = base.substring(0, base.length - 1) + String.fromCharCode(lastUnit & 0xFFFF);
          }
        } else if (value is List<Object?>) {
          for (int j = 0; j < value.length && start + j <= end; j++) {
            final Object? entry = value[j];
            if (entry is UPdfString) map[start + j] = _utf16(entry.bytes);
          }
        }
      }
      stack.clear();
    } else if (keyword.startsWith("begin")) {
      stack.clear();
    } else if (stack.length > 3000) {
      stack.clear();
    }
  }
  return map;
}