/** * Convert a list of values to an Oak markup String, e.g. "[ true, null, false ]". * * @param values The list of values * @return An Oak markup representation of the values. * @see #parse(String) */ public String toString(List<Object> values) { assert values != null : "Arrays can't be null, only empty"; final Text t = new Text(true); t.append('['); if (values.size() > 0) { t.space(); for (final Object value : values) { t.delimit(); toMarkup(value, t); } t.space(); } t.append(']'); return t.toString(); }
/** * Convert a potentially escaped string to text. * * @param t The source string. * @param start Starting offset. * @param end Ending offset. * @return Return the un-escaped string which may be zero-length but not null. */ private static String unescape(Text t, int start, int end) { final Text result = new Text(); /* * We know that there's a starting and ending quote that's been removed * from the string but otherwise we can't trust the contents. */ for (int i = start; i < end; i++) { final char c = t.charAt(i); final char escaped; if (c == '\\') { if (i < end - 1) { i++; final char next = t.charAt(i); if (next == 't') { escaped = '\t'; } else if (next == 'n') { escaped = '\n'; } else if (next == '"') { escaped = '"'; } else if (next == '\\') { escaped = '\\'; } else { error("Invalid escape: '\\" + next + '\''); escaped = next; } } else { error("Unterminated string"); escaped = c; } } else { escaped = c; } result.append(escaped); } return result.toString(); }
/** * In Oak it is possible to embed a tab character as an ASCII 8 or as a \t but internally we store * this in ASCII. The same goes for newlines and other tables (see the Oak reference). Here we * convert external format to internal format. * * @param source The text to process, may be null. E.g. "Hello\tworld" (with the quotes) * @return Return an internal format string. */ @Nullable public static String textToInternalFormat(@Nullable String source) throws ParsingException { final String result; assert source == null || source.length() >= 2 && source.charAt(0) == '"' && source.charAt(source.length() - 1) == '"'; if (source == null) { result = null; } else { final Text t = new Text(); final char[] ca = source.toCharArray(); final int length = ca.length - 1; // 1 because remove quotes for (int i = 1; i < length; i++) { // 1 because remove quotes final char c = ca[i]; if (c == '\\') { if (i == length - 1) { error("Invalid text " + source + ", escape at end of line"); } else { i++; final char next = ca[i]; if (next == 't') { t.append('\t'); } else if (next == 'n') { t.append('\n'); } else if (next == '"') { t.append('"'); } else if (next == '\\') { t.append('\\'); } else if (next == 'u') { // Unicode, 1-4 hex characters... i++; final Text hex = new Text(); hex.append(source); hex.setCursor(i); final int start = i; if (hex.consumeAscii(Text.ASCII_0_F)) { final int end = start + Math.min(4, hex.cursor() - start); final String string = hex.getString(start, end); final char u = (char) Integer.parseInt(string, 16); t.append(u); i = end - 1; } else { error("Invalid text " + source + ", incorrect unicode"); } } else { error("Invalid text: \\" + next); } } } else { t.append(c); } } result = t.toString(); } return result; }
/** * Convert a value to an Oak markup representation. * * @param value The value to represent. * @return E.g. `/Some/Path` * @see #parse(String) */ public final String toString(Object value) { final Text t = new Text(); toMarkup(value, t); return t.toString(); }