summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/base/item.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--security/nss/lib/base/item.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/security/nss/lib/base/item.c b/security/nss/lib/base/item.c
new file mode 100644
index 0000000000..a1bb802ed6
--- /dev/null
+++ b/security/nss/lib/base/item.c
@@ -0,0 +1,186 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * item.c
+ *
+ * This contains some item-manipulation code.
+ */
+
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
+
+/*
+ * nssItem_Create
+ *
+ * -- fgmr comments --
+ *
+ * The error may be one of the following values:
+ * NSS_ERROR_INVALID_ARENA
+ * NSS_ERROR_NO_MEMORY
+ * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
+ * NSS_ERROR_INVALID_POINTER
+ *
+ * Return value:
+ * A pointer to an NSSItem upon success
+ * NULL upon failure
+ */
+
+NSS_IMPLEMENT NSSItem *
+nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length,
+ const void *data)
+{
+ NSSItem *rv = (NSSItem *)NULL;
+
+#ifdef DEBUG
+ if ((NSSArena *)NULL != arenaOpt) {
+ if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
+ return (NSSItem *)NULL;
+ }
+ }
+
+ if ((const void *)NULL == data) {
+ if (length > 0) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ return (NSSItem *)NULL;
+ }
+ }
+#endif /* DEBUG */
+
+ if ((NSSItem *)NULL == rvOpt) {
+ rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
+ if ((NSSItem *)NULL == rv) {
+ goto loser;
+ }
+ } else {
+ rv = rvOpt;
+ }
+
+ rv->size = length;
+ rv->data = nss_ZAlloc(arenaOpt, length);
+ if ((void *)NULL == rv->data) {
+ goto loser;
+ }
+
+ if (length > 0) {
+ (void)nsslibc_memcpy(rv->data, data, length);
+ }
+
+ return rv;
+
+loser:
+ if (rv != rvOpt) {
+ nss_ZFreeIf(rv);
+ }
+
+ return (NSSItem *)NULL;
+}
+
+NSS_IMPLEMENT void
+nssItem_Destroy(NSSItem *item)
+{
+ nss_ClearErrorStack();
+
+ nss_ZFreeIf(item->data);
+ nss_ZFreeIf(item);
+}
+
+/*
+ * nssItem_Duplicate
+ *
+ * -- fgmr comments --
+ *
+ * The error may be one of the following values:
+ * NSS_ERROR_INVALID_ARENA
+ * NSS_ERROR_NO_MEMORY
+ * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
+ * NSS_ERROR_INVALID_ITEM
+ *
+ * Return value:
+ * A pointer to an NSSItem upon success
+ * NULL upon failure
+ */
+
+NSS_IMPLEMENT NSSItem *
+nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt)
+{
+#ifdef DEBUG
+ if ((NSSArena *)NULL != arenaOpt) {
+ if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
+ return (NSSItem *)NULL;
+ }
+ }
+
+ if ((NSSItem *)NULL == obj) {
+ nss_SetError(NSS_ERROR_INVALID_ITEM);
+ return (NSSItem *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
+}
+
+#ifdef DEBUG
+/*
+ * nssItem_verifyPointer
+ *
+ * -- fgmr comments --
+ *
+ * The error may be one of the following values:
+ * NSS_ERROR_INVALID_ITEM
+ *
+ * Return value:
+ * PR_SUCCESS upon success
+ * PR_FAILURE upon failure
+ */
+
+NSS_IMPLEMENT PRStatus
+nssItem_verifyPointer(const NSSItem *item)
+{
+ if (((const NSSItem *)NULL == item) ||
+ (((void *)NULL == item->data) && (item->size > 0))) {
+ nss_SetError(NSS_ERROR_INVALID_ITEM);
+ return PR_FAILURE;
+ }
+
+ return PR_SUCCESS;
+}
+#endif /* DEBUG */
+
+/*
+ * nssItem_Equal
+ *
+ * -- fgmr comments --
+ *
+ * The error may be one of the following values:
+ * NSS_ERROR_INVALID_ITEM
+ *
+ * Return value:
+ * PR_TRUE if the items are identical
+ * PR_FALSE if they aren't
+ * PR_FALSE upon error
+ */
+
+NSS_IMPLEMENT PRBool
+nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt)
+{
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
+
+ if (((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two)) {
+ return PR_TRUE;
+ }
+
+ if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) {
+ return PR_FALSE;
+ }
+
+ if (one->size != two->size) {
+ return PR_FALSE;
+ }
+
+ return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
+}