func (p *binParser) unread() {
	if p.last > 0 {
		p.n--
		p.r.UnreadByte()
	}
}
unread puts the last character readed back into the stream.
(unread is used in rfunction.go, not in this file)
package ogdl
import (
	"bufio"
	"bytes"
	"io"
	"io/ioutil"
)
type binParser struct {
	r    *bufio.Reader
	last int
	n int
}
func newBytesBinParser(b []byte) *binParser {
	p := &binParser{bufio.NewReader(bytes.NewReader(b)), 0, 0}
	if p.r == nil {
		return nil
	}
	return p
}
func newFileBinParser(file string) *binParser {
	b, err := ioutil.ReadFile(file)
	if err != nil || len(b) == 0 {
		return nil
	}
	return newBytesBinParser(b)
}
func newBinParser(r io.Reader) *binParser {
	return &binParser{bufio.NewReader(r), 0, 0}
}
func FromBinary(b []byte) *Graph {
	p := newBytesBinParser(b)
	return p.parse()
}
func FromBinaryReader(r io.Reader) *Graph {
	p := newBinParser(r)
	return p.parse()
}
func FromBinaryFile(file string) *Graph {
	p := newFileBinParser(file)
	return p.parse()
}
func (g *Graph) Binary() []byte {
	if g == nil {
		return nil
	}
	buf := make([]byte, 3)
	buf[0] = 1
	buf[1] = 'G'
	buf[2] = 0
	for _, node := range g.Out {
		buf = node.bin(1, buf)
	}
	buf = append(buf, 0)
	return buf
}
func (g *Graph) bin(level int, buf []byte) []byte {
	b := _bytes(g.This)
	if len(b) != 0 {
		buf = append(buf, newVarInt(level)...)
		buf = append(buf, b...)
		buf = append(buf, 0)
		level++
	}
	for _, node := range g.Out {
		buf = node.bin(level, buf)
	}
	return buf
}
func (p *binParser) parse() *Graph {
	if p == nil || !p.header() {
		return nil
	}
	ev := &SimpleEventHandler{}
	for {
		lev, bin, b := p.line(true)
		if lev == 0 {
			break
		}
		if bin {
			ev.AddBytesAt(b, lev-1)
		} else {
			ev.AddAt(string(b), lev-1)
		}
	}
	return ev.Tree()
}
func newVarInt(i int) []byte {
	if i < 0 {
		return nil
	}
	if i < 0x80 {
		b := make([]byte, 1)
		b[0] = byte(i)
		return b
	}
	if i < 0x4000 {
		b := make([]byte, 2)
		b[0] = byte(i>>8 | 0x80)
		b[1] = byte(i & 0xff)
		return b
	}
	if i < 0x200000 {
		b := make([]byte, 3)
		b[0] = byte(i>>16 | 0xc0)
		b[1] = byte(i >> 8 & 0xff)
		b[2] = byte(i & 0xff)
		return b
	}
	if i < 0x10000000 {
		b := make([]byte, 4)
		b[0] = byte(i>>24 | 0xe0)
		b[1] = byte(i>>16 | 0xff)
		b[2] = byte(i >> 8 & 0xff)
		b[3] = byte(i & 0xff)
		return b
	}
	return nil
}
func (p *binParser) header() bool {
	if p.read() != 1 {
		return false
	}
	if p.read() != 'G' {
		return false
	}
	if p.read() != 0 {
		return false
	}
	return true
}
func (p *binParser) varInt() int {
	b0 := p.read()
	if b0 < 0x80 {
		return b0
	}
	if b0 < 0xc0 {
		b1 := p.read()
		return (b0&0x3f)<<8 | b1
	}
	if b0 < 0xe0 {
		b1 := p.read()
		b2 := p.read()
		return ((b0 & 0x1f) << 16) | (b1 << 8) | b2
	}
	if b0 < 0xf0 {
		b1 := p.read()
		b2 := p.read()
		b3 := p.read()
		return ((b0 & 0x0f) << 24) | (b1 << 16) | (b2 << 8) | b3
	}
	return -1
}
func (p *binParser) line(write bool) (int, bool, []byte) {
	level := p.varInt()
	if level < 1 {
		return 0, false, nil
	}
	buf := bytes.Buffer{}
	n := p.read()
	if n == 1 {
		for {
			n = p.varInt()
			if n < 0 {
				break
			}
			for ; n != 0; n-- {
				c := p.read()
				if c < 0 {
					return level, true, buf.Bytes()
				}
				if write {
					buf.WriteByte(byte(c))
				}
			}
		}
		return level, true, buf.Bytes()
	}
	if write {
		buf.WriteByte(byte(n))
	}
	for {
		c := p.read()
		if c == 0 {
			return level, false, buf.Bytes()
		}
		if write {
			buf.WriteByte(byte(c))
		}
	}
}
func (p *binParser) read() int {
	i, err := p.r.ReadByte()
	c := int(i)
	if err == io.EOF {
		c = -1
	} else {
		p.n++
	}
	p.last = c
	return c
}