public static int setNameTreeValue( final PdfObject pdfObject, int i, final byte[] raw, final int length, final boolean ignoreRecursion, final int PDFkeyInt, final PdfFileReader objectReader) { boolean isRef = false; // move to start while (raw[i] != '[') { // can be number as well if (raw[i] == '(') { // allow for W (7) isRef = false; break; } // allow for number as in refer 9 0 R if (raw[i] >= '0' && raw[i] <= '9') { isRef = true; break; } i++; } // allow for direct or indirect byte[] data = raw; int start = i, j = i; int count = 0; // read ref data and slot in if (isRef) { // number final int[] values = StreamReaderUtils.readRefFromStream(raw, i); i = values[2]; final int generation = values[1]; final int number = values[0]; if (raw[i] != 82) // we are expecting R to end ref { throw new RuntimeException( "3. Unexpected value in file " + raw[i] + " - please send to IDRsolutions for analysis"); } if (!ignoreRecursion) { // read the Dictionary data data = objectReader.readObjectAsByteArray( pdfObject, objectReader.isCompressed(number, generation), number, generation); // allow for data in Linear object not yet loaded if (data == null) { pdfObject.setFullyResolved(false); if (debugFastCode) { System.out.println(padding + "Data not yet loaded"); } i = length; return i; } // lose obj at start j = 3; while (data[j - 1] != 106 && data[j - 2] != 98 && data[j - 3] != 111 && data[j - 3] != '<') { j++; } j = StreamReaderUtils.skipSpaces(data, j); // reset pointer start = j; } } // move to end while (j < data.length) { if (data[j] == '[' || data[j] == '(') { count++; } else if (data[j] == ']' || data[j] == ')') { count--; } if (count == 0) { break; } j++; } if (!ignoreRecursion) { final int stringLength = j - start + 1; byte[] newString = new byte[stringLength]; System.arraycopy(data, start, newString, 0, stringLength); if (pdfObject.getObjectType() != PdfDictionary.Encrypt) { final DecryptionFactory decryption = objectReader.getDecryptionObject(); if (decryption != null) { try { newString = decryption.decrypt( newString, pdfObject.getObjectRefAsString(), false, null, false, false); } catch (final PdfSecurityException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } } pdfObject.setTextStreamValue(PDFkeyInt, newString); if (debugFastCode) { System.out.println(padding + "name=" + new String(newString) + " set in " + pdfObject); } } // roll on if (!isRef) { i = j; } return i; }
public static int setNameStringValue( final PdfObject pdfObject, int i, final byte[] raw, final boolean isMap, final Object PDFkey, final int PDFkeyInt, final PdfFileReader objectReader) { byte[] stringBytes; // move cursor to end of last command if needed while (raw[i] != 10 && raw[i] != 13 && raw[i] != 32 && raw[i] != 47 && raw[i] != '(' && raw[i] != '<') { i++; } i = StreamReaderUtils.skipSpaces(raw, i); // work out if direct (ie /String or read ref 27 0 R int j2 = i; byte[] arrayData = raw; boolean isIndirect = raw[i] != 47 && raw[i] != 40 && raw[i] != 60; // Some /NAME values start ( final boolean startsWithBrace = raw[i] == 40; // delete // @speed - lose this code once Filters done properly /* * just check its not /Filter [/FlateDecode ] or [] or [ /ASCII85Decode /FlateDecode ] * by checking next valid char not / */ boolean isInsideArray = false; if (isIndirect) { int aa = i + 1; aa = StreamReaderUtils.skipSpaces(raw, aa); if (raw[aa] == 47 || raw[aa] == ']') { isIndirect = false; i = aa + 1; isInsideArray = true; } } if (isIndirect) { // its in another object so we need to fetch final int[] values = StreamReaderUtils.readRefFromStream(raw, i); final int ref = values[0]; final int generation = values[1]; i = values[2]; if (raw[i] != 82) { // we are expecting R to end ref throw new RuntimeException( padding + "2. Unexpected value in file - please send to IDRsolutions for analysis"); } // read the Dictionary data arrayData = objectReader.readObjectAsByteArray( pdfObject, objectReader.isCompressed(ref, generation), ref, generation); // allow for data in Linear object not yet loaded if (arrayData == null) { pdfObject.setFullyResolved(false); if (debugFastCode) { System.out.println(padding + "Data not yet loaded"); } return raw.length; } // lose obj at start and roll onto / if (arrayData[0] == 47) { j2 = 0; } else { j2 = 3; while (arrayData[j2] != 47) { j2++; } } } // lose / j2++; // allow for no value with /Intent//Filter if (arrayData[j2] == 47) { return j2 - 1; } int end = j2 + 1; if (isInsideArray) { // values inside [] // move cursor to start of text j2 = StreamReaderUtils.skipSpacesOrOtherCharacter(arrayData, j2, 47); int slashes = 0; // count chars byte lastChar = 0; while (true) { if (arrayData[end] == ']') { break; } if (arrayData[end] == 47 && (lastChar == 32 || lastChar == 10 || lastChar == 13)) // count the / if gap before { slashes++; } lastChar = arrayData[end]; end++; if (end == arrayData.length) { break; } } // set value and ensure space gap final int charCount = end - slashes; int ptr = 0; stringBytes = new byte[charCount - j2]; byte nextChar, previous = 0; for (int ii = j2; ii < charCount; ii++) { nextChar = arrayData[ii]; if (nextChar == 47) { if (previous != 32 && previous != 10 && previous != 13) { stringBytes[ptr] = 32; ptr++; } } else { stringBytes[ptr] = nextChar; ptr++; } previous = nextChar; } } else { // its in data stream directly or (string) // count chars while (true) { if (startsWithBrace) { if (arrayData[end] == ')' && !ObjectUtils.isEscaped(arrayData, end)) { break; } } else if (arrayData[end] == 32 || arrayData[end] == 10 || arrayData[end] == 13 || arrayData[end] == 47 || arrayData[end] == 62) { break; } end++; if (end == arrayData.length) { break; } } // set value final int charCount = end - j2; stringBytes = new byte[charCount]; System.arraycopy(arrayData, j2, stringBytes, 0, charCount); } if (isMap) { pdfObject.setName(PDFkey, StringUtils.getTextString(stringBytes, false)); } else { pdfObject.setName(PDFkeyInt, stringBytes); } if (debugFastCode) { System.out.println( padding + "String set as =" + new String(stringBytes) + "< written to " + pdfObject); } // put cursor in correct place (already there if ref) if (!isIndirect) { i = end - 1; } return i; }