-3

I would like to create a buffer which will contain information like nickname and password. Let's say I have created empty buffer, which is

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

By then I would like to fill it up with data, like buffer << nickname(string) << password(string), so in result I'm getting

08 75 73 65 72 6e 61 6d 65 08 70 61 73 73 77 6f 72 64

which is len.nickname actual_nickname len.password password

Now, after I have created such buffer I would like to parse it to variables. That would look like buffer >> nickname(string) >> password(string)

I made something once in c++ which was using operators, but I am not sure how to do so in Golang.

These buffers would be used as packets body in my networking app. I don't want to use structs, but kind of above.

I hope I explained my issue properly. I also do not want to use splitters like : to get these into array table.

Thank you.

  • p.s. not sure why people downvotes this question, since this issue does not seem to be easy as it seems. – sadlyconfused Jan 14 '18 at 20:50
  • 1
    You want to write arbitrary bytes into a buffer and be able to parse it back, but you don't want separators. Then you'll have to store a length before the actual data. Better yet, use a common encoding (json, protobuf, gob, etc...). And please show what you're tried, we won't just write the code for you. Maybe try [binary](https://golang.org/pkg/encoding/binary/). – Marc Jan 14 '18 at 20:50
  • Hi Marc, thanks for the anwser. That's what I was able to do in C++ with operators, but since I can't define them in Golang I was wondering if there is other way than using structs or protobuf/json. – sadlyconfused Jan 14 '18 at 20:53
  • Take a look at the binary package mentioned above. It gives you convenient methods to read/write fixed-sized numbers, and has lots of examples. You were asking why the downvotes? Probably because you didn't do any research. – Marc Jan 14 '18 at 20:57
  • Would you please show the c++ code? I am quite curious at how do you manage to store byte without separators and length of data. – leaf bebop Jan 15 '18 at 05:01
  • @sadlyconfused don't take the downvotes personally; the golang community on this website tends to aggressively downvote questions and answers, regardless of their validity, helpfulness, or general usefulness. – maerics Jan 15 '18 at 19:47
  • @leafbebop I have used offsets calculation by variable type. – sadlyconfused Jan 15 '18 at 20:27

2 Answers2

-1

Try using a bytes.Buffer, to which you can write as necessary, including using fmt.Fprintf if necessary. When everything is written to the buffer, you can get the bytes back out.

buf := bytes.NewBuffer(nil)
fmt.Fprint(buf, nickname)
fmt.Fprint(buf, password)
fmt.Print(buf.Bytes())

Working example here: https://play.golang.org/p/bRL6-N-3qH_n

Adrian
  • 42,911
  • 6
  • 107
  • 99
  • This does not answer the OP's question which asks about a way to get the data back. – Marc Jan 15 '18 at 15:22
-1

You can do fixed-size encoding using the encoding/binary package, including choosing endianness.

The example below writes two strings preceded by the length stored as a uint32 in network byte order. This would be appropriate to send over the wire. You can use uint16, or even uint8 if you're certain this will be enough to represent the string lengths.

Warning: I'm ignoring all errors in this sample code. Please do not do that in yours.

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
)

func main() {
    user := "foouser"
    password := "barpassword"

    // Write "len(user) user len(password) password".
    // Lengths are unsigned 32 bit ints in network byte order.
    var buf bytes.Buffer
    binary.Write(&buf, binary.BigEndian, (uint32)(len(user)))
    buf.WriteString(user)
    binary.Write(&buf, binary.BigEndian, (uint32)(len(password)))
    buf.WriteString(password)

    var output []byte = buf.Bytes()
    fmt.Printf("% x\n", output)

    // Now read it back (we could use the buffer,
    // but let's use Reader for clarity)
    input := bytes.NewReader(output)
    var uLen, pLen uint32

    binary.Read(input, binary.BigEndian, &uLen)
    uBytes := make([]byte, uLen)
    input.Read(uBytes)
    newUser := string(uBytes)

    binary.Read(input, binary.BigEndian, &pLen)
    pBytes := make([]byte, pLen)
    input.Read(pBytes)
    newPassword := string(pBytes)

    fmt.Printf("User: %q, Password: %q", newUser, newPassword)
}

This outputs the byte array and the strings extracted from it:

00 00 00 07 66 6f 6f 75 73 65 72 00 00 00 0b 62 61 72 70 61 73 73 77 6f 72 64
User: "foouser", Password: "barpassword"

playground link

Marc
  • 19,394
  • 6
  • 47
  • 51