Documentation ¶
Overview ¶
Package wire9 provides a boilerplate protocol generator. Wire9 parses wire definitions from a go package or source file. It generates structs and methods according to the given definition.
To use wire9, run the standalone command line program on a go package directory containing wire definitions.
go install github.com/as/wire9/cmd cd $GOPATH/src/github.com/as/wire9/ wire9 -f example/0/ex_wire9.go example/0/
Wire Definitions:
A wire definition begins with a slash comment and wire9 prefix. There is no space between the slashes and prefix. The prefix is followed by a struct name and a variadic list of fields.
//wire9 struct⁰ field⁰[width,type,endian] ... fieldⁿ[width,type,endian]
A field becomes the name of a struct field. Next, a [bracket-enclosed], comma-seperated list of field options: width, type, and endian.
field⁰[width,type,endian]
Width is a field's binary width. Its value is an integer constant, a previously-defined numeric field, or empty.
Types specify a field's type. This affects the type value in the final struct field, numeric and fixed types may have empty widths.
Endian specifies byte-order (LE or BE), which stand for Little-Endian and Big-Endian. Little-Endian is the default value.
The width and type are interpreted one of three ways depending on other values in the field options:
Width is a numeric literal A. Type is empty: If width is 1, 2, 4, or 8, type is byte, uint16, uint32, and uint64, respectively. Otherwise type is []byte.
B. Type is identifier: The type represents a fixed width struct, numeric value, or slice type. The width must match the fixed types binary width or be the number of expected slice elements.
Width is identifier A. Type is empty: Type is implicitly []byte. The width represents the number of bytes to expect in the slice.
B. Type is identifier: The type represents a slice type. The width is the number of expected elements in the slice.
Width is empty A. Type is a fixed-width struct, number, or implements the Wire interface.
Examples:
//wire9 Ex1A Time[8] IP[4] Port[2] n[1] //wire9 Ex1B Time[8,uint64] IP[4,uint32] Port[2,uint16] n[1,byte]
//wire9 Ex2A n[1] URL[n] //wire9 Ex2B n[1] URL[n,[]byte]
//wire9 Ex3A p[,image.Point] size[,int64] reply[,Ex2A]
//wire9 Git index[4,,BE] ...
Example:
The wire definition for a two-byte length-prefixed string:
//wire9 Bstr n[2] data[n]
Generates the following struct and (fully-implemented) methods:
type Bstr struct { n uint16 data []byte } func (z *Bstr) ReadBinary(r io.Reader) (err error) func (z Bstr) WriteBinary(w io.Writer) (err error)
This example defines four common length-prefixed strings
//wire9 Pstr n[1] data[n] //wire9 Bstr n[2] data[n] //wire9 Dstr n[4] data[n] //wire9 Qstr n[8] data[n]
The following construction builds on the last example. The value of the four 4-byte integers set the expected number of slice elements for each corresponding length-prefixed string.
//wire9 BurstRX np[4] nb[4] nd[4] nq[4] SP[np,[]Pstr] SB[nb,[]Bstr] SD[nd,[]Dstr] SQ[nq,[]Qstr]
Trivia:
The goal of this package is to save time when implementing custom protocols, such as Microsoft RDP. The package's original purpose was to take the Plan 9 draw(3) manual page and generate Go for parsing the messages written to the data file.
Index ¶
- Variables
- func Access(a ast.Expr) string
- func Array(f ast.Expr) (ok bool)
- func ByteArray(f ast.Expr) (ok bool)
- func ByteSlice(f ast.Expr) (ok bool)
- func Clean(src []byte) []byte
- func Coherent(f ast.Expr) (ok bool)
- func Custom(f ast.Expr) bool
- func CustomSlice(f ast.Expr) (ok bool)
- func Endian(m ast.Node) (string, error)
- func FromFiles(files []string, dups DupMap, dofmt bool) ([]byte, error)
- func Literal(f ast.Expr) (ok bool)
- func NewCleaner() *cleaner
- func NewParser(fset *token.FileSet, line string, dups DupMap) (p *parser, err error)
- func Numeric(f ast.Expr) (ok bool)
- func Selector(f ast.Expr) string
- func Slice(f ast.Expr) (ok bool)
- func SliceOf(f ast.Expr) ast.Expr
- func String(f ast.Expr) (ok bool)
- func TypeFromWidth(w ast.Expr) (ast.Expr, error)
- func TypeString(f interface{}) string
- func WasSet(s string) bool
- func WidthOf(ts *ast.TypeSpec, f *ast.Field) (s string, err error)
- func WireFile(file interface{}) bool
- type Dup
- type DupMap
- type File
- type Info
- type Mode
- type Package
- type Source
- type TypeInfo
- type WidthFlag
Constants ¶
This section is empty.
Variables ¶
var Flags = map[string]bool{}
var Nesting nesting
Nesting tracks the level of expression nesting during code generation
Functions ¶
func Clean ¶
Clean examines scopes in input src and removes unnecessary braces. It returns the clean copy. The src is assumed to be valid, error-free Go source.
func CustomSlice ¶
CustomSlice returns true if f is not a builtin type, and is a slice
func Endian ¶
Endian returns the endianness of a field. TODO: return an error if the field can't have an endian value.
func FromFiles ¶
FromFiles produces wire9 structures and functions by reading wire definitions from files. Dofmt controls gofmt operation.
func NewCleaner ¶
func NewCleaner() *cleaner
func Selector ¶
Selector returns the syntax for selecting an element of f. If f is not an array or slice, the field is returned as is.
func TypeFromWidth ¶
TypeFromWidth determines the type by the width
func TypeString ¶
func TypeString(f interface{}) string
TypeString returns the named field's type as a string
Types ¶
type Dup ¶
type Dup struct {
// contains filtered or unexported fields
}
Dup marks the type of duplicate found in the original source code. A that a wire definition would likely conflict with.
type DupMap ¶
Dup marks the type of duplicate found in the original source code. A that a wire definition would likely conflict with.
type Mode ¶
type Mode uint
A Mode value is a set of flags (or 0). They control the amount of source code parsed and other optional parser functionality.
const ( PackageClauseOnly Mode = 1 << iota // stop parsing after package clause ImportsOnly // stop parsing after import declarations ParseComments // parse comments and add them to AST Trace // print a trace of parsed productions DeclarationErrors // report declaration errors SpuriousErrors // same as AllErrors, for backward-compatibility AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines) )
Parser flags
type Package ¶
type Package struct { Info *types.Info Path string Files []string ASTFiles []*ast.File Data []byte Fset *token.FileSet Pkg *types.Package DupMap DupMap }
Package is a box for AST, wire9 and package type information.
func FromPackage ¶
FromPackage produces wire9 structures and functions via from a Package opened with OpenPackage.
func OpenPackage ¶
OpenPackage opens the package at path. It returns a partialy-initialized Package containing initialized ASTFiles, Fset, and Files.
type Source ¶
type Source struct { Files []*File Structs []*ast.TypeSpec DupMap // contains filtered or unexported fields }
Source files. TODO: Revise
func ParseFiles ¶
ParseFiles parses files listed in fs and extracts all sys comments. It returns source files and their list of wire9 expressions
func (*Source) Eval ¶
Eval parses and processes a line of input as a wire definition. The definition must start with a double slash and follow the format given in the package description comment.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
example
|
|
0
MACHINE GENERATED BY 'go generate' COMMAND TO EDIT A TYPE OR METHOD, COPY IT TO ANOTHER FILE IN THE PACKAGE
|
MACHINE GENERATED BY 'go generate' COMMAND TO EDIT A TYPE OR METHOD, COPY IT TO ANOTHER FILE IN THE PACKAGE |
1
MACHINE GENERATED BY 'go generate' COMMAND TO EDIT A TYPE OR METHOD, COPY IT TO ANOTHER FILE IN THE PACKAGE
|
MACHINE GENERATED BY 'go generate' COMMAND TO EDIT A TYPE OR METHOD, COPY IT TO ANOTHER FILE IN THE PACKAGE |
Package varint provides the varint type V. V knows how to write and read its binary encoded representation from a reader or writer
|
Package varint provides the varint type V. V knows how to write and read its binary encoded representation from a reader or writer |