mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Vendor Update (#16121)
* update github.com/PuerkitoBio/goquery * update github.com/alecthomas/chroma * update github.com/blevesearch/bleve/v2 * update github.com/caddyserver/certmagic * update github.com/go-enry/go-enry/v2 * update github.com/go-git/go-billy/v5 * update github.com/go-git/go-git/v5 * update github.com/go-redis/redis/v8 * update github.com/go-testfixtures/testfixtures/v3 * update github.com/jaytaylor/html2text * update github.com/json-iterator/go * update github.com/klauspost/compress * update github.com/markbates/goth * update github.com/mattn/go-isatty * update github.com/mholt/archiver/v3 * update github.com/microcosm-cc/bluemonday * update github.com/minio/minio-go/v7 * update github.com/prometheus/client_golang * update github.com/unrolled/render * update github.com/xanzy/go-gitlab * update github.com/yuin/goldmark * update github.com/yuin/goldmark-highlighting Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							
								
								
									
										343
									
								
								vendor/github.com/andybalholm/brotli/brotli_bit_stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										343
									
								
								vendor/github.com/andybalholm/brotli/brotli_bit_stream.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -121,7 +121,7 @@ func encodeMlen(length uint, bits *uint64, numbits *uint, nibblesbits *uint64) { | ||||
| 	*bits = uint64(length) - 1 | ||||
| } | ||||
|  | ||||
| func storeCommandExtra(cmd *command, bw *bitWriter) { | ||||
| func storeCommandExtra(cmd *command, storage_ix *uint, storage []byte) { | ||||
| 	var copylen_code uint32 = commandCopyLenCode(cmd) | ||||
| 	var inscode uint16 = getInsertLengthCode(uint(cmd.insert_len_)) | ||||
| 	var copycode uint16 = getCopyLengthCode(uint(copylen_code)) | ||||
| @@ -129,7 +129,7 @@ func storeCommandExtra(cmd *command, bw *bitWriter) { | ||||
| 	var insextraval uint64 = uint64(cmd.insert_len_) - uint64(getInsertBase(inscode)) | ||||
| 	var copyextraval uint64 = uint64(copylen_code) - uint64(getCopyBase(copycode)) | ||||
| 	var bits uint64 = copyextraval<<insnumextra | insextraval | ||||
| 	bw.writeBits(uint(insnumextra+getCopyExtra(copycode)), bits) | ||||
| 	writeBits(uint(insnumextra+getCopyExtra(copycode)), bits, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| /* Data structure that stores almost everything that is needed to encode each | ||||
| @@ -143,21 +143,21 @@ type blockSplitCode struct { | ||||
| } | ||||
|  | ||||
| /* Stores a number between 0 and 255. */ | ||||
| func storeVarLenUint8(n uint, bw *bitWriter) { | ||||
| func storeVarLenUint8(n uint, storage_ix *uint, storage []byte) { | ||||
| 	if n == 0 { | ||||
| 		bw.writeBits(1, 0) | ||||
| 		writeBits(1, 0, storage_ix, storage) | ||||
| 	} else { | ||||
| 		var nbits uint = uint(log2FloorNonZero(n)) | ||||
| 		bw.writeBits(1, 1) | ||||
| 		bw.writeBits(3, uint64(nbits)) | ||||
| 		bw.writeBits(nbits, uint64(n)-(uint64(uint(1))<<nbits)) | ||||
| 		writeBits(1, 1, storage_ix, storage) | ||||
| 		writeBits(3, uint64(nbits), storage_ix, storage) | ||||
| 		writeBits(nbits, uint64(n)-(uint64(uint(1))<<nbits), storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Stores the compressed meta-block header. | ||||
|    REQUIRES: length > 0 | ||||
|    REQUIRES: length <= (1 << 24) */ | ||||
| func storeCompressedMetaBlockHeader(is_final_block bool, length uint, bw *bitWriter) { | ||||
| func storeCompressedMetaBlockHeader(is_final_block bool, length uint, storage_ix *uint, storage []byte) { | ||||
| 	var lenbits uint64 | ||||
| 	var nlenbits uint | ||||
| 	var nibblesbits uint64 | ||||
| @@ -169,41 +169,41 @@ func storeCompressedMetaBlockHeader(is_final_block bool, length uint, bw *bitWri | ||||
| 	} | ||||
|  | ||||
| 	/* Write ISLAST bit. */ | ||||
| 	bw.writeBits(1, is_final) | ||||
| 	writeBits(1, is_final, storage_ix, storage) | ||||
|  | ||||
| 	/* Write ISEMPTY bit. */ | ||||
| 	if is_final_block { | ||||
| 		bw.writeBits(1, 0) | ||||
| 		writeBits(1, 0, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) | ||||
| 	bw.writeBits(2, nibblesbits) | ||||
| 	bw.writeBits(nlenbits, lenbits) | ||||
| 	writeBits(2, nibblesbits, storage_ix, storage) | ||||
| 	writeBits(nlenbits, lenbits, storage_ix, storage) | ||||
|  | ||||
| 	if !is_final_block { | ||||
| 		/* Write ISUNCOMPRESSED bit. */ | ||||
| 		bw.writeBits(1, 0) | ||||
| 		writeBits(1, 0, storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Stores the uncompressed meta-block header. | ||||
|    REQUIRES: length > 0 | ||||
|    REQUIRES: length <= (1 << 24) */ | ||||
| func storeUncompressedMetaBlockHeader(length uint, bw *bitWriter) { | ||||
| func storeUncompressedMetaBlockHeader(length uint, storage_ix *uint, storage []byte) { | ||||
| 	var lenbits uint64 | ||||
| 	var nlenbits uint | ||||
| 	var nibblesbits uint64 | ||||
|  | ||||
| 	/* Write ISLAST bit. | ||||
| 	   Uncompressed block cannot be the last one, so set to 0. */ | ||||
| 	bw.writeBits(1, 0) | ||||
| 	writeBits(1, 0, storage_ix, storage) | ||||
|  | ||||
| 	encodeMlen(length, &lenbits, &nlenbits, &nibblesbits) | ||||
| 	bw.writeBits(2, nibblesbits) | ||||
| 	bw.writeBits(nlenbits, lenbits) | ||||
| 	writeBits(2, nibblesbits, storage_ix, storage) | ||||
| 	writeBits(nlenbits, lenbits, storage_ix, storage) | ||||
|  | ||||
| 	/* Write ISUNCOMPRESSED bit. */ | ||||
| 	bw.writeBits(1, 1) | ||||
| 	writeBits(1, 1, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| var storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15} | ||||
| @@ -211,7 +211,7 @@ var storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder = [codeLengthCodes]byte | ||||
| var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols = [6]byte{0, 7, 3, 2, 1, 15} | ||||
| var storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths = [6]byte{2, 4, 3, 2, 2, 4} | ||||
|  | ||||
| func storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes int, code_length_bitdepth []byte, bw *bitWriter) { | ||||
| func storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes int, code_length_bitdepth []byte, storage_ix *uint, storage []byte) { | ||||
| 	var skip_some uint = 0 | ||||
| 	var codes_to_store uint = codeLengthCodes | ||||
| 	/* The bit lengths of the Huffman code over the code length alphabet | ||||
| @@ -241,38 +241,38 @@ func storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes int, code_length_bitdepth | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBits(2, uint64(skip_some)) | ||||
| 	writeBits(2, uint64(skip_some), storage_ix, storage) | ||||
| 	{ | ||||
| 		var i uint | ||||
| 		for i = skip_some; i < codes_to_store; i++ { | ||||
| 			var l uint = uint(code_length_bitdepth[storeHuffmanTreeOfHuffmanTreeToBitMask_kStorageOrder[i]]) | ||||
| 			bw.writeBits(uint(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths[l]), uint64(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols[l])) | ||||
| 			writeBits(uint(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeBitLengths[l]), uint64(storeHuffmanTreeOfHuffmanTreeToBitMask_kHuffmanBitLengthHuffmanCodeSymbols[l]), storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeHuffmanTreeToBitMask(huffman_tree_size uint, huffman_tree []byte, huffman_tree_extra_bits []byte, code_length_bitdepth []byte, code_length_bitdepth_symbols []uint16, bw *bitWriter) { | ||||
| func storeHuffmanTreeToBitMask(huffman_tree_size uint, huffman_tree []byte, huffman_tree_extra_bits []byte, code_length_bitdepth []byte, code_length_bitdepth_symbols []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var i uint | ||||
| 	for i = 0; i < huffman_tree_size; i++ { | ||||
| 		var ix uint = uint(huffman_tree[i]) | ||||
| 		bw.writeBits(uint(code_length_bitdepth[ix]), uint64(code_length_bitdepth_symbols[ix])) | ||||
| 		writeBits(uint(code_length_bitdepth[ix]), uint64(code_length_bitdepth_symbols[ix]), storage_ix, storage) | ||||
|  | ||||
| 		/* Extra bits */ | ||||
| 		switch ix { | ||||
| 		case repeatPreviousCodeLength: | ||||
| 			bw.writeBits(2, uint64(huffman_tree_extra_bits[i])) | ||||
| 			writeBits(2, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) | ||||
|  | ||||
| 		case repeatZeroCodeLength: | ||||
| 			bw.writeBits(3, uint64(huffman_tree_extra_bits[i])) | ||||
| 			writeBits(3, uint64(huffman_tree_extra_bits[i]), storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max_bits uint, bw *bitWriter) { | ||||
| func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max_bits uint, storage_ix *uint, storage []byte) { | ||||
| 	/* value of 1 indicates a simple Huffman code */ | ||||
| 	bw.writeBits(2, 1) | ||||
| 	writeBits(2, 1, storage_ix, storage) | ||||
|  | ||||
| 	bw.writeBits(2, uint64(num_symbols)-1) /* NSYM - 1 */ | ||||
| 	writeBits(2, uint64(num_symbols)-1, storage_ix, storage) /* NSYM - 1 */ | ||||
| 	{ | ||||
| 		/* Sort */ | ||||
| 		var i uint | ||||
| @@ -289,17 +289,17 @@ func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max | ||||
| 	} | ||||
|  | ||||
| 	if num_symbols == 2 { | ||||
| 		bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 		writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 	} else if num_symbols == 3 { | ||||
| 		bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[2])) | ||||
| 		writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) | ||||
| 	} else { | ||||
| 		bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[2])) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[3])) | ||||
| 		writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) | ||||
|  | ||||
| 		/* tree-select */ | ||||
| 		var tmp int | ||||
| @@ -308,13 +308,13 @@ func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max | ||||
| 		} else { | ||||
| 			tmp = 0 | ||||
| 		} | ||||
| 		bw.writeBits(1, uint64(tmp)) | ||||
| 		writeBits(1, uint64(tmp), storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* num = alphabet size | ||||
|    depths = symbol depths */ | ||||
| func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, bw *bitWriter) { | ||||
| func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	var huffman_tree [numCommandSymbols]byte | ||||
| 	var huffman_tree_extra_bits [numCommandSymbols]byte | ||||
| 	var huffman_tree_size uint = 0 | ||||
| @@ -357,19 +357,19 @@ func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, bw *bitWriter | ||||
| 	convertBitDepthsToSymbols(code_length_bitdepth[:], codeLengthCodes, code_length_bitdepth_symbols[:]) | ||||
|  | ||||
| 	/* Now, we have all the data, let's start storing it */ | ||||
| 	storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth[:], bw) | ||||
| 	storeHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth[:], storage_ix, storage) | ||||
|  | ||||
| 	if num_codes == 1 { | ||||
| 		code_length_bitdepth[code] = 0 | ||||
| 	} | ||||
|  | ||||
| 	/* Store the real Huffman tree now. */ | ||||
| 	storeHuffmanTreeToBitMask(huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:], code_length_bitdepth[:], code_length_bitdepth_symbols[:], bw) | ||||
| 	storeHuffmanTreeToBitMask(huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:], code_length_bitdepth[:], code_length_bitdepth_symbols[:], storage_ix, storage) | ||||
| } | ||||
|  | ||||
| /* Builds a Huffman tree from histogram[0:length] into depth[0:length] and | ||||
|    bits[0:length] and stores the encoded tree to the bit stream. */ | ||||
| func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabet_size uint, tree []huffmanTree, depth []byte, bits []uint16, bw *bitWriter) { | ||||
| func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabet_size uint, tree []huffmanTree, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var count uint = 0 | ||||
| 	var s4 = [4]uint{0} | ||||
| 	var i uint | ||||
| @@ -394,8 +394,8 @@ func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabe | ||||
| 	} | ||||
|  | ||||
| 	if count <= 1 { | ||||
| 		bw.writeBits(4, 1) | ||||
| 		bw.writeBits(max_bits, uint64(s4[0])) | ||||
| 		writeBits(4, 1, storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(s4[0]), storage_ix, storage) | ||||
| 		depth[s4[0]] = 0 | ||||
| 		bits[s4[0]] = 0 | ||||
| 		return | ||||
| @@ -408,9 +408,9 @@ func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabe | ||||
| 	convertBitDepthsToSymbols(depth, histogram_length, bits) | ||||
|  | ||||
| 	if count <= 4 { | ||||
| 		storeSimpleHuffmanTree(depth, s4[:], count, max_bits, bw) | ||||
| 		storeSimpleHuffmanTree(depth, s4[:], count, max_bits, storage_ix, storage) | ||||
| 	} else { | ||||
| 		storeHuffmanTree(depth, histogram_length, tree, bw) | ||||
| 		storeHuffmanTree(depth, histogram_length, tree, storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -420,7 +420,7 @@ func sortHuffmanTree1(v0 huffmanTree, v1 huffmanTree) bool { | ||||
|  | ||||
| var huffmanTreePool sync.Pool | ||||
|  | ||||
| func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, bw *bitWriter) { | ||||
| func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var count uint = 0 | ||||
| 	var symbols = [4]uint{0} | ||||
| 	var length uint = 0 | ||||
| @@ -439,8 +439,8 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_ | ||||
| 	} | ||||
|  | ||||
| 	if count <= 1 { | ||||
| 		bw.writeBits(4, 1) | ||||
| 		bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 		writeBits(4, 1, storage_ix, storage) | ||||
| 		writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 		depth[symbols[0]] = 0 | ||||
| 		bits[symbols[0]] = 0 | ||||
| 		return | ||||
| @@ -544,9 +544,9 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_ | ||||
| 		var i uint | ||||
|  | ||||
| 		/* value of 1 indicates a simple Huffman code */ | ||||
| 		bw.writeBits(2, 1) | ||||
| 		writeBits(2, 1, storage_ix, storage) | ||||
|  | ||||
| 		bw.writeBits(2, uint64(count)-1) /* NSYM - 1 */ | ||||
| 		writeBits(2, uint64(count)-1, storage_ix, storage) /* NSYM - 1 */ | ||||
|  | ||||
| 		/* Sort */ | ||||
| 		for i = 0; i < count; i++ { | ||||
| @@ -561,27 +561,33 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_ | ||||
| 		} | ||||
|  | ||||
| 		if count == 2 { | ||||
| 			bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 			writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 		} else if count == 3 { | ||||
| 			bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[2])) | ||||
| 			writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) | ||||
| 		} else { | ||||
| 			bw.writeBits(max_bits, uint64(symbols[0])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[1])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[2])) | ||||
| 			bw.writeBits(max_bits, uint64(symbols[3])) | ||||
| 			writeBits(max_bits, uint64(symbols[0]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[1]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[2]), storage_ix, storage) | ||||
| 			writeBits(max_bits, uint64(symbols[3]), storage_ix, storage) | ||||
|  | ||||
| 			/* tree-select */ | ||||
| 			bw.writeSingleBit(depth[symbols[0]] == 1) | ||||
| 			var tmp int | ||||
| 			if depth[symbols[0]] == 1 { | ||||
| 				tmp = 1 | ||||
| 			} else { | ||||
| 				tmp = 0 | ||||
| 			} | ||||
| 			writeBits(1, uint64(tmp), storage_ix, storage) | ||||
| 		} | ||||
| 	} else { | ||||
| 		var previous_value byte = 8 | ||||
| 		var i uint | ||||
|  | ||||
| 		/* Complex Huffman Tree */ | ||||
| 		storeStaticCodeLengthCode(bw) | ||||
| 		storeStaticCodeLengthCode(storage_ix, storage) | ||||
|  | ||||
| 		/* Actual RLE coding. */ | ||||
| 		for i = 0; i < length; { | ||||
| @@ -594,21 +600,21 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_ | ||||
|  | ||||
| 			i += reps | ||||
| 			if value == 0 { | ||||
| 				bw.writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps]) | ||||
| 				writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps], storage_ix, storage) | ||||
| 			} else { | ||||
| 				if previous_value != value { | ||||
| 					bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value])) | ||||
| 					writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) | ||||
| 					reps-- | ||||
| 				} | ||||
|  | ||||
| 				if reps < 3 { | ||||
| 					for reps != 0 { | ||||
| 						reps-- | ||||
| 						bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value])) | ||||
| 						writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]), storage_ix, storage) | ||||
| 					} | ||||
| 				} else { | ||||
| 					reps -= 3 | ||||
| 					bw.writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps]) | ||||
| 					writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps], storage_ix, storage) | ||||
| 				} | ||||
|  | ||||
| 				previous_value = value | ||||
| @@ -733,7 +739,7 @@ const symbolBits = 9 | ||||
|  | ||||
| var encodeContextMap_kSymbolMask uint32 = (1 << symbolBits) - 1 | ||||
|  | ||||
| func encodeContextMap(context_map []uint32, context_map_size uint, num_clusters uint, tree []huffmanTree, bw *bitWriter) { | ||||
| func encodeContextMap(context_map []uint32, context_map_size uint, num_clusters uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	var i uint | ||||
| 	var rle_symbols []uint32 | ||||
| 	var max_run_length_prefix uint32 = 6 | ||||
| @@ -742,7 +748,7 @@ func encodeContextMap(context_map []uint32, context_map_size uint, num_clusters | ||||
| 	var depths [maxContextMapSymbols]byte | ||||
| 	var bits [maxContextMapSymbols]uint16 | ||||
|  | ||||
| 	storeVarLenUint8(num_clusters-1, bw) | ||||
| 	storeVarLenUint8(num_clusters-1, storage_ix, storage) | ||||
|  | ||||
| 	if num_clusters == 1 { | ||||
| 		return | ||||
| @@ -757,45 +763,45 @@ func encodeContextMap(context_map []uint32, context_map_size uint, num_clusters | ||||
| 	} | ||||
| 	{ | ||||
| 		var use_rle bool = (max_run_length_prefix > 0) | ||||
| 		bw.writeSingleBit(use_rle) | ||||
| 		writeSingleBit(use_rle, storage_ix, storage) | ||||
| 		if use_rle { | ||||
| 			bw.writeBits(4, uint64(max_run_length_prefix)-1) | ||||
| 			writeBits(4, uint64(max_run_length_prefix)-1, storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	buildAndStoreHuffmanTree(histogram[:], uint(uint32(num_clusters)+max_run_length_prefix), uint(uint32(num_clusters)+max_run_length_prefix), tree, depths[:], bits[:], bw) | ||||
| 	buildAndStoreHuffmanTree(histogram[:], uint(uint32(num_clusters)+max_run_length_prefix), uint(uint32(num_clusters)+max_run_length_prefix), tree, depths[:], bits[:], storage_ix, storage) | ||||
| 	for i = 0; i < num_rle_symbols; i++ { | ||||
| 		var rle_symbol uint32 = rle_symbols[i] & encodeContextMap_kSymbolMask | ||||
| 		var extra_bits_val uint32 = rle_symbols[i] >> symbolBits | ||||
| 		bw.writeBits(uint(depths[rle_symbol]), uint64(bits[rle_symbol])) | ||||
| 		writeBits(uint(depths[rle_symbol]), uint64(bits[rle_symbol]), storage_ix, storage) | ||||
| 		if rle_symbol > 0 && rle_symbol <= max_run_length_prefix { | ||||
| 			bw.writeBits(uint(rle_symbol), uint64(extra_bits_val)) | ||||
| 			writeBits(uint(rle_symbol), uint64(extra_bits_val), storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBits(1, 1) /* use move-to-front */ | ||||
| 	writeBits(1, 1, storage_ix, storage) /* use move-to-front */ | ||||
| 	rle_symbols = nil | ||||
| } | ||||
|  | ||||
| /* Stores the block switch command with index block_ix to the bit stream. */ | ||||
| func storeBlockSwitch(code *blockSplitCode, block_len uint32, block_type byte, is_first_block bool, bw *bitWriter) { | ||||
| func storeBlockSwitch(code *blockSplitCode, block_len uint32, block_type byte, is_first_block bool, storage_ix *uint, storage []byte) { | ||||
| 	var typecode uint = nextBlockTypeCode(&code.type_code_calculator, block_type) | ||||
| 	var lencode uint | ||||
| 	var len_nextra uint32 | ||||
| 	var len_extra uint32 | ||||
| 	if !is_first_block { | ||||
| 		bw.writeBits(uint(code.type_depths[typecode]), uint64(code.type_bits[typecode])) | ||||
| 		writeBits(uint(code.type_depths[typecode]), uint64(code.type_bits[typecode]), storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	getBlockLengthPrefixCode(block_len, &lencode, &len_nextra, &len_extra) | ||||
|  | ||||
| 	bw.writeBits(uint(code.length_depths[lencode]), uint64(code.length_bits[lencode])) | ||||
| 	bw.writeBits(uint(len_nextra), uint64(len_extra)) | ||||
| 	writeBits(uint(code.length_depths[lencode]), uint64(code.length_bits[lencode]), storage_ix, storage) | ||||
| 	writeBits(uint(len_nextra), uint64(len_extra), storage_ix, storage) | ||||
| } | ||||
|  | ||||
| /* Builds a BlockSplitCode data structure from the block split given by the | ||||
|    vector of block types and block lengths and stores it to the bit stream. */ | ||||
| func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint, num_types uint, tree []huffmanTree, code *blockSplitCode, bw *bitWriter) { | ||||
| func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint, num_types uint, tree []huffmanTree, code *blockSplitCode, storage_ix *uint, storage []byte) { | ||||
| 	var type_histo [maxBlockTypeSymbols]uint32 | ||||
| 	var length_histo [numBlockLenSymbols]uint32 | ||||
| 	var i uint | ||||
| @@ -813,17 +819,17 @@ func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint | ||||
| 		length_histo[blockLengthPrefixCode(lengths[i])]++ | ||||
| 	} | ||||
|  | ||||
| 	storeVarLenUint8(num_types-1, bw) | ||||
| 	storeVarLenUint8(num_types-1, storage_ix, storage) | ||||
| 	if num_types > 1 { /* TODO: else? could StoreBlockSwitch occur? */ | ||||
| 		buildAndStoreHuffmanTree(type_histo[0:], num_types+2, num_types+2, tree, code.type_depths[0:], code.type_bits[0:], bw) | ||||
| 		buildAndStoreHuffmanTree(length_histo[0:], numBlockLenSymbols, numBlockLenSymbols, tree, code.length_depths[0:], code.length_bits[0:], bw) | ||||
| 		storeBlockSwitch(code, lengths[0], types[0], true, bw) | ||||
| 		buildAndStoreHuffmanTree(type_histo[0:], num_types+2, num_types+2, tree, code.type_depths[0:], code.type_bits[0:], storage_ix, storage) | ||||
| 		buildAndStoreHuffmanTree(length_histo[0:], numBlockLenSymbols, numBlockLenSymbols, tree, code.length_depths[0:], code.length_bits[0:], storage_ix, storage) | ||||
| 		storeBlockSwitch(code, lengths[0], types[0], true, storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Stores a context map where the histogram type is always the block type. */ | ||||
| func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTree, bw *bitWriter) { | ||||
| 	storeVarLenUint8(num_types-1, bw) | ||||
| func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	storeVarLenUint8(num_types-1, storage_ix, storage) | ||||
| 	if num_types > 1 { | ||||
| 		var repeat_code uint = context_bits - 1 | ||||
| 		var repeat_bits uint = (1 << repeat_code) - 1 | ||||
| @@ -837,16 +843,16 @@ func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTre | ||||
| 		} | ||||
|  | ||||
| 		/* Write RLEMAX. */ | ||||
| 		bw.writeBits(1, 1) | ||||
| 		writeBits(1, 1, storage_ix, storage) | ||||
|  | ||||
| 		bw.writeBits(4, uint64(repeat_code)-1) | ||||
| 		writeBits(4, uint64(repeat_code)-1, storage_ix, storage) | ||||
| 		histogram[repeat_code] = uint32(num_types) | ||||
| 		histogram[0] = 1 | ||||
| 		for i = context_bits; i < alphabet_size; i++ { | ||||
| 			histogram[i] = 1 | ||||
| 		} | ||||
|  | ||||
| 		buildAndStoreHuffmanTree(histogram[:], alphabet_size, alphabet_size, tree, depths[:], bits[:], bw) | ||||
| 		buildAndStoreHuffmanTree(histogram[:], alphabet_size, alphabet_size, tree, depths[:], bits[:], storage_ix, storage) | ||||
| 		for i = 0; i < num_types; i++ { | ||||
| 			var tmp uint | ||||
| 			if i == 0 { | ||||
| @@ -855,13 +861,13 @@ func storeTrivialContextMap(num_types uint, context_bits uint, tree []huffmanTre | ||||
| 				tmp = i + context_bits - 1 | ||||
| 			} | ||||
| 			var code uint = tmp | ||||
| 			bw.writeBits(uint(depths[code]), uint64(bits[code])) | ||||
| 			bw.writeBits(uint(depths[repeat_code]), uint64(bits[repeat_code])) | ||||
| 			bw.writeBits(repeat_code, uint64(repeat_bits)) | ||||
| 			writeBits(uint(depths[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 			writeBits(uint(depths[repeat_code]), uint64(bits[repeat_code]), storage_ix, storage) | ||||
| 			writeBits(repeat_code, uint64(repeat_bits), storage_ix, storage) | ||||
| 		} | ||||
|  | ||||
| 		/* Write IMTF (inverse-move-to-front) bit. */ | ||||
| 		bw.writeBits(1, 1) | ||||
| 		writeBits(1, 1, storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -915,13 +921,13 @@ func cleanupBlockEncoder(self *blockEncoder) { | ||||
|  | ||||
| /* Creates entropy codes of block lengths and block types and stores them | ||||
|    to the bit stream. */ | ||||
| func buildAndStoreBlockSwitchEntropyCodes(self *blockEncoder, tree []huffmanTree, bw *bitWriter) { | ||||
| 	buildAndStoreBlockSplitCode(self.block_types_, self.block_lengths_, self.num_blocks_, self.num_block_types_, tree, &self.block_split_code_, bw) | ||||
| func buildAndStoreBlockSwitchEntropyCodes(self *blockEncoder, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	buildAndStoreBlockSplitCode(self.block_types_, self.block_lengths_, self.num_blocks_, self.num_block_types_, tree, &self.block_split_code_, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| /* Stores the next symbol with the entropy code of the current block type. | ||||
|    Updates the block type and block length at block boundaries. */ | ||||
| func storeSymbol(self *blockEncoder, symbol uint, bw *bitWriter) { | ||||
| func storeSymbol(self *blockEncoder, symbol uint, storage_ix *uint, storage []byte) { | ||||
| 	if self.block_len_ == 0 { | ||||
| 		self.block_ix_++ | ||||
| 		var block_ix uint = self.block_ix_ | ||||
| @@ -929,20 +935,20 @@ func storeSymbol(self *blockEncoder, symbol uint, bw *bitWriter) { | ||||
| 		var block_type byte = self.block_types_[block_ix] | ||||
| 		self.block_len_ = uint(block_len) | ||||
| 		self.entropy_ix_ = uint(block_type) * self.histogram_length_ | ||||
| 		storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, bw) | ||||
| 		storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	self.block_len_-- | ||||
| 	{ | ||||
| 		var ix uint = self.entropy_ix_ + symbol | ||||
| 		bw.writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix])) | ||||
| 		writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Stores the next symbol with the entropy code of the current block type and | ||||
|    context value. | ||||
|    Updates the block type and block length at block boundaries. */ | ||||
| func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, context_map []uint32, bw *bitWriter, context_bits uint) { | ||||
| func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, context_map []uint32, storage_ix *uint, storage []byte, context_bits uint) { | ||||
| 	if self.block_len_ == 0 { | ||||
| 		self.block_ix_++ | ||||
| 		var block_ix uint = self.block_ix_ | ||||
| @@ -950,18 +956,18 @@ func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, conte | ||||
| 		var block_type byte = self.block_types_[block_ix] | ||||
| 		self.block_len_ = uint(block_len) | ||||
| 		self.entropy_ix_ = uint(block_type) << context_bits | ||||
| 		storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, bw) | ||||
| 		storeBlockSwitch(&self.block_split_code_, block_len, block_type, false, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	self.block_len_-- | ||||
| 	{ | ||||
| 		var histo_ix uint = uint(context_map[self.entropy_ix_+context]) | ||||
| 		var ix uint = histo_ix*self.histogram_length_ + symbol | ||||
| 		bw.writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix])) | ||||
| 		writeBits(uint(self.depths_[ix]), uint64(self.bits_[ix]), storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func buildAndStoreEntropyCodesLiteral(self *blockEncoder, histograms []histogramLiteral, histograms_size uint, alphabet_size uint, tree []huffmanTree, bw *bitWriter) { | ||||
| func buildAndStoreEntropyCodesLiteral(self *blockEncoder, histograms []histogramLiteral, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	var table_size uint = histograms_size * self.histogram_length_ | ||||
| 	if cap(self.depths_) < int(table_size) { | ||||
| 		self.depths_ = make([]byte, table_size) | ||||
| @@ -977,12 +983,12 @@ func buildAndStoreEntropyCodesLiteral(self *blockEncoder, histograms []histogram | ||||
| 		var i uint | ||||
| 		for i = 0; i < histograms_size; i++ { | ||||
| 			var ix uint = i * self.histogram_length_ | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], bw) | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func buildAndStoreEntropyCodesCommand(self *blockEncoder, histograms []histogramCommand, histograms_size uint, alphabet_size uint, tree []huffmanTree, bw *bitWriter) { | ||||
| func buildAndStoreEntropyCodesCommand(self *blockEncoder, histograms []histogramCommand, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	var table_size uint = histograms_size * self.histogram_length_ | ||||
| 	if cap(self.depths_) < int(table_size) { | ||||
| 		self.depths_ = make([]byte, table_size) | ||||
| @@ -998,12 +1004,12 @@ func buildAndStoreEntropyCodesCommand(self *blockEncoder, histograms []histogram | ||||
| 		var i uint | ||||
| 		for i = 0; i < histograms_size; i++ { | ||||
| 			var ix uint = i * self.histogram_length_ | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], bw) | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func buildAndStoreEntropyCodesDistance(self *blockEncoder, histograms []histogramDistance, histograms_size uint, alphabet_size uint, tree []huffmanTree, bw *bitWriter) { | ||||
| func buildAndStoreEntropyCodesDistance(self *blockEncoder, histograms []histogramDistance, histograms_size uint, alphabet_size uint, tree []huffmanTree, storage_ix *uint, storage []byte) { | ||||
| 	var table_size uint = histograms_size * self.histogram_length_ | ||||
| 	if cap(self.depths_) < int(table_size) { | ||||
| 		self.depths_ = make([]byte, table_size) | ||||
| @@ -1019,12 +1025,17 @@ func buildAndStoreEntropyCodesDistance(self *blockEncoder, histograms []histogra | ||||
| 		var i uint | ||||
| 		for i = 0; i < histograms_size; i++ { | ||||
| 			var ix uint = i * self.histogram_length_ | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], bw) | ||||
| 			buildAndStoreHuffmanTree(histograms[i].data_[0:], self.histogram_length_, alphabet_size, tree, self.depths_[ix:], self.bits_[ix:], storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_byte byte, prev_byte2 byte, is_last bool, params *encoderParams, literal_context_mode int, commands []command, mb *metaBlockSplit, bw *bitWriter) { | ||||
| func jumpToByteBoundary(storage_ix *uint, storage []byte) { | ||||
| 	*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 	storage[*storage_ix>>3] = 0 | ||||
| } | ||||
|  | ||||
| func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_byte byte, prev_byte2 byte, is_last bool, params *encoderParams, literal_context_mode int, commands []command, mb *metaBlockSplit, storage_ix *uint, storage []byte) { | ||||
| 	var pos uint = start_pos | ||||
| 	var i uint | ||||
| 	var num_distance_symbols uint32 = params.dist.alphabet_size | ||||
| @@ -1036,48 +1047,48 @@ func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_b | ||||
| 		num_effective_distance_symbols = numHistogramDistanceSymbols | ||||
| 	} | ||||
|  | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, bw) | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) | ||||
|  | ||||
| 	tree = make([]huffmanTree, maxHuffmanTreeSize) | ||||
| 	literal_enc := getBlockEncoder(numLiteralSymbols, mb.literal_split.num_types, mb.literal_split.types, mb.literal_split.lengths, mb.literal_split.num_blocks) | ||||
| 	command_enc := getBlockEncoder(numCommandSymbols, mb.command_split.num_types, mb.command_split.types, mb.command_split.lengths, mb.command_split.num_blocks) | ||||
| 	distance_enc := getBlockEncoder(uint(num_effective_distance_symbols), mb.distance_split.num_types, mb.distance_split.types, mb.distance_split.lengths, mb.distance_split.num_blocks) | ||||
|  | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, bw) | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(command_enc, tree, bw) | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, bw) | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, storage_ix, storage) | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(command_enc, tree, storage_ix, storage) | ||||
| 	buildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, storage_ix, storage) | ||||
|  | ||||
| 	bw.writeBits(2, uint64(dist.distance_postfix_bits)) | ||||
| 	bw.writeBits(4, uint64(dist.num_direct_distance_codes)>>dist.distance_postfix_bits) | ||||
| 	writeBits(2, uint64(dist.distance_postfix_bits), storage_ix, storage) | ||||
| 	writeBits(4, uint64(dist.num_direct_distance_codes)>>dist.distance_postfix_bits, storage_ix, storage) | ||||
| 	for i = 0; i < mb.literal_split.num_types; i++ { | ||||
| 		bw.writeBits(2, uint64(literal_context_mode)) | ||||
| 		writeBits(2, uint64(literal_context_mode), storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	if mb.literal_context_map_size == 0 { | ||||
| 		storeTrivialContextMap(mb.literal_histograms_size, literalContextBits, tree, bw) | ||||
| 		storeTrivialContextMap(mb.literal_histograms_size, literalContextBits, tree, storage_ix, storage) | ||||
| 	} else { | ||||
| 		encodeContextMap(mb.literal_context_map, mb.literal_context_map_size, mb.literal_histograms_size, tree, bw) | ||||
| 		encodeContextMap(mb.literal_context_map, mb.literal_context_map_size, mb.literal_histograms_size, tree, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	if mb.distance_context_map_size == 0 { | ||||
| 		storeTrivialContextMap(mb.distance_histograms_size, distanceContextBits, tree, bw) | ||||
| 		storeTrivialContextMap(mb.distance_histograms_size, distanceContextBits, tree, storage_ix, storage) | ||||
| 	} else { | ||||
| 		encodeContextMap(mb.distance_context_map, mb.distance_context_map_size, mb.distance_histograms_size, tree, bw) | ||||
| 		encodeContextMap(mb.distance_context_map, mb.distance_context_map_size, mb.distance_histograms_size, tree, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	buildAndStoreEntropyCodesLiteral(literal_enc, mb.literal_histograms, mb.literal_histograms_size, numLiteralSymbols, tree, bw) | ||||
| 	buildAndStoreEntropyCodesCommand(command_enc, mb.command_histograms, mb.command_histograms_size, numCommandSymbols, tree, bw) | ||||
| 	buildAndStoreEntropyCodesDistance(distance_enc, mb.distance_histograms, mb.distance_histograms_size, uint(num_distance_symbols), tree, bw) | ||||
| 	buildAndStoreEntropyCodesLiteral(literal_enc, mb.literal_histograms, mb.literal_histograms_size, numLiteralSymbols, tree, storage_ix, storage) | ||||
| 	buildAndStoreEntropyCodesCommand(command_enc, mb.command_histograms, mb.command_histograms_size, numCommandSymbols, tree, storage_ix, storage) | ||||
| 	buildAndStoreEntropyCodesDistance(distance_enc, mb.distance_histograms, mb.distance_histograms_size, uint(num_distance_symbols), tree, storage_ix, storage) | ||||
| 	tree = nil | ||||
|  | ||||
| 	for _, cmd := range commands { | ||||
| 		var cmd_code uint = uint(cmd.cmd_prefix_) | ||||
| 		storeSymbol(command_enc, cmd_code, bw) | ||||
| 		storeCommandExtra(&cmd, bw) | ||||
| 		storeSymbol(command_enc, cmd_code, storage_ix, storage) | ||||
| 		storeCommandExtra(&cmd, storage_ix, storage) | ||||
| 		if mb.literal_context_map_size == 0 { | ||||
| 			var j uint | ||||
| 			for j = uint(cmd.insert_len_); j != 0; j-- { | ||||
| 				storeSymbol(literal_enc, uint(input[pos&mask]), bw) | ||||
| 				storeSymbol(literal_enc, uint(input[pos&mask]), storage_ix, storage) | ||||
| 				pos++ | ||||
| 			} | ||||
| 		} else { | ||||
| @@ -1085,7 +1096,7 @@ func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_b | ||||
| 			for j = uint(cmd.insert_len_); j != 0; j-- { | ||||
| 				var context uint = uint(getContext(prev_byte, prev_byte2, literal_context_lut)) | ||||
| 				var literal byte = input[pos&mask] | ||||
| 				storeSymbolWithContext(literal_enc, uint(literal), context, mb.literal_context_map, bw, literalContextBits) | ||||
| 				storeSymbolWithContext(literal_enc, uint(literal), context, mb.literal_context_map, storage_ix, storage, literalContextBits) | ||||
| 				prev_byte2 = prev_byte | ||||
| 				prev_byte = literal | ||||
| 				pos++ | ||||
| @@ -1101,13 +1112,13 @@ func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_b | ||||
| 				var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 | ||||
| 				var distextra uint64 = uint64(cmd.dist_extra_) | ||||
| 				if mb.distance_context_map_size == 0 { | ||||
| 					storeSymbol(distance_enc, dist_code, bw) | ||||
| 					storeSymbol(distance_enc, dist_code, storage_ix, storage) | ||||
| 				} else { | ||||
| 					var context uint = uint(commandDistanceContext(&cmd)) | ||||
| 					storeSymbolWithContext(distance_enc, dist_code, context, mb.distance_context_map, bw, distanceContextBits) | ||||
| 					storeSymbolWithContext(distance_enc, dist_code, context, mb.distance_context_map, storage_ix, storage, distanceContextBits) | ||||
| 				} | ||||
|  | ||||
| 				bw.writeBits(uint(distnumextra), distextra) | ||||
| 				writeBits(uint(distnumextra), distextra, storage_ix, storage) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -1116,7 +1127,7 @@ func storeMetaBlock(input []byte, start_pos uint, length uint, mask uint, prev_b | ||||
| 	cleanupBlockEncoder(command_enc) | ||||
| 	cleanupBlockEncoder(literal_enc) | ||||
| 	if is_last { | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		jumpToByteBoundary(storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1137,16 +1148,16 @@ func buildHistograms(input []byte, start_pos uint, mask uint, commands []command | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeDataWithHuffmanCodes(input []byte, start_pos uint, mask uint, commands []command, lit_depth []byte, lit_bits []uint16, cmd_depth []byte, cmd_bits []uint16, dist_depth []byte, dist_bits []uint16, bw *bitWriter) { | ||||
| func storeDataWithHuffmanCodes(input []byte, start_pos uint, mask uint, commands []command, lit_depth []byte, lit_bits []uint16, cmd_depth []byte, cmd_bits []uint16, dist_depth []byte, dist_bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var pos uint = start_pos | ||||
| 	for _, cmd := range commands { | ||||
| 		var cmd_code uint = uint(cmd.cmd_prefix_) | ||||
| 		var j uint | ||||
| 		bw.writeBits(uint(cmd_depth[cmd_code]), uint64(cmd_bits[cmd_code])) | ||||
| 		storeCommandExtra(&cmd, bw) | ||||
| 		writeBits(uint(cmd_depth[cmd_code]), uint64(cmd_bits[cmd_code]), storage_ix, storage) | ||||
| 		storeCommandExtra(&cmd, storage_ix, storage) | ||||
| 		for j = uint(cmd.insert_len_); j != 0; j-- { | ||||
| 			var literal byte = input[pos&mask] | ||||
| 			bw.writeBits(uint(lit_depth[literal]), uint64(lit_bits[literal])) | ||||
| 			writeBits(uint(lit_depth[literal]), uint64(lit_bits[literal]), storage_ix, storage) | ||||
| 			pos++ | ||||
| 		} | ||||
|  | ||||
| @@ -1155,13 +1166,13 @@ func storeDataWithHuffmanCodes(input []byte, start_pos uint, mask uint, commands | ||||
| 			var dist_code uint = uint(cmd.dist_prefix_) & 0x3FF | ||||
| 			var distnumextra uint32 = uint32(cmd.dist_prefix_) >> 10 | ||||
| 			var distextra uint32 = cmd.dist_extra_ | ||||
| 			bw.writeBits(uint(dist_depth[dist_code]), uint64(dist_bits[dist_code])) | ||||
| 			bw.writeBits(uint(distnumextra), uint64(distextra)) | ||||
| 			writeBits(uint(dist_depth[dist_code]), uint64(dist_bits[dist_code]), storage_ix, storage) | ||||
| 			writeBits(uint(distnumextra), uint64(distextra), storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, bw *bitWriter) { | ||||
| func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { | ||||
| 	var lit_histo histogramLiteral | ||||
| 	var cmd_histo histogramCommand | ||||
| 	var dist_histo histogramDistance | ||||
| @@ -1174,7 +1185,7 @@ func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, | ||||
| 	var tree []huffmanTree | ||||
| 	var num_distance_symbols uint32 = params.dist.alphabet_size | ||||
|  | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, bw) | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) | ||||
|  | ||||
| 	histogramClearLiteral(&lit_histo) | ||||
| 	histogramClearCommand(&cmd_histo) | ||||
| @@ -1182,26 +1193,26 @@ func storeMetaBlockTrivial(input []byte, start_pos uint, length uint, mask uint, | ||||
|  | ||||
| 	buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) | ||||
|  | ||||
| 	bw.writeBits(13, 0) | ||||
| 	writeBits(13, 0, storage_ix, storage) | ||||
|  | ||||
| 	tree = make([]huffmanTree, maxHuffmanTreeSize) | ||||
| 	buildAndStoreHuffmanTree(lit_histo.data_[:], numLiteralSymbols, numLiteralSymbols, tree, lit_depth[:], lit_bits[:], bw) | ||||
| 	buildAndStoreHuffmanTree(cmd_histo.data_[:], numCommandSymbols, numCommandSymbols, tree, cmd_depth[:], cmd_bits[:], bw) | ||||
| 	buildAndStoreHuffmanTree(dist_histo.data_[:], maxSimpleDistanceAlphabetSize, uint(num_distance_symbols), tree, dist_depth[:], dist_bits[:], bw) | ||||
| 	buildAndStoreHuffmanTree(lit_histo.data_[:], numLiteralSymbols, numLiteralSymbols, tree, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 	buildAndStoreHuffmanTree(cmd_histo.data_[:], numCommandSymbols, numCommandSymbols, tree, cmd_depth[:], cmd_bits[:], storage_ix, storage) | ||||
| 	buildAndStoreHuffmanTree(dist_histo.data_[:], maxSimpleDistanceAlphabetSize, uint(num_distance_symbols), tree, dist_depth[:], dist_bits[:], storage_ix, storage) | ||||
| 	tree = nil | ||||
| 	storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], bw) | ||||
| 	storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) | ||||
| 	if is_last { | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		jumpToByteBoundary(storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, bw *bitWriter) { | ||||
| func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is_last bool, params *encoderParams, commands []command, storage_ix *uint, storage []byte) { | ||||
| 	var num_distance_symbols uint32 = params.dist.alphabet_size | ||||
| 	var distance_alphabet_bits uint32 = log2FloorNonZero(uint(num_distance_symbols-1)) + 1 | ||||
|  | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, bw) | ||||
| 	storeCompressedMetaBlockHeader(is_last, length, storage_ix, storage) | ||||
|  | ||||
| 	bw.writeBits(13, 0) | ||||
| 	writeBits(13, 0, storage_ix, storage) | ||||
|  | ||||
| 	if len(commands) <= 128 { | ||||
| 		var histogram = [numLiteralSymbols]uint32{0} | ||||
| @@ -1221,11 +1232,11 @@ func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is | ||||
| 		} | ||||
|  | ||||
| 		buildAndStoreHuffmanTreeFast(histogram[:], num_literals, /* max_bits = */ | ||||
| 			8, lit_depth[:], lit_bits[:], bw) | ||||
| 			8, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
|  | ||||
| 		storeStaticCommandHuffmanTree(bw) | ||||
| 		storeStaticDistanceHuffmanTree(bw) | ||||
| 		storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], kStaticCommandCodeDepth[:], kStaticCommandCodeBits[:], kStaticDistanceCodeDepth[:], kStaticDistanceCodeBits[:], bw) | ||||
| 		storeStaticCommandHuffmanTree(storage_ix, storage) | ||||
| 		storeStaticDistanceHuffmanTree(storage_ix, storage) | ||||
| 		storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], kStaticCommandCodeDepth[:], kStaticCommandCodeBits[:], kStaticDistanceCodeDepth[:], kStaticDistanceCodeBits[:], storage_ix, storage) | ||||
| 	} else { | ||||
| 		var lit_histo histogramLiteral | ||||
| 		var cmd_histo histogramCommand | ||||
| @@ -1241,43 +1252,49 @@ func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is | ||||
| 		histogramClearDistance(&dist_histo) | ||||
| 		buildHistograms(input, start_pos, mask, commands, &lit_histo, &cmd_histo, &dist_histo) | ||||
| 		buildAndStoreHuffmanTreeFast(lit_histo.data_[:], lit_histo.total_count_, /* max_bits = */ | ||||
| 			8, lit_depth[:], lit_bits[:], bw) | ||||
| 			8, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
|  | ||||
| 		buildAndStoreHuffmanTreeFast(cmd_histo.data_[:], cmd_histo.total_count_, /* max_bits = */ | ||||
| 			10, cmd_depth[:], cmd_bits[:], bw) | ||||
| 			10, cmd_depth[:], cmd_bits[:], storage_ix, storage) | ||||
|  | ||||
| 		buildAndStoreHuffmanTreeFast(dist_histo.data_[:], dist_histo.total_count_, /* max_bits = */ | ||||
| 			uint(distance_alphabet_bits), dist_depth[:], dist_bits[:], bw) | ||||
| 			uint(distance_alphabet_bits), dist_depth[:], dist_bits[:], storage_ix, storage) | ||||
|  | ||||
| 		storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], bw) | ||||
| 		storeDataWithHuffmanCodes(input, start_pos, mask, commands, lit_depth[:], lit_bits[:], cmd_depth[:], cmd_bits[:], dist_depth[:], dist_bits[:], storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	if is_last { | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		jumpToByteBoundary(storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* This is for storing uncompressed blocks (simple raw storage of | ||||
|    bytes-as-bytes). */ | ||||
| func storeUncompressedMetaBlock(is_final_block bool, input []byte, position uint, mask uint, len uint, bw *bitWriter) { | ||||
| func storeUncompressedMetaBlock(is_final_block bool, input []byte, position uint, mask uint, len uint, storage_ix *uint, storage []byte) { | ||||
| 	var masked_pos uint = position & mask | ||||
| 	storeUncompressedMetaBlockHeader(uint(len), bw) | ||||
| 	bw.jumpToByteBoundary() | ||||
| 	storeUncompressedMetaBlockHeader(uint(len), storage_ix, storage) | ||||
| 	jumpToByteBoundary(storage_ix, storage) | ||||
|  | ||||
| 	if masked_pos+len > mask+1 { | ||||
| 		var len1 uint = mask + 1 - masked_pos | ||||
| 		bw.writeBytes(input[masked_pos:][:len1]) | ||||
| 		copy(storage[*storage_ix>>3:], input[masked_pos:][:len1]) | ||||
| 		*storage_ix += len1 << 3 | ||||
| 		len -= len1 | ||||
| 		masked_pos = 0 | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBytes(input[masked_pos:][:len]) | ||||
| 	copy(storage[*storage_ix>>3:], input[masked_pos:][:len]) | ||||
| 	*storage_ix += uint(len << 3) | ||||
|  | ||||
| 	/* We need to clear the next 4 bytes to continue to be | ||||
| 	   compatible with BrotliWriteBits. */ | ||||
| 	writeBitsPrepareStorage(*storage_ix, storage) | ||||
|  | ||||
| 	/* Since the uncompressed block itself may not be the final block, add an | ||||
| 	   empty one after this. */ | ||||
| 	if is_final_block { | ||||
| 		bw.writeBits(1, 1) /* islast */ | ||||
| 		bw.writeBits(1, 1) /* isempty */ | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		writeBits(1, 1, storage_ix, storage) /* islast */ | ||||
| 		writeBits(1, 1, storage_ix, storage) /* isempty */ | ||||
| 		jumpToByteBoundary(storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										355
									
								
								vendor/github.com/andybalholm/brotli/compress_fragment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										355
									
								
								vendor/github.com/andybalholm/brotli/compress_fragment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -45,7 +45,7 @@ func isMatch5(p1 []byte, p2 []byte) bool { | ||||
|    and thus have to assign a non-zero depth for each literal. | ||||
|    Returns estimated compression ratio millibytes/char for encoding given input | ||||
|    with generated code. */ | ||||
| func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte, bits []uint16, bw *bitWriter) uint { | ||||
| func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte, bits []uint16, storage_ix *uint, storage []byte) uint { | ||||
| 	var histogram = [256]uint32{0} | ||||
| 	var histogram_total uint | ||||
| 	var i uint | ||||
| @@ -82,7 +82,7 @@ func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte | ||||
| 	} | ||||
|  | ||||
| 	buildAndStoreHuffmanTreeFast(histogram[:], histogram_total, /* max_bits = */ | ||||
| 		8, depths, bits, bw) | ||||
| 		8, depths, bits, storage_ix, storage) | ||||
| 	{ | ||||
| 		var literal_ratio uint = 0 | ||||
| 		for i = 0; i < 256; i++ { | ||||
| @@ -98,7 +98,7 @@ func buildAndStoreLiteralPrefixCode(input []byte, input_size uint, depths []byte | ||||
|  | ||||
| /* Builds a command and distance prefix code (each 64 symbols) into "depth" and | ||||
|    "bits" based on "histogram" and stores it into the bit stream. */ | ||||
| func buildAndStoreCommandPrefixCode1(histogram []uint32, depth []byte, bits []uint16, bw *bitWriter) { | ||||
| func buildAndStoreCommandPrefixCode1(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var tree [129]huffmanTree | ||||
| 	var cmd_depth = [numCommandSymbols]byte{0} | ||||
| 	/* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ | ||||
| @@ -145,141 +145,141 @@ func buildAndStoreCommandPrefixCode1(histogram []uint32, depth []byte, bits []ui | ||||
| 			cmd_depth[448+8*i] = depth[56+i] | ||||
| 		} | ||||
|  | ||||
| 		storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], bw) | ||||
| 		storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	storeHuffmanTree(depth[64:], 64, tree[:], bw) | ||||
| 	storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) | ||||
| } | ||||
|  | ||||
| /* REQUIRES: insertlen < 6210 */ | ||||
| func emitInsertLen1(insertlen uint, depth []byte, bits []uint16, histo []uint32, bw *bitWriter) { | ||||
| func emitInsertLen1(insertlen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { | ||||
| 	if insertlen < 6 { | ||||
| 		var code uint = insertlen + 40 | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 	} else if insertlen < 130 { | ||||
| 		var tail uint = insertlen - 2 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) - 1 | ||||
| 		var prefix uint = tail >> nbits | ||||
| 		var inscode uint = uint((nbits << 1) + uint32(prefix) + 42) | ||||
| 		bw.writeBits(uint(depth[inscode]), uint64(bits[inscode])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits)) | ||||
| 		writeBits(uint(depth[inscode]), uint64(bits[inscode]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits), storage_ix, storage) | ||||
| 		histo[inscode]++ | ||||
| 	} else if insertlen < 2114 { | ||||
| 		var tail uint = insertlen - 66 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) | ||||
| 		var code uint = uint(nbits + 50) | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits)) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 	} else { | ||||
| 		bw.writeBits(uint(depth[61]), uint64(bits[61])) | ||||
| 		bw.writeBits(12, uint64(insertlen)-2114) | ||||
| 		writeBits(uint(depth[61]), uint64(bits[61]), storage_ix, storage) | ||||
| 		writeBits(12, uint64(insertlen)-2114, storage_ix, storage) | ||||
| 		histo[61]++ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitLongInsertLen(insertlen uint, depth []byte, bits []uint16, histo []uint32, bw *bitWriter) { | ||||
| func emitLongInsertLen(insertlen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { | ||||
| 	if insertlen < 22594 { | ||||
| 		bw.writeBits(uint(depth[62]), uint64(bits[62])) | ||||
| 		bw.writeBits(14, uint64(insertlen)-6210) | ||||
| 		writeBits(uint(depth[62]), uint64(bits[62]), storage_ix, storage) | ||||
| 		writeBits(14, uint64(insertlen)-6210, storage_ix, storage) | ||||
| 		histo[62]++ | ||||
| 	} else { | ||||
| 		bw.writeBits(uint(depth[63]), uint64(bits[63])) | ||||
| 		bw.writeBits(24, uint64(insertlen)-22594) | ||||
| 		writeBits(uint(depth[63]), uint64(bits[63]), storage_ix, storage) | ||||
| 		writeBits(24, uint64(insertlen)-22594, storage_ix, storage) | ||||
| 		histo[63]++ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitCopyLen1(copylen uint, depth []byte, bits []uint16, histo []uint32, bw *bitWriter) { | ||||
| func emitCopyLen1(copylen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { | ||||
| 	if copylen < 10 { | ||||
| 		bw.writeBits(uint(depth[copylen+14]), uint64(bits[copylen+14])) | ||||
| 		writeBits(uint(depth[copylen+14]), uint64(bits[copylen+14]), storage_ix, storage) | ||||
| 		histo[copylen+14]++ | ||||
| 	} else if copylen < 134 { | ||||
| 		var tail uint = copylen - 6 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) - 1 | ||||
| 		var prefix uint = tail >> nbits | ||||
| 		var code uint = uint((nbits << 1) + uint32(prefix) + 20) | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits)) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 	} else if copylen < 2118 { | ||||
| 		var tail uint = copylen - 70 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) | ||||
| 		var code uint = uint(nbits + 28) | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits)) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 	} else { | ||||
| 		bw.writeBits(uint(depth[39]), uint64(bits[39])) | ||||
| 		bw.writeBits(24, uint64(copylen)-2118) | ||||
| 		writeBits(uint(depth[39]), uint64(bits[39]), storage_ix, storage) | ||||
| 		writeBits(24, uint64(copylen)-2118, storage_ix, storage) | ||||
| 		histo[39]++ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitCopyLenLastDistance1(copylen uint, depth []byte, bits []uint16, histo []uint32, bw *bitWriter) { | ||||
| func emitCopyLenLastDistance1(copylen uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { | ||||
| 	if copylen < 12 { | ||||
| 		bw.writeBits(uint(depth[copylen-4]), uint64(bits[copylen-4])) | ||||
| 		writeBits(uint(depth[copylen-4]), uint64(bits[copylen-4]), storage_ix, storage) | ||||
| 		histo[copylen-4]++ | ||||
| 	} else if copylen < 72 { | ||||
| 		var tail uint = copylen - 8 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) - 1 | ||||
| 		var prefix uint = tail >> nbits | ||||
| 		var code uint = uint((nbits << 1) + uint32(prefix) + 4) | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits)) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(prefix)<<nbits), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 	} else if copylen < 136 { | ||||
| 		var tail uint = copylen - 8 | ||||
| 		var code uint = (tail >> 5) + 30 | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(5, uint64(tail)&31) | ||||
| 		bw.writeBits(uint(depth[64]), uint64(bits[64])) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(5, uint64(tail)&31, storage_ix, storage) | ||||
| 		writeBits(uint(depth[64]), uint64(bits[64]), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 		histo[64]++ | ||||
| 	} else if copylen < 2120 { | ||||
| 		var tail uint = copylen - 72 | ||||
| 		var nbits uint32 = log2FloorNonZero(tail) | ||||
| 		var code uint = uint(nbits + 28) | ||||
| 		bw.writeBits(uint(depth[code]), uint64(bits[code])) | ||||
| 		bw.writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits)) | ||||
| 		bw.writeBits(uint(depth[64]), uint64(bits[64])) | ||||
| 		writeBits(uint(depth[code]), uint64(bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(nbits), uint64(tail)-(uint64(uint(1))<<nbits), storage_ix, storage) | ||||
| 		writeBits(uint(depth[64]), uint64(bits[64]), storage_ix, storage) | ||||
| 		histo[code]++ | ||||
| 		histo[64]++ | ||||
| 	} else { | ||||
| 		bw.writeBits(uint(depth[39]), uint64(bits[39])) | ||||
| 		bw.writeBits(24, uint64(copylen)-2120) | ||||
| 		bw.writeBits(uint(depth[64]), uint64(bits[64])) | ||||
| 		writeBits(uint(depth[39]), uint64(bits[39]), storage_ix, storage) | ||||
| 		writeBits(24, uint64(copylen)-2120, storage_ix, storage) | ||||
| 		writeBits(uint(depth[64]), uint64(bits[64]), storage_ix, storage) | ||||
| 		histo[39]++ | ||||
| 		histo[64]++ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitDistance1(distance uint, depth []byte, bits []uint16, histo []uint32, bw *bitWriter) { | ||||
| func emitDistance1(distance uint, depth []byte, bits []uint16, histo []uint32, storage_ix *uint, storage []byte) { | ||||
| 	var d uint = distance + 3 | ||||
| 	var nbits uint32 = log2FloorNonZero(d) - 1 | ||||
| 	var prefix uint = (d >> nbits) & 1 | ||||
| 	var offset uint = (2 + prefix) << nbits | ||||
| 	var distcode uint = uint(2*(nbits-1) + uint32(prefix) + 80) | ||||
| 	bw.writeBits(uint(depth[distcode]), uint64(bits[distcode])) | ||||
| 	bw.writeBits(uint(nbits), uint64(d)-uint64(offset)) | ||||
| 	writeBits(uint(depth[distcode]), uint64(bits[distcode]), storage_ix, storage) | ||||
| 	writeBits(uint(nbits), uint64(d)-uint64(offset), storage_ix, storage) | ||||
| 	histo[distcode]++ | ||||
| } | ||||
|  | ||||
| func emitLiterals(input []byte, len uint, depth []byte, bits []uint16, bw *bitWriter) { | ||||
| func emitLiterals(input []byte, len uint, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var j uint | ||||
| 	for j = 0; j < len; j++ { | ||||
| 		var lit byte = input[j] | ||||
| 		bw.writeBits(uint(depth[lit]), uint64(bits[lit])) | ||||
| 		writeBits(uint(depth[lit]), uint64(bits[lit]), storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* REQUIRES: len <= 1 << 24. */ | ||||
| func storeMetaBlockHeader1(len uint, is_uncompressed bool, bw *bitWriter) { | ||||
| func storeMetaBlockHeader1(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { | ||||
| 	var nibbles uint = 6 | ||||
|  | ||||
| 	/* ISLAST */ | ||||
| 	bw.writeBits(1, 0) | ||||
| 	writeBits(1, 0, storage_ix, storage) | ||||
|  | ||||
| 	if len <= 1<<16 { | ||||
| 		nibbles = 4 | ||||
| @@ -287,11 +287,34 @@ func storeMetaBlockHeader1(len uint, is_uncompressed bool, bw *bitWriter) { | ||||
| 		nibbles = 5 | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBits(2, uint64(nibbles)-4) | ||||
| 	bw.writeBits(nibbles*4, uint64(len)-1) | ||||
| 	writeBits(2, uint64(nibbles)-4, storage_ix, storage) | ||||
| 	writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) | ||||
|  | ||||
| 	/* ISUNCOMPRESSED */ | ||||
| 	bw.writeSingleBit(is_uncompressed) | ||||
| 	writeSingleBit(is_uncompressed, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| func updateBits(n_bits uint, bits uint32, pos uint, array []byte) { | ||||
| 	for n_bits > 0 { | ||||
| 		var byte_pos uint = pos >> 3 | ||||
| 		var n_unchanged_bits uint = pos & 7 | ||||
| 		var n_changed_bits uint = brotli_min_size_t(n_bits, 8-n_unchanged_bits) | ||||
| 		var total_bits uint = n_unchanged_bits + n_changed_bits | ||||
| 		var mask uint32 = (^((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1) | ||||
| 		var unchanged_bits uint32 = uint32(array[byte_pos]) & mask | ||||
| 		var changed_bits uint32 = bits & ((1 << n_changed_bits) - 1) | ||||
| 		array[byte_pos] = byte(changed_bits<<n_unchanged_bits | unchanged_bits) | ||||
| 		n_bits -= n_changed_bits | ||||
| 		bits >>= n_changed_bits | ||||
| 		pos += n_changed_bits | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func rewindBitPosition1(new_storage_ix uint, storage_ix *uint, storage []byte) { | ||||
| 	var bitpos uint = new_storage_ix & 7 | ||||
| 	var mask uint = (1 << bitpos) - 1 | ||||
| 	storage[new_storage_ix>>3] &= byte(mask) | ||||
| 	*storage_ix = new_storage_ix | ||||
| } | ||||
|  | ||||
| var shouldMergeBlock_kSampleRate uint = 43 | ||||
| @@ -322,26 +345,151 @@ func shouldUseUncompressedMode(metablock_start []byte, next_emit []byte, insertl | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitUncompressedMetaBlock1(data []byte, storage_ix_start uint, bw *bitWriter) { | ||||
| 	bw.rewind(storage_ix_start) | ||||
| 	storeMetaBlockHeader1(uint(len(data)), true, bw) | ||||
| 	bw.jumpToByteBoundary() | ||||
| 	bw.writeBytes(data) | ||||
| func emitUncompressedMetaBlock1(begin []byte, end []byte, storage_ix_start uint, storage_ix *uint, storage []byte) { | ||||
| 	var len uint = uint(-cap(end) + cap(begin)) | ||||
| 	rewindBitPosition1(storage_ix_start, storage_ix, storage) | ||||
| 	storeMetaBlockHeader1(uint(len), true, storage_ix, storage) | ||||
| 	*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 	copy(storage[*storage_ix>>3:], begin[:len]) | ||||
| 	*storage_ix += uint(len << 3) | ||||
| 	storage[*storage_ix>>3] = 0 | ||||
| } | ||||
|  | ||||
| var kCmdHistoSeed = [128]uint32{ | ||||
| 	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, | ||||
| 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, | ||||
| 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, | ||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||||
| 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||||
| 	1, 1, 1, 1, 0, 0, 0, 0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	1, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| } | ||||
|  | ||||
| var compressFragmentFastImpl_kFirstBlockSize uint = 3 << 15 | ||||
| var compressFragmentFastImpl_kMergeBlockSize uint = 1 << 16 | ||||
|  | ||||
| func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table []int, table_bits uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, bw *bitWriter) { | ||||
| func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table []int, table_bits uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { | ||||
| 	var cmd_histo [128]uint32 | ||||
| 	var ip_end int | ||||
| 	var next_emit int = 0 | ||||
| @@ -352,7 +500,7 @@ func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table [] | ||||
| 	var metablock_start int = input | ||||
| 	var block_size uint = brotli_min_size_t(input_size, compressFragmentFastImpl_kFirstBlockSize) | ||||
| 	var total_block_size uint = block_size | ||||
| 	var mlen_storage_ix uint = bw.getPos() + 3 | ||||
| 	var mlen_storage_ix uint = *storage_ix + 3 | ||||
| 	var lit_depth [256]byte | ||||
| 	var lit_bits [256]uint16 | ||||
| 	var literal_ratio uint | ||||
| @@ -369,21 +517,21 @@ func compressFragmentFastImpl(in []byte, input_size uint, is_last bool, table [] | ||||
|  | ||||
| 	/* Save the bit position of the MLEN field of the meta-block header, so that | ||||
| 	   we can update it later if we decide to extend this meta-block. */ | ||||
| 	storeMetaBlockHeader1(block_size, false, bw) | ||||
| 	storeMetaBlockHeader1(block_size, false, storage_ix, storage) | ||||
|  | ||||
| 	/* No block splits, no contexts. */ | ||||
| 	bw.writeBits(13, 0) | ||||
| 	writeBits(13, 0, storage_ix, storage) | ||||
|  | ||||
| 	literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], bw) | ||||
| 	literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 	{ | ||||
| 		/* Store the pre-compressed command and distance prefix codes. */ | ||||
| 		var i uint | ||||
| 		for i = 0; i+7 < *cmd_code_numbits; i += 8 { | ||||
| 			bw.writeBits(8, uint64(cmd_code[i>>3])) | ||||
| 			writeBits(8, uint64(cmd_code[i>>3]), storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBits(*cmd_code_numbits&7, uint64(cmd_code[*cmd_code_numbits>>3])) | ||||
| 	writeBits(*cmd_code_numbits&7, uint64(cmd_code[*cmd_code_numbits>>3]), storage_ix, storage) | ||||
|  | ||||
| 	/* Initialize the command and distance histograms. We will gather | ||||
| 	   statistics of command and distance codes during the processing | ||||
| @@ -482,27 +630,27 @@ emit_commands: | ||||
| 				var insert uint = uint(base - next_emit) | ||||
| 				ip += int(matched) | ||||
| 				if insert < 6210 { | ||||
| 					emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 					emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 				} else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { | ||||
| 					emitUncompressedMetaBlock1(in[metablock_start:base], mlen_storage_ix-3, bw) | ||||
| 					emitUncompressedMetaBlock1(in[metablock_start:], in[base:], mlen_storage_ix-3, storage_ix, storage) | ||||
| 					input_size -= uint(base - input) | ||||
| 					input = base | ||||
| 					next_emit = input | ||||
| 					goto next_block | ||||
| 				} else { | ||||
| 					emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 					emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 				} | ||||
|  | ||||
| 				emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], bw) | ||||
| 				emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 				if distance == last_distance { | ||||
| 					bw.writeBits(uint(cmd_depth[64]), uint64(cmd_bits[64])) | ||||
| 					writeBits(uint(cmd_depth[64]), uint64(cmd_bits[64]), storage_ix, storage) | ||||
| 					cmd_histo[64]++ | ||||
| 				} else { | ||||
| 					emitDistance1(uint(distance), cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 					emitDistance1(uint(distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 					last_distance = distance | ||||
| 				} | ||||
|  | ||||
| 				emitCopyLenLastDistance1(matched, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 				emitCopyLenLastDistance1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
|  | ||||
| 				next_emit = ip | ||||
| 				if ip >= ip_limit { | ||||
| @@ -538,8 +686,8 @@ emit_commands: | ||||
| 				} | ||||
| 				ip += int(matched) | ||||
| 				last_distance = int(base - candidate) /* > 0 */ | ||||
| 				emitCopyLen1(matched, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 				emitDistance1(uint(last_distance), cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 				emitCopyLen1(matched, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 				emitDistance1(uint(last_distance), cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
|  | ||||
| 				next_emit = ip | ||||
| 				if ip >= ip_limit { | ||||
| @@ -585,7 +733,7 @@ emit_remainder: | ||||
| 		   nibbles. */ | ||||
| 		total_block_size += block_size | ||||
|  | ||||
| 		bw.updateBits(20, uint32(total_block_size-1), mlen_storage_ix) | ||||
| 		updateBits(20, uint32(total_block_size-1), mlen_storage_ix, storage) | ||||
| 		goto emit_commands | ||||
| 	} | ||||
|  | ||||
| @@ -593,13 +741,13 @@ emit_remainder: | ||||
| 	if next_emit < ip_end { | ||||
| 		var insert uint = uint(ip_end - next_emit) | ||||
| 		if insert < 6210 { | ||||
| 			emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 			emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], bw) | ||||
| 			emitInsertLen1(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 			emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 		} else if shouldUseUncompressedMode(in[metablock_start:], in[next_emit:], insert, literal_ratio) { | ||||
| 			emitUncompressedMetaBlock1(in[metablock_start:ip_end], mlen_storage_ix-3, bw) | ||||
| 			emitUncompressedMetaBlock1(in[metablock_start:], in[ip_end:], mlen_storage_ix-3, storage_ix, storage) | ||||
| 		} else { | ||||
| 			emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], bw) | ||||
| 			emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], bw) | ||||
| 			emitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo[:], storage_ix, storage) | ||||
| 			emitLiterals(in[next_emit:], insert, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -615,29 +763,30 @@ next_block: | ||||
|  | ||||
| 		/* Save the bit position of the MLEN field of the meta-block header, so that | ||||
| 		   we can update it later if we decide to extend this meta-block. */ | ||||
| 		mlen_storage_ix = bw.getPos() + 3 | ||||
| 		mlen_storage_ix = *storage_ix + 3 | ||||
|  | ||||
| 		storeMetaBlockHeader1(block_size, false, bw) | ||||
| 		storeMetaBlockHeader1(block_size, false, storage_ix, storage) | ||||
|  | ||||
| 		/* No block splits, no contexts. */ | ||||
| 		bw.writeBits(13, 0) | ||||
| 		writeBits(13, 0, storage_ix, storage) | ||||
|  | ||||
| 		literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], bw) | ||||
| 		buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, bw) | ||||
| 		literal_ratio = buildAndStoreLiteralPrefixCode(in[input:], block_size, lit_depth[:], lit_bits[:], storage_ix, storage) | ||||
| 		buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, storage_ix, storage) | ||||
| 		goto emit_commands | ||||
| 	} | ||||
|  | ||||
| 	if !is_last { | ||||
| 		/* If this is not the last block, update the command and distance prefix | ||||
| 		   codes for the next block and store the compressed forms. */ | ||||
| 		var bw bitWriter | ||||
| 		bw.dst = cmd_code | ||||
| 		buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, &bw) | ||||
| 		*cmd_code_numbits = bw.getPos() | ||||
| 		cmd_code[0] = 0 | ||||
|  | ||||
| 		*cmd_code_numbits = 0 | ||||
| 		buildAndStoreCommandPrefixCode1(cmd_histo[:], cmd_depth, cmd_bits, cmd_code_numbits, cmd_code) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Compresses "input" string to bw as one or more complete meta-blocks. | ||||
| /* Compresses "input" string to the "*storage" buffer as one or more complete | ||||
|    meta-blocks, and updates the "*storage_ix" bit position. | ||||
|  | ||||
|    If "is_last" is 1, emits an additional empty last meta-block. | ||||
|  | ||||
| @@ -658,28 +807,28 @@ next_block: | ||||
|    REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two | ||||
|    OUTPUT: maximal copy distance <= |input_size| | ||||
|    OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ | ||||
| func compressFragmentFast(input []byte, input_size uint, is_last bool, table []int, table_size uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, bw *bitWriter) { | ||||
| 	var initial_storage_ix uint = bw.getPos() | ||||
| func compressFragmentFast(input []byte, input_size uint, is_last bool, table []int, table_size uint, cmd_depth []byte, cmd_bits []uint16, cmd_code_numbits *uint, cmd_code []byte, storage_ix *uint, storage []byte) { | ||||
| 	var initial_storage_ix uint = *storage_ix | ||||
| 	var table_bits uint = uint(log2FloorNonZero(table_size)) | ||||
|  | ||||
| 	if input_size == 0 { | ||||
| 		assert(is_last) | ||||
| 		bw.writeBits(1, 1) /* islast */ | ||||
| 		bw.writeBits(1, 1) /* isempty */ | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		writeBits(1, 1, storage_ix, storage) /* islast */ | ||||
| 		writeBits(1, 1, storage_ix, storage) /* isempty */ | ||||
| 		*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	compressFragmentFastImpl(input, input_size, is_last, table, table_bits, cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, bw) | ||||
| 	compressFragmentFastImpl(input, input_size, is_last, table, table_bits, cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage) | ||||
|  | ||||
| 	/* If output is larger than single uncompressed block, rewrite it. */ | ||||
| 	if bw.getPos()-initial_storage_ix > 31+(input_size<<3) { | ||||
| 		emitUncompressedMetaBlock1(input[:input_size], initial_storage_ix, bw) | ||||
| 	if *storage_ix-initial_storage_ix > 31+(input_size<<3) { | ||||
| 		emitUncompressedMetaBlock1(input, input[input_size:], initial_storage_ix, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	if is_last { | ||||
| 		bw.writeBits(1, 1) /* islast */ | ||||
| 		bw.writeBits(1, 1) /* isempty */ | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		writeBits(1, 1, storage_ix, storage) /* islast */ | ||||
| 		writeBits(1, 1, storage_ix, storage) /* isempty */ | ||||
| 		*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										237
									
								
								vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										237
									
								
								vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -41,7 +41,7 @@ func isMatch1(p1 []byte, p2 []byte, length uint) bool { | ||||
|  | ||||
| /* Builds a command and distance prefix code (each 64 symbols) into "depth" and | ||||
|    "bits" based on "histogram" and stores it into the bit stream. */ | ||||
| func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uint16, bw *bitWriter) { | ||||
| func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) { | ||||
| 	var tree [129]huffmanTree | ||||
| 	var cmd_depth = [numCommandSymbols]byte{0} | ||||
| 	/* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ | ||||
| @@ -87,10 +87,10 @@ func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uin | ||||
| 			cmd_depth[448+8*i] = depth[16+i] | ||||
| 		} | ||||
|  | ||||
| 		storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], bw) | ||||
| 		storeHuffmanTree(cmd_depth[:], numCommandSymbols, tree[:], storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	storeHuffmanTree(depth[64:], 64, tree[:], bw) | ||||
| 	storeHuffmanTree(depth[64:], 64, tree[:], storage_ix, storage) | ||||
| } | ||||
|  | ||||
| func emitInsertLen(insertlen uint32, commands *[]uint32) { | ||||
| @@ -197,11 +197,11 @@ func emitDistance(distance uint32, commands *[]uint32) { | ||||
| } | ||||
|  | ||||
| /* REQUIRES: len <= 1 << 24. */ | ||||
| func storeMetaBlockHeader(len uint, is_uncompressed bool, bw *bitWriter) { | ||||
| func storeMetaBlockHeader(len uint, is_uncompressed bool, storage_ix *uint, storage []byte) { | ||||
| 	var nibbles uint = 6 | ||||
|  | ||||
| 	/* ISLAST */ | ||||
| 	bw.writeBits(1, 0) | ||||
| 	writeBits(1, 0, storage_ix, storage) | ||||
|  | ||||
| 	if len <= 1<<16 { | ||||
| 		nibbles = 4 | ||||
| @@ -209,11 +209,11 @@ func storeMetaBlockHeader(len uint, is_uncompressed bool, bw *bitWriter) { | ||||
| 		nibbles = 5 | ||||
| 	} | ||||
|  | ||||
| 	bw.writeBits(2, uint64(nibbles)-4) | ||||
| 	bw.writeBits(nibbles*4, uint64(len)-1) | ||||
| 	writeBits(2, uint64(nibbles)-4, storage_ix, storage) | ||||
| 	writeBits(nibbles*4, uint64(len)-1, storage_ix, storage) | ||||
|  | ||||
| 	/* ISUNCOMPRESSED */ | ||||
| 	bw.writeSingleBit(is_uncompressed) | ||||
| 	writeSingleBit(is_uncompressed, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| func createCommands(input []byte, block_size uint, input_size uint, base_ip_ptr []byte, table []int, table_bits uint, min_match uint, literals *[]byte, commands *[]uint32) { | ||||
| @@ -440,20 +440,163 @@ emit_remainder: | ||||
| } | ||||
|  | ||||
| var storeCommands_kNumExtraBits = [128]uint32{ | ||||
| 	0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24, | ||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, | ||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24, | ||||
| 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
| 	1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, | ||||
| 	9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, | ||||
| 	17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	2, | ||||
| 	2, | ||||
| 	3, | ||||
| 	3, | ||||
| 	4, | ||||
| 	4, | ||||
| 	5, | ||||
| 	5, | ||||
| 	6, | ||||
| 	7, | ||||
| 	8, | ||||
| 	9, | ||||
| 	10, | ||||
| 	12, | ||||
| 	14, | ||||
| 	24, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	2, | ||||
| 	2, | ||||
| 	3, | ||||
| 	3, | ||||
| 	4, | ||||
| 	4, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	2, | ||||
| 	2, | ||||
| 	3, | ||||
| 	3, | ||||
| 	4, | ||||
| 	4, | ||||
| 	5, | ||||
| 	5, | ||||
| 	6, | ||||
| 	7, | ||||
| 	8, | ||||
| 	9, | ||||
| 	10, | ||||
| 	24, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	0, | ||||
| 	1, | ||||
| 	1, | ||||
| 	2, | ||||
| 	2, | ||||
| 	3, | ||||
| 	3, | ||||
| 	4, | ||||
| 	4, | ||||
| 	5, | ||||
| 	5, | ||||
| 	6, | ||||
| 	6, | ||||
| 	7, | ||||
| 	7, | ||||
| 	8, | ||||
| 	8, | ||||
| 	9, | ||||
| 	9, | ||||
| 	10, | ||||
| 	10, | ||||
| 	11, | ||||
| 	11, | ||||
| 	12, | ||||
| 	12, | ||||
| 	13, | ||||
| 	13, | ||||
| 	14, | ||||
| 	14, | ||||
| 	15, | ||||
| 	15, | ||||
| 	16, | ||||
| 	16, | ||||
| 	17, | ||||
| 	17, | ||||
| 	18, | ||||
| 	18, | ||||
| 	19, | ||||
| 	19, | ||||
| 	20, | ||||
| 	20, | ||||
| 	21, | ||||
| 	21, | ||||
| 	22, | ||||
| 	22, | ||||
| 	23, | ||||
| 	23, | ||||
| 	24, | ||||
| 	24, | ||||
| } | ||||
| var storeCommands_kInsertOffset = [24]uint32{ | ||||
| 	0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, | ||||
| 	1090, 2114, 6210, 22594, | ||||
| 	0, | ||||
| 	1, | ||||
| 	2, | ||||
| 	3, | ||||
| 	4, | ||||
| 	5, | ||||
| 	6, | ||||
| 	8, | ||||
| 	10, | ||||
| 	14, | ||||
| 	18, | ||||
| 	26, | ||||
| 	34, | ||||
| 	50, | ||||
| 	66, | ||||
| 	98, | ||||
| 	130, | ||||
| 	194, | ||||
| 	322, | ||||
| 	578, | ||||
| 	1090, | ||||
| 	2114, | ||||
| 	6210, | ||||
| 	22594, | ||||
| } | ||||
|  | ||||
| func storeCommands(literals []byte, num_literals uint, commands []uint32, num_commands uint, bw *bitWriter) { | ||||
| func storeCommands(literals []byte, num_literals uint, commands []uint32, num_commands uint, storage_ix *uint, storage []byte) { | ||||
| 	var lit_depths [256]byte | ||||
| 	var lit_bits [256]uint16 | ||||
| 	var lit_histo = [256]uint32{0} | ||||
| @@ -466,7 +609,7 @@ func storeCommands(literals []byte, num_literals uint, commands []uint32, num_co | ||||
| 	} | ||||
|  | ||||
| 	buildAndStoreHuffmanTreeFast(lit_histo[:], num_literals, /* max_bits = */ | ||||
| 		8, lit_depths[:], lit_bits[:], bw) | ||||
| 		8, lit_depths[:], lit_bits[:], storage_ix, storage) | ||||
|  | ||||
| 	for i = 0; i < num_commands; i++ { | ||||
| 		var code uint32 = commands[i] & 0xFF | ||||
| @@ -478,21 +621,21 @@ func storeCommands(literals []byte, num_literals uint, commands []uint32, num_co | ||||
| 	cmd_histo[2] += 1 | ||||
| 	cmd_histo[64] += 1 | ||||
| 	cmd_histo[84] += 1 | ||||
| 	buildAndStoreCommandPrefixCode(cmd_histo[:], cmd_depths[:], cmd_bits[:], bw) | ||||
| 	buildAndStoreCommandPrefixCode(cmd_histo[:], cmd_depths[:], cmd_bits[:], storage_ix, storage) | ||||
|  | ||||
| 	for i = 0; i < num_commands; i++ { | ||||
| 		var cmd uint32 = commands[i] | ||||
| 		var code uint32 = cmd & 0xFF | ||||
| 		var extra uint32 = cmd >> 8 | ||||
| 		assert(code < 128) | ||||
| 		bw.writeBits(uint(cmd_depths[code]), uint64(cmd_bits[code])) | ||||
| 		bw.writeBits(uint(storeCommands_kNumExtraBits[code]), uint64(extra)) | ||||
| 		writeBits(uint(cmd_depths[code]), uint64(cmd_bits[code]), storage_ix, storage) | ||||
| 		writeBits(uint(storeCommands_kNumExtraBits[code]), uint64(extra), storage_ix, storage) | ||||
| 		if code < 24 { | ||||
| 			var insert uint32 = storeCommands_kInsertOffset[code] + extra | ||||
| 			var j uint32 | ||||
| 			for j = 0; j < insert; j++ { | ||||
| 				var lit byte = literals[0] | ||||
| 				bw.writeBits(uint(lit_depths[lit]), uint64(lit_bits[lit])) | ||||
| 				writeBits(uint(lit_depths[lit]), uint64(lit_bits[lit]), storage_ix, storage) | ||||
| 				literals = literals[1:] | ||||
| 			} | ||||
| 		} | ||||
| @@ -520,13 +663,22 @@ func shouldCompress(input []byte, input_size uint, num_literals uint) bool { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func emitUncompressedMetaBlock(input []byte, input_size uint, bw *bitWriter) { | ||||
| 	storeMetaBlockHeader(input_size, true, bw) | ||||
| 	bw.jumpToByteBoundary() | ||||
| 	bw.writeBytes(input[:input_size]) | ||||
| func rewindBitPosition(new_storage_ix uint, storage_ix *uint, storage []byte) { | ||||
| 	var bitpos uint = new_storage_ix & 7 | ||||
| 	var mask uint = (1 << bitpos) - 1 | ||||
| 	storage[new_storage_ix>>3] &= byte(mask) | ||||
| 	*storage_ix = new_storage_ix | ||||
| } | ||||
|  | ||||
| func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_bits uint, min_match uint, bw *bitWriter) { | ||||
| func emitUncompressedMetaBlock(input []byte, input_size uint, storage_ix *uint, storage []byte) { | ||||
| 	storeMetaBlockHeader(input_size, true, storage_ix, storage) | ||||
| 	*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 	copy(storage[*storage_ix>>3:], input[:input_size]) | ||||
| 	*storage_ix += input_size << 3 | ||||
| 	storage[*storage_ix>>3] = 0 | ||||
| } | ||||
|  | ||||
| func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_bits uint, min_match uint, storage_ix *uint, storage []byte) { | ||||
| 	/* Save the start of the first block for position and distance computations. | ||||
| 	 */ | ||||
| 	var base_ip []byte = input | ||||
| @@ -540,17 +692,17 @@ func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, co | ||||
| 		num_literals = uint(-cap(literals) + cap(literal_buf)) | ||||
| 		if shouldCompress(input, block_size, num_literals) { | ||||
| 			var num_commands uint = uint(-cap(commands) + cap(command_buf)) | ||||
| 			storeMetaBlockHeader(block_size, false, bw) | ||||
| 			storeMetaBlockHeader(block_size, false, storage_ix, storage) | ||||
|  | ||||
| 			/* No block splits, no contexts. */ | ||||
| 			bw.writeBits(13, 0) | ||||
| 			writeBits(13, 0, storage_ix, storage) | ||||
|  | ||||
| 			storeCommands(literal_buf, num_literals, command_buf, num_commands, bw) | ||||
| 			storeCommands(literal_buf, num_literals, command_buf, num_commands, storage_ix, storage) | ||||
| 		} else { | ||||
| 			/* Since we did not find many backward references and the entropy of | ||||
| 			   the data is close to 8 bits, we can simply emit an uncompressed block. | ||||
| 			   This makes compression speed of uncompressible data about 3x faster. */ | ||||
| 			emitUncompressedMetaBlock(input, block_size, bw) | ||||
| 			emitUncompressedMetaBlock(input, block_size, storage_ix, storage) | ||||
| 		} | ||||
|  | ||||
| 		input = input[block_size:] | ||||
| @@ -558,7 +710,8 @@ func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, co | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Compresses "input" string to bw as one or more complete meta-blocks. | ||||
| /* Compresses "input" string to the "*storage" buffer as one or more complete | ||||
|    meta-blocks, and updates the "*storage_ix" bit position. | ||||
|  | ||||
|    If "is_last" is 1, emits an additional empty last meta-block. | ||||
|  | ||||
| @@ -570,8 +723,8 @@ func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, co | ||||
|    REQUIRES: "table_size" is a power of two | ||||
|    OUTPUT: maximal copy distance <= |input_size| | ||||
|    OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ | ||||
| func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_size uint, bw *bitWriter) { | ||||
| 	var initial_storage_ix uint = bw.getPos() | ||||
| func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_size uint, storage_ix *uint, storage []byte) { | ||||
| 	var initial_storage_ix uint = *storage_ix | ||||
| 	var table_bits uint = uint(log2FloorNonZero(table_size)) | ||||
| 	var min_match uint | ||||
| 	if table_bits <= 15 { | ||||
| @@ -579,17 +732,17 @@ func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, comman | ||||
| 	} else { | ||||
| 		min_match = 6 | ||||
| 	} | ||||
| 	compressFragmentTwoPassImpl(input, input_size, is_last, command_buf, literal_buf, table, table_bits, min_match, bw) | ||||
| 	compressFragmentTwoPassImpl(input, input_size, is_last, command_buf, literal_buf, table, table_bits, min_match, storage_ix, storage) | ||||
|  | ||||
| 	/* If output is larger than single uncompressed block, rewrite it. */ | ||||
| 	if bw.getPos()-initial_storage_ix > 31+(input_size<<3) { | ||||
| 		bw.rewind(initial_storage_ix) | ||||
| 		emitUncompressedMetaBlock(input, input_size, bw) | ||||
| 	if *storage_ix-initial_storage_ix > 31+(input_size<<3) { | ||||
| 		rewindBitPosition(initial_storage_ix, storage_ix, storage) | ||||
| 		emitUncompressedMetaBlock(input, input_size, storage_ix, storage) | ||||
| 	} | ||||
|  | ||||
| 	if is_last { | ||||
| 		bw.writeBits(1, 1) /* islast */ | ||||
| 		bw.writeBits(1, 1) /* isempty */ | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		writeBits(1, 1, storage_ix, storage) /* islast */ | ||||
| 		writeBits(1, 1, storage_ix, storage) /* isempty */ | ||||
| 		*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										171
									
								
								vendor/github.com/andybalholm/brotli/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										171
									
								
								vendor/github.com/andybalholm/brotli/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -87,9 +87,11 @@ type Writer struct { | ||||
| 	last_processed_pos_ uint64 | ||||
| 	dist_cache_         [numDistanceShortCodes]int | ||||
| 	saved_dist_cache_   [4]int | ||||
| 	last_bytes_         uint16 | ||||
| 	last_bytes_bits_    byte | ||||
| 	prev_byte_          byte | ||||
| 	prev_byte2_         byte | ||||
| 	bw                  bitWriter | ||||
| 	storage             []byte | ||||
| 	small_table_        [1 << 10]int | ||||
| 	large_table_        []int | ||||
| 	large_table_size_   uint | ||||
| @@ -139,6 +141,14 @@ func wrapPosition(position uint64) uint32 { | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (s *Writer) getStorage(size int) []byte { | ||||
| 	if len(s.storage) < size { | ||||
| 		s.storage = make([]byte, size) | ||||
| 	} | ||||
|  | ||||
| 	return s.storage | ||||
| } | ||||
|  | ||||
| func hashTableSize(max_table_size uint, input_size uint) uint { | ||||
| 	var htsize uint = 256 | ||||
| 	for htsize < max_table_size && htsize < input_size { | ||||
| @@ -184,18 +194,23 @@ func getHashTable(s *Writer, quality int, input_size uint, table_size *uint) []i | ||||
| 	return table | ||||
| } | ||||
|  | ||||
| func encodeWindowBits(lgwin int, large_window bool, bw *bitWriter) { | ||||
| func encodeWindowBits(lgwin int, large_window bool, last_bytes *uint16, last_bytes_bits *byte) { | ||||
| 	if large_window { | ||||
| 		bw.writeBits(14, uint64((lgwin&0x3F)<<8|0x11)) | ||||
| 		*last_bytes = uint16((lgwin&0x3F)<<8 | 0x11) | ||||
| 		*last_bytes_bits = 14 | ||||
| 	} else { | ||||
| 		if lgwin == 16 { | ||||
| 			bw.writeBits(1, 0) | ||||
| 			*last_bytes = 0 | ||||
| 			*last_bytes_bits = 1 | ||||
| 		} else if lgwin == 17 { | ||||
| 			bw.writeBits(7, 1) | ||||
| 			*last_bytes = 1 | ||||
| 			*last_bytes_bits = 7 | ||||
| 		} else if lgwin > 17 { | ||||
| 			bw.writeBits(4, uint64((lgwin-17)<<1|0x01)) | ||||
| 			*last_bytes = uint16((lgwin-17)<<1 | 0x01) | ||||
| 			*last_bytes_bits = 4 | ||||
| 		} else { | ||||
| 			bw.writeBits(7, uint64((lgwin-8)<<4|0x01)) | ||||
| 			*last_bytes = uint16((lgwin-8)<<4 | 0x01) | ||||
| 			*last_bytes_bits = 7 | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -417,15 +432,18 @@ func chooseContextMode(params *encoderParams, data []byte, pos uint, mask uint, | ||||
| 	return contextUTF8 | ||||
| } | ||||
|  | ||||
| func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes uint, is_last bool, literal_context_mode int, params *encoderParams, prev_byte byte, prev_byte2 byte, num_literals uint, commands []command, saved_dist_cache []int, dist_cache []int, bw *bitWriter) { | ||||
| func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes uint, is_last bool, literal_context_mode int, params *encoderParams, prev_byte byte, prev_byte2 byte, num_literals uint, commands []command, saved_dist_cache []int, dist_cache []int, storage_ix *uint, storage []byte) { | ||||
| 	var wrapped_last_flush_pos uint32 = wrapPosition(last_flush_pos) | ||||
| 	var last_bytes uint16 | ||||
| 	var last_bytes_bits byte | ||||
| 	var literal_context_lut contextLUT = getContextLUT(literal_context_mode) | ||||
| 	var block_params encoderParams = *params | ||||
|  | ||||
| 	if bytes == 0 { | ||||
| 		/* Write the ISLAST and ISEMPTY bits. */ | ||||
| 		bw.writeBits(2, 3) | ||||
| 		bw.jumpToByteBoundary() | ||||
| 		writeBits(2, 3, storage_ix, storage) | ||||
|  | ||||
| 		*storage_ix = (*storage_ix + 7) &^ 7 | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @@ -434,15 +452,17 @@ func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes | ||||
| 		   CreateBackwardReferences is now unused. */ | ||||
| 		copy(dist_cache, saved_dist_cache[:4]) | ||||
|  | ||||
| 		storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, bw) | ||||
| 		storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	savedPos := bw.getPos() | ||||
| 	assert(*storage_ix <= 14) | ||||
| 	last_bytes = uint16(storage[1])<<8 | uint16(storage[0]) | ||||
| 	last_bytes_bits = byte(*storage_ix) | ||||
| 	if params.quality <= maxQualityForStaticEntropyCodes { | ||||
| 		storeMetaBlockFast(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, bw) | ||||
| 		storeMetaBlockFast(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) | ||||
| 	} else if params.quality < minQualityForBlockSplit { | ||||
| 		storeMetaBlockTrivial(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, bw) | ||||
| 		storeMetaBlockTrivial(data, uint(wrapped_last_flush_pos), bytes, mask, is_last, params, commands, storage_ix, storage) | ||||
| 	} else { | ||||
| 		mb := getMetaBlockSplit() | ||||
| 		if params.quality < minQualityForHqBlockSplitting { | ||||
| @@ -469,15 +489,18 @@ func writeMetaBlockInternal(data []byte, mask uint, last_flush_pos uint64, bytes | ||||
| 			optimizeHistograms(num_effective_dist_codes, mb) | ||||
| 		} | ||||
|  | ||||
| 		storeMetaBlock(data, uint(wrapped_last_flush_pos), bytes, mask, prev_byte, prev_byte2, is_last, &block_params, literal_context_mode, commands, mb, bw) | ||||
| 		storeMetaBlock(data, uint(wrapped_last_flush_pos), bytes, mask, prev_byte, prev_byte2, is_last, &block_params, literal_context_mode, commands, mb, storage_ix, storage) | ||||
| 		freeMetaBlockSplit(mb) | ||||
| 	} | ||||
|  | ||||
| 	if bytes+4 < bw.getPos()>>3 { | ||||
| 	if bytes+4 < *storage_ix>>3 { | ||||
| 		/* Restore the distance cache and last byte. */ | ||||
| 		copy(dist_cache, saved_dist_cache[:4]) | ||||
| 		bw.rewind(savedPos) | ||||
| 		storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, bw) | ||||
|  | ||||
| 		storage[0] = byte(last_bytes) | ||||
| 		storage[1] = byte(last_bytes >> 8) | ||||
| 		*storage_ix = uint(last_bytes_bits) | ||||
| 		storeUncompressedMetaBlock(is_last, data, uint(wrapped_last_flush_pos), mask, bytes, storage_ix, storage) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -510,10 +533,8 @@ func ensureInitialized(s *Writer) bool { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	s.bw.bits = 0 | ||||
| 	s.bw.nbits = 0 | ||||
| 	s.bw.dst = s.bw.dst[:0] | ||||
|  | ||||
| 	s.last_bytes_bits_ = 0 | ||||
| 	s.last_bytes_ = 0 | ||||
| 	s.remaining_metadata_bytes_ = math.MaxUint32 | ||||
|  | ||||
| 	sanitizeParams(&s.params) | ||||
| @@ -529,7 +550,7 @@ func ensureInitialized(s *Writer) bool { | ||||
| 			lgwin = brotli_max_int(lgwin, 18) | ||||
| 		} | ||||
|  | ||||
| 		encodeWindowBits(lgwin, s.params.large_window, &s.bw) | ||||
| 		encodeWindowBits(lgwin, s.params.large_window, &s.last_bytes_, &s.last_bytes_bits_) | ||||
| 	} | ||||
|  | ||||
| 	if s.params.quality == fastOnePassCompressionQuality { | ||||
| @@ -761,6 +782,8 @@ func encodeData(s *Writer, is_last bool, force_flush bool) bool { | ||||
| 	} | ||||
|  | ||||
| 	if s.params.quality == fastOnePassCompressionQuality || s.params.quality == fastTwoPassCompressionQuality { | ||||
| 		var storage []byte | ||||
| 		var storage_ix uint = uint(s.last_bytes_bits_) | ||||
| 		var table_size uint | ||||
| 		var table []int | ||||
|  | ||||
| @@ -770,16 +793,20 @@ func encodeData(s *Writer, is_last bool, force_flush bool) bool { | ||||
| 			return true | ||||
| 		} | ||||
|  | ||||
| 		storage = s.getStorage(int(2*bytes + 503)) | ||||
| 		storage[0] = byte(s.last_bytes_) | ||||
| 		storage[1] = byte(s.last_bytes_ >> 8) | ||||
| 		table = getHashTable(s, s.params.quality, uint(bytes), &table_size) | ||||
| 		if s.params.quality == fastOnePassCompressionQuality { | ||||
| 			compressFragmentFast(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &s.bw) | ||||
| 			compressFragmentFast(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) | ||||
| 		} else { | ||||
| 			compressFragmentTwoPass(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, s.command_buf_, s.literal_buf_, table, table_size, &s.bw) | ||||
| 			compressFragmentTwoPass(data[wrapped_last_processed_pos&mask:], uint(bytes), is_last, s.command_buf_, s.literal_buf_, table, table_size, &storage_ix, storage) | ||||
| 		} | ||||
|  | ||||
| 		s.last_bytes_ = uint16(storage[storage_ix>>3]) | ||||
| 		s.last_bytes_bits_ = byte(storage_ix & 7) | ||||
| 		updateLastProcessedPos(s) | ||||
| 		s.writeOutput(s.bw.dst) | ||||
| 		s.bw.dst = s.bw.dst[:0] | ||||
| 		s.writeOutput(storage[:storage_ix>>3]) | ||||
| 		return true | ||||
| 	} | ||||
| 	{ | ||||
| @@ -856,7 +883,13 @@ func encodeData(s *Writer, is_last bool, force_flush bool) bool { | ||||
| 	assert(s.input_pos_-s.last_flush_pos_ <= 1<<24) | ||||
| 	{ | ||||
| 		var metablock_size uint32 = uint32(s.input_pos_ - s.last_flush_pos_) | ||||
| 		writeMetaBlockInternal(data, uint(mask), s.last_flush_pos_, uint(metablock_size), is_last, literal_context_mode, &s.params, s.prev_byte_, s.prev_byte2_, s.num_literals_, s.commands, s.saved_dist_cache_[:], s.dist_cache_[:], &s.bw) | ||||
| 		var storage []byte = s.getStorage(int(2*metablock_size + 503)) | ||||
| 		var storage_ix uint = uint(s.last_bytes_bits_) | ||||
| 		storage[0] = byte(s.last_bytes_) | ||||
| 		storage[1] = byte(s.last_bytes_ >> 8) | ||||
| 		writeMetaBlockInternal(data, uint(mask), s.last_flush_pos_, uint(metablock_size), is_last, literal_context_mode, &s.params, s.prev_byte_, s.prev_byte2_, s.num_literals_, s.commands, s.saved_dist_cache_[:], s.dist_cache_[:], &storage_ix, storage) | ||||
| 		s.last_bytes_ = uint16(storage[storage_ix>>3]) | ||||
| 		s.last_bytes_bits_ = byte(storage_ix & 7) | ||||
| 		s.last_flush_pos_ = s.input_pos_ | ||||
| 		if updateLastProcessedPos(s) { | ||||
| 			hasherReset(s.hasher_) | ||||
| @@ -877,22 +910,28 @@ func encodeData(s *Writer, is_last bool, force_flush bool) bool { | ||||
| 		   emitting an uncompressed block. */ | ||||
| 		copy(s.saved_dist_cache_[:], s.dist_cache_[:]) | ||||
|  | ||||
| 		s.writeOutput(s.bw.dst) | ||||
| 		s.bw.dst = s.bw.dst[:0] | ||||
| 		s.writeOutput(storage[:storage_ix>>3]) | ||||
| 		return true | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Dumps remaining output bits and metadata header to s.bw. | ||||
| /* Dumps remaining output bits and metadata header to |header|. | ||||
|    Returns number of produced bytes. | ||||
|    REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long. | ||||
|    REQUIRED: |block_size| <= (1 << 24). */ | ||||
| func writeMetadataHeader(s *Writer, block_size uint) { | ||||
| 	bw := &s.bw | ||||
| func writeMetadataHeader(s *Writer, block_size uint, header []byte) uint { | ||||
| 	var storage_ix uint | ||||
| 	storage_ix = uint(s.last_bytes_bits_) | ||||
| 	header[0] = byte(s.last_bytes_) | ||||
| 	header[1] = byte(s.last_bytes_ >> 8) | ||||
| 	s.last_bytes_ = 0 | ||||
| 	s.last_bytes_bits_ = 0 | ||||
|  | ||||
| 	bw.writeBits(1, 0) | ||||
| 	bw.writeBits(2, 3) | ||||
| 	bw.writeBits(1, 0) | ||||
| 	writeBits(1, 0, &storage_ix, header) | ||||
| 	writeBits(2, 3, &storage_ix, header) | ||||
| 	writeBits(1, 0, &storage_ix, header) | ||||
| 	if block_size == 0 { | ||||
| 		bw.writeBits(2, 0) | ||||
| 		writeBits(2, 0, &storage_ix, header) | ||||
| 	} else { | ||||
| 		var nbits uint32 | ||||
| 		if block_size == 1 { | ||||
| @@ -901,19 +940,34 @@ func writeMetadataHeader(s *Writer, block_size uint) { | ||||
| 			nbits = log2FloorNonZero(uint(uint32(block_size)-1)) + 1 | ||||
| 		} | ||||
| 		var nbytes uint32 = (nbits + 7) / 8 | ||||
| 		bw.writeBits(2, uint64(nbytes)) | ||||
| 		bw.writeBits(uint(8*nbytes), uint64(block_size)-1) | ||||
| 		writeBits(2, uint64(nbytes), &storage_ix, header) | ||||
| 		writeBits(uint(8*nbytes), uint64(block_size)-1, &storage_ix, header) | ||||
| 	} | ||||
|  | ||||
| 	bw.jumpToByteBoundary() | ||||
| 	return (storage_ix + 7) >> 3 | ||||
| } | ||||
|  | ||||
| func injectBytePaddingBlock(s *Writer) { | ||||
| 	var seal uint32 = uint32(s.last_bytes_) | ||||
| 	var seal_bits uint = uint(s.last_bytes_bits_) | ||||
| 	s.last_bytes_ = 0 | ||||
| 	s.last_bytes_bits_ = 0 | ||||
|  | ||||
| 	/* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */ | ||||
| 	s.bw.writeBits(6, 0x6) | ||||
| 	s.bw.jumpToByteBoundary() | ||||
| 	s.writeOutput(s.bw.dst) | ||||
| 	s.bw.dst = s.bw.dst[:0] | ||||
| 	seal |= 0x6 << seal_bits | ||||
|  | ||||
| 	seal_bits += 6 | ||||
|  | ||||
| 	destination := s.tiny_buf_.u8[:] | ||||
|  | ||||
| 	destination[0] = byte(seal) | ||||
| 	if seal_bits > 8 { | ||||
| 		destination[1] = byte(seal >> 8) | ||||
| 	} | ||||
| 	if seal_bits > 16 { | ||||
| 		destination[2] = byte(seal >> 16) | ||||
| 	} | ||||
| 	s.writeOutput(destination[:(seal_bits+7)>>3]) | ||||
| } | ||||
|  | ||||
| func checkFlushComplete(s *Writer) { | ||||
| @@ -945,7 +999,7 @@ func encoderCompressStreamFast(s *Writer, op int, available_in *uint, next_in *[ | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		if s.stream_state_ == streamFlushRequested && s.bw.nbits&7 != 0 { | ||||
| 		if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { | ||||
| 			injectBytePaddingBlock(s) | ||||
| 			continue | ||||
| 		} | ||||
| @@ -957,6 +1011,9 @@ func encoderCompressStreamFast(s *Writer, op int, available_in *uint, next_in *[ | ||||
| 			var block_size uint = brotli_min_size_t(block_size_limit, *available_in) | ||||
| 			var is_last bool = (*available_in == block_size) && (op == int(operationFinish)) | ||||
| 			var force_flush bool = (*available_in == block_size) && (op == int(operationFlush)) | ||||
| 			var max_out_size uint = 2*block_size + 503 | ||||
| 			var storage []byte = nil | ||||
| 			var storage_ix uint = uint(s.last_bytes_bits_) | ||||
| 			var table_size uint | ||||
| 			var table []int | ||||
|  | ||||
| @@ -965,18 +1022,25 @@ func encoderCompressStreamFast(s *Writer, op int, available_in *uint, next_in *[ | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			storage = s.getStorage(int(max_out_size)) | ||||
|  | ||||
| 			storage[0] = byte(s.last_bytes_) | ||||
| 			storage[1] = byte(s.last_bytes_ >> 8) | ||||
| 			table = getHashTable(s, s.params.quality, block_size, &table_size) | ||||
|  | ||||
| 			if s.params.quality == fastOnePassCompressionQuality { | ||||
| 				compressFragmentFast(*next_in, block_size, is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &s.bw) | ||||
| 				compressFragmentFast(*next_in, block_size, is_last, table, table_size, s.cmd_depths_[:], s.cmd_bits_[:], &s.cmd_code_numbits_, s.cmd_code_[:], &storage_ix, storage) | ||||
| 			} else { | ||||
| 				compressFragmentTwoPass(*next_in, block_size, is_last, command_buf, literal_buf, table, table_size, &s.bw) | ||||
| 				compressFragmentTwoPass(*next_in, block_size, is_last, command_buf, literal_buf, table, table_size, &storage_ix, storage) | ||||
| 			} | ||||
|  | ||||
| 			*next_in = (*next_in)[block_size:] | ||||
| 			*available_in -= block_size | ||||
| 			s.writeOutput(s.bw.dst) | ||||
| 			s.bw.dst = s.bw.dst[:0] | ||||
| 			var out_bytes uint = storage_ix >> 3 | ||||
| 			s.writeOutput(storage[:out_bytes]) | ||||
|  | ||||
| 			s.last_bytes_ = uint16(storage[storage_ix>>3]) | ||||
| 			s.last_bytes_bits_ = byte(storage_ix & 7) | ||||
|  | ||||
| 			if force_flush { | ||||
| 				s.stream_state_ = streamFlushRequested | ||||
| @@ -1010,7 +1074,7 @@ func processMetadata(s *Writer, available_in *uint, next_in *[]byte) bool { | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		if s.stream_state_ == streamFlushRequested && s.bw.nbits&7 != 0 { | ||||
| 		if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { | ||||
| 			injectBytePaddingBlock(s) | ||||
| 			continue | ||||
| 		} | ||||
| @@ -1024,9 +1088,8 @@ func processMetadata(s *Writer, available_in *uint, next_in *[]byte) bool { | ||||
| 		} | ||||
|  | ||||
| 		if s.stream_state_ == streamMetadataHead { | ||||
| 			writeMetadataHeader(s, uint(s.remaining_metadata_bytes_)) | ||||
| 			s.writeOutput(s.bw.dst) | ||||
| 			s.bw.dst = s.bw.dst[:0] | ||||
| 			n := writeMetadataHeader(s, uint(s.remaining_metadata_bytes_), s.tiny_buf_.u8[:]) | ||||
| 			s.writeOutput(s.tiny_buf_.u8[:n]) | ||||
| 			s.stream_state_ = streamMetadataBody | ||||
| 			continue | ||||
| 		} else { | ||||
| @@ -1112,7 +1175,7 @@ func encoderCompressStream(s *Writer, op int, available_in *uint, next_in *[]byt | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if s.stream_state_ == streamFlushRequested && s.bw.nbits&7 != 0 { | ||||
| 		if s.stream_state_ == streamFlushRequested && s.last_bytes_bits_ != 0 { | ||||
| 			injectBytePaddingBlock(s) | ||||
| 			continue | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										16
									
								
								vendor/github.com/andybalholm/brotli/entropy_encode_static.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/andybalholm/brotli/entropy_encode_static.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -778,9 +778,8 @@ var kStaticDistanceCodeDepth = [64]byte{ | ||||
|  | ||||
| var kCodeLengthBits = [18]uint32{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 15, 31, 0, 11, 7} | ||||
|  | ||||
| func storeStaticCodeLengthCode(bw *bitWriter) { | ||||
| 	bw.writeBits(32, 0x55555554) | ||||
| 	bw.writeBits(8, 0xFF) | ||||
| func storeStaticCodeLengthCode(storage_ix *uint, storage []byte) { | ||||
| 	writeBits(40, 0x0000FF55555554, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| var kZeroRepsBits = [numCommandSymbols]uint64{ | ||||
| @@ -4318,10 +4317,9 @@ var kStaticCommandCodeBits = [numCommandSymbols]uint16{ | ||||
| 	2047, | ||||
| } | ||||
|  | ||||
| func storeStaticCommandHuffmanTree(bw *bitWriter) { | ||||
| 	bw.writeBits(32, 0x16307003) | ||||
| 	bw.writeBits(24, 0x926244) | ||||
| 	bw.writeBits(3, 0x00000000) | ||||
| func storeStaticCommandHuffmanTree(storage_ix *uint, storage []byte) { | ||||
| 	writeBits(56, 0x92624416307003, storage_ix, storage) | ||||
| 	writeBits(3, 0x00000000, storage_ix, storage) | ||||
| } | ||||
|  | ||||
| var kStaticDistanceCodeBits = [64]uint16{ | ||||
| @@ -4391,6 +4389,6 @@ var kStaticDistanceCodeBits = [64]uint16{ | ||||
| 	63, | ||||
| } | ||||
|  | ||||
| func storeStaticDistanceHuffmanTree(bw *bitWriter) { | ||||
| 	bw.writeBits(28, 0x0369DC03) | ||||
| func storeStaticDistanceHuffmanTree(storage_ix *uint, storage []byte) { | ||||
| 	writeBits(28, 0x0369DC03, storage_ix, storage) | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/andybalholm/brotli/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/andybalholm/brotli/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,5 @@ | ||||
| module github.com/andybalholm/brotli | ||||
|  | ||||
| go 1.12 | ||||
|  | ||||
| retract v1.0.1 // occasional panics and data corruption | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/andybalholm/brotli/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/andybalholm/brotli/reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -33,7 +33,9 @@ func NewReader(src io.Reader) *Reader { | ||||
| func (r *Reader) Reset(src io.Reader) error { | ||||
| 	decoderStateInit(r) | ||||
| 	r.src = src | ||||
| 	r.buf = make([]byte, readBufSize) | ||||
| 	if r.buf == nil { | ||||
| 		r.buf = make([]byte, readBufSize) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										108
									
								
								vendor/github.com/andybalholm/brotli/write_bits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/andybalholm/brotli/write_bits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,5 +1,7 @@ | ||||
| package brotli | ||||
|  | ||||
| import "encoding/binary" | ||||
|  | ||||
| /* Copyright 2010 Google Inc. All Rights Reserved. | ||||
|  | ||||
|    Distributed under MIT license. | ||||
| @@ -8,87 +10,43 @@ package brotli | ||||
|  | ||||
| /* Write bits into a byte array. */ | ||||
|  | ||||
| type bitWriter struct { | ||||
| 	dst []byte | ||||
| /* This function writes bits into bytes in increasing addresses, and within | ||||
|    a byte least-significant-bit first. | ||||
|  | ||||
| 	// Data waiting to be written is the low nbits of bits. | ||||
| 	bits  uint64 | ||||
| 	nbits uint | ||||
|    The function can write up to 56 bits in one go with WriteBits | ||||
|    Example: let's assume that 3 bits (Rs below) have been written already: | ||||
|  | ||||
|    BYTE-0     BYTE+1       BYTE+2 | ||||
|  | ||||
|    0000 0RRR    0000 0000    0000 0000 | ||||
|  | ||||
|    Now, we could write 5 or less bits in MSB by just sifting by 3 | ||||
|    and OR'ing to BYTE-0. | ||||
|  | ||||
|    For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, | ||||
|    and locate the rest in BYTE+1, BYTE+2, etc. */ | ||||
| func writeBits(n_bits uint, bits uint64, pos *uint, array []byte) { | ||||
| 	/* This branch of the code can write up to 56 bits at a time, | ||||
| 	   7 bits are lost by being perhaps already in *p and at least | ||||
| 	   1 bit is needed to initialize the bit-stream ahead (i.e. if 7 | ||||
| 	   bits are in *p and we write 57 bits, then the next write will | ||||
| 	   access a byte that was never initialized). */ | ||||
| 	p := array[*pos>>3:] | ||||
| 	v := uint64(p[0]) | ||||
| 	v |= bits << (*pos & 7) | ||||
| 	binary.LittleEndian.PutUint64(p, v) | ||||
| 	*pos += n_bits | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) writeBits(nb uint, b uint64) { | ||||
| 	w.bits |= b << w.nbits | ||||
| 	w.nbits += nb | ||||
| 	if w.nbits >= 32 { | ||||
| 		bits := w.bits | ||||
| 		w.bits >>= 32 | ||||
| 		w.nbits -= 32 | ||||
| 		w.dst = append(w.dst, | ||||
| 			byte(bits), | ||||
| 			byte(bits>>8), | ||||
| 			byte(bits>>16), | ||||
| 			byte(bits>>24), | ||||
| 		) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) writeSingleBit(bit bool) { | ||||
| func writeSingleBit(bit bool, pos *uint, array []byte) { | ||||
| 	if bit { | ||||
| 		w.writeBits(1, 1) | ||||
| 		writeBits(1, 1, pos, array) | ||||
| 	} else { | ||||
| 		w.writeBits(1, 0) | ||||
| 		writeBits(1, 0, pos, array) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) jumpToByteBoundary() { | ||||
| 	dst := w.dst | ||||
| 	for w.nbits != 0 { | ||||
| 		dst = append(dst, byte(w.bits)) | ||||
| 		w.bits >>= 8 | ||||
| 		if w.nbits > 8 { // Avoid underflow | ||||
| 			w.nbits -= 8 | ||||
| 		} else { | ||||
| 			w.nbits = 0 | ||||
| 		} | ||||
| 	} | ||||
| 	w.bits = 0 | ||||
| 	w.dst = dst | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) writeBytes(b []byte) { | ||||
| 	if w.nbits&7 != 0 { | ||||
| 		panic("writeBytes with unfinished bits") | ||||
| 	} | ||||
| 	for w.nbits != 0 { | ||||
| 		w.dst = append(w.dst, byte(w.bits)) | ||||
| 		w.bits >>= 8 | ||||
| 		w.nbits -= 8 | ||||
| 	} | ||||
| 	w.dst = append(w.dst, b...) | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) getPos() uint { | ||||
| 	return uint(len(w.dst)<<3) + w.nbits | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) rewind(p uint) { | ||||
| 	w.bits = uint64(w.dst[p>>3] & byte((1<<(p&7))-1)) | ||||
| 	w.nbits = p & 7 | ||||
| 	w.dst = w.dst[:p>>3] | ||||
| } | ||||
|  | ||||
| func (w *bitWriter) updateBits(n_bits uint, bits uint32, pos uint) { | ||||
| 	for n_bits > 0 { | ||||
| 		var byte_pos uint = pos >> 3 | ||||
| 		var n_unchanged_bits uint = pos & 7 | ||||
| 		var n_changed_bits uint = brotli_min_size_t(n_bits, 8-n_unchanged_bits) | ||||
| 		var total_bits uint = n_unchanged_bits + n_changed_bits | ||||
| 		var mask uint32 = (^((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1) | ||||
| 		var unchanged_bits uint32 = uint32(w.dst[byte_pos]) & mask | ||||
| 		var changed_bits uint32 = bits & ((1 << n_changed_bits) - 1) | ||||
| 		w.dst[byte_pos] = byte(changed_bits<<n_unchanged_bits | unchanged_bits) | ||||
| 		n_bits -= n_changed_bits | ||||
| 		bits >>= n_changed_bits | ||||
| 		pos += n_changed_bits | ||||
| 	} | ||||
| func writeBitsPrepareStorage(pos uint, array []byte) { | ||||
| 	assert(pos&7 == 0) | ||||
| 	array[pos>>3] = 0 | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/andybalholm/cascadia/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/andybalholm/cascadia/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,5 @@ | ||||
| module "github.com/andybalholm/cascadia" | ||||
| module github.com/andybalholm/cascadia | ||||
|  | ||||
| require "golang.org/x/net" v0.0.0-20180218175443-cbe0f9307d01 | ||||
| require golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01 | ||||
|  | ||||
| go 1.13 | ||||
|   | ||||
							
								
								
									
										93
									
								
								vendor/github.com/andybalholm/cascadia/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/andybalholm/cascadia/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,6 +13,10 @@ import ( | ||||
| type parser struct { | ||||
| 	s string // the source text | ||||
| 	i int    // the current position | ||||
|  | ||||
| 	// if `false`, parsing a pseudo-element | ||||
| 	// returns an error. | ||||
| 	acceptPseudoElements bool | ||||
| } | ||||
|  | ||||
| // parseEscape parses a backslash escape. | ||||
| @@ -29,7 +33,7 @@ func (p *parser) parseEscape() (result string, err error) { | ||||
| 	case hexDigit(c): | ||||
| 		// unicode escape (hex) | ||||
| 		var i int | ||||
| 		for i = start; i < p.i+6 && i < len(p.s) && hexDigit(p.s[i]); i++ { | ||||
| 		for i = start; i < start+6 && i < len(p.s) && hexDigit(p.s[i]); i++ { | ||||
| 			// empty | ||||
| 		} | ||||
| 		v, _ := strconv.ParseUint(p.s[start:i], 16, 21) | ||||
| @@ -422,17 +426,25 @@ var errExpectedParenthesis = errors.New("expected '(' but didn't find it") | ||||
| var errExpectedClosingParenthesis = errors.New("expected ')' but didn't find it") | ||||
| var errUnmatchedParenthesis = errors.New("unmatched '('") | ||||
|  | ||||
| // parsePseudoclassSelector parses a pseudoclass selector like :not(p) | ||||
| func (p *parser) parsePseudoclassSelector() (out Sel, err error) { | ||||
| // parsePseudoclassSelector parses a pseudoclass selector like :not(p) or a pseudo-element | ||||
| // For backwards compatibility, both ':' and '::' prefix are allowed for pseudo-elements. | ||||
| // https://drafts.csswg.org/selectors-3/#pseudo-elements | ||||
| // Returning a nil `Sel` (and a nil `error`) means we found a pseudo-element. | ||||
| func (p *parser) parsePseudoclassSelector() (out Sel, pseudoElement string, err error) { | ||||
| 	if p.i >= len(p.s) { | ||||
| 		return nil, fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead") | ||||
| 		return nil, "", fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead") | ||||
| 	} | ||||
| 	if p.s[p.i] != ':' { | ||||
| 		return nil, fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i]) | ||||
| 		return nil, "", fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i]) | ||||
| 	} | ||||
|  | ||||
| 	p.i++ | ||||
| 	var mustBePseudoElement bool | ||||
| 	if p.i >= len(p.s) { | ||||
| 		return nil, "", fmt.Errorf("got empty pseudoclass (or pseudoelement)") | ||||
| 	} | ||||
| 	if p.s[p.i] == ':' { // we found a pseudo-element | ||||
| 		mustBePseudoElement = true | ||||
| 		p.i++ | ||||
| 	} | ||||
|  | ||||
| @@ -441,27 +453,33 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) { | ||||
| 		return | ||||
| 	} | ||||
| 	name = toLowerASCII(name) | ||||
| 	if mustBePseudoElement && (name != "after" && name != "backdrop" && name != "before" && | ||||
| 		name != "cue" && name != "first-letter" && name != "first-line" && name != "grammar-error" && | ||||
| 		name != "marker" && name != "placeholder" && name != "selection" && name != "spelling-error") { | ||||
| 		return out, "", fmt.Errorf("unknown pseudoelement :%s", name) | ||||
| 	} | ||||
|  | ||||
| 	switch name { | ||||
| 	case "not", "has", "haschild": | ||||
| 		if !p.consumeParenthesis() { | ||||
| 			return out, errExpectedParenthesis | ||||
| 			return out, "", errExpectedParenthesis | ||||
| 		} | ||||
| 		sel, parseErr := p.parseSelectorGroup() | ||||
| 		if parseErr != nil { | ||||
| 			return out, parseErr | ||||
| 			return out, "", parseErr | ||||
| 		} | ||||
| 		if !p.consumeClosingParenthesis() { | ||||
| 			return out, errExpectedClosingParenthesis | ||||
| 			return out, "", errExpectedClosingParenthesis | ||||
| 		} | ||||
|  | ||||
| 		out = relativePseudoClassSelector{name: name, match: sel} | ||||
|  | ||||
| 	case "contains", "containsown": | ||||
| 		if !p.consumeParenthesis() { | ||||
| 			return out, errExpectedParenthesis | ||||
| 			return out, "", errExpectedParenthesis | ||||
| 		} | ||||
| 		if p.i == len(p.s) { | ||||
| 			return out, errUnmatchedParenthesis | ||||
| 			return out, "", errUnmatchedParenthesis | ||||
| 		} | ||||
| 		var val string | ||||
| 		switch p.s[p.i] { | ||||
| @@ -471,46 +489,46 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) { | ||||
| 			val, err = p.parseIdentifier() | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return out, err | ||||
| 			return out, "", err | ||||
| 		} | ||||
| 		val = strings.ToLower(val) | ||||
| 		p.skipWhitespace() | ||||
| 		if p.i >= len(p.s) { | ||||
| 			return out, errors.New("unexpected EOF in pseudo selector") | ||||
| 			return out, "", errors.New("unexpected EOF in pseudo selector") | ||||
| 		} | ||||
| 		if !p.consumeClosingParenthesis() { | ||||
| 			return out, errExpectedClosingParenthesis | ||||
| 			return out, "", errExpectedClosingParenthesis | ||||
| 		} | ||||
|  | ||||
| 		out = containsPseudoClassSelector{own: name == "containsown", value: val} | ||||
|  | ||||
| 	case "matches", "matchesown": | ||||
| 		if !p.consumeParenthesis() { | ||||
| 			return out, errExpectedParenthesis | ||||
| 			return out, "", errExpectedParenthesis | ||||
| 		} | ||||
| 		rx, err := p.parseRegex() | ||||
| 		if err != nil { | ||||
| 			return out, err | ||||
| 			return out, "", err | ||||
| 		} | ||||
| 		if p.i >= len(p.s) { | ||||
| 			return out, errors.New("unexpected EOF in pseudo selector") | ||||
| 			return out, "", errors.New("unexpected EOF in pseudo selector") | ||||
| 		} | ||||
| 		if !p.consumeClosingParenthesis() { | ||||
| 			return out, errExpectedClosingParenthesis | ||||
| 			return out, "", errExpectedClosingParenthesis | ||||
| 		} | ||||
|  | ||||
| 		out = regexpPseudoClassSelector{own: name == "matchesown", regexp: rx} | ||||
|  | ||||
| 	case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type": | ||||
| 		if !p.consumeParenthesis() { | ||||
| 			return out, errExpectedParenthesis | ||||
| 			return out, "", errExpectedParenthesis | ||||
| 		} | ||||
| 		a, b, err := p.parseNth() | ||||
| 		if err != nil { | ||||
| 			return out, err | ||||
| 			return out, "", err | ||||
| 		} | ||||
| 		if !p.consumeClosingParenthesis() { | ||||
| 			return out, errExpectedClosingParenthesis | ||||
| 			return out, "", errExpectedClosingParenthesis | ||||
| 		} | ||||
| 		last := name == "nth-last-child" || name == "nth-last-of-type" | ||||
| 		ofType := name == "nth-of-type" || name == "nth-last-of-type" | ||||
| @@ -535,9 +553,9 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) { | ||||
| 	case "root": | ||||
| 		out = rootPseudoClassSelector{} | ||||
| 	case "after", "backdrop", "before", "cue", "first-letter", "first-line", "grammar-error", "marker", "placeholder", "selection", "spelling-error": | ||||
| 		return out, errors.New("pseudo-elements are not yet supported") | ||||
| 		return nil, name, nil | ||||
| 	default: | ||||
| 		return out, fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name) | ||||
| 		return out, "", fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| @@ -706,11 +724,13 @@ func (p *parser) parseSimpleSelectorSequence() (Sel, error) { | ||||
| 		selectors = append(selectors, r) | ||||
| 	} | ||||
|  | ||||
| 	var pseudoElement string | ||||
| loop: | ||||
| 	for p.i < len(p.s) { | ||||
| 		var ( | ||||
| 			ns  Sel | ||||
| 			err error | ||||
| 			ns               Sel | ||||
| 			newPseudoElement string | ||||
| 			err              error | ||||
| 		) | ||||
| 		switch p.s[p.i] { | ||||
| 		case '#': | ||||
| @@ -720,20 +740,37 @@ loop: | ||||
| 		case '[': | ||||
| 			ns, err = p.parseAttributeSelector() | ||||
| 		case ':': | ||||
| 			ns, err = p.parsePseudoclassSelector() | ||||
| 			ns, newPseudoElement, err = p.parsePseudoclassSelector() | ||||
| 		default: | ||||
| 			break loop | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		// From https://drafts.csswg.org/selectors-3/#pseudo-elements : | ||||
| 		// "Only one pseudo-element may appear per selector, and if present | ||||
| 		// it must appear after the sequence of simple selectors that | ||||
| 		// represents the subjects of the selector."" | ||||
| 		if ns == nil { // we found a pseudo-element | ||||
| 			if pseudoElement != "" { | ||||
| 				return nil, fmt.Errorf("only one pseudo-element is accepted per selector, got %s and %s", pseudoElement, newPseudoElement) | ||||
| 			} | ||||
| 			if !p.acceptPseudoElements { | ||||
| 				return nil, fmt.Errorf("pseudo-element %s found, but pseudo-elements support is disabled", newPseudoElement) | ||||
| 			} | ||||
| 			pseudoElement = newPseudoElement | ||||
| 		} else { | ||||
| 			if pseudoElement != "" { | ||||
| 				return nil, fmt.Errorf("pseudo-element %s must be at the end of selector", pseudoElement) | ||||
| 			} | ||||
| 			selectors = append(selectors, ns) | ||||
| 		} | ||||
|  | ||||
| 		selectors = append(selectors, ns) | ||||
| 	} | ||||
| 	if len(selectors) == 1 { // no need wrap the selectors in compoundSelector | ||||
| 	if len(selectors) == 1 && pseudoElement == "" { // no need wrap the selectors in compoundSelector | ||||
| 		return selectors[0], nil | ||||
| 	} | ||||
| 	return compoundSelector{selectors: selectors}, nil | ||||
| 	return compoundSelector{selectors: selectors, pseudoElement: pseudoElement}, nil | ||||
| } | ||||
|  | ||||
| // parseSelector parses a selector that may include combinators. | ||||
|   | ||||
							
								
								
									
										113
									
								
								vendor/github.com/andybalholm/cascadia/selector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								vendor/github.com/andybalholm/cascadia/selector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -16,14 +16,19 @@ type Matcher interface { | ||||
| } | ||||
|  | ||||
| // Sel is the interface for all the functionality provided by selectors. | ||||
| // It is currently the same as Matcher, but other methods may be added in the | ||||
| // future. | ||||
| type Sel interface { | ||||
| 	Matcher | ||||
| 	Specificity() Specificity | ||||
|  | ||||
| 	// Returns a CSS input compiling to this selector. | ||||
| 	String() string | ||||
|  | ||||
| 	// Returns a pseudo-element, or an empty string. | ||||
| 	PseudoElement() string | ||||
| } | ||||
|  | ||||
| // Parse parses a selector. | ||||
| // Parse parses a selector. Use `ParseWithPseudoElement` | ||||
| // if you need support for pseudo-elements. | ||||
| func Parse(sel string) (Sel, error) { | ||||
| 	p := &parser{s: sel} | ||||
| 	compiled, err := p.parseSelector() | ||||
| @@ -38,7 +43,25 @@ func Parse(sel string) (Sel, error) { | ||||
| 	return compiled, nil | ||||
| } | ||||
|  | ||||
| // ParseWithPseudoElement parses a single selector, | ||||
| // with support for pseudo-element. | ||||
| func ParseWithPseudoElement(sel string) (Sel, error) { | ||||
| 	p := &parser{s: sel, acceptPseudoElements: true} | ||||
| 	compiled, err := p.parseSelector() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if p.i < len(sel) { | ||||
| 		return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i) | ||||
| 	} | ||||
|  | ||||
| 	return compiled, nil | ||||
| } | ||||
|  | ||||
| // ParseGroup parses a selector, or a group of selectors separated by commas. | ||||
| // Use `ParseGroupWithPseudoElements` | ||||
| // if you need support for pseudo-elements. | ||||
| func ParseGroup(sel string) (SelectorGroup, error) { | ||||
| 	p := &parser{s: sel} | ||||
| 	compiled, err := p.parseSelectorGroup() | ||||
| @@ -53,6 +76,22 @@ func ParseGroup(sel string) (SelectorGroup, error) { | ||||
| 	return compiled, nil | ||||
| } | ||||
|  | ||||
| // ParseGroupWithPseudoElements parses a selector, or a group of selectors separated by commas. | ||||
| // It supports pseudo-elements. | ||||
| func ParseGroupWithPseudoElements(sel string) (SelectorGroup, error) { | ||||
| 	p := &parser{s: sel, acceptPseudoElements: true} | ||||
| 	compiled, err := p.parseSelectorGroup() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if p.i < len(sel) { | ||||
| 		return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i) | ||||
| 	} | ||||
|  | ||||
| 	return compiled, nil | ||||
| } | ||||
|  | ||||
| // A Selector is a function which tells whether a node matches or not. | ||||
| // | ||||
| // This type is maintained for compatibility; I recommend using the newer and | ||||
| @@ -182,6 +221,10 @@ func (c tagSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 0, 1} | ||||
| } | ||||
|  | ||||
| func (c tagSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type classSelector struct { | ||||
| 	class string | ||||
| } | ||||
| @@ -197,6 +240,10 @@ func (c classSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c classSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type idSelector struct { | ||||
| 	id string | ||||
| } | ||||
| @@ -212,6 +259,10 @@ func (c idSelector) Specificity() Specificity { | ||||
| 	return Specificity{1, 0, 0} | ||||
| } | ||||
|  | ||||
| func (c idSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type attrSelector struct { | ||||
| 	key, val, operation string | ||||
| 	regexp              *regexp.Regexp | ||||
| @@ -352,6 +403,10 @@ func (c attrSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c attrSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| // ---------------- Pseudo class selectors ---------------- | ||||
| // we use severals concrete types of pseudo-class selectors | ||||
|  | ||||
| @@ -415,6 +470,10 @@ func (s relativePseudoClassSelector) Specificity() Specificity { | ||||
| 	return max | ||||
| } | ||||
|  | ||||
| func (c relativePseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type containsPseudoClassSelector struct { | ||||
| 	own   bool | ||||
| 	value string | ||||
| @@ -436,6 +495,10 @@ func (s containsPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c containsPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type regexpPseudoClassSelector struct { | ||||
| 	own    bool | ||||
| 	regexp *regexp.Regexp | ||||
| @@ -488,6 +551,10 @@ func (s regexpPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c regexpPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type nthPseudoClassSelector struct { | ||||
| 	a, b         int | ||||
| 	last, ofType bool | ||||
| @@ -623,6 +690,10 @@ func (s nthPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c nthPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type onlyChildPseudoClassSelector struct { | ||||
| 	ofType bool | ||||
| } | ||||
| @@ -661,6 +732,10 @@ func (s onlyChildPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c onlyChildPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type inputPseudoClassSelector struct{} | ||||
|  | ||||
| // Matches input, select, textarea and button elements. | ||||
| @@ -672,6 +747,10 @@ func (s inputPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c inputPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type emptyElementPseudoClassSelector struct{} | ||||
|  | ||||
| // Matches empty elements. | ||||
| @@ -694,6 +773,10 @@ func (s emptyElementPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c emptyElementPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type rootPseudoClassSelector struct{} | ||||
|  | ||||
| // Match implements :root | ||||
| @@ -711,8 +794,13 @@ func (s rootPseudoClassSelector) Specificity() Specificity { | ||||
| 	return Specificity{0, 1, 0} | ||||
| } | ||||
|  | ||||
| func (c rootPseudoClassSelector) PseudoElement() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| type compoundSelector struct { | ||||
| 	selectors []Sel | ||||
| 	selectors     []Sel | ||||
| 	pseudoElement string | ||||
| } | ||||
|  | ||||
| // Matches elements if each sub-selectors matches. | ||||
| @@ -734,9 +822,17 @@ func (s compoundSelector) Specificity() Specificity { | ||||
| 	for _, sel := range s.selectors { | ||||
| 		out = out.Add(sel.Specificity()) | ||||
| 	} | ||||
| 	if s.pseudoElement != "" { | ||||
| 		// https://drafts.csswg.org/selectors-3/#specificity | ||||
| 		out = out.Add(Specificity{0, 0, 1}) | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (c compoundSelector) PseudoElement() string { | ||||
| 	return c.pseudoElement | ||||
| } | ||||
|  | ||||
| type combinedSelector struct { | ||||
| 	first      Sel | ||||
| 	combinator byte | ||||
| @@ -818,6 +914,15 @@ func (s combinedSelector) Specificity() Specificity { | ||||
| 	return spec | ||||
| } | ||||
|  | ||||
| // on combinedSelector, a pseudo-element only makes sens on the last | ||||
| // selector, although others increase specificity. | ||||
| func (c combinedSelector) PseudoElement() string { | ||||
| 	if c.second == nil { | ||||
| 		return "" | ||||
| 	} | ||||
| 	return c.second.PseudoElement() | ||||
| } | ||||
|  | ||||
| // A SelectorGroup is a list of selectors, which matches if any of the | ||||
| // individual selectors matches. | ||||
| type SelectorGroup []Sel | ||||
|   | ||||
							
								
								
									
										120
									
								
								vendor/github.com/andybalholm/cascadia/serialize.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								vendor/github.com/andybalholm/cascadia/serialize.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| package cascadia | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // implements the reverse operation Sel -> string | ||||
|  | ||||
| func (c tagSelector) String() string { | ||||
| 	return c.tag | ||||
| } | ||||
|  | ||||
| func (c idSelector) String() string { | ||||
| 	return "#" + c.id | ||||
| } | ||||
|  | ||||
| func (c classSelector) String() string { | ||||
| 	return "." + c.class | ||||
| } | ||||
|  | ||||
| func (c attrSelector) String() string { | ||||
| 	val := c.val | ||||
| 	if c.operation == "#=" { | ||||
| 		val = c.regexp.String() | ||||
| 	} else if c.operation != "" { | ||||
| 		val = fmt.Sprintf(`"%s"`, val) | ||||
| 	} | ||||
| 	return fmt.Sprintf(`[%s%s%s]`, c.key, c.operation, val) | ||||
| } | ||||
|  | ||||
| func (c relativePseudoClassSelector) String() string { | ||||
| 	return fmt.Sprintf(":%s(%s)", c.name, c.match.String()) | ||||
| } | ||||
| func (c containsPseudoClassSelector) String() string { | ||||
| 	s := "contains" | ||||
| 	if c.own { | ||||
| 		s += "Own" | ||||
| 	} | ||||
| 	return fmt.Sprintf(`:%s("%s")`, s, c.value) | ||||
| } | ||||
| func (c regexpPseudoClassSelector) String() string { | ||||
| 	s := "matches" | ||||
| 	if c.own { | ||||
| 		s += "Own" | ||||
| 	} | ||||
| 	return fmt.Sprintf(":%s(%s)", s, c.regexp.String()) | ||||
| } | ||||
| func (c nthPseudoClassSelector) String() string { | ||||
| 	if c.a == 0 && c.b == 1 { // special cases | ||||
| 		s := ":first-" | ||||
| 		if c.last { | ||||
| 			s = ":last-" | ||||
| 		} | ||||
| 		if c.ofType { | ||||
| 			s += "of-type" | ||||
| 		} else { | ||||
| 			s += "child" | ||||
| 		} | ||||
| 		return s | ||||
| 	} | ||||
| 	var name string | ||||
| 	switch [2]bool{c.last, c.ofType} { | ||||
| 	case [2]bool{true, true}: | ||||
| 		name = "nth-last-of-type" | ||||
| 	case [2]bool{true, false}: | ||||
| 		name = "nth-last-child" | ||||
| 	case [2]bool{false, true}: | ||||
| 		name = "nth-of-type" | ||||
| 	case [2]bool{false, false}: | ||||
| 		name = "nth-child" | ||||
| 	} | ||||
| 	return fmt.Sprintf(":%s(%dn+%d)", name, c.a, c.b) | ||||
| } | ||||
| func (c onlyChildPseudoClassSelector) String() string { | ||||
| 	if c.ofType { | ||||
| 		return ":only-of-type" | ||||
| 	} | ||||
| 	return ":only-child" | ||||
| } | ||||
| func (c inputPseudoClassSelector) String() string { | ||||
| 	return ":input" | ||||
| } | ||||
| func (c emptyElementPseudoClassSelector) String() string { | ||||
| 	return ":empty" | ||||
| } | ||||
| func (c rootPseudoClassSelector) String() string { | ||||
| 	return ":root" | ||||
| } | ||||
|  | ||||
| func (c compoundSelector) String() string { | ||||
| 	if len(c.selectors) == 0 && c.pseudoElement == "" { | ||||
| 		return "*" | ||||
| 	} | ||||
| 	chunks := make([]string, len(c.selectors)) | ||||
| 	for i, sel := range c.selectors { | ||||
| 		chunks[i] = sel.String() | ||||
| 	} | ||||
| 	s := strings.Join(chunks, "") | ||||
| 	if c.pseudoElement != "" { | ||||
| 		s += "::" + c.pseudoElement | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| func (c combinedSelector) String() string { | ||||
| 	start := c.first.String() | ||||
| 	if c.second != nil { | ||||
| 		start += fmt.Sprintf(" %s %s", string(c.combinator), c.second.String()) | ||||
| 	} | ||||
| 	return start | ||||
| } | ||||
|  | ||||
| func (c SelectorGroup) String() string { | ||||
| 	ck := make([]string, len(c)) | ||||
| 	for i, s := range c { | ||||
| 		ck[i] = s.String() | ||||
| 	} | ||||
| 	return strings.Join(ck, ", ") | ||||
| } | ||||
		Reference in New Issue
	
	Block a user