1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef BASE_H
6 #define BASE_H
7 
8 /*
9  * base.h
10  *
11  * This header file contains basic prototypes and preprocessor
12  * definitions used throughout nss but not available publicly.
13  */
14 
15 #ifndef BASET_H
16 #include "baset.h"
17 #endif /* BASET_H */
18 
19 #ifndef NSSBASE_H
20 #include "nssbase.h"
21 #endif /* NSSBASE_H */
22 
23 #include "plhash.h"
24 
25 PR_BEGIN_EXTERN_C
26 
27 /*
28  * NSSArena
29  *
30  * The nonpublic methods relating to this type are:
31  *
32  *  nssArena_Create  -- constructor
33  *  nssArena_Destroy
34  *  nssArena_Mark
35  *  nssArena_Release
36  *  nssArena_Unmark
37  *
38  *  nss_ZAlloc
39  *  nss_ZFreeIf
40  *  nss_ZRealloc
41  *
42  * Additionally, there are some preprocessor macros:
43  *
44  *  nss_ZNEW
45  *  nss_ZNEWARRAY
46  *
47  * In debug builds, the following calls are available:
48  *
49  *  nssArena_verifyPointer
50  *  nssArena_registerDestructor
51  *  nssArena_deregisterDestructor
52  *
53  * The following preprocessor macro is also always available:
54  *
55  *  nssArena_VERIFYPOINTER
56  *
57  * A constant PLHashAllocOps structure is available for users
58  * of the NSPL PLHashTable routines.
59  *
60  *  nssArenaHashAllocOps
61  */
62 
63 /*
64  * nssArena_Create
65  *
66  * This routine creates a new memory arena.  This routine may return
67  * NULL upon error, in which case it will have set an error on the
68  * error stack.
69  *
70  * The error may be one of the following values:
71  *  NSS_ERROR_NO_MEMORY
72  *
73  * Return value:
74  *  NULL upon error
75  *  A pointer to an NSSArena upon success
76  */
77 
78 /*
79  * XXX fgmr
80  * Arenas can be named upon creation; this is mostly of use when
81  * debugging.  Should we expose that here, allowing an optional
82  * "const char *name" argument?  Should the public version of this
83  * call (NSSArena_Create) have it too?
84  */
85 
86 NSS_EXTERN NSSArena *nssArena_Create(void);
87 
88 extern const NSSError NSS_ERROR_NO_MEMORY;
89 
90 /*
91  * nssArena_Destroy
92  *
93  * This routine will destroy the specified arena, freeing all memory
94  * allocated from it.  This routine returns a PRStatus value; if
95  * successful, it will return PR_SUCCESS.  If unsuccessful, it will
96  * set an error on the error stack and return PR_FAILURE.
97  *
98  * The error may be one of the following values:
99  *  NSS_ERROR_INVALID_ARENA
100  *
101  * Return value:
102  *  PR_SUCCESS
103  *  PR_FAILURE
104  */
105 
106 NSS_EXTERN PRStatus nssArena_Destroy(NSSArena *arena);
107 
108 extern const NSSError NSS_ERROR_INVALID_ARENA;
109 
110 /*
111  * nssArena_Mark
112  *
113  * This routine "marks" the current state of an arena.  Space
114  * allocated after the arena has been marked can be freed by
115  * releasing the arena back to the mark with nssArena_Release,
116  * or committed by calling nssArena_Unmark.  When successful,
117  * this routine returns a valid nssArenaMark pointer.  This
118  * routine may return NULL upon error, in which case it will
119  * have set an error on the error stack.
120  *
121  * The error may be one of the following values:
122  *  NSS_ERROR_INVALID_ARENA
123  *  NSS_ERROR_NO_MEMORY
124  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
125  *
126  * Return value:
127  *  NULL upon failure
128  *  An nssArenaMark pointer upon success
129  */
130 
131 NSS_EXTERN nssArenaMark *nssArena_Mark(NSSArena *arena);
132 
133 extern const NSSError NSS_ERROR_INVALID_ARENA;
134 extern const NSSError NSS_ERROR_NO_MEMORY;
135 extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
136 
137 /*
138  * nssArena_Release
139  *
140  * This routine invalidates and releases all memory allocated from
141  * the specified arena after the point at which the specified mark
142  * was obtained.  This routine returns a PRStatus value; if successful,
143  * it will return PR_SUCCESS.  If unsuccessful, it will set an error
144  * on the error stack and return PR_FAILURE.
145  *
146  * The error may be one of the following values:
147  *  NSS_ERROR_INVALID_ARENA
148  *  NSS_ERROR_INVALID_ARENA_MARK
149  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
150  *
151  * Return value:
152  *  PR_SUCCESS
153  *  PR_FAILURE
154  */
155 
156 NSS_EXTERN PRStatus nssArena_Release(NSSArena *arena, nssArenaMark *arenaMark);
157 
158 extern const NSSError NSS_ERROR_INVALID_ARENA;
159 extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
160 
161 /*
162  * nssArena_Unmark
163  *
164  * This routine "commits" the indicated mark and any marks after
165  * it, making them unreleasable.  Note that any earlier marks can
166  * still be released, and such a release will invalidate these
167  * later unmarked regions.  If an arena is to be safely shared by
168  * more than one thread, all marks must be either released or
169  * unmarked.  This routine returns a PRStatus value; if successful,
170  * it will return PR_SUCCESS.  If unsuccessful, it will set an error
171  * on the error stack and return PR_FAILURE.
172  *
173  * The error may be one of the following values:
174  *  NSS_ERROR_INVALID_ARENA
175  *  NSS_ERROR_INVALID_ARENA_MARK
176  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
177  *
178  * Return value:
179  *  PR_SUCCESS
180  *  PR_FAILURE
181  */
182 
183 NSS_EXTERN PRStatus nssArena_Unmark(NSSArena *arena, nssArenaMark *arenaMark);
184 
185 extern const NSSError NSS_ERROR_INVALID_ARENA;
186 extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
187 extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
188 
189 #ifdef ARENA_DESTRUCTOR_LIST
190 
191 /*
192  * nssArena_registerDestructor
193  *
194  * This routine stores a pointer to a callback and an arbitrary
195  * pointer-sized argument in the arena, at the current point in
196  * the mark stack.  If the arena is destroyed, or an "earlier"
197  * mark is released, then this destructor will be called at that
198  * time.  Note that the destructor will be called with the arena
199  * locked, which means the destructor may free memory in that
200  * arena, but it may not allocate or cause to be allocated any
201  * memory.  This callback facility was included to support our
202  * debug-version pointer-tracker feature; overuse runs counter to
203  * the the original intent of arenas.  This routine returns a
204  * PRStatus value; if successful, it will return PR_SUCCESS.  If
205  * unsuccessful, it will set an error on the error stack and
206  * return PR_FAILURE.
207  *
208  * The error may be one of the following values:
209  *  NSS_ERROR_INVALID_ARENA
210  *  NSS_ERROR_NO_MEMORY
211  *
212  * Return value:
213  *  PR_SUCCESS
214  *  PR_FAILURE
215  */
216 
217 NSS_EXTERN PRStatus nssArena_registerDestructor(
218     NSSArena *arena, void (*destructor)(void *argument), void *arg);
219 
220 extern const NSSError NSS_ERROR_INVALID_ARENA;
221 extern const NSSError NSS_ERROR_NO_MEMORY;
222 
223 /*
224  * nssArena_deregisterDestructor
225  *
226  * This routine will remove the first destructor in the specified
227  * arena which has the specified destructor and argument values.
228  * The destructor will not be called.  This routine returns a
229  * PRStatus value; if successful, it will return PR_SUCCESS.  If
230  * unsuccessful, it will set an error on the error stack and
231  * return PR_FAILURE.
232  *
233  * The error may be one of the following values:
234  *  NSS_ERROR_INVALID_ARENA
235  *  NSS_ERROR_NOT_FOUND
236  *
237  * Return value:
238  *  PR_SUCCESS
239  *  PR_FAILURE
240  */
241 
242 NSS_EXTERN PRStatus nssArena_deregisterDestructor(
243     NSSArena *arena, void (*destructor)(void *argument), void *arg);
244 
245 extern const NSSError NSS_ERROR_INVALID_ITEM;
246 extern const NSSError NSS_ERROR_INVALID_ARENA;
247 extern const NSSError NSS_ERROR_NOT_FOUND;
248 
249 #endif /* ARENA_DESTRUCTOR_LIST */
250 
251 /*
252  * nss_ZAlloc
253  *
254  * This routine allocates and zeroes a section of memory of the
255  * size, and returns to the caller a pointer to that memory.  If
256  * the optional arena argument is non-null, the memory will be
257  * obtained from that arena; otherwise, the memory will be obtained
258  * from the heap.  This routine may return NULL upon error, in
259  * which case it will have set an error upon the error stack.  The
260  * value specified for size may be zero; in which case a valid
261  * zero-length block of memory will be allocated.  This block may
262  * be expanded by calling nss_ZRealloc.
263  *
264  * The error may be one of the following values:
265  *  NSS_ERROR_INVALID_ARENA
266  *  NSS_ERROR_NO_MEMORY
267  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
268  *
269  * Return value:
270  *  NULL upon error
271  *  A pointer to the new segment of zeroed memory
272  */
273 
274 NSS_EXTERN void *nss_ZAlloc(NSSArena *arenaOpt, PRUint32 size);
275 
276 extern const NSSError NSS_ERROR_INVALID_ARENA;
277 extern const NSSError NSS_ERROR_NO_MEMORY;
278 extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
279 
280 /*
281  * nss_ZFreeIf
282  *
283  * If the specified pointer is non-null, then the region of memory
284  * to which it points -- which must have been allocated with
285  * nss_ZAlloc -- will be zeroed and released.  This routine
286  * returns a PRStatus value; if successful, it will return PR_SUCCESS.
287  * If unsuccessful, it will set an error on the error stack and return
288  * PR_FAILURE.
289  *
290  * The error may be one of the following values:
291  *  NSS_ERROR_INVALID_POINTER
292  *
293  * Return value:
294  *  PR_SUCCESS
295  *  PR_FAILURE
296  */
297 
298 NSS_EXTERN PRStatus nss_ZFreeIf(void *pointer);
299 
300 extern const NSSError NSS_ERROR_INVALID_POINTER;
301 
302 /*
303  * nss_ZRealloc
304  *
305  * This routine reallocates a block of memory obtained by calling
306  * nss_ZAlloc or nss_ZRealloc.  The portion of memory
307  * between the new and old sizes -- which is either being newly
308  * obtained or released -- is in either case zeroed.  This routine
309  * may return NULL upon failure, in which case it will have placed
310  * an error on the error stack.
311  *
312  * The error may be one of the following values:
313  *  NSS_ERROR_INVALID_POINTER
314  *  NSS_ERROR_NO_MEMORY
315  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
316  *
317  * Return value:
318  *  NULL upon error
319  *  A pointer to the replacement segment of memory
320  */
321 
322 NSS_EXTERN void *nss_ZRealloc(void *pointer, PRUint32 newSize);
323 
324 extern const NSSError NSS_ERROR_INVALID_POINTER;
325 extern const NSSError NSS_ERROR_NO_MEMORY;
326 extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
327 
328 /*
329  * nss_ZNEW
330  *
331  * This preprocessor macro will allocate memory for a new object
332  * of the specified type with nss_ZAlloc, and will cast the
333  * return value appropriately.  If the optional arena argument is
334  * non-null, the memory will be obtained from that arena; otherwise,
335  * the memory will be obtained from the heap.  This routine may
336  * return NULL upon error, in which case it will have set an error
337  * upon the error stack.
338  *
339  * The error may be one of the following values:
340  *  NSS_ERROR_INVALID_ARENA
341  *  NSS_ERROR_NO_MEMORY
342  *
343  * Return value:
344  *  NULL upon error
345  *  A pointer to the new segment of zeroed memory
346  */
347 
348 #define nss_ZNEW(arenaOpt, type) ((type *)nss_ZAlloc((arenaOpt), sizeof(type)))
349 
350 /*
351  * nss_ZNEWARRAY
352  *
353  * This preprocessor macro will allocate memory for an array of
354  * new objects, and will cast the return value appropriately.
355  * If the optional arena argument is non-null, the memory will
356  * be obtained from that arena; otherwise, the memory will be
357  * obtained from the heap.  This routine may return NULL upon
358  * error, in which case it will have set an error upon the error
359  * stack.  The array size may be specified as zero.
360  *
361  * The error may be one of the following values:
362  *  NSS_ERROR_INVALID_ARENA
363  *  NSS_ERROR_NO_MEMORY
364  *
365  * Return value:
366  *  NULL upon error
367  *  A pointer to the new segment of zeroed memory
368  */
369 
370 #define nss_ZNEWARRAY(arenaOpt, type, quantity) \
371     ((type *)nss_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
372 
373 /*
374  * nss_ZREALLOCARRAY
375  *
376  * This preprocessor macro will reallocate memory for an array of
377  * new objects, and will cast the return value appropriately.
378  * This routine may return NULL upon error, in which case it will
379  *  have set an error upon the error stack.
380  *
381  * The error may be one of the following values:
382  *  NSS_ERROR_INVALID_POINTER
383  *  NSS_ERROR_NO_MEMORY
384  *  NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
385  *
386  * Return value:
387  *  NULL upon error
388  *  A pointer to the replacement segment of memory
389  */
390 #define nss_ZREALLOCARRAY(p, type, quantity) \
391     ((type *)nss_ZRealloc((p), sizeof(type) * (quantity)))
392 
393 /*
394  * nssArena_verifyPointer
395  *
396  * This method is only present in debug builds.
397  *
398  * If the specified pointer is a valid pointer to an NSSArena object,
399  * this routine will return PR_SUCCESS.  Otherwise, it will put an
400  * error on the error stack and return PR_FAILURE.
401  *
402  * The error may be one of the following values:
403  *  NSS_ERROR_INVALID_ARENA
404  *
405  * Return value:
406  *  PR_SUCCESS if the pointer is valid
407  *  PR_FAILURE if it isn't
408  */
409 
410 #ifdef DEBUG
411 NSS_EXTERN PRStatus nssArena_verifyPointer(const NSSArena *arena);
412 
413 extern const NSSError NSS_ERROR_INVALID_ARENA;
414 #endif /* DEBUG */
415 
416 /*
417  * nssArena_VERIFYPOINTER
418  *
419  * This macro is always available.  In debug builds it will call
420  * nssArena_verifyPointer; in non-debug builds, it will merely
421  * check that the pointer is not null.  Note that in non-debug
422  * builds it cannot place an error on the error stack.
423  *
424  * Return value:
425  *  PR_SUCCESS if the pointer is valid
426  *  PR_FAILURE if it isn't
427  */
428 
429 #ifdef DEBUG
430 #define nssArena_VERIFYPOINTER(p) nssArena_verifyPointer(p)
431 #else /* DEBUG */
432 
433 #define nssArena_VERIFYPOINTER(p) \
434     (((NSSArena *)NULL == (p)) ? PR_FAILURE : PR_SUCCESS)
435 #endif /* DEBUG */
436 
437 /*
438  * Private function to be called by NSS_Shutdown to cleanup nssArena
439  * bookkeeping.
440  */
441 extern PRStatus nssArena_Shutdown(void);
442 
443 /*
444  * nssArenaHashAllocOps
445  *
446  * This constant structure contains allocation callbacks designed for
447  * use with the NSPL routine PL_NewHashTable.  For example:
448  *
449  *  NSSArena *hashTableArena = nssArena_Create();
450  *  PLHashTable *t = PL_NewHashTable(n, hasher, key_compare,
451  *    value_compare, nssArenaHashAllocOps, hashTableArena);
452  */
453 
454 NSS_EXTERN_DATA PLHashAllocOps nssArenaHashAllocOps;
455 
456 /*
457  * The error stack
458  *
459  * The nonpublic methods relating to the error stack are:
460  *
461  *  nss_SetError
462  *  nss_ClearErrorStack
463  */
464 
465 /*
466  * nss_SetError
467  *
468  * This routine places a new error code on the top of the calling
469  * thread's error stack.  Calling this routine wiht an error code
470  * of zero will clear the error stack.
471  */
472 
473 NSS_EXTERN void nss_SetError(PRUint32 error);
474 
475 /*
476  * nss_ClearErrorStack
477  *
478  * This routine clears the calling thread's error stack.
479  */
480 
481 NSS_EXTERN void nss_ClearErrorStack(void);
482 
483 /*
484  * nss_DestroyErrorStack
485  *
486  * This routine frees the calling thread's error stack.
487  */
488 
489 NSS_EXTERN void nss_DestroyErrorStack(void);
490 
491 /*
492  * NSSItem
493  *
494  * nssItem_Create
495  * nssItem_Duplicate
496  * nssItem_Equal
497  */
498 
499 NSS_EXTERN NSSItem *nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt,
500                                    PRUint32 length, const void *data);
501 
502 NSS_EXTERN void nssItem_Destroy(NSSItem *item);
503 
504 NSS_EXTERN NSSItem *nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt,
505                                       NSSItem *rvOpt);
506 
507 NSS_EXTERN PRBool nssItem_Equal(const NSSItem *one, const NSSItem *two,
508                                 PRStatus *statusOpt);
509 
510 /*
511  * NSSUTF8
512  *
513  *  nssUTF8_CaseIgnoreMatch
514  *  nssUTF8_Duplicate
515  *  nssUTF8_Size
516  *  nssUTF8_Length
517  *  nssUTF8_CopyIntoFixedBuffer
518  */
519 
520 /*
521  * nssUTF8_CaseIgnoreMatch
522  *
523  * Returns true if the two UTF8-encoded strings pointed to by the
524  * two specified NSSUTF8 pointers differ only in typcase.
525  *
526  * The error may be one of the following values:
527  *  NSS_ERROR_INVALID_POINTER
528  *
529  * Return value:
530  *  PR_TRUE if the strings match, ignoring case
531  *  PR_FALSE if they don't
532  *  PR_FALSE upon error
533  */
534 
535 NSS_EXTERN PRBool nssUTF8_CaseIgnoreMatch(const NSSUTF8 *a, const NSSUTF8 *b,
536                                           PRStatus *statusOpt);
537 
538 /*
539  * nssUTF8_Duplicate
540  *
541  * This routine duplicates the UTF8-encoded string pointed to by the
542  * specified NSSUTF8 pointer.  If the optional arenaOpt argument is
543  * not null, the memory required will be obtained from that arena;
544  * otherwise, the memory required will be obtained from the heap.
545  * A pointer to the new string will be returned.  In case of error,
546  * an error will be placed on the error stack and NULL will be
547  * returned.
548  *
549  * The error may be one of the following values:
550  *  NSS_ERROR_INVALID_POINTER
551  *  NSS_ERROR_INVALID_ARENA
552  *  NSS_ERROR_NO_MEMORY
553  */
554 
555 NSS_EXTERN NSSUTF8 *nssUTF8_Duplicate(const NSSUTF8 *s, NSSArena *arenaOpt);
556 
557 /*
558  * nssUTF8_PrintableMatch
559  *
560  * Returns true if the two Printable strings pointed to by the
561  * two specified NSSUTF8 pointers match when compared with the
562  * rules for Printable String (leading and trailing spaces are
563  * disregarded, extents of whitespace match irregardless of length,
564  * and case is not significant), then PR_TRUE will be returned.
565  * Otherwise, PR_FALSE will be returned.  Upon failure, PR_FALSE
566  * will be returned.  If the optional statusOpt argument is not
567  * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that
568  * location.
569  *
570  * The error may be one of the following values:
571  *  NSS_ERROR_INVALID_POINTER
572  *
573  * Return value:
574  *  PR_TRUE if the strings match, ignoring case
575  *  PR_FALSE if they don't
576  *  PR_FALSE upon error
577  */
578 
579 NSS_EXTERN PRBool nssUTF8_PrintableMatch(const NSSUTF8 *a, const NSSUTF8 *b,
580                                          PRStatus *statusOpt);
581 
582 /*
583  * nssUTF8_Size
584  *
585  * This routine returns the length in bytes (including the terminating
586  * null) of the UTF8-encoded string pointed to by the specified
587  * NSSUTF8 pointer.  Zero is returned on error.
588  *
589  * The error may be one of the following values:
590  *  NSS_ERROR_INVALID_POINTER
591  *  NSS_ERROR_VALUE_TOO_LARGE
592  *
593  * Return value:
594  *  nonzero size of the string
595  *  0 on error
596  */
597 
598 NSS_EXTERN PRUint32 nssUTF8_Size(const NSSUTF8 *s, PRStatus *statusOpt);
599 
600 extern const NSSError NSS_ERROR_INVALID_POINTER;
601 extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
602 
603 /*
604  * nssUTF8_Length
605  *
606  * This routine returns the length in characters (not including the
607  * terminating null) of the UTF8-encoded string pointed to by the
608  * specified NSSUTF8 pointer.
609  *
610  * The error may be one of the following values:
611  *  NSS_ERROR_INVALID_POINTER
612  *  NSS_ERROR_VALUE_TOO_LARGE
613  *  NSS_ERROR_INVALID_STRING
614  *
615  * Return value:
616  *  length of the string (which may be zero)
617  *  0 on error
618  */
619 
620 NSS_EXTERN PRUint32 nssUTF8_Length(const NSSUTF8 *s, PRStatus *statusOpt);
621 
622 extern const NSSError NSS_ERROR_INVALID_POINTER;
623 extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
624 extern const NSSError NSS_ERROR_INVALID_STRING;
625 
626 /*
627  * nssUTF8_Create
628  *
629  * This routine creates a UTF8 string from a string in some other
630  * format.  Some types of string may include embedded null characters,
631  * so for them the length parameter must be used.  For string types
632  * that are null-terminated, the length parameter is optional; if it
633  * is zero, it will be ignored.  If the optional arena argument is
634  * non-null, the memory used for the new string will be obtained from
635  * that arena, otherwise it will be obtained from the heap.  This
636  * routine may return NULL upon error, in which case it will have
637  * placed an error on the error stack.
638  *
639  * The error may be one of the following:
640  *  NSS_ERROR_INVALID_POINTER
641  *  NSS_ERROR_NO_MEMORY
642  *  NSS_ERROR_UNSUPPORTED_TYPE
643  *
644  * Return value:
645  *  NULL upon error
646  *  A non-null pointer to a new UTF8 string otherwise
647  */
648 
649 NSS_EXTERN NSSUTF8 *nssUTF8_Create(NSSArena *arenaOpt, nssStringType type,
650                                    const void *inputString,
651                                    PRUint32 size /* in bytes, not characters */
652                                    );
653 
654 extern const NSSError NSS_ERROR_INVALID_POINTER;
655 extern const NSSError NSS_ERROR_NO_MEMORY;
656 extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE;
657 
658 NSS_EXTERN NSSItem *nssUTF8_GetEncoding(NSSArena *arenaOpt, NSSItem *rvOpt,
659                                         nssStringType type, NSSUTF8 *string);
660 
661 /*
662  * nssUTF8_CopyIntoFixedBuffer
663  *
664  * This will copy a UTF8 string into a fixed-length buffer, making
665  * sure that the all characters are valid.  Any remaining space will
666  * be padded with the specified ASCII character, typically either
667  * null or space.
668  *
669  * Blah, blah, blah.
670  */
671 
672 extern const NSSError NSS_ERROR_INVALID_POINTER;
673 extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
674 
675 NSS_EXTERN PRStatus nssUTF8_CopyIntoFixedBuffer(NSSUTF8 *string, char *buffer,
676                                                 PRUint32 bufferSize, char pad);
677 
678 /*
679  * nssUTF8_Equal
680  *
681  */
682 
683 NSS_EXTERN PRBool nssUTF8_Equal(const NSSUTF8 *a, const NSSUTF8 *b,
684                                 PRStatus *statusOpt);
685 
686 /*
687  * nssList
688  *
689  * The goal is to provide a simple, optionally threadsafe, linked list
690  * class.  Since NSS did not seem to use the circularity of PRCList
691  * much before, this provides a list that appears to be a linear,
692  * NULL-terminated list.
693  */
694 
695 /*
696  * nssList_Create
697  *
698  * If threadsafe is true, the list will be locked during modifications
699  * and traversals.
700  */
701 NSS_EXTERN nssList *nssList_Create(NSSArena *arenaOpt, PRBool threadSafe);
702 
703 /*
704  * nssList_Destroy
705  */
706 NSS_EXTERN PRStatus nssList_Destroy(nssList *list);
707 
708 NSS_EXTERN void nssList_Clear(nssList *list,
709                               nssListElementDestructorFunc destructor);
710 
711 /*
712  * nssList_SetCompareFunction
713  *
714  * By default, two list elements will be compared by comparing their
715  * data pointers.  By setting this function, the user can control
716  * how elements are compared.
717  */
718 NSS_EXTERN void nssList_SetCompareFunction(nssList *list,
719                                            nssListCompareFunc compareFunc);
720 
721 /*
722  * nssList_SetSortFunction
723  *
724  * Sort function to use for an ordered list.
725  */
726 NSS_EXTERN void nssList_SetSortFunction(nssList *list,
727                                         nssListSortFunc sortFunc);
728 
729 /*
730  * nssList_Add
731  */
732 NSS_EXTERN PRStatus nssList_Add(nssList *list, void *data);
733 
734 /*
735  * nssList_AddUnique
736  *
737  * This will use the compare function to see if the element is already
738  * in the list.
739  */
740 NSS_EXTERN PRStatus nssList_AddUnique(nssList *list, void *data);
741 
742 /*
743  * nssList_Remove
744  *
745  * Uses the compare function to locate the element and remove it.
746  */
747 NSS_EXTERN PRStatus nssList_Remove(nssList *list, void *data);
748 
749 /*
750  * nssList_Get
751  *
752  * Uses the compare function to locate an element.  Also serves as
753  * nssList_Exists.
754  */
755 NSS_EXTERN void *nssList_Get(nssList *list, void *data);
756 
757 /*
758  * nssList_Count
759  */
760 NSS_EXTERN PRUint32 nssList_Count(nssList *list);
761 
762 /*
763  * nssList_GetArray
764  *
765  * Fill rvArray, up to maxElements, with elements in the list.  The
766  * array is NULL-terminated, so its allocated size must be maxElements + 1.
767  */
768 NSS_EXTERN PRStatus nssList_GetArray(nssList *list, void **rvArray,
769                                      PRUint32 maxElements);
770 
771 /*
772  * nssList_CreateIterator
773  *
774  * Create an iterator for list traversal.
775  */
776 NSS_EXTERN nssListIterator *nssList_CreateIterator(nssList *list);
777 
778 NSS_EXTERN nssList *nssList_Clone(nssList *list);
779 
780 /*
781  * nssListIterator_Destroy
782  */
783 NSS_EXTERN void nssListIterator_Destroy(nssListIterator *iter);
784 
785 /*
786  * nssListIterator_Start
787  *
788  * Begin a list iteration.  After this call, if the list is threadSafe,
789  * the list is *locked*.
790  */
791 NSS_EXTERN void *nssListIterator_Start(nssListIterator *iter);
792 
793 /*
794  * nssListIterator_Next
795  *
796  * Continue a list iteration.
797  */
798 NSS_EXTERN void *nssListIterator_Next(nssListIterator *iter);
799 
800 /*
801  * nssListIterator_Finish
802  *
803  * Complete a list iteration.  This *must* be called in order for the
804  * lock to be released.
805  */
806 NSS_EXTERN PRStatus nssListIterator_Finish(nssListIterator *iter);
807 
808 /*
809  * nssHash
810  *
811  *  nssHash_Create
812  *  nssHash_Destroy
813  *  nssHash_Add
814  *  nssHash_Remove
815  *  nssHash_Count
816  *  nssHash_Exists
817  *  nssHash_Lookup
818  *  nssHash_Iterate
819  */
820 
821 /*
822  * nssHash_Create
823  *
824  */
825 
826 NSS_EXTERN nssHash *nssHash_Create(NSSArena *arenaOpt, PRUint32 numBuckets,
827                                    PLHashFunction keyHash,
828                                    PLHashComparator keyCompare,
829                                    PLHashComparator valueCompare);
830 
831 NSS_EXTERN nssHash *nssHash_CreatePointer(NSSArena *arenaOpt,
832                                           PRUint32 numBuckets);
833 
834 NSS_EXTERN nssHash *nssHash_CreateString(NSSArena *arenaOpt,
835                                          PRUint32 numBuckets);
836 
837 NSS_EXTERN nssHash *nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets);
838 
839 /*
840  * nssHash_Destroy
841  *
842  */
843 NSS_EXTERN void nssHash_Destroy(nssHash *hash);
844 
845 /*
846  * nssHash_Add
847  *
848  */
849 
850 extern const NSSError NSS_ERROR_HASH_COLLISION;
851 
852 NSS_EXTERN PRStatus nssHash_Add(nssHash *hash, const void *key,
853                                 const void *value);
854 
855 /*
856  * nssHash_Remove
857  *
858  */
859 NSS_EXTERN void nssHash_Remove(nssHash *hash, const void *it);
860 
861 /*
862  * nssHash_Count
863  *
864  */
865 NSS_EXTERN PRUint32 nssHash_Count(nssHash *hash);
866 
867 /*
868  * nssHash_Exists
869  *
870  */
871 NSS_EXTERN PRBool nssHash_Exists(nssHash *hash, const void *it);
872 
873 /*
874  * nssHash_Lookup
875  *
876  */
877 NSS_EXTERN void *nssHash_Lookup(nssHash *hash, const void *it);
878 
879 /*
880  * nssHash_Iterate
881  *
882  */
883 NSS_EXTERN void nssHash_Iterate(nssHash *hash, nssHashIterator fcn,
884                                 void *closure);
885 
886 /*
887  * nssPointerTracker
888  *
889  * This type and these methods are only present in debug builds.
890  *
891  * The nonpublic methods relating to this type are:
892  *
893  *  nssPointerTracker_initialize
894  *  nssPointerTracker_finalize
895  *  nssPointerTracker_add
896  *  nssPointerTracker_remove
897  *  nssPointerTracker_verify
898  */
899 
900 /*
901  * nssPointerTracker_initialize
902  *
903  * This method is only present in debug builds.
904  *
905  * This routine initializes an nssPointerTracker object.  Note that
906  * the object must have been declared *static* to guarantee that it
907  * is in a zeroed state initially.  This routine is idempotent, and
908  * may even be safely called by multiple threads simultaneously with
909  * the same argument.  This routine returns a PRStatus value; if
910  * successful, it will return PR_SUCCESS.  On failure it will set an
911  * error on the error stack and return PR_FAILURE.
912  *
913  * The error may be one of the following values:
914  *  NSS_ERROR_NO_MEMORY
915  *
916  * Return value:
917  *  PR_SUCCESS
918  *  PR_FAILURE
919  */
920 
921 #ifdef DEBUG
922 NSS_EXTERN PRStatus nssPointerTracker_initialize(nssPointerTracker *tracker);
923 
924 extern const NSSError NSS_ERROR_NO_MEMORY;
925 #endif /* DEBUG */
926 
927 /*
928  * nssPointerTracker_finalize
929  *
930  * This method is only present in debug builds.
931  *
932  * This routine returns the nssPointerTracker object to the pre-
933  * initialized state, releasing all resources used by the object.
934  * It will *NOT* destroy the objects being tracked by the pointer
935  * (should any remain), and therefore cannot be used to "sweep up"
936  * remaining objects.  This routine returns a PRStatus value; if
937  * successful, it will return PR_SUCCES.  On failure it will set an
938  * error on the error stack and return PR_FAILURE.  If any objects
939  * remain in the tracker when it is finalized, that will be treated
940  * as an error.
941  *
942  * The error may be one of the following values:
943  *  NSS_ERROR_TRACKER_NOT_EMPTY
944  *
945  * Return value:
946  *  PR_SUCCESS
947  *  PR_FAILURE
948  */
949 
950 #ifdef DEBUG
951 NSS_EXTERN PRStatus nssPointerTracker_finalize(nssPointerTracker *tracker);
952 
953 extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
954 #endif /* DEBUG */
955 
956 /*
957  * nssPointerTracker_add
958  *
959  * This method is only present in debug builds.
960  *
961  * This routine adds the specified pointer to the nssPointerTracker
962  * object.  It should be called in constructor objects to register
963  * new valid objects.  The nssPointerTracker is threadsafe, but this
964  * call is not idempotent.  This routine returns a PRStatus value;
965  * if successful it will return PR_SUCCESS.  On failure it will set
966  * an error on the error stack and return PR_FAILURE.
967  *
968  * The error may be one of the following values:
969  *  NSS_ERROR_NO_MEMORY
970  *  NSS_ERROR_TRACKER_NOT_INITIALIZED
971  *  NSS_ERROR_DUPLICATE_POINTER
972  *
973  * Return value:
974  *  PR_SUCCESS
975  *  PR_FAILURE
976  */
977 
978 #ifdef DEBUG
979 NSS_EXTERN PRStatus nssPointerTracker_add(nssPointerTracker *tracker,
980                                           const void *pointer);
981 
982 extern const NSSError NSS_ERROR_NO_MEMORY;
983 extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
984 extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
985 #endif /* DEBUG */
986 
987 /*
988  * nssPointerTracker_remove
989  *
990  * This method is only present in debug builds.
991  *
992  * This routine removes the specified pointer from the
993  * nssPointerTracker object.  It does not call any destructor for the
994  * object; rather, this should be called from the object's destructor.
995  * The nssPointerTracker is threadsafe, but this call is not
996  * idempotent.  This routine returns a PRStatus value; if successful
997  * it will return PR_SUCCESS.  On failure it will set an error on the
998  * error stack and return PR_FAILURE.
999  *
1000  * The error may be one of the following values:
1001  *  NSS_ERROR_TRACKER_NOT_INITIALIZED
1002  *  NSS_ERROR_POINTER_NOT_REGISTERED
1003  *
1004  * Return value:
1005  *  PR_SUCCESS
1006  *  PR_FAILURE
1007  */
1008 
1009 #ifdef DEBUG
1010 NSS_EXTERN PRStatus nssPointerTracker_remove(nssPointerTracker *tracker,
1011                                              const void *pointer);
1012 
1013 extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
1014 extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
1015 #endif /* DEBUG */
1016 
1017 /*
1018  * nssPointerTracker_verify
1019  *
1020  * This method is only present in debug builds.
1021  *
1022  * This routine verifies that the specified pointer has been registered
1023  * with the nssPointerTracker object.  The nssPointerTracker object is
1024  * threadsafe, and this call may be safely called from multiple threads
1025  * simultaneously with the same arguments.  This routine returns a
1026  * PRStatus value; if the pointer is registered this will return
1027  * PR_SUCCESS.  Otherwise it will set an error on the error stack and
1028  * return PR_FAILURE.  Although the error is suitable for leaving on
1029  * the stack, callers may wish to augment the information available by
1030  * placing a more type-specific error on the stack.
1031  *
1032  * The error may be one of the following values:
1033  *  NSS_ERROR_POINTER_NOT_REGISTERED
1034  *
1035  * Return value:
1036  *  PR_SUCCESS
1037  *  PR_FAILRUE
1038  */
1039 
1040 #ifdef DEBUG
1041 NSS_EXTERN PRStatus nssPointerTracker_verify(nssPointerTracker *tracker,
1042                                              const void *pointer);
1043 
1044 extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
1045 #endif /* DEBUG */
1046 
1047 /*
1048  * libc
1049  *
1050  * nsslibc_memcpy
1051  * nsslibc_memset
1052  * nsslibc_offsetof
1053  */
1054 
1055 /*
1056  * nsslibc_memcpy
1057  *
1058  * Errors:
1059  *  NSS_ERROR_INVALID_POINTER
1060  *
1061  * Return value:
1062  *  NULL on error
1063  *  The destination pointer on success
1064  */
1065 
1066 NSS_EXTERN void *nsslibc_memcpy(void *dest, const void *source, PRUint32 n);
1067 
1068 extern const NSSError NSS_ERROR_INVALID_POINTER;
1069 
1070 /*
1071  * nsslibc_memset
1072  *
1073  * Errors:
1074  *  NSS_ERROR_INVALID_POINTER
1075  *
1076  * Return value:
1077  *  NULL on error
1078  *  The destination pointer on success
1079  */
1080 
1081 NSS_EXTERN void *nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n);
1082 
1083 extern const NSSError NSS_ERROR_INVALID_POINTER;
1084 
1085 /*
1086  * nsslibc_memequal
1087  *
1088  * Errors:
1089  *  NSS_ERROR_INVALID_POINTER
1090  *
1091  * Return value:
1092  *  PR_TRUE if they match
1093  *  PR_FALSE if they don't
1094  *  PR_FALSE upon error
1095  */
1096 
1097 NSS_EXTERN PRBool nsslibc_memequal(const void *a, const void *b, PRUint32 len,
1098                                    PRStatus *statusOpt);
1099 
1100 extern const NSSError NSS_ERROR_INVALID_POINTER;
1101 
1102 #define nsslibc_offsetof(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
1103 
1104 PR_END_EXTERN_C
1105 
1106 #endif /* BASE_H */
1107