| 58 | } |
| 59 | |
| 60 | func (b *DataBuilder) Add(chunk *ChunkPiece) (bool, error) { |
| 61 | b.mu.Lock() |
| 62 | defer b.mu.Unlock() |
| 63 | |
| 64 | if !bytes.Equal(b.Hash, chunk.FullDataHash) { |
| 65 | return b.done(), xerrors.Errorf("data hash does not match, this chunk is for a different data upload") |
| 66 | } |
| 67 | |
| 68 | if b.done() { |
| 69 | return b.done(), xerrors.Errorf("data upload is already complete, cannot add more chunks") |
| 70 | } |
| 71 | |
| 72 | if chunk.PieceIndex != b.chunkIndex { |
| 73 | return b.done(), xerrors.Errorf("chunks ordering, expected chunk index %d, got %d", b.chunkIndex, chunk.PieceIndex) |
| 74 | } |
| 75 | |
| 76 | expectedSize := len(b.data) + len(chunk.Data) |
| 77 | if expectedSize > int(b.Size) { |
| 78 | return b.done(), xerrors.Errorf("data exceeds expected size, data is now %d bytes, %d bytes over the limit of %d", |
| 79 | expectedSize, int64(expectedSize)-b.Size, b.Size) |
| 80 | } |
| 81 | |
| 82 | b.data = append(b.data, chunk.Data...) |
| 83 | b.chunkIndex++ |
| 84 | |
| 85 | return b.done(), nil |
| 86 | } |
| 87 | |
| 88 | // IsDone is always safe to call |
| 89 | func (b *DataBuilder) IsDone() bool { |