internal virtual void WriteHeader(bool reverse, int cleanLength, int dirtyLength) { int cleanLengthMinus2 = cleanLength - 2; Debug.Assert(cleanLengthMinus2 >= 0); Debug.Assert(dirtyLength >= 0); int token = ((cleanLengthMinus2 & 0x03) << 4) | (dirtyLength & 0x07); if (reverse) { token |= 1 << 7; } if (cleanLengthMinus2 > 0x03) { token |= 1 << 6; } if (dirtyLength > 0x07) { token |= 1 << 3; } @out.WriteByte((byte)(sbyte)token); if (cleanLengthMinus2 > 0x03) { @out.WriteVInt32((int)((uint)cleanLengthMinus2 >> 2)); } if (dirtyLength > 0x07) { @out.WriteVInt32((int)((uint)dirtyLength >> 3)); } }
internal virtual void AddWord(int wordNum, byte word) { Debug.Assert(wordNum > lastWordNum); Debug.Assert(word != 0); if (!reverse) { if (lastWordNum == -1) { clean = 2 + wordNum; // special case for the 1st sequence dirtyWords.WriteByte(word); } else { switch (wordNum - lastWordNum) { case 1: if (word == 0xFF && (byte)dirtyWords.Bytes[dirtyWords.Length - 1] == 0xFF) { --dirtyWords.Length; WriteSequence(); reverse = true; clean = 2; } else { dirtyWords.WriteByte(word); } break; case 2: dirtyWords.WriteByte(0); dirtyWords.WriteByte(word); break; default: WriteSequence(); clean = wordNum - lastWordNum - 1; dirtyWords.WriteByte(word); break; } } } else { Debug.Assert(lastWordNum >= 0); switch (wordNum - lastWordNum) { case 1: if (word == 0xFF) { if (dirtyWords.Length == 0) { ++clean; } else if ((byte)dirtyWords.Bytes[dirtyWords.Length - 1] == 0xFF) { --dirtyWords.Length; WriteSequence(); clean = 2; } else { dirtyWords.WriteByte(word); } } else { dirtyWords.WriteByte(word); } break; case 2: dirtyWords.WriteByte(0); dirtyWords.WriteByte(word); break; default: WriteSequence(); reverse = false; clean = wordNum - lastWordNum - 1; dirtyWords.WriteByte(word); break; } } lastWordNum = wordNum; cardinality += BitUtil.BitCount(word); }