teldrive/internal/reader/tg_reader.go

98 lines
1.6 KiB
Go
Raw Normal View History

2024-06-22 20:29:59 +08:00
package reader
import (
"context"
"io"
)
type tgReader struct {
ctx context.Context
2024-06-29 17:37:54 +08:00
cur *buffer
2024-06-22 20:29:59 +08:00
offset int64
limit int64
chunkSize int64
leftCut int64
rightCut int64
totalParts int
currentPart int
chunkSrc ChunkSource
2024-06-29 17:37:54 +08:00
err error
2024-06-22 20:29:59 +08:00
}
func newTGReader(
ctx context.Context,
start int64,
end int64,
chunkSrc ChunkSource,
2024-06-29 17:37:54 +08:00
) (io.ReadCloser, error) {
2024-06-22 20:29:59 +08:00
chunkSize := chunkSrc.ChunkSize(start, end)
offset := start - (start % chunkSize)
r := &tgReader{
ctx: ctx,
leftCut: start - offset,
rightCut: (end % chunkSize) + 1,
totalParts: int((end - offset + chunkSize) / chunkSize),
offset: offset,
2024-06-29 17:37:54 +08:00
limit: end - start + 1,
2024-06-22 20:29:59 +08:00
chunkSize: chunkSize,
chunkSrc: chunkSrc,
2024-06-29 17:37:54 +08:00
currentPart: 1,
2024-06-22 20:29:59 +08:00
}
return r, nil
}
func (r *tgReader) Read(p []byte) (int, error) {
if r.limit <= 0 {
return 0, io.EOF
}
if r.cur.isEmpty() {
2024-06-29 17:37:54 +08:00
r.cur, r.err = r.next()
if r.err != nil {
return 0, r.err
2024-06-22 20:29:59 +08:00
}
}
n := copy(p, r.cur.buffer())
r.cur.increment(n)
r.limit -= int64(n)
if r.limit <= 0 {
return n, io.EOF
}
return n, nil
}
2024-06-29 17:37:54 +08:00
func (*tgReader) Close() error {
return nil
2024-06-22 20:29:59 +08:00
}
2024-06-29 17:37:54 +08:00
func (r *tgReader) next() (*buffer, error) {
2024-06-22 20:29:59 +08:00
2024-06-29 17:37:54 +08:00
if r.currentPart > r.totalParts {
return nil, io.EOF
2024-06-22 20:29:59 +08:00
}
2024-06-29 17:37:54 +08:00
chunk, err := r.chunkSrc.Chunk(r.ctx, r.offset, r.chunkSize)
if err != nil {
return nil, err
2024-06-22 20:29:59 +08:00
}
2024-06-29 17:37:54 +08:00
if r.totalParts == 1 {
chunk = chunk[r.leftCut:r.rightCut]
} else if r.currentPart == 1 {
chunk = chunk[r.leftCut:]
} else if r.currentPart == r.totalParts {
chunk = chunk[:r.rightCut]
2024-06-22 20:29:59 +08:00
}
2024-06-29 17:37:54 +08:00
r.currentPart++
r.offset += r.chunkSize
return &buffer{buf: chunk}, nil
2024-06-22 20:29:59 +08:00
}