static size_t DecodeLiteralsBlock()

in csharp/src/ZStdDecompress.cs [683:821]


		static size_t DecodeLiteralsBlock(ZSTD_DCtx dctx, void* src, size_t srcSize)   /* note : srcSize < BLOCKSIZE */
		{
			if (srcSize < MIN_CBLOCK_SIZE) return ERROR(Error.corruption_detected);

			{
				BYTE* istart = (BYTE*)src;
				symbolEncodingType_e litEncType = (symbolEncodingType_e)(istart[0] & 3);

				switch (litEncType)
				{
					case symbolEncodingType_e.set_repeat:
					case symbolEncodingType_e.set_compressed:
						/* fall-through */
						if (litEncType == symbolEncodingType_e.set_repeat)
							if (dctx.litEntropy == 0) return ERROR(Error.dictionary_corrupted);

						if (srcSize < 5) return ERROR(Error.corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
						{
							size_t lhSize, litSize, litCSize;
							bool singleStream = false;
							U32 lhlCode = ((U32)istart[0] >> 2) & 3;
							U32 lhc = MEM_readLE32(istart);
							switch (lhlCode)
							{
								case 0:
								case 1:
								default:   /* note : default is impossible, since lhlCode into [0..3] */
										   /* 2 - 2 - 10 - 10 */
									singleStream = lhlCode == 0;
									lhSize = 3;
									litSize = (lhc >> 4) & 0x3FF;
									litCSize = (lhc >> 14) & 0x3FF;
									break;
								case 2:
									/* 2 - 2 - 14 - 14 */
									lhSize = 4;
									litSize = (lhc >> 4) & 0x3FFF;
									litCSize = lhc >> 18;
									break;
								case 3:
									/* 2 - 2 - 18 - 18 */
									lhSize = 5;
									litSize = (lhc >> 4) & 0x3FFFF;
									litCSize = (lhc >> 22) + ((U32)istart[4] << 10);
									break;
							}
							if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(Error.corruption_detected);
							if (litCSize + lhSize > srcSize) return ERROR(Error.corruption_detected);

							if (IsError((litEncType == symbolEncodingType_e.set_repeat) ?
												(singleStream ?
													 HUF_decompress1X_usingDTable_bmi2(dctx.litBuffer, litSize, istart + lhSize, litCSize, dctx.HUFptr/*, dctx.bmi2*/) :
													 HUF_decompress4X_usingDTable_bmi2(dctx.litBuffer, litSize, istart + lhSize, litCSize, dctx.HUFptr/*, dctx.bmi2*/)) :
												(singleStream ?
													 HUF_decompress1X2_DCtx_wksp_bmi2(dctx.entropy.hufTable, dctx.litBuffer, litSize, istart + lhSize, litCSize,
																					 dctx.entropy.workspace, sizeof(U32) * HUF_DECOMPRESS_WORKSPACE_SIZE_U32/*, dctx.bmi2*/) :

													 HUF_decompress4X_hufOnly_wksp_bmi2(dctx.entropy.hufTable, dctx.litBuffer, litSize, istart + lhSize, litCSize,
																					   dctx.entropy.workspace, sizeof(U32) * HUF_DECOMPRESS_WORKSPACE_SIZE_U32/*, dctx.bmi2*/))))
								return ERROR(Error.corruption_detected);

							dctx.litPtr = dctx.litBuffer;
							dctx.litSize = litSize;
							dctx.litEntropy = 1;
							if (litEncType == symbolEncodingType_e.set_compressed) dctx.HUFptr = dctx.entropy.hufTable;
							memset(dctx.litBuffer + dctx.litSize, 0, WILDCOPY_OVERLENGTH);
							return litCSize + lhSize;
						}

					case symbolEncodingType_e.set_basic:
						{
							size_t litSize, lhSize;
							U32 lhlCode = ((U32)istart[0] >> 2) & 3;
							switch (lhlCode)
							{
								case 0:
								case 2:
								default:   /* note : default is impossible, since lhlCode into [0..3] */
									lhSize = 1;
									litSize = (U32)istart[0] >> 3;
									break;
								case 1:
									lhSize = 2;
									litSize = MEM_readLE16(istart) >> 4;
									break;
								case 3:
									lhSize = 3;
									litSize = MEM_readLE24(istart) >> 4;
									break;
							}

							if (lhSize + litSize + WILDCOPY_OVERLENGTH > srcSize)
							{  /* risk reading beyond src buffer with wildcopy */
								if (litSize + lhSize > srcSize) return ERROR(Error.corruption_detected);
								memcpy(dctx.litBuffer, istart + lhSize, litSize);
								dctx.litPtr = dctx.litBuffer;
								dctx.litSize = litSize;
								memset(dctx.litBuffer + dctx.litSize, 0, WILDCOPY_OVERLENGTH);
								return lhSize + litSize;
							}
							/* direct reference into compressed stream */
							dctx.litPtr = istart + lhSize;
							dctx.litSize = litSize;
							return lhSize + litSize;
						}

					case symbolEncodingType_e.set_rle:
						{
							U32 lhlCode = ((U32)istart[0] >> 2) & 3;
							size_t litSize, lhSize;
							switch (lhlCode)
							{
								case 0:
								case 2:
								default:   /* note : default is impossible, since lhlCode into [0..3] */
									lhSize = 1;
									litSize = (U32)istart[0] >> 3;
									break;
								case 1:
									lhSize = 2;
									litSize = MEM_readLE16(istart) >> 4;
									break;
								case 3:
									lhSize = 3;
									litSize = MEM_readLE24(istart) >> 4;
									if (srcSize < 4) return ERROR(Error.corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
									break;
							}
							if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(Error.corruption_detected);
							memset(dctx.litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
							dctx.litPtr = dctx.litBuffer;
							dctx.litSize = litSize;
							return lhSize + 1;
						}
					default:
						return ERROR(Error.corruption_detected);   /* impossible */
				}
			}
		}