How to copy from slice to array with seeking onto slice












2















I'm writing a library to deal with a binary format.



I have a struct with array vars, that I would like to keep for documentation purposes.



I need also to seek and tell from the input slice of bytes.



Some pseudocode:



type foo struct {
boo [5]byte
coo [3]byte
}

func main() {

// input is a byte full of datas, read from a file

var bar foo

// Here i need something that writes 5 bytes to bar.foo from input
bar.foo = somefunc(input, numberOfFoo) // ???
// I need also tell() and seek()
input.seek(n)

}


How can I do that with a single function?










share|improve this question





























    2















    I'm writing a library to deal with a binary format.



    I have a struct with array vars, that I would like to keep for documentation purposes.



    I need also to seek and tell from the input slice of bytes.



    Some pseudocode:



    type foo struct {
    boo [5]byte
    coo [3]byte
    }

    func main() {

    // input is a byte full of datas, read from a file

    var bar foo

    // Here i need something that writes 5 bytes to bar.foo from input
    bar.foo = somefunc(input, numberOfFoo) // ???
    // I need also tell() and seek()
    input.seek(n)

    }


    How can I do that with a single function?










    share|improve this question



























      2












      2








      2


      1






      I'm writing a library to deal with a binary format.



      I have a struct with array vars, that I would like to keep for documentation purposes.



      I need also to seek and tell from the input slice of bytes.



      Some pseudocode:



      type foo struct {
      boo [5]byte
      coo [3]byte
      }

      func main() {

      // input is a byte full of datas, read from a file

      var bar foo

      // Here i need something that writes 5 bytes to bar.foo from input
      bar.foo = somefunc(input, numberOfFoo) // ???
      // I need also tell() and seek()
      input.seek(n)

      }


      How can I do that with a single function?










      share|improve this question
















      I'm writing a library to deal with a binary format.



      I have a struct with array vars, that I would like to keep for documentation purposes.



      I need also to seek and tell from the input slice of bytes.



      Some pseudocode:



      type foo struct {
      boo [5]byte
      coo [3]byte
      }

      func main() {

      // input is a byte full of datas, read from a file

      var bar foo

      // Here i need something that writes 5 bytes to bar.foo from input
      bar.foo = somefunc(input, numberOfFoo) // ???
      // I need also tell() and seek()
      input.seek(n)

      }


      How can I do that with a single function?







      arrays go struct slice reader






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 11:52









      icza

      171k25340373




      171k25340373










      asked Nov 22 '18 at 10:56









      BlalloBlallo

      987




      987
























          1 Answer
          1






          active

          oldest

          votes


















          3














          Operating on byte slice input



          You may use the builtin copy() to copy bytes from a source slice into a destination. If you have an array, slice it to obtain a slice, e.g. bar.boo[:]. To seek, just use a different offset in the source slice, also by reslicing it, e.g. input[startPos:].



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}

          var bar foo
          copy(bar.boo[:], input)

          // Skip 2 bytes, seek to the 8th byte:
          input = input[7:]

          copy(bar.coo[:], input)

          fmt.Printf("%+v", bar)


          Output (try it on the Go Playground):



          {boo:[1 2 3 4 5] coo:[8 9 10]}


          Creating a ReadSeeker



          Another option is to wrap your input byte slice into an io.ReadSeeker such as bytes.Reader, then you can read from it.



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
          panic(err)
          }

          // Skip 2 bytes, seek to the 8th byte:
          if _, err := r.Seek(7, io.SeekStart); err != nil {
          panic(err)
          }

          if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is the same, try it on the Go Playground.



          Using encoding/binary



          Yet another solution would be to use encoding/binary to read your whole struct in one step.



          In order to do this, we need to export the fields, and we have to insert an anonymous or blank field that covers the skipped bytes:



          type foo struct {
          Boo [5]byte
          _ [2]byte // don't care
          Coo [3]byte
          }


          Having the above type, we can read all of it in one step like this:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is similar, except that it also displays the anonymous field (try it on the Go Playground):



          {Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}


          See related answer: Why use arrays instead of slices?



          Reading directly from the original file



          You mentioned your input slice is from reading a file. Note that you do not need to read the file prior, as os.File implements io.Reader, even io.ReadSeeker, which means you can read from it directly, see the Creating a ReadSeeker section. You can also directly apply the encoding/binary solution, as we used a reader in that solution too.






          share|improve this answer


























          • You are great, man. Thanks, very instructive!

            – Blallo
            Nov 22 '18 at 13:44






          • 1





            @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

            – icza
            Nov 22 '18 at 14:04











          • Exactly what i was googling right now, thanks man!

            – Blallo
            Nov 22 '18 at 14:16













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429405%2fhow-to-copy-from-slice-to-array-with-seeking-onto-slice%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Operating on byte slice input



          You may use the builtin copy() to copy bytes from a source slice into a destination. If you have an array, slice it to obtain a slice, e.g. bar.boo[:]. To seek, just use a different offset in the source slice, also by reslicing it, e.g. input[startPos:].



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}

          var bar foo
          copy(bar.boo[:], input)

          // Skip 2 bytes, seek to the 8th byte:
          input = input[7:]

          copy(bar.coo[:], input)

          fmt.Printf("%+v", bar)


          Output (try it on the Go Playground):



          {boo:[1 2 3 4 5] coo:[8 9 10]}


          Creating a ReadSeeker



          Another option is to wrap your input byte slice into an io.ReadSeeker such as bytes.Reader, then you can read from it.



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
          panic(err)
          }

          // Skip 2 bytes, seek to the 8th byte:
          if _, err := r.Seek(7, io.SeekStart); err != nil {
          panic(err)
          }

          if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is the same, try it on the Go Playground.



          Using encoding/binary



          Yet another solution would be to use encoding/binary to read your whole struct in one step.



          In order to do this, we need to export the fields, and we have to insert an anonymous or blank field that covers the skipped bytes:



          type foo struct {
          Boo [5]byte
          _ [2]byte // don't care
          Coo [3]byte
          }


          Having the above type, we can read all of it in one step like this:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is similar, except that it also displays the anonymous field (try it on the Go Playground):



          {Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}


          See related answer: Why use arrays instead of slices?



          Reading directly from the original file



          You mentioned your input slice is from reading a file. Note that you do not need to read the file prior, as os.File implements io.Reader, even io.ReadSeeker, which means you can read from it directly, see the Creating a ReadSeeker section. You can also directly apply the encoding/binary solution, as we used a reader in that solution too.






          share|improve this answer


























          • You are great, man. Thanks, very instructive!

            – Blallo
            Nov 22 '18 at 13:44






          • 1





            @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

            – icza
            Nov 22 '18 at 14:04











          • Exactly what i was googling right now, thanks man!

            – Blallo
            Nov 22 '18 at 14:16


















          3














          Operating on byte slice input



          You may use the builtin copy() to copy bytes from a source slice into a destination. If you have an array, slice it to obtain a slice, e.g. bar.boo[:]. To seek, just use a different offset in the source slice, also by reslicing it, e.g. input[startPos:].



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}

          var bar foo
          copy(bar.boo[:], input)

          // Skip 2 bytes, seek to the 8th byte:
          input = input[7:]

          copy(bar.coo[:], input)

          fmt.Printf("%+v", bar)


          Output (try it on the Go Playground):



          {boo:[1 2 3 4 5] coo:[8 9 10]}


          Creating a ReadSeeker



          Another option is to wrap your input byte slice into an io.ReadSeeker such as bytes.Reader, then you can read from it.



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
          panic(err)
          }

          // Skip 2 bytes, seek to the 8th byte:
          if _, err := r.Seek(7, io.SeekStart); err != nil {
          panic(err)
          }

          if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is the same, try it on the Go Playground.



          Using encoding/binary



          Yet another solution would be to use encoding/binary to read your whole struct in one step.



          In order to do this, we need to export the fields, and we have to insert an anonymous or blank field that covers the skipped bytes:



          type foo struct {
          Boo [5]byte
          _ [2]byte // don't care
          Coo [3]byte
          }


          Having the above type, we can read all of it in one step like this:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is similar, except that it also displays the anonymous field (try it on the Go Playground):



          {Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}


          See related answer: Why use arrays instead of slices?



          Reading directly from the original file



          You mentioned your input slice is from reading a file. Note that you do not need to read the file prior, as os.File implements io.Reader, even io.ReadSeeker, which means you can read from it directly, see the Creating a ReadSeeker section. You can also directly apply the encoding/binary solution, as we used a reader in that solution too.






          share|improve this answer


























          • You are great, man. Thanks, very instructive!

            – Blallo
            Nov 22 '18 at 13:44






          • 1





            @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

            – icza
            Nov 22 '18 at 14:04











          • Exactly what i was googling right now, thanks man!

            – Blallo
            Nov 22 '18 at 14:16
















          3












          3








          3







          Operating on byte slice input



          You may use the builtin copy() to copy bytes from a source slice into a destination. If you have an array, slice it to obtain a slice, e.g. bar.boo[:]. To seek, just use a different offset in the source slice, also by reslicing it, e.g. input[startPos:].



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}

          var bar foo
          copy(bar.boo[:], input)

          // Skip 2 bytes, seek to the 8th byte:
          input = input[7:]

          copy(bar.coo[:], input)

          fmt.Printf("%+v", bar)


          Output (try it on the Go Playground):



          {boo:[1 2 3 4 5] coo:[8 9 10]}


          Creating a ReadSeeker



          Another option is to wrap your input byte slice into an io.ReadSeeker such as bytes.Reader, then you can read from it.



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
          panic(err)
          }

          // Skip 2 bytes, seek to the 8th byte:
          if _, err := r.Seek(7, io.SeekStart); err != nil {
          panic(err)
          }

          if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is the same, try it on the Go Playground.



          Using encoding/binary



          Yet another solution would be to use encoding/binary to read your whole struct in one step.



          In order to do this, we need to export the fields, and we have to insert an anonymous or blank field that covers the skipped bytes:



          type foo struct {
          Boo [5]byte
          _ [2]byte // don't care
          Coo [3]byte
          }


          Having the above type, we can read all of it in one step like this:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is similar, except that it also displays the anonymous field (try it on the Go Playground):



          {Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}


          See related answer: Why use arrays instead of slices?



          Reading directly from the original file



          You mentioned your input slice is from reading a file. Note that you do not need to read the file prior, as os.File implements io.Reader, even io.ReadSeeker, which means you can read from it directly, see the Creating a ReadSeeker section. You can also directly apply the encoding/binary solution, as we used a reader in that solution too.






          share|improve this answer















          Operating on byte slice input



          You may use the builtin copy() to copy bytes from a source slice into a destination. If you have an array, slice it to obtain a slice, e.g. bar.boo[:]. To seek, just use a different offset in the source slice, also by reslicing it, e.g. input[startPos:].



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}

          var bar foo
          copy(bar.boo[:], input)

          // Skip 2 bytes, seek to the 8th byte:
          input = input[7:]

          copy(bar.coo[:], input)

          fmt.Printf("%+v", bar)


          Output (try it on the Go Playground):



          {boo:[1 2 3 4 5] coo:[8 9 10]}


          Creating a ReadSeeker



          Another option is to wrap your input byte slice into an io.ReadSeeker such as bytes.Reader, then you can read from it.



          For example:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
          panic(err)
          }

          // Skip 2 bytes, seek to the 8th byte:
          if _, err := r.Seek(7, io.SeekStart); err != nil {
          panic(err)
          }

          if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is the same, try it on the Go Playground.



          Using encoding/binary



          Yet another solution would be to use encoding/binary to read your whole struct in one step.



          In order to do this, we need to export the fields, and we have to insert an anonymous or blank field that covers the skipped bytes:



          type foo struct {
          Boo [5]byte
          _ [2]byte // don't care
          Coo [3]byte
          }


          Having the above type, we can read all of it in one step like this:



          input := byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
          r := bytes.NewReader(input)

          var bar foo
          if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
          panic(err)
          }

          fmt.Printf("%+v", bar)


          Output is similar, except that it also displays the anonymous field (try it on the Go Playground):



          {Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}


          See related answer: Why use arrays instead of slices?



          Reading directly from the original file



          You mentioned your input slice is from reading a file. Note that you do not need to read the file prior, as os.File implements io.Reader, even io.ReadSeeker, which means you can read from it directly, see the Creating a ReadSeeker section. You can also directly apply the encoding/binary solution, as we used a reader in that solution too.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 22 '18 at 14:27

























          answered Nov 22 '18 at 11:23









          iczaicza

          171k25340373




          171k25340373













          • You are great, man. Thanks, very instructive!

            – Blallo
            Nov 22 '18 at 13:44






          • 1





            @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

            – icza
            Nov 22 '18 at 14:04











          • Exactly what i was googling right now, thanks man!

            – Blallo
            Nov 22 '18 at 14:16





















          • You are great, man. Thanks, very instructive!

            – Blallo
            Nov 22 '18 at 13:44






          • 1





            @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

            – icza
            Nov 22 '18 at 14:04











          • Exactly what i was googling right now, thanks man!

            – Blallo
            Nov 22 '18 at 14:16



















          You are great, man. Thanks, very instructive!

          – Blallo
          Nov 22 '18 at 13:44





          You are great, man. Thanks, very instructive!

          – Blallo
          Nov 22 '18 at 13:44




          1




          1





          @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

          – icza
          Nov 22 '18 at 14:04





          @Blallo Also see last section: you can read directly from the file, you do not need to read its content prior.

          – icza
          Nov 22 '18 at 14:04













          Exactly what i was googling right now, thanks man!

          – Blallo
          Nov 22 '18 at 14:16







          Exactly what i was googling right now, thanks man!

          – Blallo
          Nov 22 '18 at 14:16






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429405%2fhow-to-copy-from-slice-to-array-with-seeking-onto-slice%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

          Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

          A Topological Invariant for $pi_3(U(n))$