blob: ca7259c69f938ea7d35e282a91ddeda130a76e3e [file] [log] [blame]
giolekva7be17df2020-03-21 13:57:02 +04001package chunk
2
giolekvac5126d92020-03-21 16:39:56 +04003import (
4 "bytes"
giolekva1f6577a2020-03-25 12:53:06 +04005 "errors"
giolekvac5126d92020-03-21 16:39:56 +04006 "io"
giolekva1f6577a2020-03-25 12:53:06 +04007
8 "pcloud/api"
giolekvac5126d92020-03-21 16:39:56 +04009)
giolekva7be17df2020-03-21 13:57:02 +040010
11type InMemoryChunk struct {
giolekva1f6577a2020-03-25 12:53:06 +040012 status api.ChunkStatus
13 payload []byte
14 committed int
giolekva7be17df2020-03-21 13:57:02 +040015}
16
giolekva1f6577a2020-03-25 12:53:06 +040017func (c *InMemoryChunk) Stats() (ChunkInfo, error) {
18 return ChunkInfo{c.status, len(c.payload), c.committed}, nil
giolekva7be17df2020-03-21 13:57:02 +040019}
20
giolekva1f6577a2020-03-25 12:53:06 +040021func (c *InMemoryChunk) ReaderAt() io.ReaderAt {
22 return bytes.NewReader(c.payload[:c.committed])
giolekva7be17df2020-03-21 13:57:02 +040023}
24
giolekva1f6577a2020-03-25 12:53:06 +040025func (c *InMemoryChunk) WriterAt() io.WriterAt {
26 return &byteWriter{c}
27}
28
29type byteWriter struct {
30 c *InMemoryChunk
31}
32
33func (w *byteWriter) WriteAt(p []byte, offset int64) (n int, err error) {
34 if int(offset) > w.c.committed {
35 panic(1)
36 return 0, errors.New("Gaps are not allowed when writing in chunks")
37 }
38 if int(offset) < w.c.committed {
39 if int(offset)+len(p) <= w.c.committed {
40 if bytes.Compare(w.c.payload[int(offset):int(offset)+len(p)], p) != 0 {
41 panic(2)
42 return 0, errors.New("Can not change contents of allready committed chunk bytes")
43 }
44 panic(3)
45 return len(p), nil
46 }
47 n = w.c.committed - int(offset)
48 p = p[n:]
49 offset = int64(w.c.committed)
50 }
51 if w.c.committed+len(p) > len(w.c.payload) {
52 panic(4)
53 return 0, errors.New("In memory chunk does not have enough space available")
54 }
55 n += copy(w.c.payload[w.c.committed:], p)
56 w.c.committed += n
57 return
giolekva7be17df2020-03-21 13:57:02 +040058}
59
60type InMemoryChunkFactory struct {
61}
62
giolekva1f6577a2020-03-25 12:53:06 +040063func (f InMemoryChunkFactory) New(size int) Chunk {
64 return &InMemoryChunk{
65 status: api.ChunkStatus_CREATED,
66 payload: make([]byte, size),
67 committed: 0}
giolekva7be17df2020-03-21 13:57:02 +040068}