Mega Code Archive

 
Categories / Java / File Input Output
 

Decode a path

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.    *    * <p>Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded bytes.    * <p>The validity of the input path is not checked (i.e. characters that were not encoded will    * not be reported as errors).    * <p>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();   } }