github.com/signintech/pdft@v0.5.0/pdf_obj_data.go (about)

     1  package pdft
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rc4"
     6  	"errors"
     7  
     8  	gopdf "github.com/signintech/pdft/minigopdf"
     9  )
    10  
    11  // PDFObjData byte of obj
    12  type PDFObjData struct {
    13  	objID int
    14  	data  []byte
    15  }
    16  
    17  func (p *PDFObjData) parse(raw *[]byte, stratoffset int) error {
    18  
    19  	tmp := (*raw)[stratoffset:]
    20  	endObjIndex := regexpEndObj.FindAllIndex(tmp, 1)
    21  	if len(endObjIndex) <= 0 {
    22  		return errors.New("bad endobj")
    23  	}
    24  	endObjOffsetBefore := endObjIndex[0][0] + stratoffset
    25  
    26  	tmp = (*raw)[stratoffset:endObjOffsetBefore]
    27  	startObjIndex := regexpStartObj.FindAllIndex(tmp, 1)
    28  	if len(startObjIndex) <= 0 {
    29  		return errors.New("bad start obj")
    30  	}
    31  
    32  	startObjOffsetAfter := startObjIndex[0][1]
    33  	startObjOffset := startObjIndex[0][0]
    34  	startObjLine := tmp[startObjOffset:startObjOffsetAfter]
    35  	data := tmp[startObjOffsetAfter:]
    36  	objID, err := objIDFromStartObjLine(string(startObjLine))
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	p.objID = objID
    42  	p.data = data
    43  
    44  	return nil
    45  }
    46  
    47  // ReadProperties read all obj Properties
    48  func (p *PDFObjData) readProperties() (*PDFObjPropertiesData, error) {
    49  	var props PDFObjPropertiesData
    50  	err := readProperties(&p.data, &props)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	return &props, nil
    55  }
    56  
    57  func (p *PDFObjData) setProperties(props *PDFObjPropertiesData) {
    58  	var data bytes.Buffer
    59  	data.WriteString("<<\n")
    60  	for _, prop := range *props {
    61  		data.WriteString("/" + prop.key + " " + prop.rawVal)
    62  	}
    63  	data.WriteString(">>\n")
    64  	p.data = data.Bytes()
    65  }
    66  
    67  func (p *PDFObjData) encrypt(protection *gopdf.PDFProtection) error {
    68  
    69  	stream := []byte("stream")
    70  	endstream := []byte("endstream")
    71  	start := bytes.Index(p.data, stream)
    72  	if start != -1 {
    73  		end := bytes.LastIndex(p.data, endstream)
    74  
    75  		var head, body bytes.Buffer
    76  		head.Write(p.data[0:start])
    77  		body.Write(p.data[start+len(stream) : end])
    78  		tmp := bytes.Trim(body.Bytes(), "\r\n")
    79  		tmp = bytes.Trim(tmp, "\n")
    80  		bodyRc4, err := rc4Cip(protection.Objectkey(p.objID), tmp)
    81  		if err != nil {
    82  			return err
    83  		}
    84  
    85  		var data bytes.Buffer
    86  		data.Write(head.Bytes())
    87  		data.Write(stream)
    88  		data.WriteString("\n")
    89  		data.Write(bodyRc4)
    90  		data.WriteString("\n")
    91  		data.Write(endstream)
    92  		p.data = data.Bytes()
    93  	}
    94  	return nil
    95  }
    96  
    97  func rc4Cip(key []byte, src []byte) ([]byte, error) {
    98  	cip, err := rc4.NewCipher(key)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	dest := make([]byte, len(src))
   103  	cip.XORKeyStream(dest, src)
   104  	return dest, nil
   105  }