package wireproto import ( `bytes` `fmt` `io` `strings` `github.com/google/uuid` ) // ConnId returns a copy of the connection ID. func (r *RequestRecordGroup) ConnId() (conn uuid.UUID) { conn = r.connId return } // GetParent returns this RecordGroup's Message. func (r *RequestRecordGroup) GetParent() (msg Message) { msg = r.parent return } // MarshalBinary renders a RequestRecordGroup into a byte-packed format. func (r *RequestRecordGroup) 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 *RequestRecordGroup) Model() (out string) { out = r.ModelCustom(IndentChars, SeparatorChars, indentRG) return } // ModelCustom is like Model with user-defined formatting. func (r *RequestRecordGroup) ModelCustom(indent, sep string, level uint) (out string) { var size int var sb strings.Builder 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 *RequestRecordGroup) Resolve() { for idx, i := range r.Records { i.parent = r i.rgIdx = r.rgIdx i.rIdx = idx i.Resolve() } } // Size returns the RequestRecordGroup's calculated size (in bytes) and updates the size field if 0. func (r *RequestRecordGroup) 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.size == 0 { r.common = new(common) } r.common.size = uint32(size) return } // ToMap returns a slice of slice of FVP maps for this RecordGroup. func (r *RequestRecordGroup) 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 RequestRecordGroup from packed bytes. func (r *RequestRecordGroup) 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 = RequestRecordGroup{} } 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([]*RequestRecord, 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) if _, err = io.CopyN(recBuf, buf, int64(recSize)); err != nil { return } r.Records[idx] = new(RequestRecord) 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 *RequestRecordGroup) getIdx() (idx int) { idx = r.rgIdx return } // getRecords returns the Records in this RecordGroup. func (r *RequestRecordGroup) getRecords() (records []Record) { records = make([]Record, len(r.Records)) for idx, rec := range r.Records { records[idx] = rec } return }