001    // from java.util.Properties;
002    
003    package com.saelist.stx.util;
004    
005    public class Escaper {
006    
007      private static final String keyValueSeparators = "=: \t\r\n\f";
008    
009      private static final String strictKeyValueSeparators = "=:";
010    
011      private static final String specialSaveChars = "=: \t\r\n\f#!";
012    
013      private static final String whiteSpaceChars = " \t\r\n\f";
014    
015      /*
016       * Converts encoded \uxxxx to unicode chars
017       * and changes special saved chars to their original forms
018       */
019      public static String loadConvert (String theString) {
020        char aChar;
021        int len = theString.length();
022        StringBuffer outBuffer = new StringBuffer(len);
023    
024        for(int x=0; x<len; ) {
025          aChar = theString.charAt(x++);
026          if (aChar == '\\') {
027            aChar = theString.charAt(x++);
028            if(aChar == 'u') {
029              // Read the xxxx
030              int value=0;
031              for (int i=0; i<4; i++) {
032                aChar = theString.charAt(x++);
033                switch (aChar) {
034                case '0':
035                case '1':
036                case '2':
037                case '3':
038                case '4':
039                case '5':
040                case '6':
041                case '7':
042                case '8':
043                case '9':
044                  value = (value << 4) + aChar - '0';
045                  break;
046                case 'a':
047                case 'b':
048                case 'c':
049                case 'd':
050                case 'e':
051                case 'f':
052                  value = (value << 4) + 10 + aChar - 'a';
053                  break;
054                case 'A':
055                case 'B':
056                case 'C':
057                case 'D':
058                case 'E':
059                case 'F':
060                  value = (value << 4) + 10 + aChar - 'A';
061                  break;
062                default:
063                  throw new IllegalArgumentException(
064                    "Malformed \\uxxxx encoding.");
065                }
066              }
067              outBuffer.append((char)value);
068            } else {
069              if (aChar == 't')
070                aChar = '\t';
071              else if (aChar == 'r')
072                aChar = '\r';
073              else if (aChar == 'n')
074                aChar = '\n';
075              else if (aChar == 'f')
076                aChar = '\f';
077              outBuffer.append(aChar);
078            }
079          } else
080            outBuffer.append(aChar);
081        }
082        return outBuffer.toString();
083      }
084    
085      /*
086       * Converts unicodes to encoded \uxxxx
087       * and writes out any of the characters in specialSaveChars
088       * with a preceding slash
089       */
090      public static String saveConvert(String theString, boolean escapeSpace) {
091        int len = theString.length();
092        StringBuffer outBuffer = new StringBuffer(len*2);
093    
094        for(int x=0; x<len; x++) {
095          char aChar = theString.charAt(x);
096          switch(aChar) {
097          case ' ':
098            if (x == 0 || escapeSpace)
099              outBuffer.append('\\');
100    
101            outBuffer.append(' ');
102            break;
103          case '\\':
104            outBuffer.append('\\');
105            outBuffer.append('\\');
106            break;
107          case '\t':
108            outBuffer.append('\\');
109            outBuffer.append('t');
110            break;
111          case '\n':
112            outBuffer.append('\\');
113            outBuffer.append('n');
114            break;
115          case '\r':
116            outBuffer.append('\\');
117            outBuffer.append('r');
118            break;
119          case '\f':
120            outBuffer.append('\\');
121            outBuffer.append('f');
122            break;
123          default:
124            if ((aChar < 0x0020) || (aChar > 0x007e)) {
125              outBuffer.append('\\');
126              outBuffer.append('u');
127              outBuffer.append(toHex((aChar >> 12) & 0xF));
128              outBuffer.append(toHex((aChar >>  8) & 0xF));
129              outBuffer.append(toHex((aChar >>  4) & 0xF));
130              outBuffer.append(toHex( aChar        & 0xF));
131            } else {
132              if (specialSaveChars.indexOf(aChar) != -1)
133                outBuffer.append('\\');
134              outBuffer.append(aChar);
135            }
136          }
137        }
138        return outBuffer.toString();
139      }
140    
141      /**
142       * Convert a nibble to a hex character
143       * @param  nibble  the nibble to convert.
144       */
145      private static char toHex(int nibble) {
146        return hexDigit[(nibble & 0xF)];
147      }
148    
149      /** A table of hex digits */
150      private static final char[] hexDigit = {
151        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
152      };
153    
154    
155    
156    }