/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server; import com.foundationdb.util.AkibanAppender; import java.nio.ByteBuffer; import java.util.Collections; import java.util.EnumSet; import java.util.Formatter; public enum Quote { NONE(null, false), SINGLE_QUOTE('\'', false), DOUBLE_QUOTE('"', false), JSON_QUOTE('"', true); private final Character quoteChar; private final boolean escapeControlChars; Quote(Character quoteChar, boolean escapeControlChars) { this.quoteChar = quoteChar; this.escapeControlChars = escapeControlChars; } public void append(AkibanAppender sb, String s) { doAppend(sb, s, quoteChar, escapeControlChars); } private static boolean needsEscaping(char ch) { // Anything other than printing ASCII. return (ch >= 0200) || Character.isISOControl(ch); } private static final String SIMPLY_ESCAPED = "\r\n\t"; private static final String SIMPLY_ESCAPES = "rnt"; static void doAppend(AkibanAppender sb, String s, Character quote, boolean escapeControlChars) { if (s == null) { sb.append(null); return; } if (quote == null) { if (escapeControlChars) { // this is not put in as an assert, so that we can unit test it throw new AssertionError("can't escape without quoting, as a simplification to the code"); } sb.append(s); return; } for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if (escapeControlChars && needsEscaping(ch)) { int idx = SIMPLY_ESCAPED.indexOf(ch); if (idx < 0) { new Formatter(sb.getAppendable()).format("\\u%04x", (int)ch); } else { sb.append('\\'); sb.append(SIMPLY_ESCAPES.charAt(idx)); } } else { if (ch == quote || ch == '\\') { sb.append('\\'); } sb.append(ch); } } } }