Created
July 18, 2011 19:36
-
-
Save cthom06/1090434 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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