Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support array of content streams and parse them as a single stream #36

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 77 additions & 61 deletions ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,77 +49,93 @@ func newDict() Value {
// in PDF files, such as cmap files that describe the mapping from font code
// points to Unicode code points.
//
// There is no support for executable blocks, among other limitations.
// A stream can also be represented by an array of streams that has to be handled as a single stream
// In the case of a simple stream read only once, otherwise get the length of the stream to handle it properly
//
// There is no support for executable blocks, among other limitations.
func Interpret(strm Value, do func(stk *Stack, op string)) {
rd := strm.Reader()
b := newBuffer(rd, 0)
b.allowEOF = true
b.allowObjptr = false
b.allowStream = false
var stk Stack
var dicts []dict
Reading:
for {
tok := b.readToken()
if tok == io.EOF {
break
s := strm
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe there is a more GO like way of doing this without repeating code.
I'm open for suggestions.

strmlen := 1
if strm.Kind() == Array {
strmlen = strm.Len()
}

for i := 0; i < strmlen; i++ {
if strm.Kind() == Array {
s = strm.Index(i)
}
if kw, ok := tok.(keyword); ok {
switch kw {
case "null", "[", "]", "<<", ">>":

rd := s.Reader()

b := newBuffer(rd, 0)
b.allowEOF = true
b.allowObjptr = false
b.allowStream = false

Reading:
for {
tok := b.readToken()
if tok == io.EOF {
break
default:
for i := len(dicts) - 1; i >= 0; i-- {
if v, ok := dicts[i][name(kw)]; ok {
stk.Push(Value{nil, objptr{}, v})
continue Reading
}
if kw, ok := tok.(keyword); ok {
switch kw {
case "null", "[", "]", "<<", ">>":
break
default:
for i := len(dicts) - 1; i >= 0; i-- {
if v, ok := dicts[i][name(kw)]; ok {
stk.Push(Value{nil, objptr{}, v})
continue Reading
}
}
do(&stk, string(kw))
continue
case "dict":
stk.Pop()
stk.Push(Value{nil, objptr{}, make(dict)})
continue
case "currentdict":
if len(dicts) == 0 {
panic("no current dictionary")
}
stk.Push(Value{nil, objptr{}, dicts[len(dicts)-1]})
continue
case "begin":
d := stk.Pop()
if d.Kind() != Dict {
panic("cannot begin non-dict")
}
dicts = append(dicts, d.data.(dict))
continue
case "end":
if len(dicts) <= 0 {
panic("mismatched begin/end")
}
dicts = dicts[:len(dicts)-1]
continue
case "def":
if len(dicts) <= 0 {
panic("def without open dict")
}
val := stk.Pop()
key, ok := stk.Pop().data.(name)
if !ok {
panic("def of non-name")
}
dicts[len(dicts)-1][key] = val.data
continue
case "pop":
stk.Pop()
continue
}
do(&stk, string(kw))
continue
case "dict":
stk.Pop()
stk.Push(Value{nil, objptr{}, make(dict)})
continue
case "currentdict":
if len(dicts) == 0 {
panic("no current dictionary")
}
stk.Push(Value{nil, objptr{}, dicts[len(dicts)-1]})
continue
case "begin":
d := stk.Pop()
if d.Kind() != Dict {
panic("cannot begin non-dict")
}
dicts = append(dicts, d.data.(dict))
continue
case "end":
if len(dicts) <= 0 {
panic("mismatched begin/end")
}
dicts = dicts[:len(dicts)-1]
continue
case "def":
if len(dicts) <= 0 {
panic("def without open dict")
}
val := stk.Pop()
key, ok := stk.Pop().data.(name)
if !ok {
panic("def of non-name")
}
dicts[len(dicts)-1][key] = val.data
continue
case "pop":
stk.Pop()
continue
}
b.unreadToken(tok)
obj := b.readObject()
stk.Push(Value{nil, objptr{}, obj})
}
b.unreadToken(tok)
obj := b.readObject()
stk.Push(Value{nil, objptr{}, obj})
}
}

Expand Down