static byte[] getBytes(final long start, final int count, final RandomAccessBuffer pdf_datafile) { final byte[] buffer = new byte[count]; try { pdf_datafile.seek(start); pdf_datafile.read(buffer); // get next chars } catch (final IOException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } return buffer; }
/** read table of values */ public int readXRefs( int current, final byte[] Bytes, final int endTable, int i, final long eof, final RandomAccessBuffer pdf_datafile) { char flag; int id, tokenCount, generation, lineLen, startLine, endLine; boolean skipNext = false; boolean isFirstValue = true; final int[] breaks = new int[5]; final int[] starts = new int[5]; // loop to read all references while (i < endTable) { // exit end at trailer startLine = i; endLine = -1; /** read line locations */ // move to start of value ignoring spaces or returns while (Bytes[i] != 10 && Bytes[i] != 13) { // scan for % if ((endLine == -1) && (Bytes[i] == 37)) { endLine = i - 1; } i++; } // set end if no comment if (endLine == -1) { endLine = i - 1; } // strip any spaces while (Bytes[startLine] == 32) { startLine++; } // strip any spaces while (Bytes[endLine] == 32) { endLine--; } i++; /** decode the line */ tokenCount = 0; lineLen = endLine - startLine + 1; if (lineLen > 0) { // decide if line is a section header or value // first count tokens int lastChar = 1, currentChar; for (int j = 1; j < lineLen; j++) { currentChar = Bytes[startLine + j]; if ((currentChar == 32) && (lastChar != 32)) { breaks[tokenCount] = j; tokenCount++; } else if ((currentChar != 32) && (lastChar == 32)) { starts[tokenCount] = j; } lastChar = currentChar; } // update numbers so loops work breaks[tokenCount] = lineLen; tokenCount++; if (tokenCount == 1) { // fix for first 2 values on separate lines if (skipNext) { skipNext = false; } else { current = NumberUtils.parseInt(startLine, startLine + breaks[0], Bytes); skipNext = true; } } else if (tokenCount == 2) { current = NumberUtils.parseInt(startLine, startLine + breaks[0], Bytes); } else { id = NumberUtils.parseInt(startLine, startLine + breaks[0], Bytes); generation = NumberUtils.parseInt(startLine + starts[1], startLine + breaks[1], Bytes); flag = (char) Bytes[startLine + starts[2]]; if ((flag == 'n')) { // only add objects in use /** assume not valid and test to see if valid */ boolean isValid = false; // get bytes int bufSize = 20; // adjust buffer if less than 1024 bytes left in file if (id + bufSize > eof) { bufSize = (int) (eof - id); } if (bufSize > 0) { /** get bytes into buffer */ final byte[] buffer = getBytes(id, bufSize, pdf_datafile); // look for space o b j for (int ii = 4; ii < bufSize; ii++) { if ((buffer[ii - 3] == 32 || buffer[ii - 3] == 10) && (buffer[ii - 2] == 111) && (buffer[ii - 1] == 98) && (buffer[ii] == 106)) { isValid = true; ii = bufSize; } } // check number if (isValid && isFirstValue) { isFirstValue = false; if (buffer[0] == 48 && buffer[1] != 48 && current == 1) { current = 0; } else if (buffer[0] == 49 && buffer[1] == 32) { current = 1; } } if (isValid) { storeObjectOffset(current, id, generation, false, false); xref.addElement(id); } else if (LogWriter.isRunningFromIDE) { LogWriter.writeLog(current + " " + id + " is bum reference"); } } current++; // update our pointer } else if (flag == 'f') { current++; // update our pointer } } } } return current; }