node build fixed

This commit is contained in:
ra_ma
2025-09-20 14:08:38 +01:00
parent c6ebbe069d
commit 3d298fa434
1516 changed files with 535727 additions and 2 deletions

View File

@@ -0,0 +1,111 @@
package util
import (
"fmt"
"io"
)
// CachedReadSeeker wraps an io.ReadSeekCloser and caches bytes as they are read.
// It implements io.ReadSeeker, allowing seeking within the already-cached
// range without hitting the underlying reader again.
// Additional reads beyond the cache will append to the cache automatically.
type CachedReadSeeker struct {
src io.ReadSeekCloser // underlying source
cache []byte // bytes read so far
pos int64 // current read position
}
func (c *CachedReadSeeker) Close() error {
return c.src.Close()
}
var _ io.ReadSeekCloser = (*CachedReadSeeker)(nil)
// NewCachedReadSeeker constructs a new CachedReadSeeker wrapping a io.ReadSeekCloser.
func NewCachedReadSeeker(r io.ReadSeekCloser) *CachedReadSeeker {
return &CachedReadSeeker{src: r}
}
// Read reads up to len(p) bytes into p. It first serves from cache
// if possible, then reads any remaining bytes from the underlying source,
// appending them to the cache.
func (c *CachedReadSeeker) Read(p []byte) (n int, err error) {
// Check if any part of the request can be served from cache
if c.pos < int64(len(c.cache)) {
// Calculate how much we can read from cache
available := int64(len(c.cache)) - c.pos
toRead := int64(len(p))
if available >= toRead {
// Can serve entirely from cache
n = copy(p, c.cache[c.pos:c.pos+toRead])
c.pos += int64(n)
return n, nil
}
// Read what we can from cache
n = copy(p, c.cache[c.pos:])
c.pos += int64(n)
if n == len(p) {
return n, nil
}
// Read the rest from source
m, err := c.readFromSrc(p[n:])
n += m
return n, err
}
// Nothing in cache, read from source
return c.readFromSrc(p)
}
// readFromSrc reads from the underlying source at the current position,
// appends those bytes to cache, and updates the current position.
func (c *CachedReadSeeker) readFromSrc(p []byte) (n int, err error) {
// Seek to the current position in the source
if _, err = c.src.Seek(c.pos, io.SeekStart); err != nil {
return 0, err
}
// Read the requested data
n, err = c.src.Read(p)
if n > 0 {
// If reading sequentially or within small gap of cache, append to cache
if c.pos <= int64(len(c.cache)) {
c.cache = append(c.cache, p[:n]...)
}
c.pos += int64(n)
}
return n, err
}
// Seek sets the read position for subsequent Read calls. Seeking within the
// cached range simply updates the position. Seeking beyond will position
// Read to fetch new data from the underlying source (and cache it).
func (c *CachedReadSeeker) Seek(offset int64, whence int) (int64, error) {
var target int64
switch whence {
case io.SeekStart:
target = offset
case io.SeekCurrent:
target = c.pos + offset
case io.SeekEnd:
// determine end by seeking underlying
end, err := c.src.Seek(0, io.SeekEnd)
if err != nil {
return 0, err
}
target = end + offset
// Cache the end position for future SeekEnd calls
if int64(len(c.cache)) < end {
c.cache = append(c.cache, make([]byte, end-int64(len(c.cache)))...)
}
default:
return 0, fmt.Errorf("invalid whence: %d", whence)
}
if target < 0 {
return 0, fmt.Errorf("negative position: %d", target)
}
c.pos = target
return c.pos, nil
}