diff options
| author | Jakob Unterwurzacher | 2021-05-26 18:28:59 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2021-05-26 18:28:59 +0200 | 
| commit | 07164cbb3a42946a8bb0286da1bc7ea52bb33ee1 (patch) | |
| tree | 2bade682e75489597aed6a71bca64455f766e403 | |
| parent | b4794bedecbddfd90c2a018825a798d2989a2838 (diff) | |
contentenc: add PlainOffToCipherOff helper
Will be used for improving Lseek()
| -rw-r--r-- | internal/contentenc/offsets.go | 16 | ||||
| -rw-r--r-- | internal/contentenc/offsets_test.go | 47 | 
2 files changed, 32 insertions, 31 deletions
| diff --git a/internal/contentenc/offsets.go b/internal/contentenc/offsets.go index 7487baf..3a0abf3 100644 --- a/internal/contentenc/offsets.go +++ b/internal/contentenc/offsets.go @@ -76,20 +76,20 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 {  	return cipherSize - overhead  } -// PlainSizeToCipherSize calculates the ciphertext size from a plaintext size +// PlainSizeToCipherSize calculates the ciphertext size from a plaintext size.  func (be *ContentEnc) PlainSizeToCipherSize(plainSize uint64) uint64 {  	// Zero-sized files stay zero-sized  	if plainSize == 0 {  		return 0  	} +	return be.PlainOffToCipherOff(plainSize-1) + 1 +} -	// Block number at last byte -	blockNo := be.PlainOffToBlockNo(plainSize - 1) -	blockCount := blockNo + 1 - -	overhead := be.BlockOverhead()*blockCount + HeaderLen - -	return plainSize + overhead +// PlainOffToCipherOff tells you the highest ciphertext offset that is +// *guaranteed* to be written/read when you write/read at `plainOff`. +func (be *ContentEnc) PlainOffToCipherOff(plainOff uint64) uint64 { +	startOfBlock := be.BlockNoToCipherOff(be.PlainOffToBlockNo(plainOff)) +	return startOfBlock + plainOff%be.PlainBS() + be.BlockOverhead()  }  // ExplodePlainRange splits a plaintext byte range into (possibly partial) blocks diff --git a/internal/contentenc/offsets_test.go b/internal/contentenc/offsets_test.go index 4bc3762..c3b8fcd 100644 --- a/internal/contentenc/offsets_test.go +++ b/internal/contentenc/offsets_test.go @@ -15,38 +15,39 @@ func TestSizeToSize(t *testing.T) {  	const rangeMax = 10000 -	var c2p [rangeMax]uint64 -	var p2c [rangeMax]uint64 +	// y values in this order: +	// 0 ... CipherSizeToPlainSize +	// 1 ... PlainSizeToCipherSize +	// 2 ... PlainOffToCipherOff +	var yTable [rangeMax][3]uint64  	// Calculate values -	for i := range c2p { -		c2p[i] = ce.CipherSizeToPlainSize(uint64(i)) -		p2c[i] = ce.PlainSizeToCipherSize(uint64(i)) +	for x := range yTable { +		yTable[x][0] = ce.CipherSizeToPlainSize(uint64(x)) +		yTable[x][1] = ce.PlainSizeToCipherSize(uint64(x)) +		yTable[x][2] = ce.PlainOffToCipherOff(uint64(x))  	}  	// Print data table -	fmt.Print("x\tToPlainSize\tToCipherSize\n") -	for i := range c2p { -		if i > 1 && i < rangeMax-1 { +	fmt.Print("x\tCipherSizeToPlainSize\tPlainSizeToCipherSize\tPlainOffToCipherOff\n") +	for x := range yTable { +		if x > 1 && x < rangeMax-1 {  			// If the point before has value-1 and the point after has value+1,  			// it is not interesting. Don't print it out. -			if c2p[i] == c2p[i-1]+1 && p2c[i] == p2c[i-1]+1 && c2p[i+1] == c2p[i]+1 && p2c[i+1] == p2c[i]+1 { +			interesting := false +			for i := 0; i <= 2; i++ { +				if yTable[x-1][i]+1 != yTable[x][i] && yTable[x][i]+1 != yTable[x+1][i]+1 { +					interesting = true +				} +				// Monotonicity check +				if yTable[x][i] < yTable[x-1][i] { +					t.Errorf("column %d is non-monotonic!", i) +				} +			} +			if !interesting {  				continue  			}  		} -		fmt.Printf("%d\t%d\t%d\n", i, c2p[i], p2c[i]) -	} - -	// Monotonicity check -	for i := range c2p { -		if i < 1 { -			continue -		} -		if c2p[i-1] > c2p[i] { -			t.Errorf("error: c2p is non-monotonic: c2p[%d]=%d c2p[%d]=%d ", i-1, c2p[i-1], i, c2p[i]) -		} -		if p2c[i-1] > p2c[i] { -			t.Errorf("error: p2c is non-monotonic: p2c[%d]=%d p2c[%d]=%d ", i-1, p2c[i-1], i, p2c[i]) -		} +		fmt.Printf("%d\t%d\t%d\t%d\n", x, yTable[x][0], yTable[x][1], yTable[x][2])  	}  } | 
