Skip to content

Instantly share code, notes, and snippets.

@cthom06
Created July 18, 2011 19:36
Show Gist options
  • Save cthom06/1090434 to your computer and use it in GitHub Desktop.
Save cthom06/1090434 to your computer and use it in GitHub Desktop.
package damn
import (
"os"
"bytes"
)
type PacketBody struct {
Args map[string]string
Body string
}
// A type to represent a dAmn packet
type Packet struct {
Cmd, Param string
PacketBody
}
func ParseBody(b []byte) (p PacketBody, e os.Error) {
p.Args = make(map[string]string)
for ; len(b) > 0 && b[0] != '\n'; b = b[1:] {
i, j := bytes.Index(b, []byte{'='}), bytes.Index(b, []byte{'\n'})
if i < 0 || j < 0 || i > j {
return p, os.NewError("Bad packet: malformed args")
}
p.Args[string(b[:i])] = string(b[i+1:j])
b = b[j:]
}
if len(b) == 0 {
return p, os.NewError("Bad packet: no newline after args")
}
p.Body = string(b[1:])
return
}
// I haven't really tested this thoroughly but I doubt it has errors
// It's written for efficiency more than readability
// It does not expect a null byte
func Parse(b []byte) (*Packet, os.Error) {
var p Packet
if len(b) == 0 {
return nil, os.NewError("Empty Packet")
}
i, j := bytes.Index(b, []byte{' '}), bytes.Index(b, []byte{'\n'})
if j < 0 {
return nil, os.NewError("Bad packet: missing newline")
}
if i > -1 && i < j {
p.Cmd = string(b[:i])
p.Param = string(b[i+1:j])
} else {
p.Cmd = string(b[:j])
}
b = b[j+1:]
if len(b) == 0 {
return &p, nil
}
var e os.Error
p.PacketBody, e = ParseBody(b)
return &p, e
}
// Converts a packet back to the wire format
// Does not include the null byte
func (p *Packet) Bytes() []byte {
b := new(bytes.Buffer)
if p.Param == "" {
b.WriteString(p.Cmd + "\n")
} else b.WriteString(p.Cmd + " " + p.Param + "\n")
if p.Args != nil {
for k, v := range p.Args {
b.WriteString(k + "=" + v + "\n")
}
}
if p.Args != nil || p.Body != "" {
b.WriteString("\n"+p.Body)
}
return b.Bytes()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment