fixes bug 288786 "Add BeginWriting equivalent to frozen string API" r=biesi sr=dbaron a=asa

This commit is contained in:
darin%meer.net 2005-04-27 01:38:35 +00:00
parent c7c0859ea1
commit 3b218b11f8
7 changed files with 208 additions and 1 deletions

View File

@ -207,6 +207,7 @@ void XXXNeverCalled()
NS_CStringContainerInit2(sc1, nsnull, 0, 0);
NS_CStringContainerFinish(sc1);
NS_CStringGetData(str2, nsnull, nsnull);
NS_CStringGetMutableData(str2, 0, nsnull);
NS_CStringSetData(str2, nsnull, 0);
NS_CStringSetDataRange(str2, 0, 0, nsnull, 0);
NS_CStringCopy(str2, str2);
@ -216,6 +217,7 @@ void XXXNeverCalled()
NS_StringContainerInit2(sc2, nsnull, 0, 0);
NS_StringContainerFinish(sc2);
NS_StringGetData(str1, nsnull, nsnull);
NS_StringGetMutableData(str1, 0, nsnull);
NS_StringSetData(str1, nsnull, 0);
NS_StringSetDataRange(str1, 0, 0, nsnull, 0);
NS_StringCopy(str1, str1);

View File

@ -122,6 +122,24 @@ NS_StringGetData(const nsAString &aStr, const PRUnichar **aData,
return begin.size_forward();
}
NS_STRINGAPI(PRUint32)
NS_StringGetMutableData(nsAString &aStr, PRUint32 aDataLength,
PRUnichar **aData)
{
if (aDataLength != PR_UINT32_MAX) {
aStr.SetLength(aDataLength);
if (aStr.Length() != aDataLength) {
*aData = nsnull;
return 0;
}
}
nsAString::iterator begin;
aStr.BeginWriting(begin);
*aData = begin.get();
return begin.size_forward();
}
NS_STRINGAPI(PRUnichar *)
NS_StringCloneData(const nsAString &aStr)
{
@ -252,6 +270,23 @@ NS_CStringGetData(const nsACString &aStr, const char **aData,
return begin.size_forward();
}
NS_STRINGAPI(PRUint32)
NS_CStringGetMutableData(nsACString &aStr, PRUint32 aDataLength, char **aData)
{
if (aDataLength != PR_UINT32_MAX) {
aStr.SetLength(aDataLength);
if (aStr.Length() != aDataLength) {
*aData = nsnull;
return 0;
}
}
nsACString::iterator begin;
aStr.BeginWriting(begin);
*aData = begin.get();
return begin.size_forward();
}
NS_STRINGAPI(char *)
NS_CStringCloneData(const nsACString &aStr)
{

View File

@ -99,6 +99,7 @@ typedef nsresult (* StringContainerInitFunc)(nsStringContainer&);
typedef nsresult (* StringContainerInit2Func)(nsStringContainer&, const PRUnichar *, PRUint32, PRUint32);
typedef void (* StringContainerFinishFunc)(nsStringContainer&);
typedef PRUint32 (* StringGetDataFunc)(const nsAString&, const PRUnichar**, PRBool*);
typedef PRUint32 (* StringGetMutableDataFunc)(nsAString&, PRUint32, PRUnichar**);
typedef PRUnichar* (* StringCloneDataFunc)(const nsAString&);
typedef nsresult (* StringSetDataFunc)(nsAString&, const PRUnichar*, PRUint32);
typedef nsresult (* StringSetDataRangeFunc)(nsAString&, PRUint32, PRUint32, const PRUnichar*, PRUint32);
@ -108,6 +109,7 @@ typedef nsresult (* CStringContainerInitFunc)(nsCStringContainer&);
typedef nsresult (* CStringContainerInit2Func)(nsCStringContainer&, const char *, PRUint32, PRUint32);
typedef void (* CStringContainerFinishFunc)(nsCStringContainer&);
typedef PRUint32 (* CStringGetDataFunc)(const nsACString&, const char**, PRBool*);
typedef PRUint32 (* CStringGetMutableDataFunc)(nsACString&, PRUint32, char**);
typedef char* (* CStringCloneDataFunc)(const nsACString&);
typedef nsresult (* CStringSetDataFunc)(nsACString&, const char*, PRUint32);
typedef nsresult (* CStringSetDataRangeFunc)(nsACString&, PRUint32, PRUint32, const char*, PRUint32);
@ -168,6 +170,8 @@ typedef struct XPCOMFunctions{
FreeFunc freeFunc;
StringContainerInit2Func stringContainerInit2;
CStringContainerInit2Func cstringContainerInit2;
StringGetMutableDataFunc stringGetMutableData;
CStringGetMutableDataFunc cstringGetMutableData;
} XPCOMFunctions;

View File

@ -317,6 +317,16 @@ NS_StringGetData(const nsAString &aStr, const PRUnichar **aBuf, PRBool *aTerm)
return xpcomFunctions.stringGetData(aStr, aBuf, aTerm);
}
extern "C" NS_COM PRUint32
NS_StringGetMutableData(nsAString &aStr, PRUint32 aLen, PRUnichar **aBuf)
{
if (!xpcomFunctions.stringGetMutableData) {
*aBuf = nsnull;
return 0;
}
return xpcomFunctions.stringGetMutableData(aStr, aLen, aBuf);
}
extern "C" NS_COM PRUnichar *
NS_StringCloneData(const nsAString &aStr)
{
@ -388,6 +398,16 @@ NS_CStringGetData(const nsACString &aStr, const char **aBuf, PRBool *aTerm)
return xpcomFunctions.cstringGetData(aStr, aBuf, aTerm);
}
extern "C" NS_COM PRUint32
NS_CStringGetMutableData(nsACString &aStr, PRUint32 aLen, char **aBuf)
{
if (!xpcomFunctions.cstringGetMutableData) {
*aBuf = nsnull;
return 0;
}
return xpcomFunctions.cstringGetMutableData(aStr, aLen, aBuf);
}
extern "C" NS_COM char *
NS_CStringCloneData(const nsACString &aStr)
{

View File

@ -52,6 +52,7 @@
# define NS_StringContainerInit2 NS_StringContainerInit2_P
# define NS_StringContainerFinish NS_StringContainerFinish_P
# define NS_StringGetData NS_StringGetData_P
# define NS_StringGetMutableData NS_StringGetMutableData_P
# define NS_StringCloneData NS_StringCloneData_P
# define NS_StringSetData NS_StringSetData_P
# define NS_StringSetDataRange NS_StringSetDataRange_P
@ -60,6 +61,7 @@
# define NS_CStringContainerInit2 NS_CStringContainerInit2_P
# define NS_CStringContainerFinish NS_CStringContainerFinish_P
# define NS_CStringGetData NS_CStringGetData_P
# define NS_CStringGetMutableData NS_CStringGetMutableData_P
# define NS_CStringCloneData NS_CStringCloneData_P
# define NS_CStringSetData NS_CStringSetData_P
# define NS_CStringSetDataRange NS_CStringSetDataRange_P
@ -247,6 +249,39 @@ NS_StringGetData
(const nsAString &aStr, const PRUnichar **aData,
PRBool *aTerminated = nsnull);
/**
* NS_StringGetMutableData
*
* This function provides mutable access to a string's internal buffer. It
* returns a pointer to an array of characters that may be modified. The
* returned pointer remains valid until the string object is passed to some
* other string function.
*
* Optionally, this function may be used to resize the string's internal
* buffer. The aDataLength parameter specifies the requested length of the
* string's internal buffer. By passing some value other than PR_UINT32_MAX,
* the caller can request that the buffer be resized to the specified number of
* characters before returning. The caller is not responsible for writing a
* null-terminator.
*
* @param aStr abstract string reference
* @param aDataLength number of characters to resize the string's internal
* buffer to or PR_UINT32_MAX if no resizing is needed
* @param aData out param that upon return holds the address of aStr's
* internal buffer or null if the function failed
* @return number of characters or zero if the function failed
*
* This function does not necessarily null-terminate aStr after resizing its
* internal buffer. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its data
* will be null-terminated by this function.
*
* @status FROZEN
*/
NS_STRINGAPI(PRUint32)
NS_StringGetMutableData
(nsAString &aStr, PRUint32 aDataLength, PRUnichar **aData);
/**
* NS_StringCloneData
*
@ -519,6 +554,39 @@ NS_CStringGetData
(const nsACString &aStr, const char **aData,
PRBool *aTerminated = nsnull);
/**
* NS_CStringGetMutableData
*
* This function provides mutable access to a string's internal buffer. It
* returns a pointer to an array of characters that may be modified. The
* returned pointer remains valid until the string object is passed to some
* other string function.
*
* Optionally, this function may be used to resize the string's internal
* buffer. The aDataLength parameter specifies the requested length of the
* string's internal buffer. By passing some value other than PR_UINT32_MAX,
* the caller can request that the buffer be resized to the specified number of
* characters before returning. The caller is not responsible for writing a
* null-terminator.
*
* @param aStr abstract string reference
* @param aDataLength number of characters to resize the string's internal
* buffer to or PR_UINT32_MAX if no resizing is needed
* @param aData out param that upon return holds the address of aStr's
* internal buffer or null if the function failed
* @return number of characters or zero if the function failed
*
* This function does not necessarily null-terminate aStr after resizing its
* internal buffer. The behavior depends on the implementation of the abstract
* string, aStr. If aStr is a reference to a nsStringContainer, then its data
* will be null-terminated by this function.
*
* @status FROZEN
*/
NS_STRINGAPI(PRUint32)
NS_CStringGetMutableData
(nsACString &aStr, PRUint32 aDataLength, char **aData);
/**
* NS_CStringCloneData
*
@ -782,6 +850,20 @@ public:
return data + len;
}
NS_HIDDEN_(char_type*) BeginWriting()
{
char_type *data;
NS_StringGetMutableData(*this, PR_UINT32_MAX, &data);
return data;
}
NS_HIDDEN_(PRBool) SetLength(PRUint32 aLen)
{
char_type *data;
NS_StringGetMutableData(*this, aLen, &data);
return data != nsnull;
}
NS_HIDDEN_(size_type) Length() const
{
const char_type* data;
@ -869,6 +951,20 @@ public:
return data + len;
}
NS_HIDDEN_(char_type*) BeginWriting()
{
char_type *data;
NS_CStringGetMutableData(*this, PR_UINT32_MAX, &data);
return data;
}
NS_HIDDEN_(PRBool) SetLength(PRUint32 aLen)
{
char_type *data;
NS_CStringGetMutableData(*this, aLen, &data);
return data != nsnull;
}
NS_HIDDEN_(size_type) Length() const
{
const char_type* data;

View File

@ -82,7 +82,9 @@ static const XPCOMFunctions kFrozenFunctions = {
&NS_Realloc_P,
&NS_Free_P,
&NS_StringContainerInit2_P,
&NS_CStringContainerInit2_P
&NS_CStringContainerInit2_P,
&NS_StringGetMutableData_P,
&NS_CStringGetMutableData_P
};
extern "C" NS_EXPORT nsresult
@ -259,6 +261,13 @@ NS_StringGetData(const nsAString &aStr, const PRUnichar **aBuf, PRBool *aTerm)
return NS_StringGetData_P(aStr, aBuf, aTerm);
}
#undef NS_StringGetMutableData
extern "C" NS_EXPORT PRUint32
NS_StringGetMutableData(nsAString &aStr, PRUint32 aLen, PRUnichar **aBuf)
{
return NS_StringGetMutableData_P(aStr, aLen, aBuf);
}
#undef NS_StringCloneData
extern "C" NS_EXPORT PRUnichar *
NS_StringCloneData(const nsAString &aStr)
@ -319,6 +328,13 @@ NS_CStringGetData(const nsACString &aStr, const char **aBuf, PRBool *aTerm)
return NS_CStringGetData_P(aStr, aBuf, aTerm);
}
#undef NS_CStringGetMutableData
extern "C" NS_EXPORT PRUint32
NS_CStringGetMutableData(nsACString &aStr, PRUint32 aLen, char **aBuf)
{
return NS_CStringGetMutableData_P(aStr, aLen, aBuf);
}
#undef NS_CStringCloneData
extern "C" NS_EXPORT char *
NS_CStringCloneData(const nsACString &aStr)

View File

@ -431,6 +431,39 @@ static PRBool test_adopt_sub()
return rv;
}
static PRBool test_mutation()
{
nsCStringContainer s;
NS_CStringContainerInit(s);
const char kText[] = "Every good boy does fine.";
char *buf;
PRUint32 len = NS_CStringGetMutableData(s, sizeof(kText) - 1, &buf);
if (!buf || len != sizeof(kText) - 1)
return PR_FALSE;
memcpy(buf, kText, sizeof(kText));
const char *data;
NS_CStringGetData(s, &data);
if (strcmp(data, kText) != 0)
return PR_FALSE;
PRUint32 newLen = len + 1;
len = NS_CStringGetMutableData(s, newLen, &buf);
if (!buf || len != newLen)
return PR_FALSE;
buf[len - 1] = '.';
NS_CStringGetData(s, &data);
if (strncmp(data, kText, len - 1) != 0 || data[len - 1] != '.')
return PR_FALSE;
NS_CStringContainerFinish(s);
return PR_TRUE;
}
//----
typedef PRBool (*TestFunc)();
@ -452,6 +485,7 @@ tests[] =
{ "test_depend_sub", test_depend_sub },
{ "test_adopt", test_adopt },
{ "test_adopt_sub", test_adopt_sub },
{ "test_mutation", test_mutation },
{ nsnull, nsnull }
};