183 lines
6.7 KiB
Go
183 lines
6.7 KiB
Go
|
package wireproto
|
||
|
|
||
|
import (
|
||
|
`encoding/xml`
|
||
|
|
||
|
`github.com/google/uuid`
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
Fields, commonly referred to in this library as "fv", "fvpair", etc. consist of both a name and a value.
|
||
|
|
||
|
This not intended to be a map conceptually so much as a "type" of data and the data itself, but it certainly can be represented as map-like.
|
||
|
*/
|
||
|
type (
|
||
|
// FieldName represents the name/identifier of a field.
|
||
|
FieldName []byte
|
||
|
// FieldValue is the value (data) of a specified field
|
||
|
FieldValue []byte
|
||
|
)
|
||
|
|
||
|
type common struct {
|
||
|
size uint32
|
||
|
}
|
||
|
|
||
|
type (
|
||
|
FVP interface {
|
||
|
Model
|
||
|
GetParent() (rec Record)
|
||
|
ToMap() (m map[string]interface{})
|
||
|
}
|
||
|
Record interface {
|
||
|
Model
|
||
|
GetParent() (rg RecordGroup)
|
||
|
ToMap() (m []map[string]interface{})
|
||
|
getFvps() (fvp []FVP)
|
||
|
}
|
||
|
RecordGroup interface {
|
||
|
Model
|
||
|
GetParent() (msg Message)
|
||
|
ToMap() (m [][]map[string]interface{})
|
||
|
getRecords() (records []Record)
|
||
|
}
|
||
|
Message interface {
|
||
|
Model
|
||
|
ToMap() (m [][][]map[string]interface{})
|
||
|
getRecordGroups() (recordGroups []RecordGroup)
|
||
|
}
|
||
|
Model interface {
|
||
|
Model() (out string)
|
||
|
ModelCustom(indent, sep string, level uint) (out string)
|
||
|
getIdx() (idx int)
|
||
|
}
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
Request contains a Request message as sent to a remote target. It conforms to Message.
|
||
|
|
||
|
Either end ("client" or "server") may send a request, but it should represent the beginning of a complete/new transaction (a Message).
|
||
|
*/
|
||
|
type Request struct {
|
||
|
XMLName xml.Name `xml:"request" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
/*
|
||
|
Checksum is a CRC32 (see specification) checksum of the message.
|
||
|
|
||
|
It is optional (but recommended) for requests.
|
||
|
*/
|
||
|
Checksum *uint32 `json:"cksum,omitempty" xml:"cksum,attr,omitempty" yaml:"Checksum,omitempty" toml:"Checksum,omitempty" validate:"omitempty"`
|
||
|
// ProtocolVersion specifies the specification version of this message.
|
||
|
ProtocolVersion uint32 `json:"proto_ver" xml:"protoVer,attr" yaml:"Protocol Version" toml:"ProtocolVersion" validate:"required"`
|
||
|
/*
|
||
|
RecordGroups contains grouped sets (RequestRecordGroup) of RequestRecord.
|
||
|
At least one is required.
|
||
|
|
||
|
Most implementations are likely to use only a single RequestRecordGroup in RecordGroups,
|
||
|
but multiple may be included. They are assumed to be seperate contexts/queries/commands/etc. if
|
||
|
multiple groups are included.
|
||
|
*/
|
||
|
RecordGroups []*RequestRecordGroup `json:"rg" xml:"recordGroups>recordGroup" yaml:"Record Groups" toml:"RecordGroups" validate:"required,dive"`
|
||
|
resp *ResponseRecord // only if part of a Response.
|
||
|
connId uuid.UUID
|
||
|
}
|
||
|
|
||
|
// RequestRecordGroup contains one or more related RequestRecord. It conforms to RecordGroup.
|
||
|
type RequestRecordGroup struct {
|
||
|
XMLName xml.Name `xml:"recordGroup" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
// Records contains the sets of one or more related RequestRecord.
|
||
|
Records []*RequestRecord `json:"rec" xml:"records>record" yaml:"Records" toml:"Records" validate:"required,dive"`
|
||
|
connId uuid.UUID
|
||
|
parent *Request
|
||
|
rgIdx int
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
RequestRecord contains a record of one or more related FieldValuePair. It conforms to Record.
|
||
|
|
||
|
It is designed such that a single RequestRecord is responded with a single ResponseRecord.
|
||
|
*/
|
||
|
type RequestRecord struct {
|
||
|
XMLName xml.Name `xml:"record" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
// Pairs contains one or more related FieldValuePair.
|
||
|
Pairs []*FieldValuePair `json:"fvp" xml:"fvPairs>fvPair" yaml:"Field/Value Pairs" toml:"FieldValuePairs" validate:"required,dive"`
|
||
|
connId uuid.UUID
|
||
|
parent *RequestRecordGroup
|
||
|
rgIdx int
|
||
|
rIdx int
|
||
|
}
|
||
|
|
||
|
// Response contains an entire response message to a Request. It conforms to Message.
|
||
|
type Response struct {
|
||
|
XMLName xml.Name `xml:"response" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
/*
|
||
|
Status is a short identifier of the status for the Request as executed.
|
||
|
It is the very first byte on the wire to allow the remote end to easily check whether an error has occurred.
|
||
|
(Detailed error messages should be contained in the RecordGroups.)
|
||
|
|
||
|
TODO: custom type, marshal/unmarshalers?
|
||
|
*/
|
||
|
Status uint8 `json:"status" xml:"status,attr" yaml:"Status" toml:"Status" validate:"required"`
|
||
|
/*
|
||
|
Checksum is a CRC32 (see specification) checksum of the message.
|
||
|
|
||
|
It is required for responses.
|
||
|
*/
|
||
|
Checksum uint32 `json:"cksum" xml:"cksum,attr" yaml:"Checksum" toml:"Checksum" validate:"required"`
|
||
|
// ProtocolVersion specifies the specification version of this message.
|
||
|
ProtocolVersion uint32 `json:"proto_ver" xml:"protoVer,attr" yaml:"Protocol Version" toml:"ProtocolVersion" validate:"required"`
|
||
|
/*
|
||
|
RecordGroups contains grouped sets (ResponseRecordGroup) of ResponseRecord.
|
||
|
At least one is required.
|
||
|
|
||
|
Most implementations are likely to use only a single ResponseRecordGroup in RecordGroups,
|
||
|
but multiple may be included. They are assumed to be seperate contexts/queries/commands/etc. if
|
||
|
multiple groups are included.
|
||
|
*/
|
||
|
RecordGroups []*ResponseRecordGroup `json:"rg" xml:"recordGroups>recordGroup" yaml:"Record Groups"`
|
||
|
}
|
||
|
|
||
|
// ResponseRecordGroup contains related ResponseRecord objects. It conforms to RecordGroup.
|
||
|
type ResponseRecordGroup struct {
|
||
|
XMLName xml.Name `xml:"recordGroup" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
// Records contains one or more related ResponseRecord.
|
||
|
Records []*ResponseRecord `json:"rec" xml:"records>record" yaml:"Records" toml:"Records" validate:"required,dive"`
|
||
|
parent *Response
|
||
|
rgIdx int
|
||
|
}
|
||
|
|
||
|
// ResponseRecord contains the response to a single RequestRecord. It conforms to Record.
|
||
|
type ResponseRecord struct {
|
||
|
XMLName xml.Name `xml:"record" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
Pairs []*FieldValuePair `json:"fvp" xml:"fvPairs>fvPair" yaml:"Field/Value Pairs" toml:"FieldValuePairs" validate:"required,dive"`
|
||
|
/*
|
||
|
OriginalRecord contains the associcated RequestRecord.
|
||
|
*/
|
||
|
OriginalRecord *RequestRecord `json:"orig_req" xml:"originalReq" yaml:"Original Request" toml:"OriginalRequest"`
|
||
|
parent *ResponseRecordGroup
|
||
|
rgIdx int
|
||
|
rIdx int
|
||
|
}
|
||
|
|
||
|
// FieldValuePair contains a single "key" (identifier) and value. It is found in both a RequestRecord and a ResponseRecord. It conforms to FVP.
|
||
|
type FieldValuePair struct {
|
||
|
XMLName xml.Name `xml:"fvPair" json:"-" yaml:"-" toml:"-" validate:"-"`
|
||
|
*common
|
||
|
// Name should be treated as a "type" or "identifier" for the data in Value.
|
||
|
Name FieldName `json:"name,omitempty" xml:"name,attr,omitempty" yaml:"Name,omitempty" toml:"Name,omitempty" validate:"omitempty"`
|
||
|
/*
|
||
|
Value containts arbitrary data.
|
||
|
Content, validation/verification, parsing, etc. of the data is left to downstream implementations and is out of spec for this protocol.
|
||
|
*/
|
||
|
Value FieldValue `json:"value,omitempty" xml:"value,chardata,omitempty" yaml:"Value,omitempty" toml:"Value,omitempty" validate:"omitempty"`
|
||
|
connId *uuid.UUID
|
||
|
parent Record
|
||
|
rgIdx int
|
||
|
rIdx int
|
||
|
fvpidx int
|
||
|
}
|