    1   /* JavaLiterals
    2    *
    3    * Created on Dec 31, 2003
    4    *
    5    * Copyright (C) 2004 Internet Archive.
    6    *
    7    * This file is part of the Heritrix web crawler (crawler.archive.org).
    8    *
    9    * Heritrix is free software; you can redistribute it and/or modify
    10   * it under the terms of the GNU Lesser Public License as published by
    11   * the Free Software Foundation; either version 2.1 of the License, or
    12   * any later version.
    13   *
    14   * Heritrix is distributed in the hope that it will be useful,
    15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17   * GNU Lesser Public License for more details.
    18   *
    19   * You should have received a copy of the GNU Lesser Public License
    20   * along with Heritrix; if not, write to the Free Software
    21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22   */
    23  package org.archive.util;
    24
    25  /***
    26   * Utility functions to escape or unescape Java literal strings.
    27   *
    28   * @author gojomo
    29   *
    30   */
    31  public class JavaLiterals {
    32
    33    public static String escape(String raw) {
    34      StringBuffer escaped = new StringBuffer();
    35      for(int i = 0; i<raw.length(); i++) {
    36        char c = raw.charAt(i);
    37        switch (c) {
    38          case '\b':
    39            escaped.append("//b");
    40            break;
    41          case '\t':
    42            escaped.append("//t");
    43            break;
    44          case '\n':
    45            escaped.append("//n");
    46            break;
    47          case '\f':
    48            escaped.append("//f");
    49            break;
    50          case '\r':
    51            escaped.append("//r");
    52            break;
    53          case '\"':
    54            escaped.append("//\"");
    55            break;
    56          case '\'':
    57            escaped.append("//'");
    58            break;
    59          case '//':
    60            escaped.append("////");
    61            break;
    62          default:
    63            if(Character.getType(c)==Character.CONTROL) {
    64              String unicode = Integer.toHexString((int)c);
    65              while(unicode.length()<4) {
    66                unicode = "0"+unicode;
    67              }
    68              escaped.append("//u"+unicode);
    69            } else {
    70              escaped.append(c);
    71            }
    72        }
    73
    74      }
    75      return escaped.toString();
    76    }
    77
    78    public static String unescape(String escaped) {
    79      StringBuffer raw = new StringBuffer();
    80      for(int i = 0; i<escaped.length(); i++) {
    81        char c = escaped.charAt(i);
    82        if (c!='//') {
    83          raw.append(c);
    84        } else {
    85          i++;
    86          if(i>=escaped.length()) {
    87            // trailing '/'
    88            raw.append(c);
    89            continue;
    90          }
    91          c = escaped.charAt(i);
    92          switch (c) {
    93            case 'b':
    94              raw.append('\b');
    95              break;
    96            case 't':
    97              raw.append('\t');
    98              break;
    99            case 'n':
    100             raw.append('\n');
    101             break;
    102           case 'f':
    103             raw.append('\f');
    104             break;
    105           case 'r':
    106             raw.append('r');
    107             break;
    108           case '"':
    109             raw.append('\"');
    110             break;
    111           case '\'':
    112             raw.append('\'');
    113             break;
    114           case '//':
    115             raw.append('//');
    116             break;
    117           case 'u':
    118             // unicode hex escape
    119             try {
    120               int unicode = Integer.parseInt(escaped.substring(i+1,i+5),16);
    121               raw.append((char)unicode);
    122               i = i + 4;
    123             } catch (IndexOutOfBoundsException e) {
    124               // err
    125               raw.append("//u");
    126             }
    127             break;
    128           default:
    129               if(Character.isDigit(c)) {
    130                 // octal escape
    131                 int end = Math.min(i+4,escaped.length());
    132                 int octal = Integer.parseInt(escaped.substring(i+1,end),8);
    133                 if(octal<256) {
    134                   raw.append((char)octal);
    135                   i = end - 1;
    136                 } else {
    137                   // err
    138                   raw.append('//');
    139                   raw.append(c);
    140                 }
    141               }
    142               break;
    143         }
    144       }
    145     }
    146     return raw.toString();
    147   }
    148 }