Everton
Everton

Reputation: 13865

Generic Go function to save bytes into a fixed-size byte array buffer

How do I to write a generic Go function to push bytes into a byte array?

I suppose appending to a slice is not a perfect fit, because the array should not grow. However the function should handle any array size. I am considering to slice the array just to make the function accept any array size. See my sketch below.

Is there a cleaner way?

Play: http://play.golang.org/p/Gii9-JM33E

func push(buf []byte, size int, b byte) (int, error) {
    max := len(buf)

    if max < 1 {
        return size, fmt.Errorf("buffer underflow: max=%d char=%d", max, b)
    }

    if size >= max {
        return size, fmt.Errorf("buffer overflow: size=%d max=%d char=%d", size, max, b)
    }

    buf[size] = b

    return size + 1, nil
}

Usage:

buf := [3]byte{}
size := 0
var err error
size, err = push(buf[:], size, 'a')

Upvotes: 0

Views: 1813

Answers (2)

Paul Hankin
Paul Hankin

Reputation: 58409

You almost certainly want to use a slice instead of an array. A slice has three things: an underlying backing array, a capacity, and a length. The capacity "cap" tells you the size of the underlying backing array.

So, you can use append after checking that len(s) < cap(s) to avoid any reallocation. Or if you want to make a function, perhaps something like this:

func pushByte(s []byte, b byte) ([]byte, error) {
    if len(s) == cap(s) {
        return s, errors.New("capacity reached")
    }
    return append(s, b), nil
}

You'd use it something like this:

s := make([]byte, 0, 10)
var err error
if s, err = pushByte(s, 10); err != nil {
    ... handle error
}

Upvotes: 2

Mr_Pink
Mr_Pink

Reputation: 109475

The size of an array is part if its type.

If there's a set of sizes you know you are going to accept, you could take a buf interface{} with a type switch on the sizes you want. I would assume you know the array sizes, since they must be constant at compile time.

Other than that you would need to use reflection to actually find the array size, and store elements within the array.

It's very infrequent you need to use an array instead of a slice. You may want to reconsider why you have to pass arrays of varying sizes around.

Upvotes: 1

Related Questions