v1.0.0
Initial release.
This commit is contained in:
251
funcs_responserecordgroup.go
Normal file
251
funcs_responserecordgroup.go
Normal file
@@ -0,0 +1,251 @@
|
||||
package wireproto
|
||||
|
||||
import (
|
||||
`bytes`
|
||||
`fmt`
|
||||
`io`
|
||||
`strings`
|
||||
)
|
||||
|
||||
// GetParent returns this RecordGroup's Message.
|
||||
func (r *ResponseRecordGroup) GetParent() (msg Message) {
|
||||
|
||||
msg = r.parent
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalBinary renders a ResponseRecordGroup into a byte-packed format.
|
||||
func (r *ResponseRecordGroup) MarshalBinary() (data []byte, err error) {
|
||||
|
||||
var b []byte
|
||||
var rgSize int
|
||||
var buf *bytes.Buffer = new(bytes.Buffer)
|
||||
|
||||
_ = r.Size()
|
||||
|
||||
for _, i := range r.Records {
|
||||
rgSize += i.Size()
|
||||
}
|
||||
|
||||
// Count
|
||||
if _, err = buf.Write(PackInt(len(r.Records))); err != nil {
|
||||
return
|
||||
}
|
||||
// Size
|
||||
if _, err = buf.Write(PackInt(rgSize)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, i := range r.Records {
|
||||
if b, err = i.MarshalBinary(); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = buf.Write(b); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
data = buf.Bytes()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Model returns an indented string representation of the model.
|
||||
func (r *ResponseRecordGroup) Model() (out string) {
|
||||
|
||||
out = r.ModelCustom(IndentChars, SeparatorChars, indentRG)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ModelCustom is like Model with user-defined formatting.
|
||||
func (r *ResponseRecordGroup) ModelCustom(indent, sep string, level uint) (out string) {
|
||||
|
||||
var sb strings.Builder
|
||||
var size int
|
||||
|
||||
for _, rec := range r.Records {
|
||||
size += rec.Size()
|
||||
}
|
||||
|
||||
// Count
|
||||
sb.WriteString(strings.Repeat(indent, int(level)))
|
||||
sb.WriteString(fmt.Sprintf("%x", PackUint32(uint32(len(r.Records)))))
|
||||
sb.WriteString(sep)
|
||||
sb.WriteString(fmt.Sprintf("// Record Count (%d)\n", len(r.Records)))
|
||||
// Size
|
||||
sb.WriteString(strings.Repeat(indent, int(level)))
|
||||
sb.WriteString(fmt.Sprintf("%x", PackUint32(uint32(size))))
|
||||
sb.WriteString(sep)
|
||||
sb.WriteString(fmt.Sprintf("// Record Group Size (%d)\n", size))
|
||||
|
||||
// VALUES
|
||||
for idx, rec := range r.Records {
|
||||
sb.WriteString(strings.Repeat(indent, int(level)))
|
||||
sb.WriteString(
|
||||
fmt.Sprintf(
|
||||
"// Record Group %d, Record %d (%d bytes)\n",
|
||||
r.rgIdx+1, idx+1, rec.Size(),
|
||||
),
|
||||
)
|
||||
sb.WriteString(rec.ModelCustom(indent, sep, level+1))
|
||||
}
|
||||
|
||||
out = sb.String()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve associates children with parents.
|
||||
func (r *ResponseRecordGroup) Resolve() {
|
||||
for idx, i := range r.Records {
|
||||
i.parent = r
|
||||
i.rgIdx = r.rgIdx
|
||||
i.rIdx = idx
|
||||
i.Resolve()
|
||||
}
|
||||
}
|
||||
|
||||
// Size returns the ResponseRecordGroup's calculated size (in bytes) and updates the size field if 0.
|
||||
func (r *ResponseRecordGroup) Size() (size int) {
|
||||
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Count and Size uint32s
|
||||
size += PackedNumSize * 2
|
||||
|
||||
for _, p := range r.Records {
|
||||
size += p.Size()
|
||||
}
|
||||
|
||||
if r.common == nil {
|
||||
r.common = new(common)
|
||||
}
|
||||
|
||||
r.common.size = uint32(size)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ToMap returns a slice of slice of FVP maps for this RecordGroup.
|
||||
func (r *ResponseRecordGroup) ToMap() (m [][]map[string]interface{}) {
|
||||
|
||||
m = make([][]map[string]interface{}, len(r.Records))
|
||||
for idx, rec := range r.Records {
|
||||
m[idx] = rec.ToMap()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalBinary populates a ResponseRecordGroup from packed bytes.
|
||||
func (r *ResponseRecordGroup) UnmarshalBinary(data []byte) (err error) {
|
||||
|
||||
if data == nil || len(data) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var b []byte
|
||||
var cnt, size int
|
||||
var recSize int
|
||||
var recBuf *bytes.Buffer
|
||||
var buf *bytes.Reader = bytes.NewReader(data)
|
||||
|
||||
if r == nil {
|
||||
*r = ResponseRecordGroup{}
|
||||
}
|
||||
if r.common == nil {
|
||||
r.common = new(common)
|
||||
}
|
||||
r.size = 0
|
||||
|
||||
// The record count.
|
||||
b = make([]byte, PackedNumSize)
|
||||
if _, err = buf.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
cnt = UnpackInt(b)
|
||||
|
||||
// The record group size.
|
||||
b = make([]byte, PackedNumSize)
|
||||
if _, err = buf.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
size = UnpackInt(b)
|
||||
|
||||
b = make([]byte, size)
|
||||
if _, err = buf.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get a new buf for the actual records.
|
||||
buf = bytes.NewReader(b)
|
||||
|
||||
r.Records = make([]*ResponseRecord, cnt)
|
||||
|
||||
for idx := 0; idx < cnt; idx++ {
|
||||
recBuf = new(bytes.Buffer)
|
||||
|
||||
// We skip over the KVP count; that's handled in the record Unmarshaler.
|
||||
// We *do*, however, need to save it to the recBuf.
|
||||
if _, err = io.CopyN(recBuf, buf, int64(PackedNumSize)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Size of the actual record
|
||||
b = make([]byte, PackedNumSize)
|
||||
if _, err = buf.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = recBuf.Write(b); err != nil {
|
||||
return
|
||||
}
|
||||
recSize = UnpackInt(b)
|
||||
|
||||
// And add the size of the response record.
|
||||
b = make([]byte, PackedNumSize)
|
||||
if _, err = buf.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = recBuf.Write(b); err != nil {
|
||||
return
|
||||
}
|
||||
recSize += UnpackInt(b)
|
||||
|
||||
// Then the record (and original record).
|
||||
if _, err = io.CopyN(recBuf, buf, int64(recSize)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.Records[idx] = new(ResponseRecord)
|
||||
if err = r.Records[idx].UnmarshalBinary(recBuf.Bytes()); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_ = r.Size()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getIdx returns the RecordGroup index in the parent Message.
|
||||
func (r *ResponseRecordGroup) getIdx() (idx int) {
|
||||
|
||||
idx = r.rgIdx
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getRecords returns the Records in this RecordGroup.
|
||||
func (r *ResponseRecordGroup) getRecords() (records []Record) {
|
||||
|
||||
records = make([]Record, len(r.Records))
|
||||
for idx, rec := range r.Records {
|
||||
records[idx] = rec
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user