Clover coverage report - Clover results for XOM 1.2d1
Coverage timestamp: Wed Feb 8 2006 08:31:33 EST
file stats: LOC: 414   Methods: 8
NCLOC: 333   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
UnicodeWriter.java 100% 85.4% 100% 87.3%
coverage coverage
 1    /* Copyright 2002, 2003, 2005 Elliotte Rusty Harold
 2   
 3    This library is free software; you can redistribute it and/or modify
 4    it under the terms of version 2.1 of the GNU Lesser General Public
 5    License as published by the Free Software Foundation.
 6   
 7    This library is distributed in the hope that it will be useful,
 8    but WITHOUT ANY WARRANTY; without even the implied warranty of
 9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 10    GNU Lesser General Public License for more details.
 11   
 12    You should have received a copy of the GNU Lesser General Public
 13    License along with this library; if not, write to the
 14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 15    Boston, MA 02111-1307 USA
 16   
 17    You can contact Elliotte Rusty Harold by sending e-mail to
 18    elharo@metalab.unc.edu. Please include the word "XOM" in the
 19    subject line. The XOM home page is located at http://www.xom.nu/
 20    */
 21   
 22    package nu.xom;
 23   
 24    import java.io.IOException;
 25    import java.io.Writer;
 26   
 27    /**
 28    * @author Elliotte Rusty Harold
 29    * @version 1.1b4
 30    *
 31    */
 32    final class UnicodeWriter extends TextWriter {
 33   
 34  19160 UnicodeWriter(Writer out, String encoding) {
 35  19160 super(out, encoding);
 36    }
 37   
 38    /**
 39    * @see nu.xom.TextWriter#needsEscaping(char)
 40    */
 41  1964102 boolean needsEscaping(char c) {
 42  1964102 return false;
 43    }
 44   
 45   
 46  974164 void writeMarkup(String s) throws IOException {
 47   
 48  974164 if (normalize) {
 49  222668 s = normalize(s);
 50    }
 51   
 52  974164 int unicodeStringLength = getUnicodeLengthForMarkup(s);
 53  974164 if (unicodeStringLength >= 0) {
 54  921793 out.write(s);
 55  921793 if (unicodeStringLength > 0) {
 56  921773 column += unicodeStringLength;
 57  921773 lastCharacterWasSpace = false;
 58  921773 skipFollowingLinefeed = false;
 59  921773 justBroke=false;
 60    }
 61    }
 62    else { // write character by character
 63  52371 int length = s.length();
 64  52371 for (int i=0; i < length; i++) {
 65  1302518 writeMarkup(s.charAt(i));
 66    }
 67    }
 68   
 69    }
 70   
 71   
 72    /*
 73    * This is tricky. This method is doing two things:
 74    *
 75    * 1. It's counting the number of Unicode characters in s.
 76    * 2. It's checking to see if this text contains anything
 77    * that might need to be escaped.
 78    *
 79    * If the latter it returns -1; otherwise it returns the number of characters.
 80    */
 81  974164 private static int getUnicodeLengthForMarkup(String s) {
 82   
 83  974164 int unicodeLength = 0;
 84  974164 int javaLength = s.length();
 85  974164 for (int i = 0; i < javaLength; i++) {
 86  2163366 char c = s.charAt(i);
 87  2163366 if (c <= ' ') {
 88    // Really we're testing only for \t, \n, and space here.
 89    // However all other characters less than or equal to 32
 90    // can't appear in markup sections.
 91    // These characters cause an adjustment of
 92    // lastCharacterWasSpace, skipFollowingLinefeed, and justBroke
 93    // They may need to be escaped but only in doctype declarations.
 94    // Should these have their own writeDoctypeDeclaration method????
 95    // Also an issue with spaces and such in PIs, XML declaration, comments
 96  52371 return -1;
 97    }
 98    // Count the low surrogates but skip the high surrogates
 99    // so surrogate pairs aren't counted twice.
 100  2110981 else if (c < 0xD800 || c > 0xDBFF) unicodeLength++;
 101    }
 102  921793 return unicodeLength;
 103   
 104    }
 105   
 106   
 107  307699 void writeAttributeValue(String s) throws IOException {
 108   
 109  307699 if (normalize) {
 110  171231 s = normalize(s);
 111    }
 112  307699 int unicodeStringLength = getUnicodeLengthForAttributeValue(s);
 113  307699 if (unicodeStringLength >= 0) {
 114  307021 out.write(s);
 115  307021 if (unicodeStringLength > 0) {
 116  307013 column += unicodeStringLength;
 117  307013 lastCharacterWasSpace = false;
 118  307013 skipFollowingLinefeed = false;
 119  307013 justBroke=false;
 120    }
 121    }
 122    else {
 123  678 int length = s.length();
 124  678 for (int i=0; i < length; i++) {
 125  7222 writeAttributeValue(s.charAt(i));
 126    }
 127    }
 128   
 129    }
 130   
 131   
 132    // All three getUnicodeLengthForFOO methods are very similar.
 133    // Could the code duplciation be eliminated efficiently somehow?
 134  307699 private static int getUnicodeLengthForAttributeValue(String s) {
 135   
 136  307699 int unicodeLength = 0;
 137  307699 int javaLength = s.length();
 138  307699 for (int i = 0; i < javaLength; i++) {
 139  915148 char c = s.charAt(i);
 140  915148 switch (c) {
 141  2 case '\t': return -1;
 142  7 case '\n': return -1;
 143  0 case 11: // unreachable
 144  0 case 12: throw new XMLException("Bad character snuck into document");
 145  4 case '\r': return -1;
 146  0 case 14: // unreachable
 147  0 case 15: // unreachable
 148  0 case 16: // unreachable
 149  0 case 17: // unreachable
 150  0 case 18: // unreachable
 151  0 case 19: // unreachable
 152  0 case 20: // unreachable
 153  0 case 21: // unreachable
 154  0 case 22: // unreachable
 155  0 case 23: // unreachable
 156  0 case 24: // unreachable
 157  0 case 25: // unreachable
 158  0 case 26: // unreachable
 159  0 case 27: // unreachable
 160  0 case 28: // unreachable
 161  0 case 29: // unreachable
 162  0 case 30: // unreachable
 163  0 case 31: // unreachable
 164  0 throw new XMLException("Bad character snuck into document");
 165  628 case ' ': return -1;
 166  24 case '!':
 167  24 unicodeLength++;
 168  24 break;
 169  10 case '"':
 170  10 return -1;
 171  267 case '#':
 172  267 unicodeLength++;
 173  267 break;
 174  8 case '$':
 175  8 unicodeLength++;
 176  8 break;
 177  10 case '%':
 178  10 unicodeLength++;
 179  10 break;
 180  8 case '&':
 181  8 return -1;
 182  5 case '\'':
 183  5 unicodeLength++;
 184  5 break;
 185  472 case '(':
 186  472 unicodeLength++;
 187  472 break;
 188  473 case ')':
 189  473 unicodeLength++;
 190  473 break;
 191  8 case '*':
 192  8 unicodeLength++;
 193  8 break;
 194  20 case '+':
 195  20 unicodeLength++;
 196  20 break;
 197  8 case ',':
 198  8 unicodeLength++;
 199  8 break;
 200  4954 case '-':
 201  4954 unicodeLength++;
 202  4954 break;
 203  487 case '.':
 204  487 unicodeLength++;
 205  487 break;
 206  431 case '/':
 207  431 unicodeLength++;
 208  431 break;
 209  50802 case '0':
 210  50802 unicodeLength++;
 211  50802 break;
 212  74733 case '1':
 213  74733 unicodeLength++;
 214  74733 break;
 215  72778 case '2':
 216  72778 unicodeLength++;
 217  72778 break;
 218  72573 case '3':
 219  72573 unicodeLength++;
 220  72573 break;
 221  72559 case '4':
 222  72559 unicodeLength++;
 223  72559 break;
 224  66033 case '5':
 225  66033 unicodeLength++;
 226  66033 break;
 227  59450 case '6':
 228  59450 unicodeLength++;
 229  59450 break;
 230  49636 case '7':
 231  49636 unicodeLength++;
 232  49636 break;
 233  50314 case '8':
 234  50314 unicodeLength++;
 235  50314 break;
 236  51074 case '9':
 237  51074 unicodeLength++;
 238  51074 break;
 239  139 case ':':
 240  139 unicodeLength++;
 241  139 break;
 242  21 case ';':
 243  21 unicodeLength++;
 244  21 break;
 245  10 case '<':
 246  10 return -1;
 247  40 case '=':
 248  40 unicodeLength++;
 249  40 break;
 250  9 case '>':
 251  9 return -1;
 252  287151 default:
 253  275249 if (c < 0xd800 || c > 0xDBFF) unicodeLength++;
 254    }
 255    }
 256  307021 return unicodeLength;
 257   
 258    }
 259   
 260   
 261  169482 void writePCDATA(String s) throws IOException {
 262   
 263  169482 if (normalize) {
 264  17141 s = normalize(s);
 265    }
 266   
 267  169482 int unicodeStringLength = getUnicodeLengthForPCDATA(s);
 268  169482 if (unicodeStringLength >= 0) {
 269  137279 out.write(s);
 270  137279 if (unicodeStringLength > 0) {
 271  137246 column += unicodeStringLength;
 272  137246 lastCharacterWasSpace = false;
 273  137246 skipFollowingLinefeed = false;
 274  137246 justBroke=false;
 275    }
 276    }
 277    else {
 278  32203 int length = s.length();
 279  32203 for (int i=0; i < length; i++) {
 280  780242 writePCDATA(s.charAt(i));
 281    }
 282    }
 283   
 284    }
 285   
 286   
 287  169482 private static int getUnicodeLengthForPCDATA(String s) {
 288   
 289  169482 int unicodeLength = 0;
 290  169482 int javaLength = s.length();
 291  169482 for (int i = 0; i < javaLength; i++) {
 292  436934 char c = s.charAt(i);
 293  436934 switch (c) {
 294  1 case '\t': return -1;
 295  11203 case '\n': return -1;
 296  0 case 11: // unreachable
 297  0 case 12: throw new XMLException("Bad character snuck into document");
 298  5 case '\r': return -1;
 299  0 case 14: // unreachable
 300  0 case 15: // unreachable
 301  0 case 16: // unreachable
 302  0 case 17: // unreachable
 303  0 case 18: // unreachable
 304  0 case 19: // unreachable
 305  0 case 20: // unreachable
 306  0 case 21: // unreachable
 307  0 case 22: // unreachable
 308  0 case 23: // unreachable
 309  0 case 24: // unreachable
 310  0 case 25: // unreachable
 311  0 case 26: // unreachable
 312  0 case 27: // unreachable
 313  0 case 28: // unreachable
 314  0 case 29: // unreachable
 315  0 case 30: // unreachable
 316  0 case 31: // unreachable
 317  0 throw new XMLException("Bad character snuck into document");
 318  20554 case ' ': return -1;
 319  8 case '!':
 320  8 unicodeLength++;
 321  8 break;
 322  831 case '"':
 323  831 unicodeLength++;
 324  831 break;
 325  236 case '#':
 326  236 unicodeLength++;
 327  236 break;
 328  2 case '$':
 329  2 unicodeLength++;
 330  2 break;
 331  34 case '%':
 332  34 unicodeLength++;
 333  34 break;
 334  148 case '&':
 335  148 return -1;
 336  476 case '\'':
 337  476 unicodeLength++;
 338  476 break;
 339  633 case '(':
 340  633 unicodeLength++;
 341  633 break;
 342  1053 case ')':
 343  1053 unicodeLength++;
 344  1053 break;
 345  206 case '*':
 346  206 unicodeLength++;
 347  206 break;
 348  20 case '+':
 349  20 unicodeLength++;
 350  20 break;
 351  242 case ',':
 352  242 unicodeLength++;
 353  242 break;
 354  911 case '-':
 355  911 unicodeLength++;
 356  911 break;
 357  548 case '.':
 358  548 unicodeLength++;
 359  548 break;
 360  463 case '/':
 361  463 unicodeLength++;
 362  463 break;
 363  734 case '0':
 364  734 unicodeLength++;
 365  734 break;
 366  841 case '1':
 367  841 unicodeLength++;
 368  841 break;
 369  359 case '2':
 370  359 unicodeLength++;
 371  359 break;
 372  282 case '3':
 373  282 unicodeLength++;
 374  282 break;
 375  92 case '4':
 376  92 unicodeLength++;
 377  92 break;
 378  63 case '5':
 379  63 unicodeLength++;
 380  63 break;
 381  302 case '6':
 382  302 unicodeLength++;
 383  302 break;
 384  200 case '7':
 385  200 unicodeLength++;
 386  200 break;
 387  128 case '8':
 388  128 unicodeLength++;
 389  128 break;
 390  719 case '9':
 391  719 unicodeLength++;
 392  719 break;
 393  273 case ':':
 394  273 unicodeLength++;
 395  273 break;
 396  38 case ';':
 397  38 unicodeLength++;
 398  38 break;
 399  264 case '<':
 400  264 return -1;
 401  20 case '=':
 402  20 unicodeLength++;
 403  20 break;
 404  28 case '>':
 405  28 return -1;
 406  395017 default:
 407  394497 if (c < 0xd800 || c > 0xDBFF) unicodeLength++;
 408    }
 409    }
 410  137279 return unicodeLength;
 411   
 412    }
 413   
 414    }