import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.BitSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.StringTokenizer;
/*
Derby - Class org.apache.derby.iapi.util.PropertyUtil
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to you 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.
*/
public class Main {
/**
* Array containing the safe characters set as defined by RFC 1738
*/
private static BitSet safeCharacters;
private static final char[] hexadecimal =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
static {
safeCharacters = new BitSet(256);
int i;
// 'lowalpha' rule
for (i = 'a'; i <= 'z'; i++) {
safeCharacters.set(i);
}
// 'hialpha' rule
for (i = 'A'; i <= 'Z'; i++) {
safeCharacters.set(i);
}
// 'digit' rule
for (i = '0'; i <= '9'; i++) {
safeCharacters.set(i);
}
// 'safe' rule
safeCharacters.set('$');
safeCharacters.set('-');
safeCharacters.set('_');
safeCharacters.set('.');
safeCharacters.set('+');
// 'extra' rule
safeCharacters.set('!');
safeCharacters.set('*');
safeCharacters.set('\'');
safeCharacters.set('(');
safeCharacters.set(')');
safeCharacters.set(',');
// special characters common to http: file: and ftp: URLs ('fsegment' and 'hsegment' rules)
safeCharacters.set('/');
safeCharacters.set(':');
safeCharacters.set('@');
safeCharacters.set('&');
safeCharacters.set('=');
}
/**
* Decode a path.
*
* Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded bytes.
*
The validity of the input path is not checked (i.e. characters that were not encoded will
* not be reported as errors).
*
This method differs from URLDecoder.decode in that it always uses UTF-8 (while URLDecoder
* uses the platform default encoding, often ISO-8859-1), and doesn't translate + characters to spaces.
*
* @param path the path to decode
* @return the decoded path
*/
public static String decodePath(String path) {
StringBuffer translatedPath = new StringBuffer(path.length());
byte[] encodedchars = new byte[path.length() / 3];
int i = 0;
int length = path.length();
int encodedcharsLength = 0;
while (i < length) {
if (path.charAt(i) == '%') {
// we must process all consecutive %-encoded characters in one go, because they represent
// an UTF-8 encoded string, and in UTF-8 one character can be encoded as multiple bytes
while (i < length && path.charAt(i) == '%') {
if (i + 2 < length) {
try {
byte x = (byte)Integer.parseInt(path.substring(i + 1, i + 3), 16);
encodedchars[encodedcharsLength] = x;
} catch (NumberFormatException e) {
throw new IllegalArgumentException("NetUtils.decodePath: " +
"Illegal hex characters in pattern %" + path.substring(i + 1, i + 3));
}
encodedcharsLength++;
i += 3;
} else {
throw new IllegalArgumentException("NetUtils.decodePath: " +
"% character should be followed by 2 hexadecimal characters.");
}
}
try {
String translatedPart = new String(encodedchars, 0, encodedcharsLength, "UTF-8");
translatedPath.append(translatedPart);
} catch (UnsupportedEncodingException e) {
// the situation that UTF-8 is not supported is quite theoretical, so throw a runtime exception
throw new RuntimeException("Problem in decodePath: UTF-8 encoding not supported.");
}
encodedcharsLength = 0;
} else {
// a normal character
translatedPath.append(path.charAt(i));
i++;
}
}
return translatedPath.toString();
}
}