Commit 5271f58d authored by Kamil Kisiel's avatar Kamil Kisiel

More opcodes

parent 19945465
...@@ -73,23 +73,26 @@ const ( ...@@ -73,23 +73,26 @@ const (
LONG4 = "\x8b" // push really big long LONG4 = "\x8b" // push really big long
) )
// special marker
type mark struct{}
// None is a representation of Python's None
type None struct{}
// Decoder is a decoder for pickle streams
type Decoder struct { type Decoder struct {
r *bufio.Reader r *bufio.Reader
stack []interface{} stack []interface{}
memo map[string]interface{} memo map[string]interface{}
} }
// NewDecoder constructs a new Decoder which will decode the pickle stream in r
func NewDecoder(r io.Reader) Decoder { func NewDecoder(r io.Reader) Decoder {
reader := bufio.NewReader(r) reader := bufio.NewReader(r)
return Decoder{reader, make([]interface{}, 0), make(map[string]interface{})} return Decoder{reader, make([]interface{}, 0), make(map[string]interface{})}
} }
// special marker // Decode decodes the pickele stream and returns the result or an error
type mark struct{}
// representation of None
type None struct{}
func (d Decoder) Decode() (interface{}, error) { func (d Decoder) Decode() (interface{}, error) {
for { for {
key, err := d.r.ReadByte() key, err := d.r.ReadByte()
...@@ -193,12 +196,12 @@ func (d Decoder) Decode() (interface{}, error) { ...@@ -193,12 +196,12 @@ func (d Decoder) Decode() (interface{}, error) {
return d.pop(), nil return d.pop(), nil
} }
// Push a marker on to the stack // Push a marker
func (d *Decoder) mark() { func (d *Decoder) mark() {
d.append(mark{}) d.append(mark{})
} }
// Return the position of the marker // Return the position of the topmost marker
func (d *Decoder) marker() int { func (d *Decoder) marker() int {
m := mark{} m := mark{}
var k int var k int
...@@ -210,26 +213,29 @@ func (d *Decoder) marker() int { ...@@ -210,26 +213,29 @@ func (d *Decoder) marker() int {
panic("no marker in stack") panic("no marker in stack")
} }
// Append a new value to the decoder stack // Append a new value
func (d *Decoder) append(v interface{}) { func (d *Decoder) append(v interface{}) {
d.stack = append(d.stack, v) d.stack = append(d.stack, v)
} }
// Pop a value from the decoder stack // Pop a value
func (d *Decoder) pop() interface{} { func (d *Decoder) pop() interface{} {
v := d.stack[len(d.stack)-1] v := d.stack[len(d.stack)-1]
d.stack = d.stack[:len(d.stack)-1] d.stack = d.stack[:len(d.stack)-1]
return v return v
} }
// Discard the stack through to the topmost marker
func (d *Decoder) popMark() { func (d *Decoder) popMark() {
} }
// Duplicate the top stack item
func (d *Decoder) dup() { func (d *Decoder) dup() {
d.stack = append(d.stack, d.stack[len(d.stack)-1]) d.stack = append(d.stack, d.stack[len(d.stack)-1])
} }
// Push a float
func (d *Decoder) loadFloat() error { func (d *Decoder) loadFloat() error {
line, _, err := d.r.ReadLine() line, _, err := d.r.ReadLine()
if err != nil { if err != nil {
...@@ -243,6 +249,7 @@ func (d *Decoder) loadFloat() error { ...@@ -243,6 +249,7 @@ func (d *Decoder) loadFloat() error {
return nil return nil
} }
// Push an int
func (d *Decoder) loadInt() error { func (d *Decoder) loadInt() error {
line, _, err := d.r.ReadLine() line, _, err := d.r.ReadLine()
if err != nil { if err != nil {
...@@ -268,12 +275,15 @@ func (d *Decoder) loadInt() error { ...@@ -268,12 +275,15 @@ func (d *Decoder) loadInt() error {
return nil return nil
} }
// Push a four-byte signed int
func (d *Decoder) loadBinInt() { func (d *Decoder) loadBinInt() {
} }
// Push a 1-byte unsigned int
func (d *Decoder) loadBinInt1() { func (d *Decoder) loadBinInt1() {
} }
// Push a long
func (d *Decoder) loadLong() error { func (d *Decoder) loadLong() error {
line, _, err := d.r.ReadLine() line, _, err := d.r.ReadLine()
if err != nil { if err != nil {
...@@ -285,13 +295,21 @@ func (d *Decoder) loadLong() error { ...@@ -285,13 +295,21 @@ func (d *Decoder) loadLong() error {
return nil return nil
} }
// Push a 2-byte unsigned int
func (d *Decoder) loadBinInt2() { func (d *Decoder) loadBinInt2() {
} }
// Push None
func (d *Decoder) loadNone() {
d.append(None{})
}
// Push a persistent object id
func (d *Decoder) loadPersid() { func (d *Decoder) loadPersid() {
} }
// Push a persistent object id from items on the stack
func (d *Decoder) loadBinPersid() { func (d *Decoder) loadBinPersid() {
} }
...@@ -304,6 +322,7 @@ func decodeStringEscape(b []byte) string { ...@@ -304,6 +322,7 @@ func decodeStringEscape(b []byte) string {
return string(b) return string(b)
} }
// Push a string
func (d *Decoder) loadString() error { func (d *Decoder) loadString() error {
line, _, err := d.r.ReadLine() line, _, err := d.r.ReadLine()
if err != nil { if err != nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment