001 /*
002 * Copyright 2005,2009 Ivan SZKIBA
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.ini4j.spi;
017
018 public class EscapeTool
019 {
020 private static final char[] HEX = "0123456789abcdef".toCharArray();
021 private static final EscapeTool INSTANCE = ServiceFinder.findService(EscapeTool.class);
022 private static final char ASCII_MIN = 0x20;
023 private static final char ASCII_MAX = 0x7e;
024 private static final int HEX_DIGIT_MASK = 0x0f;
025 private static final int DIGIT_3_OFFSET = 4;
026 private static final int DIGIT_2_OFFSET = 8;
027 private static final int DIGIT_1_OFFSET = 12;
028 private static final int HEX_RADIX = 16;
029 private static final int UNICODE_HEX_DIGITS = 4;
030
031 public static EscapeTool getInstance()
032 {
033 return INSTANCE;
034 }
035
036 public String escape(String line)
037 {
038 int len = line.length();
039 StringBuilder buffer = new StringBuilder(len * 2);
040
041 for (int i = 0; i < len; i++)
042 {
043 char c = line.charAt(i);
044 int idx = "\\\t\n\f".indexOf(c);
045
046 if (idx >= 0)
047 {
048 buffer.append('\\');
049 buffer.append("\\tnf".charAt(idx));
050 }
051 else
052 {
053 if ((c < ASCII_MIN) || (c > ASCII_MAX))
054 {
055 buffer.append("\\u");
056 buffer.append(HEX[(c >>> DIGIT_1_OFFSET) & HEX_DIGIT_MASK]);
057 buffer.append(HEX[(c >>> DIGIT_2_OFFSET) & HEX_DIGIT_MASK]);
058 buffer.append(HEX[(c >>> DIGIT_3_OFFSET) & HEX_DIGIT_MASK]);
059 buffer.append(HEX[c & HEX_DIGIT_MASK]);
060 }
061 else
062 {
063 buffer.append(c);
064 }
065 }
066 }
067
068 return buffer.toString();
069 }
070
071 public String unescape(String line)
072 {
073 int n = line.length();
074 StringBuilder buffer = new StringBuilder(n);
075 int i = 0;
076
077 while (i < n)
078 {
079 char c = line.charAt(i++);
080
081 if (c == '\\')
082 {
083 c = line.charAt(i++);
084 if (c == 'u')
085 {
086 try
087 {
088 c = (char) Integer.parseInt(line.substring(i, i + UNICODE_HEX_DIGITS), HEX_RADIX);
089 i += UNICODE_HEX_DIGITS;
090 }
091 catch (Exception x)
092 {
093 throw new IllegalArgumentException("Malformed \\uxxxx encoding.", x);
094 }
095 }
096 else
097 {
098 int idx = "\\tnf".indexOf(c);
099
100 if (idx >= 0)
101 {
102 c = "\\\t\n\f".charAt(idx);
103 }
104 }
105 }
106
107 buffer.append(c);
108 }
109
110 return buffer.toString();
111 }
112 }