/*
* Copyright 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.nimingban.client;
import android.support.annotation.StringDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class StringEscape {
@StringDef({LANGUAGE_JSON})
@Retention(RetentionPolicy.SOURCE)
private @interface Language {}
private static final String LANGUAGE_JSON = "json";
private static char charAt(String str, int index, @Language String language) throws UnescapeException {
if (index < 0 || index >= str.length()) {
throw new UnescapeException(language);
}
return str.charAt(index);
}
private static String substring(String str, int start, int end, @Language String language) throws UnescapeException {
if (start >= 0 && start <= end && end <= str.length()) {
return str.substring(start, end);
} else {
throw new UnescapeException(language);
}
}
private static void checkQuote(char quote, @Language String language) throws UnescapeException {
if (quote != '\'' && quote != '"') {
throw new UnescapeException(language);
}
}
public static String unescapeJson(String str) throws UnescapeException {
if (str == null) {
return null;
}
if (str.length() == 0) {
return "";
}
int index = 0;
char c;
char quote;
// Get quote
quote = charAt(str, index++, LANGUAGE_JSON);
checkQuote(quote, LANGUAGE_JSON);
StringBuilder sb = new StringBuilder();
for (;;) {
c = charAt(str, index++, LANGUAGE_JSON);
switch (c) {
case 0:
case '\n':
case '\r':
throw new UnescapeException(LANGUAGE_JSON);
case '\\':
c = charAt(str, index++, LANGUAGE_JSON);
switch (c) {
case 'b':
sb.append('\b');
break;
case 't':
sb.append('\t');
break;
case 'n':
sb.append('\n');
break;
case 'f':
sb.append('\f');
break;
case 'r':
sb.append('\r');
break;
case 'u':
sb.append((char) Integer.parseInt(substring(str, index, index += 4, LANGUAGE_JSON), 16));
break;
case 'x' :
sb.append((char) Integer.parseInt(substring(str, index, index += 2, LANGUAGE_JSON), 16));
break;
default:
sb.append(c);
}
break;
default:
if (c == quote) {
return sb.toString();
} else {
sb.append(c);
}
}
}
}
public static class UnescapeException extends Exception {
public UnescapeException(@Language String language) {
super("Can't unescape " + language);
}
}
}