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.

1325 lines
45 KiB

  1. #include "precomp.h"
  2. //
  3. // OE2.CPP
  4. // Order Encoding Second Level
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_ORDER
  9. //
  10. // OE2_HostStarting()
  11. //
  12. BOOL ASHost::OE2_HostStarting(void)
  13. {
  14. DebugEntry(ASHost::OE2_HostStarting);
  15. //
  16. // Set up the pointers for 2nd level encoding
  17. //
  18. m_oe2Tx.LastOrder[OE2_DSTBLT_ORDER ] = &m_oe2Tx.LastDstblt;
  19. m_oe2Tx.LastOrder[OE2_PATBLT_ORDER ] = &m_oe2Tx.LastPatblt;
  20. m_oe2Tx.LastOrder[OE2_SCRBLT_ORDER ] = &m_oe2Tx.LastScrblt;
  21. m_oe2Tx.LastOrder[OE2_MEMBLT_ORDER ] = &m_oe2Tx.LastMemblt;
  22. m_oe2Tx.LastOrder[OE2_MEM3BLT_ORDER ] = &m_oe2Tx.LastMem3blt;
  23. m_oe2Tx.LastOrder[OE2_TEXTOUT_ORDER ] = &m_oe2Tx.LastTextOut;
  24. m_oe2Tx.LastOrder[OE2_EXTTEXTOUT_ORDER] = &m_oe2Tx.LastExtTextOut;
  25. m_oe2Tx.LastOrder[OE2_RECTANGLE_ORDER ] = &m_oe2Tx.LastRectangle;
  26. m_oe2Tx.LastOrder[OE2_LINETO_ORDER ] = &m_oe2Tx.LastLineTo;
  27. m_oe2Tx.LastOrder[OE2_OPAQUERECT_ORDER] = &m_oe2Tx.LastOpaqueRect;
  28. m_oe2Tx.LastOrder[OE2_SAVEBITMAP_ORDER] = &m_oe2Tx.LastSaveBitmap;
  29. m_oe2Tx.LastOrder[OE2_DESKSCROLL_ORDER] = &m_oe2Tx.LastDeskScroll;
  30. m_oe2Tx.LastOrder[OE2_MEMBLT_R2_ORDER ] = &m_oe2Tx.LastMembltR2;
  31. m_oe2Tx.LastOrder[OE2_MEM3BLT_R2_ORDER] = &m_oe2Tx.LastMem3bltR2;
  32. m_oe2Tx.LastOrder[OE2_POLYGON_ORDER ] = &m_oe2Tx.LastPolygon;
  33. m_oe2Tx.LastOrder[OE2_PIE_ORDER ] = &m_oe2Tx.LastPie;
  34. m_oe2Tx.LastOrder[OE2_ELLIPSE_ORDER ] = &m_oe2Tx.LastEllipse;
  35. m_oe2Tx.LastOrder[OE2_ARC_ORDER ] = &m_oe2Tx.LastArc;
  36. m_oe2Tx.LastOrder[OE2_CHORD_ORDER ] = &m_oe2Tx.LastChord;
  37. m_oe2Tx.LastOrder[OE2_POLYBEZIER_ORDER] = &m_oe2Tx.LastPolyBezier;
  38. m_oe2Tx.LastOrder[OE2_ROUNDRECT_ORDER ] = &m_oe2Tx.LastRoundRect;
  39. //
  40. // Set up the last order values to a known value.
  41. //
  42. m_oe2Tx.LastOrderType = OE2_PATBLT_ORDER;
  43. m_oe2Tx.pLastOrder = (LPCOM_ORDER)m_oe2Tx.LastOrder[m_oe2Tx.LastOrderType];
  44. DebugExitBOOL(ASHost::OE2_HostStarting, TRUE);
  45. return(TRUE);
  46. }
  47. //
  48. // OE2_HostEnded()
  49. //
  50. void ASHost::OE2_HostEnded(void)
  51. {
  52. DebugEntry(ASHost::OE2_HostEnded);
  53. //
  54. // For OUTGOING order encoding, free the last font we cached.
  55. //
  56. if (m_oe2Tx.LastHFONT != NULL)
  57. {
  58. ASSERT(m_pShare);
  59. ASSERT(m_usrWorkDC);
  60. SelectFont(m_usrWorkDC, (HFONT)GetStockObject(SYSTEM_FONT));
  61. DeleteFont(m_oe2Tx.LastHFONT);
  62. m_oe2Tx.LastHFONT = NULL;
  63. }
  64. DebugExitVOID(ASHost::OE2_HostEnded);
  65. }
  66. //
  67. // OE2_SyncOutgoing()
  68. // Called when NEW dude starts to host, a share is created, or somebody new
  69. // joins the share.
  70. // Resets the OUTGOING 2nd level order encoding data.
  71. //
  72. void ASHost::OE2_SyncOutgoing(void)
  73. {
  74. DebugEntry(ASHost::OE2_SyncOutgoing);
  75. //
  76. // Set up the last order values to a known value.
  77. //
  78. m_oe2Tx.LastOrderType = OE2_PATBLT_ORDER;
  79. m_oe2Tx.pLastOrder = (LPCOM_ORDER)m_oe2Tx.LastOrder[m_oe2Tx.LastOrderType];
  80. //
  81. // Clear out all the last orders.
  82. //
  83. ZeroMemory(&m_oe2Tx.LastDstblt, sizeof(m_oe2Tx.LastDstblt));
  84. ((PATBLT_ORDER*)&m_oe2Tx.LastDstblt)->type = ORD_DSTBLT_TYPE;
  85. ZeroMemory(&m_oe2Tx.LastPatblt, sizeof(m_oe2Tx.LastPatblt));
  86. ((PATBLT_ORDER*)&m_oe2Tx.LastPatblt)->type = ORD_PATBLT_TYPE;
  87. ZeroMemory(&m_oe2Tx.LastScrblt, sizeof(m_oe2Tx.LastScrblt));
  88. ((PATBLT_ORDER*)&m_oe2Tx.LastScrblt)->type = ORD_SCRBLT_TYPE;
  89. ZeroMemory(&m_oe2Tx.LastMemblt, sizeof(m_oe2Tx.LastMemblt));
  90. ((PATBLT_ORDER*)&m_oe2Tx.LastMemblt)->type = ORD_MEMBLT_TYPE;
  91. ZeroMemory(&m_oe2Tx.LastMem3blt,sizeof(m_oe2Tx.LastMem3blt));
  92. ((PATBLT_ORDER*)&m_oe2Tx.LastMem3blt)->type = ORD_MEM3BLT_TYPE;
  93. ZeroMemory(&m_oe2Tx.LastTextOut, sizeof(m_oe2Tx.LastTextOut));
  94. ((PATBLT_ORDER*)&m_oe2Tx.LastTextOut)->type = ORD_TEXTOUT_TYPE;
  95. ZeroMemory(&m_oe2Tx.LastExtTextOut, sizeof(m_oe2Tx.LastExtTextOut));
  96. ((PATBLT_ORDER*)&m_oe2Tx.LastExtTextOut)->type = ORD_EXTTEXTOUT_TYPE;
  97. ZeroMemory(&m_oe2Tx.LastRectangle, sizeof(m_oe2Tx.LastRectangle));
  98. ((PATBLT_ORDER*)&m_oe2Tx.LastRectangle)->type = ORD_RECTANGLE_TYPE;
  99. ZeroMemory(&m_oe2Tx.LastPolygon, sizeof(m_oe2Tx.LastPolygon));
  100. ((POLYGON_ORDER*)&m_oe2Tx.LastPolygon)->type = ORD_POLYGON_TYPE;
  101. ZeroMemory(&m_oe2Tx.LastPie, sizeof(m_oe2Tx.LastPie));
  102. ((PIE_ORDER*)&m_oe2Tx.LastPie)->type = ORD_PIE_TYPE;
  103. ZeroMemory(&m_oe2Tx.LastEllipse, sizeof(m_oe2Tx.LastEllipse));
  104. ((ELLIPSE_ORDER*)&m_oe2Tx.LastEllipse)->type = ORD_ELLIPSE_TYPE;
  105. ZeroMemory(&m_oe2Tx.LastArc, sizeof(m_oe2Tx.LastArc));
  106. ((ARC_ORDER*)&m_oe2Tx.LastArc)->type = ORD_ARC_TYPE;
  107. ZeroMemory(&m_oe2Tx.LastChord, sizeof(m_oe2Tx.LastChord));
  108. ((CHORD_ORDER*)&m_oe2Tx.LastChord)->type = ORD_CHORD_TYPE;
  109. ZeroMemory(&m_oe2Tx.LastPolyBezier, sizeof(m_oe2Tx.LastPolyBezier));
  110. ((POLYBEZIER_ORDER*)&m_oe2Tx.LastPolyBezier)->type = ORD_POLYBEZIER_TYPE;
  111. ZeroMemory(&m_oe2Tx.LastRoundRect, sizeof(m_oe2Tx.LastRoundRect));
  112. ((ROUNDRECT_ORDER*)&m_oe2Tx.LastRoundRect)->type = ORD_ROUNDRECT_TYPE;
  113. ZeroMemory(&m_oe2Tx.LastLineTo, sizeof(m_oe2Tx.LastLineTo));
  114. ((PATBLT_ORDER*)&m_oe2Tx.LastLineTo)->type = ORD_LINETO_TYPE;
  115. ZeroMemory(&m_oe2Tx.LastOpaqueRect, sizeof(m_oe2Tx.LastOpaqueRect));
  116. ((PATBLT_ORDER*)&m_oe2Tx.LastOpaqueRect)->type = ORD_OPAQUERECT_TYPE;
  117. ZeroMemory(&m_oe2Tx.LastSaveBitmap, sizeof(m_oe2Tx.LastSaveBitmap));
  118. ((PATBLT_ORDER*)&m_oe2Tx.LastSaveBitmap)->type = ORD_SAVEBITMAP_TYPE;
  119. ZeroMemory(&m_oe2Tx.LastDeskScroll, sizeof(m_oe2Tx.LastDeskScroll));
  120. ((PATBLT_ORDER*)&m_oe2Tx.LastDeskScroll)->type = ORD_DESKSCROLL_TYPE;
  121. ZeroMemory(&m_oe2Tx.LastMembltR2, sizeof(m_oe2Tx.LastMembltR2));
  122. ((PATBLT_ORDER*)&m_oe2Tx.LastMembltR2)->type = ORD_MEMBLT_R2_TYPE;
  123. ZeroMemory(&m_oe2Tx.LastMem3bltR2, sizeof(m_oe2Tx.LastMem3bltR2));
  124. ((PATBLT_ORDER*)&m_oe2Tx.LastMem3bltR2)->type = ORD_MEM3BLT_R2_TYPE;
  125. ZeroMemory(&m_oe2Tx.LastBounds, sizeof(m_oe2Tx.LastBounds));
  126. DebugExitVOID(ASHost::OE2_SyncOutgoing);
  127. }
  128. //
  129. // OE2_EncodeOrder()
  130. //
  131. TSHR_UINT16 ASHost::OE2_EncodeOrder
  132. (
  133. LPINT_ORDER pIntOrder,
  134. void * pBuffer,
  135. TSHR_UINT16 cbBufferSize
  136. )
  137. {
  138. POE2ETFIELD pTableEntry;
  139. LPSTR pNextFreeSpace;
  140. UINT thisFlag = 0;
  141. RECT Rect;
  142. TSHR_RECT16 Rect16;
  143. UINT cbEncodedOrderSize;
  144. UINT cbMaxEncodedOrderSize;
  145. LPBYTE pControlFlags;
  146. LPTSHR_UINT32_UA pEncodingFlags;
  147. LPSTR pEncodedOrder;
  148. UINT numEncodingFlagBytes;
  149. LPSTR pVariableField;
  150. BOOL useDeltaCoords;
  151. UINT i;
  152. LPCOM_ORDER pComOrder;
  153. UINT fieldLength;
  154. UINT numReps;
  155. DebugEntry(ASHost::OE2_EncodeOrder);
  156. #ifdef ORDER_TRACE
  157. if (OE2_DebugOrderTrace)
  158. {
  159. TrcUnencodedOrder(pIntOrder);
  160. }
  161. #endif // ORDER_TRACE
  162. //
  163. // Set up a pointer to the Common Order.
  164. //
  165. pComOrder = (LPCOM_ORDER)&(pIntOrder->OrderHeader.Common);
  166. //
  167. // Calculate the maximum bytes required to encode this order.
  168. //
  169. if (pComOrder->OrderHeader.fOrderFlags & OF_PRIVATE)
  170. {
  171. //
  172. // Private order.
  173. //
  174. cbMaxEncodedOrderSize = OE2_CONTROL_FLAGS_FIELD_SIZE +
  175. COM_ORDER_SIZE(pComOrder);
  176. }
  177. else
  178. {
  179. //
  180. // Normal (not Private) order.
  181. //
  182. cbMaxEncodedOrderSize = OE2_CONTROL_FLAGS_FIELD_SIZE +
  183. OE2_TYPE_FIELD_SIZE +
  184. OE2_MAX_FIELD_FLAG_BYTES +
  185. OE2_MAX_ADDITIONAL_BOUNDS_BYTES +
  186. COM_ORDER_SIZE(pComOrder);
  187. }
  188. //
  189. // If we are not absolutely certain that the supplied buffer is big
  190. // enough to hold this order (encoded) then return immediately.
  191. //
  192. if (cbMaxEncodedOrderSize > cbBufferSize)
  193. {
  194. cbEncodedOrderSize = 0;
  195. goto encode_order_exit;
  196. }
  197. //
  198. // Set up some local variables to access the encoding buffer in various
  199. // ways.
  200. //
  201. pControlFlags = &((PDCEO2ORDER)pBuffer)->ControlFlags;
  202. pEncodedOrder = (LPSTR)&((PDCEO2ORDER)pBuffer)->EncodedOrder[0];
  203. pEncodingFlags = (LPTSHR_UINT32_UA)&pEncodedOrder[0];
  204. //
  205. // Initialise the control flags field to indicate this is a standard
  206. // encoding (ie the rest of the control flags have the meaning defined
  207. // by the rest of the OE2_CF_XXX definitions).
  208. //
  209. *pControlFlags = OE2_CF_STANDARD_ENC;
  210. //
  211. // If the private flag is set then we must return the encoded order
  212. // as it is (ie without doing any further encoding).
  213. //
  214. if (pComOrder->OrderHeader.fOrderFlags & OF_PRIVATE)
  215. {
  216. *pControlFlags |= OE2_CF_UNENCODED;
  217. cbEncodedOrderSize = SBC_CopyPrivateOrderData(
  218. (LPBYTE)pEncodedOrder,
  219. pComOrder,
  220. cbMaxEncodedOrderSize -
  221. FIELD_OFFSET(DCEO2ORDER, EncodedOrder) );
  222. cbEncodedOrderSize += FIELD_OFFSET(DCEO2ORDER, EncodedOrder);
  223. TRACE_OUT(( "PRIVATE order size %u", cbEncodedOrderSize));
  224. goto encode_order_exit;
  225. }
  226. //
  227. // If the type of this order is different to the last order encoded,
  228. // get a pointer to the last order of this type encoded and remember
  229. // what type of order it is. We must also tell the decoding end that
  230. // this type is different from the last one, so set the new type flag
  231. // and copy type into buffer
  232. //
  233. // The "type" field come before the encoding flags so that the number
  234. // of flags we have can vary depending on the order. Set up a pointer
  235. // to these flags here depending on whether or not we have to encode
  236. // the order type.
  237. //
  238. if (TEXTFIELD(pComOrder)->type != ((PATBLT_ORDER*)m_oe2Tx.pLastOrder)->type)
  239. {
  240. TRACE_OUT(( "change type from %04X to %04X",
  241. LOWORD(((PATBLT_ORDER*)m_oe2Tx.pLastOrder)->type),
  242. LOWORD(TEXTFIELD(pComOrder)->type)));
  243. m_oe2Tx.LastOrderType = OE2GetOrderType(pComOrder);
  244. m_oe2Tx.pLastOrder = (LPCOM_ORDER)m_oe2Tx.LastOrder[m_oe2Tx.LastOrderType];
  245. *(LPBYTE)pEncodedOrder = m_oe2Tx.LastOrderType;
  246. *pControlFlags |= OE2_CF_TYPE_CHANGE;
  247. pEncodingFlags = (LPTSHR_UINT32_UA)&pEncodedOrder[1];
  248. }
  249. else
  250. {
  251. pEncodingFlags = (LPTSHR_UINT32_UA)&pEncodedOrder[0];
  252. }
  253. //
  254. // Work out how many bytes we will need to store the encoding flags in.
  255. // (We have a flag for each field in the order structure). This code
  256. // we have written will cope with up to a DWORD of encoding flags.
  257. //
  258. numEncodingFlagBytes= (s_etable.NumFields[m_oe2Tx.LastOrderType]+7)/8;
  259. if (numEncodingFlagBytes > OE2_MAX_FIELD_FLAG_BYTES)
  260. {
  261. ERROR_OUT(( "Too many flag bytes (%d) for this code", numEncodingFlagBytes));
  262. }
  263. //
  264. // Now we know how many bytes make up the flags we can get a pointer
  265. // to the position at which to start encoding the orders fields into.
  266. //
  267. pNextFreeSpace = ((LPSTR)pEncodingFlags) + numEncodingFlagBytes;
  268. //
  269. // Calculate the bounds. If these are the same as those already in the
  270. // order header then there is no need to send any bounds because we can
  271. // recalculate them at the receiver.
  272. //
  273. m_pShare->OD2_CalculateBounds(pComOrder, &Rect, FALSE, m_pShare->m_pasLocal);
  274. TSHR_RECT16_FROM_RECT(&Rect16, Rect);
  275. if (memcmp(&(pComOrder->OrderHeader.rcsDst), &Rect16, sizeof(Rect16)))
  276. {
  277. TRACE_OUT(( "copy bounding rect"));
  278. OE2EncodeBounds((LPBYTE*)&pNextFreeSpace,
  279. &pComOrder->OrderHeader.rcsDst);
  280. *pControlFlags |= OE2_CF_BOUNDS;
  281. }
  282. //
  283. // Before we do the field encoding (using s_etable) check all the field
  284. // entries flagged as coordinates to see if we can switch to
  285. // OE2_CF_DELTACOORDS mode.
  286. //
  287. pTableEntry = s_etable.pFields[m_oe2Tx.LastOrderType];
  288. useDeltaCoords = TRUE;
  289. //
  290. // Loop through each fixed field in this order structure...
  291. //
  292. while ( useDeltaCoords
  293. && (pTableEntry->FieldPos != 0)
  294. && ((pTableEntry->FieldType & OE2_ETF_FIXED) != 0) )
  295. {
  296. //
  297. // If this field entry is a coordinate then compare it to the
  298. // previous coordinate we sent for this field to determine whether
  299. // we can send it as a delta
  300. //
  301. if (pTableEntry->FieldType & OE2_ETF_COORDINATES)
  302. {
  303. useDeltaCoords =
  304. OE2CanUseDeltaCoords(((LPSTR)pComOrder->abOrderData)
  305. + pTableEntry->FieldPos,
  306. ((LPSTR)m_oe2Tx.pLastOrder)
  307. + pTableEntry->FieldPos,
  308. pTableEntry->FieldUnencodedLen,
  309. pTableEntry->FieldSigned,
  310. 1);
  311. }
  312. pTableEntry++;
  313. }
  314. //
  315. // Loop through each of the variable fields...
  316. //
  317. pVariableField = ((LPSTR)(pComOrder->abOrderData))
  318. + pTableEntry->FieldPos;
  319. while (useDeltaCoords && (pTableEntry->FieldPos != 0))
  320. {
  321. //
  322. // The length of the field (in bytes) is given in the first
  323. // TSHR_UINT32 of the variable sized field structure.
  324. //
  325. fieldLength = *(TSHR_UINT32 FAR *)pVariableField;
  326. pVariableField += sizeof(TSHR_UINT32);
  327. //
  328. // If this field entry is a coordinate then compare it to the
  329. // previous coordinate we sent for this field to determine whether
  330. // we can send it as a delta
  331. //
  332. if (pTableEntry->FieldType & OE2_ETF_COORDINATES)
  333. {
  334. //
  335. // The number of coordinates is given by the number of bytes in
  336. // the field divided by the size of each entry
  337. //
  338. numReps = fieldLength / pTableEntry->FieldUnencodedLen;
  339. useDeltaCoords =
  340. OE2CanUseDeltaCoords(pVariableField,
  341. ((LPSTR)m_oe2Tx.pLastOrder)
  342. + pTableEntry->FieldPos,
  343. pTableEntry->FieldUnencodedLen,
  344. pTableEntry->FieldSigned,
  345. numReps);
  346. }
  347. //
  348. // Move on to the next field in the order structure. Note that
  349. // variable sized fields are packed on the send side. (ie
  350. // increment pVariableField by fieldLength not by
  351. // pTableEntry->FieldLen).
  352. //
  353. pVariableField += fieldLength;
  354. pTableEntry++;
  355. }
  356. if (useDeltaCoords)
  357. {
  358. *pControlFlags |= OE2_CF_DELTACOORDS;
  359. }
  360. //
  361. // Now do the encoding...
  362. //
  363. pTableEntry = s_etable.pFields[m_oe2Tx.LastOrderType];
  364. //
  365. // Clear the encoding flag bytes.
  366. //
  367. for (i = 0; i < numEncodingFlagBytes; i++)
  368. {
  369. ((LPBYTE)pEncodingFlags)[i] = 0;
  370. }
  371. thisFlag = 0x00000001;
  372. //
  373. // First process all the fixed size fields in the order structure...
  374. // (These come before the variable sized fields).
  375. //
  376. while ( (pTableEntry->FieldPos != 0)
  377. && (pTableEntry->FieldType & OE2_ETF_FIXED) )
  378. {
  379. //
  380. // If the field has changed since it was previously transmitted then
  381. // we need to send it again.
  382. //
  383. if (memcmp(
  384. ((LPBYTE)(pComOrder->abOrderData)) + pTableEntry->FieldPos,
  385. ((LPBYTE)m_oe2Tx.pLastOrder) + pTableEntry->FieldPos,
  386. pTableEntry->FieldUnencodedLen))
  387. {
  388. //
  389. // Update the encoding flags
  390. //
  391. *pEncodingFlags |= thisFlag;
  392. //
  393. // If we are encoding in delta coordinate mode and this field
  394. // is a coordinate...
  395. //
  396. if (useDeltaCoords &&
  397. ((pTableEntry->FieldType & OE2_ETF_COORDINATES) != 0) )
  398. {
  399. OE2CopyToDeltaCoords((LPTSHR_INT8*)&pNextFreeSpace,
  400. (((LPSTR)pComOrder->abOrderData)
  401. + pTableEntry->FieldPos),
  402. (((LPSTR)m_oe2Tx.pLastOrder)
  403. + pTableEntry->FieldPos),
  404. pTableEntry->FieldUnencodedLen,
  405. pTableEntry->FieldSigned,
  406. 1);
  407. }
  408. else
  409. {
  410. //
  411. // Update the data to be sent
  412. //
  413. OE2EncodeField(((LPBYTE)(pComOrder->abOrderData)) +
  414. pTableEntry->FieldPos,
  415. (LPBYTE*)&pNextFreeSpace,
  416. pTableEntry->FieldUnencodedLen,
  417. pTableEntry->FieldEncodedLen,
  418. pTableEntry->FieldSigned,
  419. 1);
  420. }
  421. //
  422. // Save the current value for comparison next time.
  423. //
  424. memcpy(((LPBYTE)m_oe2Tx.pLastOrder) + pTableEntry->FieldPos,
  425. ((LPBYTE)(pComOrder->abOrderData)) + pTableEntry->FieldPos,
  426. pTableEntry->FieldUnencodedLen);
  427. }
  428. //
  429. // Move on to the next field in the structure.
  430. //
  431. thisFlag = thisFlag << 1;
  432. pTableEntry++;
  433. }
  434. //
  435. // Now process the variable sized entries...
  436. //
  437. pVariableField = ((LPSTR)(pComOrder->abOrderData))
  438. + pTableEntry->FieldPos;
  439. while (pTableEntry->FieldPos != 0)
  440. {
  441. //
  442. // The length of the field is given in the first UINT of the
  443. // variable sized field structure.
  444. //
  445. fieldLength = *(TSHR_UINT32 FAR *)pVariableField;
  446. //
  447. // If the field has changed (either in size or in contents) then we
  448. // need to copy it across.
  449. //
  450. if (memcmp(pVariableField, ((LPBYTE)m_oe2Tx.pLastOrder) +
  451. pTableEntry->FieldPos, fieldLength + sizeof(TSHR_UINT32)))
  452. {
  453. //
  454. // Update the encoding flags
  455. //
  456. *pEncodingFlags |= thisFlag;
  457. //
  458. // Work out how many elements we are encoding for this field.
  459. //
  460. numReps = fieldLength / pTableEntry->FieldUnencodedLen;
  461. //
  462. // Fill in the length of the field into the encoded buffer
  463. // (this is always encoded in a single byte), then increment
  464. // the pointer ready to encode the actual field.
  465. //
  466. // Note that the length must always be set to the length
  467. // required for regular second level encoding of the field,
  468. // regardless of whether regular encoding or delta encoding is
  469. // used.
  470. //
  471. ASSERT(numReps * pTableEntry->FieldEncodedLen < 256);
  472. *pNextFreeSpace =
  473. (BYTE)(numReps * pTableEntry->FieldEncodedLen);
  474. pNextFreeSpace++;
  475. //
  476. // If we are encoding in delta coordinate mode and this field
  477. // is a coordinate...
  478. //
  479. if (useDeltaCoords &&
  480. ((pTableEntry->FieldType & OE2_ETF_COORDINATES) != 0) )
  481. {
  482. //
  483. // Encode using delta coordinate encoding
  484. //
  485. OE2CopyToDeltaCoords((LPTSHR_INT8*)&pNextFreeSpace,
  486. pVariableField + sizeof(TSHR_UINT32),
  487. ((LPSTR)m_oe2Tx.pLastOrder)
  488. + pTableEntry->FieldPos
  489. + sizeof(TSHR_UINT32),
  490. pTableEntry->FieldUnencodedLen,
  491. pTableEntry->FieldSigned,
  492. numReps);
  493. }
  494. else
  495. {
  496. //
  497. // Use regular encoding
  498. //
  499. OE2EncodeField((LPBYTE)(pVariableField + sizeof(TSHR_UINT32)),
  500. (LPBYTE*)&pNextFreeSpace,
  501. pTableEntry->FieldUnencodedLen,
  502. pTableEntry->FieldEncodedLen,
  503. pTableEntry->FieldSigned,
  504. numReps);
  505. }
  506. //
  507. // Keep data for comparison next time.
  508. //
  509. // Note that the variable fields of pLastOrder are not packed
  510. // (unlike the order which we are encoding), so we can use
  511. // pTableEntry->FieldPos to get the start of the field.
  512. //
  513. memcpy(((LPSTR)m_oe2Tx.pLastOrder) + pTableEntry->FieldPos,
  514. pVariableField,
  515. fieldLength + sizeof(TSHR_UINT32));
  516. }
  517. //
  518. // Move on to the next field in the order structure, remembering to
  519. // step. Note that past the size field. variable sized fields are
  520. // packed on the send side. (ie increment pVariableField by
  521. // fieldLength not by pTableEntry->FieldLen).
  522. //
  523. pVariableField += fieldLength + sizeof(TSHR_UINT32);
  524. //
  525. // Make sure that we are at the next 4-byte boundary
  526. //
  527. if ((((UINT_PTR)pVariableField) % 4) != 0)
  528. {
  529. pVariableField += 4 - (((UINT_PTR)pVariableField) % 4);
  530. }
  531. thisFlag = thisFlag << 1;
  532. pTableEntry++;
  533. }
  534. //
  535. // record some stats:
  536. // Increment the count of order bytes of this type
  537. // Set the flags on for the fields which have been encoded
  538. //
  539. cbEncodedOrderSize = (UINT)(pNextFreeSpace - (LPSTR)pBuffer);
  540. TRACE_OUT(( "return %u flags %x,%x", cbEncodedOrderSize,
  541. (UINT)*pControlFlags, *pEncodingFlags));
  542. encode_order_exit:
  543. //
  544. // "Insurance" check that we have not overwritten the end of the buffer.
  545. //
  546. if (cbEncodedOrderSize > cbBufferSize)
  547. {
  548. //
  549. // Oh dear!
  550. // We should never take this path - if we do, the code has gone
  551. // seriously wrong.
  552. //
  553. ERROR_OUT(( "End of buffer overwritten! enc(%d) buff(%d) type(%d)",
  554. cbEncodedOrderSize,
  555. cbBufferSize,
  556. m_oe2Tx.LastOrderType));
  557. }
  558. //
  559. // Return the length of the encoded order
  560. //
  561. DebugExitDWORD(ASShare::OE2_EncodeOrder, cbEncodedOrderSize);
  562. return((TSHR_UINT16)cbEncodedOrderSize);
  563. }
  564. //
  565. //
  566. // OE2GetOrderType() - see oe2.h
  567. //
  568. //
  569. BYTE OE2GetOrderType(LPCOM_ORDER pOrder)
  570. {
  571. BYTE type = 0xff;
  572. DebugEntry(OE2GetOrderType);
  573. TRACE_OUT(( "order type = %hx", TEXTFIELD(pOrder)->type));
  574. switch ( TEXTFIELD(pOrder)->type )
  575. {
  576. case ORD_DSTBLT_TYPE:
  577. type = OE2_DSTBLT_ORDER;
  578. break;
  579. case ORD_PATBLT_TYPE:
  580. type = OE2_PATBLT_ORDER;
  581. break;
  582. case ORD_SCRBLT_TYPE:
  583. type = OE2_SCRBLT_ORDER;
  584. break;
  585. case ORD_MEMBLT_TYPE:
  586. type = OE2_MEMBLT_ORDER;
  587. break;
  588. case ORD_MEM3BLT_TYPE:
  589. type = OE2_MEM3BLT_ORDER;
  590. break;
  591. case ORD_MEMBLT_R2_TYPE:
  592. type = OE2_MEMBLT_R2_ORDER;
  593. break;
  594. case ORD_MEM3BLT_R2_TYPE:
  595. type = OE2_MEM3BLT_R2_ORDER;
  596. break;
  597. case ORD_TEXTOUT_TYPE:
  598. type = OE2_TEXTOUT_ORDER;
  599. break;
  600. case ORD_EXTTEXTOUT_TYPE:
  601. type = OE2_EXTTEXTOUT_ORDER;
  602. break;
  603. case ORD_RECTANGLE_TYPE:
  604. type = OE2_RECTANGLE_ORDER;
  605. break;
  606. case ORD_LINETO_TYPE:
  607. type = OE2_LINETO_ORDER;
  608. break;
  609. case ORD_OPAQUERECT_TYPE:
  610. type = OE2_OPAQUERECT_ORDER;
  611. break;
  612. case ORD_SAVEBITMAP_TYPE:
  613. type = OE2_SAVEBITMAP_ORDER;
  614. break;
  615. case ORD_DESKSCROLL_TYPE:
  616. type = OE2_DESKSCROLL_ORDER;
  617. break;
  618. case ORD_POLYGON_TYPE:
  619. type = OE2_POLYGON_ORDER;
  620. break;
  621. case ORD_PIE_TYPE:
  622. type = OE2_PIE_ORDER;
  623. break;
  624. case ORD_ELLIPSE_TYPE:
  625. type = OE2_ELLIPSE_ORDER;
  626. break;
  627. case ORD_ARC_TYPE:
  628. type = OE2_ARC_ORDER;
  629. break;
  630. case ORD_CHORD_TYPE:
  631. type = OE2_CHORD_ORDER;
  632. break;
  633. case ORD_POLYBEZIER_TYPE:
  634. type = OE2_POLYBEZIER_ORDER;
  635. break;
  636. case ORD_ROUNDRECT_TYPE:
  637. type = OE2_ROUNDRECT_ORDER;
  638. break;
  639. default:
  640. ERROR_OUT(( "Unknown order type %x",
  641. TEXTFIELD(pOrder)->type));
  642. }
  643. DebugExitDWORD(OE2GetOrderType, type);
  644. return(type);
  645. }
  646. //
  647. // Given a pointer to 2 arrays, work out if the difference between every
  648. // element at corresponding indices in the arrays can be represented by a
  649. // delta (1 byte integer).
  650. //
  651. // ARRAY1 - The first array
  652. // ARRAY2 - The second array
  653. // NUMELEMENTS - The number of elements in the arrays
  654. // DELTASPOSSIBLE - The "return value". Set to TRUE if all differences
  655. // can be represented by deltas, FALSE if not.
  656. //
  657. #define CHECK_DELTA_ARRAY(ARRAY1, ARRAY2, NUMELEMENTS, DELTASPOSSIBLE) \
  658. { \
  659. UINT index; \
  660. int delta; \
  661. (DELTASPOSSIBLE) = TRUE; \
  662. for (index=0 ; index<(NUMELEMENTS) ; index++) \
  663. { \
  664. delta = (ARRAY1)[index] - (ARRAY2)[index]; \
  665. if (delta != (int)(TSHR_INT8)delta) \
  666. { \
  667. (DELTASPOSSIBLE) = FALSE; \
  668. break; \
  669. } \
  670. } \
  671. }
  672. //
  673. //
  674. // Name: OE2CanUseDeltaCoords
  675. //
  676. // Purpose: This function compares two arrays containing a number of
  677. // coordinate values. If the difference between each
  678. // coordinate pair can be expressed as a byte sized delta
  679. // quantity then the function returns TRUE otherwise it returns
  680. // FALSE.
  681. //
  682. // Returns: TRUE if delta coords can be used, FALSE otherwise
  683. //
  684. // Params: IN pNewCoords - Pointer to the new array
  685. // IN pOldCoords - Pointer to the existing array
  686. // IN fieldLength - The size (in bytes) of each element in the
  687. // array.
  688. // IN signedValue - TRUE of the elements in the arrays are
  689. // signed values, FALSE otherwise.
  690. // IN numElements - The number of elements in the arrays.
  691. //
  692. //
  693. BOOL OE2CanUseDeltaCoords(void * pNewCoords,
  694. void * pOldCoords,
  695. UINT fieldLength,
  696. BOOL signedValue,
  697. UINT numElements)
  698. {
  699. LPTSHR_INT16 pNew16Signed = (LPTSHR_INT16)pNewCoords;
  700. LPTSHR_INT32 pNew32Signed = (LPTSHR_INT32)pNewCoords;
  701. LPTSHR_UINT16 pNew16Unsigned = (LPTSHR_UINT16)pNewCoords;
  702. LPUINT pNew32Unsigned = (LPUINT)pNewCoords;
  703. LPTSHR_INT16 pOld16Signed = (LPTSHR_INT16)pOldCoords;
  704. LPTSHR_INT32 pOld32Signed = (LPTSHR_INT32)pOldCoords;
  705. LPTSHR_UINT16 pOld16Unsigned = (LPTSHR_UINT16)pOldCoords;
  706. LPUINT pOld32Unsigned = (LPUINT)pOldCoords;
  707. BOOL useDeltaCoords;
  708. DebugEntry(OE2CanUseDeltaCoords);
  709. switch (fieldLength)
  710. {
  711. case 2:
  712. {
  713. if (signedValue)
  714. {
  715. CHECK_DELTA_ARRAY(pNew16Signed,
  716. pOld16Signed,
  717. numElements,
  718. useDeltaCoords);
  719. }
  720. else
  721. {
  722. CHECK_DELTA_ARRAY(pNew16Unsigned,
  723. pOld16Unsigned,
  724. numElements,
  725. useDeltaCoords);
  726. }
  727. }
  728. break;
  729. case 4:
  730. {
  731. if (signedValue)
  732. {
  733. CHECK_DELTA_ARRAY(pNew32Signed,
  734. pOld32Signed,
  735. numElements,
  736. useDeltaCoords);
  737. }
  738. else
  739. {
  740. CHECK_DELTA_ARRAY(pNew32Unsigned,
  741. pOld32Unsigned,
  742. numElements,
  743. useDeltaCoords);
  744. }
  745. }
  746. break;
  747. default:
  748. {
  749. ERROR_OUT(( "Bad field length %d", fieldLength));
  750. useDeltaCoords = FALSE;
  751. }
  752. break;
  753. }
  754. DebugExitDWORD(OE2CanUseDeltaCoords, useDeltaCoords);
  755. return(useDeltaCoords);
  756. }
  757. //
  758. // Given two arrays, fill in a delta array with each element holding
  759. // ARRAY1[i] - ARRAY2[i]
  760. //
  761. // DESTARRAY - The delta array. This is an array of TSHR_INT8s
  762. // ARRAY1 - The first array
  763. // ARRAY2 - The second array
  764. // NUMELEMENTS - The number of elements in the arrays
  765. //
  766. //
  767. #define COPY_TO_DELTA_ARRAY(DESTARRAY, ARRAY1, ARRAY2, NUMELEMENTS) \
  768. { \
  769. UINT index; \
  770. for (index=0 ; index<(NUMELEMENTS) ; index++) \
  771. { \
  772. (DESTARRAY)[index] = (TSHR_INT8)((ARRAY1)[index] - (ARRAY2)[index]); \
  773. } \
  774. }
  775. //
  776. //
  777. // Name: OE2CopyToDeltaCoords
  778. //
  779. // Purpose: Copies an array of coordinate values to an array of delta
  780. // (byte sized) coordinate values relative to a reference array
  781. // of coordinate values.
  782. //
  783. // Returns: Nothing
  784. //
  785. // Params: IN/OUT ppDestination - Pointer to the start of the
  786. // destination delta array. This is
  787. // updated to point to the byte following
  788. // the last delta on exit.
  789. // IN pNewCoords - Pointer to the new array
  790. // IN pOldCoords - Pointer to the reference array
  791. // IN fieldLength - The size (in bytes) of each element in
  792. // New/OldCoords arrays.
  793. // IN signedValue - TRUE of the elements in the coords
  794. // arrays are signed values, FALSE
  795. // otherwise.
  796. // IN numElements - The number of elements in the arrays.
  797. //
  798. // Operation: The caller should call OE2CanUseDeltaCoords() before calling
  799. // this function to ensure that the differences can be
  800. // encoded using delta coordingates.
  801. //
  802. //
  803. void OE2CopyToDeltaCoords(LPTSHR_INT8* ppDestination,
  804. void * pNewCoords,
  805. void * pOldCoords,
  806. UINT fieldLength,
  807. BOOL signedValue,
  808. UINT numElements)
  809. {
  810. LPTSHR_INT16 pNew16Signed = (LPTSHR_INT16)pNewCoords;
  811. LPTSHR_INT32 pNew32Signed = (LPTSHR_INT32)pNewCoords;
  812. LPTSHR_UINT16 pNew16Unsigned = (LPTSHR_UINT16)pNewCoords;
  813. LPUINT pNew32Unsigned = (LPUINT)pNewCoords;
  814. LPTSHR_INT16 pOld16Signed = (LPTSHR_INT16)pOldCoords;
  815. LPTSHR_INT32 pOld32Signed = (LPTSHR_INT32)pOldCoords;
  816. LPTSHR_UINT16 pOld16Unsigned = (LPTSHR_UINT16)pOldCoords;
  817. LPUINT pOld32Unsigned = (LPUINT)pOldCoords;
  818. DebugEntry(OE2CopyToDeltaCoords);
  819. switch (fieldLength)
  820. {
  821. case 2:
  822. {
  823. if (signedValue)
  824. {
  825. COPY_TO_DELTA_ARRAY(*ppDestination,
  826. pNew16Signed,
  827. pOld16Signed,
  828. numElements);
  829. }
  830. else
  831. {
  832. COPY_TO_DELTA_ARRAY(*ppDestination,
  833. pNew16Unsigned,
  834. pOld16Unsigned,
  835. numElements);
  836. }
  837. }
  838. break;
  839. case 4:
  840. {
  841. if (signedValue)
  842. {
  843. COPY_TO_DELTA_ARRAY(*ppDestination,
  844. pNew32Signed,
  845. pOld32Signed,
  846. numElements);
  847. }
  848. else
  849. {
  850. COPY_TO_DELTA_ARRAY(*ppDestination,
  851. pNew32Unsigned,
  852. pOld32Unsigned,
  853. numElements);
  854. }
  855. }
  856. break;
  857. default:
  858. {
  859. ERROR_OUT(( "Bad field length %d", fieldLength));
  860. }
  861. break;
  862. }
  863. //
  864. // Update the next free position in the destination buffer
  865. //
  866. *ppDestination += numElements;
  867. DebugExitVOID(OE2CopyToDeltaCoords);
  868. }
  869. //
  870. // OE2EncodeBounds()
  871. //
  872. void ASHost::OE2EncodeBounds
  873. (
  874. LPBYTE * ppNextFreeSpace,
  875. LPTSHR_RECT16 pRect
  876. )
  877. {
  878. LPBYTE pFlags;
  879. DebugEntry(ASHost::OE2EncodeBounds);
  880. //
  881. // The encoding used is a byte of flags followed by a variable number
  882. // of 16bit coordinate values and 8bit delta coordinate values (which
  883. // may be interleaved).
  884. //
  885. //
  886. // The first byte of the encoding will contain the flags that represent
  887. // how the coordinates of the rectangle were encoded.
  888. //
  889. pFlags = *ppNextFreeSpace;
  890. *pFlags = 0;
  891. (*ppNextFreeSpace)++;
  892. //
  893. // For each of the four coordinate values in the rectangle: If the
  894. // coordinate has not changed then the encoding is null. If the
  895. // coordinate can be encoded as a delta then do so and set the
  896. // appropriate flag. Otherwise copy the coordinate as a 16bit value
  897. // and set the appropriate flag.
  898. //
  899. if (m_oe2Tx.LastBounds.left != pRect->left)
  900. {
  901. if (OE2CanUseDeltaCoords(&pRect->left,
  902. &m_oe2Tx.LastBounds.left,
  903. sizeof(pRect->left),
  904. TRUE, // signed value
  905. 1))
  906. {
  907. OE2CopyToDeltaCoords((LPTSHR_INT8*)ppNextFreeSpace,
  908. &pRect->left,
  909. &m_oe2Tx.LastBounds.left,
  910. sizeof(pRect->left),
  911. TRUE, // signed value
  912. 1);
  913. *pFlags |= OE2_BCF_DELTA_LEFT;
  914. }
  915. else
  916. {
  917. *((LPTSHR_UINT16)(*ppNextFreeSpace)) = pRect->left;
  918. *pFlags |= OE2_BCF_LEFT;
  919. (*ppNextFreeSpace) = (*ppNextFreeSpace) + sizeof(TSHR_UINT16);
  920. }
  921. }
  922. if (m_oe2Tx.LastBounds.top != pRect->top)
  923. {
  924. if (OE2CanUseDeltaCoords(&pRect->top,
  925. &m_oe2Tx.LastBounds.top,
  926. sizeof(pRect->top),
  927. TRUE, // signed value
  928. 1))
  929. {
  930. OE2CopyToDeltaCoords((LPTSHR_INT8*)ppNextFreeSpace,
  931. &pRect->top,
  932. &m_oe2Tx.LastBounds.top,
  933. sizeof(pRect->top),
  934. TRUE, // signed value
  935. 1);
  936. *pFlags |= OE2_BCF_DELTA_TOP;
  937. }
  938. else
  939. {
  940. *((LPTSHR_UINT16)(*ppNextFreeSpace)) = pRect->top;
  941. *pFlags |= OE2_BCF_TOP;
  942. (*ppNextFreeSpace) = (*ppNextFreeSpace) + sizeof(TSHR_UINT16);
  943. }
  944. }
  945. if (m_oe2Tx.LastBounds.right != pRect->right)
  946. {
  947. if (OE2CanUseDeltaCoords(&pRect->right,
  948. &m_oe2Tx.LastBounds.right,
  949. sizeof(pRect->right),
  950. TRUE, // signed value
  951. 1))
  952. {
  953. OE2CopyToDeltaCoords((LPTSHR_INT8*)ppNextFreeSpace,
  954. &pRect->right,
  955. &m_oe2Tx.LastBounds.right,
  956. sizeof(pRect->right),
  957. TRUE, // signed value
  958. 1);
  959. *pFlags |= OE2_BCF_DELTA_RIGHT;
  960. }
  961. else
  962. {
  963. *((LPTSHR_UINT16)(*ppNextFreeSpace)) = pRect->right;
  964. *pFlags |= OE2_BCF_RIGHT;
  965. (*ppNextFreeSpace) = (*ppNextFreeSpace) + sizeof(TSHR_UINT16);
  966. }
  967. }
  968. if (m_oe2Tx.LastBounds.bottom != pRect->bottom)
  969. {
  970. if (OE2CanUseDeltaCoords(&pRect->bottom,
  971. &m_oe2Tx.LastBounds.bottom,
  972. sizeof(pRect->bottom),
  973. TRUE, // signed value
  974. 1))
  975. {
  976. OE2CopyToDeltaCoords((LPTSHR_INT8*)ppNextFreeSpace,
  977. &pRect->bottom,
  978. &m_oe2Tx.LastBounds.bottom,
  979. sizeof(pRect->bottom),
  980. TRUE, // signed value
  981. 1);
  982. *pFlags |= OE2_BCF_DELTA_BOTTOM;
  983. }
  984. else
  985. {
  986. *((LPTSHR_UINT16)(*ppNextFreeSpace)) = pRect->bottom;
  987. *pFlags |= OE2_BCF_BOTTOM;
  988. (*ppNextFreeSpace) = (*ppNextFreeSpace) + sizeof(TSHR_UINT16);
  989. }
  990. }
  991. //
  992. // Copy the rectangle for reference with the next encoding.
  993. //
  994. m_oe2Tx.LastBounds = *pRect;
  995. DebugExitVOID(ASHost::OE2EncodeBounds);
  996. }
  997. //
  998. // OE2_UseFont()
  999. //
  1000. BOOL ASHost::OE2_UseFont
  1001. (
  1002. LPSTR pName,
  1003. TSHR_UINT16 facelength,
  1004. TSHR_UINT16 CodePage,
  1005. TSHR_UINT16 MaxHeight,
  1006. TSHR_UINT16 Height,
  1007. TSHR_UINT16 Width,
  1008. TSHR_UINT16 Weight,
  1009. TSHR_UINT16 flags
  1010. )
  1011. {
  1012. BOOL rc = TRUE;
  1013. DebugEntry(ASHost::OE2_UseFont);
  1014. if ((!m_oe2Tx.LastHFONT) ||
  1015. (m_oe2Tx.LastFontFaceLen != facelength) ||
  1016. (memcmp(m_oe2Tx.LastFaceName, pName, facelength)) ||
  1017. (m_oe2Tx.LastCodePage != CodePage) ||
  1018. (m_oe2Tx.LastFontHeight != Height ) ||
  1019. (m_oe2Tx.LastFontWidth != Width ) ||
  1020. (m_oe2Tx.LastFontWeight != Weight ) ||
  1021. (m_oe2Tx.LastFontFlags != flags ))
  1022. {
  1023. memcpy(m_oe2Tx.LastFaceName, pName, facelength);
  1024. m_oe2Tx.LastFaceName[facelength] = '\0';
  1025. m_oe2Tx.LastFontFaceLen = facelength;
  1026. m_oe2Tx.LastCodePage = CodePage;
  1027. m_oe2Tx.LastFontHeight = Height;
  1028. m_oe2Tx.LastFontWidth = Width;
  1029. m_oe2Tx.LastFontWeight = Weight;
  1030. m_oe2Tx.LastFontFlags = flags;
  1031. rc = m_pShare->USR_UseFont(m_usrWorkDC,
  1032. &m_oe2Tx.LastHFONT,
  1033. &m_oe2Tx.LastFontMetrics,
  1034. (LPSTR)m_oe2Tx.LastFaceName,
  1035. CodePage,
  1036. MaxHeight,
  1037. Height,
  1038. Width,
  1039. Weight,
  1040. flags);
  1041. }
  1042. DebugExitBOOL(ASHost::OE2_UseFont, rc);
  1043. return(rc);
  1044. }
  1045. //
  1046. // Copy an array of source elements to an array of destination elements,
  1047. // converting the types as the copy takes place.
  1048. //
  1049. // DESTARRAY - The destination array
  1050. // SRCARRAY - The source array
  1051. // DESTTYPE - The type of the elements in the destination array
  1052. // NUMELEMENTS - The number of elements in the array
  1053. //
  1054. //
  1055. #define CONVERT_ARRAY(DESTARRAY, SRCARRAY, DESTTYPE, NUMELEMENTS) \
  1056. { \
  1057. UINT index; \
  1058. for (index=0 ; index<(NUMELEMENTS) ; index++) \
  1059. { \
  1060. (DESTARRAY)[index] = (DESTTYPE)(SRCARRAY)[index]; \
  1061. } \
  1062. }
  1063. //
  1064. // OE2EncodeField - see oe2.h
  1065. //
  1066. void OE2EncodeField(void * pSrc,
  1067. LPBYTE* ppDest,
  1068. UINT srcFieldLength,
  1069. UINT destFieldLength,
  1070. BOOL signedValue,
  1071. UINT numElements)
  1072. {
  1073. LPTSHR_UINT8 pSrc8 = (LPTSHR_UINT8)pSrc;
  1074. LPTSHR_INT16 pSrc16Signed = (LPTSHR_INT16)pSrc;
  1075. LPTSHR_INT32 pSrc32Signed = (LPTSHR_INT32)pSrc;
  1076. LPTSHR_INT8 pDest8Signed = (LPTSHR_INT8)*ppDest;
  1077. LPTSHR_INT16_UA pDest16Signed = (LPTSHR_INT16_UA)*ppDest;
  1078. //
  1079. // Note that the source fields may not be aligned correctly, so we use
  1080. // unaligned pointers. The destination is aligned correctly.
  1081. //
  1082. DebugEntry(OE2EncodeField);
  1083. //
  1084. // We can ignore signed values since we only ever truncate the data.
  1085. // Consider the case where we have a 16 bit integer that we want to
  1086. // convert to 8 bits. We know our values are permissable within the
  1087. // lower integer size (ie. we know the unsigned value will be less
  1088. // than 256 of that a signed value will be -128 >= value >= 127), so we
  1089. // just need to make sure that we have the right high bit set.
  1090. //
  1091. // But this must be the case for a 16-bit equivalent of an 8-bit
  1092. // number. No problems - just take the truncated integer.
  1093. //
  1094. //
  1095. // Make sure that the destination field length is larger or equal to
  1096. // the source field length. If it isn't, something has gone wrong.
  1097. //
  1098. if (srcFieldLength < destFieldLength)
  1099. {
  1100. ERROR_OUT(( "Source field length %d is smaller than destination %d",
  1101. srcFieldLength,
  1102. destFieldLength));
  1103. DC_QUIT;
  1104. }
  1105. //
  1106. // If the source and destination field lengths are the same, we can
  1107. // just do a copy (no type conversion required).
  1108. //
  1109. if (srcFieldLength == destFieldLength)
  1110. {
  1111. memcpy(*ppDest, pSrc, destFieldLength * numElements);
  1112. }
  1113. else
  1114. {
  1115. //
  1116. // We know that srcFieldLength must be greater than destFieldLength
  1117. // because of our checks above. So there are only three
  1118. // conversions to consider:
  1119. //
  1120. // 16 bit -> 8 bit
  1121. // 32 bit -> 8 bit
  1122. // 32 bit -> 16 bit
  1123. //
  1124. // We can ignore the sign as all we are ever doing is truncating
  1125. // the integer.
  1126. //
  1127. if ((srcFieldLength == 4) && (destFieldLength == 1))
  1128. {
  1129. CONVERT_ARRAY(pDest8Signed,
  1130. pSrc32Signed,
  1131. TSHR_INT8,
  1132. numElements);
  1133. }
  1134. else if ((srcFieldLength == 4) && (destFieldLength == 2))
  1135. {
  1136. CONVERT_ARRAY(pDest16Signed,
  1137. pSrc32Signed,
  1138. TSHR_INT16,
  1139. numElements);
  1140. }
  1141. else if ((srcFieldLength == 2) && (destFieldLength == 1))
  1142. {
  1143. CONVERT_ARRAY(pDest8Signed,
  1144. pSrc16Signed,
  1145. TSHR_INT8,
  1146. numElements);
  1147. }
  1148. else
  1149. {
  1150. ERROR_OUT(( "Bad conversion, dest length = %d, src length = %d",
  1151. destFieldLength,
  1152. srcFieldLength));
  1153. }
  1154. }
  1155. DC_EXIT_POINT:
  1156. *ppDest += destFieldLength * numElements;
  1157. DebugExitVOID(OE2EncodeField);
  1158. }
  1159.