/* $Id$ */
/** @file
* IPRT - ASN.1, Basic Operations.
*/
/*
* Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
*
* The currently most frequent use of the RTAsn1 module is to decode ASN.1 byte
* streams. In that scenario we do not allocate memory for the raw content
* bytes, but share it with the byte stream. Also, a great number of RTASN1CORE
* structures will never need to have any content bytes allocated with this.
*
* So, in order to avoid adding an extra 16 (64-bit) or 8 (32-bit) bytes to each
* RTASN1CORE structure just to keep track of the occational content allocation,
* we put the allocator tracking structure inside the allocation. During
* allocator operations it lives temporarily on the stack.
*/
typedef struct RTASN1MEMCONTENT
{
/** The allocation tracker. */
#if ARCH_BITS == 32
#endif
/** The content bytes, i.e. what RTASN1CORE::uData.pv points to. Use a 64-bit
* type here to emphasize that it's 8-byte aligned on all platforms. */
/** Pointer to a ASN.1 content allocation. */
{
pAllocation->cReallocs++;
/* Initial allocation? */
if (cCurrent == 0)
{
return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry);
}
/* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */
{
/* Need to grow. Adjust the new size according to how many times we've been called. */
{
cNew += 8;
cNew += 2;
else
cNew += 4;
}
int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew);
if (RT_FAILURE(rc))
return rc;
/* Clear the memory. */
}
return VINF_SUCCESS;
}
{
return rc;
}
RTDECL(int) RTAsn1MemDup(PRTASN1ALLOCATION pAllocation, void **ppvMem, const void *pvSrc, size_t cbMem)
{
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
return rc;
}
{
if (pv)
{
}
}
RTDECL(PRTASN1ALLOCATION) RTAsn1MemInitAllocation(PRTASN1ALLOCATION pAllocation, PCRTASN1ALLOCATORVTABLE pAllocator)
{
pAllocation->cbAllocated = 0;
pAllocation->cReallocs = 0;
pAllocation->uReserved0 = 0;
return pAllocation;
}
RTDECL(int) RTAsn1ContentAllocZ(PRTASN1CORE pAsn1Core, size_t cb, PCRTASN1ALLOCATORVTABLE pAllocator)
{
/* Initialize the temporary allocation tracker. */
Allocation.cbAllocated = 0;
Allocation.cReallocs = 0;
Allocation.uReserved0 = 0;
/* Make the allocation. */
if (RT_SUCCESS(rc))
{
}
return rc;
}
RTDECL(int) RTAsn1ContentDup(PRTASN1CORE pAsn1Core, void const *pvSrc, size_t cbSrc, PCRTASN1ALLOCATORVTABLE pAllocator)
{
if (RT_SUCCESS(rc))
return rc;
}
RTDECL(int) RTAsn1ContentReallocZ(PRTASN1CORE pAsn1Core, size_t cb, PCRTASN1ALLOCATORVTABLE pAllocator)
{
/* Validate input. */
if (cb > 0)
{
/*
* Case 1 - Initial allocation.
*/
/* Locate the header. */
/*
* Case 2 - Reallocation using the same allocator.
*/
|| !pAllocator)
{
/* Modify the allocation if necessary. */
{
int rc = Allocation.pAllocator->pfnRealloc(Allocation.pAllocator, &Allocation, pHdr, (void **)&pHdr, cbNeeded);
if (RT_FAILURE(rc))
return rc;
}
/* Clear any additional memory we're letting the user use and
update the content size. */
}
/*
* Case 3 - Reallocation using a different allocator.
*/
else
{
/* Initialize the temporary allocation tracker. */
Allocation.cbAllocated = 0;
Allocation.uReserved0 = 0;
/* Make the allocation. */
if (RT_FAILURE(rc))
return rc;
/* Duplicate the old content and zero any new memory we might've added. */
else
{
}
/* Update the core. */
/* Free the old content. */
}
}
/*
* Case 4 - It's a request to free the memory.
*/
else
return VINF_SUCCESS;
}
{
if (pAsn1Core)
{
{
}
}
}
/*
* Virtual method table based API.
*/
{
if (pAsn1Core)
{
if (pOps)
}
}
/**
* Context data passed by RTAsn1VtDeepEnum to it's worker callbacks.
*/
typedef struct RTASN1DEEPENUMCTX
{
void *pvUser;
static DECLCALLBACK(int) rtAsn1VtDeepEnumDepthFirst(PRTASN1CORE pAsn1Core, const char *pszName, uint32_t uDepth, void *pvUser)
{
{
if (rc != VINF_SUCCESS)
return rc;
}
}
static DECLCALLBACK(int) rtAsn1VtDeepEnumDepthLast(PRTASN1CORE pAsn1Core, const char *pszName, uint32_t uDepth, void *pvUser)
{
if (rc == VINF_SUCCESS)
{
}
return rc;
}
{
int rc;
{
{
rc = pOps->pfnEnum(pThisCore, fDepthFirst ? rtAsn1VtDeepEnumDepthFirst : rtAsn1VtDeepEnumDepthLast, uDepth, &Ctx);
}
else
rc = VINF_SUCCESS;
}
else
rc = VINF_SUCCESS;
return rc;
}
RTDECL(int) RTAsn1VtClone(PRTASN1CORE pThisCore, PRTASN1CORE pSrcCore, PCRTASN1ALLOCATORVTABLE pAllocator)
{
if (RTAsn1Core_IsPresent(pSrcCore))
{
}
return VINF_SUCCESS;
}
{
int iDiff;
{
{
{
}
else
}
else
iDiff = 1;
}
else
return iDiff;
}
{
int rc;
{
else if (pOps)
"%s: Has no pfnCheckSanity function.", pszErrorTag);
else
}
else
return rc;
}
/*
* Dummy ASN.1 object.
*/
{
NULL,
}
/*
* ASN.1 SEQUENCE OF object.
*/
{
}
RTDECL(int) RTAsn1SeqOfCore_Clone(PRTASN1SEQOFCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SEQOFCORE pSrc)
{
}
/*
* ASN.1 SET OF object.
*/
{
}
RTDECL(int) RTAsn1SetOfCore_Clone(PRTASN1SETOFCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SETOFCORE pSrc)
{
}
/*
* ASN.1 SEQUENCE object.
*/
{
}
RTDECL(int) RTAsn1SequenceCore_Clone(PRTASN1SEQUENCECORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SEQUENCECORE pSrc)
{
}
/*
* ASN.1 SEQUENCE object - only used by SPC, so probably doing something wrong there.
*/
{
}
RTDECL(int) RTAsn1SetCore_Clone(PRTASN1SETCORE pThis, PCRTASN1COREVTABLE pVtable, PCRTASN1SETCORE pSrc)
{
}
/*
* ASN.1 Context Tag object.
*/
{
uTag,
NULL,
}
RTDECL(int) RTAsn1ContextTagN_Clone(PRTASN1CONTEXTTAG pThis, PCRTASN1CONTEXTTAG pSrc, uint32_t uTag)
{
}