static ByteString unescapeBytes()

in tajo-common/src/main/java/org/apache/tajo/datum/protobuf/ProtobufJsonFormat.java [1102:1195]


  static ByteString unescapeBytes(CharSequence input) throws InvalidEscapeSequence {
    byte[] result = new byte[input.length()];
    int pos = 0;
    for (int i = 0; i < input.length(); i++) {
      char c = input.charAt(i);
      if (c == '\\') {
        if (i + 1 < input.length()) {
          ++i;
          c = input.charAt(i);
          if (TextUtils.isOctal(c)) {
            // Octal escape.
            int code = TextUtils.digitValue(c);
            if ((i + 1 < input.length()) && TextUtils.isOctal(input.charAt(i + 1))) {
              ++i;
              code = code * 8 + TextUtils.digitValue(input.charAt(i));
            }
            if ((i + 1 < input.length()) && TextUtils.isOctal(input.charAt(i + 1))) {
              ++i;
              code = code * 8 + TextUtils.digitValue(input.charAt(i));
            }
            result[pos++] = (byte) code;
          } else {
            switch (c) {
              case 'a':
                result[pos++] = 0x07;
                break;
              case 'b':
                result[pos++] = '\b';
                break;
              case 'f':
                result[pos++] = '\f';
                break;
              case 'n':
                result[pos++] = '\n';
                break;
              case 'r':
                result[pos++] = '\r';
                break;
              case 't':
                result[pos++] = '\t';
                break;
              case 'v':
                result[pos++] = 0x0b;
                break;
              case '\\':
                result[pos++] = '\\';
                break;
              case '\'':
                result[pos++] = '\'';
                break;
              case '"':
                result[pos++] = '\"';
                break;

              case 'x':
                // hex escape
                int code = 0;
                if ((i + 1 < input.length()) && TextUtils.isHex(input.charAt(i + 1))) {
                  ++i;
                  code = TextUtils.digitValue(input.charAt(i));
                } else {
                  throw new InvalidEscapeSequence("Invalid escape sequence: '\\x' with no digits");
                }
                if ((i + 1 < input.length()) && TextUtils.isHex(input.charAt(i + 1))) {
                  ++i;
                  code = code * 16 + TextUtils.digitValue(input.charAt(i));
                }
                result[pos++] = (byte) code;
                break;
              case 'u':
                // UTF8 escape
                code = (16 * 3 * TextUtils.digitValue(input.charAt(i+1))) +
                    (16 * 2 * TextUtils.digitValue(input.charAt(i+2))) +
                    (16 * TextUtils.digitValue(input.charAt(i+3))) +
                    TextUtils.digitValue(input.charAt(i+4));
                i = i+4;
                result[pos++] = (byte) code;
                break;

              default:
                throw new InvalidEscapeSequence("Invalid escape sequence: '\\" + c
                    + "'");
            }
          }
        } else {
          throw new InvalidEscapeSequence("Invalid escape sequence: '\\' at end of string.");
        }
      } else {
        result[pos++] = (byte) c;
      }
    }

    return ByteString.copyFrom(result, 0, pos);
  }