mirror of
https://github.com/safing/portbase
synced 2025-09-01 10:09:50 +00:00
Add new functions to add and get data as a container
This commit is contained in:
parent
a747272674
commit
27c55f5d35
2 changed files with 64 additions and 2 deletions
|
@ -48,12 +48,28 @@ func (c *Container) AppendNumber(n uint64) {
|
|||
c.compartments = append(c.compartments, varint.Pack64(n))
|
||||
}
|
||||
|
||||
// AppendInt appends an int (varint encoded).
|
||||
func (c *Container) AppendInt(n int) {
|
||||
c.compartments = append(c.compartments, varint.Pack64(uint64(n)))
|
||||
}
|
||||
|
||||
// AppendAsBlock appends the length of the data and the data itself. Data will NOT be copied.
|
||||
func (c *Container) AppendAsBlock(data []byte) {
|
||||
c.AppendNumber(uint64(len(data)))
|
||||
c.Append(data)
|
||||
}
|
||||
|
||||
// AppendContainer appends another Container. Data will NOT be copied.
|
||||
func (c *Container) AppendContainer(data *Container) {
|
||||
c.compartments = append(c.compartments, data.compartments...)
|
||||
}
|
||||
|
||||
// AppendContainerAsBlock appends another Container (length and data). Data will NOT be copied.
|
||||
func (c *Container) AppendContainerAsBlock(data *Container) {
|
||||
c.AppendNumber(uint64(data.Length()))
|
||||
c.compartments = append(c.compartments, data.compartments...)
|
||||
}
|
||||
|
||||
// Length returns the full length of all bytes held by the container.
|
||||
func (c *Container) Length() (length int) {
|
||||
for i := c.offset; i < len(c.compartments); i++ {
|
||||
|
@ -92,6 +108,16 @@ func (c *Container) Get(n int) ([]byte, error) {
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
// GetAsContainer returns the given amount of bytes in a new container. Data will NOT be copied and IS consumed.
|
||||
func (c *Container) GetAsContainer(n int) (*Container, error) {
|
||||
new := c.gatherAsContainer(n)
|
||||
if new == nil {
|
||||
return nil, errors.New("container: not enough data to return")
|
||||
}
|
||||
c.skip(n)
|
||||
return new, nil
|
||||
}
|
||||
|
||||
// GetMax returns as much as possible, but the given amount of bytes at maximum. Data MAY be copied and IS consumed.
|
||||
func (c *Container) GetMax(n int) []byte {
|
||||
buf := c.gather(n)
|
||||
|
@ -214,6 +240,23 @@ func (c *Container) gather(n int) []byte {
|
|||
return slice[:n]
|
||||
}
|
||||
|
||||
func (c *Container) gatherAsContainer(n int) (new *Container) {
|
||||
new = &Container{}
|
||||
for i := c.offset; i < len(c.compartments); i++ {
|
||||
if n >= len(c.compartments[i]) {
|
||||
new.compartments = append(new.compartments, c.compartments[i])
|
||||
n -= len(c.compartments[i])
|
||||
} else {
|
||||
new.compartments = append(new.compartments, c.compartments[i][:n])
|
||||
n = 0
|
||||
}
|
||||
}
|
||||
if n > 0 {
|
||||
return nil
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
func (c *Container) skip(n int) {
|
||||
for i := c.offset; i < len(c.compartments); i++ {
|
||||
if len(c.compartments[i]) <= n {
|
||||
|
@ -233,7 +276,7 @@ func (c *Container) skip(n int) {
|
|||
c.checkOffset()
|
||||
}
|
||||
|
||||
// GetNextBlock returns the next block of data defined by a varint (note: data will MAY be copied and IS consumed).
|
||||
// GetNextBlock returns the next block of data defined by a varint. Data MAY be copied and IS consumed.
|
||||
func (c *Container) GetNextBlock() ([]byte, error) {
|
||||
blockSize, err := c.GetNextN64()
|
||||
if err != nil {
|
||||
|
@ -242,6 +285,15 @@ func (c *Container) GetNextBlock() ([]byte, error) {
|
|||
return c.Get(int(blockSize))
|
||||
}
|
||||
|
||||
// GetNextBlockAsContainer returns the next block of data as a Container defined by a varint. Data will NOT be copied and IS consumed.
|
||||
func (c *Container) GetNextBlockAsContainer() (*Container, error) {
|
||||
blockSize, err := c.GetNextN64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.GetAsContainer(int(blockSize))
|
||||
}
|
||||
|
||||
// GetNextN8 parses and returns a varint of type uint8.
|
||||
func (c *Container) GetNextN8() (uint8, error) {
|
||||
buf := c.gather(2)
|
||||
|
|
|
@ -66,7 +66,12 @@ func TestContainerDataHandling(t *testing.T) {
|
|||
}
|
||||
c8.clean()
|
||||
|
||||
compareMany(t, testData, c1.CompileData(), c2.CompileData(), c3.CompileData(), d4, d5, c6.CompileData(), c7.CompileData(), c8.CompileData())
|
||||
c9 := c8.gatherAsContainer(len(testData))
|
||||
|
||||
c10 := c9.gatherAsContainer(len(testData) - 1)
|
||||
c10.Append(testData[len(testData)-1:])
|
||||
|
||||
compareMany(t, testData, c1.CompileData(), c2.CompileData(), c3.CompileData(), d4, d5, c6.CompileData(), c7.CompileData(), c8.CompileData(), c9.CompileData(), c10.CompileData())
|
||||
}
|
||||
|
||||
func compareMany(t *testing.T, reference []byte, other ...[]byte) {
|
||||
|
@ -120,6 +125,11 @@ func TestDataFetching(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Error("should fail")
|
||||
}
|
||||
|
||||
_, err = c1.GetAsContainer(1000)
|
||||
if err == nil {
|
||||
t.Error("should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlocks(t *testing.T) {
|
||||
|
|
Loading…
Add table
Reference in a new issue