tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

base.h (30796B)


      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 */