Clover coverage report - Java Language Levels Test Coverage (javalanglevels-20120305-r5436)
Coverage timestamp: Sun Mar 4 2012 22:02:46 CST
file stats: LOC: 286   Methods: 7
NCLOC: 123   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CharConverter.java 29.2% 18.9% 42.9% 21.9%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.javalanglevels;
 38   
 39    /**
 40    * A class full of static methods for escaping/unescaping characters.
 41    * It's abstract because it should not be instantiated.
 42    */
 43    public abstract class CharConverter {
 44    /**
 45    * Escapes the given char to be suitable for writing out in
 46    * a Java char or String literal.
 47    *
 48    * @param c Character to escape
 49    * @return A string consisting of c, properly escaped for use
 50    * inside a Java char or String literal. There are no
 51    * quotation marks around the result.
 52    */
 53  0 public static String escapeChar(char c) {
 54  0 StringBuffer buf = new StringBuffer();
 55  0 escapeChar(c, buf);
 56  0 return buf.toString();
 57    }
 58   
 59    /**
 60    * Escapes the given char to be suitable for writing out in
 61    * a Java char or String literal.
 62    *
 63    * @param c Character to escape
 64    * @param buf StringBuffer where the result is written out
 65    */
 66  0 public static void escapeChar(char c, StringBuffer buf) {
 67  0 switch (c) {
 68  0 case '\n': buf.append("\\n"); break;
 69  0 case '\t': buf.append("\\t"); break;
 70  0 case '\b': buf.append("\\b"); break;
 71  0 case '\r': buf.append("\\r"); break;
 72  0 case '\f': buf.append("\\f"); break;
 73  0 case '\\': buf.append("\\\\"); break;
 74  0 case '\'': buf.append("\\\'"); break;
 75  0 case '\"': buf.append("\\\""); break;
 76  0 default:
 77    // unicode escape all non-ascii
 78  0 if ((c < 32) || (c > 127)) {
 79  0 String hex = Integer.toHexString(c);
 80  0 buf.append("\\u");
 81   
 82  0 for (int i = hex.length(); i < 4; i++) {
 83  0 buf.append('0');
 84    }
 85   
 86  0 buf.append(hex);
 87    }
 88    else {
 89  0 buf.append(c);
 90    }
 91  0 break;
 92    }
 93    }
 94   
 95    /**
 96    * Escapes the given String to be suitable for writing out as a
 97    * Java String literal.
 98    *
 99    * @param s String to escape
 100    * @return A string consisting of s, properly escaped for use
 101    * inside a Java String literal. There are no
 102    * quotation marks around the result.
 103    */
 104  0 public static String escapeString(String s) {
 105  0 StringBuffer buf = new StringBuffer();
 106   
 107  0 for (int i = 0; i < s.length(); i++) {
 108  0 escapeChar(s.charAt(i), buf);
 109    }
 110   
 111  0 return buf.toString();
 112    }
 113   
 114    /**
 115    * Unescapes the given string, escaped as it would be in Java source,
 116    * to a single char. Note that this does not handle unicode escapes
 117    * of the form \ uXXXX; these are expected to have already been processed
 118    * out of the input string. The only escapes that are handled are octal escapes
 119    * and \n \t \b \r \f \\ \' \".
 120    *
 121    * @param in String containing (possibly) escaped character, without quotes
 122    * @return char value of the input string, unescaped.
 123    */
 124  7 public static char unescapeChar(String in) {
 125  7 StringBuffer buf = new StringBuffer();
 126  7 int endPos = unescapeString(in, 0, buf);
 127  7 if (endPos < in.length()) {
 128  0 throw new IllegalArgumentException((in.length() - endPos) + " trailing" +
 129    " characters at the end of character"+
 130    " literal '" + in + "'");
 131    }
 132   
 133  7 return buf.charAt(0);
 134    }
 135   
 136    /**
 137    * Unescapes the given string, escaped as it would be in Java source,
 138    * to a String. Note that this does not handle unicode escapes
 139    * of the form \ uXXXX; these are expected to have already been processed
 140    * out of the input string. The only escapes that are handled are octal escapes
 141    * and \n \t \b \r \f \\ \' \".
 142    *
 143    * @param in String containing (possibly) escaped characters, without quotes
 144    * @return Unescaped string value of the input string
 145    */
 146  66 public static String unescapeString(String in) {
 147    // short circuit "" to allow the rest to assume != "".
 148  66 if (in.length() == 0) {
 149  2 return in;
 150    }
 151   
 152  64 StringBuffer buf = new StringBuffer();
 153  64 int nextStart = 0;
 154   
 155  64 while (nextStart < in.length()) {
 156  867 nextStart = unescapeString(in, nextStart, buf);
 157    }
 158   
 159  64 return buf.toString();
 160    }
 161   
 162    /*
 163    public static char unescapeChar(String in) {
 164    if (in.length() == 1) {
 165    return s.charAt(0);
 166    }
 167    else if ((in.length() > 1) && (in.charAt(0) == '\\')) {
 168    switch (in.charAt(1)) {
 169    case 'n': return '\n';
 170    case 't': return '\t';
 171    case 'b': return '\b';
 172    case 'r': return '\r';
 173    case 'f': return '\f';
 174    case '\\': return '\\';
 175    case '\'': return '\'';
 176    case '\"': return '\"';
 177    }
 178   
 179    // deal with octal escapes
 180    String afterBackslash = in.substring(1);
 181    try {
 182    int charValue = Integer.parseInt(afterBackslash, 8);
 183    if ((charValue > Character.MAX_VALUE) || (charValue < Character.MIN_VALUE)) {
 184    throw new RuntimeException("octal escaped character out of range: " + in);
 185    }
 186   
 187    return (char) charValue;
 188    }
 189    catch (NumberFormatException e) {
 190    throw new RuntimeException("multi-char char literal invalid! value=" + in);
 191    }
 192    }
 193    else {
 194    throw new RuntimeException("multi-character char literal doesn't start with \\! value=" + in);
 195    }
 196    }
 197    */
 198   
 199    /**
 200    * Unescapes one character in the given string, escaped as it would be in
 201    * Java source, to a String. Note that this does not handle unicode escapes
 202    * of the form \ uXXXX; these are expected to have already been processed
 203    * out of the input string. The only escapes that are handled are octal escapes
 204    * and \n \t \b \r \f \\ \' \".
 205    *
 206    * @param in String containing (possibly) escaped characters
 207    * @param startPos Starting position of the next character to unescape
 208    * @param out StringBuffer to write out the unescaped character to.
 209    *
 210    * @return Position after the end of the parsed character
 211    */
 212  874 public static int unescapeString(final String in,
 213    final int startPos,
 214    final StringBuffer out)
 215    {
 216  874 char first = in.charAt(startPos);
 217   
 218  874 if (first != '\\') {
 219  873 out.append(first);
 220  873 return startPos + 1;
 221    }
 222   
 223  1 char second = in.charAt(startPos + 1);
 224   
 225  1 switch (second) {
 226  0 case 'n': out.append('\n'); return startPos + 2;
 227  0 case 't': out.append('\t'); return startPos + 2;
 228  0 case 'b': out.append('\b'); return startPos + 2;
 229  0 case 'r': out.append('\r'); return startPos + 2;
 230  0 case 'f': out.append('\f'); return startPos + 2;
 231  1 case '\\': out.append('\\'); return startPos + 2;
 232  0 case '\'': out.append('\''); return startPos + 2;
 233  0 case '\"': out.append('\"'); return startPos + 2;
 234    }
 235   
 236    // The only cases left to deal with are octal escapes or invalid.
 237  0 if (_isOctalDigit(second)) {
 238    // If the first digit is < 4, there could be three octal digits.
 239    // Otherwise there can be only two.
 240  0 int maxDigits;
 241  0 if (second < '4') {
 242  0 maxDigits = 3;
 243    }
 244    else {
 245  0 maxDigits = 2;
 246    }
 247   
 248  0 StringBuffer octal = new StringBuffer(maxDigits);
 249  0 octal.append(second);
 250   
 251  0 int nextDigitPos = startPos + 2;
 252  0 while ((octal.length() < maxDigits) && (nextDigitPos < in.length())) {
 253  0 char nextChar = in.charAt(nextDigitPos);
 254  0 if (_isOctalDigit(nextChar)) {
 255  0 octal.append(nextChar);
 256  0 nextDigitPos++;
 257    }
 258    else { // not an octal digit, so our work here is done.
 259  0 break;
 260    }
 261    }
 262   
 263  0 try {
 264  0 int charValue = Integer.parseInt(octal.toString(), 8);
 265  0 if ((charValue > Character.MAX_VALUE) || (charValue < Character.MIN_VALUE)) {
 266  0 throw new IllegalArgumentException("Octal escape beginning at " +
 267    "position " + startPos + " out of range: " + in);
 268    }
 269   
 270  0 out.append((char) charValue);
 271  0 return nextDigitPos;
 272    }
 273    catch (NumberFormatException e) {
 274  0 throw new RuntimeException("Impossible to occur, but number format exception in octal escape!");
 275    }
 276    }
 277    else {
 278  0 throw new IllegalArgumentException("Invalid escape sequence at position "+
 279    startPos + ": " + in);
 280    }
 281    }
 282   
 283  0 private static boolean _isOctalDigit(char c) {
 284  0 return ((c >= '0') && (c <= '7'));
 285    }
 286    }