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.

524 lines
9.4 KiB

  1. // -----------------------------------------------------------------------------------
  2. // Created by RogerJ, October 4th, 2000
  3. // Implementation of MultiSZ smart Array
  4. //
  5. #include <windows.h>
  6. #include "MultiSZArray.h"
  7. // class CMultiSZString
  8. // defatul constructor
  9. CMultiSZString::CMultiSZString()
  10. {
  11. m_nSize = m_nStringCount = m_nIndex = 0;
  12. m_bFound = FALSE;
  13. m_szHardwareId = NULL;
  14. prev = next = NULL;
  15. }
  16. // constructor
  17. CMultiSZString::CMultiSZString(LPCTSTR pszHardwareId, int nSize)
  18. {
  19. prev = next = NULL;
  20. m_nSize = m_nStringCount = m_nIndex = 0;
  21. m_bFound = FALSE;
  22. m_szHardwareId = NULL;
  23. if (pszHardwareId)
  24. {
  25. if (nSize >= 0)
  26. {
  27. // passed in a regular LPCTSTR
  28. m_nSize = nSize;
  29. m_nStringCount = 1;
  30. }
  31. else
  32. {
  33. // passed in a multi-sz LPCTSTR
  34. // get the size
  35. LPTSTR pTemp = const_cast<LPTSTR>(pszHardwareId);
  36. while (*pTemp)
  37. {
  38. int nTempSize = lstrlen(pTemp) + 1;
  39. m_nSize += nTempSize;
  40. pTemp += nTempSize;
  41. m_nStringCount++;
  42. }
  43. }
  44. // allocate memory
  45. m_szHardwareId = new TCHAR [m_nSize+1];
  46. if (!m_szHardwareId)
  47. // failed to allocate memory
  48. throw ERROR_OUTOFMEMORY;
  49. // initialize allocated memory
  50. ZeroMemory (m_szHardwareId, (m_nSize+1) * sizeof(TCHAR)); // +1 for a possible trail NULL
  51. CopyMemory ((PVOID)m_szHardwareId, (CONST VOID*)pszHardwareId, m_nSize*sizeof(TCHAR));
  52. m_nSize ++;
  53. }
  54. }
  55. // copy constructor
  56. CMultiSZString::CMultiSZString(CMultiSZString& CopyInfo)
  57. {
  58. prev = next = NULL;
  59. m_nIndex = 0;
  60. m_nSize = CopyInfo.m_nSize;
  61. m_bFound = CopyInfo.m_bFound;
  62. // allocate memory
  63. m_szHardwareId = new TCHAR [m_nSize];
  64. if (!m_szHardwareId)
  65. // failed to allocate memory
  66. throw ERROR_OUTOFMEMORY;
  67. // initialize allocated memory
  68. ZeroMemory (m_szHardwareId, m_nSize * sizeof(TCHAR));
  69. CopyMemory ((PVOID)m_szHardwareId, (CONST VOID*)(CopyInfo.m_szHardwareId), m_nSize*sizeof(TCHAR));
  70. }
  71. // destructor
  72. CMultiSZString::~CMultiSZString()
  73. {
  74. if (m_szHardwareId)
  75. delete [] m_szHardwareId;
  76. m_szHardwareId = NULL;
  77. prev = next = NULL;
  78. m_nSize = m_nIndex = 0;
  79. }
  80. BOOL CMultiSZString::ToString (LPTSTR pszBuffer, int* pnBufferLen)
  81. {
  82. if (!pszBuffer)
  83. {
  84. // query for output buffer length
  85. if (m_nSize <= 0)
  86. *pnBufferLen = 1;
  87. else
  88. *pnBufferLen = m_nSize;
  89. return TRUE;
  90. }
  91. if (*pnBufferLen < m_nSize)
  92. {
  93. *pnBufferLen = m_nSize;
  94. return FALSE;
  95. }
  96. // duel with NULL string special case
  97. if (m_nSize <= 0)
  98. {
  99. *pszBuffer = NULL;
  100. return TRUE;
  101. }
  102. ZeroMemory(pszBuffer, *pnBufferLen * sizeof(TCHAR));
  103. LPTSTR pTemp = m_szHardwareId;
  104. LPTSTR pTemp2 = pszBuffer;
  105. while (*pTemp)
  106. {
  107. lstrcpy(pTemp2,pTemp);
  108. // add space in the place of NULL character
  109. pTemp2 += lstrlen(pTemp2);
  110. *pTemp2 = ' ';
  111. pTemp2++;
  112. // move to next string in Multi-SZ string
  113. pTemp += lstrlen(pTemp) + 1;
  114. }
  115. return TRUE;
  116. }
  117. // compare two multi-sz string
  118. BOOL CMultiSZString::Compare (CMultiSZString& CompareSZ)
  119. {
  120. LPTSTR pThis = m_szHardwareId;
  121. LPTSTR pComp = CompareSZ.m_szHardwareId;
  122. // compare size first
  123. if (m_nSize != CompareSZ.m_nSize) return FALSE;
  124. // size are same
  125. while (*pThis && *pComp)
  126. {
  127. // compare one string in the list
  128. if (0 != lstrcmp(pThis, pComp))
  129. return FALSE;
  130. // move to next string
  131. int nIncrement = lstrlen(pThis);
  132. pThis += nIncrement + 1;
  133. pComp += nIncrement + 1;
  134. }
  135. // one multi-sz terminates, check to see if both terminates
  136. if (*pThis || *pComp) return FALSE;
  137. else return TRUE;
  138. }
  139. // compare two multi-sz string case insensitively
  140. BOOL CMultiSZString::CompareNoCase (CMultiSZString& CompareSZ)
  141. {
  142. LPTSTR pThis = m_szHardwareId;
  143. LPTSTR pComp = CompareSZ.m_szHardwareId;
  144. // compare size first
  145. if (m_nSize != CompareSZ.m_nSize) return FALSE;
  146. // size are same
  147. while (*pThis && *pComp)
  148. {
  149. // compare one string in the list
  150. if (0 != lstrcmpi(pThis, pComp))
  151. return FALSE;
  152. // move to next string
  153. int nIncrement = lstrlen(pThis) + 1;
  154. pThis += nIncrement;
  155. pComp += nIncrement;
  156. }
  157. // one multi-sz terminates, check to see if both terminates
  158. if (*pThis || *pComp) return FALSE;
  159. else return TRUE;
  160. }
  161. LPCTSTR CMultiSZString::GetNextString(void)
  162. {
  163. // reached end of the multiSZ string
  164. if (m_nIndex >= m_nSize) return NULL;
  165. // else
  166. LPTSTR pTemp = m_szHardwareId + m_nIndex;
  167. m_nIndex += lstrlen(pTemp) + 1;
  168. return pTemp;
  169. }
  170. // return TRUE if pszIn is in the Multi-SZ string
  171. BOOL CMultiSZString::Contains(LPCTSTR pszIn)
  172. {
  173. LPTSTR pThis = m_szHardwareId;
  174. while (*pThis)
  175. {
  176. if (!lstrcmp(pThis, pszIn))
  177. // match found
  178. return TRUE;
  179. pThis += (lstrlen(pThis) +1);
  180. }
  181. // not found
  182. return FALSE;
  183. }
  184. // return TRUE if pszIn is in the Multi-SZ string
  185. BOOL CMultiSZString::ContainsNoCase(LPCTSTR pszIn)
  186. {
  187. LPTSTR pThis = m_szHardwareId;
  188. while (*pThis)
  189. {
  190. if (!lstrcmpi(pThis, pszIn))
  191. // match found
  192. return TRUE;
  193. pThis += (lstrlen(pThis) +1);
  194. }
  195. // not found
  196. return FALSE;
  197. }
  198. BOOL CMultiSZString::PositionIndex(LPCTSTR pszIn, int* pPosition)
  199. {
  200. if (!pPosition) return FALSE;
  201. *pPosition = 0;
  202. LPTSTR pThis = m_szHardwareId;
  203. while (*pThis)
  204. {
  205. if (!lstrcmpi(pThis, pszIn))
  206. {
  207. // match found
  208. return TRUE;
  209. }
  210. pThis += (lstrlen(pThis) +1);
  211. (*pPosition)++;
  212. }
  213. // not found
  214. *pPosition = -1;
  215. return FALSE;
  216. }
  217. // Class CMultiSZArray
  218. // default constructor
  219. CMultiSZArray::CMultiSZArray()
  220. {
  221. m_nCount = 0;
  222. m_pHead = m_pTail = m_pIndex = NULL;
  223. }
  224. // other constructors
  225. CMultiSZArray::CMultiSZArray(LPCTSTR pszHardwareId, int nSize)
  226. {
  227. CMultiSZString *pNode = new CMultiSZString(pszHardwareId, nSize);
  228. if (!pNode) throw ERROR_OUTOFMEMORY;
  229. m_nCount = 1;
  230. m_pHead = m_pTail = m_pIndex = pNode;
  231. }
  232. CMultiSZArray::CMultiSZArray(CMultiSZString* pNode)
  233. {
  234. if (!pNode) return;
  235. m_nCount = 1;
  236. m_pHead = m_pTail = m_pIndex =pNode;
  237. }
  238. // destructor
  239. CMultiSZArray::~CMultiSZArray(void)
  240. {
  241. RemoveAll();
  242. }
  243. // member functions
  244. // Function RemoveAll() delete all the memory allocated for the array and set the status back to initial state
  245. BOOL CMultiSZArray::RemoveAll(void)
  246. {
  247. CMultiSZString* pTemp = NULL;
  248. for (int i=0; i<m_nCount; i++)
  249. {
  250. pTemp = m_pHead;
  251. m_pHead = m_pHead->next;
  252. delete pTemp;
  253. }
  254. m_pHead = m_pTail = m_pIndex = NULL;
  255. m_nCount = 0;
  256. return TRUE;
  257. }
  258. BOOL CMultiSZArray::Add(CMultiSZString* pInfo)
  259. {
  260. if (!pInfo) return TRUE;
  261. if (!m_nCount)
  262. m_pHead = pInfo;
  263. else
  264. {
  265. // link
  266. m_pTail->next = pInfo;
  267. pInfo->prev = m_pTail;
  268. pInfo->next = NULL;
  269. }
  270. // move tail
  271. m_pTail = pInfo;
  272. m_nCount++;
  273. return TRUE;
  274. }
  275. BOOL CMultiSZArray::Add(LPCSTR pszHardwareId, int nSize)
  276. {
  277. CMultiSZString* pNode = new CMultiSZString(pszHardwareId, nSize);
  278. return Add(pNode);
  279. }
  280. BOOL CMultiSZArray::Remove(LPCSTR pszHardwareId)
  281. {
  282. CMultiSZString* pTemp = m_pHead;
  283. while (pTemp)
  284. {
  285. if (pTemp->m_szHardwareId == pszHardwareId)
  286. {
  287. // found match
  288. if (pTemp->prev)
  289. // not the head node
  290. pTemp->prev->next = pTemp->next;
  291. else
  292. {
  293. // head node, move the head node
  294. m_pHead = pTemp->next;
  295. if (m_pHead) m_pHead->prev = NULL;
  296. }
  297. if (pTemp->next)
  298. // not the tail node
  299. pTemp->next->prev = pTemp->prev;
  300. else
  301. {
  302. // tail node, move the tail node
  303. m_pTail = pTemp->prev;
  304. if (m_pTail) m_pTail->next = NULL;
  305. }
  306. delete pTemp;
  307. m_nCount--;
  308. return TRUE;
  309. }
  310. pTemp = pTemp->next;
  311. }
  312. // no match found or no node in the array
  313. return FALSE;
  314. }
  315. BOOL CMultiSZArray::ToString(LPTSTR pszBuffer, int* pnBufferLen)
  316. {
  317. int nTempLen = 0;
  318. CMultiSZString* pTemp = m_pHead;
  319. for (int i=0; i<m_nCount; i++)
  320. {
  321. nTempLen += pTemp->m_nSize;
  322. pTemp = pTemp->next;
  323. }
  324. nTempLen++; // the trailing NULL character
  325. if (!pszBuffer)
  326. {
  327. // request for length
  328. *pnBufferLen = nTempLen;
  329. return TRUE;
  330. }
  331. else
  332. {
  333. if (*pnBufferLen < nTempLen)
  334. {
  335. // buffer too small
  336. *pnBufferLen = nTempLen;
  337. return FALSE;
  338. }
  339. else
  340. {
  341. ZeroMemory(pszBuffer, *pnBufferLen * sizeof (TCHAR));
  342. LPTSTR pszTemp = pszBuffer;
  343. int nSizeLeft = *pnBufferLen;
  344. pTemp = m_pHead;
  345. for (int j=0; j<m_nCount; j++)
  346. {
  347. pTemp->ToString(pszTemp, &nSizeLeft);
  348. pszTemp += pTemp->m_nSize - 1;
  349. *pszTemp = '\n';
  350. nSizeLeft -= pTemp->m_nSize;
  351. pTemp = pTemp->next;
  352. }
  353. return TRUE;
  354. }
  355. }
  356. }
  357. int CMultiSZArray::GetTotalStringCount()
  358. {
  359. CMultiSZString* pTemp = m_pHead;
  360. int nTotalCount = 0;
  361. for (int i = 0; i<m_nCount; i++)
  362. {
  363. nTotalCount += pTemp->m_nStringCount;
  364. pTemp = pTemp->next;
  365. }
  366. return nTotalCount;
  367. }
  368. CMultiSZString* CMultiSZArray::GetNextMultiSZString()
  369. {
  370. CMultiSZString* pTemp = m_pIndex;
  371. if (m_pIndex) m_pIndex = m_pIndex->next;
  372. return pTemp;
  373. }
  374. BOOL CMultiSZArray::Contains(LPCTSTR pszIn)
  375. {
  376. CMultiSZString* pTemp = m_pHead;
  377. for (int i=0; i<m_nCount; i++)
  378. {
  379. if (pTemp->Contains(pszIn))
  380. return TRUE;
  381. pTemp = pTemp->next;
  382. }
  383. return FALSE;
  384. }
  385. BOOL CMultiSZArray::ContainsNoCase(LPCTSTR pszIn)
  386. {
  387. CMultiSZString* pTemp = m_pHead;
  388. for (int i=0; i<m_nCount; i++)
  389. {
  390. if (pTemp->ContainsNoCase(pszIn))
  391. return TRUE;
  392. pTemp = pTemp->next;
  393. }
  394. return FALSE;
  395. }
  396. BOOL CMultiSZArray::PositionIndex(LPCTSTR pszIn, PosIndex* pPosition)
  397. {
  398. if (!pPosition) return FALSE;
  399. CMultiSZString* pTemp = m_pHead;
  400. pPosition->y = 0;
  401. pPosition->x = 0;
  402. for (int i=0; i<m_nCount; i++)
  403. {
  404. if (pTemp->PositionIndex(pszIn, &(pPosition->y)))
  405. return TRUE;
  406. (pPosition->x)++;
  407. pTemp = pTemp->next;
  408. }
  409. pPosition->x = pPosition->y = -1;
  410. return FALSE;
  411. }
  412. BOOL CMultiSZArray::CheckFound(int nIndex)
  413. {
  414. if (nIndex > m_nCount) return FALSE;
  415. CMultiSZString* pTemp = NULL;
  416. ResetIndex();
  417. for (int i=0; i<=nIndex; i++)
  418. {
  419. pTemp = GetNextMultiSZString();
  420. }
  421. pTemp->CheckFound();
  422. return TRUE;
  423. }