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 }