Browse Source

Regroup static errors into their own file. Minor cosmetic adjustments.

Pierre Curto 6 years ago
parent
commit
1112564638
5 changed files with 44 additions and 51 deletions
  1. 7 27
      block.go
  2. 3 4
      decode_other.go
  3. 19 0
      errors.go
  4. 1 1
      reader.go
  5. 14 19
      writer.go

+ 7 - 27
block.go

@@ -2,15 +2,6 @@ package lz4
 
 import (
 	"encoding/binary"
-	"errors"
-)
-
-var (
-	// ErrInvalidSourceShortBuffer is returned by UncompressBlock or CompressBLock when a compressed
-	// block is corrupted or the destination buffer is not large enough for the uncompressed data.
-	ErrInvalidSourceShortBuffer = errors.New("lz4: invalid source or destination buffer too short")
-	// ErrInvalid is returned when reading an invalid LZ4 archive.
-	ErrInvalid = errors.New("lz4: bad magic number")
 )
 
 // blockHash hashes 4 bytes into a value < winSize.
@@ -30,17 +21,14 @@ func CompressBlockBound(n int) int {
 // The destination buffer must be sized appropriately.
 //
 // An error is returned if the source data is invalid or the destination buffer is too small.
-func UncompressBlock(src, dst []byte) (di int, err error) {
-	sn := len(src)
-	if sn == 0 {
+func UncompressBlock(src, dst []byte) (int, error) {
+	if len(src) == 0 {
 		return 0, nil
 	}
-
-	di = decodeBlock(dst, src)
-	if di < 0 {
-		return 0, ErrInvalidSourceShortBuffer
+	if di := decodeBlock(dst, src); di >= 0 {
+		return di, nil
 	}
-	return di, nil
+	return 0, ErrInvalidSourceShortBuffer
 }
 
 // CompressBlock compresses the source buffer into the destination one.
@@ -51,11 +39,7 @@ func UncompressBlock(src, dst []byte) (di int, err error) {
 //
 // An error is returned if the destination buffer is too small.
 func CompressBlock(src, dst []byte, hashTable []int) (di int, err error) {
-	defer func() {
-		if recover() != nil {
-			err = ErrInvalidSourceShortBuffer
-		}
-	}()
+	defer recoverBlock(&err)
 
 	sn, dn := len(src)-mfLimit, len(dst)
 	if sn <= 0 || dn == 0 {
@@ -181,11 +165,7 @@ func CompressBlock(src, dst []byte, hashTable []int) (di int, err error) {
 //
 // An error is returned if the destination buffer is too small.
 func CompressBlockHC(src, dst []byte, depth int) (di int, err error) {
-	defer func() {
-		if recover() != nil {
-			err = ErrInvalidSourceShortBuffer
-		}
-	}()
+	defer recoverBlock(&err)
 
 	sn, dn := len(src)-mfLimit, len(dst)
 	if sn <= 0 || dn == 0 {

+ 3 - 4
decode_other.go

@@ -3,11 +3,10 @@
 package lz4
 
 func decodeBlock(dst, src []byte) (ret int) {
+	const hasError = -2
 	defer func() {
-		// It is now faster to let the runtime panic and recover on out of bound slice access
-		// than checking indices as we go along.
 		if recover() != nil {
-			ret = -2
+			ret = hasError
 		}
 	}()
 
@@ -61,7 +60,7 @@ func decodeBlock(dst, src []byte) (ret int) {
 
 		offset := int(src[si]) | int(src[si+1])<<8
 		if offset == 0 {
-			return -2
+			return hasError
 		}
 		si += 2
 

+ 19 - 0
errors.go

@@ -0,0 +1,19 @@
+package lz4
+
+import "errors"
+
+var (
+	// ErrInvalidSourceShortBuffer is returned by UncompressBlock or CompressBLock when a compressed
+	// block is corrupted or the destination buffer is not large enough for the uncompressed data.
+	ErrInvalidSourceShortBuffer = errors.New("lz4: invalid source or destination buffer too short")
+	// ErrInvalid is returned when reading an invalid LZ4 archive.
+	ErrInvalid = errors.New("lz4: bad magic number")
+	// ErrBlockDependency is returned when attempting to decompress an archive created with block dependency.
+	ErrBlockDependency = errors.New("lz4: block dependency not supported")
+)
+
+func recoverBlock(e *error) {
+	if recover() != nil && *e == nil {
+		*e = ErrInvalidSourceShortBuffer
+	}
+}

+ 1 - 1
reader.go

@@ -79,7 +79,7 @@ func (z *Reader) readHeader(first bool) error {
 		return fmt.Errorf("lz4: invalid version: got %d; expected %d", v, Version)
 	}
 	if b>>5&1 == 0 {
-		return fmt.Errorf("lz4: block dependency not supported")
+		return ErrBlockDependency
 	}
 	z.BlockChecksum = b>>4&1 > 0
 	frameSize := b>>3&1 > 0

+ 14 - 19
writer.go

@@ -193,20 +193,18 @@ func (z *Writer) compressBlock(data []byte) error {
 		h(written)
 	}
 
-	if z.BlockChecksum {
-		checksum := xxh32.ChecksumZero(zdata)
+	if !z.BlockChecksum {
 		if debugFlag {
-			debug("block checksum %x", checksum)
-		}
-		if err := z.writeUint32(checksum); err != nil {
-			return err
+			debug("current frame checksum %x", z.checksum.Sum32())
 		}
+		return nil
 	}
+	checksum := xxh32.ChecksumZero(zdata)
 	if debugFlag {
-		debug("current frame checksum %x", z.checksum.Sum32())
+		debug("block checksum %x", checksum)
+		defer func() { debug("current frame checksum %x", z.checksum.Sum32()) }()
 	}
-
-	return nil
+	return z.writeUint32(checksum)
 }
 
 // Flush flushes any pending compressed data to the underlying writer.
@@ -234,7 +232,6 @@ func (z *Writer) Close() error {
 			return err
 		}
 	}
-
 	if err := z.Flush(); err != nil {
 		return err
 	}
@@ -245,16 +242,14 @@ func (z *Writer) Close() error {
 	if err := z.writeUint32(0); err != nil {
 		return err
 	}
-	if !z.NoChecksum {
-		checksum := z.checksum.Sum32()
-		if debugFlag {
-			debug("stream checksum %x", checksum)
-		}
-		if err := z.writeUint32(checksum); err != nil {
-			return err
-		}
+	if z.NoChecksum {
+		return nil
 	}
-	return nil
+	checksum := z.checksum.Sum32()
+	if debugFlag {
+		debug("stream checksum %x", checksum)
+	}
+	return z.writeUint32(checksum)
 }
 
 // Reset clears the state of the Writer z such that it is equivalent to its