PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Modules/hdf5-1.8.0/src/H5RS.c

#
C | 497 lines | 159 code | 58 blank | 280 comment | 10 complexity | e1561926fc5884379e33ad19d5db5fe7 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, BSD-3-Clause
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. * Copyright by The HDF Group. *
  3. * Copyright by the Board of Trustees of the University of Illinois. *
  4. * All rights reserved. *
  5. * *
  6. * This file is part of HDF5. The full HDF5 copyright notice, including *
  7. * terms governing use, modification, and redistribution, is contained in *
  8. * the files COPYING and Copyright.html. COPYING can be found at the root *
  9. * of the source code distribution tree; Copyright.html can be found at the *
  10. * root level of an installed copy of the electronic HDF5 document set and *
  11. * is linked from the top-level documents page. It can also be found at *
  12. * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
  13. * access to either file, you may request a copy from help@hdfgroup.org. *
  14. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  15. /*
  16. * Reference counted string algorithms.
  17. *
  18. * These are used for various internal strings which get copied multiple times.
  19. *
  20. */
  21. #include "H5Eprivate.h" /* Error handling */
  22. #include "H5FLprivate.h" /* Free lists */
  23. #include "H5RSprivate.h" /* Reference-counted strings */
  24. /* Private typedefs & structs */
  25. struct H5RS_str_t {
  26. char *s; /* String to be reference counted */
  27. unsigned wrapped; /* Indicates that the string to be ref-counted is not copied */
  28. unsigned n; /* Reference count of number of pointers sharing string */
  29. };
  30. /* Declare a free list to manage the H5RS_str_t struct */
  31. H5FL_DEFINE_STATIC(H5RS_str_t);
  32. /* Declare the PQ free list for the wrapped strings */
  33. H5FL_BLK_DEFINE(str_buf);
  34. /*--------------------------------------------------------------------------
  35. NAME
  36. H5RS_xstrdup
  37. PURPOSE
  38. Duplicate the string being reference counted
  39. USAGE
  40. char *H5RS_xstrdup(s)
  41. const char *s; IN: String to duplicate
  42. RETURNS
  43. Returns a pointer to a new string on success, NULL on failure.
  44. DESCRIPTION
  45. Duplicate a string buffer being reference counted. Use this instead of
  46. [H5MM_][x]strdup, in order to use the free-list memory routines.
  47. GLOBAL VARIABLES
  48. COMMENTS, BUGS, ASSUMPTIONS
  49. EXAMPLES
  50. REVISION LOG
  51. --------------------------------------------------------------------------*/
  52. static char *
  53. H5RS_xstrdup(const char *s)
  54. {
  55. char *ret_value; /* Return value */
  56. FUNC_ENTER_NOAPI_NOINIT(H5RS_xstrdup)
  57. if(s) {
  58. ret_value = (char *)H5FL_BLK_MALLOC(str_buf, HDstrlen(s) + 1);
  59. HDassert(ret_value);
  60. HDstrcpy(ret_value, s);
  61. } /* end if */
  62. else
  63. ret_value = NULL;
  64. FUNC_LEAVE_NOAPI(ret_value)
  65. } /* end H5RS_xstrdup() */
  66. /*--------------------------------------------------------------------------
  67. NAME
  68. H5RS_create
  69. PURPOSE
  70. Create a reference counted string
  71. USAGE
  72. H5RS_str_t *H5RS_create(s)
  73. const char *s; IN: String to initialize ref-counted string with
  74. RETURNS
  75. Returns a pointer to a new ref-counted string on success, NULL on failure.
  76. DESCRIPTION
  77. Create a reference counted string. The string passed in is copied into an
  78. internal buffer.
  79. GLOBAL VARIABLES
  80. COMMENTS, BUGS, ASSUMPTIONS
  81. EXAMPLES
  82. REVISION LOG
  83. --------------------------------------------------------------------------*/
  84. H5RS_str_t *
  85. H5RS_create(const char *s)
  86. {
  87. H5RS_str_t *ret_value=NULL; /* Return value */
  88. FUNC_ENTER_NOAPI(H5RS_create,NULL);
  89. /* Allocate ref-counted string structure */
  90. if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
  91. HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
  92. /* Set the internal fields */
  93. ret_value->s=H5RS_xstrdup(s);
  94. ret_value->wrapped=0;
  95. ret_value->n=1;
  96. done:
  97. FUNC_LEAVE_NOAPI(ret_value);
  98. } /* end H5RS_create() */
  99. /*--------------------------------------------------------------------------
  100. NAME
  101. H5RS_wrap
  102. PURPOSE
  103. "Wrap" a reference counted string around an existing string
  104. USAGE
  105. H5RS_str_t *H5RS_wrap(s)
  106. const char *s; IN: String to wrap ref-counted string around
  107. RETURNS
  108. Returns a pointer to a new ref-counted string on success, NULL on failure.
  109. DESCRIPTION
  110. Wrap a reference counted string around an existing string, which is not
  111. duplicated, unless its reference count gets incremented.
  112. GLOBAL VARIABLES
  113. COMMENTS, BUGS, ASSUMPTIONS
  114. EXAMPLES
  115. REVISION LOG
  116. --------------------------------------------------------------------------*/
  117. H5RS_str_t *
  118. H5RS_wrap(const char *s)
  119. {
  120. H5RS_str_t *ret_value=NULL; /* Return value */
  121. FUNC_ENTER_NOAPI(H5RS_wrap,NULL);
  122. /* Allocate ref-counted string structure */
  123. if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
  124. HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
  125. /* Set the internal fields */
  126. ret_value->s=(char*)s; /* (Cast away const OK - QAK) */
  127. ret_value->wrapped=1;
  128. ret_value->n=1;
  129. done:
  130. FUNC_LEAVE_NOAPI(ret_value);
  131. } /* end H5RS_wrap() */
  132. /*--------------------------------------------------------------------------
  133. NAME
  134. H5RS_own
  135. PURPOSE
  136. Transfer ownership of a regular string to a reference counted string
  137. USAGE
  138. H5RS_str_t *H5RS_own(s)
  139. const char *s; IN: String to transfer ownership of
  140. RETURNS
  141. Returns a pointer to a new ref-counted string on success, NULL on failure.
  142. DESCRIPTION
  143. Transfer ownership of a dynamically allocated string to a reference counted
  144. string. The routine which passed in the string should not attempt to free
  145. it, the reference counting string routines will do that when the reference
  146. count drops to zero.
  147. GLOBAL VARIABLES
  148. COMMENTS, BUGS, ASSUMPTIONS
  149. EXAMPLES
  150. REVISION LOG
  151. --------------------------------------------------------------------------*/
  152. H5RS_str_t *
  153. H5RS_own(char *s)
  154. {
  155. H5RS_str_t *ret_value=NULL; /* Return value */
  156. FUNC_ENTER_NOAPI(H5RS_own,NULL);
  157. /* Allocate ref-counted string structure */
  158. if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
  159. HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
  160. /* Set the internal fields */
  161. ret_value->s=s;
  162. ret_value->wrapped=0;
  163. ret_value->n=1;
  164. done:
  165. FUNC_LEAVE_NOAPI(ret_value);
  166. } /* end H5RS_own() */
  167. /*--------------------------------------------------------------------------
  168. NAME
  169. H5RS_decr
  170. PURPOSE
  171. Decrement the reference count for a ref-counted string
  172. USAGE
  173. herr_t H5RS_decr(rs)
  174. H5RS_str_t *rs; IN/OUT: Ref-counted string to decrement count of
  175. RETURNS
  176. Non-negative on success/Negative on failure
  177. DESCRIPTION
  178. Decrement the reference count for a reference counted string. If the
  179. reference count drops to zero, the reference counted string is deleted.
  180. GLOBAL VARIABLES
  181. COMMENTS, BUGS, ASSUMPTIONS
  182. EXAMPLES
  183. REVISION LOG
  184. --------------------------------------------------------------------------*/
  185. herr_t
  186. H5RS_decr(H5RS_str_t *rs)
  187. {
  188. FUNC_ENTER_NOAPI_NOFUNC(H5RS_decr);
  189. /* Sanity check */
  190. assert(rs);
  191. assert(rs->n > 0);
  192. /* Decrement reference count for string */
  193. if((--rs->n)==0) {
  194. if(!rs->wrapped)
  195. (void)H5FL_BLK_FREE(str_buf,rs->s);
  196. H5FL_FREE(H5RS_str_t,rs);
  197. } /* end if */
  198. FUNC_LEAVE_NOAPI(SUCCEED);
  199. } /* end H5RS_decr() */
  200. /*--------------------------------------------------------------------------
  201. NAME
  202. H5RS_incr
  203. PURPOSE
  204. Increment the reference count for a ref-counted string
  205. USAGE
  206. herr_t H5RS_incr(rs)
  207. H5RS_str_t *rs; IN/OUT: Ref-counted string to increment count of
  208. RETURNS
  209. Non-negative on success/Negative on failure
  210. DESCRIPTION
  211. Increment the reference count for a reference counted string.
  212. GLOBAL VARIABLES
  213. COMMENTS, BUGS, ASSUMPTIONS
  214. EXAMPLES
  215. REVISION LOG
  216. --------------------------------------------------------------------------*/
  217. herr_t
  218. H5RS_incr(H5RS_str_t *rs)
  219. {
  220. FUNC_ENTER_NOAPI_NOFUNC(H5RS_incr);
  221. /* Sanity check */
  222. assert(rs);
  223. assert(rs->n > 0);
  224. /* If the ref-counted string started life as a wrapper around an existing
  225. * string, duplicate the string now, so that the wrapped string can go out
  226. * scope appropriately.
  227. */
  228. if(rs->wrapped) {
  229. rs->s=H5RS_xstrdup(rs->s);
  230. rs->wrapped=0;
  231. } /* end if */
  232. /* Increment reference count for string */
  233. rs->n++;
  234. FUNC_LEAVE_NOAPI(SUCCEED);
  235. } /* end H5RS_incr() */
  236. /*--------------------------------------------------------------------------
  237. NAME
  238. H5RS_dup
  239. PURPOSE
  240. "Duplicate" a ref-counted string
  241. USAGE
  242. H5RS_str_t H5RS_dup(rs)
  243. H5RS_str_t *rs; IN/OUT: Ref-counted string to "duplicate"
  244. RETURNS
  245. Returns a pointer to ref-counted string on success, NULL on failure.
  246. DESCRIPTION
  247. Increment the reference count for the reference counted string and return
  248. a pointer to it.
  249. GLOBAL VARIABLES
  250. COMMENTS, BUGS, ASSUMPTIONS
  251. EXAMPLES
  252. REVISION LOG
  253. --------------------------------------------------------------------------*/
  254. H5RS_str_t *
  255. H5RS_dup(H5RS_str_t *ret_value)
  256. {
  257. FUNC_ENTER_NOAPI_NOFUNC(H5RS_dup);
  258. /* Check for valid reference counted string */
  259. if(ret_value!=NULL)
  260. /* Increment reference count for string */
  261. ret_value->n++;
  262. FUNC_LEAVE_NOAPI(ret_value);
  263. } /* end H5RS_dup() */
  264. /*--------------------------------------------------------------------------
  265. NAME
  266. H5RS_dup_str
  267. PURPOSE
  268. "Duplicate" a regular string into a ref-counted string
  269. USAGE
  270. H5RS_str_t H5RS_dup_str(s)
  271. const char *s; IN: Regular string to duplicate
  272. RETURNS
  273. Returns a pointer to ref-counted string on success, NULL on failure.
  274. DESCRIPTION
  275. Duplicate a regular string into a ref-counted string.
  276. GLOBAL VARIABLES
  277. COMMENTS, BUGS, ASSUMPTIONS
  278. EXAMPLES
  279. REVISION LOG
  280. --------------------------------------------------------------------------*/
  281. H5RS_str_t *
  282. H5RS_dup_str(const char *s)
  283. {
  284. char *new_str = NULL; /* Duplicate of string */
  285. size_t path_len; /* Length of the path */
  286. H5RS_str_t *ret_value;
  287. FUNC_ENTER_NOAPI(H5RS_dup_str, NULL)
  288. /* Sanity check */
  289. HDassert(s);
  290. /* Get the length of the string */
  291. path_len = HDstrlen(s);
  292. /* Allocate space for the string */
  293. if(NULL == (new_str = (char *)H5FL_BLK_MALLOC(str_buf, path_len + 1)))
  294. HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
  295. /* Copy name for full path */
  296. HDstrcpy(new_str, s);
  297. /* Create reference counted string for path */
  298. ret_value = H5RS_own(new_str);
  299. done:
  300. FUNC_LEAVE_NOAPI(ret_value)
  301. } /* end H5RS_dup_str() */
  302. /*--------------------------------------------------------------------------
  303. NAME
  304. H5RS_cmp
  305. PURPOSE
  306. Compare two ref-counted strings
  307. USAGE
  308. int H5RS_cmp(rs1,rs2)
  309. const H5RS_str_t *rs1; IN: First Ref-counted string to compare
  310. const H5RS_str_t *rs2; IN: Second Ref-counted string to compare
  311. RETURNS
  312. Returns positive, negative or 0 for comparison of two r-strings [same as
  313. strcmp()]
  314. DESCRIPTION
  315. Compare two ref-counted strings and return a value indicating their sort
  316. order [same as strcmp()]
  317. GLOBAL VARIABLES
  318. COMMENTS, BUGS, ASSUMPTIONS
  319. EXAMPLES
  320. REVISION LOG
  321. --------------------------------------------------------------------------*/
  322. int
  323. H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
  324. {
  325. /* Can't return invalid value from this function */
  326. FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_cmp);
  327. /* Sanity check */
  328. assert(rs1);
  329. assert(rs1->s);
  330. assert(rs2);
  331. assert(rs2->s);
  332. FUNC_LEAVE_NOAPI(HDstrcmp(rs1->s,rs2->s));
  333. } /* end H5RS_cmp() */
  334. /*--------------------------------------------------------------------------
  335. NAME
  336. H5RS_len
  337. PURPOSE
  338. Compute the length of a ref-counted string
  339. USAGE
  340. ssize_t H5RS_cmp(rs)
  341. const H5RS_str_t *rs; IN: Ref-counted string to compute length of
  342. RETURNS
  343. Returns non-negative value on success, negative value on failure
  344. DESCRIPTION
  345. Compute the length of a ref-counted string. [same as strlen()]
  346. GLOBAL VARIABLES
  347. COMMENTS, BUGS, ASSUMPTIONS
  348. EXAMPLES
  349. REVISION LOG
  350. --------------------------------------------------------------------------*/
  351. ssize_t
  352. H5RS_len(const H5RS_str_t *rs)
  353. {
  354. FUNC_ENTER_NOAPI_NOFUNC(H5RS_len);
  355. /* Sanity check */
  356. assert(rs);
  357. assert(rs->s);
  358. FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s));
  359. } /* end H5RS_len() */
  360. /*--------------------------------------------------------------------------
  361. NAME
  362. H5RS_get_str
  363. PURPOSE
  364. Get a pointer to the internal string contained in a ref-counted string
  365. USAGE
  366. char *H5RS_get_str(rs)
  367. const H5RS_str_t *rs; IN: Ref-counted string to get internal string from
  368. RETURNS
  369. Returns a pointer to the internal string being ref-counted on success,
  370. NULL on failure.
  371. DESCRIPTION
  372. Gets a pointer to the internal string being reference counted. This
  373. pointer is volatile and might be invalid is further calls to the H5RS
  374. API are made.
  375. GLOBAL VARIABLES
  376. COMMENTS, BUGS, ASSUMPTIONS
  377. EXAMPLES
  378. REVISION LOG
  379. --------------------------------------------------------------------------*/
  380. char *
  381. H5RS_get_str(const H5RS_str_t *rs)
  382. {
  383. FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_str);
  384. /* Sanity check */
  385. assert(rs);
  386. assert(rs->s);
  387. FUNC_LEAVE_NOAPI(rs->s);
  388. } /* end H5RS_get_str() */
  389. /*--------------------------------------------------------------------------
  390. NAME
  391. H5RS_get_count
  392. PURPOSE
  393. Get the reference count for a ref-counted string
  394. USAGE
  395. unsigned H5RS_get_count(rs)
  396. const H5RS_str_t *rs; IN: Ref-counted string to get internal count from
  397. RETURNS
  398. Returns the number of references to the internal string being ref-counted on success,
  399. 0 on failure.
  400. DESCRIPTION
  401. Gets the count of references to the reference counted string.
  402. GLOBAL VARIABLES
  403. COMMENTS, BUGS, ASSUMPTIONS
  404. EXAMPLES
  405. REVISION LOG
  406. --------------------------------------------------------------------------*/
  407. unsigned
  408. H5RS_get_count(const H5RS_str_t *rs)
  409. {
  410. FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_count);
  411. /* Sanity check */
  412. assert(rs);
  413. assert(rs->n>0);
  414. FUNC_LEAVE_NOAPI(rs->n);
  415. } /* end H5RS_get_count() */