go_wireproto/funcs_responserecordgroup.go

252 lines
5.0 KiB
Go
Raw Normal View History

2024-07-09 23:40:20 -04:00
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
}