diff options
Diffstat (limited to 'xpcom/build/nsXPCOMStrings.cpp')
-rw-r--r-- | xpcom/build/nsXPCOMStrings.cpp | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/xpcom/build/nsXPCOMStrings.cpp b/xpcom/build/nsXPCOMStrings.cpp new file mode 100644 index 000000000..617edbab2 --- /dev/null +++ b/xpcom/build/nsXPCOMStrings.cpp @@ -0,0 +1,366 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsString.h" +#include "nsCharTraits.h" + +#include "nsXPCOMStrings.h" +#include "nsNativeCharsetUtils.h" + +/* ------------------------------------------------------------------------- */ + +XPCOM_API(nsresult) +NS_StringContainerInit(nsStringContainer& aContainer) +{ + NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString), + "nsStringContainer is not large enough"); + + // use placement new to avoid heap allocating nsString object + new (&aContainer) nsString(); + + return NS_OK; +} + +XPCOM_API(nsresult) +NS_StringContainerInit2(nsStringContainer& aContainer, + const char16_t* aData, + uint32_t aDataLength, + uint32_t aFlags) +{ + NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString), + "nsStringContainer is not large enough"); + + if (!aData) { + new (&aContainer) nsString(); + } else { + if (aDataLength == UINT32_MAX) { + if (NS_WARN_IF(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)) { + return NS_ERROR_INVALID_ARG; + } + aDataLength = nsCharTraits<char16_t>::length(aData); + } + + if (aFlags & (NS_STRING_CONTAINER_INIT_DEPEND | + NS_STRING_CONTAINER_INIT_ADOPT)) { + uint32_t flags; + if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING) { + flags = nsSubstring::F_NONE; + } else { + flags = nsSubstring::F_TERMINATED; + } + + if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT) { + flags |= nsSubstring::F_OWNED; + } + + new (&aContainer) nsSubstring(const_cast<char16_t*>(aData), + aDataLength, flags); + } else { + new (&aContainer) nsString(aData, aDataLength); + } + } + + return NS_OK; +} + +XPCOM_API(void) +NS_StringContainerFinish(nsStringContainer& aContainer) +{ + // call the nsString dtor + reinterpret_cast<nsString*>(&aContainer)->~nsString(); +} + +/* ------------------------------------------------------------------------- */ + +XPCOM_API(uint32_t) +NS_StringGetData(const nsAString& aStr, const char16_t** aData, + bool* aTerminated) +{ + if (aTerminated) { + *aTerminated = aStr.IsTerminated(); + } + + *aData = aStr.BeginReading(); + return aStr.Length(); +} + +XPCOM_API(uint32_t) +NS_StringGetMutableData(nsAString& aStr, uint32_t aDataLength, + char16_t** aData) +{ + if (aDataLength != UINT32_MAX) { + aStr.SetLength(aDataLength); + if (aStr.Length() != aDataLength) { + *aData = nullptr; + return 0; + } + } + + *aData = aStr.BeginWriting(); + return aStr.Length(); +} + +XPCOM_API(char16_t*) +NS_StringCloneData(const nsAString& aStr) +{ + return ToNewUnicode(aStr); +} + +XPCOM_API(nsresult) +NS_StringSetData(nsAString& aStr, const char16_t* aData, uint32_t aDataLength) +{ + aStr.Assign(aData, aDataLength); + return NS_OK; // XXX report errors +} + +XPCOM_API(nsresult) +NS_StringSetDataRange(nsAString& aStr, + uint32_t aCutOffset, uint32_t aCutLength, + const char16_t* aData, uint32_t aDataLength) +{ + if (aCutOffset == UINT32_MAX) { + // append case + if (aData) { + aStr.Append(aData, aDataLength); + } + return NS_OK; // XXX report errors + } + + if (aCutLength == UINT32_MAX) { + aCutLength = aStr.Length() - aCutOffset; + } + + if (aData) { + if (aDataLength == UINT32_MAX) { + aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData)); + } else { + aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength)); + } + } else { + aStr.Cut(aCutOffset, aCutLength); + } + + return NS_OK; // XXX report errors +} + +XPCOM_API(nsresult) +NS_StringCopy(nsAString& aDest, const nsAString& aSrc) +{ + aDest.Assign(aSrc); + return NS_OK; // XXX report errors +} + +XPCOM_API(void) +NS_StringSetIsVoid(nsAString& aStr, const bool aIsVoid) +{ + aStr.SetIsVoid(aIsVoid); +} + +XPCOM_API(bool) +NS_StringGetIsVoid(const nsAString& aStr) +{ + return aStr.IsVoid(); +} + +/* ------------------------------------------------------------------------- */ + +XPCOM_API(nsresult) +NS_CStringContainerInit(nsCStringContainer& aContainer) +{ + NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString), + "nsCStringContainer is not large enough"); + + // use placement new to avoid heap allocating nsCString object + new (&aContainer) nsCString(); + + return NS_OK; +} + +XPCOM_API(nsresult) +NS_CStringContainerInit2(nsCStringContainer& aContainer, + const char* aData, + uint32_t aDataLength, + uint32_t aFlags) +{ + NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString), + "nsStringContainer is not large enough"); + + if (!aData) { + new (&aContainer) nsCString(); + } else { + if (aDataLength == UINT32_MAX) { + if (NS_WARN_IF(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)) { + return NS_ERROR_INVALID_ARG; + } + aDataLength = nsCharTraits<char>::length(aData); + } + + if (aFlags & (NS_CSTRING_CONTAINER_INIT_DEPEND | + NS_CSTRING_CONTAINER_INIT_ADOPT)) { + uint32_t flags; + if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING) { + flags = nsCSubstring::F_NONE; + } else { + flags = nsCSubstring::F_TERMINATED; + } + + if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT) { + flags |= nsCSubstring::F_OWNED; + } + + new (&aContainer) nsCSubstring(const_cast<char*>(aData), + aDataLength, flags); + } else { + new (&aContainer) nsCString(aData, aDataLength); + } + } + + return NS_OK; +} + +XPCOM_API(void) +NS_CStringContainerFinish(nsCStringContainer& aContainer) +{ + // call the nsCString dtor + reinterpret_cast<nsCString*>(&aContainer)->~nsCString(); +} + +/* ------------------------------------------------------------------------- */ + +XPCOM_API(uint32_t) +NS_CStringGetData(const nsACString& aStr, const char** aData, + bool* aTerminated) +{ + if (aTerminated) { + *aTerminated = aStr.IsTerminated(); + } + + *aData = aStr.BeginReading(); + return aStr.Length(); +} + +XPCOM_API(uint32_t) +NS_CStringGetMutableData(nsACString& aStr, uint32_t aDataLength, char** aData) +{ + if (aDataLength != UINT32_MAX) { + aStr.SetLength(aDataLength); + if (aStr.Length() != aDataLength) { + *aData = nullptr; + return 0; + } + } + + *aData = aStr.BeginWriting(); + return aStr.Length(); +} + +XPCOM_API(char*) +NS_CStringCloneData(const nsACString& aStr) +{ + return ToNewCString(aStr); +} + +XPCOM_API(nsresult) +NS_CStringSetData(nsACString& aStr, const char* aData, uint32_t aDataLength) +{ + aStr.Assign(aData, aDataLength); + return NS_OK; // XXX report errors +} + +XPCOM_API(nsresult) +NS_CStringSetDataRange(nsACString& aStr, + uint32_t aCutOffset, uint32_t aCutLength, + const char* aData, uint32_t aDataLength) +{ + if (aCutOffset == UINT32_MAX) { + // append case + if (aData) { + aStr.Append(aData, aDataLength); + } + return NS_OK; // XXX report errors + } + + if (aCutLength == UINT32_MAX) { + aCutLength = aStr.Length() - aCutOffset; + } + + if (aData) { + if (aDataLength == UINT32_MAX) { + aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData)); + } else { + aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength)); + } + } else { + aStr.Cut(aCutOffset, aCutLength); + } + + return NS_OK; // XXX report errors +} + +XPCOM_API(nsresult) +NS_CStringCopy(nsACString& aDest, const nsACString& aSrc) +{ + aDest.Assign(aSrc); + return NS_OK; // XXX report errors +} + +XPCOM_API(void) +NS_CStringSetIsVoid(nsACString& aStr, const bool aIsVoid) +{ + aStr.SetIsVoid(aIsVoid); +} + +XPCOM_API(bool) +NS_CStringGetIsVoid(const nsACString& aStr) +{ + return aStr.IsVoid(); +} + +/* ------------------------------------------------------------------------- */ + +XPCOM_API(nsresult) +NS_CStringToUTF16(const nsACString& aSrc, + nsCStringEncoding aSrcEncoding, + nsAString& aDest) +{ + switch (aSrcEncoding) { + case NS_CSTRING_ENCODING_ASCII: + CopyASCIItoUTF16(aSrc, aDest); + break; + case NS_CSTRING_ENCODING_UTF8: + CopyUTF8toUTF16(aSrc, aDest); + break; + case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM: + NS_CopyNativeToUnicode(aSrc, aDest); + break; + default: + return NS_ERROR_NOT_IMPLEMENTED; + } + + return NS_OK; // XXX report errors +} + +XPCOM_API(nsresult) +NS_UTF16ToCString(const nsAString& aSrc, + nsCStringEncoding aDestEncoding, + nsACString& aDest) +{ + switch (aDestEncoding) { + case NS_CSTRING_ENCODING_ASCII: + LossyCopyUTF16toASCII(aSrc, aDest); + break; + case NS_CSTRING_ENCODING_UTF8: + CopyUTF16toUTF8(aSrc, aDest); + break; + case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM: + NS_CopyUnicodeToNative(aSrc, aDest); + break; + default: + return NS_ERROR_NOT_IMPLEMENTED; + } + + return NS_OK; // XXX report errors +} |