Documentation ¶
Overview ¶
Package sexprs implements Ron Rivest's canonical S-expressions (c.f. http://people.csail.mit.edu/rivest/Sexp.txt or rivest-draft.txt in this package) in Go. I'm indebted to Inferno's sexprs(2), whose API I first accidentally, and then deliberately, mimicked. I've copied much of its style, only making it more Go-like.
Canonical S-expressions are a compact, easy-to-parse, ordered, hashable data representation ideal for cryptographic operations. They are simpler and more compact than either JSON or XML.
An S-expression is composed of lists and atoms. An atom is a string of bytes, with an optional display hint, also a byte string. A list can contain zero or more atoms or lists.
There are two representations of an S-expression: the canonical representation is a byte-oriented, packed representation, while the advanced representation is string-oriented and more traditional in appearance.
The S-expression ("foo" "bar" ["bin"]"baz quux") is canonically:
(3:foo3:bar[3:bin]8:quux)
Among the valid advanced representations are:
(foo 3:bar [bin]"baz quux")
and:
("foo" #626172# [3:bin]|YmF6IHF1dXg=|)
There is also a transport encoding (intended for use in 7-bit transport modes), delimited with {}:
{KDM6Zm9vMzpiYXJbMzpiaW5dODpiYXogcXV1eCk=}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Atom ¶
An Atom is a byte sequence, together with an optional display hint, also a byte sequence. The display hint could potentially be used to inform a user agent that a value should be interpreted as, e.g., a JPEG. One might use MIME types as display hints, e.g. text/plain"This is plain text" (although this particular case is somewhat unlikely, since most user agents are likely to default to plain text). Note that there are no semantics attached to the value; it could be a UTF-8 string, a little-endian integer, a big-endian integer or any other byte sequence.
func (Atom) Base64String ¶
func (Atom) Pack ¶
Pack returns the canonical form of an Atom: a decimal indicating its length in bytes, a colon, and then the bytes. If there is a display hint, it is prepended within square brackets. E.g. "foo" is packed as "3:foo" and "bar" with a display hint of "text/plain" is packed as "[10:text/plain]3:bar".
Example ¶
foo := Atom{Value: []byte("foo")} fmt.Println(string(foo.Pack())) bar := Atom{DisplayHint: []byte("text/plain"), Value: []byte("bar")} fmt.Println(string(bar.Pack()))
Output: 3:foo [10:text/plain]3:bar
func (Atom) String ¶
Example ¶
foo := Atom{Value: []byte("foo")} fmt.Println(foo.String()) foo.Value = []byte("bar baz") fmt.Println(foo.String()) foo.Value = []byte("bar\nbaz") fmt.Println(foo.String()) foo.Value = []byte{0, 1, 2, 3} fmt.Println(foo.String())
Output: foo "bar baz" "bar\nbaz" |AAECAw==|
type List ¶
type List []Sexp
A List is a slice of Lists and Atoms.
func (List) Base64String ¶
func (List) Pack ¶
Pack returns each component of List l within parentheses, e.g. "(foo)" would pack as "(3:foo)".
Example ¶
list := List{Atom{Value: []byte("foo")}, List{Atom{Value: []byte("bar baz"), DisplayHint: []byte("text/plain")}, Atom{DisplayHint: []byte{'\n'}}}} fmt.Println(string(list.Pack())) readList, _, err := Parse([]byte(list.String())) if err != nil { panic(err) } fmt.Println(readList.Equal(list))
Output: (3:foo([10:text/plain]7:bar baz[1: ]0:)) true
func (List) String ¶
Example ¶
list := List{Atom{Value: []byte("foo")}, List{Atom{Value: []byte("bar baz"), DisplayHint: []byte("text/plain")}, Atom{DisplayHint: []byte{1, 2, 3}}}} fmt.Println(list.String()) readList, _, err := Parse([]byte(list.String())) if err != nil { panic(err) } fmt.Println(readList.Equal(list))
Output: (foo ([text/plain]"bar baz" [|AQID|]"")) true
type Sexp ¶
type Sexp interface { // String returns an advanced representation of the object, with // no line breaks. String() string // Base64String returns a transport-encoded rendering of the // S-expression Base64String() string // Pack returns the canonical representation of the object. It // will always return the same sequence of bytes for the same // object. Pack() []byte // PackedLen returns the size in bytes of the canonical // representation. PackedLen() int // Equal will return true if its receiver and argument are // identical. Equal(b Sexp) bool // contains filtered or unexported methods }
Sexp is the interface implemented by both lists and atoms.