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.

1430 lines
35 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999.
  5. //
  6. // File: Restrict.cxx
  7. //
  8. // Contents: C++ wrappers for restrictions.
  9. //
  10. // History: 31-Dec-92 KyleP Created
  11. // 28-Jul-94 KyleP Hand marshalling
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include <pidmap.hxx>
  17. #include <coldesc.hxx>
  18. #include <pickle.hxx>
  19. //+-------------------------------------------------------------------------
  20. //
  21. // Member: CFullPropSpec::CFullPropSpec, public
  22. //
  23. // Synopsis: Copy constructor
  24. //
  25. // Arguments: [src] -- Source property spec
  26. //
  27. // History: 17-Jul-93 KyleP Created
  28. //
  29. //--------------------------------------------------------------------------
  30. CFullPropSpec::CFullPropSpec( CFullPropSpec const & src )
  31. : _guidPropSet( src._guidPropSet )
  32. {
  33. _psProperty.ulKind = src._psProperty.ulKind;
  34. if ( _psProperty.ulKind == PRSPEC_LPWSTR )
  35. {
  36. if ( src._psProperty.lpwstr )
  37. {
  38. _psProperty.ulKind = PRSPEC_PROPID;
  39. SetProperty( src._psProperty.lpwstr );
  40. }
  41. else
  42. _psProperty.lpwstr = 0;
  43. }
  44. else
  45. {
  46. _psProperty.propid = src._psProperty.propid;
  47. }
  48. }
  49. void CFullPropSpec::Marshall( PSerStream & stm ) const
  50. {
  51. stm.PutGUID( _guidPropSet );
  52. stm.PutULong( _psProperty.ulKind );
  53. switch( _psProperty.ulKind )
  54. {
  55. case PRSPEC_PROPID:
  56. stm.PutULong( _psProperty.propid );
  57. break;
  58. case PRSPEC_LPWSTR:
  59. {
  60. ULONG cc = wcslen( _psProperty.lpwstr );
  61. stm.PutULong( cc );
  62. stm.PutWChar( _psProperty.lpwstr, cc );
  63. break;
  64. }
  65. default:
  66. Win4Assert( !"Invalid PROPSPEC" );
  67. break;
  68. }
  69. }
  70. CFullPropSpec::CFullPropSpec( PDeSerStream & stm )
  71. {
  72. stm.GetGUID( _guidPropSet );
  73. _psProperty.ulKind = stm.GetULong();
  74. switch( _psProperty.ulKind )
  75. {
  76. case PRSPEC_PROPID:
  77. _psProperty.propid = stm.GetULong();
  78. break;
  79. case PRSPEC_LPWSTR:
  80. {
  81. _psProperty.lpwstr = UnMarshallWideString( stm );
  82. break;
  83. }
  84. default:
  85. Win4Assert( !"Invalid PROPSPEC" );
  86. // Make the fullpropspec look invalid, so the later check fails.
  87. _psProperty.ulKind = PRSPEC_LPWSTR;
  88. _psProperty.lpwstr = 0;
  89. break;
  90. }
  91. }
  92. void CFullPropSpec::SetProperty( PROPID pidProperty )
  93. {
  94. if ( _psProperty.ulKind == PRSPEC_LPWSTR &&
  95. 0 != _psProperty.lpwstr )
  96. {
  97. CoTaskMemFree( _psProperty.lpwstr );
  98. }
  99. _psProperty.ulKind = PRSPEC_PROPID;
  100. _psProperty.propid = pidProperty;
  101. }
  102. BOOL CFullPropSpec::SetProperty( WCHAR const * wcsProperty )
  103. {
  104. if ( _psProperty.ulKind == PRSPEC_LPWSTR &&
  105. 0 != _psProperty.lpwstr )
  106. {
  107. CoTaskMemFree( _psProperty.lpwstr );
  108. }
  109. _psProperty.ulKind = PRSPEC_LPWSTR;
  110. int len = (wcslen( wcsProperty ) + 1) * sizeof( WCHAR );
  111. _psProperty.lpwstr = (WCHAR *)CoTaskMemAlloc( len );
  112. if ( 0 != _psProperty.lpwstr )
  113. {
  114. memcpy( _psProperty.lpwstr,
  115. wcsProperty,
  116. len );
  117. return( TRUE );
  118. }
  119. else
  120. {
  121. _psProperty.lpwstr = 0;
  122. return( FALSE );
  123. }
  124. }
  125. //
  126. // Methods for CColumns
  127. //
  128. CColumns::CColumns( unsigned size )
  129. : _size( size ),
  130. _cCol( 0 ),
  131. _aCol( 0 )
  132. {
  133. Win4Assert( OFFSETS_MATCH( COLUMNSET, cCol, CColumns, _cCol ) );
  134. Win4Assert( OFFSETS_MATCH( COLUMNSET, aCol, CColumns, _aCol ) );
  135. //
  136. // Avoid nasty boundary condition for ::IsValid
  137. //
  138. if ( _size == 0 )
  139. _size = 8;
  140. _aCol = new CFullPropSpec [ _size ];
  141. memset( _aCol, PRSPEC_PROPID, _size * sizeof( CFullPropSpec ) );
  142. }
  143. CColumns::CColumns( CColumns const & src )
  144. : _size( src._cCol ),
  145. _cCol( 0 )
  146. {
  147. Win4Assert( OFFSETS_MATCH( COLUMNSET, cCol, CColumns, _cCol ) );
  148. Win4Assert( OFFSETS_MATCH( COLUMNSET, aCol, CColumns, _aCol ) );
  149. //
  150. // Avoid nasty boundary condition for ::IsValid
  151. //
  152. if ( _size == 0 )
  153. _size = 1;
  154. _aCol = new CFullPropSpec [ _size ];
  155. if ( 0 == _aCol )
  156. THROW( CException( E_OUTOFMEMORY ) );
  157. memset( _aCol, PRSPEC_PROPID, _size * sizeof( CFullPropSpec ) );
  158. // Add does not throw since the array has been sized already
  159. while ( _cCol < src._cCol )
  160. {
  161. Add( src.Get( _cCol ), _cCol );
  162. if ( !Get( _cCol-1 ).IsValid() )
  163. {
  164. delete [] _aCol;
  165. _aCol = 0;
  166. THROW( CException( E_OUTOFMEMORY ) );
  167. }
  168. }
  169. }
  170. CColumns::~CColumns()
  171. {
  172. delete [] _aCol;
  173. }
  174. void CColumns::Marshall( PSerStream & stm ) const
  175. {
  176. stm.PutULong( _cCol );
  177. for ( unsigned i = 0; i < _cCol; i++ )
  178. {
  179. _aCol[i].Marshall( stm );
  180. }
  181. }
  182. CColumns::CColumns( PDeSerStream & stm )
  183. {
  184. _size = stm.GetULong();
  185. //
  186. // Avoid nasty boundary condition for ::IsValid
  187. //
  188. // Guard against attack
  189. if ( _size == 0 )
  190. _size = 1;
  191. else if ( _size > 1000 )
  192. THROW( CException( E_INVALIDARG ) );
  193. XArray< CFullPropSpec > xCol( _size );
  194. _aCol = xCol.GetPointer();
  195. for( _cCol = 0; _cCol < _size; _cCol++ )
  196. {
  197. CFullPropSpec ps(stm);
  198. Add( ps, _cCol );
  199. }
  200. xCol.Acquire();
  201. }
  202. void CColumns::Add( CFullPropSpec const & Property, unsigned pos )
  203. {
  204. if ( pos >= _size )
  205. {
  206. unsigned cNew = (_size > 0) ? (_size * 2) : 8;
  207. while ( pos >= cNew )
  208. cNew = cNew * 2;
  209. CFullPropSpec * aNew = new CFullPropSpec[cNew];
  210. if ( _aCol )
  211. {
  212. memcpy( aNew, _aCol, _cCol * sizeof( CFullPropSpec ) );
  213. memset( _aCol, PRSPEC_PROPID, _size * sizeof CFullPropSpec );
  214. delete [] _aCol;
  215. }
  216. memset( aNew + _cCol, PRSPEC_PROPID, (cNew - _cCol) * sizeof( CFullPropSpec ) );
  217. _aCol = aNew;
  218. _size = cNew;
  219. }
  220. _aCol[pos] = Property;
  221. if ( pos >= _cCol )
  222. _cCol = pos + 1;
  223. }
  224. void CColumns::Remove( unsigned pos )
  225. {
  226. if ( pos < _cCol )
  227. {
  228. _aCol[pos].CFullPropSpec::~CFullPropSpec();
  229. _cCol--;
  230. RtlMoveMemory( _aCol + pos,
  231. _aCol + pos + 1,
  232. (_cCol - pos) * sizeof( CFullPropSpec ) );
  233. }
  234. }
  235. //
  236. // Methods for CSort
  237. //
  238. CSort::CSort( unsigned size )
  239. : _size( size ),
  240. _csk( 0 ),
  241. _ask( 0 )
  242. {
  243. Win4Assert( OFFSETS_MATCH( SORTSET, cCol, CSort, _csk ) );
  244. Win4Assert( OFFSETS_MATCH( SORTSET, aCol, CSort, _ask ) );
  245. if ( _size > 0 )
  246. {
  247. _ask = new CSortKey[_size];
  248. memset( _ask, PRSPEC_PROPID, _size * sizeof( CSortKey ) );
  249. }
  250. }
  251. CSort::CSort( CSort const & src )
  252. : _size( src._csk ),
  253. _csk( 0 ),
  254. _ask( 0 )
  255. {
  256. Win4Assert( OFFSETS_MATCH( SORTSET, cCol, CSort, _csk ) );
  257. Win4Assert( OFFSETS_MATCH( SORTSET, aCol, CSort, _ask ) );
  258. if ( _size > 0 )
  259. {
  260. _ask = new CSortKey[ _size ];
  261. memset( _ask, PRSPEC_PROPID, _size * sizeof( CSortKey ) );
  262. while( _csk < src._csk )
  263. {
  264. Add( src.Get( _csk ), _csk );
  265. }
  266. }
  267. }
  268. void CSortKey::Marshall( PSerStream & stm ) const
  269. {
  270. //
  271. // NOTE: Order is important!
  272. //
  273. _property.Marshall( stm );
  274. stm.PutULong( _dwOrder );
  275. }
  276. CSortKey::CSortKey( PDeSerStream & stm )
  277. : _property( stm ),
  278. _dwOrder( stm.GetULong() )
  279. {
  280. if ( !_property.IsValid() )
  281. THROW( CException( E_OUTOFMEMORY ) );
  282. }
  283. CSort::~CSort()
  284. {
  285. delete [] _ask;
  286. }
  287. void CSort::Marshall( PSerStream & stm ) const
  288. {
  289. stm.PutULong( _csk );
  290. for ( unsigned i = 0; i < _csk; i++ )
  291. {
  292. _ask[i].Marshall( stm );
  293. }
  294. }
  295. CSort::CSort( PDeSerStream & stm )
  296. : _csk( stm.GetULong() ),
  297. _size( _csk )
  298. {
  299. XPtr<CSortKey> xSortKey( new CSortKey[ _csk ] );
  300. _ask = xSortKey.GetPointer();
  301. for ( unsigned i = 0; i < _csk; i++ )
  302. {
  303. CSortKey sk( stm );
  304. Add( sk, i );
  305. }
  306. xSortKey.Acquire();
  307. }
  308. void CSort::Add( CSortKey const & sk, unsigned pos )
  309. {
  310. if ( pos >= _size )
  311. {
  312. unsigned cNew = (_size > 0) ? (_size * 2) : 4;
  313. while ( pos >= cNew )
  314. {
  315. cNew = cNew * 2;
  316. }
  317. CSortKey * aNew = new CSortKey[ cNew ];
  318. if ( _ask )
  319. {
  320. memcpy( aNew, _ask, _csk * sizeof( CSortKey ) );
  321. memset( _ask, PRSPEC_PROPID, _size * sizeof CSortKey );
  322. delete [] _ask;
  323. }
  324. memset( aNew + _csk, PRSPEC_PROPID, (cNew - _csk) * sizeof( CSortKey ) );
  325. _ask = aNew;
  326. _size = cNew;
  327. }
  328. _ask[pos] = sk;
  329. if ( !_ask[pos].IsValid() )
  330. THROW( CException( E_OUTOFMEMORY ) );
  331. if ( pos >= _csk )
  332. {
  333. _csk = pos + 1;
  334. }
  335. }
  336. void CSort::Add( CFullPropSpec const & property, ULONG dwOrder, unsigned pos )
  337. {
  338. CSortKey sk( property, dwOrder );
  339. Add(sk, pos);
  340. }
  341. void CSort::Remove( unsigned pos )
  342. {
  343. if ( pos < _csk )
  344. {
  345. _ask[pos].GetProperty().CFullPropSpec::~CFullPropSpec();
  346. _csk--;
  347. RtlMoveMemory( _ask + pos,
  348. _ask + pos + 1,
  349. (_csk - pos) * sizeof( CSortKey ) );
  350. }
  351. }
  352. //
  353. // Methods for CRestriction
  354. //
  355. //+-------------------------------------------------------------------------
  356. //
  357. // Member: CRestriction::~CRestriction(), public
  358. //
  359. // Synopsis: Destroy restriction. See Notes below.
  360. //
  361. // History: 31-Dec-92 KyleP Created
  362. //
  363. // Notes: This destructor simulates virtual destruction. A
  364. // virtual destructor is not possible in CRestriction
  365. // because it maps directly to the C structure SRestriction.
  366. //
  367. // Classes derived from CRestriction must be sure to set their
  368. // restriction type to RTNone in their destructor, so when the
  369. // base destructor below is called the derived destructor is
  370. // not called a second time.
  371. //
  372. //--------------------------------------------------------------------------
  373. CRestriction::~CRestriction()
  374. {
  375. //
  376. // It would be nice to assert in constructor but it's inline and
  377. // Win4Assert is not a public export.
  378. //
  379. Win4Assert( OFFSETS_MATCH( RESTRICTION, rt, CRestriction, _ulType ) );
  380. Win4Assert( OFFSETS_MATCH( RESTRICTION, weight,
  381. CRestriction, _lWeight ) );
  382. switch ( Type() )
  383. {
  384. case RTNone:
  385. break;
  386. case RTAnd:
  387. case RTOr:
  388. case RTProximity:
  389. case RTVector:
  390. case RTPhrase:
  391. CastToNode()->CNodeRestriction::~CNodeRestriction();
  392. break;
  393. case RTNot:
  394. ((CNotRestriction *)this)->
  395. CNotRestriction::~CNotRestriction();
  396. break;
  397. case RTProperty:
  398. ((CPropertyRestriction *)this)->
  399. CPropertyRestriction::~CPropertyRestriction();
  400. break;
  401. case RTContent:
  402. ((CContentRestriction *)this)->
  403. CContentRestriction::~CContentRestriction();
  404. break;
  405. case RTNatLanguage:
  406. ((CNatLanguageRestriction *)this)->
  407. CNatLanguageRestriction::~CNatLanguageRestriction();
  408. break;
  409. case RTScope:
  410. ((CScopeRestriction *)this)->CScopeRestriction::~CScopeRestriction();
  411. break;
  412. case RTWord:
  413. ((CWordRestriction *)this)->CWordRestriction::~CWordRestriction();
  414. break;
  415. case RTSynonym:
  416. ((CSynRestriction *)this)->CSynRestriction::~CSynRestriction();
  417. break;
  418. case RTRange:
  419. ((CRangeRestriction *)this)->CRangeRestriction::~CRangeRestriction();
  420. break;
  421. case RTInternalProp:
  422. ((CInternalPropertyRestriction *)this)->
  423. CInternalPropertyRestriction::~CInternalPropertyRestriction();
  424. break;
  425. default:
  426. ciDebugOut(( DEB_ERROR,
  427. "Unhandled child (%d) of class CRestriction\n", Type() ));
  428. Win4Assert( !"Unhandled child class of CRestriction" );
  429. break;
  430. }
  431. }
  432. //+-------------------------------------------------------------------------
  433. //
  434. // Member: CRestriction::TreeCount(), public
  435. //
  436. // Synopsis: Returns the number of items in the tree
  437. //
  438. // History: 15-Jul-96 dlee Created
  439. //
  440. //--------------------------------------------------------------------------
  441. ULONG CRestriction::TreeCount() const
  442. {
  443. ULONG cItems = 1;
  444. switch ( Type() )
  445. {
  446. case RTNone:
  447. break;
  448. case RTAnd:
  449. case RTOr:
  450. case RTProximity:
  451. case RTVector:
  452. case RTPhrase:
  453. {
  454. CNodeRestriction * p = CastToNode();
  455. for ( ULONG x = 0; x < p->Count(); x++ )
  456. {
  457. cItems += p->GetChild( x )->TreeCount();
  458. }
  459. break;
  460. }
  461. case RTNot:
  462. {
  463. CNotRestriction * p = (CNotRestriction *) this;
  464. cItems += p->GetChild()->TreeCount();
  465. break;
  466. }
  467. case RTProperty:
  468. case RTContent:
  469. case RTNatLanguage:
  470. case RTScope:
  471. case RTWord:
  472. case RTSynonym:
  473. case RTRange:
  474. case RTInternalProp:
  475. break;
  476. default:
  477. ciDebugOut(( DEB_ERROR,
  478. "Unhandled child (%d) of class CRestriction\n", Type() ));
  479. Win4Assert( !"Unhandled child class of CRestriction" );
  480. break;
  481. }
  482. return cItems;
  483. }
  484. //+-------------------------------------------------------------------------
  485. //
  486. // Member: CRestriction::IsValid(), public
  487. //
  488. // History: 14-Nov-95 KyleP Created
  489. //
  490. // Returns: TRUE if all memory allocations, etc. succeeded.
  491. //
  492. //--------------------------------------------------------------------------
  493. BOOL CRestriction::IsValid() const
  494. {
  495. BOOL fValid = TRUE;
  496. switch ( Type() )
  497. {
  498. case RTNone:
  499. break;
  500. case RTAnd:
  501. case RTOr:
  502. case RTProximity:
  503. case RTVector:
  504. case RTPhrase:
  505. fValid = CastToNode()->CNodeRestriction::IsValid();
  506. break;
  507. case RTNot:
  508. fValid = ((CNotRestriction *)this)->
  509. CNotRestriction::IsValid();
  510. break;
  511. case RTProperty:
  512. fValid = ((CPropertyRestriction *)this)->
  513. CPropertyRestriction::IsValid();
  514. break;
  515. case RTContent:
  516. fValid = ((CContentRestriction *)this)->
  517. CContentRestriction::IsValid();
  518. break;
  519. case RTNatLanguage:
  520. fValid = ((CNatLanguageRestriction *)this)->
  521. CNatLanguageRestriction::IsValid();
  522. break;
  523. case RTScope:
  524. fValid = ((CScopeRestriction *)this)->
  525. CScopeRestriction::IsValid();
  526. break;
  527. case RTWord:
  528. fValid = ((CWordRestriction *)this)->
  529. CWordRestriction::IsValid();
  530. break;
  531. case RTSynonym:
  532. fValid = ((CSynRestriction *)this)->
  533. CSynRestriction::IsValid();
  534. break;
  535. case RTRange:
  536. fValid = ((CRangeRestriction *)this)->
  537. CRangeRestriction::IsValid();
  538. break;
  539. case RTInternalProp:
  540. fValid = ((CInternalPropertyRestriction *)this)->
  541. CInternalPropertyRestriction::IsValid();
  542. break;
  543. default:
  544. ciDebugOut(( DEB_ERROR,
  545. "Unhandled child (%d) of class CRestriction\n", Type() ));
  546. Win4Assert( !"Unhandled child class of CRestriction" );
  547. fValid = FALSE;
  548. break;
  549. }
  550. return fValid;
  551. }
  552. void CRestriction::Marshall( PSerStream & stm ) const
  553. {
  554. stm.PutULong( Type() );
  555. stm.PutLong( Weight() );
  556. switch ( Type() )
  557. {
  558. case RTNone:
  559. break;
  560. case RTAnd:
  561. case RTOr:
  562. case RTProximity:
  563. case RTPhrase:
  564. ((CNodeRestriction *)this)->Marshall( stm );
  565. break;
  566. case RTVector:
  567. ((CVectorRestriction *)this)->Marshall( stm );
  568. break;
  569. case RTNot:
  570. ((CNotRestriction *)this)->Marshall( stm );
  571. break;
  572. case RTProperty:
  573. ((CPropertyRestriction *)this)->Marshall( stm );
  574. break;
  575. case RTContent:
  576. ((CContentRestriction *)this)->Marshall( stm );
  577. break;
  578. case RTNatLanguage:
  579. ((CNatLanguageRestriction *)this)->Marshall( stm );
  580. break;
  581. case RTScope:
  582. ((CScopeRestriction *)this)->Marshall( stm );
  583. break;
  584. case RTWord:
  585. case RTSynonym:
  586. ((COccRestriction *)this)->Marshall( stm );
  587. break;
  588. case RTRange:
  589. ((CRangeRestriction *)this)->Marshall( stm );
  590. break;
  591. case RTInternalProp:
  592. ((CInternalPropertyRestriction *)this)->Marshall( stm );
  593. break;
  594. default:
  595. ciDebugOut(( DEB_ERROR,
  596. "Unhandled child (%d) of class CRestriction\n", Type() ));
  597. Win4Assert( !"Unhandled child class of CRestriction" );
  598. break;
  599. }
  600. }
  601. CRestriction * CRestriction::UnMarshall( PDeSerStream & stm )
  602. {
  603. ULONG ulType = stm.GetULong();
  604. LONG lWeight = stm.GetLong();
  605. switch ( ulType )
  606. {
  607. case RTNone:
  608. return new CRestriction( ulType, lWeight );
  609. case RTAnd:
  610. case RTOr:
  611. case RTProximity:
  612. return new CNodeRestriction( ulType, lWeight, stm );
  613. break;
  614. case RTPhrase:
  615. return new CPhraseRestriction( lWeight, stm );
  616. break;
  617. case RTVector:
  618. return new CVectorRestriction( lWeight, stm );
  619. break;
  620. case RTNot:
  621. return new CNotRestriction( lWeight, stm );
  622. break;
  623. case RTProperty:
  624. return new CPropertyRestriction( lWeight, stm );
  625. break;
  626. case RTContent:
  627. return new CContentRestriction( lWeight, stm );
  628. break;
  629. case RTNatLanguage:
  630. return new CNatLanguageRestriction( lWeight, stm );
  631. break;
  632. case RTScope:
  633. return new CScopeRestriction( lWeight, stm );
  634. break;
  635. case RTWord:
  636. return new CWordRestriction( lWeight, stm );
  637. break;
  638. case RTSynonym:
  639. return new CSynRestriction( lWeight, stm );
  640. break;
  641. case RTRange:
  642. return new CRangeRestriction( lWeight, stm );
  643. break;
  644. case RTInternalProp:
  645. return new CInternalPropertyRestriction( lWeight, stm );
  646. break;
  647. default:
  648. ciDebugOut(( DEB_ERROR,
  649. "Unhandled child (%d) of class CRestriction during unmarshalling\n",
  650. ulType ));
  651. Win4Assert( !"Unhandled child class of CRestriction" );
  652. THROW( CException( E_INVALIDARG ) );
  653. break;
  654. }
  655. return( 0 );
  656. }
  657. //+-------------------------------------------------------------------------
  658. //
  659. // Member: CRestriction::IsLeaf, public
  660. //
  661. // Returns: TRUE if node is a leaf node
  662. //
  663. // History: 12-Feb-93 KyleP Moved from .hxx
  664. //
  665. //--------------------------------------------------------------------------
  666. BOOL CRestriction::IsLeaf() const
  667. {
  668. switch( Type() )
  669. {
  670. case RTAnd:
  671. case RTOr:
  672. case RTNot:
  673. case RTProximity:
  674. case RTVector:
  675. case RTPhrase:
  676. return( FALSE );
  677. default:
  678. return( TRUE );
  679. }
  680. }
  681. CRestriction *CRestriction::Clone() const
  682. {
  683. switch ( Type() )
  684. {
  685. case RTAnd:
  686. case RTOr:
  687. case RTProximity:
  688. case RTPhrase:
  689. return ( (CNodeRestriction *) this)->Clone();
  690. case RTVector:
  691. return ( (CVectorRestriction *) this)->Clone();
  692. case RTNot:
  693. return ( (CNotRestriction *) this)->Clone();
  694. case RTInternalProp:
  695. return ( (CInternalPropertyRestriction *) this)->Clone();
  696. case RTContent:
  697. return ( (CContentRestriction *) this)->Clone();
  698. case RTWord:
  699. return ( (CWordRestriction *) this)->Clone();
  700. case RTSynonym:
  701. return ( (CSynRestriction *) this)->Clone();
  702. case RTRange:
  703. return( (CRangeRestriction *) this)->Clone();
  704. case RTScope:
  705. return ((CScopeRestriction *) this)->Clone();
  706. case RTNone:
  707. return new CRestriction;
  708. default:
  709. ciDebugOut(( DEB_ERROR, "No clone method for restriction type - %d\n", Type() ));
  710. Win4Assert( !"CRestriction: Clone method should be overridden in child class" );
  711. return 0;
  712. }
  713. }
  714. CNodeRestriction::CNodeRestriction( ULONG NodeType,
  715. unsigned cInitAllocated )
  716. : CRestriction( NodeType, MAX_QUERY_RANK ),
  717. _cNode( 0 ),
  718. _paNode( 0 ),
  719. _cNodeAllocated( cInitAllocated )
  720. {
  721. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.cRes,
  722. CNodeRestriction, _cNode ) );
  723. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.paRes,
  724. CNodeRestriction, _paNode ) );
  725. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.reserved,
  726. CNodeRestriction, _cNodeAllocated ) );
  727. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.cRes,
  728. CNodeRestriction, _cNode ) );
  729. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.paRes,
  730. CNodeRestriction, _paNode ) );
  731. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.reserved,
  732. CNodeRestriction, _cNodeAllocated ) );
  733. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.cRes,
  734. CNodeRestriction, _cNode ) );
  735. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.paRes,
  736. CNodeRestriction, _paNode ) );
  737. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.reserved,
  738. CNodeRestriction, _cNodeAllocated ) );
  739. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.cRes,
  740. CNodeRestriction, _cNode ) );
  741. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.paRes,
  742. CNodeRestriction, _paNode ) );
  743. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.reserved,
  744. CNodeRestriction, _cNodeAllocated ) );
  745. if ( _cNodeAllocated > 0 )
  746. {
  747. _paNode = new CRestriction * [ _cNodeAllocated ];
  748. }
  749. }
  750. CNodeRestriction::CNodeRestriction( const CNodeRestriction& nodeRst )
  751. : CRestriction( nodeRst.Type(), nodeRst.Weight() ),
  752. _cNode( nodeRst.Count() ),
  753. _cNodeAllocated( nodeRst.Count() ),
  754. _paNode( 0 )
  755. {
  756. if ( _cNodeAllocated > 0 )
  757. {
  758. _paNode = new CRestriction * [ _cNodeAllocated ];
  759. RtlZeroMemory( _paNode, _cNodeAllocated * sizeof( CRestriction * ) );
  760. for ( unsigned i=0; i<_cNode; i++ )
  761. _paNode[i] = nodeRst.GetChild( i )->Clone();
  762. }
  763. }
  764. //+-------------------------------------------------------------------------
  765. //
  766. // Member: CNodeRestriction::~CNodeRestriction(), public
  767. //
  768. // Synopsis: Destroy node restriction. See Notes below.
  769. //
  770. // History: 31-Dec-92 KyleP Created
  771. //
  772. // Notes: This destructor simulates virtual destruction. A
  773. // virtual destructor is not possible in CNodeRestriction
  774. // because it maps directly to a C structure.
  775. //
  776. // Classes derived from CNodeRestriction must be sure to set their
  777. // restriction type to RTNone in their destructor, so when the
  778. // base destructor below is called the derived destructor is
  779. // not called a second time.
  780. //
  781. //--------------------------------------------------------------------------
  782. CNodeRestriction::~CNodeRestriction()
  783. {
  784. switch( Type() )
  785. {
  786. case RTNone:
  787. break;
  788. case RTAnd:
  789. case RTOr:
  790. case RTProximity:
  791. case RTVector:
  792. {
  793. if ( 0 != _paNode )
  794. {
  795. for ( unsigned i = 0; i < _cNode; i++ )
  796. delete _paNode[i];
  797. delete [] _paNode;
  798. }
  799. SetType( RTNone ); // Avoid recursion.
  800. break;
  801. }
  802. case RTPhrase:
  803. (( CPhraseRestriction *)this)->CPhraseRestriction::~CPhraseRestriction();
  804. break;
  805. case RTScope:
  806. (( CScopeRestriction *)this)->CScopeRestriction::~CScopeRestriction();
  807. break;
  808. default:
  809. ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CNodeRestriction\n",
  810. Type() ));
  811. Win4Assert( !"Unhandled child of class CNodeRestriction" );
  812. break;
  813. }
  814. }
  815. //+-------------------------------------------------------------------------
  816. //
  817. // Member: CNodeRestriction::IsValid(), public
  818. //
  819. // History: 14-Nov-95 KyleP Created
  820. //
  821. // Returns: TRUE if all memory allocations, etc. succeeded.
  822. //
  823. //--------------------------------------------------------------------------
  824. BOOL CNodeRestriction::IsValid() const
  825. {
  826. if ( 0 == _paNode )
  827. return FALSE;
  828. for ( unsigned i = 0; i < _cNode; i++ )
  829. {
  830. if ( 0 == _paNode[i] || !_paNode[i]->IsValid() )
  831. return FALSE;
  832. }
  833. return TRUE;
  834. }
  835. void CNodeRestriction::Marshall( PSerStream & stm ) const
  836. {
  837. #if CIDBG == 1
  838. if ( Type() == RTPhrase )
  839. {
  840. for ( unsigned i = 0; i < _cNode; i++ )
  841. Win4Assert( _paNode[i]->Type() == RTWord || _paNode[i]->Type() == RTSynonym );
  842. }
  843. #endif
  844. stm.PutULong( _cNode );
  845. for ( unsigned i = 0; i < _cNode; i++ )
  846. {
  847. _paNode[i]->Marshall( stm );
  848. }
  849. }
  850. CNodeRestriction::CNodeRestriction( ULONG ulType, LONG lWeight, PDeSerStream & stm )
  851. : CRestriction( ulType, lWeight ),
  852. _cNode( 0 ),
  853. _paNode( 0 ),
  854. _cNodeAllocated( 0 )
  855. {
  856. ULONG cNodeAllocated = stm.GetULong();
  857. // Note: this is an arbitrary limit intended to protect against attack
  858. if ( cNodeAllocated > 65536 )
  859. THROW( CException( E_INVALIDARG ) );
  860. _cNodeAllocated = cNodeAllocated;
  861. //
  862. // Note: the destructor will be called if the constructor doesn't finish,
  863. // from ~CRestriction. So _paNode will be freed if AddChild fails.
  864. //
  865. _paNode = new CRestriction * [ _cNodeAllocated ];
  866. RtlZeroMemory( _paNode, _cNodeAllocated * sizeof( CRestriction * ) );
  867. for ( unsigned i = 0; i < _cNodeAllocated; i++ )
  868. AddChild( CRestriction::UnMarshall( stm ) );
  869. }
  870. void CNodeRestriction::AddChild( CRestriction * presChild, unsigned & pos )
  871. {
  872. if ( _cNode == _cNodeAllocated )
  873. Grow();
  874. _paNode[_cNode] = presChild;
  875. pos = _cNode;
  876. _cNode++;
  877. }
  878. CRestriction * CNodeRestriction::RemoveChild( unsigned pos )
  879. {
  880. if ( pos < _cNode )
  881. {
  882. CRestriction * prstRemoved = _paNode[pos];
  883. //
  884. // A memcpy would be nice, but is dangerous with overlapping
  885. // regions.
  886. //
  887. for ( pos++; pos < _cNode; pos++ )
  888. {
  889. _paNode[pos-1] = _paNode[pos];
  890. }
  891. _cNode--;
  892. return( prstRemoved );
  893. }
  894. else
  895. {
  896. return( 0 );
  897. }
  898. }
  899. void CNodeRestriction::Grow()
  900. {
  901. int count = (_cNodeAllocated != 0) ? _cNodeAllocated * 2 : 2;
  902. CRestriction ** paNew= new CRestriction * [ count ];
  903. RtlZeroMemory( paNew, count * sizeof( CRestriction * ) );
  904. memcpy( paNew, _paNode, _cNode * sizeof( CRestriction * ) );
  905. delete (BYTE *) _paNode;
  906. _paNode = paNew;
  907. _cNodeAllocated = count;
  908. }
  909. CNodeRestriction *CNodeRestriction::Clone() const
  910. {
  911. return new CNodeRestriction( *this );
  912. }
  913. CNotRestriction::CNotRestriction( CNotRestriction const & notRst )
  914. : CRestriction( RTNot, notRst.Weight() ),
  915. _pres( 0 )
  916. {
  917. CRestriction *pChildRst = notRst.GetChild();
  918. if ( pChildRst )
  919. _pres = pChildRst->Clone();
  920. }
  921. CNotRestriction::~CNotRestriction()
  922. {
  923. delete _pres;
  924. SetType( RTNone ); // Avoid recursion.
  925. }
  926. void CNotRestriction::Marshall( PSerStream & stm ) const
  927. {
  928. _pres->Marshall( stm );
  929. }
  930. CNotRestriction::CNotRestriction( LONG lWeight, PDeSerStream & stm )
  931. : CRestriction( RTNot, lWeight ),
  932. _pres( 0 )
  933. {
  934. _pres = CRestriction::UnMarshall( stm );
  935. }
  936. CNotRestriction *CNotRestriction::Clone() const
  937. {
  938. return new CNotRestriction( *this );
  939. }
  940. void CVectorRestriction::Marshall( PSerStream & stm ) const
  941. {
  942. CNodeRestriction::Marshall( stm );
  943. stm.PutULong( _ulRankMethod );
  944. }
  945. CVectorRestriction::CVectorRestriction( LONG lWeight, PDeSerStream & stm )
  946. : CNodeRestriction( RTVector, lWeight, stm ),
  947. _ulRankMethod( stm.GetULong() )
  948. {
  949. }
  950. CVectorRestriction *CVectorRestriction::Clone() const
  951. {
  952. return new CVectorRestriction( *this );
  953. }
  954. CContentRestriction::CContentRestriction( WCHAR const * pwcsPhrase,
  955. CFullPropSpec const & Property,
  956. ULONG ulGenerateMethod,
  957. LCID lcid )
  958. : CRestriction( RTContent, MAX_QUERY_RANK ),
  959. _pwcsPhrase( 0 ),
  960. _Property( Property ),
  961. _lcid( lcid ),
  962. _ulGenerateMethod( ulGenerateMethod )
  963. {
  964. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.prop,
  965. CContentRestriction, _Property ) );
  966. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.pwcsPhrase,
  967. CContentRestriction, _pwcsPhrase ) );
  968. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.lcid,
  969. CContentRestriction, _lcid ) );
  970. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.ulGenerateMethod,
  971. CContentRestriction, _ulGenerateMethod ) );
  972. if ( !_Property.IsValid() )
  973. THROW( CException( E_OUTOFMEMORY ) );
  974. SetPhrase( pwcsPhrase );
  975. }
  976. CContentRestriction::CContentRestriction( CContentRestriction const & contentRst )
  977. : CRestriction( RTContent, contentRst.Weight() ),
  978. _pwcsPhrase( 0 ),
  979. _Property( contentRst.GetProperty() ),
  980. _lcid( contentRst.GetLocale() ),
  981. _ulGenerateMethod( contentRst.GenerateMethod() )
  982. {
  983. if ( !_Property.IsValid() )
  984. THROW( CException( E_OUTOFMEMORY ) );
  985. SetPhrase( contentRst.GetPhrase() );
  986. }
  987. CContentRestriction::~CContentRestriction()
  988. {
  989. delete [] _pwcsPhrase;
  990. SetType( RTNone ); // Avoid recursion.
  991. }
  992. void CContentRestriction::Marshall( PSerStream & stm ) const
  993. {
  994. _Property.Marshall( stm );
  995. ULONG cc = wcslen( _pwcsPhrase );
  996. stm.PutULong( cc );
  997. stm.PutWChar( _pwcsPhrase, cc );
  998. stm.PutULong( _lcid );
  999. stm.PutULong( _ulGenerateMethod );
  1000. }
  1001. CContentRestriction::CContentRestriction( LONG lWeight, PDeSerStream & stm )
  1002. : CRestriction( RTContent, lWeight ),
  1003. _Property( stm )
  1004. {
  1005. // set to 0 in case allocation fails, since ~CRestriction will call
  1006. // ~CNatLanguageRestriction
  1007. _pwcsPhrase = 0;
  1008. if ( !_Property.IsValid() )
  1009. THROW( CException( E_OUTOFMEMORY ) );
  1010. XPtrST<WCHAR> xPhrase( UnMarshallWideStringNew( stm ) );
  1011. _lcid = stm.GetULong();
  1012. _ulGenerateMethod = stm.GetULong();
  1013. _pwcsPhrase = xPhrase.Acquire();
  1014. }
  1015. void CContentRestriction::SetPhrase( WCHAR const * pwcsPhrase )
  1016. {
  1017. delete [] _pwcsPhrase;
  1018. _pwcsPhrase = 0;
  1019. int len = ( wcslen( pwcsPhrase ) + 1 ) * sizeof( WCHAR );
  1020. _pwcsPhrase = new WCHAR[len];
  1021. memcpy( _pwcsPhrase, pwcsPhrase, len );
  1022. }
  1023. CContentRestriction *CContentRestriction::Clone() const
  1024. {
  1025. return new CContentRestriction( *this );
  1026. }
  1027. CNatLanguageRestriction::CNatLanguageRestriction( WCHAR const * pwcsPhrase,
  1028. CFullPropSpec const & Property,
  1029. LCID lcid )
  1030. : CRestriction( RTNatLanguage, MAX_QUERY_RANK ),
  1031. _pwcsPhrase( 0 ),
  1032. _Property( Property ),
  1033. _lcid( lcid )
  1034. {
  1035. if ( !_Property.IsValid() )
  1036. THROW( CException( E_OUTOFMEMORY ) );
  1037. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.prop,
  1038. CNatLanguageRestriction, _Property ) );
  1039. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.pwcsPhrase,
  1040. CNatLanguageRestriction, _pwcsPhrase ) );
  1041. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.lcid,
  1042. CNatLanguageRestriction, _lcid ) );
  1043. SetPhrase( pwcsPhrase );
  1044. }
  1045. CNatLanguageRestriction::~CNatLanguageRestriction()
  1046. {
  1047. delete [] _pwcsPhrase;
  1048. SetType( RTNone ); // Avoid recursion.
  1049. }
  1050. void CNatLanguageRestriction::Marshall( PSerStream & stm ) const
  1051. {
  1052. _Property.Marshall( stm );
  1053. ULONG cc = wcslen( _pwcsPhrase );
  1054. stm.PutULong( cc );
  1055. stm.PutWChar( _pwcsPhrase, cc );
  1056. stm.PutULong( _lcid );
  1057. }
  1058. CNatLanguageRestriction::CNatLanguageRestriction( LONG lWeight, PDeSerStream & stm )
  1059. : CRestriction( RTNatLanguage, lWeight ),
  1060. _Property( stm )
  1061. {
  1062. // set to 0 in case allocation fails, since ~CRestriction will call
  1063. // ~CNatLanguageRestriction
  1064. _pwcsPhrase = 0;
  1065. if ( !_Property.IsValid() )
  1066. THROW( CException( E_OUTOFMEMORY ) );
  1067. XPtrST<WCHAR> xPhrase( UnMarshallWideStringNew( stm ) );
  1068. _lcid = stm.GetULong();
  1069. _pwcsPhrase = xPhrase.Acquire();
  1070. }
  1071. void CNatLanguageRestriction::SetPhrase( WCHAR const * pwcsPhrase )
  1072. {
  1073. delete [] _pwcsPhrase;
  1074. _pwcsPhrase = 0;
  1075. int len = ( wcslen( pwcsPhrase ) + 1 ) * sizeof( WCHAR );
  1076. _pwcsPhrase = new WCHAR[len];
  1077. RtlCopyMemory( _pwcsPhrase, pwcsPhrase, len );
  1078. }
  1079. CPropertyRestriction::CPropertyRestriction()
  1080. : CRestriction( RTProperty, MAX_QUERY_RANK )
  1081. {
  1082. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.rel,
  1083. CPropertyRestriction, _relop ) );
  1084. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prop,
  1085. CPropertyRestriction, _Property ) );
  1086. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prval,
  1087. CPropertyRestriction, _prval ) );
  1088. }
  1089. CPropertyRestriction::CPropertyRestriction( ULONG relop,
  1090. CFullPropSpec const & Property,
  1091. CStorageVariant const & prval )
  1092. : CRestriction( RTProperty, MAX_QUERY_RANK ),
  1093. _relop( relop ),
  1094. _Property( Property ),
  1095. _prval( prval )
  1096. {
  1097. if ( !_Property.IsValid() ||
  1098. !_prval.IsValid() )
  1099. THROW( CException( E_OUTOFMEMORY ) );
  1100. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.rel,
  1101. CPropertyRestriction, _relop ) );
  1102. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prop,
  1103. CPropertyRestriction, _Property ) );
  1104. Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prval,
  1105. CPropertyRestriction, _prval ) );
  1106. }
  1107. CPropertyRestriction::~CPropertyRestriction()
  1108. {
  1109. SetType( RTNone ); // Avoid recursion.
  1110. }
  1111. void CPropertyRestriction::Marshall( PSerStream & stm ) const
  1112. {
  1113. stm.PutULong( _relop );
  1114. _Property.Marshall( stm );
  1115. _prval.Marshall( stm );
  1116. }
  1117. CPropertyRestriction::CPropertyRestriction( LONG lWeight, PDeSerStream & stm )
  1118. : CRestriction( RTProperty, lWeight ),
  1119. _relop( stm.GetULong() ),
  1120. _Property( stm ),
  1121. _prval( stm )
  1122. {
  1123. if ( !_Property.IsValid() ||
  1124. !_prval.IsValid() )
  1125. THROW( CException( E_OUTOFMEMORY ) );
  1126. }
  1127. void CPropertyRestriction::SetValue( WCHAR * pwcsValue )
  1128. {
  1129. _prval = pwcsValue;
  1130. }
  1131. void CPropertyRestriction::SetValue( BLOB & bValue )
  1132. {
  1133. _prval = bValue;
  1134. }
  1135. void CPropertyRestriction::SetValue( GUID * pguidValue )
  1136. {
  1137. _prval = pguidValue;
  1138. }
  1139. CSortKey::CSortKey( CFullPropSpec const & ps, ULONG dwOrder )
  1140. : _property( ps ),
  1141. _dwOrder( dwOrder )
  1142. {
  1143. if ( !_property.IsValid() )
  1144. THROW( CException( E_OUTOFMEMORY ) );
  1145. }
  1146. CSortKey::CSortKey( CFullPropSpec const & ps, ULONG dwOrder, LCID locale )
  1147. : _property( ps ),
  1148. _dwOrder( dwOrder ),
  1149. _locale ( locale )
  1150. {
  1151. if ( !_property.IsValid() )
  1152. THROW( CException( E_OUTOFMEMORY ) );
  1153. }