Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1455 lines
41 KiB

  1. #include "precomp.h"
  2. //
  3. // GDC.CPP
  4. // General Data Compressor
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_NET
  9. //
  10. // Tables used by the compression / decompression algorithms
  11. //
  12. const BYTE s_gdcExLenBits[GDC_LEN_SIZE] =
  13. {
  14. 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8
  15. };
  16. const WORD s_gdcLenBase[GDC_LEN_SIZE] =
  17. {
  18. 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 14, 22, 38, 70, 134, 262
  19. };
  20. //
  21. // Dist: Bits, Coded, Decoded
  22. //
  23. const BYTE s_gdcDistBits[GDC_DIST_SIZE] =
  24. {
  25. 2, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  26. 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  27. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  28. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  29. };
  30. const BYTE s_gdcDistCode[GDC_DIST_SIZE] =
  31. {
  32. 0x03, 0x0d, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3e,
  33. 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06, 0x3a,
  34. 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x42, 0x02,
  35. 0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c,
  36. 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04,
  37. 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
  38. 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
  39. 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
  40. };
  41. //
  42. // Len: Bits, Coded, Decoded
  43. //
  44. const BYTE s_gdcLenBits[GDC_LEN_SIZE] =
  45. {
  46. 3, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7
  47. };
  48. const BYTE s_gdcLenCode[GDC_LEN_SIZE] =
  49. {
  50. 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14,
  51. 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
  52. };
  53. //
  54. // GDC_Init()
  55. //
  56. // BOGUS LAURABU:
  57. // Having one global scratch compression buffer is lousy in multiple
  58. // conference situations. Maybe allocate it or use caching scheme in
  59. // future, then get rid of mutex.
  60. //
  61. void GDC_Init(void)
  62. {
  63. UINT i, j, k;
  64. DebugEntry(GDC_Init);
  65. //
  66. // Set up the binary data used for PDC compression. We 'calculate'
  67. // these since putting this in raw const data is too complicated!
  68. // The LitBits/LitCodes arrays have 774 entries each, and
  69. // the LenBits/DistBits arrays have 256 entries.
  70. //
  71. // Non-compressed chars take 9 bits in the compressed version: one
  72. // bit (zero) to indicate that what follows is not a distance/size
  73. // code, then the 8 bits of the char.
  74. //
  75. for (k = 0; k < GDC_DECODED_SIZE; k++)
  76. {
  77. s_gdcLitBits[k] = 9;
  78. s_gdcLitCode[k] = (WORD)(k << 1);
  79. }
  80. for (i = 0; i < GDC_LEN_SIZE; i++)
  81. {
  82. for (j = 0; j < (1U << s_gdcExLenBits[i]); j++, k++)
  83. {
  84. s_gdcLitBits[k] = (BYTE)(s_gdcLenBits[i] + s_gdcExLenBits[i] + 1);
  85. s_gdcLitCode[k] = (WORD)((j << (s_gdcLenBits[i] + 1)) |
  86. (s_gdcLenCode[i] << 1) | 1);
  87. }
  88. }
  89. GDCCalcDecode(s_gdcLenBits, s_gdcLenCode, GDC_LEN_SIZE, s_gdcLenDecode);
  90. GDCCalcDecode(s_gdcDistBits, s_gdcDistCode, GDC_DIST_SIZE, s_gdcDistDecode);
  91. DebugExitVOID(GDC_Init);
  92. }
  93. //
  94. // GDCCalcDecode()
  95. // This calculates 'const' arrays for s_gdcLenDecode and s_gdcDistDecode.
  96. //
  97. void GDCCalcDecode
  98. (
  99. const BYTE * pSrcBits,
  100. const BYTE * pSrcCodes,
  101. UINT cSrc,
  102. LPBYTE pDstDecodes
  103. )
  104. {
  105. UINT j;
  106. UINT Incr;
  107. int i;
  108. DebugEntry(GDC_CalcDecode);
  109. for (i = cSrc-1; i >= 0; i--)
  110. {
  111. Incr = 1 << pSrcBits[i];
  112. j = pSrcCodes[i];
  113. do
  114. {
  115. pDstDecodes[j] = (BYTE)i;
  116. j += Incr;
  117. }
  118. while (j < GDC_DECODED_SIZE);
  119. }
  120. DebugExitVOID(GDC_CalcDecode);
  121. }
  122. //
  123. // Optimize compilation for speed (not space)
  124. //
  125. #pragma optimize ("s", off)
  126. #pragma optimize ("t", on)
  127. //
  128. // GDC_Compress()
  129. // Compresses data based on different options.
  130. // This compresses data using PKZIP for both persistent and non-persistent
  131. // types. The differences between the algorithms are few:
  132. // * Persistent compression is never used for sources > 4096 bytes
  133. // * We copy in & update saved dictionary data before starting
  134. // * We copy back updated dictionary data after ending
  135. // * One byte of the used DistBits is used for PDC, 2 bytes for
  136. // plain PKZIP compression in the resulting compressed packet.
  137. //
  138. BOOL GDC_Compress
  139. (
  140. PGDC_DICTIONARY pDictionary, // NULL if not persistent
  141. UINT Options, // Not meaningful if pDictionary
  142. LPBYTE pWorkBuf,
  143. LPBYTE pSrc,
  144. UINT cbSrcSize,
  145. LPBYTE pDst,
  146. UINT * pcbDstSize
  147. )
  148. {
  149. BOOL rc = FALSE;
  150. UINT Len;
  151. UINT cbRaw;
  152. UINT Passes;
  153. LPBYTE pCur;
  154. LPBYTE pMax;
  155. PGDC_IMPLODE pgdcImp;
  156. #ifdef _DEBUG
  157. UINT cbSrcOrg;
  158. #endif // _DEBUG
  159. DebugEntry(GDC_Compress);
  160. pgdcImp = (PGDC_IMPLODE)pWorkBuf;
  161. ASSERT(pgdcImp);
  162. #ifdef _DEBUG
  163. cbSrcOrg = cbSrcSize;
  164. #endif // _DEBUG
  165. //
  166. // Figure out what size dictionary to use.
  167. //
  168. if (pDictionary)
  169. pgdcImp->cbDictSize = GDC_DATA_MAX;
  170. else if (Options == GDCCO_MAXSPEED)
  171. {
  172. //
  173. // Use the smallest for max speed.
  174. //
  175. pgdcImp->cbDictSize = GDC_DATA_SMALL;
  176. }
  177. else
  178. {
  179. ASSERT(Options == GDCCO_MAXCOMPRESSION);
  180. //
  181. // Use the nearest dictionary size to the source size.
  182. //
  183. if (cbSrcSize <= GDC_DATA_SMALL)
  184. pgdcImp->cbDictSize = GDC_DATA_SMALL;
  185. else if (cbSrcSize <= GDC_DATA_MEDIUM)
  186. pgdcImp->cbDictSize = GDC_DATA_MEDIUM;
  187. else
  188. pgdcImp->cbDictSize = GDC_DATA_MAX;
  189. }
  190. //
  191. // How many bits of distance are needed to back the dictionary size
  192. // # of bytes?
  193. //
  194. switch (pgdcImp->cbDictSize)
  195. {
  196. case GDC_DATA_SMALL:
  197. pgdcImp->ExtDistBits = EXT_DIST_BITS_MIN;
  198. break;
  199. case GDC_DATA_MEDIUM:
  200. pgdcImp->ExtDistBits = EXT_DIST_BITS_MEDIUM;
  201. break;
  202. case GDC_DATA_MAX:
  203. pgdcImp->ExtDistBits = EXT_DIST_BITS_MAC;
  204. break;
  205. }
  206. pgdcImp->ExtDistMask = 0xFFFF >> (16 - pgdcImp->ExtDistBits);
  207. //
  208. // We need at least 4 bytes (2 max for ExtDistBits, 2 for EOF code).
  209. //
  210. ASSERT(*pcbDstSize > 4);
  211. //
  212. // Now save the destination info in our struct. That we we can just
  213. // pass a pointer to our GDC_IMPLODE routine around with everything
  214. // we need.
  215. //
  216. pgdcImp->pDst = pDst;
  217. pgdcImp->cbDst = *pcbDstSize;
  218. //
  219. // For non PDC compression, the first little-endian WORD is the ExtDistBits
  220. // used in decompression. For PDC compression, just the first BYTE is
  221. // the ExtDistBits.
  222. //
  223. if (!pDictionary)
  224. {
  225. *(pgdcImp->pDst)++ = 0;
  226. --(pgdcImp->cbDst);
  227. }
  228. *(pgdcImp->pDst)++ = (BYTE)pgdcImp->ExtDistBits;
  229. --(pgdcImp->cbDst);
  230. //
  231. // Since pDst could be huge, we don't zero it all out before using.
  232. // As the pointer into the destination advances, we zero out a byte
  233. // just before we start writing bits into it.
  234. //
  235. pgdcImp->iDstBit = 0;
  236. *(pgdcImp->pDst) = 0;
  237. //
  238. // Now, if we have a dictonary, restore the contents into our scratch
  239. // buffer.
  240. //
  241. if (pDictionary && pDictionary->cbUsed)
  242. {
  243. TRACE_OUT(("Restoring %u dictionary bytes before compression",
  244. pDictionary->cbUsed));
  245. //
  246. // NOTE: the data saved in pDictionary->pData is front aligned.
  247. // But the data in RawData is end aligned so that we can slide up
  248. // new data chunk by chunk when compressing. Therefore only copy
  249. // the part that is valid, but make it end at the back of the
  250. // space for the dictionary data.
  251. //
  252. ASSERT(pDictionary->cbUsed <= pgdcImp->cbDictSize);
  253. memcpy(pgdcImp->RawData + GDC_MAXREP + pgdcImp->cbDictSize - pDictionary->cbUsed,
  254. pDictionary->pData, pDictionary->cbUsed);
  255. pgdcImp->cbDictUsed = pDictionary->cbUsed;
  256. }
  257. else
  258. {
  259. pgdcImp->cbDictUsed = 0;
  260. }
  261. //
  262. // We only compress GDC_DATA_MAX bytes at a time. Therefore we have
  263. // this loop to grab at most that amount each time around. Since we
  264. // only persistently compress packets <= GDC_DATA_MAX, we should never
  265. // go through it more than once for that compression type. But normal
  266. // compression, you betcha since the max packet size is 32K.
  267. //
  268. Passes = 0;
  269. pCur = pgdcImp->RawData + GDC_MAXREP + pgdcImp->cbDictSize;
  270. do
  271. {
  272. //
  273. // cbRaw will either be GDC_DATA_MAX (if source has >= that to go)
  274. // or remainder. Copy that much uncompressed data into our
  275. // working RawData buffer in the 'new data' space.
  276. //
  277. ASSERT(cbSrcSize);
  278. cbRaw = min(cbSrcSize, GDC_DATA_MAX);
  279. memcpy(pgdcImp->RawData + GDC_MAXREP + pgdcImp->cbDictSize,
  280. pSrc, cbRaw);
  281. pSrc += cbRaw;
  282. cbSrcSize -= cbRaw;
  283. //
  284. // Now get a pointer just past the end of the data we read. Well,
  285. // almost. We fed in cbRaw bytes starting at GDC_MAXREP +
  286. // pgdcImp->cbDictSize. So unless this is the last chunk of raw
  287. // data to process, pMax is GDC_MAXREP before the end of the
  288. // new raw data.
  289. //
  290. // NOTE that in several of the functions that follow, we read
  291. // a byte or two past the end and the beginning of the valid new
  292. // raw data. THIS IS INTENTIONAL.
  293. //
  294. // Doing so is the only way to get the beginning and ending bytes
  295. // indexed, since the hash function uses TWO bytes. We won't
  296. // GPF because of padding in our RawData buffer.
  297. //
  298. pMax = pgdcImp->RawData + pgdcImp->cbDictSize + cbRaw;
  299. if (!cbSrcSize)
  300. {
  301. pMax += GDC_MAXREP;
  302. }
  303. else
  304. {
  305. //
  306. // This better NOT be persistent compression, since we don't
  307. // let you compress packets bigger than the chunk size we
  308. // process (GDC_DATA_MAX).
  309. //
  310. ASSERT(!pDictionary);
  311. }
  312. //
  313. // Generate the sort buffer, which orders the raw data according
  314. // to an index calculated using pairs of contiguous bytes that
  315. // occur within it. Without a dictionary yet, the first pass
  316. // only indexes the current chunk. With a dictionary (a second or
  317. // greater pass--or PERSISTENT COMPRESSION has saved enough data
  318. // from last time), we look back into the previous chunk (what we
  319. // call the dictionary).
  320. //
  321. // This takes longer since we go through more bytes, but produces
  322. // better results. Hence the dictionary size controls the speed/
  323. // resulting size.
  324. //
  325. switch (Passes)
  326. {
  327. case 0:
  328. {
  329. if (pgdcImp->cbDictUsed > GDC_MAXREP)
  330. {
  331. //
  332. // On the zeroth pass, cbDictUsed is always ZERO
  333. // for non-persistent PKZIP.
  334. //
  335. ASSERT(pDictionary);
  336. GDCSortBuffer(pgdcImp, pCur - pgdcImp->cbDictUsed + GDC_MAXREP,
  337. pMax + 1);
  338. }
  339. else
  340. {
  341. GDCSortBuffer(pgdcImp, pCur, pMax + 1);
  342. }
  343. ++Passes;
  344. //
  345. // After completing a pass we slide the raw data up into
  346. // the dictionary slot, bumping out the older dictionary
  347. // data.
  348. //
  349. if (pgdcImp->cbDictSize != GDC_DATA_MAX)
  350. {
  351. ASSERT(pgdcImp->cbDictUsed == 0);
  352. ASSERT(!pDictionary);
  353. ++Passes;
  354. }
  355. }
  356. break;
  357. case 1:
  358. {
  359. //
  360. // Start sorting GDC_MAXREP bytes after the start. NOTE
  361. // that this is exactly what PERSISTENT compression does
  362. // on the zeroth pass--it acts like we already have
  363. // dictionary data, using the bytes from the last time
  364. // we compressed something.
  365. //
  366. GDCSortBuffer(pgdcImp, pCur - pgdcImp->cbDictSize + GDC_MAXREP,
  367. pMax + 1);
  368. ++Passes;
  369. }
  370. break;
  371. default:
  372. {
  373. //
  374. // Start sort from the beginning of the dictionary.
  375. // This works because we copy raw data around before
  376. // starting the next pass.
  377. //
  378. GDCSortBuffer(pgdcImp, pCur - pgdcImp->cbDictSize, pMax + 1);
  379. }
  380. break;
  381. }
  382. //
  383. // Now compress the raw data chunk we ar working on.
  384. //
  385. while (pCur < pMax)
  386. {
  387. Len = GDCFindRep(pgdcImp, pCur);
  388. SkipFindRep:
  389. if (!Len || (Len == GDC_MINREP && pgdcImp->Distance >= GDC_DECODED_SIZE))
  390. {
  391. if (!GDCOutputBits(pgdcImp, s_gdcLitBits[*pCur],
  392. s_gdcLitCode[*pCur]))
  393. DC_QUIT;
  394. pCur++;
  395. continue;
  396. }
  397. //
  398. // Only do this if we're on the last chunk
  399. //
  400. if (!cbSrcSize && (pCur + Len > pMax))
  401. {
  402. //
  403. // Peg run size so it doesn't go past end of raw data.
  404. //
  405. Len = (UINT)(pMax - pCur);
  406. if ((Len < GDC_MINREP) ||
  407. (Len == GDC_MINREP && pgdcImp->Distance >= GDC_DECODED_SIZE))
  408. {
  409. if (!GDCOutputBits(pgdcImp, s_gdcLitBits[*pCur],
  410. s_gdcLitCode[*pCur]))
  411. DC_QUIT;
  412. pCur++;
  413. continue;
  414. }
  415. }
  416. else if ((Len < 8) && (pCur + 1 < pMax))
  417. {
  418. UINT Save_Distance;
  419. UINT Save_Len;
  420. //
  421. // Make temp copies of Distance and Len so we can
  422. // look ahead and see if a better compression run is
  423. // looming. If so, we won't bother starting it here,
  424. // we'll grab the better one next time around.
  425. //
  426. Save_Distance = pgdcImp->Distance;
  427. Save_Len = Len;
  428. Len = GDCFindRep(pgdcImp, pCur + 1);
  429. if ((Len > Save_Len) &&
  430. ((Len > Save_Len + 1) || (Save_Distance > (GDC_DECODED_SIZE/2))))
  431. {
  432. if (!GDCOutputBits(pgdcImp, s_gdcLitBits[*pCur],
  433. s_gdcLitCode[*pCur]))
  434. DC_QUIT;
  435. ++pCur;
  436. goto SkipFindRep;
  437. }
  438. //
  439. // Put back old Len and Distance, we'll take this one.
  440. //
  441. Len = Save_Len;
  442. pgdcImp->Distance = Save_Distance;
  443. }
  444. if (!GDCOutputBits(pgdcImp, s_gdcLitBits[256 + Len - GDC_MINREP],
  445. s_gdcLitCode[256 + Len - GDC_MINREP]))
  446. DC_QUIT;
  447. if (Len == GDC_MINREP)
  448. {
  449. //
  450. // GDC_MINREP is 2, so we right shift Distance by 2
  451. // (divide by 4). Then we mask out the last 2 bits
  452. // of Distance.
  453. //
  454. if (!GDCOutputBits(pgdcImp,
  455. s_gdcDistBits[pgdcImp->Distance >> GDC_MINREP],
  456. s_gdcDistCode[pgdcImp->Distance >> GDC_MINREP]))
  457. DC_QUIT;
  458. if (!GDCOutputBits(pgdcImp, GDC_MINREP, (WORD)(pgdcImp->Distance & 3)))
  459. DC_QUIT;
  460. }
  461. else
  462. {
  463. if (!GDCOutputBits(pgdcImp,
  464. s_gdcDistBits[pgdcImp->Distance >> pgdcImp->ExtDistBits],
  465. s_gdcDistCode[pgdcImp->Distance >> pgdcImp->ExtDistBits]))
  466. DC_QUIT;
  467. if (!GDCOutputBits(pgdcImp, (WORD)pgdcImp->ExtDistBits,
  468. (WORD)(pgdcImp->Distance & pgdcImp->ExtDistMask)))
  469. DC_QUIT;
  470. }
  471. pCur += Len;
  472. }
  473. if (cbSrcSize)
  474. {
  475. //
  476. // There's more data to process. Here's where we slide up the
  477. // current raw data into the dictionary space. This is simply
  478. // the final cbDictSize + GDC_MAXREP bytes of data. It
  479. // begins GDC_DATA_MAX after the start of the bufer.
  480. //
  481. // For example, if the dict size is 1K, the current data goes
  482. // from 1K to 5K, and we slide up the data from 4K to 5K.
  483. //
  484. memcpy(pgdcImp->RawData, pgdcImp->RawData + GDC_DATA_MAX,
  485. pgdcImp->cbDictSize + GDC_MAXREP);
  486. //
  487. // Now move our raw data pointer back and update the
  488. // dictonary used amount. Since we have GDC_DATA_MAX of data,
  489. // we fill the dictionary completely.
  490. //
  491. pCur -= GDC_DATA_MAX;
  492. pgdcImp->cbDictUsed = pgdcImp->cbDictSize;
  493. }
  494. }
  495. while (cbSrcSize);
  496. //
  497. // Add the end code.
  498. //
  499. if (!GDCOutputBits(pgdcImp, s_gdcLitBits[EOF_CODE], s_gdcLitCode[EOF_CODE]))
  500. DC_QUIT;
  501. //
  502. // Return the resulting compressed data size.
  503. //
  504. // NOTE that partial bits are already in the destination. But we
  505. // need to account for any in the total size.
  506. //
  507. if (pgdcImp->iDstBit)
  508. ++(pgdcImp->pDst);
  509. *pcbDstSize = (UINT)(pgdcImp->pDst - pDst);
  510. //
  511. // We're done. If we have a persistent dictionary, copy back our
  512. // last block of raw data into it. We only copy as much as is actually
  513. // valid however.
  514. //
  515. // We can only get here on successful compression. NOTE that we do not
  516. // wipe out our dictionary on failure like we used to. This helps us
  517. // by permitting better compression the next time. The receiver will
  518. // be OK, since his receive dictionary won't be altered upon reception
  519. // of a non-compressed packet.
  520. //
  521. if (pDictionary)
  522. {
  523. pDictionary->cbUsed = min(pgdcImp->cbDictSize, pgdcImp->cbDictUsed + cbRaw);
  524. TRACE_OUT(("Copying back %u dictionary bytes after compression",
  525. pDictionary->cbUsed));
  526. memcpy(pDictionary->pData, pgdcImp->RawData + GDC_MAXREP +
  527. pgdcImp->cbDictSize + cbRaw - pDictionary->cbUsed,
  528. pDictionary->cbUsed);
  529. }
  530. TRACE_OUT(("%sCompressed %u bytes to %u",
  531. (pDictionary ? "PDC " : ""), cbSrcOrg, *pcbDstSize));
  532. rc = TRUE;
  533. DC_EXIT_POINT:
  534. if (!rc && !pgdcImp->cbDst)
  535. {
  536. TRACE_OUT(("GDC_Compress: compressed size is bigger than decompressed size %u.",
  537. cbSrcOrg));
  538. }
  539. DebugExitBOOL(GDC_Compress, rc);
  540. return(rc);
  541. }
  542. //
  543. // GDCSortBuffer()
  544. //
  545. void GDCSortBuffer
  546. (
  547. PGDC_IMPLODE pgdcImp,
  548. LPBYTE pStart,
  549. LPBYTE pEnd
  550. )
  551. {
  552. WORD Accum;
  553. WORD * pHash;
  554. LPBYTE pTmp;
  555. DebugEntry(GDCSortBuffer);
  556. ASSERT(pStart >= pgdcImp->RawData + pgdcImp->cbDictSize - pgdcImp->cbDictUsed);
  557. //
  558. // For each pair of bytes in the raw data, from pStart to pEnd,
  559. // calculate the hash value for the pair . The hash value ranges from
  560. // 0 to GDC_HASH_SIZE-1. Thus the HashArray structure is an array of
  561. // GDC_HASH_SIZE WORDs. Keep a count of how many times a particular
  562. // hash value occurs in the uncompressed data.
  563. //
  564. //
  565. ZeroMemory(pgdcImp->HashArray, sizeof(pgdcImp->HashArray));
  566. pTmp = pStart;
  567. do
  568. {
  569. ++(pgdcImp->HashArray[GDC_HASHFN(pTmp)]);
  570. }
  571. while (++pTmp < pEnd);
  572. //
  573. // Now go back and make each HashArray entry a cumulative total of the
  574. // occurrences of the hash values up to and including itself. Kind
  575. // of like the Fibonacci sequence actually.
  576. //
  577. Accum = 0;
  578. pHash = pgdcImp->HashArray;
  579. do
  580. {
  581. Accum += *pHash;
  582. *pHash = Accum;
  583. }
  584. while (++pHash < pgdcImp->HashArray + GDC_HASH_SIZE);
  585. //
  586. // Find the entry in the HashArray containing the accumulated
  587. // instance count for the current data WORD. Since these values are
  588. // calculated from the data in the passed in range, we know that the
  589. // value in any slot we get to by hashing some bytes in the range is
  590. // at least 1.
  591. //
  592. // We start at the end and work towards the beginning so that we
  593. // end up with the first instance of such an occurrence in the SortArray.
  594. //
  595. pTmp = pEnd - 1;
  596. do
  597. {
  598. pHash = pgdcImp->HashArray + GDC_HASHFN(pTmp);
  599. ASSERT(*pHash > 0);
  600. //
  601. // The count (*pHash) is to be used as an array index, so subtract
  602. // one from it. If there was only one instance, put it in array
  603. // element 0. If there is more than one instance of a particular
  604. // hash, then next time we will start with a lower accumulated
  605. // total. The array element will be one back, and so on.
  606. //
  607. --(*pHash);
  608. //
  609. // Store an offset from the beginning of the RawData buffer to
  610. // each byte of data into the SortArray. This is inserted
  611. // using the hash instance count as the index.
  612. //
  613. // In other words, the buffer is sorted in ascending order of hash
  614. // for a particular piece of data. Where two bytes of data have
  615. // the same hash, they are referenced in the SortBuffer in the
  616. // same order as in the RawData since we are scanning backwards.
  617. //
  618. pgdcImp->SortArray[*pHash] = (WORD)(pTmp - pgdcImp->RawData);
  619. }
  620. while (--pTmp >= pStart);
  621. //
  622. // Now all entries in the HashArray index the first occurrence of a byte
  623. // in the workspace which has a particular index, via the SortArray
  624. // offset. That is, the above do-while loop decrements each HashArray
  625. // entry until all data bytes for that entry are written to SortBuffer.
  626. //
  627. DebugExitVOID(GDCSortBuffer);
  628. }
  629. //
  630. // GDCFindRep
  631. //
  632. // This looks for byte patterns in the uncompressed data that can be
  633. // represented in the compressed data with smaller sequences. The biggest
  634. // wins come from repeating byte sequences; later sequences can be
  635. // compressed into a few bytes referring to an earlier sequence (how big,
  636. // how many bytes back).
  637. //
  638. // This returns the length of the uncompressed data to be replaced.
  639. //
  640. UINT GDCFindRep
  641. (
  642. PGDC_IMPLODE pgdcImp,
  643. LPBYTE pDataStart
  644. )
  645. {
  646. UINT CurLen;
  647. UINT Len;
  648. LPBYTE pDataPat;
  649. LPBYTE pData;
  650. UINT iDataMin;
  651. UINT SortIndex;
  652. LPBYTE pDataMax;
  653. UINT HashVal;
  654. UINT i1;
  655. short j1;
  656. LPBYTE pBase;
  657. DebugEntry(GDCFindRep);
  658. //
  659. // See GDCSortBuffer for a description of the contents of the
  660. // Index array. GDC_HASHFN() returns a hash value for a byte
  661. // using it and its successor in the uncompressed data stream.
  662. //
  663. HashVal = GDC_HASHFN(pDataStart);
  664. ASSERT(HashVal < GDC_HASH_SIZE);
  665. SortIndex = pgdcImp->HashArray[HashVal];
  666. //
  667. // Find the minimum sort buffer value. This is the offset of the
  668. // first byte of data.
  669. //
  670. iDataMin = (UINT)(pDataStart - pgdcImp->cbDictSize + 1 - pgdcImp->RawData);
  671. if (pgdcImp->SortArray[SortIndex] < iDataMin)
  672. {
  673. //
  674. // The SortArray is referencing stale data, data that is no
  675. // longer in the range we are processing. Move forward until
  676. // we hit the first entry that's in the current chunk.
  677. //
  678. do
  679. {
  680. ++SortIndex;
  681. }
  682. while (pgdcImp->SortArray[SortIndex] < iDataMin);
  683. //
  684. // Save this new sort value in the hash.
  685. //
  686. pgdcImp->HashArray[HashVal] = (WORD)SortIndex;
  687. }
  688. //
  689. // Need more than 2 bytes with the same index before processing it.
  690. //
  691. pDataMax = pDataStart - 1;
  692. //
  693. // Get a Ptr to the first byte in the compression buffer referenced by
  694. // the SortBuffer offset indexed by the SortIndex we just calculated.
  695. // If this Ptr is not at least 2 bytes before pDataStart then return 0.
  696. // This means that the byte pointed to by Start does not share the
  697. // index with earlier bytes.
  698. //
  699. pData = pgdcImp->RawData + pgdcImp->SortArray[SortIndex];
  700. if (pData >= pDataMax)
  701. return 0;
  702. //
  703. // Now the current bytes have the same index as at least 2 other
  704. // sequences. Ptr points to the first compress buffer byte with
  705. // the same index as that pointed to by pDataStart.
  706. //
  707. pDataPat = pDataStart;
  708. CurLen = 1;
  709. do
  710. {
  711. if (*(pData + CurLen - 1) == *(pDataPat + CurLen - 1) &&
  712. *(pData) == *(pDataPat))
  713. {
  714. //
  715. // This processes a sequence of identical bytes, one starting
  716. // at pDataPat, the other at pData.
  717. //
  718. ++pData;
  719. ++pDataPat;
  720. Len = 2;
  721. // Skip past matching bytes, keeping a count.
  722. while ((*++pData == *++pDataPat) && (++Len < GDC_MAXREP))
  723. ;
  724. pDataPat = pDataStart;
  725. if (Len >= CurLen)
  726. {
  727. pgdcImp->Distance = (UINT)(pDataPat - pData + Len - 1);
  728. if ((CurLen = Len) > KMP_THRESHOLD)
  729. {
  730. if (Len == GDC_MAXREP)
  731. {
  732. --(pgdcImp->Distance);
  733. return Len;
  734. }
  735. goto DoKMP;
  736. }
  737. }
  738. }
  739. //
  740. // Get a pointer to the next compress buffer byte having the same
  741. // hash. If this byte comes before pDataMax, go back around the
  742. // loop and look for a matching sequence.
  743. //
  744. pData = pgdcImp->RawData + pgdcImp->SortArray[++SortIndex];
  745. }
  746. while (pData < pDataMax);
  747. return (CurLen >= GDC_MINREP) ? CurLen : 0;
  748. DoKMP:
  749. if (pgdcImp->RawData + pgdcImp->SortArray[SortIndex+1] >= pDataMax)
  750. return CurLen;
  751. j1 = pgdcImp->Next[1] = 0;
  752. pgdcImp->Next[0] = -1;
  753. i1 = 1;
  754. do
  755. {
  756. if ((pDataPat[i1] == pDataPat[j1]) || ((j1 = pgdcImp->Next[j1]) == -1))
  757. pgdcImp->Next[++i1] = ++j1;
  758. }
  759. while (i1 < CurLen);
  760. Len = CurLen;
  761. pData = pgdcImp->RawData + pgdcImp->SortArray[SortIndex] + CurLen;
  762. while (TRUE)
  763. {
  764. if ((Len = pgdcImp->Next[Len]) == -1)
  765. Len = 0;
  766. do
  767. {
  768. pBase = pgdcImp->RawData + pgdcImp->SortArray[++SortIndex];
  769. if (pBase >= pDataMax)
  770. return CurLen;
  771. }
  772. while (pBase + Len < pData);
  773. if (*(pBase + CurLen - 2) != *(pDataPat + CurLen - 2))
  774. {
  775. do
  776. {
  777. pBase = pgdcImp->RawData + pgdcImp->SortArray[++SortIndex];
  778. if (pBase >= pDataMax)
  779. return CurLen;
  780. }
  781. while ((*(pBase + CurLen - 2) != *(pDataPat + CurLen - 2)) ||
  782. (*(pBase) != *(pDataPat)));
  783. Len = 2;
  784. pData = pBase + Len;
  785. }
  786. else if (pBase + Len != pData)
  787. {
  788. Len = 0;
  789. pData = pBase;
  790. }
  791. while ((*pData == pDataPat[Len]) && (++Len < GDC_MAXREP))
  792. pData++;
  793. if (Len >= CurLen)
  794. {
  795. ASSERT(pBase < pDataStart);
  796. pgdcImp->Distance = (UINT)(pDataStart - pBase - 1);
  797. if (Len > CurLen)
  798. {
  799. if (Len == GDC_MAXREP)
  800. return Len;
  801. CurLen = Len;
  802. do
  803. {
  804. if ((pDataPat[i1] == pDataPat[j1]) ||
  805. ((j1 = pgdcImp->Next[j1]) == -1))
  806. pgdcImp->Next[++i1] = ++j1;
  807. }
  808. while (i1 < CurLen);
  809. }
  810. }
  811. }
  812. DebugExitVOID(GDCFindRep);
  813. }
  814. //
  815. // GDCOutputBits()
  816. //
  817. // This writes compressed output into our output buffer. If the total
  818. // goes past the max compressed chunk we have workspace for, we flush
  819. // our buffer into the apps'destination.
  820. //
  821. // It returns FALSE on failure, i.e. we would go past the end of the
  822. // destination.
  823. //
  824. BOOL GDCOutputBits
  825. (
  826. PGDC_IMPLODE pgdcImp,
  827. WORD Cnt,
  828. WORD Code
  829. )
  830. {
  831. UINT iDstBit;
  832. BOOL rc = FALSE;
  833. DebugEntry(GDCOutputBits);
  834. //
  835. // If we are writing more than a byte's worth of bits, call ourself
  836. // recursively to write just 8. NOTE THAT WE NEVER OUTPUT MORE THAN
  837. // A WORD'S WORTH, since Code is a WORD sized object.
  838. //
  839. if (Cnt > 8)
  840. {
  841. if (!GDCOutputBits(pgdcImp, 8, Code))
  842. DC_QUIT;
  843. Cnt -= 8;
  844. Code >>= 8;
  845. }
  846. ASSERT(pgdcImp->cbDst > 0);
  847. //
  848. // OR on the bits of the Code (Cnt of them). Then advance our
  849. // current bit pointer and current byte pointer in the output buffer.
  850. //
  851. iDstBit = pgdcImp->iDstBit;
  852. ASSERT(iDstBit < 8);
  853. //
  854. // NOTE: This is why it is extremely important to have zeroed out
  855. // the current destination byte when we advance. We OR on bit
  856. // sequences to the current byte.
  857. //
  858. *(pgdcImp->pDst) |= (BYTE)(Code << iDstBit);
  859. pgdcImp->iDstBit += Cnt;
  860. if (pgdcImp->iDstBit >= 8)
  861. {
  862. //
  863. // We've gone past a byte. Advance the destination ptr to the next
  864. // one.
  865. //
  866. ++(pgdcImp->pDst);
  867. if (--(pgdcImp->cbDst) == 0)
  868. {
  869. //
  870. // We just filled the last byte and are trying to move past
  871. // the end of the destination. Bail out now
  872. //
  873. DC_QUIT;
  874. }
  875. //
  876. // Phew, we have room left. Carry over the slop bits.
  877. //
  878. if (pgdcImp->iDstBit > 8)
  879. {
  880. //
  881. // Carry over slop.
  882. //
  883. *(pgdcImp->pDst) = (BYTE)(Code >> (8 - iDstBit));
  884. }
  885. else
  886. *(pgdcImp->pDst) = 0;
  887. // Now the new byte is fullly initialized.
  888. pgdcImp->iDstBit &= 7;
  889. }
  890. rc= TRUE;
  891. DC_EXIT_POINT:
  892. DebugExitBOOL(GDCOutputBits, rc);
  893. return(rc);
  894. }
  895. //
  896. // GDC_Decompress()
  897. //
  898. BOOL GDC_Decompress
  899. (
  900. PGDC_DICTIONARY pDictionary,
  901. LPBYTE pWorkBuf,
  902. LPBYTE pSrc,
  903. UINT cbSrcSize,
  904. LPBYTE pDst,
  905. UINT * pcbDstSize
  906. )
  907. {
  908. BOOL rc = FALSE;
  909. UINT Len;
  910. UINT Dist;
  911. UINT i;
  912. UINT cbDstSize;
  913. LPBYTE pDstOrg;
  914. LPBYTE pEarlier;
  915. LPBYTE pNow;
  916. PGDC_EXPLODE pgdcExp;
  917. #ifdef _DEBUG
  918. UINT cbSrcOrg;
  919. #endif // _DEBUG
  920. DebugEntry(GDC_Decompress);
  921. pgdcExp = (PGDC_EXPLODE)pWorkBuf;
  922. ASSERT(pgdcExp);
  923. #ifdef _DEBUG
  924. cbSrcOrg = cbSrcSize;
  925. #endif // _DEBUG
  926. //
  927. // This shouldn't be possible--but since this compressed data
  928. // comes from another machine, we want to make sure _we_ don't blow
  929. // up if that machine flaked out.
  930. //
  931. if (cbSrcSize <= 4)
  932. {
  933. ERROR_OUT(("GDC_Decompress: bogus compressed data"));
  934. DC_QUIT;
  935. }
  936. //
  937. // Get the distance bits and calculate the mask needed for that many.
  938. //
  939. // NOTE: For PDC compression, the ExtDistBits are just in the first
  940. // byte. For plain compression, the ExtDistBits are in the first
  941. // little-endian word. Either way, we only allow from 4 to 6, so
  942. // the high byte in the non-PDC case is not useful.
  943. //
  944. if (!pDictionary)
  945. {
  946. // First byte better be zero
  947. if (*pSrc != 0)
  948. {
  949. ERROR_OUT(("GDC_Decompress: unrecognized distance bits"));
  950. DC_QUIT;
  951. }
  952. ++pSrc;
  953. --cbSrcSize;
  954. }
  955. pgdcExp->ExtDistBits = *pSrc;
  956. if ((pgdcExp->ExtDistBits < EXT_DIST_BITS_MIN) ||
  957. (pgdcExp->ExtDistBits > EXT_DIST_BITS_MAC))
  958. {
  959. ERROR_OUT(("GDC_Decompress: unrecognized distance bits"));
  960. DC_QUIT;
  961. }
  962. pgdcExp->ExtDistMask = 0xFFFF >> (16 - pgdcExp->ExtDistBits);
  963. //
  964. // Set up source data info (compressed goop). SrcByte is the current
  965. // byte & bits we're reading from. pSrc is the pointer to the next
  966. // byte.
  967. //
  968. pgdcExp->SrcByte = *(pSrc+1);
  969. pgdcExp->SrcBits = 0;
  970. pgdcExp->pSrc = pSrc + 2;
  971. pgdcExp->cbSrc = cbSrcSize - 2;
  972. //
  973. // Save the beginning of the result buffer so we can calculate how
  974. // many bytes we wrote into it afterwards.
  975. //
  976. pDstOrg = pDst;
  977. cbDstSize = *pcbDstSize;
  978. //
  979. // If we have a dictionary, put its data into our work area--the
  980. // compression might be referencing byte sequences in it (that's the
  981. // whole point, you get better compression that way when you send
  982. // packets with the same info over and over).
  983. //
  984. // We remember and update cbDictUsed to do the minimal dictionary
  985. // byte copying back and forth.
  986. //
  987. if (pDictionary && pDictionary->cbUsed)
  988. {
  989. TRACE_OUT(("Restoring %u dictionary bytes before decompression",
  990. pDictionary->cbUsed));
  991. memcpy(pgdcExp->RawData + GDC_DATA_MAX - pDictionary->cbUsed,
  992. pDictionary->pData, pDictionary->cbUsed);
  993. pgdcExp->cbDictUsed = pDictionary->cbUsed;
  994. }
  995. else
  996. {
  997. pgdcExp->cbDictUsed = 0;
  998. }
  999. //
  1000. // The decompressed data starts filling in at GDC_DATA_MAX bytes into
  1001. // the RawData array. We have to double buffer the output (just
  1002. // like we double buffer the input during compression) because
  1003. // decompressing may require reaching backwards into the decompressed
  1004. // byte stream to pull out sequences.
  1005. //
  1006. pgdcExp->iRawData = GDC_DATA_MAX;
  1007. while ((Len = GDCDecodeLit(pgdcExp)) < EOF_CODE)
  1008. {
  1009. if (Len < 256)
  1010. {
  1011. pgdcExp->RawData[pgdcExp->iRawData++] = (BYTE)Len;
  1012. }
  1013. else
  1014. {
  1015. Len -= (256 - GDC_MINREP);
  1016. Dist = GDCDecodeDist(pgdcExp, Len);
  1017. if (!Dist)
  1018. DC_QUIT;
  1019. //
  1020. // Now we're reaching back, this may in fact spill into the
  1021. // dictionary data that preceded us.
  1022. //
  1023. pNow = pgdcExp->RawData + pgdcExp->iRawData;
  1024. pEarlier = pNow - Dist;
  1025. ASSERT(pEarlier >= pgdcExp->RawData + GDC_DATA_MAX - pgdcExp->cbDictUsed);
  1026. pgdcExp->iRawData += Len;
  1027. do
  1028. {
  1029. *pNow++ = *pEarlier++;
  1030. }
  1031. while (--Len > 0);
  1032. }
  1033. //
  1034. // We've gone past the end of our workspace, flush the decompressed
  1035. // data out. This is why RawData in GDC_EXPLODE has an extra pad of
  1036. // GDC_MAXREP at the end. This prevents us from spilling out of
  1037. // the RawData buffer, we will never go more than GDC_MAXREP beyond
  1038. // the last GDC_DATA_MAX chunk.
  1039. //
  1040. if (pgdcExp->iRawData >= 2*GDC_DATA_MAX)
  1041. {
  1042. //
  1043. // Do we have enough space left in the destination?
  1044. //
  1045. if (cbDstSize < GDC_DATA_MAX)
  1046. {
  1047. cbDstSize = 0;
  1048. DC_QUIT;
  1049. }
  1050. // Yup.
  1051. memcpy(pDst, pgdcExp->RawData + GDC_DATA_MAX, GDC_DATA_MAX);
  1052. pDst += GDC_DATA_MAX;
  1053. cbDstSize -= GDC_DATA_MAX;
  1054. //
  1055. // Slide decoded data up to be used for decoding the next
  1056. // chunk ofcompressed source. It's convenient that the
  1057. // dictionary size and flush size are the same.
  1058. //
  1059. pgdcExp->iRawData -= GDC_DATA_MAX;
  1060. memcpy(pgdcExp->RawData, pgdcExp->RawData + GDC_DATA_MAX,
  1061. pgdcExp->iRawData);
  1062. pgdcExp->cbDictUsed = GDC_DATA_MAX;
  1063. }
  1064. }
  1065. if (Len == ABORT_CODE)
  1066. DC_QUIT;
  1067. i = pgdcExp->iRawData - GDC_DATA_MAX;
  1068. if (i > 0)
  1069. {
  1070. //
  1071. // This is the remaining decompressed data--can we we right it
  1072. // out?
  1073. //
  1074. if (cbDstSize < i)
  1075. {
  1076. cbDstSize = 0;
  1077. DC_QUIT;
  1078. }
  1079. memcpy(pDst, pgdcExp->RawData + GDC_DATA_MAX, i);
  1080. //
  1081. // Advance pDst so that the delta between it and the original is
  1082. // the resulting uncompressed size.
  1083. //
  1084. pDst += i;
  1085. //
  1086. // And update the dictionary used size
  1087. //
  1088. pgdcExp->cbDictUsed = min(pgdcExp->cbDictUsed + i, GDC_DATA_MAX);
  1089. }
  1090. //
  1091. // If we make it to here, we've successfully decompressed the input.
  1092. // So fill in the resulting uncompressed size.
  1093. //
  1094. *pcbDstSize = (UINT)(pDst - pDstOrg);
  1095. //
  1096. // If a persistent dictionary was passed in, save the current contents
  1097. // back into the thing for next time.
  1098. //
  1099. if (pDictionary)
  1100. {
  1101. TRACE_OUT(("Copying back %u dictionary bytes after decompression",
  1102. pgdcExp->cbDictUsed));
  1103. memcpy(pDictionary->pData, pgdcExp->RawData + GDC_DATA_MAX +
  1104. i - pgdcExp->cbDictUsed, pgdcExp->cbDictUsed);
  1105. pDictionary->cbUsed = pgdcExp->cbDictUsed;
  1106. }
  1107. TRACE_OUT(("%sExploded %u bytes from %u",
  1108. (pDictionary ? "PDC " : ""), *pcbDstSize, cbSrcOrg));
  1109. rc = TRUE;
  1110. DC_EXIT_POINT:
  1111. if (!rc && !cbDstSize)
  1112. {
  1113. ERROR_OUT(("GDC_Decompress: decompressed data too big"));
  1114. }
  1115. DebugExitBOOL(GDC_Decompress, rc);
  1116. return(rc);
  1117. }
  1118. //
  1119. // GDCDecodeLit()
  1120. //
  1121. UINT GDCDecodeLit
  1122. (
  1123. PGDC_EXPLODE pgdcExp
  1124. )
  1125. {
  1126. UINT LitChar, i;
  1127. if (pgdcExp->SrcByte & 0x01)
  1128. {
  1129. // Length found
  1130. if (!GDCWasteBits(pgdcExp, 1))
  1131. return ABORT_CODE;
  1132. LitChar = s_gdcLenDecode[pgdcExp->SrcByte & 0xFF];
  1133. if (!GDCWasteBits(pgdcExp, s_gdcLenBits[LitChar]))
  1134. return ABORT_CODE;
  1135. if (s_gdcExLenBits[LitChar])
  1136. {
  1137. i = pgdcExp->SrcByte & ((1 << s_gdcExLenBits[LitChar]) - 1);
  1138. if (!GDCWasteBits(pgdcExp, s_gdcExLenBits[LitChar]))
  1139. {
  1140. // If this isn't EOF, something is wrong
  1141. if (LitChar + i != 15 + 255)
  1142. return ABORT_CODE;
  1143. }
  1144. LitChar = s_gdcLenBase[LitChar] + i;
  1145. }
  1146. LitChar += 256;
  1147. }
  1148. else
  1149. {
  1150. // Char found
  1151. if (!GDCWasteBits(pgdcExp, 1))
  1152. return ABORT_CODE;
  1153. LitChar = (pgdcExp->SrcByte & 0xFF);
  1154. if (!GDCWasteBits(pgdcExp, 8))
  1155. return ABORT_CODE;
  1156. }
  1157. return LitChar;
  1158. }
  1159. //
  1160. // GDCDecodeDist()
  1161. //
  1162. UINT GDCDecodeDist
  1163. (
  1164. PGDC_EXPLODE pgdcExp,
  1165. UINT Len
  1166. )
  1167. {
  1168. UINT Dist;
  1169. Dist = s_gdcDistDecode[pgdcExp->SrcByte & 0xFF];
  1170. if (!GDCWasteBits(pgdcExp, s_gdcDistBits[Dist]))
  1171. return 0;
  1172. if (Len == GDC_MINREP)
  1173. {
  1174. // GDC_MINREP is 2, hence we shift over by 2 then mask the low 2 bits
  1175. Dist <<= GDC_MINREP;
  1176. Dist |= (pgdcExp->SrcByte & 3);
  1177. if (!GDCWasteBits(pgdcExp, GDC_MINREP))
  1178. return 0;
  1179. }
  1180. else
  1181. {
  1182. Dist <<= pgdcExp->ExtDistBits;
  1183. Dist |=( pgdcExp->SrcByte & pgdcExp->ExtDistMask);
  1184. if (!GDCWasteBits(pgdcExp, pgdcExp->ExtDistBits))
  1185. return 0;
  1186. }
  1187. return Dist+1;
  1188. }
  1189. //
  1190. // GDCWasteBits()
  1191. //
  1192. BOOL GDCWasteBits
  1193. (
  1194. PGDC_EXPLODE pgdcExp,
  1195. UINT cBits
  1196. )
  1197. {
  1198. if (cBits <= pgdcExp->SrcBits)
  1199. {
  1200. pgdcExp->SrcByte >>= cBits;
  1201. pgdcExp->SrcBits -= cBits;
  1202. }
  1203. else
  1204. {
  1205. pgdcExp->SrcByte >>= pgdcExp->SrcBits;
  1206. //
  1207. // We need to advance to the next source byte. Can we, or have
  1208. // we reached the end already?
  1209. //
  1210. if (!pgdcExp->cbSrc)
  1211. return(FALSE);
  1212. pgdcExp->SrcByte |= (*pgdcExp->pSrc) << 8;
  1213. //
  1214. // Move these to the next byte in the compressed source
  1215. //
  1216. ++(pgdcExp->pSrc);
  1217. --(pgdcExp->cbSrc);
  1218. pgdcExp->SrcByte >>= (cBits - pgdcExp->SrcBits);
  1219. pgdcExp->SrcBits = 8 - (cBits - pgdcExp->SrcBits);
  1220. }
  1221. return(TRUE);
  1222. }