How to copy from slice to array with seeking onto slice
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
add a comment |
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
add a comment |
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
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
arrays go struct slice reader
edited Nov 22 '18 at 11:52
icza
171k25340373
171k25340373
asked Nov 22 '18 at 10:56
BlalloBlallo
987
987
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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