github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/snappy/snappy.go (about) 1 // Copyright 2011 The Snappy-Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package snappy implements the snappy block-based compression format. 6 // It aims for very high speeds and reasonable compression. 7 // 8 // The C++ snappy implementation is at https://yougam/libraries/google/snappy 9 package snappy // import "github.com/insionng/yougam/libraries/golang/snappy" 10 11 import ( 12 "hash/crc32" 13 ) 14 15 /* 16 Each encoded block begins with the varint-encoded length of the decoded data, 17 followed by a sequence of chunks. Chunks begin and end on byte boundaries. The 18 first byte of each chunk is broken into its 2 least and 6 most significant bits 19 called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag. 20 Zero means a literal tag. All other values mean a copy tag. 21 22 For literal tags: 23 - If m < 60, the next 1 + m bytes are literal bytes. 24 - Otherwise, let n be the little-endian unsigned integer denoted by the next 25 m - 59 bytes. The next 1 + n bytes after that are literal bytes. 26 27 For copy tags, length bytes are copied from offset bytes ago, in the style of 28 Lempel-Ziv compression algorithms. In particular: 29 - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12). 30 The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10 31 of the offset. The next byte is bits 0-7 of the offset. 32 - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65). 33 The length is 1 + m. The offset is the little-endian unsigned integer 34 denoted by the next 2 bytes. 35 - For l == 3, this tag is a legacy format that is no longer supported. 36 */ 37 const ( 38 tagLiteral = 0x00 39 tagCopy1 = 0x01 40 tagCopy2 = 0x02 41 tagCopy4 = 0x03 42 ) 43 44 const ( 45 checksumSize = 4 46 chunkHeaderSize = 4 47 magicChunk = "\xff\x06\x00\x00" + magicBody 48 magicBody = "sNaPpY" 49 50 // maxBlockSize is the maximum size of the input to encodeBlock. It is not 51 // part of the wire format per se, but some parts of the encoder assume 52 // that an offset fits into a uint16. 53 // 54 // Also, for the framing format (Writer type instead of Encode function), 55 // https://yougam/libraries/google/snappy/blob/master/framing_format.txt says 56 // that "the uncompressed data in a chunk must be no longer than 65536 57 // bytes". 58 maxBlockSize = 65536 59 60 // maxEncodedLenOfMaxBlockSize equals MaxEncodedLen(maxBlockSize), but is 61 // hard coded to be a const instead of a variable, so that obufLen can also 62 // be a const. Their equivalence is confirmed by 63 // TestMaxEncodedLenOfMaxBlockSize. 64 maxEncodedLenOfMaxBlockSize = 76490 65 66 obufHeaderLen = len(magicChunk) + checksumSize + chunkHeaderSize 67 obufLen = obufHeaderLen + maxEncodedLenOfMaxBlockSize 68 ) 69 70 const ( 71 chunkTypeCompressedData = 0x00 72 chunkTypeUncompressedData = 0x01 73 chunkTypePadding = 0xfe 74 chunkTypeStreamIdentifier = 0xff 75 ) 76 77 var crcTable = crc32.MakeTable(crc32.Castagnoli) 78 79 // crc implements the checksum specified in section 3 of 80 // https://yougam/libraries/google/snappy/blob/master/framing_format.txt 81 func crc(b []byte) uint32 { 82 c := crc32.Update(0, crcTable, b) 83 return uint32(c>>15|c<<17) + 0xa282ead8 84 }