13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/* $Id$ */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @file
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * IPRT - ASN.1, Basic Operations.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Copyright (C) 2006-2014 Oracle Corporation
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * available from http://www.virtualbox.org. This file is free software;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * General Public License (GPL) as published by the Free Software
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The contents of this file may alternatively be used under the terms
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * of the Common Development and Distribution License Version 1.0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * CDDL are applicable instead of those of the GPL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * You may elect to license modified versions of this file under the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * terms and conditions of either the GPL or the CDDL or both.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Header Files *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "internal/iprt.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/alloca.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/bignum.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/ctype.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/err.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/string.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/uni.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/formats/asn1.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Structures and Typedefs *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 content/value allocation.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The currently most frequent use of the RTAsn1 module is to decode ASN.1 byte
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * streams. In that scenario we do not allocate memory for the raw content
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * bytes, but share it with the byte stream. Also, a great number of RTASN1CORE
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * structures will never need to have any content bytes allocated with this.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * So, in order to avoid adding an extra 16 (64-bit) or 8 (32-bit) bytes to each
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * RTASN1CORE structure just to keep track of the occational content allocation,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * we put the allocator tracking structure inside the allocation. During
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * allocator operations it lives temporarily on the stack.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef struct RTASN1MEMCONTENT
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The allocation tracker. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1ALLOCATION Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#if ARCH_BITS == 32
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t Padding; /**< Alignment padding. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#endif
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The content bytes, i.e. what RTASN1CORE::uData.pv points to. Use a 64-bit
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * type here to emphasize that it's 8-byte aligned on all platforms. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint64_t au64Content[1];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync} RTASN1MEMCONTENT;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncAssertCompileMemberAlignment(RTASN1MEMCONTENT, au64Content, 8);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** Pointer to a ASN.1 content allocation. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef RTASN1MEMCONTENT *PRTASN1MEMCONTENT;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cCurrent, uint32_t cNew)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cbEntry > 0, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cNew > cCurrent, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cNew < _1M, VERR_OUT_OF_RANGE);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->cReallocs++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync void *pvOld = *ppvArray;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Initial allocation? */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cCurrent == 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pvOld == NULL, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cNew != 0, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync size_t cbNew = cNew * cbEntry;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAllocation->cbAllocated < cbNew)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Need to grow. Adjust the new size according to how many times we've been called. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAllocation->cReallocs > 2)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAllocation->cReallocs > 8)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cNew += 8;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (pAllocation->cReallocs < 4)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cNew += 2;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cNew += 4;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync cbNew += cNew * cbEntry;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pAllocation->cbAllocated >= cbNew);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Clear the memory. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync size_t cbOld = cCurrent * cbEntry;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_BZERO((uint8_t *)*ppvArray + cbOld, pAllocation->cbAllocated - cbOld);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1MemAllocZ(PRTASN1ALLOCATION pAllocation, void **ppvMem, size_t cbMem)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(ppvMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(cbMem > 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvMem, cbMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pAllocation->cbAllocated >= cbMem || RT_FAILURE_NP(rc));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1MemDup(PRTASN1ALLOCATION pAllocation, void **ppvMem, const void *pvSrc, size_t cbMem)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(ppvMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pvSrc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(cbMem > 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvMem, cbMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pAllocation->cbAllocated >= cbMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(*ppvMem, pvSrc, cbMem);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(void) RTAsn1MemFree(PRTASN1ALLOCATION pAllocation, void *pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pAllocation->pAllocator != NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->pAllocator->pfnFree(pAllocation->pAllocator, pAllocation, pv);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pAllocation->cbAllocated == 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(PRTASN1ALLOCATION) RTAsn1MemInitAllocation(PRTASN1ALLOCATION pAllocation, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->cbAllocated = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->cReallocs = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->uReserved0 = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAllocation->pAllocator = pAllocator;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pAllocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1ContentAllocZ(PRTASN1CORE pAsn1Core, size_t cb, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAllocator != NULL, VERR_WRONG_ORDER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cb > 0 && cb < _1G, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pAsn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(!(pAsn1Core->fFlags & RTASN1CORE_F_ALLOCATED_CONTENT), VERR_INVALID_STATE);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Initialize the temporary allocation tracker. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1ALLOCATION Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.cbAllocated = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.cReallocs = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.uReserved0 = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.pAllocator = pAllocator;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Make the allocation. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbAlloc = RT_OFFSETOF(RTASN1MEMCONTENT, au64Content) + (uint32_t)cb;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1MEMCONTENT pHdr;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAllocator->pfnAlloc(pAllocator, &Allocation, (void **)&pHdr, cbAlloc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(Allocation.cbAllocated >= cbAlloc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pHdr->Allocation = Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->cb = (uint32_t)cb;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->uData.pv = &pHdr->au64Content[0];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->fFlags |= RTASN1CORE_F_ALLOCATED_CONTENT;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1ContentDup(PRTASN1CORE pAsn1Core, void const *pvSrc, size_t cbSrc, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1ContentAllocZ(pAsn1Core, cbSrc, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy((void *)pAsn1Core->uData.pv, pvSrc, cbSrc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1ContentReallocZ(PRTASN1CORE pAsn1Core, size_t cb, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Validate input. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pAsn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cb < _1G, VERR_INVALID_PARAMETER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cb > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Case 1 - Initial allocation.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbNeeded = RT_OFFSETOF(RTASN1MEMCONTENT, au64Content) + (uint32_t)cb;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!(pAsn1Core->fFlags & RTASN1CORE_F_ALLOCATED_CONTENT))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1ContentAllocZ(pAsn1Core, cb, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Locate the header. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1MEMCONTENT pHdr = RT_FROM_MEMBER(pAsn1Core->uData.pv, RTASN1MEMCONTENT, au64Content);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Case 2 - Reallocation using the same allocator.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pHdr->Allocation.pAllocator == pAllocator
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync || !pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pHdr->Allocation.cReallocs++;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Modify the allocation if necessary. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pHdr->Allocation.cbAllocated < cbNeeded)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1ALLOCATION Allocation = pHdr->Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = Allocation.pAllocator->pfnRealloc(Allocation.pAllocator, &Allocation, pHdr, (void **)&pHdr, cbNeeded);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(Allocation.cbAllocated >= cbNeeded);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->uData.pv = &pHdr->au64Content[0];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pHdr->Allocation = Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Clear any additional memory we're letting the user use and
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync update the content size. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core->cb < cb)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_BZERO((uint8_t *)&pAsn1Core->uData.pu8[pAsn1Core->cb], cb - pAsn1Core->cb);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->cb = (uint32_t)cb;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Case 3 - Reallocation using a different allocator.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Initialize the temporary allocation tracker. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1ALLOCATION Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.cbAllocated = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.cReallocs = pHdr->Allocation.cReallocs + 1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.uReserved0 = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.pAllocator = pAllocator;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Make the allocation. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1MEMCONTENT pHdrNew;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAllocator->pfnAlloc(pAllocator, &Allocation, (void **)&pHdrNew, cbNeeded);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(Allocation.cbAllocated >= cbNeeded);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Duplicate the old content and zero any new memory we might've added. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core->cb >= cb)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(&pHdrNew->au64Content[0], &pHdr->au64Content[0], cb);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(&pHdrNew->au64Content[0], &pHdr->au64Content[0], pAsn1Core->cb);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_BZERO((uint8_t *)&pHdrNew->au64Content[0] + pAsn1Core->cb, cb - pAsn1Core->cb);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Update the core. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pHdrNew->Allocation = Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->uData.pv = &pHdrNew->au64Content[0];
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->fFlags |= RTASN1CORE_F_ALLOCATED_CONTENT; /* free cleared it. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->cb = (uint32_t)cb;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Free the old content. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation = pHdr->Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.pAllocator->pfnFree(Allocation.pAllocator, &Allocation, pHdr);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(Allocation.cbAllocated == 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Case 4 - It's a request to free the memory.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1ContentFree(pAsn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(void) RTAsn1ContentFree(PRTASN1CORE pAsn1Core)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->cb = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core->fFlags & RTASN1CORE_F_ALLOCATED_CONTENT)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->fFlags &= ~RTASN1CORE_F_ALLOCATED_CONTENT;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturnVoid(pAsn1Core->uData.pv);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1MEMCONTENT pHdr = RT_FROM_MEMBER(pAsn1Core->uData.pv, RTASN1MEMCONTENT, au64Content);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1ALLOCATION Allocation = pHdr->Allocation;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Allocation.pAllocator->pfnFree(Allocation.pAllocator, &Allocation, pHdr);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(Allocation.cbAllocated == 0);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pAsn1Core->uData.pv = NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Virtual method table based API.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(void) RTAsn1VtDelete(PRTASN1CORE pAsn1Core)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1COREVTABLE pOps = pAsn1Core->pOps;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pOps)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pOps->pfnDtor(pAsn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/**
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Context data passed by RTAsn1VtDeepEnum to it's worker callbacks.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef struct RTASN1DEEPENUMCTX
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PFNRTASN1ENUMCALLBACK pfnCallback;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync void *pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync} RTASN1DEEPENUMCTX;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) rtAsn1VtDeepEnumDepthFirst(PRTASN1CORE pAsn1Core, const char *pszName, uint32_t uDepth, void *pvUser)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAsn1Core, VINF_SUCCESS);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core->pOps && pAsn1Core->pOps->pfnEnum)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pAsn1Core->pOps->pfnEnum(pAsn1Core, rtAsn1VtDeepEnumDepthFirst, uDepth, pvUser);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (rc != VINF_SUCCESS)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1DEEPENUMCTX *pCtx = (RTASN1DEEPENUMCTX *)pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pCtx->pfnCallback(pAsn1Core, pszName, uDepth, pCtx->pvUser);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) rtAsn1VtDeepEnumDepthLast(PRTASN1CORE pAsn1Core, const char *pszName, uint32_t uDepth, void *pvUser)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pAsn1Core, VINF_SUCCESS);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1DEEPENUMCTX *pCtx = (RTASN1DEEPENUMCTX *)pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = pCtx->pfnCallback(pAsn1Core, pszName, uDepth, pCtx->pvUser);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (rc == VINF_SUCCESS)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pAsn1Core->pOps && pAsn1Core->pOps->pfnEnum)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = pAsn1Core->pOps->pfnEnum(pAsn1Core, rtAsn1VtDeepEnumDepthFirst, uDepth, pvUser);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1VtDeepEnum(PRTASN1CORE pThisCore, bool fDepthFirst, uint32_t uDepth,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PFNRTASN1ENUMCALLBACK pfnCallback, void *pvUser)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1Core_IsPresent(pThisCore))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1COREVTABLE pOps = pThisCore->pOps;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pOps && pOps->pfnEnum)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1DEEPENUMCTX Ctx;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.pfnCallback = pfnCallback;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.pvUser = pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = pOps->pfnEnum(pThisCore, fDepthFirst ? rtAsn1VtDeepEnumDepthFirst : rtAsn1VtDeepEnumDepthLast, uDepth, &Ctx);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1VtClone(PRTASN1CORE pThisCore, PRTASN1CORE pSrcCore, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtrReturn(pThisCore, VERR_INVALID_POINTER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtrReturn(pSrcCore, VERR_INVALID_POINTER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtrReturn(pAllocator, VERR_INVALID_POINTER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1Core_IsPresent(pSrcCore))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtrReturn(pSrcCore->pOps, VERR_INVALID_POINTER);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pSrcCore->pOps->pfnClone);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pSrcCore->pOps->pfnClone(pThisCore, pSrcCore, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(*pThisCore);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1VtCompare(PCRTASN1CORE pLeftCore, PCRTASN1CORE pRightCore)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int iDiff;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1Core_IsPresent(pLeftCore))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1Core_IsPresent(pRightCore))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1COREVTABLE pOps = pLeftCore->pOps;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pOps == pRightCore->pOps)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pOps->pfnCompare);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = pOps->pfnCompare(pLeftCore, pRightCore);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = (uintptr_t)pOps < (uintptr_t)pRightCore->pOps ? -1 : 1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = 1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = 0 - (int)RTAsn1Core_IsPresent(pRightCore);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return iDiff;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1VtCheckSanity(PCRTASN1CORE pThisCore, uint32_t fFlags,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTERRINFO pErrInfo, const char *pszErrorTag)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1Core_IsPresent(pThisCore))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1COREVTABLE pOps = pThisCore->pOps;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pOps && pOps->pfnCheckSanity)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = pOps->pfnCheckSanity(pThisCore, fFlags, pErrInfo, pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else if (pOps)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTErrInfoSetF(pErrInfo, VERR_ASN1_NO_CHECK_SANITY_METHOD,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "%s: Has no pfnCheckSanity function.", pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTErrInfoSetF(pErrInfo, VERR_ASN1_NO_VTABLE, "%s: Has no Vtable function.", pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTErrInfoSetF(pErrInfo, VERR_ASN1_NOT_PRESENT, "%s: Not present.", pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Dummy ASN.1 object.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1Dummy_InitEx(PRTASN1DUMMY pThis)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync UINT32_MAX,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_PRIVATE | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync NULL,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_DUMMY);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 SEQUENCE OF object.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SeqOfCore_Init(PRTASN1SEQOFCORE pThis, PCRTASN1COREVTABLE pVtable)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAG_SEQUENCE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pVtable,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_PRESENT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SeqOfCore_Clone(PRTASN1SEQOFCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SEQOFCORE pSrc)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pSrc->Asn1Core.pOps == pVtable, VERR_ASN1_INTERNAL_ERROR_5);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 SET OF object.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SetOfCore_Init(PRTASN1SETOFCORE pThis, PCRTASN1COREVTABLE pVtable)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAG_SET,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pVtable,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_PRESENT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SetOfCore_Clone(PRTASN1SETOFCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SETOFCORE pSrc)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pSrc->Asn1Core.pOps == pVtable, VERR_ASN1_INTERNAL_ERROR_5);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 SEQUENCE object.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SequenceCore_Init(PRTASN1SEQUENCECORE pThis, PCRTASN1COREVTABLE pVtable)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAG_SEQUENCE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pVtable,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_PRESENT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SequenceCore_Clone(PRTASN1SEQUENCECORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SEQUENCECORE pSrc)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pSrc->Asn1Core.pOps == pVtable, VERR_ASN1_INTERNAL_ERROR_5);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 SEQUENCE object - only used by SPC, so probably doing something wrong there.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SetCore_Init(PRTASN1SETCORE pThis, PCRTASN1COREVTABLE pVtable)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAG_SET,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pVtable,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_PRESENT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1SetCore_Clone(PRTASN1SETCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SETCORE pSrc)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pSrc->Asn1Core.pOps == pVtable, VERR_ASN1_INTERNAL_ERROR_5);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 Context Tag object.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1ContextTagN_Init(PRTASN1CONTEXTTAG pThis, uint32_t uTag)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_InitEx(&pThis->Asn1Core,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uTag,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync NULL,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1CORE_F_PRESENT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1ContextTagN_Clone(PRTASN1CONTEXTTAG pThis, PCRTASN1CONTEXTTAG pSrc, uint32_t uTag)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pSrc->Asn1Core.uTag == uTag || !RTASN1CORE_IS_PRESENT(&pSrc->Asn1Core));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync