reader.go
func (z *Reader) readHeader(first bool) error {
	defer z.checksum.Reset()

	buf := z.buf[:]
	for {
		magic, err := z.readUint32()
		if err != nil {
			z.pos += 4
			if !first && err == io.ErrUnexpectedEOF {
				return io.EOF
			}
			return err
		}
		if magic == frameMagic {
			break
		}
		if magic>>8 != frameSkipMagic>>8 {
			return ErrInvalid
		}
		skipSize, err := z.readUint32()
		if err != nil {
			return err
		}
		z.pos += 4
		m, err := io.CopyN(ioutil.Discard, z.src, int64(skipSize))
		if err != nil {
			return err
		}
		z.pos += m
	}

	// Header.
	if _, err := io.ReadFull(z.src, buf[:2]); err != nil {
		return err
	}
	z.pos += 8

	b := buf[0]
	if v := b >> 6; v != Version {
		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")
	}
	z.BlockChecksum = b>>4&1 > 0
	frameSize := b>>3&1 > 0
	z.NoChecksum = b>>2&1 == 0

	bmsID := buf[1] >> 4 & 0x7
	bSize, ok := bsMapID[bmsID]
	if !ok {
		return fmt.Errorf("lz4: invalid block max size ID: %d", bmsID)
	}
	z.BlockMaxSize = bSize

	// Allocate the compressed/uncompressed buffers.
	// The compressed buffer cannot exceed the uncompressed one.
	if n := 2 * bSize; cap(z.zdata) < n {
		z.zdata = make([]byte, n, n)
	}
	if debugFlag {
		debug("header block max size id=%d size=%d", bmsID, bSize)
	}
	z.zdata = z.zdata[:bSize]
	z.data = z.zdata[:cap(z.zdata)][bSize:]
	z.idx = len(z.data)

	_, _ = z.checksum.Write(buf[0:2])

	if frameSize {
		buf := buf[:8]
		if _, err := io.ReadFull(z.src, buf); err != nil {
			return err
		}
		z.Size = binary.LittleEndian.Uint64(buf)
		z.pos += 8
		_, _ = z.checksum.Write(buf)
	}

	// Header checksum.
	if _, err := io.ReadFull(z.src, buf[:1]); err != nil {
		return err
	}
	z.pos++
	if h := byte(z.checksum.Sum32() >> 8 & 0xFF); h != buf[0] {
		return fmt.Errorf("lz4: invalid header checksum: got %x; expected %x", buf[0], h)
	}

	z.Header.done = true
	if debugFlag {
		debug("header read: %v", z.Header)
	}

	return nil
}
func (z *Reader) readHeader(first bool) error {
	defer z.checksum.Reset()

	buf := z.buf[:]
	for {
		magic, err := z.readUint32()
		if err != nil {
			z.pos += 4
			if !first && err == io.ErrUnexpectedEOF {
				return io.EOF
			}
			return err
		}
		if magic == frameMagic {
			break
		}
		if magic>>8 != frameSkipMagic>>8 {
			return ErrInvalid
		}
		skipSize, err := z.readUint32()
		if err != nil {
			return err
		}
		z.pos += 4
		m, err := io.CopyN(ioutil.Discard, z.src, int64(skipSize))
		if err != nil {
			return err
		}
		z.pos += m
	}

	// Header.
	if _, err := io.ReadFull(z.src, buf[:2]); err != nil {
		return err
	}
	z.pos += 8

	b := buf[0]
	if v := b >> 6; v != Version {
		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")
	}
	z.BlockChecksum = b>>4&1 > 0
	frameSize := b>>3&1 > 0
	z.NoChecksum = b>>2&1 == 0

	bmsID := buf[1] >> 4 & 0x7
	bSize, ok := bsMapID[bmsID]
	if !ok {
		return fmt.Errorf("lz4: invalid block max size ID: %d", bmsID)
	}
	z.BlockMaxSize = bSize

	// Allocate the compressed/uncompressed buffers.
	// The compressed buffer cannot exceed the uncompressed one.
	if n := 2 * bSize; cap(z.zdata) < n {
		z.zdata = make([]byte, n, n)
	}
	if debugFlag {
		debug("header block max size id=%d size=%d", bmsID, bSize)
	}
	z.zdata = z.zdata[:bSize]
	z.data = z.zdata[:cap(z.zdata)][bSize:]
	z.idx = len(z.data)

	_, _ = z.checksum.Write(buf[0:2])

	if frameSize {
		buf := buf[:8]
		if _, err := io.ReadFull(z.src, buf); err != nil {
			return err
		}
		z.Size = binary.LittleEndian.Uint64(buf)
		z.pos += 8
		_, _ = z.checksum.Write(buf)
	}

	// Header checksum.
	if _, err := io.ReadFull(z.src, buf[:1]); err != nil {
		return err
	}
	z.pos++
	if h := byte(z.checksum.Sum32() >> 8 & 0xFF); h != buf[0] {
		return fmt.Errorf("lz4: invalid header checksum: got %x; expected %x", buf[0], h)
	}

	z.Header.done = true
	if debugFlag {
		debug("header read: %v", z.Header)
	}

	return nil
}
func ( z * Reader ) readHeader ( first bool ) error { defer z . checksum . Reset ( ) buf := z . buf [ : ] for { magic , err := z . readUint32 ( ) if err != nil { z . pos += 4 if ! first && err == io . ErrUnexpectedEOF { return io . EOF } return err } if magic == frameMagic { break } if magic >> 8 != frameSkipMagic >> 8 { return ErrInvalid } skipSize , err := z . readUint32 ( ) if err != nil { return err } z . pos += 4 m , err := io . CopyN ( ioutil . Discard , z . src , int64 ( skipSize ) ) if err != nil { return err } z . pos += m } // Header. if _ , err := io . ReadFull ( z . src , buf [ : 2 ] ) ; err != nil { return err } z . pos += 8 b := buf [ 0 ] if v := b >> 6 ; v != Version { return fmt . Errorf ( " " , v , Version ) } if b >> 5 & 1 == 0 { return fmt . Errorf ( " " ) } z . BlockChecksum = b >> 4 & 1 > 0 frameSize := b >> 3 & 1 > 0 z . NoChecksum = b >> 2 & 1 == 0 bmsID := buf [ 1 ] >> 4 & 0x7 bSize , ok := bsMapID [ bmsID ] if ! ok { return fmt . Errorf ( " " , bmsID ) } z . BlockMaxSize = bSize // Allocate the compressed/uncompressed buffers. // The compressed buffer cannot exceed the uncompressed one. if n := 2 * bSize ; cap ( z . zdata ) < n { z . zdata = make ( [ ] byte , n , n ) } if debugFlag { debug ( " " , bmsID , bSize ) } z . zdata = z . zdata [ : bSize ] z . data = z . zdata [ : cap ( z . zdata ) ] [ bSize : ] z . idx = len ( z . data ) _ , _ = z . checksum . Write ( buf [ 0 : 2 ] ) if frameSize { buf := buf [ : 8 ] if _ , err := io . ReadFull ( z . src , buf ) ; err != nil { return err } z . Size = binary . LittleEndian . Uint64 ( buf ) z . pos += 8 _ , _ = z . checksum . Write ( buf ) } // Header checksum. if _ , err := io . ReadFull ( z . src , buf [ : 1 ] ) ; err != nil { return err } z . pos ++ if h := byte ( z . checksum . Sum32 ( ) >> 8 & 0xFF ) ; h != buf [ 0 ] { return fmt . Errorf ( " " , buf [ 0 ] , h ) } z . Header . done = true if debugFlag { debug ( " " , z . Header ) } return nil }
// readHeader checks the frame magic number and parses the frame descriptoz.
// Skippable frames are supported even as a first frame although the LZ4
// specifications recommends skippable frames not to be used as first frames.
readHeader checks the frame magic number and parses the frame descriptoz . Skippable frames are supported even as a first frame although the LZ4 specifications recommends skippable frames not to be used as first frames .