getStringifiedTagType static method

TagType getStringifiedTagType(
  1. StringReader reader
)

Implementation

static TagType getStringifiedTagType(StringReader reader) {
  reader.startSeek(); // Enter fake read mode
  TagType ret = TagType.End;
  bool isQuoted = false;
  bool isNumeric = true; // Assume true until proven otherwise
  bool isAlpha = true; // Assume true until proven otherwise
  bool hasDecimalPoint = false;
  StringBuffer buffer = StringBuffer();

  while (reader.canRead) {
    var val =
        reader.peek(); // Peek at the next character without consuming it

    if (val == ',' || val == '\n' || val == "]" || val == "}") {
      break; // Stop at comma or newline
    }

    if (val == '"') {
      reader.next(); // Consume the quote character
      isQuoted = true; // Toggle quoted state
      break;
    }

    if (val == "'") {
      reader.next();
      isQuoted = true;
      break;
    }

    if (val == "-" || val == "+") {
      reader.next();
    }

    if (val == '{') {
      ret = TagType.Compound; // Detected a CompoundTag
      reader.next(); // Consume '{'
      reader.endSeek(); // Restore the original stream position
      return ret;
    }

    if (val == '[') {
      reader.next(); // Consume '['
      // Peek ahead to differentiate between List and Array
      var prefix = reader.readUntil(";", 2).toUpperCase();

      switch (prefix) {
        case "B":
          ret = TagType.ByteArray;
          break;
        case "I":
          ret = TagType.IntArray;
          break;
        case "L":
          ret = TagType.LongArray;
          break;
        default:
          ret = TagType.List; // No type prefix, it's a List
          break;
      }

      reader.endSeek(); // Restore the original stream position
      return ret;
    }

    // Adjusting numeric and alphabetic checks
    var current = reader.next(); // Consume the character

    buffer.write(current);

    // Updated check to allow digits, decimal points, and numeric suffixes
    if (!RegExp(r'^[0-9]$').hasMatch(current)) {
      if (current == '.' && !hasDecimalPoint) {
        hasDecimalPoint = true; // Allow only one decimal point
      } else if (!RegExp(r'^[sSbBiIlLfFdD]$').hasMatch(current)) {
        isNumeric = false; // Not purely numeric or allowed decimal/suffix
      }
    }

    // Check if current character is purely alphabetical
    if (!RegExp(r'^[A-Za-z]$').hasMatch(current)) {
      isAlpha = false; // Not purely alphabetical
    }
  }

  var input = buffer.toString().trim();
  reader.endSeek(); // Restore the original stream position

  if (input.isEmpty) {
    return TagType.String; // No input detected
  }

  if (isQuoted) {
    return TagType.String; // Quoted string
  }

  if (isNumeric) {
    // Check the last character for type indicator (only for numeric input)
    var lastChar = input.substring(input.length - 1).toUpperCase();
    switch (lastChar) {
      case 'S':
        return TagType.Short;
      case 'B':
        return TagType.Byte;
      case 'I':
        return TagType.Int;
      case 'F':
        return TagType.Float;
      case 'D':
        return TagType.Double;
      case 'L':
        return TagType.Long;
      default:
        return TagType
            .Int; // Default to Int if purely numeric with no specific suffix
    }
  } else if (isAlpha && !input.contains(' ')) {
    return TagType.String; // Unquoted purely alphabetical string
  } else {
    return TagType.String; // Unquoted string with mixed content or spaces
  }
}