ministring_cpp.h revision 9b2ac77c825d403359ac91e9606b91878646df9f
/** @file
* VirtualBox mini C++ string class. This is a base for both Utf8Str and
* other places where IPRT may want to use a lean C++ string class.
*/
/*
* Copyright (C) 2007-2009 Sun Microsystems, Inc.
*
* 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.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#ifndef ___VBox_ministring_h
#define ___VBox_ministring_h
#include <new>
{
/**
* "MiniString" is a small C++ string class that does not depend on anything
* else except IPRT memory management functions. This is used as the base of
* both the Utf8Str class that COM uses as well as C++ code in IPRT that
* prefers to have a string class, like in xml.cpp.
*
* Semantics are like in std::string, except it can do a lot less.
*
* Much of the code in here used to be in com::Utf8Str so that com::Utf8Str
* can now derive from MiniString and only contain code that is COM-specific,
* such as com::Bstr conversions. Compared to the old Utf8Str though, MiniString
* always knows the length of its member string and the size of the buffer
* so it can use memcpy() instead of strdup().
*/
{
/**
* Creates an empty string that has no memory allocated.
*/
m_cbLength(0),
{
}
/**
* Creates a copy of another MiniString. This allocates
* s.length() + 1 bytes for the new instance.
* @param s
*/
MiniString(const MiniString &s)
{
copyFrom(s);
}
/**
* Creates a copy of another MiniString. This allocates
* strlen(pcsz) + 1 bytes for the new instance.
* @param pcsz
*/
MiniString(const char *pcsz)
{
}
/**
* Destructor.
*/
{
cleanup();
}
/**
* Returns the length of the member string. This is always cached
* so calling this is cheap and requires no strlen() invocation.
* @return
*/
{
return m_cbLength;
}
/**
* Returns the number of bytes allocated in the internal string buffer,
* which is at least length() + 1 if length() > 0.
* @return
*/
{
return m_cbAllocated;
}
/**
* Requests that the contained memory buffer have at least cb bytes allocated.
* This may expand or shrink the string's storage, but will never truncate the
* contained string. In other words, cb will be ignored if it's smaller than
* length() + 1.
* @param cb new minimum size of member memory buffer
*/
{
if ( (cb != m_cbAllocated)
)
{
#ifdef RT_EXCEPTIONS_ENABLED
if (!m_psz)
#endif
m_cbAllocated = cb;
}
}
/**
* Deallocates all memory.
*/
inline void setNull()
{
cleanup();
}
/**
* Returns a non-const raw pointer that allows to modify the string directly.
* @warning
* 1) Be sure not to modify data beyond the allocated memory! Call
* capacity() to find out how large that buffer is.
* 2) After any operation that modifies the length of the string,
* you _must_ call MiniString::jolt(), or subsequent copy operations
* may go nowhere. Better not use mutableRaw() at all.
*/
char* mutableRaw()
{
return m_psz;
}
/**
* Intended to be called after something has messed with the internal string
* buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets
* the internal lengths correctly. Otherwise subsequent copy operations may
* go nowhere.
*/
void jolt()
{
if (m_psz)
{
}
else
{
m_cbLength = 0;
m_cbAllocated = 0;
}
}
/**
* Assigns a copy of pcsz to "this".
* @param pcsz
* @return
*/
{
{
cleanup();
}
return *this;
}
/**
* Assigns a copy of s to "this".
* @param s
* @return
*/
{
if (this != &s)
{
cleanup();
copyFrom(s);
}
return *this;
}
/**
* Appends a copy of @a that to "this".
* @param that
*/
{
if (cbThat)
{
// calls realloc(cbBoth) and sets m_cbAllocated
}
}
/**
* Returns the contained string as a C-style const char* pointer.
* @return
*/
inline const char* c_str() const
{
return m_psz;
}
/**
* Like c_str(), for compatibility with lots of VirtualBox Main code.
* @return
*/
inline const char* raw() const
{
return m_psz;
}
/** Intended to to pass instances as input (|char *|) parameters to methods. */
inline operator const char*() const
{
return c_str();
}
/**
* Returns true if the member string has no length. This states nothing about
* how much memory might be allocated.
* @return
*/
bool isEmpty() const
{
return length() == 0;
}
enum CaseSensitivity
{
};
/**
* Compares the member string to pcsz.
* @param pcsz
* @param cs Whether comparison should be case-sensitive.
* @return
*/
{
return 0;
return -1;
return 1;
if (cs == CaseSensitive)
else
}
{
}
/**
* Hide operator bool() to force people to use isEmpty() explicitly.
*/
operator bool() const { return false; }
/**
* Destructor implementation, also used to clean up in operator=()
* before assigning a new string.
*/
void cleanup()
{
if (m_psz)
{
m_cbLength = 0;
m_cbAllocated = 0;
}
}
/**
* Protected internal helper.
* copyFrom() unconditionally sets the members to a copy of the
* given other strings and makes no assumptions about previous
* contents. Can therefore be used both in copy constructors,
* when member variables have no defined value, and in assignments
* after having called cleanup().
*
* This variant copies from another MiniString and is fast since
* the length of source string is known.
*
* @param s
*/
void copyFrom(const MiniString &s)
{
if ((m_cbLength = s.m_cbLength))
{
#ifdef RT_EXCEPTIONS_ENABLED
if (!m_psz)
#endif
}
else
{
m_cbAllocated = 0;
}
}
/**
* Protected internal helper.
* See copyFrom() above.
*
* This variant copies from a C string and needs to call strlen()
* on it. It's therefore slower than the one above.
*
* @param pcsz
*/
{
if (pcsz)
{
#ifdef RT_EXCEPTIONS_ENABLED
if (!m_psz)
#endif
}
else
{
m_cbLength = 0;
m_cbAllocated = 0;
}
}
char *m_psz;
};
} // namespace iprt
#endif