summaryrefslogtreecommitdiff
path: root/internal/contentenc/offsets.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/contentenc/offsets.go')
-rw-r--r--internal/contentenc/offsets.go31
1 files changed, 30 insertions, 1 deletions
diff --git a/internal/contentenc/offsets.go b/internal/contentenc/offsets.go
index 813a15f..e331d55 100644
--- a/internal/contentenc/offsets.go
+++ b/internal/contentenc/offsets.go
@@ -11,8 +11,11 @@ func (be *ContentEnc) PlainOffToBlockNo(plainOffset uint64) uint64 {
return plainOffset / be.plainBS
}
-// get the block number at ciphter-text offset
+// get the block number at cipher-text offset
func (be *ContentEnc) CipherOffToBlockNo(cipherOffset uint64) uint64 {
+ if cipherOffset < HEADER_LEN {
+ panic("BUG: offset is inside the file header")
+ }
return (cipherOffset - HEADER_LEN) / be.cipherBS
}
@@ -89,6 +92,32 @@ func (be *ContentEnc) ExplodePlainRange(offset uint64, length uint64) []intraBlo
return blocks
}
+// Split a ciphertext byte range into (possibly partial) blocks
+// This is used in reverse mode when reading files
+func (be *ContentEnc) ExplodeCipherRange(offset uint64, length uint64) []intraBlock {
+ var blocks []intraBlock
+ var nextBlock intraBlock
+ nextBlock.fs = be
+
+ for length > 0 {
+ nextBlock.BlockNo = be.CipherOffToBlockNo(offset)
+ nextBlock.Skip = offset - be.BlockNoToCipherOff(nextBlock.BlockNo)
+
+ // This block can carry up to "maxLen" payload bytes
+ maxLen := be.cipherBS - nextBlock.Skip
+ nextBlock.Length = maxLen
+ // But if the user requested less, we truncate the block to "length".
+ if length < maxLen {
+ nextBlock.Length = length
+ }
+
+ blocks = append(blocks, nextBlock)
+ offset += nextBlock.Length
+ length -= nextBlock.Length
+ }
+ return blocks
+}
+
func (be *ContentEnc) BlockOverhead() uint64 {
return be.cipherBS - be.plainBS
}