OnlineLibrary
72 строки · 1.3 Кб
1package lkf
2
3import (
4"fmt"
5"io"
6
7"gitverse.ru/kvark128/lkf"
8)
9
10type Reader struct {
11src io.ReadSeeker
12buf []byte
13bufLength int
14c *lkf.Cryptor
15lastError error
16}
17
18func NewReader(src io.ReadSeeker) *Reader {
19return &Reader{
20src: src,
21buf: make([]byte, lkf.BlockSize*32), // 16 Kb
22c: new(lkf.Cryptor),
23}
24}
25
26func (r *Reader) Read(p []byte) (int, error) {
27if len(p) == 0 {
28return 0, nil
29}
30
31if r.bufLength == 0 {
32for r.bufLength < len(r.buf) && r.lastError == nil {
33var nRead int
34nRead, r.lastError = r.src.Read(r.buf[r.bufLength:])
35r.bufLength += nRead
36}
37
38if r.bufLength == 0 && r.lastError != nil {
39return 0, r.lastError
40}
41
42t := r.buf[:r.bufLength]
43r.c.Decrypt(t, t)
44}
45
46n := copy(p, r.buf[:r.bufLength])
47copy(r.buf, r.buf[n:r.bufLength])
48r.bufLength -= n
49return n, nil
50}
51
52func (r *Reader) Seek(offset int64, whence int) (int64, error) {
53if whence != io.SeekStart {
54return 0, fmt.Errorf("LKFReader: Seek: only io.SeekStart is supported")
55}
56
57r.bufLength = 0
58r.lastError = nil
59
60blockOffset := offset % lkf.BlockSize
61pos, err := r.src.Seek(offset-blockOffset, whence)
62if err != nil {
63return 0, err
64}
65
66if blockOffset == 0 {
67return pos, nil
68}
69
70n, err := io.ReadFull(r, make([]byte, blockOffset))
71return pos + int64(n), err
72}
73