Compare commits
3 commits
0a4c62f9e3
...
edad47b568
Author | SHA1 | Date | |
---|---|---|---|
![]() |
edad47b568 | ||
![]() |
96f0b64a11 | ||
![]() |
b7f8103a94 |
5 changed files with 101 additions and 11 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 FLUX
|
||||
Copyright (c) 2025 Zervó Zadachin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# GoSBHPF
|
||||
|
||||
Go implementation of the SBHPF binary format
|
||||
Go implementation of the SBHPF binary format.
|
|
@ -2,7 +2,6 @@ package sbhpfv1_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
|
@ -90,13 +89,13 @@ func TestNodeSerialization(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
w := io.WriteSeeker{}
|
||||
err := sbhpfv1.SerializeNode(buf, &node)
|
||||
var w bytes.Buffer
|
||||
err := sbhpfv1.SerializeNodeStream(&w, &node)
|
||||
if err != nil {
|
||||
t.Fatalf("Node serialization failed: %v", err)
|
||||
}
|
||||
|
||||
if !slices.Equal(buf.Bytes(), node_ser_targetbytes) {
|
||||
t.Fatalf("Node serialization generated bad data: %v", buf.Bytes())
|
||||
if !slices.Equal(w.Bytes(), node_ser_targetbytes) {
|
||||
t.Fatalf("Node serialization generated bad data: %v", w.Bytes())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package sbhpfv1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"git.zervo.org/FLUX/GoSBHPF/pkg/seekablebuffer"
|
||||
)
|
||||
|
||||
// SerializeNodeStream serializes a node object into a SBHPF node.
|
||||
// It is a wrapper around SerializeNode that temporarily stores the serialized nodes in a memory buffer.
|
||||
// This is less efficient, but also works with writers that lack seeking support.
|
||||
// It is a wrapper around SerializeNode that temporarily stores the serialized nodes in a seekable memory buffer.
|
||||
// This is less efficient, but provides compatibility with writers that lack seeking support.
|
||||
func SerializeNodeStream(w io.Writer, node *Node) error {
|
||||
buf := &bytes.Buffer{}
|
||||
buf := &seekablebuffer.Buffer{}
|
||||
if err := SerializeNode(buf, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
90
pkg/seekablebuffer/seekablebuffer.go
Normal file
90
pkg/seekablebuffer/seekablebuffer.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
SeekableBuffer
|
||||
|
||||
Copyright (c) 2023 aler9
|
||||
Copyright (c) 2025 Zervó Zadachin
|
||||
|
||||
Implementation based on code from "bluenviron/mediacommon".
|
||||
See: https://github.com/bluenviron/mediacommon/blob/main/pkg/formats/fmp4/seekablebuffer/seekablebuffer.go
|
||||
|
||||
Original code was licensed under the MIT License.
|
||||
See: https://github.com/bluenviron/mediacommon/blob/main/LICENSE
|
||||
*/
|
||||
|
||||
package seekablebuffer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Buffer is a bytes.Buffer with an additional Seek() method.
|
||||
type Buffer struct {
|
||||
bytes.Buffer
|
||||
pos int64
|
||||
}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (b *Buffer) Write(p []byte) (int, error) {
|
||||
var n int
|
||||
|
||||
if b.pos < int64(b.Len()) {
|
||||
n = copy(b.Bytes()[b.pos:], p)
|
||||
p = p[n:]
|
||||
}
|
||||
|
||||
if len(p) > 0 {
|
||||
// Buffer.Write should never return an error here.
|
||||
nn, _ := b.Buffer.Write(p)
|
||||
n += nn
|
||||
}
|
||||
|
||||
b.pos += int64(n)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Read (almost) implements io.Reader.
|
||||
func (b *Buffer) Read(_ []byte) (int, error) {
|
||||
return 0, fmt.Errorf("read not implemented")
|
||||
}
|
||||
|
||||
// Seek implements io.Seeker.
|
||||
func (b *Buffer) Seek(offset int64, whence int) (int64, error) {
|
||||
var pos2 int64
|
||||
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
pos2 = offset
|
||||
|
||||
case io.SeekCurrent:
|
||||
pos2 = b.pos + offset
|
||||
|
||||
case io.SeekEnd:
|
||||
pos2 = int64(b.Len()) + offset
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid seek whence")
|
||||
}
|
||||
|
||||
if pos2 < 0 {
|
||||
return 0, fmt.Errorf("negative position")
|
||||
}
|
||||
|
||||
b.pos = pos2
|
||||
|
||||
// Expand buffer if needed
|
||||
diff := b.pos - int64(b.Len())
|
||||
if diff > 0 {
|
||||
// Buffer.Write should never return an error here.
|
||||
b.Buffer.Write(make([]byte, diff))
|
||||
}
|
||||
|
||||
return pos2, nil
|
||||
}
|
||||
|
||||
// Reset resets the buffer state.
|
||||
func (b *Buffer) Reset() {
|
||||
b.Buffer.Reset()
|
||||
b.pos = 0
|
||||
}
|
Loading…
Add table
Reference in a new issue