Props.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //
  20. // Props.H
  21. //
  22. // History:
  23. // 01/05/97 JMI Started.
  24. //
  25. // 01/09/97 JMI Removed #include <utility>.
  26. //
  27. // 01/14/97 JMI Changed order of ItemType and KeyType in calls that
  28. // take both. Also, RemoveProp() no longer complains
  29. // about removing props that didn't exist. Who really
  30. // wants to check if a prop exists before removing it?
  31. //
  32. // 03/28/97 JMI Removed all traces of STL. IN PROGRESS!!!!!
  33. //
  34. // 03/31/97 JMI Finished converting. Note that the STL map was much
  35. // better suited for this class than the regular "Jon Lists"
  36. // (as they've been called). Perhaps RSPiX could use its
  37. // own implementation of map or a more advanced 'Jon List'
  38. // suite. The major difference being the allocation of the
  39. // data in chunks that are larger than the actual nodes and,
  40. // in the case of a map, being able to access the data
  41. // actually allocated by the map.
  42. //
  43. //////////////////////////////////////////////////////////////////////////////
  44. //
  45. // This class keeps track of a group of 'properties' that are identified by
  46. // a key.
  47. // This class does not claim to be especially fast or memory efficient. It
  48. // is, however, an extremely simple to use way of adding dynamic data
  49. // association to an object.
  50. // A typical use of this class would be to descend from it so that the user
  51. // can dynamically associate data with a class instance simply by calling
  52. // AddProp() and SetProp().
  53. // To clean up this class without complaint by its destructor, call Reset()
  54. // from your classes destructor.
  55. //
  56. //////////////////////////////////////////////////////////////////////////////
  57. #ifndef PROPS_H
  58. #define PROPS_H
  59. //////////////////////////////////////////////////////////////////////////////
  60. // C Headers -- Must be included before RSPiX.h b/c RSPiX utilizes SHMalloc.
  61. //////////////////////////////////////////////////////////////////////////////
  62. ///////////////////////////////////////////////////////////////////////////////
  63. // RSPiX Headers.
  64. // If PATHS_IN_INCLUDES macro is defined, we can utilize relative
  65. // paths to a header file. In this case we generally go off of our
  66. // RSPiX root directory. System.h MUST be included before this macro
  67. // is evaluated. System.h is the header that, based on the current
  68. // platform (or more so in this case on the compiler), defines
  69. // PATHS_IN_INCLUDES. Blue.h includes system.h so you can include that
  70. // instead.
  71. ///////////////////////////////////////////////////////////////////////////////
  72. #include "System.h"
  73. #ifdef PATHS_IN_INCLUDES
  74. #include "ORANGE/CDT/List.h"
  75. #else
  76. #include "list.h"
  77. #endif
  78. //////////////////////////////////////////////////////////////////////////////
  79. // Macros.
  80. //////////////////////////////////////////////////////////////////////////////
  81. //////////////////////////////////////////////////////////////////////////////
  82. // Protos.
  83. //////////////////////////////////////////////////////////////////////////////
  84. //////////////////////////////////////////////////////////////////////////////
  85. // Typedefs.
  86. //////////////////////////////////////////////////////////////////////////////
  87. template <class ItemType, class KeyType>
  88. class RProps
  89. {
  90. ///////////////////////////////////////////////////////////////////////////
  91. // Typedefs.
  92. ///////////////////////////////////////////////////////////////////////////
  93. public:
  94. typedef struct
  95. {
  96. ItemType item;
  97. KeyType key;
  98. } Node;
  99. typedef RList<Node> Container;
  100. ///////////////////////////////////////////////////////////////////////////
  101. // Con/Destruction.
  102. ///////////////////////////////////////////////////////////////////////////
  103. public:
  104. RProps()
  105. {
  106. }
  107. ~RProps()
  108. {
  109. // If there are still props . . .
  110. if (m_container.IsEmpty() == FALSE)
  111. {
  112. TRACE("~RProps(): Warning: Cleaning up unremoved props.\n");
  113. }
  114. Reset();
  115. }
  116. ///////////////////////////////////////////////////////////////////////////
  117. // Methods.
  118. ///////////////////////////////////////////////////////////////////////////
  119. public:
  120. // Adds a new property.
  121. short AddProp( // Returns 0 on success.
  122. // Returns 1 if key already exists.
  123. // Returns -1 if error.
  124. KeyType key, // Key to identify item.
  125. ItemType item) // Item to add.
  126. {
  127. short sRes = 0; // Assume success.
  128. // Verify key does not exist . . .
  129. if (Find(&key) == NULL)
  130. {
  131. // Insert item . . .
  132. sRes = Add(key, item);
  133. }
  134. else
  135. {
  136. TRACE("AddProp(): Key already exists. Not adding prop.\n");
  137. sRes = 1;
  138. }
  139. return sRes;
  140. }
  141. // Replaces an existing or adds a new property.
  142. // Be careful with this. You could inadvertently replace
  143. // a prop that was supplied by another user.
  144. void SetProp( // Returns 0 on success.
  145. // Returns -1 if error.
  146. KeyType key, // Key to identify old item.
  147. ItemType item) // New item.
  148. {
  149. // If the key already exists . . .
  150. Node* pnode = Find(&key);
  151. if (pnode != NULL)
  152. {
  153. // Change the value.
  154. pnode->item = item;
  155. }
  156. else
  157. {
  158. // Insert item.
  159. Add(key, item);
  160. }
  161. }
  162. // Removes an existing property.
  163. void RemoveProp( // Returns nothing.
  164. KeyType key) // Key of item to remove.
  165. {
  166. Remove(key);
  167. }
  168. ///////////////////////////////////////////////////////////////////////////
  169. // Querries.
  170. ///////////////////////////////////////////////////////////////////////////
  171. public:
  172. // Does the specified prop key exist?
  173. short IsProp( // Returns TRUE if item exists, FALSE otherwise.
  174. KeyType key) // Key of item to query.
  175. {
  176. return (short)(Find(&key) != NULL);
  177. }
  178. // Get a property.
  179. short GetProp( // Returns 0 on success.
  180. // Returns 1 if no item with specified key.
  181. KeyType key, // Key of item to get.
  182. ItemType* pitem) // Where to put item.
  183. {
  184. short sRes = 0; // Assume success.
  185. // Find node by key . . .
  186. Node* pnode = Find(&key);
  187. if (pnode != NULL)
  188. {
  189. // Get item.
  190. *pitem = pnode->item;
  191. }
  192. else
  193. {
  194. TRACE("GetProp(): Key does not exist.\n");
  195. sRes = 1;
  196. }
  197. return sRes;
  198. }
  199. ///////////////////////////////////////////////////////////////////////////
  200. // Internal functionality.
  201. ///////////////////////////////////////////////////////////////////////////
  202. protected:
  203. // Find the node with the specified key.
  204. Node* Find( // Returns the node with the specified key.
  205. KeyType* pkey) // In: Ptr to the key to search for.
  206. {
  207. Node* pn = m_container.GetHead();
  208. while (pn != NULL)
  209. {
  210. if (pn->key == *pkey)
  211. break;
  212. pn = m_container.GetNext();
  213. }
  214. return pn;
  215. }
  216. // Add a node, as specified by the supplied item and key.
  217. short Add( // Returns 0 on success.
  218. // Returns -1 if error.
  219. KeyType key, // Key to identify item.
  220. ItemType item) // Item to add.
  221. {
  222. short sRes = 0; // Assume success.
  223. // Allocate node to add . . .
  224. Node* pn = new Node;
  225. if (pn != NULL)
  226. {
  227. pn->key = key;
  228. pn->item = item;
  229. if (m_container.AddTail(pn) == 0)
  230. {
  231. // Success.
  232. }
  233. else
  234. {
  235. TRACE("Add(): m_container.AddTail() failed.\n");
  236. sRes = -2;
  237. }
  238. // If any errors occurred after allocation . . .
  239. if (sRes != 0)
  240. {
  241. delete pn;
  242. }
  243. }
  244. else
  245. {
  246. TRACE("Add(): Unable to allocate new Node.\n");
  247. sRes = -1;
  248. }
  249. return sRes;
  250. }
  251. // Remove the node identified by the supplied key.
  252. short Remove( // Returns 0 on success.
  253. // Returns -1 if error.
  254. KeyType key) // Key to identify item to remove.
  255. {
  256. short sRes = 0; // Assume success.
  257. Node* pn = Find(&key);
  258. if (pn != NULL)
  259. {
  260. // The container's current item is the one we want to remove.
  261. if (m_container.Remove() == 0)
  262. {
  263. // Success.
  264. delete pn;
  265. }
  266. else
  267. {
  268. TRACE("Remove(): m_container.Remove() failed.\n");
  269. sRes = -1;
  270. }
  271. }
  272. else
  273. {
  274. // No such node.
  275. sRes = 1;
  276. }
  277. return sRes;
  278. }
  279. // Empty container of current contents.
  280. void Reset(void)
  281. {
  282. Node* pn = m_container.GetHead();
  283. while (pn != NULL)
  284. {
  285. m_container.Remove();
  286. delete pn;
  287. pn = m_container.GetNext();
  288. }
  289. }
  290. ///////////////////////////////////////////////////////////////////////////
  291. // Instantiable data.
  292. ///////////////////////////////////////////////////////////////////////////
  293. public:
  294. Container m_container; // Contains the props.
  295. ///////////////////////////////////////////////////////////////////////////
  296. // Static data.
  297. ///////////////////////////////////////////////////////////////////////////
  298. public:
  299. };
  300. #endif // PROPS_H
  301. //////////////////////////////////////////////////////////////////////////////
  302. // EOF
  303. //////////////////////////////////////////////////////////////////////////////