parseObject static method

Object? parseObject(
  1. UDocCursor cursor, {
  2. int depth = 0,
})

Implementation

static Object? parseObject(UDocCursor cursor, {int depth = 0}) {
  if (depth > uDocMaxDepth) throw const UDocParseException("Object nesting too deep");
  skipWhitespace(cursor);
  if (cursor.isEmpty) return null;
  final int byte = cursor.peek;
  if (byte == 0x2F) return UPdfName(readName(cursor));
  if (byte == 0x28) return readLiteralString(cursor);
  if (byte == 0x5B) {
    cursor.skip(1);
    final List<Object?> array = <Object?>[];
    while (true) {
      skipWhitespace(cursor);
      if (cursor.isEmpty) break;
      if (cursor.peek == 0x5D) {
        cursor.skip(1);
        break;
      }
      array.add(parseObject(cursor, depth: depth + 1));
      if (array.length > uDocMaxArrayLength) throw const UDocParseException("Array too large");
    }
    return array;
  }
  if (byte == 0x3C) {
    if (cursor.peekAt(1) == 0x3C) {
      cursor.skip(2);
      final Map<String, Object?> map = <String, Object?>{};
      while (true) {
        skipWhitespace(cursor);
        if (cursor.isEmpty) break;
        if (cursor.peek == 0x3E && cursor.peekAt(1) == 0x3E) {
          cursor.skip(2);
          break;
        }
        if (cursor.peek != 0x2F) {
          final Object? skipped = parseObject(cursor, depth: depth + 1);
          if (skipped == null && cursor.isEmpty) break;
          continue;
        }
        final String key = readName(cursor);
        final Object? value = parseObject(cursor, depth: depth + 1);
        map[key] = value;
        if (map.length > uDocMaxArrayLength) throw const UDocParseException("Dictionary too large");
      }
      return UPdfDict(map);
    }
    return readHexString(cursor);
  }
  if (isDigit(byte) || byte == 0x2B || byte == 0x2D || byte == 0x2E) {
    final int start = cursor.position;
    final num first = readNumber(cursor);
    if (first is int && first >= 0) {
      final int afterFirst = cursor.position;
      skipWhitespace(cursor);
      if (!cursor.isEmpty && isDigit(cursor.peek)) {
        final num second = readNumber(cursor);
        skipWhitespace(cursor);
        if (second is int && second >= 0 && !cursor.isEmpty && cursor.peek == 0x52 && !isRegular(cursor.peekAt(1))) {
          cursor.skip(1);
          return UPdfRef(first, second);
        }
      }
      cursor.seek(afterFirst);
    }
    if (cursor.position == start) cursor.skip(1);
    return first;
  }
  final String keyword = readKeyword(cursor);
  if (keyword == "true") return true;
  if (keyword == "false") return false;
  if (keyword == "null") return null;
  if (keyword.isEmpty) {
    cursor.skip(1);
    return null;
  }
  return UPdfName(keyword);
}