All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.io.types.General Maven / Gradle / Ivy

There is a newer version: 20151002
Show newest version
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2017 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * General.java
 * ---------------
 */

package org.jpedal.io.types;

import static org.jpedal.io.ObjectDecoder.debugFastCode;
import static org.jpedal.io.ObjectDecoder.padding;
import org.jpedal.io.PdfFileReader;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.LogWriter;


/**
 *
 * @author markee
 */
public class General {
    
    public static int readGeneral(final PdfObject pdfObject, int i, final byte[] raw, final int PDFkeyInt, final PdfFileReader objectReader){
       
        //if we only need top level do not read whole tree
        final boolean ignoreRecursion=pdfObject.ignoreRecursion();
        
        if(debugFastCode) {
            System.out.println(padding + "general case " + i);
        }

        //see if number or ref
        int jj=i;
        int j=i+1;
        byte[] data=raw;
        int typeFound=0;
        boolean isNumber=true, isRef=false, isString=false;

        String objRef=pdfObject.getObjectRefAsString();

        while(true){

            if(data[j]=='R' && !isString){

                isRef=true;
                final int end=j;
                j=i;
                i=end;

                final int ref;
                final int generation;

                //allow for [ref] at top level (may be followed by gap
                while (data[j] == 91 || data[j] == 32 || data[j] == 13 || data[j] == 10) {
                    j++;
                }
                final int[] values = StreamReaderUtils.readRefFromStream(data, j);
                // get object ref

                final int refStart=j;
                ref = values[0];
                generation = values[1];
                j = values[2];

                if (data[j] != 82)  //we are expecting R to end ref
                {
                    throw new RuntimeException("ref=" + ref + " gen=" + ref + " 1. Unexpected value " + data[j] + " in file - please send to IDRsolutions for analysis char=" + (char) data[j]);
                }

                objRef =new String(data,refStart,1+j-refStart);

                //read the Dictionary data
                //boolean setting=debugFastCode;
                data = objectReader.readObjectAsByteArray(pdfObject, objectReader.isCompressed(ref, generation), ref, 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=raw.length;
                    break;
                }

                //find first valid char to see if String
                int firstChar=0;

                //some data actually starts << and not 10 0 obj so allow for this
                if(data!=null && data.length>2 && data[0]=='<' && data[1]=='<'){
                    //check for already at <<

                }else{
                    firstChar = findFirstChar(data, firstChar);
                }

                //stop string with R failing in loop
                isString=data[firstChar]=='(';

                jj=skipStartObj(data);

                j=jj;

                if(debugFastCode) {
                    System.out.println(j + " >>" + new String(data) + "<' || data[j]=='/'){
                typeFound=1;
                break;
            }else if(data[j]==32 || data[j]==10 || data[j]==13 || data[j]==9){
            }else if((data[j]>='0' && data[j] <='9')|| data[j]=='.'){ //assume and disprove
            }else{
                isNumber=false;
            }
            if(data[j]!='['){
                j++;
            }
            if(j==data.length) {
                break;
            }
        }

        jj=StreamReaderUtils.skipSpaces(data, jj);

        if(typeFound==4){//direct ref done above
        }else if(data[jj]=='/' && getKeyCount(jj, data)==0){
            jj = Name.setNameStringValue(pdfObject, jj, data, PDFkeyInt, objectReader);
        }else if(data[jj]=='('){
            jj = TextStream.readTextStream(pdfObject, jj, data, PDFkeyInt,objectReader);
        }else if(data[jj]=='['){

            final ArrayDecoder objDecoder=ArrayFactory.getDecoder(objectReader, jj,PdfDictionary.VALUE_IS_STRING_ARRAY, data);
            jj=objDecoder.readArray(pdfObject, PDFkeyInt);
               
        }else if(typeFound==0){           
            try{
            jj = Dictionary.readDictionaryFromRefOrDirect(pdfObject, objRef,jj , data, PDFkeyInt,objectReader);

            }catch(final Exception e){
                LogWriter.writeLog("Exception: " + e.getMessage());
            }
        }else if(isNumber){
            jj= NumberValue.setNumberValue(pdfObject, jj, data, PDFkeyInt,objectReader);
        }else if(typeFound==1){
            jj = Name.setNameStringValue(pdfObject, jj, data, PDFkeyInt, objectReader);
        }else if(debugFastCode) {
            System.out.println(padding + "Not read");
        }

        if(!isRef) {
            i = jj;
        }

        return i;
    }

    private static int findFirstChar(final byte[] newData, int firstChar) {
        
        final int newLength=newData.length-3;
        for(int aa=3;aa47 && newData[aa]<58){//number
            }else if(newData[aa]=='o' || newData[aa]=='b' || newData[aa]=='j' || newData[aa]=='R' || newData[aa]==32 || newData[aa]==10 || newData[aa]==13){ //allowed char
            }else{ //not expected so reset and quit
                aa= newLength;
                firstChar=0;
            }
        }
        return firstChar;
    }

    private static int skipStartObj(final byte[] data) {
        
        int jj=3;
        
        if(data.length<=3){
            jj=0;
        }else{
            while(true){
                if(data[jj-2]=='o' && data[jj-1]=='b' && data[jj]=='j') {
                    break;
                }
                
                jj++;
                
                if(jj==data.length){
                    jj=0;
                    break;
                }
            }
        }
        if(data[jj]!='[' && data[jj]!='(' && data[jj]!='<') //do not roll on if text string
        {
            jj++;
        }
        
        jj=StreamReaderUtils.skipSpaces(data, jj);
        
        return jj;
    }

    private static int getKeyCount(final int jj, final byte[] data) {
        //check if name by counting /
        int count=0;
        for(int aa=jj+1;aa




© 2015 - 2024 Weber Informatics LLC | Privacy Policy