{
log.debug("parseCOSString() " + pdfSource );
}
char nextChar = (char)pdfSource.read();
//System.out.println( "parseCOSString() nextChar=" + nextChar );
COSString retval = new COSString();
char openBrace;
char closeBrace;
if( nextChar == '(' )
{
openBrace = '(';
closeBrace = ')';
}
else if( nextChar == '<' )
{
openBrace = '<';
closeBrace = '>';
}
else
{
throw new IOException( "parseCOSString string should start with '(' or '<' and not '" + nextChar + "' " + pdfSource );
}
//This is the number of braces read
//
int braces = 1;
while( braces > 0 && !pdfSource.isEOF())
{
char c = (char)pdfSource.read();
if(c == closeBrace)
{
braces--;
if( braces != 0 )
{
retval.append( c );
}
}
else if( c == openBrace )
{
braces++;
retval.append( c );
}
else if( c == '\\' )
{
int next = pdfSource.read();
switch(next)
{
case 'n':
retval.append( (char)10 );
break;
case 'r':
retval.append( (char)13 );
break;
case 't':
retval.append( (char)9 );
break;
case 'b':
retval.append( (char)8 );
break;
case 'f':
retval.append( (char)12 );
case '(':
case ')':
case '\\':
retval.append( (char)next );
break;
case 10:
case 13:
//this is a break in the line so ignore it and the newline and continue
while( isEOL() && !pdfSource.isEOF())
{
pdfSource.read();
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{
StringBuffer octal = new StringBuffer();
octal.append( "" + (char)next );
if( (char)pdfSource.peek() >= '0' && (char)pdfSource.peek() <= '7' )
{
octal.append( (char)pdfSource.read() );
}
if( (char)pdfSource.peek() >= '0' && (char)pdfSource.peek() <= '7' )
{
octal.append( (char)pdfSource.read() );
}
int character = 0;
try
{
character = Integer.parseInt( octal.toString(), 8 );
}
catch( NumberFormatException e )
{
throw new IOException( "Error: Expected octal character, actual='" + octal + "'" );
}
retval.append( character );
break;
}
default:
{
retval.append( '\\' );
retval.append( (char)next );
//another ficken problem with PDF's, sometimes the \ doesn't really
//mean escape like the PDF spec says it does, sometimes is should be literal
//which is what we will assume here.
//throw new IOException( "Unexpected break sequence '" + next + "' " + pdfSource );
}
}
}
else
{
if( openBrace == '<' )
{
if( c != 0x0d && c != 0x0a )
{
retval.append( c );
}
}
else
{
retval.append( c );
}
}
}
if( openBrace == '<' )
{
StringBuffer hexBuffer = new StringBuffer( retval.getString() );
retval = new COSString();
//if odd number then the last hex digit is assumed to be 0
if( hexBuffer.length() % 2 == 1 )
{
hexBuffer.append( "0" );
}
for( int i=0; i<hexBuffer.length(); )
{
String hexChars = "" + hexBuffer.charAt( i++ ) + hexBuffer.charAt( i++ );
try
{
retval.append( Integer.parseInt( hexChars, 16 ) );
}
catch( NumberFormatException e )
{
throw new IOException( "Error: Expected hex number, actual='" + hexChars + "'" );
}