manifest2.cpp revision d012a89a724ba60c4fb5e74ce51f8b404fda4a8c
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * IPRT - Manifest, the core.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Copyright (C) 2010 Oracle Corporation
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * available from http://www.virtualbox.org. This file is free software;
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * you can redistribute it and/or modify it under the terms of the GNU
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * General Public License (GPL) as published by the Free Software
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The contents of this file may alternatively be used under the terms
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * of the Common Development and Distribution License Version 1.0
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * VirtualBox OSE distribution, in which case the provisions of the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * CDDL are applicable instead of those of the GPL.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * You may elect to license modified versions of this file under the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * terms and conditions of either the GPL or the CDDL or both.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*******************************************************************************
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync* Header Files *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync*******************************************************************************/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/*******************************************************************************
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync* Structures and Typedefs *
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync*******************************************************************************/
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest attribute.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Used both for entries and manifest attributes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The string space core (szName). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The property value. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The attribute type if applicable, RTMANIFEST_ATTR_UNKNOWN if not. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The normalized property name that StrCore::pszString points at. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** Pointer to a manifest attribute. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The string space core (szName). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The entry attributes (hashes, checksums, size, etc) -
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFESTATTR. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The normalized entry name that StrCore::pszString points at. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** Pointer to a manifest entry. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Manifest handle data.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** Magic value (RTMANIFEST_MAGIC). */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** The number of references to this manifest. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** Manifest attributes - RTMANIFESTATTR. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** String space of the entries covered by this manifest -
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFESTENTRY. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync/** The value of RTMANIFESTINT::u32Magic. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Creates an empty manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fFlags Flags, MBZ.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param phManifest Where to return the handle to the manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestCreate(uint32_t fFlags, PRTMANIFEST phManifest)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTMANIFESTINT *pThis = (RTMANIFESTINT *)RTMemAlloc(sizeof(*pThis));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Retains a reference to the manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns The new reference count, UINT32_MAX if the handle is invalid.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to retain.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(uint32_t) RTManifestRetain(RTMANIFEST hManifest)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTATTR.}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic DECLCALLBACK(int) rtManifestDestroyAttribute(PRTSTRSPACECORE pStr, void *pvUser)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTENTRY.}
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic DECLCALLBACK(int) rtManifestDestroyEntry(PRTSTRSPACECORE pStr, void *pvUser)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrSpaceDestroy(&pEntry->Attributes, rtManifestDestroyAttribute, pvUser);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Releases a reference to the manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns The new reference count, 0 if free. UINT32_MAX is returned if the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * handle is invalid.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to release.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * NIL is quietly ignored (returns 0).
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(uint32_t) RTManifestRelease(RTMANIFEST hManifest)
666edc71e2906904545617ad6fae769f7d0bbf08vboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, UINT32_MAX);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTMANIFEST_MAGIC);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrSpaceDestroy(&pThis->Attributes, rtManifestDestroyAttribute, pThis);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync RTStrSpaceDestroy(&pThis->Entries, rtManifestDestroyEntry, pThis);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Creates a duplicate of the specified manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifestSrc The manifest to clone.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param phManifestDst Where to store the handle to the duplicate.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestDup(RTMANIFEST hManifestSrc, PRTMANIFEST phManifestDst)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** @todo implement cloning. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEqualsEx(RTMANIFEST hManifest1, RTMANIFEST hManifest2, const char * const *papszIgnoreEntries,
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync const char * const *papszIgnoreAttr, char *pszEntry, size_t cbEntry)
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync * Validate input.
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertPtrNullReturn(pszEntry, VERR_INVALID_POINTER);
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertReturn(pThis1->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync AssertReturn(pThis2->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The simple cases.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (pThis1 == NIL_RTMANIFEST || pThis2 == NIL_RTMANIFEST)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync /** @todo implement comparing. */
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEquals(RTMANIFEST hManifest1, RTMANIFEST hManifest2)
db22a92f701bfcc17823963d6c8b745f68d44e30vboxsync return RTManifestEqualsEx(hManifest1, hManifest2, NULL /*papszIgnoreEntries*/, NULL /*papszIgnoreAttrs*/, NULL, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Worker common to RTManifestSetAttr and RTManifestEntrySetAttr.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pAttributes The attribute container.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The name of the attribute to add.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type type.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestSetAttrWorker(PRTSTRSPACE pAttributes, const char *pszAttr, const char *pszValue, uint32_t fType)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Does the attribute exist already?
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(pAttributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pAttr = (PRTMANIFESTATTR)RTMemAllocVar(RT_OFFSETOF(RTMANIFESTATTR, szName[cbName]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RT_UNLIKELY(!RTStrSpaceInsert(pAttributes, &pAttr->StrCore)))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Sets a manifest attribute.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name. If this already exists,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * its value will be replaced.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type, pass
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFEST_ATTR_UNKNOWN if not known.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestSetAttr(RTMANIFEST hManifest, const char *pszAttr, const char *pszValue, uint32_t fType)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rtManifestSetAttrWorker(&pThis->Attributes, pszAttr, pszValue, fType);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Worker common to RTManifestUnsetAttr and RTManifestEntryUnsetAttr.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pAttributes The attribute container.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The name of the attribute to remove.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestUnsetAttrWorker(PRTSTRSPACE pAttributes, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(pAttributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Unsets (removes) a manifest attribute if it exists.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_NOT_FOUND if not found.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestUnsetAttr(RTMANIFEST hManifest, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rtManifestUnsetAttrWorker(&pThis->Attributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Validates the name entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name to validate.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pfNeedNormalization Where to return whether it needs normalization
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * or not. Optional.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pcchEntry Where to return the length. Optional.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestValidateNameEntry(const char *pszEntry, bool *pfNeedNormalization, size_t *pcchEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync else if (uc < 32 || uc == ':' || uc == '(' || uc == ')')
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Normalizes a entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name to normalize.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic void rtManifestNormalizeEntry(char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Gets an entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pThis The manifest to work with.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fNeedNormalization Whether rtManifestValidateNameEntry said it
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * needed normalization.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param cchEntry The length of the name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param ppEntry Where to return the entry pointer on success.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncstatic int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Sets an attribute of a manifest entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name. This will automatically be
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * added if there was no previous call to
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTManifestEntryAdd for this name. See
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTManifestEntryAdd for the entry name rules.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name. If this already exists,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * its value will be replaced.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszValue The value string.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param fType The attribute type, pass
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * RTMANIFEST_ATTR_UNKNOWN if not known.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntrySetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr,
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(RT_IS_POWER_OF_TWO(fType) && fType < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Resolve the entry, adding one if necessary.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (!RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync return rtManifestSetAttrWorker(&pEntry->Attributes, pszAttr, pszValue, fType);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Unsets (removes) an attribute of a manifest entry if they both exist.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_NOT_FOUND if not found.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszAttr The attribute name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryUnsetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Resolve the entry and hand it over to the worker.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestUnsetAttrWorker(&pEntry->Attributes, pszAttr);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Adds a new entry to a manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * The entry name rules:
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - The entry name can contain any character defined by unicode, except
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * control characters, ':', '(' and ')'. The exceptions are mainly there
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * because of uncertainty around how various formats handles these.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - It is considered case sensitive.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * - Forward (unix) and backward (dos) slashes are considered path
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * separators and converted to forward slashes.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @retval VWRN_ALREADY_EXISTS if the entry already exists.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name (UTF-8).
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @remarks Some manifest formats will not be able to store an entry without
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * any attributes. So, this is just here in case it comes in handy
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * when dealing with formats which can.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryAdd(RTMANIFEST hManifest, const char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Only add one if it does not already exist.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync pEntry = (PRTMANIFESTENTRY)RTMemAlloc(RT_OFFSETOF(RTMANIFESTENTRY, szName[cchEntry + 1]));
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync if (RTStrSpaceInsert(&pThis->Entries, &pEntry->StrCore))
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Removes an entry.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The manifest handle.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param pszEntry The entry name.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestEntryRemove(RTMANIFEST hManifest, const char *pszEntry)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Only add one if it does not already exist.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync PRTSTRSPACECORE pStrCore = RTStrSpaceRemove(&pThis->Entries, pEntry->StrCore.pszString);
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsyncstatic int rtManifestReadLine(RTVFSIOSTREAM hVfsIos, char *pszLine, size_t cbLine)
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync /* This is horribly slow right now, but it's not a biggy as the input is
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync usually cached in memory somewhere... */
d012a89a724ba60c4fb5e74ce51f8b404fda4a8cvboxsync int rc = RTVfsIoStrmRead(hVfsIos, pszLine, 1, true /*fBLocking*/, NULL);
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Reads in a "standard" manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * This reads the format used by OVF, the distinfo in FreeBSD ports, and
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to the manifest where to add the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * manifest that's read in.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hVfsIos The I/O stream to read the manifest from.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsyncRTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos)
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * Writes a "standard" manifest.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * This writes the format used by OVF, the distinfo in FreeBSD ports, and
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @returns IPRT status code.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hManifest The handle to the manifest where to add the
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * manifest that's read in.
f1f5335f9ec8e56fe0e3e27f253e24b10ff20f2evboxsync * @param hVfsIos The I/O stream to read the manifest from.