1
votes

My requirement is to convert byte stream into my structure type, which has predefined data lengths. Below sample, I could convert byte into "Test" object and read data(func buffertoStruct demonstrates that),

but the problem is

I need to cast into data types based on the string or int lengths. which is not happening now.

I have lots of different structures like "type Test" and each struct will have a good amount of data variables. So copying bytes into struct Test variables based on sizes one by one doesn't work.

WHAT I am thinking about solution:

I am thinking of keeping all struct variables names, sizes, type in a data structure, and slice byte stream in loop based on that

type datadetails struct {
 name string //ex: uniqnum, guid etc
 size int  //9 ,32
 datatype string //int, string, etc int for uniqnum, string for guid
}

Question: Need a better solution than that? here is my sample, so far.

package main

import (
     "bytes"
    "encoding/gob"
    "log"
    "fmt"
)

type Test struct{
    uniqnum int64 //9 char in byte stream ex: 708008123 (int) 
    guid string //exactly is 32 -chars
    flag byte //string 1 char   
    printnum  string //6 char

}

func convertintorec(data []byte) {
    fmt.Println(data)
    //convert byte data into Test record
}
func buffertoStruct(gbuffer []byte,pobj *Test ) {
        tmp :=bytes.NewBuffer(gbuffer)
        dec := gob.NewDecoder(tmp)
        err := dec.Decode(pobj)
        if err != nil {
           log.Fatal("decode error:", err)
        }
}

func main() {
    bdata := []byte("9885455612guidstartshere12345678901234567F")
    convertintorec(bdata)
        
}
1

1 Answers

0
votes

This should get you halfway there:

var ErrTooShort = errors.New("too short")

func convertintorec(data []byte) (t *Test, err error) {

    t = &Test{}

    if len(data) < 9 {
        err = ErrTooShort
        return
    }

    uniqnum := string(data[:9])
    t.uniqnum, err = strconv.ParseInt(uniqnum, 10, 64)
    if err != nil {
        err = fmt.Errorf("bad uniqnum %q: %w", uniqnum, err)
        return
    }

    data = data[9:]

    if len(data) < 32 {
        err = fmt.Errorf("gid %w", ErrTooShort)
        return
    }

    t.guid = string(data[:32])

    // t.flag / t.printnum is left to implement...

    return
}

https://play.golang.org/p/ZPzWC2IYjj1