Source code of Windows XP (NT5)
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.

634 lines
14 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. paddict.cxx
  5. Abstract:
  6. Implement a counted dictionary class.
  7. Implements a dictionary for handling padding expressions for unknown
  8. represent as data types.
  9. Implements a dictionary for handling sizing macro for unknown
  10. represent as data types.
  11. Implements Quintuple dictionary for registering all type names for both
  12. transmit_as and represent_as.
  13. Implements Quadruple dictionary for handling usr_marshal.
  14. Notes:
  15. History:
  16. Jan 25, 1994 RyszardK Created
  17. ----------------------------------------------------------------------------*/
  18. #include "becls.hxx"
  19. #pragma hdrstop
  20. #include "typecls.hxx"
  21. /////////////////////////////////////////////////////////////////////////////
  22. //
  23. // CountedDictionary class.
  24. //
  25. /////////////////////////////////////////////////////////////////////////////
  26. unsigned short
  27. CountedDictionary::GetListOfItems(
  28. ITERATOR& ListIter )
  29. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  30. Routine Description:
  31. Get a list of dict items into the specified iterator.
  32. Arguments:
  33. ListIter - A reference to the iterator class where the list is
  34. accumulated.
  35. Return Value:
  36. A count of the number of dictionary elements.
  37. Notes:
  38. ----------------------------------------------------------------------------*/
  39. {
  40. Dict_Status Status;
  41. void * pR;
  42. short Count = 0;
  43. //
  44. // Get to the top of the dictionary.
  45. //
  46. Status = Dict_Next( (pUserType) 0 );
  47. //
  48. // Iterate till the entire dictionary is done.
  49. //
  50. while( SUCCESS == Status )
  51. {
  52. pR = Dict_Curr_Item();
  53. ITERATOR_INSERT( ListIter, pR );
  54. Count++;
  55. Status = Dict_Next( pR );
  56. }
  57. return Count;
  58. }
  59. void *
  60. CountedDictionary::GetFirst()
  61. {
  62. Dict_Status Status;
  63. void * pFirst = 0;
  64. Status = Dict_Next( 0 );
  65. if ( Status == SUCCESS )
  66. pFirst = Dict_Curr_Item();
  67. return( pFirst );
  68. }
  69. void *
  70. CountedDictionary::GetNext()
  71. {
  72. Dict_Status Status;
  73. void *pCurr, *pNext = 0;
  74. pCurr = Dict_Curr_Item();
  75. if ( pCurr )
  76. {
  77. Status = Dict_Next( pCurr );
  78. if ( Status == SUCCESS )
  79. pNext = Dict_Curr_Item();
  80. }
  81. return( pNext );
  82. }
  83. SSIZE_T
  84. CountedDictionary::Compare(
  85. pUserType pE1,
  86. pUserType pE2
  87. )
  88. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89. Routine Description:
  90. Compare two Counted types. Defaults to string comparison.
  91. Arguments:
  92. Return Value:
  93. ----------------------------------------------------------------------------*/
  94. {
  95. return( strcmp( (char *)pE1, (char *)pE2) );
  96. }
  97. //===========================================================================
  98. void
  99. RepAsPadExprDict::Register(
  100. unsigned long Offset,
  101. node_skl * pStructType,
  102. char * pFieldName,
  103. node_skl * pPrevFieldType
  104. )
  105. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  106. Routine Description:
  107. Adds a padding expression description to the dictionary
  108. Arguments:
  109. Offset - offset of the padding field
  110. pPaddingExpr - text of the expression to be printed out
  111. ----------------------------------------------------------------------------*/
  112. {
  113. Dict_Status Status;
  114. REP_AS_PAD_EXPR_DESC * pOldEntry;
  115. REP_AS_PAD_EXPR_DESC * pEntry = new REP_AS_PAD_EXPR_DESC;
  116. pEntry->KeyOffset = Offset;
  117. pEntry->pStructType = pStructType;
  118. pEntry->pFieldName = pFieldName;
  119. pEntry->pPrevFieldType = pPrevFieldType;
  120. Status = Dict_Find( pEntry );
  121. switch( Status )
  122. {
  123. case EMPTY_DICTIONARY:
  124. case ITEM_NOT_FOUND:
  125. Dict_Insert( pEntry );
  126. EntryCount++;
  127. break;
  128. default:
  129. // The only reason for an entry (offset) to be used already
  130. // would be that the otimization has shrunk the format string.
  131. // This means that the old entry should be deleted.
  132. pOldEntry = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
  133. Dict_Delete( (pUserType *) &pOldEntry );
  134. Dict_Insert( pEntry );
  135. break;
  136. }
  137. return;
  138. }
  139. SSIZE_T
  140. RepAsPadExprDict::Compare(
  141. pUserType pE1,
  142. pUserType pE2
  143. )
  144. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  145. Routine Description:
  146. Compare pad expr descriptors.
  147. KeyOffset is the key that orders the entries.
  148. Arguments:
  149. Return Value:
  150. ----------------------------------------------------------------------------*/
  151. {
  152. if( ((REP_AS_PAD_EXPR_DESC *)pE1)->KeyOffset <
  153. ((REP_AS_PAD_EXPR_DESC *)pE2)->KeyOffset )
  154. return( -1 );
  155. else
  156. if( ((REP_AS_PAD_EXPR_DESC *)pE1)->KeyOffset >
  157. ((REP_AS_PAD_EXPR_DESC *)pE2)->KeyOffset )
  158. return( 1 );
  159. else
  160. return( 0 );
  161. }
  162. REP_AS_PAD_EXPR_DESC *
  163. RepAsPadExprDict::GetFirst()
  164. {
  165. Dict_Status Status;
  166. REP_AS_PAD_EXPR_DESC * pFirst = 0;
  167. Status = Dict_Next( 0 );
  168. if ( Status == SUCCESS )
  169. pFirst = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
  170. return( pFirst );
  171. }
  172. REP_AS_PAD_EXPR_DESC *
  173. RepAsPadExprDict::GetNext()
  174. {
  175. Dict_Status Status;
  176. REP_AS_PAD_EXPR_DESC *pCurr, *pNext = 0;
  177. pCurr = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
  178. if ( pCurr )
  179. {
  180. Status = Dict_Next( pCurr );
  181. if ( Status == SUCCESS )
  182. pNext = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
  183. }
  184. return( pNext );
  185. }
  186. void
  187. RepAsPadExprDict::WriteCurrentPadDesc(
  188. ISTREAM * pStream
  189. )
  190. /*++
  191. Routine description:
  192. Writes out the following string:
  193. (unsigned char)(NdrFieldPad(pSN,pFN,pPFN,pPFT))
  194. Arguments:
  195. pStream - stream to write to.
  196. --*/
  197. {
  198. REP_AS_PAD_EXPR_DESC *pCurr = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
  199. if ( pCurr && pCurr->pPrevFieldType )
  200. {
  201. pStream->Write( "(unsigned char)("FC_FIELD_PAD_MACRO"(" );
  202. pCurr->pStructType->PrintType( PRT_TYPE_SPECIFIER, pStream );
  203. pStream->Write( ',' );
  204. pStream->Write( pCurr->pFieldName );
  205. pStream->Write( ',' );
  206. pStream->Write( pCurr->pPrevFieldType->GetSymName() );
  207. pStream->Write( ',' );
  208. pCurr->pPrevFieldType->GetChild()->
  209. PrintType( PRT_TYPE_SPECIFIER, pStream );
  210. pStream->Write( "))," );
  211. }
  212. else
  213. pStream->Write( "0," );
  214. }
  215. //========================================================================
  216. void
  217. RepAsSizeDict::Register(
  218. unsigned long Offset,
  219. char * pTypeName
  220. )
  221. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  222. Routine Description:
  223. Adds a sizing macro description to the dictionary
  224. Arguments:
  225. Offset - offset of the padding field
  226. pPaddingExpr - text of the expression to be printed out
  227. ----------------------------------------------------------------------------*/
  228. {
  229. Dict_Status Status;
  230. REP_AS_SIZE_DESC * pOldEntry;
  231. REP_AS_SIZE_DESC * pEntry = new REP_AS_SIZE_DESC;
  232. pEntry->KeyOffset = Offset;
  233. pEntry->pTypeName = pTypeName;
  234. Status = Dict_Find( pEntry );
  235. switch( Status )
  236. {
  237. case EMPTY_DICTIONARY:
  238. case ITEM_NOT_FOUND:
  239. Dict_Insert( pEntry );
  240. EntryCount++;
  241. break;
  242. default:
  243. // The only reason for an entry (offset) to be used already
  244. // would be that the otimization has shrunk the format string.
  245. // This means that the old entry should be deleted.
  246. pOldEntry = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
  247. Dict_Delete( (pUserType *) &pOldEntry );
  248. Dict_Insert( pEntry );
  249. break;
  250. }
  251. return;
  252. }
  253. SSIZE_T
  254. RepAsSizeDict::Compare(
  255. pUserType pE1,
  256. pUserType pE2
  257. )
  258. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  259. Routine Description:
  260. Compare size descriptors.
  261. KeyOffset is the key that orders the entries.
  262. Arguments:
  263. Return Value:
  264. ----------------------------------------------------------------------------*/
  265. {
  266. if( ((REP_AS_SIZE_DESC *)pE1)->KeyOffset <
  267. ((REP_AS_SIZE_DESC *)pE2)->KeyOffset )
  268. return( -1 );
  269. else
  270. if( ((REP_AS_SIZE_DESC *)pE1)->KeyOffset >
  271. ((REP_AS_SIZE_DESC *)pE2)->KeyOffset )
  272. return( 1 );
  273. else
  274. return( 0 );
  275. }
  276. REP_AS_SIZE_DESC *
  277. RepAsSizeDict::GetFirst()
  278. {
  279. Dict_Status Status;
  280. REP_AS_SIZE_DESC * pFirst = 0;
  281. Status = Dict_Next( 0 );
  282. if ( Status == SUCCESS )
  283. pFirst = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
  284. return( pFirst );
  285. }
  286. REP_AS_SIZE_DESC *
  287. RepAsSizeDict::GetNext()
  288. {
  289. Dict_Status Status;
  290. REP_AS_SIZE_DESC *pCurr, *pNext = 0;
  291. pCurr = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
  292. if ( pCurr )
  293. {
  294. Status = Dict_Next( pCurr );
  295. if ( Status == SUCCESS )
  296. pNext = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
  297. }
  298. return( pNext );
  299. }
  300. void
  301. RepAsSizeDict::WriteCurrentSizeDesc(
  302. ISTREAM * pStream
  303. )
  304. /*++
  305. Routine description:
  306. Writes out the following string:
  307. NdrFcShort( sizeof(<type>)
  308. Arguments:
  309. pStream - stream to write to.
  310. --*/
  311. {
  312. REP_AS_SIZE_DESC *pCurr = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
  313. if ( pCurr )
  314. {
  315. pStream->Write( "NdrFcShort( sizeof(" );
  316. pStream->Write( pCurr->pTypeName );
  317. pStream->Write( "))," );
  318. }
  319. else
  320. pStream->Write( "0," );
  321. }
  322. //========================================================================
  323. BOOL
  324. QuintupleDict::Add(
  325. void * pContext
  326. )
  327. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  328. Routine Description:
  329. Adds a Quintuple description to the dictionary.
  330. Arguments:
  331. Returns:
  332. TRUE - when a new entry has been registered,
  333. FALSE - otherwise
  334. Index field gets set to appropriate index.
  335. ----------------------------------------------------------------------------*/
  336. {
  337. Dict_Status Status;
  338. XMIT_AS_CONTEXT * pEntry = (XMIT_AS_CONTEXT *) pContext;
  339. Status = Dict_Find( pEntry );
  340. if( Status == EMPTY_DICTIONARY || Status == ITEM_NOT_FOUND )
  341. {
  342. pEntry->Index = CurrentIndex;
  343. Dict_Insert( pEntry );
  344. CurrentIndex++;
  345. return TRUE;
  346. }
  347. else
  348. {
  349. pEntry->Index = ((XMIT_AS_CONTEXT *)Dict_Curr_Item())->Index;
  350. return FALSE;
  351. }
  352. }
  353. SSIZE_T
  354. QuintupleDict::Compare(
  355. pUserType pE1,
  356. pUserType pE2
  357. )
  358. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  359. Routine Description:
  360. Compare two quintuple types.
  361. Both fXmit and the name have to match.
  362. fXmit allows for comparing xmit_as with xmit_as and rep_as with rep_as.
  363. For xmit_as we compare the presented types.
  364. For rep_as we compare the wire types (not the local types).
  365. Arguments:
  366. Return Value:
  367. ----------------------------------------------------------------------------*/
  368. {
  369. if( ((XMIT_AS_CONTEXT *)pE1)->fXmit == ((XMIT_AS_CONTEXT *)pE2)->fXmit )
  370. if ( ((XMIT_AS_CONTEXT *)pE1)->fXmit )
  371. return( strcmp( ((XMIT_AS_CONTEXT *)pE1)->pTypeName,
  372. ((XMIT_AS_CONTEXT *)pE2)->pTypeName ) );
  373. else
  374. return( strcmp(
  375. ((CG_REPRESENT_AS *)((XMIT_AS_CONTEXT *)pE1)->pXmitNode)->
  376. GetTransmittedType()->GetSymName(),
  377. ((CG_REPRESENT_AS *)((XMIT_AS_CONTEXT *)pE2)->pXmitNode)->
  378. GetTransmittedType()->GetSymName()
  379. ) );
  380. else
  381. if( ((XMIT_AS_CONTEXT *)pE1)->fXmit )
  382. return( -1 );
  383. else
  384. return( 1 );
  385. }
  386. void *
  387. QuintupleDict::GetFirst()
  388. {
  389. Dict_Status Status;
  390. XMIT_AS_CONTEXT * pFirst = 0;
  391. Status = Dict_Next( 0 );
  392. if ( Status == SUCCESS )
  393. pFirst = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
  394. return( pFirst );
  395. }
  396. void *
  397. QuintupleDict::GetNext()
  398. {
  399. Dict_Status Status;
  400. XMIT_AS_CONTEXT *pCurr, *pNext = 0;
  401. pCurr = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
  402. if ( pCurr )
  403. {
  404. Status = Dict_Next( pCurr );
  405. if ( Status == SUCCESS )
  406. pNext = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
  407. }
  408. return( pNext );
  409. }
  410. //========================================================================
  411. BOOL
  412. QuadrupleDict::Add(
  413. void * pContext
  414. )
  415. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  416. Routine Description:
  417. Adds a Quadruple description to the dictionary.
  418. Arguments:
  419. Returns:
  420. TRUE - when a new entry has been registered,
  421. FALSE - otherwise entry exist already
  422. Index field gets set to appropriate index.
  423. ----------------------------------------------------------------------------*/
  424. {
  425. Dict_Status Status;
  426. USER_MARSHAL_CONTEXT * pEntry = (USER_MARSHAL_CONTEXT *) pContext;
  427. Status = Dict_Find( pEntry );
  428. if( Status == EMPTY_DICTIONARY || Status == ITEM_NOT_FOUND )
  429. {
  430. pEntry->Index = GetCount();
  431. Dict_Insert( pEntry );
  432. IncrementCount();
  433. return TRUE;
  434. }
  435. else
  436. {
  437. pEntry->Index = ((USER_MARSHAL_CONTEXT *)Dict_Curr_Item())->Index;
  438. return FALSE;
  439. }
  440. }
  441. SSIZE_T
  442. QuadrupleDict::Compare(
  443. pUserType pE1,
  444. pUserType pE2
  445. )
  446. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  447. Routine Description:
  448. Compare two Quadruple types.
  449. For usr_marshall we compare the types.
  450. Arguments:
  451. Return Value:
  452. ----------------------------------------------------------------------------*/
  453. {
  454. return( strcmp( ((USER_MARSHAL_CONTEXT *)pE1)->pTypeName,
  455. ((USER_MARSHAL_CONTEXT *)pE2)->pTypeName ) );
  456. }