func proceed(i *TypeOneI, rdr fancy.Reader) { for !i.Done { t, _ := ps.Token(rdr) // fmt.Printf("Stack: %v\n", util.StringArray(i.St.Dump())); // fmt.Printf("--- %s\n", t); if len(t) < 1 { break } b, _ := rdr.ReadByte() if b > 32 { rdr.UnreadByte() } if len(t) == 0 { break } if d, ok := find(i, "/"+string(t)); ok { if d[0] == '{' { proceed(i, fancy.SliceReader(d[1:len(d)-1])) } else { i.St.Push(d) } } else if f, ok := Ops[string(t)]; ok { f(i) } else { i.St.Push(t) } } return }
func skipComment(f fancy.Reader) { for { c, err := f.ReadByte() if err != nil || c == 13 || c == 10 { break } } }
// xrefStart() queries the start of the xref-table in a PDF file. func xrefStart(f fancy.Reader) int { s := int(f.Size()) pdf := make([]byte, min(s, 1024)) f.ReadAt(pdf, int64(max(0, s-1024))) ps := xref.FindAll(pdf, -1) if ps == nil { return -1 } return num(xref.FindSubmatch(ps[len(ps)-1])[2]) }
func skipSpaces(f fancy.Reader) byte { for { c, err := f.ReadByte() if err != nil { break } if c > 32 { return c } } return 0 }
func skipString(f fancy.Reader) { for depth := 1; depth > 0; { c, err := f.ReadByte() if err != nil { break } switch c { case '(': depth++ case ')': depth-- case '\\': f.ReadByte() } } }
func skipToDelim(f fancy.Reader) byte { for { c, err := f.ReadByte() if err != nil { break } if c < 33 { return c } switch c { case '<', '>', '(', ')', '[', ']', '/', '%', '{', '}': return c } } return 255 }
func eexec(rdr fancy.Reader) []byte { fpos, _ := rdr.Seek(0, 1) b := fancy.ReadAll(rdr) cnt := 0 pos := 0 k := 0 for ; cnt < 256 && k < len(b); k++ { switch b[k] { case 32, 10, 13, 9: case '0': cnt++ default: cnt = 0 pos = k + 1 } } b = b[0:pos] rdr.Seek(fpos+int64(k), 0) if hex.IsHex(b[0]) { b = hex.Decode(string(b)) } return T1Decrypt(EEXEC_KEY, b)[4:] }
// xrefSkip() queries the start of the trailer for a (partial) xref-table. func xrefSkip(f fancy.Reader, xref int) int { f.Seek(int64(xref), 0) t, p := ps.Token(f) if string(t) != "xref" { return -1 } for { t, p = ps.Token(f) if t[0] < '0' || t[0] > '9' { f.Seek(p, 0) break } t, _ = ps.Token(f) ps.SkipLE(f) f.Seek(int64(num(t)*20), 1) } r, _ := f.Seek(0, 1) return int(r) }
func refToken(f fancy.Reader) ([]byte, int64) { tok, p := ps.Token(f) if len(tok) > 0 && tok[0] >= '0' && tok[0] <= '9' { ps.Token(f) r, q := ps.Token(f) if string(r) == "R" { f.Seek(p, 0) tok = f.Slice(int(1 + q - p)) } else { f.Seek(p+int64(len(tok)), 0) } } return tok, p }
func SkipLE(f fancy.Reader) { for { c, err := f.ReadByte() if err != nil { return } if c > 32 { f.UnreadByte() return } if c == 13 { c, err = f.ReadByte() if err == nil && c != 10 { f.UnreadByte() } return } if c == 10 { return } } }
// xrefRead() reads the xref table(s) of a PDF file. This is not recursive // in favour of not to have to keep track of already used starting points // for xrefs. func xrefRead(f fancy.Reader, p int) map[int]int { var back [MAX_PDF_UPDATES]int b := 0 s := _Bytes for ok := true; ok; { back[b] = p b++ p = xrefSkip(f, p) f.Seek(int64(p), 0) s, _ = ps.Token(f) if string(s) != "trailer" { return nil } s, _ = ps.Token(f) s, ok = Dictionary(s)["/Prev"] p = num(s) } r := make(map[int]int) for b != 0 { b-- f.Seek(int64(back[b]), 0) ps.Token(f) // skip "xref" for { m := tupel(f, 2) if string(m[0]) == "trailer" { break } ps.SkipLE(f) o := num(m[0]) dat := f.Slice(num(m[1]) * 20) for i := 0; i < len(dat); i += 20 { if dat[i+17] != 'n' { delete(r, o) } else { r[o] = num(dat[i : i+10]) } o++ } } } return r }
func Token(f fancy.Reader) ([]byte, int64) { again: c := skipSpaces(f) if c == 0 { return []byte{}, -1 } p := fpos(f) - 1 switch c { case '%': skipComment(f) goto again case '<', '[', '{': skipComposite(f) case '(': skipString(f) default: if skipToDelim(f) != 255 { f.UnreadByte() } } n := int(fpos(f) - p) f.Seek(p, 0) return f.Slice(n), p }
func fpos(f fancy.Reader) int64 { r, _ := f.Seek(0, 1) return r }