value.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* value.c - routines for dealing with values */
  42. #undef DEBUG /* disable counters */
  43. #include <prcountr.h>
  44. #include "slap.h"
  45. #include "slapi-private.h"
  46. /*
  47. * Functions needed when a berval is embedded in a struct or
  48. * allocated on the stack rather than the heap.
  49. */
  50. static void ber_bvdone(struct berval *bvp)
  51. {
  52. if (bvp == NULL) return;
  53. slapi_ch_free_string(&bvp->bv_val);
  54. bvp->bv_len = 0;
  55. return;
  56. }
  57. static void ber_bvcpy(struct berval *bvd, const struct berval *bvs)
  58. {
  59. size_t len;
  60. if (bvd == NULL || bvs == NULL) return;
  61. len = bvs->bv_len;
  62. bvd->bv_val = slapi_ch_malloc(len+1);
  63. bvd->bv_len = len;
  64. memcpy(bvd->bv_val, bvs->bv_val, len);
  65. bvd->bv_val[len] = '\0';
  66. return;
  67. }
  68. /* <=========================== Slapi_Value ==========================> */
  69. #ifdef VALUE_DEBUG
  70. static void value_dump( const Slapi_Value *value, const char *text);
  71. #define VALUE_DUMP(value,name) value_dump(value,name)
  72. #else
  73. #define VALUE_DUMP(value,name) ((void)0)
  74. #endif
  75. static int counters_created= 0;
  76. PR_DEFINE_COUNTER(slapi_value_counter_created);
  77. PR_DEFINE_COUNTER(slapi_value_counter_deleted);
  78. PR_DEFINE_COUNTER(slapi_value_counter_exist);
  79. Slapi_Value *
  80. slapi_value_new()
  81. {
  82. return value_new(NULL,CSN_TYPE_NONE,NULL);
  83. }
  84. Slapi_Value *
  85. slapi_value_new_berval(const struct berval *bval)
  86. {
  87. return value_new(bval,CSN_TYPE_NONE,NULL);
  88. }
  89. Slapi_Value *
  90. slapi_value_new_value(const Slapi_Value *v)
  91. {
  92. return slapi_value_dup(v);
  93. }
  94. Slapi_Value *
  95. slapi_value_new_string(const char *s)
  96. {
  97. Slapi_Value *v= value_new(NULL,CSN_TYPE_UNKNOWN,NULL);
  98. slapi_value_set_string(v, s);
  99. return v;
  100. }
  101. Slapi_Value *
  102. slapi_value_new_string_passin(char *s)
  103. {
  104. Slapi_Value *v= value_new(NULL,CSN_TYPE_UNKNOWN,NULL);
  105. slapi_value_set_string_passin(v, s);
  106. return v;
  107. }
  108. Slapi_Value *
  109. slapi_value_init(Slapi_Value *v)
  110. {
  111. return value_init(v,NULL,CSN_TYPE_NONE,NULL);
  112. }
  113. Slapi_Value *
  114. slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
  115. {
  116. return value_init(v,bval,CSN_TYPE_NONE,NULL);
  117. }
  118. Slapi_Value *
  119. slapi_value_init_string(Slapi_Value *v,const char *s)
  120. {
  121. value_init(v,NULL,CSN_TYPE_UNKNOWN,NULL);
  122. slapi_value_set_string(v,s);
  123. return v;
  124. }
  125. Slapi_Value *
  126. slapi_value_init_string_passin(Slapi_Value *v, char *s)
  127. {
  128. value_init(v,NULL,CSN_TYPE_UNKNOWN,NULL);
  129. slapi_value_set_string_passin(v,s);
  130. return v;
  131. }
  132. Slapi_Value *
  133. slapi_value_dup(const Slapi_Value *v)
  134. {
  135. Slapi_Value *newvalue= value_new(&v->bv,CSN_TYPE_UNKNOWN,NULL);
  136. newvalue->v_csnset= csnset_dup(v->v_csnset);
  137. return newvalue;
  138. }
  139. Slapi_Value *
  140. value_new(const struct berval *bval,CSNType t,const CSN *csn)
  141. {
  142. Slapi_Value *v;
  143. v = (Slapi_Value *)slapi_ch_malloc(sizeof(Slapi_Value));
  144. value_init(v, bval, t, csn);
  145. if(!counters_created)
  146. {
  147. PR_CREATE_COUNTER(slapi_value_counter_created,"Slapi_Value","created","");
  148. PR_CREATE_COUNTER(slapi_value_counter_deleted,"Slapi_Value","deleted","");
  149. PR_CREATE_COUNTER(slapi_value_counter_exist,"Slapi_Value","exist","");
  150. counters_created= 1;
  151. }
  152. PR_INCREMENT_COUNTER(slapi_value_counter_created);
  153. PR_INCREMENT_COUNTER(slapi_value_counter_exist);
  154. VALUE_DUMP(v,"value_new");
  155. return v;
  156. }
  157. Slapi_Value *
  158. value_init(Slapi_Value *v, const struct berval *bval,CSNType t,const CSN *csn)
  159. {
  160. PR_ASSERT(v!=NULL);
  161. memset(v,0,sizeof(Slapi_Value));
  162. if(csn!=NULL)
  163. {
  164. value_update_csn(v,t,csn);
  165. }
  166. slapi_value_set_berval(v,bval);
  167. return v;
  168. }
  169. void
  170. slapi_value_set_flags(Slapi_Value *v, unsigned long flags)
  171. {
  172. PR_ASSERT(v!=NULL);
  173. v->v_flags = flags;
  174. }
  175. void
  176. slapi_values_set_flags(Slapi_Value **vs, unsigned long flags)
  177. {
  178. PR_ASSERT(vs!=NULL);
  179. Slapi_Value **v;
  180. for (v = vs; v && *v; v++) {
  181. slapi_value_set_flags(*v, flags);
  182. }
  183. }
  184. unsigned long
  185. slapi_value_get_flags(Slapi_Value *v)
  186. {
  187. PR_ASSERT(v!=NULL);
  188. return v->v_flags;
  189. }
  190. void
  191. slapi_value_free(Slapi_Value **v)
  192. {
  193. if(v!=NULL && *v!=NULL)
  194. {
  195. VALUE_DUMP(*v,"value_free");
  196. value_done(*v);
  197. slapi_ch_free((void **)v);
  198. *v= NULL;
  199. PR_INCREMENT_COUNTER(slapi_value_counter_deleted);
  200. PR_DECREMENT_COUNTER(slapi_value_counter_exist);
  201. }
  202. }
  203. void
  204. value_done(Slapi_Value *v)
  205. {
  206. if(v!=NULL)
  207. {
  208. if(NULL != v->v_csnset)
  209. {
  210. csnset_free(&(v->v_csnset));
  211. }
  212. ber_bvdone(&v->bv);
  213. }
  214. }
  215. const CSNSet *
  216. value_get_csnset ( const Slapi_Value *value)
  217. {
  218. if (value)
  219. return value->v_csnset;
  220. else
  221. return NULL;
  222. }
  223. const CSN *
  224. value_get_csn( const Slapi_Value *value, CSNType t)
  225. {
  226. const CSN *csn= NULL;
  227. if(NULL!=value)
  228. {
  229. csn= csnset_get_csn_of_type(value->v_csnset, t);
  230. }
  231. return csn;
  232. }
  233. int
  234. value_contains_csn( const Slapi_Value *value, CSN *csn)
  235. {
  236. int r= 0;
  237. if(NULL!=value)
  238. {
  239. r= csnset_contains(value->v_csnset, csn);
  240. }
  241. return r;
  242. }
  243. Slapi_Value *
  244. value_update_csn( Slapi_Value *value, CSNType t, const CSN *csn)
  245. {
  246. if(value!=NULL)
  247. {
  248. csnset_update_csn(&value->v_csnset,t,csn);
  249. }
  250. return value;
  251. }
  252. Slapi_Value *
  253. value_add_csn( Slapi_Value *value, CSNType t, const CSN *csn)
  254. {
  255. if(value!=NULL)
  256. {
  257. csnset_add_csn(&value->v_csnset,t,csn);
  258. }
  259. return value;
  260. }
  261. const struct berval *
  262. slapi_value_get_berval( const Slapi_Value *value )
  263. {
  264. const struct berval *bval= NULL;
  265. if(NULL != value)
  266. {
  267. bval = &value->bv;
  268. }
  269. return bval;
  270. }
  271. Slapi_Value *
  272. slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
  273. {
  274. struct berval bv;
  275. bv.bv_len= len;
  276. bv.bv_val= (void*)val; /* We cast away the const, but we're not going to change anything */
  277. slapi_value_set_berval( value, &bv);
  278. return value;
  279. }
  280. Slapi_Value *
  281. slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
  282. {
  283. slapi_value_set_berval( value, &vfrom->bv );
  284. csnset_free(&value->v_csnset);
  285. value->v_csnset= csnset_dup(vfrom->v_csnset);
  286. return value;
  287. }
  288. Slapi_Value *
  289. value_remove_csn( Slapi_Value *value, CSNType t)
  290. {
  291. if(value!=NULL)
  292. {
  293. csnset_remove_csn(&value->v_csnset,t);
  294. }
  295. return value;
  296. }
  297. Slapi_Value *
  298. slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
  299. {
  300. if(value!=NULL)
  301. {
  302. ber_bvdone(&value->bv);
  303. if(bval!=NULL)
  304. {
  305. ber_bvcpy(&value->bv, bval);
  306. }
  307. }
  308. return value;
  309. }
  310. int
  311. slapi_value_set_string(Slapi_Value *value, const char *strVal)
  312. {
  313. return slapi_value_set_string_passin(value, slapi_ch_strdup(strVal));
  314. }
  315. int
  316. slapi_value_set_string_passin(Slapi_Value *value, char *strVal)
  317. {
  318. int rc= -1;
  319. if(NULL != value)
  320. {
  321. ber_bvdone(&value->bv);
  322. value->bv.bv_val = strVal;
  323. value->bv.bv_len = strlen(strVal);
  324. rc= 0;
  325. }
  326. return rc;
  327. }
  328. int
  329. slapi_value_set_int(Slapi_Value *value, int intVal)
  330. {
  331. int rc= -1;
  332. if(NULL != value)
  333. {
  334. char valueBuf[80];
  335. ber_bvdone(&value->bv);
  336. sprintf(valueBuf,"%d",intVal);
  337. value->bv.bv_val = slapi_ch_strdup(valueBuf);
  338. value->bv.bv_len = strlen(value->bv.bv_val);
  339. rc= 0;
  340. }
  341. return rc;
  342. }
  343. /*
  344. * Warning: The value may not be '\0' terminated!
  345. * Make sure that you know this is a C string.
  346. */
  347. const char *
  348. slapi_value_get_string(const Slapi_Value *value)
  349. {
  350. const char *r= NULL;
  351. if(value!=NULL)
  352. {
  353. r= (const char*)value->bv.bv_val;
  354. }
  355. return r;
  356. }
  357. size_t
  358. slapi_value_get_length(const Slapi_Value *value)
  359. {
  360. size_t r= 0;
  361. if(NULL!=value)
  362. {
  363. r= value->bv.bv_len;
  364. }
  365. return r;
  366. }
  367. int
  368. slapi_value_get_int(const Slapi_Value *value)
  369. {
  370. int r= 0;
  371. if(NULL!=value)
  372. {
  373. char *p;
  374. p = slapi_ch_malloc(value->bv.bv_len + 1);
  375. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  376. p [value->bv.bv_len] = '\0';
  377. r= atoi(p);
  378. slapi_ch_free((void **)&p);
  379. }
  380. return r;
  381. }
  382. unsigned int
  383. slapi_value_get_uint(const Slapi_Value *value)
  384. {
  385. unsigned int r= 0;
  386. if(NULL!=value)
  387. {
  388. char *p;
  389. p = slapi_ch_malloc(value->bv.bv_len + 1);
  390. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  391. p [value->bv.bv_len] = '\0';
  392. r= (unsigned int)atoi(p);
  393. slapi_ch_free((void **)&p);
  394. }
  395. return r;
  396. }
  397. long
  398. slapi_value_get_long(const Slapi_Value *value)
  399. {
  400. long r= 0;
  401. if(NULL!=value)
  402. {
  403. char *p;
  404. p = slapi_ch_malloc(value->bv.bv_len + 1);
  405. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  406. p [value->bv.bv_len] = '\0';
  407. r = atol(p);
  408. slapi_ch_free((void **)&p);
  409. }
  410. return r;
  411. }
  412. unsigned long
  413. slapi_value_get_ulong(const Slapi_Value *value)
  414. {
  415. unsigned long r= 0;
  416. if(NULL!=value)
  417. {
  418. char *p;
  419. p = slapi_ch_malloc(value->bv.bv_len + 1);
  420. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  421. p [value->bv.bv_len] = '\0';
  422. r = (unsigned long)atol(p);
  423. slapi_ch_free((void **)&p);
  424. }
  425. return r;
  426. }
  427. long long
  428. slapi_value_get_longlong(const Slapi_Value *value)
  429. {
  430. long long r= 0;
  431. if(NULL!=value)
  432. {
  433. char *p;
  434. p = slapi_ch_malloc(value->bv.bv_len + 1);
  435. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  436. p [value->bv.bv_len] = '\0';
  437. r = strtoll(p, (char **)NULL, 0);
  438. slapi_ch_free((void **)&p);
  439. }
  440. return r;
  441. }
  442. unsigned long long
  443. slapi_value_get_ulonglong(const Slapi_Value *value)
  444. {
  445. unsigned long long r= 0;
  446. if(NULL!=value)
  447. {
  448. char *p;
  449. p = slapi_ch_malloc(value->bv.bv_len + 1);
  450. memcpy (p, value->bv.bv_val, value->bv.bv_len);
  451. p [value->bv.bv_len] = '\0';
  452. r = strtoull(p, (char **)NULL, 0);
  453. slapi_ch_free((void **)&p);
  454. }
  455. return r;
  456. }
  457. int
  458. slapi_value_compare(const Slapi_Attr *a,const Slapi_Value *v1,const Slapi_Value *v2)
  459. {
  460. int r= 0;
  461. if(v1!=NULL && v2!=NULL)
  462. {
  463. r= slapi_attr_value_cmp( a, &v1->bv, &v2->bv);
  464. }
  465. else if(v1!=NULL && v2==NULL)
  466. {
  467. r= 1; /* v1>v2 */
  468. }
  469. else if (v1==NULL && v2!=NULL)
  470. {
  471. r= -1; /* v1<v2 */
  472. }
  473. else /* (v1==NULL && v2==NULL) */
  474. {
  475. r= 0; /* The same */
  476. }
  477. return r;
  478. }
  479. size_t
  480. value_size(const Slapi_Value *v)
  481. {
  482. size_t s= v->bv.bv_len;
  483. s += csnset_size(v->v_csnset);
  484. s += sizeof(Slapi_Value);
  485. return s;
  486. }
  487. #ifdef VALUE_DEBUG
  488. static void
  489. value_dump( const Slapi_Value *value, const char *text)
  490. {
  491. LDAPDebug( LDAP_DEBUG_ANY, "Slapi_Value %s ptr=%lx\n", text, value, 0);
  492. /* JCM - Dump value contents... */
  493. }
  494. #endif