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.

1333 lines
26 KiB

  1. #ifndef __ARRAY_CPP
  2. #define __ARRAY_CPP
  3. /*
  4. * Class:
  5. *
  6. * WmiAllocator
  7. *
  8. * Description:
  9. *
  10. * Provides abstraction above heap allocation functions
  11. *
  12. * Version:
  13. *
  14. * Initial
  15. *
  16. * Last Changed:
  17. *
  18. * See Source Depot for change history
  19. *
  20. */
  21. /******************************************************************************
  22. *
  23. * Name:
  24. *
  25. *
  26. * Description:
  27. *
  28. *
  29. *****************************************************************************/
  30. #define ELEMENT_DIR_BIT_SIZE 12
  31. #define INNER_DIR_BIT_SIZE 10
  32. #define OUTER_DIR_BIT_SIZE 10
  33. #define ELEMENT_BIT_POS 0
  34. #define INNER_DIR_BIT_POS ELEMENT_DIR_BIT_SIZE
  35. #define OUTER_DIR_BIT_POS (INNER_DIR_BIT_SIZE + ELEMENT_DIR_BIT_SIZE)
  36. #define ELEMENT_DIR_SIZE 1 << ELEMENT_DIR_BIT_SIZE
  37. #define INNER_DIR_SIZE 1 << ( INNER_DIR_BIT_SIZE + ELEMENT_DIR_BIT_SIZE )
  38. #define OUTER_DIR_SIZE 1 << ( OUTER_DIR_BIT_SIZE + INNER_DIR_BIT_SIZE + ELEMENT_DIR_BIT_SIZE )
  39. #define ELEMENT_DIR_MASK 0xFFFFFFFF >> ( OUTER_DIR_BIT_SIZE + INNER_DIR_BIT_SIZE )
  40. #define OUTER_DIR_MASK 0xFFFFFFFF << ( INNER_DIR_BIT_SIZE + ELEMENT_DIR_BIT_SIZE )
  41. #define INNER_DIR_MASK OUTER_DIR_MASK & ELEMENT_DIR_MASK
  42. #define INNER_ELEMENT_DIR_MASK 0xFFFFFFFF >> OUTER_DIR_BIT_SIZE
  43. #define INITIAL_OUTER_SIZE 1
  44. #define INITIAL_INNER_SIZE 1
  45. /******************************************************************************
  46. *
  47. * Name:
  48. *
  49. *
  50. * Description:
  51. *
  52. *
  53. *****************************************************************************/
  54. template <class WmiElement>
  55. WmiArray <WmiElement> :: WmiArray (
  56. WmiAllocator &a_Allocator
  57. ) : m_Allocator ( a_Allocator ) ,
  58. m_Size ( 0 )
  59. {
  60. }
  61. /******************************************************************************
  62. *
  63. * Name:
  64. *
  65. *
  66. * Description:
  67. *
  68. *
  69. *****************************************************************************/
  70. template <class WmiElement>
  71. WmiArray <WmiElement> :: ~WmiArray ()
  72. {
  73. WmiStatusCode t_StatusCode = UnInitialize () ;
  74. }
  75. /******************************************************************************
  76. *
  77. * Name:
  78. *
  79. *
  80. * Description:
  81. *
  82. *
  83. *****************************************************************************/
  84. template <class WmiElement>
  85. WmiStatusCode WmiArray <WmiElement> :: Initialize ( ULONG a_Size )
  86. {
  87. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  88. if ( a_Size )
  89. {
  90. m_Size = a_Size ;
  91. t_StatusCode = Initialize_OuterDir ( m_Size ) ;
  92. }
  93. return t_StatusCode ;
  94. }
  95. /******************************************************************************
  96. *
  97. * Name:
  98. *
  99. *
  100. * Description:
  101. *
  102. *
  103. *****************************************************************************/
  104. template <class WmiElement>
  105. WmiStatusCode WmiArray <WmiElement> :: UnInitialize ()
  106. {
  107. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  108. if ( m_Size )
  109. {
  110. t_StatusCode = UnInitialize_OuterDir ( m_Size ) ;
  111. m_Size = 0 ;
  112. }
  113. return t_StatusCode ;
  114. }
  115. /******************************************************************************
  116. *
  117. * Name:
  118. *
  119. *
  120. * Description:
  121. *
  122. *
  123. *****************************************************************************/
  124. template <class WmiElement>
  125. WmiStatusCode WmiArray <WmiElement> :: Grow ( ULONG a_Size )
  126. {
  127. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  128. if ( m_Size )
  129. {
  130. if ( m_Size < a_Size )
  131. {
  132. ULONG t_Size = m_Size ;
  133. m_Size = a_Size ;
  134. t_StatusCode = Grow_OuterDir ( t_Size , a_Size ) ;
  135. }
  136. }
  137. return t_StatusCode ;
  138. }
  139. /******************************************************************************
  140. *
  141. * Name:
  142. *
  143. *
  144. * Description:
  145. *
  146. *
  147. *****************************************************************************/
  148. template <class WmiElement>
  149. WmiStatusCode WmiArray <WmiElement> :: Shrink ( ULONG a_Size )
  150. {
  151. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  152. if ( m_Size )
  153. {
  154. if ( m_Size > a_Size )
  155. {
  156. t_StatusCode = Shrink_OuterDir ( m_Size , a_Size ) ;
  157. m_Size = a_Size ;
  158. }
  159. }
  160. return t_StatusCode ;
  161. }
  162. /******************************************************************************
  163. *
  164. * Name:
  165. *
  166. *
  167. * Description:
  168. *
  169. *
  170. *****************************************************************************/
  171. template <class WmiElement>
  172. WmiStatusCode WmiArray <WmiElement> :: Set (const WmiElement &a_Element , ULONG a_ElementIndex )
  173. {
  174. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  175. if ( m_Size && ( a_ElementIndex < m_Size ) )
  176. {
  177. ULONG t_OuterIndex = ( a_ElementIndex >> OUTER_DIR_BIT_POS ) ;
  178. ULONG t_InnerIndex = ( ( a_ElementIndex & INNER_ELEMENT_DIR_MASK ) >> INNER_DIR_BIT_POS ) ;
  179. ULONG t_ElementIndex = a_ElementIndex & ELEMENT_DIR_MASK ;
  180. WmiInnerDir *t_InnerDir = & ( m_OuterDir.m_InnerDir [ t_OuterIndex ] ) ;
  181. WmiElementDir *t_ElementDir = & ( t_InnerDir->m_ElementDir [ t_InnerIndex ] ) ;
  182. WmiElement *t_Element = & ( t_ElementDir->m_Block [ t_ElementIndex ] ) ;
  183. try
  184. {
  185. *t_Element = a_Element ;
  186. }
  187. catch ( Wmi_Heap_Exception &a_Exception )
  188. {
  189. return e_StatusCode_OutOfMemory ;
  190. }
  191. catch ( ... )
  192. {
  193. return e_StatusCode_Unknown ;
  194. }
  195. }
  196. else
  197. {
  198. t_StatusCode = e_StatusCode_OutOfBounds ;
  199. }
  200. return t_StatusCode ;
  201. }
  202. /******************************************************************************
  203. *
  204. * Name:
  205. *
  206. *
  207. * Description:
  208. *
  209. *
  210. *****************************************************************************/
  211. template <class WmiElement>
  212. WmiStatusCode WmiArray <WmiElement> :: Get (
  213. WmiElement &a_Element ,
  214. ULONG a_ElementIndex
  215. )
  216. {
  217. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  218. if ( m_Size && ( a_ElementIndex < m_Size ) )
  219. {
  220. ULONG t_OuterIndex = ( a_ElementIndex >> OUTER_DIR_BIT_POS ) ;
  221. ULONG t_InnerIndex = ( ( a_ElementIndex & INNER_ELEMENT_DIR_MASK ) >> INNER_DIR_BIT_POS ) ;
  222. ULONG t_ElementIndex = a_ElementIndex & ELEMENT_DIR_MASK ;
  223. WmiInnerDir *t_InnerDir = & ( m_OuterDir.m_InnerDir [ t_OuterIndex ] ) ;
  224. WmiElementDir *t_ElementDir = & ( t_InnerDir->m_ElementDir [ t_InnerIndex ] ) ;
  225. WmiElement *t_Element = & ( t_ElementDir->m_Block [ t_ElementIndex ] ) ;
  226. try
  227. {
  228. a_Element = *t_Element ;
  229. }
  230. catch ( Wmi_Heap_Exception &a_Exception )
  231. {
  232. return e_StatusCode_OutOfMemory ;
  233. }
  234. catch ( ... )
  235. {
  236. return e_StatusCode_Unknown ;
  237. }
  238. }
  239. else
  240. {
  241. t_StatusCode = e_StatusCode_OutOfBounds ;
  242. }
  243. return t_StatusCode ;
  244. }
  245. /******************************************************************************
  246. *
  247. * Name:
  248. *
  249. *
  250. * Description:
  251. *
  252. *
  253. *****************************************************************************/
  254. template <class WmiElement>
  255. WmiStatusCode WmiArray <WmiElement> :: Get (
  256. WmiElement *&a_Element ,
  257. ULONG a_ElementIndex
  258. )
  259. {
  260. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  261. if ( m_Size && ( a_ElementIndex < m_Size ) )
  262. {
  263. ULONG t_OuterIndex = ( a_ElementIndex >> OUTER_DIR_BIT_POS ) ;
  264. ULONG t_InnerIndex = ( ( a_ElementIndex & INNER_ELEMENT_DIR_MASK ) >> INNER_DIR_BIT_POS ) ;
  265. ULONG t_ElementIndex = a_ElementIndex & ELEMENT_DIR_MASK ;
  266. WmiInnerDir *t_InnerDir = & ( m_OuterDir.m_InnerDir [ t_OuterIndex ] ) ;
  267. WmiElementDir *t_ElementDir = & ( t_InnerDir->m_ElementDir [ t_InnerIndex ] ) ;
  268. WmiElement *t_Element = & ( t_ElementDir->m_Block [ t_ElementIndex ] ) ;
  269. a_Element = t_Element ;
  270. }
  271. else
  272. {
  273. t_StatusCode = e_StatusCode_OutOfBounds ;
  274. }
  275. return t_StatusCode ;
  276. }
  277. /******************************************************************************
  278. *
  279. * Name:
  280. *
  281. *
  282. * Description:
  283. *
  284. *
  285. *****************************************************************************/
  286. template <class WmiElement>
  287. WmiStatusCode WmiArray <WmiElement> :: Get (
  288. Iterator &a_Iterator ,
  289. ULONG a_ElementIndex
  290. )
  291. {
  292. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  293. a_Iterator = Iterator ( this , a_ElementIndex ) ;
  294. return t_StatusCode ;
  295. }
  296. /******************************************************************************
  297. *
  298. * Name:
  299. *
  300. *
  301. * Description:
  302. *
  303. *
  304. *****************************************************************************/
  305. template <class WmiElement>
  306. WmiStatusCode WmiArray <WmiElement> :: Initialize_ElementDir (
  307. ULONG a_Size ,
  308. WmiElementDir *a_ElementDir
  309. )
  310. {
  311. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  312. ULONG t_Size = a_Size ;
  313. if ( t_Size )
  314. {
  315. t_StatusCode = m_Allocator.New (
  316. ( void ** ) & a_ElementDir->m_Block ,
  317. sizeof ( WmiElement ) * a_Size
  318. ) ;
  319. if ( t_StatusCode == e_StatusCode_Success )
  320. {
  321. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  322. {
  323. WmiElement *t_Element = & ( a_ElementDir->m_Block ) [ t_Index ] ;
  324. :: new ( ( void * ) t_Element ) WmiElement () ;
  325. }
  326. }
  327. else
  328. {
  329. m_Size = m_Size - a_Size ;
  330. }
  331. }
  332. else
  333. {
  334. t_StatusCode = e_StatusCode_Unknown ;
  335. }
  336. return t_StatusCode ;
  337. }
  338. /******************************************************************************
  339. *
  340. * Name:
  341. *
  342. *
  343. * Description:
  344. *
  345. *
  346. *****************************************************************************/
  347. template <class WmiElement>
  348. WmiStatusCode WmiArray <WmiElement> :: Initialize_InnerDir (
  349. ULONG a_Size ,
  350. WmiInnerDir *a_InnerDir
  351. )
  352. {
  353. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  354. ULONG t_Size = ( a_Size >> INNER_DIR_BIT_POS ) + 1 ;
  355. if ( t_Size )
  356. {
  357. t_StatusCode = m_Allocator.New (
  358. ( void ** ) & a_InnerDir->m_ElementDir ,
  359. sizeof ( WmiElementDir ) * t_Size
  360. ) ;
  361. if ( t_StatusCode == e_StatusCode_Success )
  362. {
  363. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  364. {
  365. if ( t_Index == t_Size - 1 )
  366. {
  367. t_StatusCode = Initialize_ElementDir (
  368. a_Size & ELEMENT_DIR_MASK ,
  369. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  370. ) ;
  371. }
  372. else
  373. {
  374. t_StatusCode = Initialize_ElementDir (
  375. ELEMENT_DIR_SIZE ,
  376. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  377. ) ;
  378. }
  379. if ( t_StatusCode != e_StatusCode_Success )
  380. {
  381. if ( t_Index != t_Size - 1 )
  382. {
  383. ULONG t_Remainder = t_Size - t_Index - 1 ;
  384. if ( t_Remainder )
  385. {
  386. m_Size = m_Size - ( ( t_Remainder - 1 ) * ELEMENT_DIR_SIZE ) ;
  387. }
  388. m_Size = m_Size - ( a_Size & ELEMENT_DIR_MASK ) ;
  389. }
  390. break ;
  391. }
  392. }
  393. }
  394. else
  395. {
  396. m_Size = m_Size - t_Size ;
  397. }
  398. }
  399. else
  400. {
  401. t_StatusCode = e_StatusCode_Unknown ;
  402. }
  403. return t_StatusCode ;
  404. }
  405. /******************************************************************************
  406. *
  407. * Name:
  408. *
  409. *
  410. * Description:
  411. *
  412. *
  413. *****************************************************************************/
  414. template <class WmiElement>
  415. WmiStatusCode WmiArray <WmiElement> :: Initialize_OuterDir ( ULONG a_Size )
  416. {
  417. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  418. ULONG t_Size = ( a_Size >> OUTER_DIR_BIT_POS ) + 1 ;
  419. t_StatusCode = m_Allocator.New (
  420. ( void ** ) & m_OuterDir.m_InnerDir ,
  421. sizeof ( WmiInnerDir ) * t_Size
  422. ) ;
  423. if ( t_StatusCode == e_StatusCode_Success )
  424. {
  425. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  426. {
  427. if ( t_Index == t_Size - 1 )
  428. {
  429. t_StatusCode = Initialize_InnerDir (
  430. a_Size & INNER_ELEMENT_DIR_MASK ,
  431. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  432. ) ;
  433. }
  434. else
  435. {
  436. t_StatusCode = Initialize_InnerDir (
  437. INNER_DIR_SIZE ,
  438. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  439. ) ;
  440. }
  441. if ( t_StatusCode != e_StatusCode_Success )
  442. {
  443. if ( t_Index != t_Size - 1 )
  444. {
  445. ULONG t_Remainder = t_Size - t_Index - 1 ;
  446. if ( t_Remainder )
  447. {
  448. m_Size = m_Size - ( ( t_Remainder - 1 ) * INNER_DIR_SIZE ) ;
  449. }
  450. m_Size = m_Size - ( a_Size & INNER_ELEMENT_DIR_MASK ) ;
  451. }
  452. break ;
  453. }
  454. }
  455. }
  456. else
  457. {
  458. m_Size = m_Size - t_Size ;
  459. }
  460. return t_StatusCode ;
  461. }
  462. /******************************************************************************
  463. *
  464. * Name:
  465. *
  466. *
  467. * Description:
  468. *
  469. *
  470. *****************************************************************************/
  471. template <class WmiElement>
  472. WmiStatusCode WmiArray <WmiElement> :: Grow_ElementDir (
  473. ULONG a_Size ,
  474. ULONG a_NewSize ,
  475. WmiElementDir *a_ElementDir
  476. )
  477. {
  478. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  479. if ( a_NewSize )
  480. {
  481. if ( a_Size )
  482. {
  483. WmiElement *t_Tmp = NULL ;
  484. t_StatusCode = m_Allocator.ReAlloc (
  485. ( void * ) a_ElementDir->m_Block ,
  486. ( void ** ) & t_Tmp ,
  487. sizeof ( WmiElement ) * a_NewSize
  488. ) ;
  489. if ( t_StatusCode == e_StatusCode_Success )
  490. {
  491. a_ElementDir->m_Block = t_Tmp ;
  492. }
  493. }
  494. else
  495. {
  496. t_StatusCode = m_Allocator.New (
  497. ( void ** ) & a_ElementDir->m_Block ,
  498. sizeof ( WmiElement ) * a_NewSize
  499. ) ;
  500. }
  501. if ( t_StatusCode == e_StatusCode_Success )
  502. {
  503. for ( ULONG t_Index = a_Size ? a_Size : 0 ; t_Index < a_NewSize ; t_Index ++ )
  504. {
  505. WmiElement *t_Element = & ( a_ElementDir->m_Block ) [ t_Index ] ;
  506. :: new ( ( void * ) t_Element ) WmiElement () ;
  507. }
  508. }
  509. else
  510. {
  511. m_Size = m_Size - ( a_NewSize - a_Size ) ;
  512. }
  513. }
  514. else
  515. {
  516. t_StatusCode = e_StatusCode_Unknown ;
  517. }
  518. return t_StatusCode ;
  519. }
  520. /******************************************************************************
  521. *
  522. * Name:
  523. *
  524. *
  525. * Description:
  526. *
  527. *
  528. *****************************************************************************/
  529. template <class WmiElement>
  530. WmiStatusCode WmiArray <WmiElement> :: Grow_InnerDir (
  531. ULONG a_Size ,
  532. ULONG a_NewSize ,
  533. WmiInnerDir *a_InnerDir
  534. )
  535. {
  536. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  537. ULONG t_OldSize = ( a_Size >> INNER_DIR_BIT_POS ) + 1 ;
  538. ULONG t_NewSize = ( a_NewSize >> INNER_DIR_BIT_POS ) + 1 ;
  539. if ( t_OldSize )
  540. {
  541. if ( t_OldSize != t_NewSize )
  542. {
  543. WmiElementDir *t_Tmp = NULL ;
  544. t_StatusCode = m_Allocator.ReAlloc (
  545. ( void * ) a_InnerDir->m_ElementDir ,
  546. ( void ** ) & t_Tmp ,
  547. sizeof ( WmiElementDir ) * t_NewSize
  548. ) ;
  549. if ( t_StatusCode == e_StatusCode_Success )
  550. {
  551. a_InnerDir->m_ElementDir = t_Tmp ;
  552. }
  553. }
  554. }
  555. else
  556. {
  557. if ( t_NewSize )
  558. {
  559. t_StatusCode = m_Allocator.New (
  560. ( void ** ) & a_InnerDir->m_ElementDir ,
  561. sizeof ( WmiElementDir ) * t_NewSize
  562. ) ;
  563. }
  564. else
  565. {
  566. t_StatusCode = e_StatusCode_Unknown ;
  567. }
  568. }
  569. if ( t_StatusCode == e_StatusCode_Success )
  570. {
  571. for ( ULONG t_Index = t_OldSize ? t_OldSize - 1 : 0 ; t_Index < t_NewSize ; t_Index ++ )
  572. {
  573. if ( t_Index == t_OldSize - 1 )
  574. {
  575. if ( t_Index == t_NewSize - 1 )
  576. {
  577. t_StatusCode = Grow_ElementDir (
  578. a_Size & ELEMENT_DIR_MASK ,
  579. a_NewSize & ELEMENT_DIR_MASK ,
  580. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  581. ) ;
  582. }
  583. else
  584. {
  585. t_StatusCode = Grow_ElementDir (
  586. a_Size & ELEMENT_DIR_MASK ,
  587. ELEMENT_DIR_SIZE ,
  588. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  589. ) ;
  590. }
  591. }
  592. else
  593. {
  594. if ( t_Index == t_NewSize - 1 )
  595. {
  596. t_StatusCode = Grow_ElementDir (
  597. a_Size & ELEMENT_DIR_MASK ,
  598. a_NewSize & ELEMENT_DIR_MASK ,
  599. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  600. ) ;
  601. }
  602. else
  603. {
  604. t_StatusCode = Grow_ElementDir (
  605. 0 ,
  606. ELEMENT_DIR_SIZE ,
  607. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  608. ) ;
  609. }
  610. }
  611. if ( t_StatusCode != e_StatusCode_Success )
  612. {
  613. if ( t_Index != t_NewSize - 1 )
  614. {
  615. ULONG t_Remainder = t_NewSize - t_Index - 1 ;
  616. if ( t_Remainder )
  617. {
  618. m_Size = m_Size - ( ( t_Remainder - 1 ) * ELEMENT_DIR_SIZE ) ;
  619. }
  620. m_Size = m_Size - ( a_NewSize & ELEMENT_DIR_MASK ) ;
  621. }
  622. break ;
  623. }
  624. }
  625. }
  626. else
  627. {
  628. m_Size = m_Size - ( a_NewSize - a_Size ) ;
  629. }
  630. return t_StatusCode ;
  631. }
  632. /******************************************************************************
  633. *
  634. * Name:
  635. *
  636. *
  637. * Description:
  638. *
  639. *
  640. *****************************************************************************/
  641. template <class WmiElement>
  642. WmiStatusCode WmiArray <WmiElement> :: Grow_OuterDir ( ULONG a_Size , ULONG a_NewSize )
  643. {
  644. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  645. ULONG t_OldSize = ( a_Size >> OUTER_DIR_BIT_POS ) + 1 ;
  646. ULONG t_NewSize = ( a_NewSize >> OUTER_DIR_BIT_POS ) + 1 ;
  647. if ( t_OldSize )
  648. {
  649. if ( t_OldSize != t_NewSize )
  650. {
  651. WmiInnerDir *t_Tmp = NULL ;
  652. t_StatusCode = m_Allocator.ReAlloc (
  653. ( void * ) m_OuterDir.m_InnerDir ,
  654. ( void ** ) & t_Tmp ,
  655. sizeof ( WmiInnerDir ) * t_NewSize
  656. ) ;
  657. if ( t_StatusCode == e_StatusCode_Success )
  658. {
  659. m_OuterDir.m_InnerDir = t_Tmp ;
  660. }
  661. }
  662. }
  663. else
  664. {
  665. if ( t_NewSize )
  666. {
  667. t_StatusCode = m_Allocator.New (
  668. ( void ** ) & m_OuterDir.m_InnerDir ,
  669. sizeof ( WmiInnerDir ) * t_NewSize
  670. ) ;
  671. }
  672. else
  673. {
  674. t_StatusCode = e_StatusCode_Unknown ;
  675. }
  676. }
  677. if ( t_StatusCode == e_StatusCode_Success )
  678. {
  679. for ( ULONG t_Index = t_OldSize ? t_OldSize - 1 : 0 ; t_Index < t_NewSize ; t_Index ++ )
  680. {
  681. if ( t_Index == t_OldSize - 1 )
  682. {
  683. if ( t_Index == t_NewSize - 1 )
  684. {
  685. t_StatusCode = Grow_InnerDir (
  686. a_Size & INNER_ELEMENT_DIR_MASK ,
  687. a_NewSize & INNER_ELEMENT_DIR_MASK ,
  688. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  689. ) ;
  690. }
  691. else
  692. {
  693. t_StatusCode = Grow_InnerDir (
  694. a_Size & INNER_ELEMENT_DIR_MASK ,
  695. INNER_DIR_SIZE ,
  696. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  697. ) ;
  698. }
  699. }
  700. else
  701. {
  702. if ( t_Index == t_NewSize - 1 )
  703. {
  704. t_StatusCode = Grow_InnerDir (
  705. 0 ,
  706. a_NewSize & INNER_ELEMENT_DIR_MASK ,
  707. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  708. ) ;
  709. }
  710. else
  711. {
  712. t_StatusCode = Grow_InnerDir (
  713. 0 ,
  714. INNER_DIR_SIZE ,
  715. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  716. ) ;
  717. }
  718. }
  719. if ( t_StatusCode != e_StatusCode_Success )
  720. {
  721. if ( t_Index != t_NewSize - 1 )
  722. {
  723. ULONG t_Remainder = t_NewSize - t_Index - 1 ;
  724. if ( t_Remainder )
  725. {
  726. m_Size = m_Size - ( ( t_Remainder - 1 ) * INNER_DIR_SIZE ) ;
  727. }
  728. m_Size = m_Size - ( a_NewSize & INNER_ELEMENT_DIR_MASK ) ;
  729. }
  730. break ;
  731. }
  732. }
  733. }
  734. else
  735. {
  736. m_Size = m_Size - ( a_NewSize - a_Size ) ;
  737. }
  738. return t_StatusCode ;
  739. }
  740. /******************************************************************************
  741. *
  742. * Name:
  743. *
  744. *
  745. * Description:
  746. *
  747. *
  748. *****************************************************************************/
  749. template <class WmiElement>
  750. WmiStatusCode WmiArray <WmiElement> :: UnInitialize_ElementDir (
  751. ULONG a_Size ,
  752. WmiElementDir *a_ElementDir
  753. )
  754. {
  755. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  756. ULONG t_Size = a_Size ;
  757. if ( t_Size )
  758. {
  759. for ( ULONG t_Index = 0 ; t_Index < a_Size ; t_Index ++ )
  760. {
  761. WmiElement *t_Element = & ( a_ElementDir->m_Block ) [ t_Index ] ;
  762. t_Element->WmiElement :: ~WmiElement () ;
  763. }
  764. t_StatusCode = m_Allocator.Delete (
  765. ( void * ) a_ElementDir->m_Block
  766. ) ;
  767. }
  768. else
  769. {
  770. t_StatusCode = e_StatusCode_Unknown ;
  771. }
  772. return t_StatusCode ;
  773. }
  774. /******************************************************************************
  775. *
  776. * Name:
  777. *
  778. *
  779. * Description:
  780. *
  781. *
  782. *****************************************************************************/
  783. template <class WmiElement>
  784. WmiStatusCode WmiArray <WmiElement> :: UnInitialize_InnerDir (
  785. ULONG a_Size ,
  786. WmiInnerDir *a_InnerDir
  787. )
  788. {
  789. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  790. ULONG t_Size = ( a_Size >> INNER_DIR_BIT_POS ) + 1 ;
  791. if ( t_Size )
  792. {
  793. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  794. {
  795. if ( t_Index == t_Size - 1 )
  796. {
  797. t_StatusCode = UnInitialize_ElementDir (
  798. a_Size & ELEMENT_DIR_MASK ,
  799. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  800. ) ;
  801. }
  802. else
  803. {
  804. t_StatusCode = UnInitialize_ElementDir (
  805. ELEMENT_DIR_SIZE ,
  806. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  807. ) ;
  808. }
  809. }
  810. t_StatusCode = m_Allocator.Delete (
  811. ( void * ) a_InnerDir->m_ElementDir
  812. ) ;
  813. }
  814. else
  815. {
  816. t_StatusCode = e_StatusCode_Unknown ;
  817. }
  818. return t_StatusCode ;
  819. }
  820. /******************************************************************************
  821. *
  822. * Name:
  823. *
  824. *
  825. * Description:
  826. *
  827. *
  828. *****************************************************************************/
  829. template <class WmiElement>
  830. WmiStatusCode WmiArray <WmiElement> :: UnInitialize_OuterDir ( ULONG a_Size )
  831. {
  832. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  833. ULONG t_Size = ( a_Size >> OUTER_DIR_BIT_POS ) + 1 ;
  834. if ( t_Size )
  835. {
  836. for ( ULONG t_Index = 0 ; t_Index < t_Size ; t_Index ++ )
  837. {
  838. if ( t_Index == t_Size - 1 )
  839. {
  840. t_StatusCode = UnInitialize_InnerDir (
  841. a_Size & INNER_ELEMENT_DIR_MASK ,
  842. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  843. ) ;
  844. }
  845. else
  846. {
  847. t_StatusCode = UnInitialize_InnerDir (
  848. INNER_DIR_SIZE ,
  849. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  850. ) ;
  851. }
  852. }
  853. t_StatusCode = m_Allocator.Delete (
  854. ( void * ) m_OuterDir.m_InnerDir
  855. ) ;
  856. }
  857. return t_StatusCode ;
  858. }
  859. /******************************************************************************
  860. *
  861. * Name:
  862. *
  863. *
  864. * Description:
  865. *
  866. *
  867. *****************************************************************************/
  868. template <class WmiElement>
  869. WmiStatusCode WmiArray <WmiElement> :: Shrink_ElementDir (
  870. ULONG a_Size ,
  871. ULONG a_NewSize ,
  872. WmiElementDir *a_ElementDir
  873. )
  874. {
  875. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  876. if ( a_Size )
  877. {
  878. for ( ULONG t_Index = a_NewSize ; t_Index < a_Size ; t_Index ++ )
  879. {
  880. WmiElement *t_Element = & ( a_ElementDir->m_Block ) [ t_Index ] ;
  881. ( t_Element )->WmiElement :: ~WmiElement () ;
  882. }
  883. if ( a_NewSize )
  884. {
  885. WmiElement *t_Tmp = NULL ;
  886. t_StatusCode = m_Allocator.ReAlloc (
  887. ( void * ) a_ElementDir->m_Block ,
  888. ( void ** ) & t_Tmp ,
  889. sizeof ( WmiElement ) * a_Size
  890. ) ;
  891. if ( t_StatusCode == e_StatusCode_Success )
  892. {
  893. a_ElementDir->m_Block = t_Tmp ;
  894. }
  895. }
  896. else
  897. {
  898. t_StatusCode = m_Allocator.Delete (
  899. ( void ** ) a_ElementDir->m_Block
  900. ) ;
  901. }
  902. if ( t_StatusCode == e_StatusCode_Success )
  903. {
  904. }
  905. else
  906. {
  907. m_Size = m_Size - ( a_NewSize - a_Size ) ;
  908. }
  909. }
  910. else
  911. {
  912. t_StatusCode = e_StatusCode_Unknown ;
  913. }
  914. return t_StatusCode ;
  915. }
  916. /******************************************************************************
  917. *
  918. * Name:
  919. *
  920. *
  921. * Description:
  922. *
  923. *
  924. *****************************************************************************/
  925. template <class WmiElement>
  926. WmiStatusCode WmiArray <WmiElement> :: Shrink_InnerDir (
  927. ULONG a_Size ,
  928. ULONG a_NewSize ,
  929. WmiInnerDir *a_InnerDir
  930. )
  931. {
  932. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  933. ULONG t_OldSize = ( a_Size >> INNER_DIR_BIT_POS ) + 1 ;
  934. ULONG t_NewSize = ( a_NewSize >> INNER_DIR_BIT_POS ) + 1 ;
  935. for ( ULONG t_Index = t_NewSize - 1 ; t_Index < t_OldSize ; t_Index ++ )
  936. {
  937. if ( t_Index == t_OldSize - 1 )
  938. {
  939. if ( t_Index == t_NewSize - 1 )
  940. {
  941. t_StatusCode = Shrink_ElementDir (
  942. a_Size & ELEMENT_DIR_MASK ,
  943. a_NewSize & ELEMENT_DIR_MASK ,
  944. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  945. ) ;
  946. }
  947. else
  948. {
  949. t_StatusCode = Shrink_ElementDir (
  950. a_Size & ELEMENT_DIR_MASK ,
  951. ELEMENT_DIR_SIZE ,
  952. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  953. ) ;
  954. }
  955. }
  956. else
  957. {
  958. if ( t_Index == t_NewSize - 1 )
  959. {
  960. t_StatusCode = Shrink_ElementDir (
  961. a_Size & ELEMENT_DIR_MASK ,
  962. a_NewSize & ELEMENT_DIR_MASK ,
  963. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  964. ) ;
  965. }
  966. else
  967. {
  968. t_StatusCode = Shrink_ElementDir (
  969. ELEMENT_DIR_SIZE ,
  970. 0 ,
  971. & ( a_InnerDir->m_ElementDir [ t_Index ] )
  972. ) ;
  973. }
  974. }
  975. if ( t_StatusCode != e_StatusCode_Success )
  976. {
  977. if ( t_Index != t_NewSize - 1 )
  978. {
  979. ULONG t_Remainder = t_NewSize - t_Index - 1 ;
  980. if ( t_Remainder )
  981. {
  982. m_Size = m_Size - ( ( t_Remainder - 1 ) * ELEMENT_DIR_SIZE ) ;
  983. }
  984. m_Size = m_Size - ( a_NewSize & ELEMENT_DIR_MASK ) ;
  985. }
  986. break ;
  987. }
  988. }
  989. if ( t_OldSize )
  990. {
  991. if ( t_OldSize != t_NewSize )
  992. {
  993. WmiElementDir *t_Tmp = NULL ;
  994. t_StatusCode = m_Allocator.ReAlloc (
  995. ( void * ) a_InnerDir->m_ElementDir ,
  996. ( void ** ) & t_Tmp ,
  997. sizeof ( WmiElementDir ) * t_NewSize
  998. ) ;
  999. if ( t_StatusCode == e_StatusCode_Success )
  1000. {
  1001. a_InnerDir->m_ElementDir = t_Tmp ;
  1002. }
  1003. }
  1004. }
  1005. else
  1006. {
  1007. if ( t_NewSize )
  1008. {
  1009. t_StatusCode = m_Allocator.Delete (
  1010. ( void ** ) & a_InnerDir->m_ElementDir
  1011. ) ;
  1012. }
  1013. else
  1014. {
  1015. t_StatusCode = e_StatusCode_Unknown ;
  1016. }
  1017. }
  1018. return t_StatusCode ;
  1019. }
  1020. /******************************************************************************
  1021. *
  1022. * Name:
  1023. *
  1024. *
  1025. * Description:
  1026. *
  1027. *
  1028. *****************************************************************************/
  1029. template <class WmiElement>
  1030. WmiStatusCode WmiArray <WmiElement> :: Shrink_OuterDir ( ULONG a_Size , ULONG a_NewSize )
  1031. {
  1032. WmiStatusCode t_StatusCode = e_StatusCode_Success ;
  1033. ULONG t_OldSize = ( a_Size >> OUTER_DIR_BIT_POS ) + 1 ;
  1034. ULONG t_NewSize = ( a_NewSize >> OUTER_DIR_BIT_POS ) + 1 ;
  1035. for ( ULONG t_Index = t_NewSize - 1 ; t_Index < t_OldSize ; t_Index ++ )
  1036. {
  1037. if ( t_Index == t_OldSize - 1 )
  1038. {
  1039. if ( t_Index == t_NewSize - 1 )
  1040. {
  1041. t_StatusCode = Shrink_InnerDir (
  1042. a_Size & INNER_ELEMENT_DIR_MASK ,
  1043. a_NewSize & INNER_ELEMENT_DIR_MASK ,
  1044. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  1045. ) ;
  1046. }
  1047. else
  1048. {
  1049. t_StatusCode = Shrink_InnerDir (
  1050. a_Size & INNER_ELEMENT_DIR_MASK ,
  1051. INNER_DIR_SIZE ,
  1052. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  1053. ) ;
  1054. }
  1055. }
  1056. else
  1057. {
  1058. if ( t_Index == t_NewSize - 1 )
  1059. {
  1060. t_StatusCode = Shrink_InnerDir (
  1061. a_NewSize & INNER_ELEMENT_DIR_MASK ,
  1062. 0 ,
  1063. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  1064. ) ;
  1065. }
  1066. else
  1067. {
  1068. t_StatusCode = Shrink_InnerDir (
  1069. INNER_DIR_SIZE ,
  1070. 0 ,
  1071. & ( m_OuterDir.m_InnerDir [ t_Index ] )
  1072. ) ;
  1073. }
  1074. }
  1075. if ( t_StatusCode != e_StatusCode_Success )
  1076. {
  1077. if ( t_Index != t_NewSize - 1 )
  1078. {
  1079. ULONG t_Remainder = t_NewSize - t_Index - 1 ;
  1080. if ( t_Remainder )
  1081. {
  1082. m_Size = m_Size - ( ( t_Remainder - 1 ) * INNER_DIR_SIZE ) ;
  1083. }
  1084. m_Size = m_Size - ( a_NewSize & INNER_ELEMENT_DIR_MASK ) ;
  1085. }
  1086. break ;
  1087. }
  1088. }
  1089. if ( t_OldSize )
  1090. {
  1091. if ( t_OldSize != t_NewSize )
  1092. {
  1093. WmiInnerDir *t_Tmp = NULL ;
  1094. t_StatusCode = m_Allocator.ReAlloc (
  1095. ( void * ) m_OuterDir.m_InnerDir ,
  1096. ( void ** ) & t_Tmp ,
  1097. sizeof ( WmiInnerDir ) * t_NewSize
  1098. ) ;
  1099. if ( t_StatusCode == e_StatusCode_Success )
  1100. {
  1101. m_OuterDir.m_InnerDir = t_Tmp ;
  1102. }
  1103. }
  1104. }
  1105. else
  1106. {
  1107. if ( t_NewSize )
  1108. {
  1109. t_StatusCode = m_Allocator.Delete (
  1110. ( void ** ) & m_OuterDir.m_InnerDir
  1111. ) ;
  1112. }
  1113. else
  1114. {
  1115. t_StatusCode = e_StatusCode_Unknown ;
  1116. }
  1117. }
  1118. return t_StatusCode ;
  1119. }
  1120. #endif __ARRAY_CPP