bin.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. //
  19. // Bin.cpp
  20. //
  21. #include "stdAfx.h"
  22. #include "bin.h"
  23. #include "assert.h"
  24. #include "list.h"
  25. Bin::Bin ( int size )
  26. {
  27. assert ( size > 0 );
  28. num_buckets = size;
  29. sh_item = NULL;
  30. bucket = new List[size];
  31. }
  32. Bin::~Bin ( )
  33. {
  34. Clear ();
  35. delete [] bucket;
  36. }
  37. void Bin::Clear ( void )
  38. {
  39. int count = num_buckets;
  40. sh_item = NULL;
  41. while ( count-- )
  42. {
  43. List *head = &bucket[count];
  44. BinItem *item;
  45. while ( ( item = (BinItem *) head->Next ()))
  46. {
  47. Remove ( item );
  48. }
  49. }
  50. }
  51. void* Bin::Get ( OLECHAR *text1, OLECHAR *text2 )
  52. {
  53. BinItem *item;
  54. if ( ( item = GetBinItem ( text1, text2 )) )
  55. {
  56. return item->Item();
  57. }
  58. return NULL;
  59. }
  60. void* Bin::GetNext ( void )
  61. {
  62. BinItem *item;
  63. if ( ( item = GetNextBinItem ( )) )
  64. {
  65. return item->Item();
  66. }
  67. return NULL;
  68. }
  69. void Bin::Add ( void *data, OLECHAR *text1, OLECHAR *text2 )
  70. {
  71. BinItem *item;
  72. List *list;
  73. int hash;
  74. sh_item = NULL;
  75. hash = calc_hash ( text1 );
  76. item = new BinItem ( data, hash, text1, text2 );
  77. list = &bucket[hash%num_buckets];
  78. list->AddToTail ( (ListNode *) item );
  79. }
  80. BinItem* Bin::GetBinItem ( OLECHAR *text1, OLECHAR *text2)
  81. {
  82. sh_size1 = sh_size2 = 0;
  83. sh_text1 = text1;
  84. sh_text2 = text2;
  85. sh_hash = calc_hash ( text1 );
  86. if ( sh_text1 )
  87. {
  88. sh_size1 = wcslen ( sh_text1 );
  89. }
  90. if ( sh_text2 )
  91. {
  92. sh_size2 = wcslen ( sh_text2 );
  93. }
  94. sh_item = (BinItem *) &bucket[sh_hash%num_buckets];
  95. return GetNextBinItem ();
  96. }
  97. BinItem* Bin::GetNextBinItem ( void )
  98. {
  99. if ( sh_item )
  100. {
  101. sh_item = (BinItem *) sh_item->Next ();
  102. }
  103. while ( sh_item )
  104. {
  105. if ( sh_item->Same ( sh_hash, sh_text1, sh_size1, sh_text2, sh_size2 ))
  106. {
  107. break;
  108. }
  109. sh_item = (BinItem *) sh_item->Next ();
  110. }
  111. return sh_item;
  112. }
  113. BinItem* Bin::GetBinItem ( void *item )
  114. {
  115. BinItem *bitem = NULL;
  116. int i;
  117. for ( i=0; i< num_buckets; i++)
  118. {
  119. if ( ( bitem = (BinItem *) bucket[i].Find ( item )))
  120. {
  121. break;
  122. }
  123. }
  124. return bitem;
  125. }
  126. void Bin::Remove ( void *item )
  127. {
  128. BinItem *bitem;
  129. if ( ( bitem = GetBinItem ( item ) ))
  130. {
  131. Remove ( bitem );
  132. }
  133. }
  134. void Bin::Remove ( OLECHAR *text1, OLECHAR *text2 )
  135. {
  136. BinItem *bitem;
  137. if ( ( bitem = GetBinItem ( text1, text2 ) ))
  138. {
  139. Remove ( bitem );
  140. }
  141. }
  142. void Bin::Remove ( BinItem *item )
  143. {
  144. sh_item = NULL;
  145. item->Remove ();
  146. delete item ;
  147. }
  148. BinItem::BinItem ( void *data, int new_hash, OLECHAR *new_text1, OLECHAR *new_text2 )
  149. {
  150. SetItem ( data );
  151. hash = new_hash;
  152. if ( (text1 = new_text1) )
  153. {
  154. text1size = wcslen ( text1 );
  155. }
  156. else
  157. {
  158. text1size = 0;
  159. }
  160. if ( (text2 = new_text2) )
  161. {
  162. text2size = wcslen ( text2 );
  163. }
  164. else
  165. {
  166. text2size = 0;
  167. }
  168. }
  169. int BinItem::Same ( int chash, OLECHAR *ctext1, int size1, OLECHAR *ctext2, int size2 )
  170. {
  171. if ( hash != chash || text1size != size1 || text2size != size2 )
  172. {
  173. return FALSE;
  174. }
  175. if ( wcsicmp ( text1, ctext1 ))
  176. {
  177. return FALSE;
  178. }
  179. if ( text2 && ctext2 && wcsicmp ( text2, ctext2 ))
  180. {
  181. return FALSE;
  182. }
  183. return TRUE;
  184. }
  185. int Bin::calc_hash ( OLECHAR *text )
  186. {
  187. int hash = 0;
  188. while ( *text )
  189. {
  190. hash += *text++;
  191. }
  192. return hash;
  193. }
  194. // Bin ID code
  195. BinID::BinID ( int size )
  196. {
  197. assert ( size > 0 );
  198. num_buckets = size;
  199. bucket = new List[size];
  200. }
  201. BinID::~BinID ( )
  202. {
  203. Clear ();
  204. delete [] bucket;
  205. }
  206. void BinID::Clear ( void )
  207. {
  208. int count = num_buckets;
  209. while ( count-- )
  210. {
  211. List *head = &bucket[count];
  212. BinIDItem *item;
  213. while ( ( item = (BinIDItem *) head->Next ()))
  214. {
  215. Remove ( item );
  216. }
  217. }
  218. }
  219. void* BinID::Get ( int id)
  220. {
  221. BinIDItem *item;
  222. if ( ( item = GetBinIDItem ( id )) )
  223. {
  224. return item->Item();
  225. }
  226. return NULL;
  227. }
  228. void BinID::Add ( void *data, int id )
  229. {
  230. BinIDItem *item;
  231. List *list;
  232. item = new BinIDItem ( data, id );
  233. list = &bucket[id%num_buckets];
  234. list->AddToTail ( (ListNode *) item );
  235. }
  236. BinIDItem* BinID::GetBinIDItem ( int id )
  237. {
  238. BinIDItem *item;
  239. item = (BinIDItem *) bucket[id%num_buckets].Next();
  240. while ( item )
  241. {
  242. if ( item->Same ( id ))
  243. {
  244. break;
  245. }
  246. item = (BinIDItem *) item->Next ();
  247. }
  248. return item ;
  249. }
  250. BinIDItem* BinID::GetBinIDItem ( void *item )
  251. {
  252. BinIDItem *bitem = NULL;
  253. int i;
  254. for ( i=0; i< num_buckets; i++)
  255. {
  256. if ( ( bitem = (BinIDItem *) bucket[i].Find ( item )))
  257. {
  258. break;
  259. }
  260. }
  261. return bitem;
  262. }
  263. void BinID::Remove ( void *item )
  264. {
  265. BinIDItem *bitem;
  266. if ( ( bitem = GetBinIDItem ( item ) ))
  267. {
  268. Remove ( bitem );
  269. }
  270. }
  271. void BinID::Remove ( int id )
  272. {
  273. BinIDItem *bitem;
  274. if ( ( bitem = GetBinIDItem ( id ) ))
  275. {
  276. Remove ( bitem );
  277. }
  278. }
  279. void BinID::Remove ( BinIDItem *item )
  280. {
  281. item->Remove ();
  282. delete item ;
  283. }
  284. BinIDItem::BinIDItem ( void *data, int new_id )
  285. {
  286. SetItem ( data );
  287. id = new_id;
  288. }
  289. int BinIDItem::Same ( int compare_id )
  290. {
  291. return id == compare_id;
  292. }