teldrive/internal/reader/reader.go

132 lines
2.6 KiB
Go
Raw Normal View History

2023-12-08 05:46:06 +08:00
package reader
import (
"context"
"io"
"github.com/divyam234/teldrive/internal/config"
2024-06-22 20:29:59 +08:00
"github.com/divyam234/teldrive/internal/tgc"
2023-12-08 05:46:06 +08:00
"github.com/divyam234/teldrive/pkg/types"
)
2024-03-20 01:01:56 +08:00
func calculatePartByteRanges(startByte, endByte, partSize int64) []types.Range {
partByteRanges := []types.Range{}
startPart := startByte / partSize
endPart := endByte / partSize
startOffset := startByte % partSize
for part := startPart; part <= endPart; part++ {
partStartByte := int64(0)
partEndByte := partSize - 1
if part == startPart {
partStartByte = startOffset
}
if part == endPart {
partEndByte = int64(endByte % partSize)
}
partByteRanges = append(partByteRanges, types.Range{Start: partStartByte, End: partEndByte, PartNo: part})
startOffset = 0
}
return partByteRanges
}
2023-12-08 05:46:06 +08:00
type linearReader struct {
2024-06-22 20:29:59 +08:00
ctx context.Context
parts []types.Part
ranges []types.Range
pos int
reader io.ReadCloser
limit int64
config *config.TGConfig
channelId int64
worker *tgc.StreamWorker
client *tgc.Client
fileId string
concurrency int
2023-12-08 05:46:06 +08:00
}
func NewLinearReader(ctx context.Context,
2024-06-22 20:29:59 +08:00
fileId string,
2023-12-08 05:46:06 +08:00
parts []types.Part,
2024-03-20 01:01:56 +08:00
start, end int64,
2024-06-22 20:29:59 +08:00
channelId int64,
config *config.TGConfig,
2024-06-22 20:29:59 +08:00
concurrency int,
client *tgc.Client,
worker *tgc.StreamWorker,
2023-12-08 05:46:06 +08:00
) (reader io.ReadCloser, err error) {
r := &linearReader{
2024-06-22 20:29:59 +08:00
ctx: ctx,
parts: parts,
limit: end - start + 1,
ranges: calculatePartByteRanges(start, end, parts[0].Size),
config: config,
client: client,
worker: worker,
channelId: channelId,
fileId: fileId,
concurrency: concurrency,
2023-12-08 05:46:06 +08:00
}
2024-03-20 01:01:56 +08:00
r.reader, err = r.nextPart()
2023-12-08 05:46:06 +08:00
if err != nil {
return nil, err
}
return r, nil
}
2024-06-22 20:29:59 +08:00
func (r *linearReader) Read(p []byte) (int, error) {
2024-03-10 22:40:09 +08:00
if r.limit <= 0 {
return 0, io.EOF
}
2024-06-22 20:29:59 +08:00
n, err := r.reader.Read(p)
2023-12-08 05:46:06 +08:00
2024-03-10 22:40:09 +08:00
if err == io.EOF {
if r.limit > 0 {
err = nil
2024-06-22 20:29:59 +08:00
if r.reader != nil {
r.reader.Close()
}
2024-03-10 22:40:09 +08:00
}
2023-12-08 05:46:06 +08:00
r.pos++
2024-03-20 01:01:56 +08:00
if r.pos < len(r.ranges) {
r.reader, err = r.nextPart()
2023-12-08 05:46:06 +08:00
}
}
2024-06-23 00:57:42 +08:00
r.limit -= int64(n)
2024-06-22 20:29:59 +08:00
return n, err
2023-12-08 05:46:06 +08:00
}
2024-03-20 01:01:56 +08:00
func (r *linearReader) nextPart() (io.ReadCloser, error) {
2024-06-22 20:29:59 +08:00
start := r.ranges[r.pos].Start
end := r.ranges[r.pos].End
2024-06-22 20:29:59 +08:00
chunkSrc := &chunkSource{channelId: r.channelId, worker: r.worker,
fileId: r.fileId, partId: r.parts[r.ranges[r.pos].PartNo].ID,
client: r.client, concurrency: r.concurrency}
return newTGReader(r.ctx, start, end, r.config, chunkSrc)
2024-03-20 01:01:56 +08:00
}
2023-12-08 05:46:06 +08:00
func (r *linearReader) Close() (err error) {
if r.reader != nil {
err = r.reader.Close()
r.reader = nil
return err
}
return nil
}