string.cpp revision c97989161fbe75bc14cea477a5443bbf474dd3ad
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/** @file
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * MS COM / XPCOM Abstraction Layer:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Smart string classes definition
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Copyright (C) 2006-2007 innotek GmbH
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * available from http://www.virtualbox.org. This file is free software;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * you can redistribute it and/or modify it under the terms of the GNU
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * General Public License as published by the Free Software Foundation,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * If you received this file as part of a commercial VirtualBox
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * distribution, then only the terms of your commercial VirtualBox
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * license agreement apply instead of the previous paragraph.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include "VBox/com/string.h"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncnamespace com
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct FormatData
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync static const size_t CacheIncrement = 256;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t size;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t pos;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync char *cache;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid Utf8StrFmt::init (const char *format, va_list args)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!format)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync // assume an extra byte for a terminating zero
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t fmtlen = strlen (format) + 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync FormatData data;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.size = FormatData::CacheIncrement;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (fmtlen >= FormatData::CacheIncrement)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.size += fmtlen;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.pos = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.cache = (char *) ::RTMemTmpAllocZ (data.size);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t n = ::RTStrFormatV (strOutput, &data, NULL, NULL, format, args);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync AssertMsg (n == data.pos,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ("The number of bytes formatted doesn't match: %d and %d!",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync n, data.pos));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NOREF (n);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync // finalize formatting
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.cache [data.pos] = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (*static_cast <Utf8Str *> (this)) = data.cache;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ::RTMemTmpFree (data.cache);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync// static
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncDECLCALLBACK(size_t) Utf8StrFmt::strOutput (void *pvArg, const char *pachChars,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t cbChars)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync Assert (pvArg);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync FormatData &data = *(FormatData *) pvArg;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!(pachChars == NULL && cbChars == 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync Assert (pachChars);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync // append to cache (always assume an extra byte for a terminating zero)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync size_t needed = cbChars + 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (data.pos + needed > data.size)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.size += FormatData::CacheIncrement;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (needed >= FormatData::CacheIncrement)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.size += needed;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.cache = (char *) ::RTMemRealloc (data.cache, data.size);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync strncpy (data.cache + data.pos, pachChars, cbChars);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data.pos += cbChars;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return cbChars;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}; // namespace com
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync