public static size_t ReadNCount()

in csharp/src/EntropyCommon.cs [79:188]


		public static size_t ReadNCount(short[] normalizedCounter, uint* maxSVPtr, uint* tableLogPtr, void* headerBuffer, size_t hbSize)
		{
			BYTE* istart = (BYTE*)headerBuffer;
			BYTE* iend = istart + hbSize;
			BYTE* ip = istart;
			int nbBits;
			int remaining;
			int threshold;
			U32 bitStream;
			int bitCount;
			uint charnum = 0;
			int previous0 = 0;

			if (hbSize < 4) return ERROR(Error.srcSize_wrong);
			bitStream = MEM_readLE32(ip);
			nbBits = (int)(bitStream & 0xF) + Fse.FSE_MIN_TABLELOG;   /* extract tableLog */
			if (nbBits > Fse.FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(Error.tableLog_tooLarge);
			bitStream >>= 4;
			bitCount = 4;
			*tableLogPtr = (size_t)nbBits;
			remaining = (1 << nbBits) + 1;
			threshold = 1 << nbBits;
			nbBits++;

			while ((remaining > 1) & (charnum <= *maxSVPtr))
			{
				if (previous0 != 0)
				{
					uint n0 = charnum;
					while ((bitStream & 0xFFFF) == 0xFFFF)
					{
						n0 += 24;
						if (ip < iend - 5)
						{
							ip += 2;
							bitStream = MEM_readLE32(ip) >> bitCount;
						}
						else
						{
							bitStream >>= 16;
							bitCount += 16;
						}
					}
					while ((bitStream & 3) == 3)
					{
						n0 += 3;
						bitStream >>= 2;
						bitCount += 2;
					}
					n0 += bitStream & 3;
					bitCount += 2;
					if (n0 > *maxSVPtr) return ERROR(Error.maxSymbolValue_tooSmall);
					while (charnum < n0) normalizedCounter[charnum++] = 0;
					if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4))
					{
						ip += bitCount >> 3;
						bitCount &= 7;
						bitStream = MEM_readLE32(ip) >> bitCount;
					}
					else
					{
						bitStream >>= 2;
					}
				}
				{
					int max = (2 * threshold - 1) - remaining;
					int count;

					if ((bitStream & (threshold - 1)) < (U32)max)
					{
						count = (int)bitStream & (threshold - 1);
						bitCount += nbBits - 1;
					}
					else
					{
						count = (int)bitStream & (2 * threshold - 1);
						if (count >= threshold) count -= max;
						bitCount += nbBits;
					}

					count--;   /* extra accuracy */
					remaining -= count < 0 ? -count : count;   /* -1 means +1 */
					normalizedCounter[charnum++] = (short)count;
					previous0 = count == 0 ? 1 : 0;
					while (remaining < threshold)
					{
						nbBits--;
						threshold >>= 1;
					}

					if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4))
					{
						ip += bitCount >> 3;
						bitCount &= 7;
					}
					else
					{
						bitCount -= (int)(8 * (iend - 4 - ip));
						ip = iend - 4;
					}
					bitStream = MEM_readLE32(ip) >> (bitCount & 31);
				}
			}   /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
			if (remaining != 1) return ERROR(Error.corruption_detected);
			if (bitCount > 32) return ERROR(Error.corruption_detected);
			*maxSVPtr = charnum - 1;

			ip += (bitCount + 7) >> 3;
			return (size_t)(ip - istart);
		}