1 31 package org.pdfbox.cos; 32 33 import java.io.ByteArrayOutputStream ; 34 import java.io.IOException ; 35 import java.io.OutputStream ; 36 import java.io.UnsupportedEncodingException ; 37 38 import org.pdfbox.persistence.util.COSHEXTable; 39 40 import org.pdfbox.exceptions.COSVisitorException; 41 42 48 public class COSString extends COSBase 49 { 50 53 public static final byte[] STRING_OPEN = new byte[]{ 40 }; 57 public static final byte[] STRING_CLOSE = new byte[]{ 41 }; 61 public static final byte[] HEX_STRING_OPEN = new byte[]{ 60 }; 65 public static final byte[] HEX_STRING_CLOSE = new byte[]{ 62 }; 69 public static final byte[] ESCAPE = new byte[]{ 92 }; 71 74 public static final byte[] CR_ESCAPE = new byte[]{ 92, 114 }; 78 public static final byte[] LF_ESCAPE = new byte[]{ 92, 110 }; 82 public static final byte[] HT_ESCAPE = new byte[]{ 92, 116 }; 86 public static final byte[] BS_ESCAPE = new byte[]{ 92, 98 }; 90 public static final byte[] FF_ESCAPE = new byte[]{ 92, 102 }; 92 private ByteArrayOutputStream out = new ByteArrayOutputStream (); 93 94 97 private boolean forceLiteralForm = false; 98 99 100 103 public COSString() 104 { 105 } 106 107 112 public COSString( String value ) 113 { 114 try 115 { 116 boolean unicode16 = false; 117 char[] chars = value.toCharArray(); 118 for( int i=0; i<chars.length; i++ ) 119 { 120 if( chars[i] > 255 ) 121 { 122 unicode16 = true; 123 } 124 } 125 if( unicode16 ) 126 { 127 out.write( 0xFE ); 128 out.write( 0xFF ); 129 out.write( value.getBytes( "UTF-16BE" ) ); 130 } 131 else 132 { 133 out.write(value.getBytes("ISO-8859-1")); 134 } 135 } 136 catch (IOException ignore) 137 { 138 ignore.printStackTrace(); 139 } 141 } 142 143 148 public COSString( byte[] value ) 149 { 150 try 151 { 152 out.write( value ); 153 } 154 catch (IOException ignore) 155 { 156 ignore.printStackTrace(); 157 } 159 } 160 161 167 168 public void setForceLiteralForm(boolean v) 169 { 170 forceLiteralForm = v; 171 } 172 173 180 public static COSString createFromHexString( String hex ) throws IOException 181 { 182 COSString retval = new COSString(); 183 StringBuffer hexBuffer = new StringBuffer ( hex.trim() ); 184 if( hexBuffer.length() % 2 == 1 ) 186 { 187 hexBuffer.append( "0" ); 188 } 189 for( int i=0; i<hexBuffer.length();) 190 { 191 String hexChars = "" + hexBuffer.charAt( i++ ) + hexBuffer.charAt( i++ ); 192 try 193 { 194 retval.append( Integer.parseInt( hexChars, 16 ) ); 195 } 196 catch( NumberFormatException e ) 197 { 198 throw new IOException ( "Error: Expected hex number, actual='" + hexChars + "'" ); 199 } 200 } 201 return retval; 202 } 203 204 209 public String getHexString() 210 { 211 StringBuffer retval = new StringBuffer ( out.size() * 2 ); 212 byte[] data = getBytes(); 213 for( int i=0; i<data.length; i++ ) 214 { 215 retval.append( COSHEXTable.HEX_TABLE[ (data[i]+256)%256 ] ); 216 } 217 218 return retval.toString(); 219 } 220 221 226 public String getString() 227 { 228 String retval; 229 String encoding = "ISO-8859-1"; 230 byte[] data = getBytes(); 231 int start = 0; 232 if( data.length > 2 ) 233 { 234 if( data[0] == (byte)0xFF && data[1] == (byte)0xFE ) 235 { 236 encoding = "UTF-16LE"; 237 start=2; 238 } 239 else if( data[0] == (byte)0xFE && data[1] == (byte)0xFF ) 240 { 241 encoding = "UTF-16BE"; 242 start=2; 243 } 244 } 245 try 246 { 247 retval = new String ( getBytes(), start, data.length-start, encoding ); 248 } 249 catch( UnsupportedEncodingException e ) 250 { 251 e.printStackTrace(); 253 retval = new String ( getBytes() ); 254 } 255 return retval; 256 } 257 258 265 public void append( byte[] data ) throws IOException 266 { 267 out.write( data ); 268 } 269 270 277 public void append( int in ) throws IOException 278 { 279 out.write( in ); 280 } 281 282 285 public void reset() 286 { 287 out.reset(); 288 } 289 290 295 public byte[] getBytes() 296 { 297 return out.toByteArray(); 298 } 299 300 303 public String toString() 304 { 305 return "COSString{" + new String ( getBytes() ) + "}"; 306 } 307 308 314 public void writePDF( OutputStream output ) throws IOException 315 { 316 boolean outsideASCII = false; 317 byte[] bytes = getBytes(); 319 for( int i=0; i<bytes.length && !outsideASCII; i++ ) 320 { 321 outsideASCII = bytes[i] <0; 324 } 325 if( !outsideASCII || forceLiteralForm ) 326 { 327 output.write(STRING_OPEN); 328 for( int i=0; i<bytes.length; i++ ) 329 { 330 int b = (bytes[i]+256)%256; 331 switch( b ) 332 { 333 case '(': 334 case ')': 335 case '\\': 336 { 337 output.write(ESCAPE); 338 output.write(b); 339 break; 340 } 341 case 10: { 343 output.write( LF_ESCAPE ); 344 break; 345 } 346 case 13: { 348 output.write( CR_ESCAPE ); 349 break; 350 } 351 case '\t': 352 { 353 output.write( HT_ESCAPE ); 354 break; 355 } 356 case '\b': 357 { 358 output.write( BS_ESCAPE ); 359 break; 360 } 361 case '\f': 362 { 363 output.write( FF_ESCAPE ); 364 break; 365 } 366 default: 367 { 368 output.write( b ); 369 } 370 } 371 } 372 output.write(STRING_CLOSE); 373 } 374 else 375 { 376 output.write(HEX_STRING_OPEN); 377 for(int i=0; i<bytes.length; i++ ) 378 { 379 output.write( COSHEXTable.TABLE[ (bytes[i]+256)%256 ] ); 380 } 381 output.write(HEX_STRING_CLOSE); 382 } 383 } 384 385 386 387 394 public Object accept(ICOSVisitor visitor) throws COSVisitorException 395 { 396 return visitor.visitFromString( this ); 397 } 398 399 402 public boolean equals(Object obj) 403 { 404 return (obj instanceof COSString) && java.util.Arrays.equals(((COSString) obj).getBytes(), getBytes()); 405 } 406 407 410 public int hashCode() 411 { 412 return getBytes().hashCode(); 413 } 414 } | Popular Tags |