landing string branch; see bug #73786

This commit is contained in:
scc%mozilla.org 2001-04-02 19:40:52 +00:00
parent 19eacb143c
commit 70de2e4a46
143 changed files with 11372 additions and 5238 deletions

View File

@ -904,7 +904,7 @@ NS_IMETHODIMP nsDocument::SetDocumentCharacterSet(const nsAReadableString& aChar
for (PRInt32 i = 0; i < n; i++) {
nsIObserver* observer = (nsIObserver*) mCharSetObservers.ElementAt(i);
observer->Observe((nsIDocument*) this, NS_LITERAL_STRING("charset").get(),
nsPromiseFlatString(aCharSetID).get());
PromiseFlatString(aCharSetID).get());
}
}
return NS_OK;

View File

@ -383,7 +383,7 @@ ConvertAndWrite(nsAReadableString& aString,
NS_ENSURE_ARG_POINTER(aEncoder);
nsresult rv;
PRInt32 charLength, startCharLength;
nsPromiseFlatString flat(aString);
const nsPromiseFlatString& flat = PromiseFlatString(aString);
const PRUnichar* unicodeBuf = flat.get();
PRInt32 unicodeLength = aString.Length();
PRInt32 startLength = unicodeLength;

View File

@ -347,7 +347,7 @@ nsNodeInfo::NamespaceEquals(const nsAReadableString& aNamespaceURI)
NS_IMETHODIMP_(PRBool)
nsNodeInfo::QualifiedNameEquals(const nsAReadableString& aQualifiedName)
{
nsPromiseFlatString flatName(aQualifiedName);
const nsPromiseFlatString& flatName = PromiseFlatString(aQualifiedName);
const PRUnichar *qname = flatName.get();
PRUint32 i = 0;

View File

@ -369,7 +369,7 @@ nsHTMLAnchorElement::StringToAttribute(nsIAtom* aAttribute,
}
}
else if (aAttribute == nsHTMLAtoms::suppress) {
if (nsCRT::strcasecmp(nsPromiseFlatString(aValue).get(),
if (nsCRT::strcasecmp(PromiseFlatString(aValue).get(),
NS_LITERAL_STRING("true").get())) {
aResult.SetEmptyValue(); // XXX? shouldn't just leave "true"
return NS_CONTENT_ATTR_HAS_VALUE;

View File

@ -122,7 +122,7 @@ nsXBLDocumentInfo::GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPro
if (!mBindingTable)
return NS_OK;
nsPromiseFlatCString flat(aRef);
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
*aResult = NS_STATIC_CAST(nsIXBLPrototypeBinding*, mBindingTable->Get(&key)); // Addref happens here.
@ -135,7 +135,7 @@ nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPro
if (!mBindingTable)
mBindingTable = new nsSupportsHashtable();
nsPromiseFlatCString flat(aRef);
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get());
mBindingTable->Put(&key, aBinding);
@ -870,7 +870,7 @@ NS_IMETHODIMP
nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc, const nsAReadableString& aURL,
nsIDocument** aResult)
{
nsCAutoString url; url.AssignWithConversion(nsPromiseFlatString(aURL).get());
nsCAutoString url; url.AssignWithConversion(PromiseFlatString(aURL).get());
nsCOMPtr<nsIURL> uri;
nsComponentManager::CreateInstance("@mozilla.org/network/standard-url;1",

View File

@ -633,7 +633,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsAReadableString& aURL,
// See if the URIs match.
nsCAutoString uri;
styleBinding->GetBindingURI(uri);
if (uri.EqualsWithConversion((const PRUnichar *) nsPromiseFlatString(aURL).get()))
if (uri.EqualsWithConversion((const PRUnichar *) PromiseFlatString(aURL).get()))
return NS_OK;
else {
FlushStyleBindings(aContent);

View File

@ -143,7 +143,7 @@ nsXBLSpecialDocInfo::GetHandlers(nsIXBLDocumentInfo* aInfo,
root->ChildAt(i, *getter_AddRefs(child));
nsAutoString id;
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
if (id.EqualsWithConversion(nsPromiseFlatCString(aRef).get())) {
if (id.EqualsWithConversion(PromiseFlatCString(aRef).get())) {
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
aInfo->SetPrototypeBinding(aRef, binding);
break;

View File

@ -152,7 +152,7 @@ nsElementMap::Add(const nsAReadableString& aID, nsIContent* aContent)
if (! mMap)
return NS_ERROR_NOT_INITIALIZED;
nsPromiseFlatString flatID(aID);
const nsPromiseFlatString& flatID = PromiseFlatString(aID);
const PRUnichar *id = flatID.get();
ContentListItem* head =
@ -251,7 +251,7 @@ nsElementMap::Remove(const nsAReadableString& aID, nsIContent* aContent)
if (! mMap)
return NS_ERROR_NOT_INITIALIZED;
nsPromiseFlatString flatID(aID);
const nsPromiseFlatString& flatID = PromiseFlatString(aID);
const PRUnichar *id = flatID.get();
#ifdef PR_LOGGING
@ -331,7 +331,7 @@ nsElementMap::Find(const nsAReadableString& aID, nsISupportsArray* aResults)
aResults->Clear();
ContentListItem* item =
NS_REINTERPRET_CAST(ContentListItem*, PL_HashTableLookup(mMap, (const PRUnichar *)nsPromiseFlatString(aID).get()));
NS_REINTERPRET_CAST(ContentListItem*, PL_HashTableLookup(mMap, (const PRUnichar *)PromiseFlatString(aID).get()));
while (item) {
aResults->AppendElement(item->mContent);
@ -349,7 +349,7 @@ nsElementMap::FindFirst(const nsAReadableString& aID, nsIContent** aResult)
return NS_ERROR_NOT_INITIALIZED;
ContentListItem* item =
NS_REINTERPRET_CAST(ContentListItem*, PL_HashTableLookup(mMap, (const PRUnichar *)nsPromiseFlatString(aID).get()));
NS_REINTERPRET_CAST(ContentListItem*, PL_HashTableLookup(mMap, (const PRUnichar *)PromiseFlatString(aID).get()));
if (item) {
*aResult = item->mContent;

View File

@ -378,7 +378,7 @@ nsXULCommandDispatcher::Matches(const nsString& aList,
if (aList.Equals(NS_LITERAL_STRING("*")))
return PR_TRUE; // match _everything_!
PRInt32 indx = aList.Find((const PRUnichar *)nsPromiseFlatString(aElement).get());
PRInt32 indx = aList.Find((const PRUnichar *)PromiseFlatString(aElement).get());
if (indx == -1)
return PR_FALSE; // not in the list at all

View File

@ -815,7 +815,7 @@ nsXULDocument::SetDocumentCharacterSet(const nsAReadableString& aCharSetID)
for (PRInt32 i = 0; i < n; i++) {
nsIObserver* observer = (nsIObserver*) mCharSetObservers.ElementAt(i);
observer->Observe((nsIDocument*) this, NS_LITERAL_STRING("charset").get(),
nsPromiseFlatString(aCharSetID).get());
PromiseFlatString(aCharSetID).get());
}
}
return NS_OK;

View File

@ -1140,7 +1140,7 @@ nsXULTemplateBuilder::SubstituteTextReplaceVariable(nsXULTemplateBuilder* aThis,
if (aVariable == NS_LITERAL_STRING("rdf:*"))
var = c->match.mRule->GetMemberVariable();
else
var = aThis->mRules.LookupSymbol(nsPromiseFlatString(aVariable).get());
var = aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get());
// No variable; treat as a variable with no substitution. (This
// shouldn't ever happen, really...)
@ -1204,7 +1204,7 @@ nsXULTemplateBuilder::IsVarInSet(nsXULTemplateBuilder* aThis,
IsVarInSetClosure* c = NS_STATIC_CAST(IsVarInSetClosure*, aClosure);
PRInt32 var =
aThis->mRules.LookupSymbol(nsPromiseFlatString(aVariable).get());
aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get());
// No variable; treat as a variable with no substitution. (This
// shouldn't ever happen, really...)
@ -2354,7 +2354,7 @@ nsXULTemplateBuilder::AddBindingsFor(nsXULTemplateBuilder* aThis,
nsTemplateRule* rule = NS_STATIC_CAST(nsTemplateRule*, aClosure);
// Lookup the variable symbol
PRInt32 var = aThis->mRules.LookupSymbol(nsPromiseFlatString(aVariable).get(), PR_TRUE);
PRInt32 var = aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get(), PR_TRUE);
// Strip it down to the raw RDF property by clobbering the "rdf:"
// prefix

View File

@ -1206,7 +1206,7 @@ nsWebShell :: IsCommandEnabled ( const nsAReadableString & inCommand, PRBool* ou
nsCOMPtr<nsIController> controller;
rv = GetControllerForCommand ( inCommand, getter_AddRefs(controller) );
if ( controller )
rv = controller->IsCommandEnabled(nsPromiseFlatString(inCommand).get(), outEnabled);
rv = controller->IsCommandEnabled(PromiseFlatString(inCommand).get(), outEnabled);
return rv;
}
@ -1220,7 +1220,7 @@ nsWebShell :: DoCommand ( const nsAReadableString & inCommand )
nsCOMPtr<nsIController> controller;
rv = GetControllerForCommand ( inCommand, getter_AddRefs(controller) );
if ( controller )
rv = controller->DoCommand(nsPromiseFlatString(inCommand).get());
rv = controller->DoCommand(PromiseFlatString(inCommand).get());
return rv;
}

View File

@ -146,7 +146,7 @@ nsDOMWindowList::NamedItem(const nsAReadableString& aName, nsIDOMWindow** aRetur
}
}
mDocShellNode->FindChildWithName(nsPromiseFlatString(aName).get(),
mDocShellNode->FindChildWithName(PromiseFlatString(aName).get(),
PR_FALSE, PR_FALSE,
nsnull, getter_AddRefs(item));

View File

@ -265,7 +265,7 @@ nsFocusController::GetParentWindowFromDocument(nsIDOMDocument* aDocument, nsIDOM
NS_IMETHODIMP
nsFocusController::GetControllerForCommand(const nsAReadableString& aCommand, nsIController** _retval)
{
nsPromiseFlatString flatCommand(aCommand);
const nsPromiseFlatString& flatCommand = PromiseFlatString(aCommand);
const PRUnichar *command = flatCommand.get();
*_retval = nsnull;

View File

@ -1017,7 +1017,7 @@ NS_IMETHODIMP GlobalWindowImpl::SetStatus(const nsAReadableString& aStatus)
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
if(browserChrome)
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT, nsPromiseFlatString(aStatus).get());
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT, PromiseFlatString(aStatus).get());
return NS_OK;
}
@ -1035,7 +1035,7 @@ NS_IMETHODIMP GlobalWindowImpl::SetDefaultStatus(const nsAReadableString& aDefau
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
if(browserChrome)
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT_DEFAULT, nsPromiseFlatString(aDefaultStatus).get());
browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT_DEFAULT, PromiseFlatString(aDefaultStatus).get());
return NS_OK;
}
@ -1056,7 +1056,7 @@ NS_IMETHODIMP GlobalWindowImpl::SetName(const nsAReadableString& aName)
nsresult result = NS_OK;
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
if (docShellAsItem)
result = docShellAsItem->SetName(nsPromiseFlatString(aName).get());
result = docShellAsItem->SetName(PromiseFlatString(aName).get());
return result;
}
@ -1136,7 +1136,7 @@ GlobalWindowImpl::SetTitle(const nsAReadableString& aTitle)
if(type == nsIDocShellTreeItem::typeChrome) {
nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
if(docShellAsWin) {
docShellAsWin->SetTitle(nsPromiseFlatString(mTitle).get());
docShellAsWin->SetTitle(PromiseFlatString(mTitle).get());
}
}
}
@ -2190,7 +2190,7 @@ NS_IMETHODIMP GlobalWindowImpl::Escape(const nsAReadableString& aStr, nsAWritabl
PRInt32 maxByteLen, srcLen;
srcLen = aStr.Length();
nsPromiseFlatString flatSrc(aStr);
const nsPromiseFlatString& flatSrc = PromiseFlatString(aStr);
const PRUnichar* src = flatSrc.get();
// Get the expected length of result string

View File

@ -486,7 +486,7 @@ nsJSContext::EvaluateStringWithValue(const nsAReadableString& aScript,
ok = ::JS_EvaluateUCScriptForPrincipals(mContext,
(JSObject *)aScopeObject,
jsprin,
(jschar*)(const PRUnichar*)nsPromiseFlatString(aScript).get(),
(jschar*)(const PRUnichar*)PromiseFlatString(aScript).get(),
aScript.Length(),
aURL,
aLineNo,
@ -602,7 +602,7 @@ nsJSContext::EvaluateString(const nsAReadableString& aScript,
ok = ::JS_EvaluateUCScriptForPrincipals(mContext,
(JSObject *)aScopeObject,
jsprin,
(jschar*)(const PRUnichar*)nsPromiseFlatString(aScript).get(),
(jschar*)(const PRUnichar*)PromiseFlatString(aScript).get(),
aScript.Length(),
aURL,
aLineNo,
@ -834,7 +834,7 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName,
JSFunction* fun =
::JS_CompileUCFunctionForPrincipals(mContext, target, jsprin,
charName, 1, gEventArgv,
(jschar*)(const PRUnichar*)nsPromiseFlatString(aBody).get(),
(jschar*)(const PRUnichar*)PromiseFlatString(aBody).get(),
aBody.Length(),
//XXXbe filename, lineno:
nsnull, 0);
@ -884,7 +884,7 @@ nsJSContext::CompileFunction(void* aTarget,
JSFunction* fun =
::JS_CompileUCFunctionForPrincipals(mContext, target, jsprin,
aName, aArgCount, aArgArray,
(jschar*)(const PRUnichar*)nsPromiseFlatString(aBody).get(),
(jschar*)(const PRUnichar*)PromiseFlatString(aBody).get(),
aBody.Length(),
aURL, aLineNo);

View File

@ -2965,7 +2965,7 @@ void nsEditorShell::GetBundleString(const nsAReadableString &stringName, nsAWrit
outString.Truncate();
nsXPIDLString tempString;
if (NS_SUCCEEDED(GetString(nsPromiseFlatString(stringName).get(), getter_Copies(tempString))) && tempString)
if (NS_SUCCEEDED(GetString(PromiseFlatString(stringName).get(), getter_Copies(tempString))) && tempString)
outString = tempString.get();
}

View File

@ -289,7 +289,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
nextNewline-posInString));
printf("Unquoted: appending '%s'\n", debug.ToNewCString());
#endif
aOutString.Append(nsPromiseSubstring<PRUnichar>(aInString, posInString,
aOutString.Append(nsPromiseSubstring(aInString, posInString,
nextNewline-posInString));
outStringCol += nextNewline - posInString;
if (nextNewline != (PRInt32)length)
@ -324,7 +324,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
nsAutoString debug (nsPromiseSubstring<PRUnichar>(aInString, posInString, nextNewline - posInString));
printf("Short line: '%s'\n", debug.ToNewCString());
#endif
aOutString += nsPromiseSubstring<PRUnichar>(aInString,
aOutString += nsPromiseSubstring(aInString,
posInString, nextNewline - posInString);
outStringCol += nextNewline - posInString;
posInString = nextNewline + 1;
@ -365,7 +365,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
printf("breakPt = %d\n", breakPt);
#endif
aOutString += nsPromiseSubstring<PRUnichar>(aInString, posInString, breakPt);
aOutString += nsPromiseSubstring(aInString, posInString, breakPt);
posInString += breakPt;
outStringCol += breakPt;

View File

@ -2965,7 +2965,7 @@ void nsEditorShell::GetBundleString(const nsAReadableString &stringName, nsAWrit
outString.Truncate();
nsXPIDLString tempString;
if (NS_SUCCEEDED(GetString(nsPromiseFlatString(stringName).get(), getter_Copies(tempString))) && tempString)
if (NS_SUCCEEDED(GetString(PromiseFlatString(stringName).get(), getter_Copies(tempString))) && tempString)
outString = tempString.get();
}

View File

@ -289,7 +289,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
nextNewline-posInString));
printf("Unquoted: appending '%s'\n", debug.ToNewCString());
#endif
aOutString.Append(nsPromiseSubstring<PRUnichar>(aInString, posInString,
aOutString.Append(nsPromiseSubstring(aInString, posInString,
nextNewline-posInString));
outStringCol += nextNewline - posInString;
if (nextNewline != (PRInt32)length)
@ -324,7 +324,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
nsAutoString debug (nsPromiseSubstring<PRUnichar>(aInString, posInString, nextNewline - posInString));
printf("Short line: '%s'\n", debug.ToNewCString());
#endif
aOutString += nsPromiseSubstring<PRUnichar>(aInString,
aOutString += nsPromiseSubstring(aInString,
posInString, nextNewline - posInString);
outStringCol += nextNewline - posInString;
posInString = nextNewline + 1;
@ -365,7 +365,7 @@ nsInternetCiter::Rewrap(const nsString& aInString,
printf("breakPt = %d\n", breakPt);
#endif
aOutString += nsPromiseSubstring<PRUnichar>(aInString, posInString, breakPt);
aOutString += nsPromiseSubstring(aInString, posInString, breakPt);
posInString += breakPt;
outStringCol += breakPt;

View File

@ -1058,7 +1058,7 @@ ChromeTooltipListener :: ShowTooltip ( PRInt32 inXCoords, PRInt32 inYCoords, con
// do the work to call the client
nsCOMPtr<nsITooltipListener> tooltipListener ( do_QueryInterface(mWebBrowserChrome) );
if ( tooltipListener ) {
rv = tooltipListener->OnShowTooltip ( inXCoords, inYCoords, nsPromiseFlatString(inTipText).get() );
rv = tooltipListener->OnShowTooltip ( inXCoords, inYCoords, PromiseFlatString(inTipText).get() );
if ( NS_SUCCEEDED(rv) )
mShowingTooltip = PR_TRUE;
}

View File

@ -1047,7 +1047,7 @@ wallet_WriteToList(
added_to_list = PR_TRUE;
break;
}
} else if((mapElementPtr->item1.Compare(item1))>=0) {
} else if(Compare(mapElementPtr->item1,item1)>=0) {
list->InsertElementAt(mapElement, i);
added_to_list = PR_TRUE;
break;

View File

@ -289,7 +289,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
{
nsresult res;
PRUnichar *encodedBuffer = nsnull;
res = mEntityConverter->ConvertToEntities(nsPromiseFlatString(aString).get(),
res = mEntityConverter->ConvertToEntities(PromiseFlatString(aString).get(),
nsIEntityConverter::html40Latin1,
&encodedBuffer);
if (NS_SUCCEEDED(res) && encodedBuffer)
@ -328,7 +328,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
{
// Call the converter to convert to the target charset.
// Convert() takes a char* output param even though it's writing unicode.
res = mCharsetEncoder->Convert(nsPromiseFlatString(aString).get(), &encodedBuffer);
res = mCharsetEncoder->Convert(PromiseFlatString(aString).get(), &encodedBuffer);
if (NS_SUCCEEDED(res) && encodedBuffer)
{
charsWritten = nsCRT::strlen(encodedBuffer);
@ -340,7 +340,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
else
{
charsWritten = aString.Length();
out.write(nsPromiseFlatString(aString).get(), charsWritten);
out.write(PromiseFlatString(aString).get(), charsWritten);
}
}
@ -348,7 +348,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
else
{
charsWritten = aString.Length();
out.write(nsPromiseFlatString(aString).get(), charsWritten);
out.write(PromiseFlatString(aString).get(), charsWritten);
}
return charsWritten;

View File

@ -711,7 +711,7 @@ nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
/*
if you're stepping through the string anyway, why not use iterators instead of forcing the string to copy?
*/
nsPromiseFlatString flat(aValue);
const nsPromiseFlatString& flat = PromiseFlatString(aValue);
const PRUnichar* cp = flat.get();
const PRUnichar* end = cp + aValue.Length();
while (cp < end) {

View File

@ -1219,13 +1219,13 @@ private:
};
// class to export a JSString as an nsAReadableString, including refcounting
class XPCReadableJSStringWrapper : public nsLiteralString
class XPCReadableJSStringWrapper : public nsLocalString
{
public:
XPCReadableJSStringWrapper(JSString *str) :
nsLiteralString(NS_REINTERPRET_CAST(PRUnichar *,
JS_GetStringChars(str)),
JS_GetStringLength(str)),
nsLocalString(NS_REINTERPRET_CAST(PRUnichar *,
JS_GetStringChars(str)),
JS_GetStringLength(str)),
mStr(str), mBufferHandle(0), mHandleIsShared(JS_FALSE)
{ }

View File

@ -280,7 +280,7 @@ PRBool nsOEScanBoxes::FindMailBoxes( nsIFileSpec* descFile)
#endif
pEntry->fileName.Right( ext, 4);
if (ext.Compare( mbxExt))
if (Compare(ext, mbxExt))
pEntry->fileName.Append( ".mbx");
m_entryArray.AppendElement( pEntry);

View File

@ -289,7 +289,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
{
nsresult res;
PRUnichar *encodedBuffer = nsnull;
res = mEntityConverter->ConvertToEntities(nsPromiseFlatString(aString).get(),
res = mEntityConverter->ConvertToEntities(PromiseFlatString(aString).get(),
nsIEntityConverter::html40Latin1,
&encodedBuffer);
if (NS_SUCCEEDED(res) && encodedBuffer)
@ -328,7 +328,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
{
// Call the converter to convert to the target charset.
// Convert() takes a char* output param even though it's writing unicode.
res = mCharsetEncoder->Convert(nsPromiseFlatString(aString).get(), &encodedBuffer);
res = mCharsetEncoder->Convert(PromiseFlatString(aString).get(), &encodedBuffer);
if (NS_SUCCEEDED(res) && encodedBuffer)
{
charsWritten = nsCRT::strlen(encodedBuffer);
@ -340,7 +340,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
else
{
charsWritten = aString.Length();
out.write(nsPromiseFlatString(aString).get(), charsWritten);
out.write(PromiseFlatString(aString).get(), charsWritten);
}
}
@ -348,7 +348,7 @@ PRInt32 nsHTMLContentSinkStream::Write(const nsAReadableString& aString)
else
{
charsWritten = aString.Length();
out.write(nsPromiseFlatString(aString).get(), charsWritten);
out.write(PromiseFlatString(aString).get(), charsWritten);
}
return charsWritten;

View File

@ -711,7 +711,7 @@ nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
/*
if you're stepping through the string anyway, why not use iterators instead of forcing the string to copy?
*/
nsPromiseFlatString flat(aValue);
const nsPromiseFlatString& flat = PromiseFlatString(aValue);
const PRUnichar* cp = flat.get();
const PRUnichar* end = cp + aValue.Length();
while (cp < end) {

View File

@ -21,11 +21,9 @@
- Scott Collins <scc@mozilla.org> (original author)
-->
<body>
<h1><span class="LXRSHORTDESC">string code will be moving here soon</span></h1>
<h1><span class="LXRSHORTDESC">managing sequences of characters</span></h1>
<p>
<span class="LXRLONGDESC">The string code will be moving here soon;
in the meantime, you can find the bulk of it in
<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/">mozilla/xpcom/ds</a>.</span>
<span class="LXRLONGDESC"></span>
</p>
</body>
</html>

View File

@ -21,7 +21,7 @@
- Scott Collins <scc@mozilla.org> (original author)
-->
<body>
<h1><span class="LXRSHORTDESC">string doc will be moving here soon</span></h1>
<h1><span class="LXRSHORTDESC">documentation aimed at programmers who are clients of the string library</span></h1>
<p>
<span class="LXRLONGDESC"></span>
</p>

Binary file not shown.

View File

@ -17,10 +17,8 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Rick Gessner <rickg@netscape.com>
*
* Contributor(s):
* Rick Gessner <rickg@netscape.com> (original author)
* Scott Collins <scc@mozilla.org>
*/

View File

@ -42,6 +42,11 @@ static const char* kPossibleNull = "Error: possible unintended null in string";
static const char* kNullPointerError = "Error: unexpected null ptr";
static const char* kWhitespace="\b\t\r\n ";
const nsBufferHandle<char>*
nsCString::GetFlatBufferHandle() const
{
return NS_REINTERPRET_CAST(const nsBufferHandle<char>*, 1);
}
static void CSubsume(nsStr& aDest,nsStr& aSource){
if(aSource.mStr && aSource.mLength) {
@ -165,7 +170,7 @@ char* nsCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFra
}
}
nsCString::nsCString( const nsAReadableCString& aReadable ) {
nsCString::nsCString( const nsACString& aReadable ) {
Initialize(*this,eOneByte);
Assign(aReadable);
}
@ -774,7 +779,7 @@ void nsCString::AssignWithConversion( const nsString& aString ) {
AssignWithConversion(aString.GetUnicode(), aString.Length());
}
void nsCString::AssignWithConversion( const nsAReadableString& aString ) {
void nsCString::AssignWithConversion( const nsAString& aString ) {
nsStr::StrTruncate(*this,0);
PRInt32 count = aString.Length();
@ -792,13 +797,13 @@ void nsCString::AssignWithConversion( const nsAReadableString& aString ) {
temp.mLength=fraglen;
StrAppend(*this,temp,0,fraglen);
start += fraglen;
start.advance(fraglen);
}
}
}
void nsCString::AppendWithConversion( const nsAReadableString& aString ) {
void nsCString::AppendWithConversion( const nsAString& aString ) {
PRInt32 count = aString.Length();
if(count){
@ -816,7 +821,7 @@ void nsCString::AppendWithConversion( const nsAReadableString& aString ) {
StrAppend(*this,temp,0,fraglen);
start += fraglen;
start.advance(fraglen);
}
}
}
@ -832,14 +837,6 @@ void nsCString::AssignWithConversion(PRUnichar aChar) {
AppendWithConversion(aChar);
}
void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable )
{
if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) )
StrAppend(*this, NS_STATIC_CAST(const nsCString&, aReadable), 0, aReadable.Length());
else
nsAWritableCString::do_AppendFromReadable(aReadable);
}
/**
* append given char to this string
@ -962,14 +959,6 @@ void nsCString::InsertWithConversion(PRUnichar aChar,PRUint32 anOffset){
StrInsert(*this,anOffset,temp,0,1);
}
void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUint32 atPosition )
{
if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) )
StrInsert(*this, atPosition, NS_STATIC_CAST(const nsCString&, aReadable), 0, aReadable.Length());
else
nsAWritableCString::do_InsertFromReadable(aReadable, atPosition);
}
@ -1382,7 +1371,7 @@ void nsCString::DebugDump(void) const {
//----------------------------------------------------------------------
NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAReadableString& aString )
NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAString& aString )
{
nsReadingIterator<PRUnichar> start; aString.BeginReading(start);
nsReadingIterator<PRUnichar> end; aString.EndReading(end);
@ -1390,7 +1379,7 @@ NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAReadableString& aString )
while (start != end) {
nsReadableFragment<PRUnichar> frag(start.fragment());
Append(frag.mStart, frag.mEnd - frag.mStart);
start += start.size_forward();
start.advance(start.size_forward());
}
}
@ -1511,7 +1500,7 @@ nsCAutoString::nsCAutoString( const nsCString& aString ) : nsCString(){
Append(aString);
}
nsCAutoString::nsCAutoString( const nsAReadableCString& aString ) : nsCString(){
nsCAutoString::nsCAutoString( const nsACString& aString ) : nsCString(){
Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE);
AddNullTerminator(*this);
Append(aString);

View File

@ -50,17 +50,27 @@
#include "nsStr.h"
#include "nsIAtom.h"
#include "nsAString.h"
/* this file will one day be _only_ a compatibility header for clients using the names
|ns[C]String| et al ... which we probably want to support forever.
In the mean time, people are used to getting the names |nsAReadable[C]String| and friends
from here as well; so we must continue to include the other compatibility headers
even though we don't use them ourself.
*/
#include "nsAWritableString.h"
// for compatibility
class NS_COM nsSubsumeCStr;
class NS_COM nsCString :
public nsAWritableCString,
public nsAFlatCString,
public nsStr {
protected:
virtual const void* Implementation() const { return "nsCString"; }
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const;
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
@ -79,7 +89,7 @@ public:
*/
nsCString(const nsCString& aString);
explicit nsCString( const nsAReadableCString& );
explicit nsCString( const nsACString& );
explicit nsCString(const char*);
nsCString(const char*, PRInt32);
@ -298,14 +308,14 @@ public:
*/
nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; }
nsCString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
//nsCString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCString& operator=( char aChar ) { Assign(aChar); return *this; }
void AssignWithConversion(const PRUnichar*,PRInt32=-1);
void AssignWithConversion( const nsString& aString );
void AssignWithConversion( const nsAReadableString& aString );
void AssignWithConversion( const nsAString& aString );
void AssignWithConversion(PRUnichar);
/*
@ -320,18 +330,20 @@ public:
void AppendWithConversion(const nsString&, PRInt32=-1);
void AppendWithConversion(PRUnichar aChar);
void AppendWithConversion( const nsAReadableString& aString );
void AppendWithConversion( const nsAString& aString );
void AppendWithConversion(const PRUnichar*, PRInt32=-1);
// Why no |AppendWithConversion(const PRUnichar*, PRInt32)|? --- now I know, because implicit construction hid the need for this routine
void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
void AppendFloat( double aFloat );
virtual void do_AppendFromReadable( const nsAReadableCString& );
void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset);
// Why no |InsertWithConversion(PRUnichar*)|?
virtual void do_InsertFromReadable( const nsAReadableCString&, PRUint32 );
#if 0
virtual void do_AppendFromReadable( const nsACString& );
virtual void do_InsertFromReadable( const nsACString&, PRUint32 );
#endif
/**********************************************************************
@ -446,7 +458,7 @@ private:
};
// NS_DEF_STRING_COMPARISON_OPERATORS(nsCString, char)
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char)
extern NS_COM int fputs(const nsCString& aString, FILE* out);
//ostream& operator<<(ostream& aStream,const nsCString& aString);
@ -466,7 +478,7 @@ public:
nsCAutoString();
explicit nsCAutoString(const nsCString& );
explicit nsCAutoString(const nsAReadableCString& aString);
explicit nsCAutoString(const nsACString& aString);
explicit nsCAutoString(const char* aString);
nsCAutoString(const char* aString,PRInt32 aLength);
explicit nsCAutoString(const CBufDescriptor& aBuffer);
@ -482,8 +494,8 @@ public:
private:
void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED
public:
nsCAutoString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
// nsCAutoString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; }
@ -496,7 +508,7 @@ public:
char mBuffer[kDefaultStringSize];
};
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
/**
* A helper class that converts a UCS2 string to UTF8
@ -525,7 +537,7 @@ class NS_COM NS_ConvertUCS2toUTF8
Append( &aChar, 1 );
}
explicit NS_ConvertUCS2toUTF8( const nsAReadableString& aString );
explicit NS_ConvertUCS2toUTF8( const nsAString& aString );
protected:
void Append( const PRUnichar* aString, PRUint32 aLength );
@ -533,7 +545,7 @@ class NS_COM NS_ConvertUCS2toUTF8
private:
// NOT TO BE IMPLEMENTED
NS_ConvertUCS2toUTF8( char );
operator const char*() const; // use |get()|
operator const char*() const; // use |get()|
};
@ -557,8 +569,8 @@ public:
nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); return *this; }
nsSubsumeCStr& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
//nsSubsumeCStr& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsSubsumeCStr& operator=( char aChar ) { Assign(aChar); return *this; }
private:

View File

@ -39,6 +39,13 @@ static const char* kPossibleNull = "Error: possible unintended null in string";
static const char* kNullPointerError = "Error: unexpected null ptr";
static const char* kWhitespace="\b\t\r\n ";
const nsBufferHandle<PRUnichar>*
nsString::GetFlatBufferHandle() const
{
return NS_REINTERPRET_CAST(const nsBufferHandle<PRUnichar>*, 1);
}
static void Subsume(nsStr& aDest,nsStr& aSource){
if(aSource.mStr && aSource.mLength) {
@ -165,7 +172,7 @@ nsString::do_AppendFromElement( PRUnichar inChar )
}
nsString::nsString( const nsAReadableString& aReadable ) {
nsString::nsString( const nsAString& aReadable ) {
Initialize(*this,eTwoByte);
Assign(aReadable);
}
@ -1647,7 +1654,7 @@ nsAutoString::nsAutoString( const nsString& aString )
Append(aString);
}
nsAutoString::nsAutoString( const nsAReadableString& aString )
nsAutoString::nsAutoString( const nsAString& aString )
: nsString()
{
Initialize(*this, mBuffer, (sizeof(mBuffer)>>eTwoByte)-1, 0, eTwoByte, PR_FALSE);

View File

@ -52,11 +52,12 @@
#include "nsStr.h"
#include "nsCRT.h"
#include "nsAWritableString.h"
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
#ifdef STANDALONE_MI_STRING_TESTS
class nsAReadableString { public: virtual ~nsAReadableString() { } };
class nsAWritableString : public nsAReadableString { public: virtual ~nsAWritableString() { } };
class nsAFlatString { public: virtual ~nsAString() { } };
#endif
class nsISizeOfHandler;
@ -68,11 +69,11 @@ class nsISizeOfHandler;
class NS_COM nsSubsumeStr;
class NS_COM nsString :
public nsAWritableString,
public nsAFlatString,
public nsStr {
protected:
virtual const void* Implementation() const { return "nsString"; }
virtual const nsBufferHandle<PRUnichar>* GetFlatBufferHandle() const;
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
@ -91,7 +92,7 @@ public:
*/
nsString(const nsString& aString);
explicit nsString(const nsAReadableString&);
explicit nsString(const nsAString&);
explicit nsString(const PRUnichar*);
nsString(const PRUnichar*, PRInt32);
@ -342,8 +343,8 @@ public:
*/
nsString& operator=( const nsString& aString ) { Assign(aString); return *this; }
nsString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
//nsString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
@ -526,7 +527,7 @@ private:
};
// NS_DEF_STRING_COMPARISON_OPERATORS(nsString, PRUnichar)
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsString, PRUnichar)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsString, PRUnichar)
extern NS_COM int fputs(const nsString& aString, FILE* out);
//ostream& operator<<(ostream& aStream,const nsString& aString);
@ -544,7 +545,7 @@ public:
virtual ~nsAutoString();
nsAutoString();
nsAutoString(const nsAutoString& aString);
explicit nsAutoString(const nsAReadableString& aString);
explicit nsAutoString(const nsAString& aString);
explicit nsAutoString(const nsString& aString);
explicit nsAutoString(const PRUnichar* aString);
nsAutoString(const PRUnichar* aString,PRInt32 aLength);
@ -562,8 +563,8 @@ public:
private:
void operator=( char ); // NOT TO BE IMPLEMENTED
public:
nsAutoString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
// nsAutoString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsAutoString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
@ -576,7 +577,7 @@ public:
char mBuffer[kDefaultStringSize<<eTwoByte];
};
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsAutoString, PRUnichar)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsAutoString, PRUnichar)
class NS_COM NS_ConvertASCIItoUCS2
: public nsAutoString
@ -589,10 +590,12 @@ class NS_COM NS_ConvertASCIItoUCS2
NS_ConvertASCIItoUCS2( const char*, PRUint32 );
explicit NS_ConvertASCIItoUCS2( char );
operator const nsLiteralString() const
#if 0
operator const nsLocalString() const
{
return nsLiteralString(mUStr, mLength);
return nsLocalString(mUStr, mLength);
}
#endif
private:
// NOT TO BE IMPLEMENTED
@ -649,8 +652,8 @@ public:
int Subsume(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
nsSubsumeStr& operator=( const nsSubsumeStr& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
//nsSubsumeStr& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsSubsumeStr& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
private:

View File

@ -21,15 +21,29 @@
#
nsAFlatString.h
nsAlgorithm.h
nsAPromiseString.h
nsAReadableString.h
nsAString.h
nsAWritableString.h
nsBufferHandle.h
nsBufferHandleUtils.h
nsCharTraits.h
nsCommonString.h
nsFragmentedString.h
nsLiteralString.h
nsLocalString.h
nsPrintfCString.h
nsPrivateSharableString.h
nsPromiseConcatenation.h
nsPromiseFlatString.h
nsPromiseSubstring.h
nsReadableUtils.h
nsSharedBufferList.h
nsSlidingString.h
nsStringFragment.h
nsStringFwd.h
nsStringIterator.h
nsStringIteratorUtils.h
nsStringTraits.h

View File

@ -18,6 +18,7 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH = ../..
@ -30,18 +31,32 @@ include $(DEPTH)/config/autoconf.mk
MODULE = string
EXPORTS = \
nsAFlatString.h \
nsAlgorithm.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsPrivateSharableString.h \
nsAPromiseString.h \
nsAReadableString.h \
nsAString.h \
nsAWritableString.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsCharTraits.h \
nsAReadableString.h \
nsAWritableString.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsFragmentedString.h \
nsPrintfCString.h \
nsCommonString.h \
nsFragmentedString.h \
nsLiteralString.h \
nsLocalString.h \
nsPrintfCString.h \
nsPrivateSharableString.h \
nsPromiseConcatenation.h \
nsPromiseFlatString.h \
nsPromiseSubstring.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsStringFragment.h \
nsStringFwd.h \
nsStringIterator.h \
nsStringIteratorUtils.h \
nsStringTraits.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -19,23 +19,38 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH=..\..
EXPORTS = \
nsAFlatString.h \
nsAlgorithm.h \
nsAPromiseString.h \
nsAReadableString.h \
nsAString.h \
nsAWritableString.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsCharTraits.h \
nsCommonString.h \
nsFragmentedString.h \
nsLiteralString.h \
nsLocalString.h \
nsPrintfCString.h \
nsPrivateSharableString.h \
nsPromiseConcatenation.h \
nsPromiseFlatString.h \
nsPromiseSubstring.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsStringFragment.h \
nsStringFwd.h \
nsStringIterator.h \
nsStringIteratorUtils.h \
nsStringTraits.h \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsAFlatString.h --- */
#ifndef nsAFlatString_h___
#define nsAFlatString_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
class NS_COM nsAFlatString
: public nsAString
{
public:
// don't really want this to be virtual, and won't after |obsolete_nsString| is really dead
virtual const PRUnichar* get() const { return GetBufferHandle()->DataStart(); }
PRUnichar operator[]( PRUint32 i ) const { return get()[ i ]; }
PRUnichar CharAt( PRUint32 ) const;
virtual PRUint32 Length() const { return PRUint32(GetBufferHandle()->DataLength()); }
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
};
class NS_COM nsAFlatCString
: public nsACString
{
public:
// don't really want this to be virtual, and won't after |obsolete_nsCString| is really dead
virtual const char* get() const { return GetBufferHandle()->DataStart(); }
char operator[]( PRUint32 i ) const { return get()[ i ]; }
char CharAt( PRUint32 ) const;
virtual PRUint32 Length() const { return PRUint32(GetBufferHandle()->DataLength()); }
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
};
inline
PRUnichar
nsAFlatString::CharAt( PRUint32 i ) const
{
NS_ASSERTION(i<Length(), "|CharAt| out-of-range");
return operator[](i);
}
inline
char
nsAFlatCString::CharAt( PRUint32 i ) const
{
NS_ASSERTION(i<Length(), "|CharAt| out-of-range");
return operator[](i);
}
#endif /* !defined(nsAFlatString_h___) */

View File

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsAPromiseString.h --- abstract base class for strings don't actually own their own characters, but proxy data from other strings */
#ifndef nsAPromiseString_h___
#define nsAPromiseString_h___
/**
* Don't |#include| this file yourself. You will get it automatically if you need it.
*
* Why is it a separate file? To make it easier to find the classes in your local tree.
*/
class NS_COM nsAPromiseString : public nsAString { };
class NS_COM nsAPromiseCString : public nsACString { };
#endif /* !defined(nsAPromiseString_h___) */

File diff suppressed because it is too large Load Diff

772
string/public/nsAString.h Normal file
View File

@ -0,0 +1,772 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsAString_h___
#define nsAString_h___
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nsPrivateSharableString_h___
#include "nsPrivateSharableString.h"
#endif
#ifndef nsCharTraits_h___
#include "nsCharTraits.h"
#endif
#ifndef nsStringIterator_h___
#include "nsStringIterator.h"
#endif
/**
*
*/
class NS_COM nsAString
: public nsPrivateSharableString
{
public:
typedef nsAString self_type;
typedef nsAPromiseString promise_type;
typedef PRUnichar char_type;
typedef char incompatible_char_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
// nsAString(); // auto-generated default constructor OK (we're abstract anyway)
// nsAString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract)
virtual ~nsAString() { } // ...yes, I expect to be sub-classed
inline const_iterator& BeginReading( const_iterator& ) const;
inline const_iterator& EndReading( const_iterator& ) const;
inline iterator& BeginWriting( iterator& );
inline iterator& EndWriting( iterator& );
virtual size_type Length() const = 0;
PRBool IsEmpty() const { return Length() == 0; }
inline PRBool Equals( const self_type& ) const;
PRBool Equals( const char_type* ) const;
/**
* |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations.
* These signatures should be pushed down into interfaces that guarantee flat allocation.
* Clients at _this_ level should always use iterators.
*/
char_type First() const;
char_type Last() const;
size_type CountChar( char_type ) const;
/*
|Left|, |Mid|, and |Right| are annoying signatures that seem better almost
any _other_ way than they are now. Consider these alternatives
aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
Left(aReadable, 17, aWritable); // ...a global function that does the assignment
as opposed to the current signature
aReadable.Left(aWritable, 17); // ...a member function that does the assignment
or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
aWritable = Substring(aReadable, 0, 17);
*/
size_type Left( self_type&, size_type ) const;
size_type Mid( self_type&, PRUint32, PRUint32 ) const;
size_type Right( self_type&, size_type ) const;
// Find( ... ) const;
PRInt32 FindChar( char_type, index_type aOffset = 0 ) const;
// FindCharInSet( ... ) const;
// RFind( ... ) const;
// RFindChar( ... ) const;
// RFindCharInSet( ... ) const;
/**
* |SetCapacity| is not required to do anything; however, it can be used
* as a hint to the implementation to reduce allocations.
* |SetCapacity(0)| is a suggestion to discard all associated storage.
*/
virtual void SetCapacity( size_type ) { }
/**
* |SetLength| is used in two ways:
* 1) to |Cut| a suffix of the string;
* 2) to prepare to |Append| or move characters around.
*
* External callers are not allowed to use |SetLength| is this latter capacity.
* Should this really be a public operation?
* Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you
* override the |do_...| routines to not need this facility.
*
* This distinction makes me think the two different uses should be split into
* two distinct functions.
*/
virtual void SetLength( size_type ) { }
void
Truncate( size_type aNewLength=0 )
{
NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer.");
if ( aNewLength < this->Length() )
SetLength(aNewLength);
}
// PRBool SetCharAt( char_type, index_type ) = 0;
// void ToLowerCase();
// void ToUpperCase();
// void StripChars( const char_type* aSet );
// void StripChar( ... );
// void StripWhitespace();
// void ReplaceChar( ... );
// void ReplaceSubstring( ... );
// void Trim( ... );
// void CompressSet( ... );
// void CompressWhitespace( ... );
//
// |Assign()|, |operator=()|
//
void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); }
inline void Assign( const promise_type& aReadable );
void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); }
void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); }
void Assign( char_type aChar ) { do_AssignFromElement(aChar); }
// copy-assignment operator. I must define my own if I don't want the compiler to make me one
self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; }
self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; }
self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; }
self_type& operator=( char_type aChar ) { Assign(aChar); return *this; }
//
// |Append()|, |operator+=()|
//
void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); }
inline void Append( const promise_type& aReadable );
void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); }
void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); }
void Append( char_type aChar ) { do_AppendFromElement(aChar); }
self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; }
self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; }
self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; }
self_type& operator+=( char_type aChar ) { Append(aChar); return *this; }
/**
* The following index based routines need to be recast with iterators.
*/
//
// |Insert()|
// Note: I would really like to move the |atPosition| parameter to the front of the argument list
//
void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); }
inline void Insert( const promise_type& aReadable, index_type atPosition );
void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); }
void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); }
void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); }
virtual void Cut( index_type cutStart, size_type cutLength );
void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); }
// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); }
private:
// NOT TO BE IMPLEMENTED
index_type CountChar( incompatible_char_type ) const;
void operator= ( incompatible_char_type );
void Assign ( incompatible_char_type );
void operator+= ( incompatible_char_type );
void Append ( incompatible_char_type );
void Insert ( incompatible_char_type, index_type );
protected:
void AssignFromReadable( const self_type& );
void AssignFromPromise( const self_type& );
virtual void do_AssignFromReadable( const self_type& );
virtual void do_AssignFromElementPtr( const char_type* );
virtual void do_AssignFromElementPtrLength( const char_type*, size_type );
virtual void do_AssignFromElement( char_type );
void AppendFromReadable( const self_type& );
void AppendFromPromise( const self_type& );
virtual void do_AppendFromReadable( const self_type& );
virtual void do_AppendFromElementPtr( const char_type* );
virtual void do_AppendFromElementPtrLength( const char_type*, size_type );
virtual void do_AppendFromElement( char_type );
void InsertFromReadable( const self_type&, index_type );
void InsertFromPromise( const self_type&, index_type );
virtual void do_InsertFromReadable( const self_type&, index_type );
virtual void do_InsertFromElementPtr( const char_type*, index_type );
virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type );
virtual void do_InsertFromElement( char_type, index_type );
void ReplaceFromReadable( index_type, size_type, const self_type& );
void ReplaceFromPromise( index_type, size_type, const self_type& );
virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& );
// protected:
public:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
virtual PRBool Promises( const self_type& aString ) const { return &aString == this; }
};
class NS_COM nsACString
: public nsPrivateSharableCString
{
public:
typedef nsACString self_type;
typedef nsAPromiseCString promise_type;
typedef char char_type;
typedef PRUnichar incompatible_char_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
// nsACString(); // auto-generated default constructor OK (we're abstract anyway)
// nsACString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract)
virtual ~nsACString() { } // ...yes, I expect to be sub-classed
inline const_iterator& BeginReading( const_iterator& ) const;
inline const_iterator& EndReading( const_iterator& ) const;
inline iterator& BeginWriting( iterator& );
inline iterator& EndWriting( iterator& );
virtual size_type Length() const = 0;
PRBool IsEmpty() const { return Length() == 0; }
inline PRBool Equals( const self_type& ) const;
PRBool Equals( const char_type* ) const;
/**
* |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations.
* These signatures should be pushed down into interfaces that guarantee flat allocation.
* Clients at _this_ level should always use iterators.
*/
char_type First() const;
char_type Last() const;
size_type CountChar( char_type ) const;
/*
|Left|, |Mid|, and |Right| are annoying signatures that seem better almost
any _other_ way than they are now. Consider these alternatives
aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
Left(aReadable, 17, aWritable); // ...a global function that does the assignment
as opposed to the current signature
aReadable.Left(aWritable, 17); // ...a member function that does the assignment
or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
aWritable = Substring(aReadable, 0, 17);
*/
size_type Left( self_type&, size_type ) const;
size_type Mid( self_type&, PRUint32, PRUint32 ) const;
size_type Right( self_type&, size_type ) const;
// Find( ... ) const;
PRInt32 FindChar( char_type, PRUint32 aOffset = 0 ) const;
// FindCharInSet( ... ) const;
// RFind( ... ) const;
// RFindChar( ... ) const;
// RFindCharInSet( ... ) const;
/**
* |SetCapacity| is not required to do anything; however, it can be used
* as a hint to the implementation to reduce allocations.
* |SetCapacity(0)| is a suggestion to discard all associated storage.
*/
virtual void SetCapacity( size_type ) { }
/**
* |SetLength| is used in two ways:
* 1) to |Cut| a suffix of the string;
* 2) to prepare to |Append| or move characters around.
*
* External callers are not allowed to use |SetLength| is this latter capacity.
* Should this really be a public operation?
* Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you
* override the |do_...| routines to not need this facility.
*
* This distinction makes me think the two different uses should be split into
* two distinct functions.
*/
virtual void SetLength( size_type ) { }
void
Truncate( size_type aNewLength=0 )
{
NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer.");
if ( aNewLength < this->Length() )
SetLength(aNewLength);
}
// PRBool SetCharAt( char_type, index_type ) = 0;
// void ToLowerCase();
// void ToUpperCase();
// void StripChars( const char_type* aSet );
// void StripChar( ... );
// void StripWhitespace();
// void ReplaceChar( ... );
// void ReplaceSubstring( ... );
// void Trim( ... );
// void CompressSet( ... );
// void CompressWhitespace( ... );
//
// |Assign()|, |operator=()|
//
void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); }
inline void Assign( const promise_type& aReadable );
void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); }
void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); }
void Assign( char_type aChar ) { do_AssignFromElement(aChar); }
// copy-assignment operator. I must define my own if I don't want the compiler to make me one
self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; }
self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; }
self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; }
self_type& operator=( char_type aChar ) { Assign(aChar); return *this; }
//
// |Append()|, |operator+=()|
//
void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); }
inline void Append( const promise_type& aReadable );
void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); }
void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); }
void Append( char_type aChar ) { do_AppendFromElement(aChar); }
self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; }
self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; }
self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; }
self_type& operator+=( char_type aChar ) { Append(aChar); return *this; }
/**
* The following index based routines need to be recast with iterators.
*/
//
// |Insert()|
// Note: I would really like to move the |atPosition| parameter to the front of the argument list
//
void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); }
inline void Insert( const promise_type& aReadable, index_type atPosition );
void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); }
void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); }
void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); }
virtual void Cut( index_type cutStart, size_type cutLength );
void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); }
// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); }
private:
// NOT TO BE IMPLEMENTED
index_type CountChar( incompatible_char_type ) const;
void operator= ( incompatible_char_type );
void Assign ( incompatible_char_type );
void operator+= ( incompatible_char_type );
void Append ( incompatible_char_type );
void Insert ( incompatible_char_type, index_type );
protected:
void AssignFromReadable( const self_type& );
void AssignFromPromise( const self_type& );
virtual void do_AssignFromReadable( const self_type& );
virtual void do_AssignFromElementPtr( const char_type* );
virtual void do_AssignFromElementPtrLength( const char_type*, size_type );
virtual void do_AssignFromElement( char_type );
void AppendFromReadable( const self_type& );
void AppendFromPromise( const self_type& );
virtual void do_AppendFromReadable( const self_type& );
virtual void do_AppendFromElementPtr( const char_type* );
virtual void do_AppendFromElementPtrLength( const char_type*, size_type );
virtual void do_AppendFromElement( char_type );
void InsertFromReadable( const self_type&, index_type );
void InsertFromPromise( const self_type&, index_type );
virtual void do_InsertFromReadable( const self_type&, index_type );
virtual void do_InsertFromElementPtr( const char_type*, index_type );
virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type );
virtual void do_InsertFromElement( char_type, index_type );
void ReplaceFromReadable( index_type, size_type, const self_type& );
void ReplaceFromPromise( index_type, size_type, const self_type& );
virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& );
// protected:
public:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
virtual PRBool Promises( const self_type& aString ) const { return &aString == this; }
};
#include "nsAPromiseString.h"
inline
void
nsAString::Assign( const nsAPromiseString& aReadable )
{
AssignFromPromise(aReadable);
}
inline
void
nsAString::Append( const nsAPromiseString& aReadable )
{
AppendFromPromise(aReadable);
}
inline
void
nsAString::Insert( const nsAPromiseString& aReadable, index_type atPosition )
{
InsertFromPromise(aReadable, atPosition);
}
inline
void
nsACString::Assign( const nsAPromiseCString& aReadable )
{
AssignFromPromise(aReadable);
}
inline
void
nsACString::Append( const nsAPromiseCString& aReadable )
{
AppendFromPromise(aReadable);
}
inline
void
nsACString::Insert( const nsAPromiseCString& aReadable, index_type atPosition )
{
InsertFromPromise(aReadable, atPosition);
}
/**
* Note: measure -- should the |Begin...| and |End...| be |inline|?
*/
inline
nsAString::const_iterator&
nsAString::BeginReading( const_iterator& aResult ) const
{
aResult.mOwningString = this;
GetReadableFragment(aResult.mFragment, kFirstFragment);
aResult.mPosition = aResult.mFragment.mStart;
aResult.normalize_forward();
return aResult;
}
inline
nsAString::const_iterator&
nsAString::EndReading( const_iterator& aResult ) const
{
aResult.mOwningString = this;
GetReadableFragment(aResult.mFragment, kLastFragment);
aResult.mPosition = aResult.mFragment.mEnd;
// must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
return aResult;
}
inline
nsAString::iterator&
nsAString::BeginWriting( iterator& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kFirstFragment);
aResult.mPosition = aResult.mFragment.mStart;
aResult.normalize_forward();
return aResult;
}
inline
nsAString::iterator&
nsAString::EndWriting( iterator& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kLastFragment);
aResult.mPosition = aResult.mFragment.mEnd;
// must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
return aResult;
}
NS_COM int Compare( const nsAString& lhs, const nsAString& rhs );
inline
PRBool
nsAString::Equals( const self_type& rhs ) const
{
return Length()==rhs.Length() && Compare(*this, rhs)==0;
}
inline
PRBool
operator!=( const nsAString& lhs, const nsAString& rhs )
{
return !lhs.Equals(rhs);
}
inline
PRBool
operator< ( const nsAString& lhs, const nsAString& rhs )
{
return Compare(lhs, rhs)< 0;
}
inline
PRBool
operator<=( const nsAString& lhs, const nsAString& rhs )
{
return Compare(lhs, rhs)<=0;
}
inline
PRBool
operator==( const nsAString& lhs, const nsAString& rhs )
{
return lhs.Equals(rhs);
}
inline
PRBool
operator>=( const nsAString& lhs, const nsAString& rhs )
{
return Compare(lhs, rhs)>=0;
}
inline
PRBool
operator> ( const nsAString& lhs, const nsAString& rhs )
{
return Compare(lhs, rhs)> 0;
}
inline
nsAString::size_type
nsAString::Left( nsAString& aResult, size_type aLengthToCopy ) const
{
return Mid(aResult, 0, aLengthToCopy);
}
/**
*
*/
inline
nsACString::const_iterator&
nsACString::BeginReading( const_iterator& aResult ) const
{
aResult.mOwningString = this;
GetReadableFragment(aResult.mFragment, kFirstFragment);
aResult.mPosition = aResult.mFragment.mStart;
aResult.normalize_forward();
return aResult;
}
inline
nsACString::const_iterator&
nsACString::EndReading( const_iterator& aResult ) const
{
aResult.mOwningString = this;
GetReadableFragment(aResult.mFragment, kLastFragment);
aResult.mPosition = aResult.mFragment.mEnd;
// must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
return aResult;
}
inline
nsACString::iterator&
nsACString::BeginWriting( iterator& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kFirstFragment);
aResult.mPosition = aResult.mFragment.mStart;
aResult.normalize_forward();
return aResult;
}
inline
nsACString::iterator&
nsACString::EndWriting( iterator& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kLastFragment);
aResult.mPosition = aResult.mFragment.mEnd;
// must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
return aResult;
}
NS_COM int Compare( const nsACString& lhs, const nsACString& rhs );
inline
PRBool
nsACString::Equals( const self_type& rhs ) const
{
return Length()==rhs.Length() && Compare(*this, rhs)==0;
}
inline
PRBool
operator!=( const nsACString& lhs, const nsACString& rhs )
{
return !lhs.Equals(rhs);
}
inline
PRBool
operator< ( const nsACString& lhs, const nsACString& rhs )
{
return Compare(lhs, rhs)< 0;
}
inline
PRBool
operator<=( const nsACString& lhs, const nsACString& rhs )
{
return Compare(lhs, rhs)<=0;
}
inline
PRBool
operator==( const nsACString& lhs, const nsACString& rhs )
{
return lhs.Equals(rhs);
}
inline
PRBool
operator>=( const nsACString& lhs, const nsACString& rhs )
{
return Compare(lhs, rhs)>=0;
}
inline
PRBool
operator> ( const nsACString& lhs, const nsACString& rhs )
{
return Compare(lhs, rhs)> 0;
}
inline
nsACString::size_type
nsACString::Left( nsACString& aResult, size_type aLengthToCopy ) const
{
return Mid(aResult, 0, aLengthToCopy);
}
// Once you've got strings, you shouldn't need to do anything else to have concatenation
#ifndef nsPromiseConcatenation_h___
#include "nsPromiseConcatenation.h"
#endif
#endif // !defined(nsAString_h___)

View File

@ -21,866 +21,16 @@
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsAWritableString.h --- a compatibility header for clients still using the names |nsAWritable[C]String| */
#ifndef nsAWritableString_h___
#define nsAWritableString_h___
// See also...
#ifndef nsAReadableString_h___
#include "nsAReadableString.h"
#endif
template <class CharT>
struct nsWritableFragment
{
CharT* mStart;
CharT* mEnd;
void* mFragmentIdentifier;
nsWritableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
}
};
template <class CharT> class basic_nsAWritableString;
template <class CharT>
class nsWritingIterator
// : public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
typedef CharT value_type;
typedef CharT* pointer;
typedef CharT& reference;
// typedef bidirectional_iterator_tag iterator_category;
private:
friend class basic_nsAWritableString<CharT>;
nsWritableFragment<CharT> mFragment;
CharT* mPosition;
basic_nsAWritableString<CharT>* mOwningString;
nsWritingIterator( nsWritableFragment<CharT>& aFragment,
CharT* aStartingPosition,
basic_nsAWritableString<CharT>& aOwningString )
: mFragment(aFragment),
mPosition(aStartingPosition),
mOwningString(&aOwningString)
{
// nothing else to do here
}
public:
nsWritingIterator() { }
// nsWritingIterator( const nsWritingIterator<CharT>& ); // auto-generated copy-constructor OK
// nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); // auto-generated copy-assignment operator OK
inline void normalize_forward();
inline void normalize_backward();
pointer
get() const
{
return mPosition;
}
reference
operator*() const
{
return *get();
}
#if 0
// An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2)
// don't like this when |CharT| is a type without members.
pointer
operator->() const
{
return get();
}
#endif
nsWritingIterator<CharT>&
operator++()
{
++mPosition;
normalize_forward();
return *this;
}
nsWritingIterator<CharT>
operator++( int )
{
nsWritingIterator<CharT> result(*this);
++mPosition;
normalize_forward();
return result;
}
nsWritingIterator<CharT>&
operator--()
{
normalize_backward();
--mPosition;
return *this;
}
nsWritingIterator<CharT>
operator--( int )
{
nsWritingIterator<CharT> result(*this);
normalize_backward();
--mPosition;
return result;
}
const nsWritableFragment<CharT>&
fragment() const
{
return mFragment;
}
nsWritableFragment<CharT>&
fragment()
{
return mFragment;
}
const basic_nsAWritableString<CharT>&
string() const
{
NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)");
return *mOwningString;
}
basic_nsAWritableString<CharT>&
string()
{
NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)");
return *mOwningString;
}
difference_type
size_forward() const
{
return mFragment.mEnd - mPosition;
}
difference_type
size_backward() const
{
return mPosition - mFragment.mStart;
}
nsWritingIterator<CharT>&
advance( difference_type n )
{
while ( n > 0 )
{
difference_type one_hop = NS_MIN(n, size_forward());
NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
normalize_forward();
n -= one_hop;
}
while ( n < 0 )
{
normalize_backward();
difference_type one_hop = NS_MAX(n, -size_backward());
NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
n -= one_hop;
}
return *this;
}
/**
* Really don't want to call these two operations |+=| and |-=|.
* Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation.
*
* We'll get rid of these as soon as we can.
*/
nsWritingIterator<CharT>&
operator+=( difference_type n ) // deprecated
{
return advance(n);
}
nsWritingIterator<CharT>&
operator-=( difference_type n ) // deprecated
{
return advance(-n);
}
PRUint32
write( const value_type* s, PRUint32 n )
{
NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!");
n = NS_MIN(n, PRUint32(size_forward()));
nsCharTraits<value_type>::move(mPosition, s, n);
advance( difference_type(n) );
return n;
}
};
#if 0
template <class CharT>
nsWritingIterator<CharT>&
nsWritingIterator<CharT>::advance( difference_type n )
{
while ( n > 0 )
{
difference_type one_hop = NS_MIN(n, size_forward());
NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
normalize_forward();
n -= one_hop;
}
while ( n < 0 )
{
normalize_backward();
difference_type one_hop = NS_MAX(n, -size_backward());
NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
n -= one_hop;
}
return *this;
}
#endif
/*
This file defines the abstract interfaces |nsAWritableString| and
|nsAWritableCString|.
|nsAWritableString| is a string of |PRUnichar|s. |nsAWritableCString| (note the
'C') is a string of |char|s.
*/
template <class CharT>
class basic_nsAWritableString
: public basic_nsAReadableString<CharT>
/*
...
*/
{
// friend class nsWritingIterator<CharT>;
public:
typedef CharT char_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
typedef nsWritingIterator<CharT> iterator;
// basic_nsAWritableString(); // auto-generated default constructor OK (we're abstract anyway)
// basic_nsAWritableString( const basic_nsAWritableString<CharT>& ); // auto-generated copy-constructor OK (again, only because we're abstract)
// ~basic_nsAWritableString(); // auto-generated destructor OK
// see below for copy-assignment operator
virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
/**
* Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|?
*/
nsWritingIterator<CharT>&
BeginWriting( nsWritingIterator<CharT>& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kFirstFragment);
aResult.mPosition = aResult.mFragment.mStart;
aResult.normalize_forward();
return aResult;
}
nsWritingIterator<CharT>&
EndWriting( nsWritingIterator<CharT>& aResult )
{
aResult.mOwningString = this;
GetWritableFragment(aResult.mFragment, kLastFragment);
aResult.mPosition = aResult.mFragment.mEnd;
// must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )|
return aResult;
}
/**
* |SetCapacity| is not required to do anything; however, it can be used
* as a hint to the implementation to reduce allocations.
* |SetCapacity(0)| is a suggestion to discard all associated storage.
*/
virtual void SetCapacity( PRUint32 ) { }
/**
* |SetLength| is used in two ways:
* 1) to |Cut| a suffix of the string;
* 2) to prepare to |Append| or move characters around.
*
* External callers are not allowed to use |SetLength| is this latter capacity.
* Should this really be a public operation?
* Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you
* override the |do_...| routines to not need this facility.
*
* This distinction makes me think the two different uses should be split into
* two distinct functions.
*/
virtual void SetLength( PRUint32 ) = 0;
void
Truncate( PRUint32 aNewLength=0 )
{
NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer.");
if ( aNewLength < this->Length() )
SetLength(aNewLength);
}
// PRBool SetCharAt( char_type, index_type ) = 0;
// void ToLowerCase();
// void ToUpperCase();
// void StripChars( const CharT* aSet );
// void StripChar( ... );
// void StripWhitespace();
// void ReplaceChar( ... );
// void ReplaceSubstring( ... );
// void Trim( ... );
// void CompressSet( ... );
// void CompressWhitespace( ... );
//
// |Assign()|, |operator=()|
//
void Assign( const basic_nsAReadableString<CharT>& aReadable ) { AssignFromReadable(aReadable); }
void Assign( const nsPromiseReadable<CharT>& aReadable ) { AssignFromPromise(aReadable); }
void Assign( const CharT* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); }
void Assign( const CharT* aPtr, PRUint32 aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); }
void Assign( CharT aChar ) { do_AssignFromElement(aChar); }
// copy-assignment operator. I must define my own if I don't want the compiler to make me one
basic_nsAWritableString<CharT>& operator=( const basic_nsAWritableString<CharT>& aWritable ) { Assign(aWritable); return *this; }
basic_nsAWritableString<CharT>& operator=( const basic_nsAReadableString<CharT>& aReadable ) { Assign(aReadable); return *this; }
basic_nsAWritableString<CharT>& operator=( const nsPromiseReadable<CharT>& aReadable ) { Assign(aReadable); return *this; }
basic_nsAWritableString<CharT>& operator=( const CharT* aPtr ) { Assign(aPtr); return *this; }
basic_nsAWritableString<CharT>& operator=( CharT aChar ) { Assign(aChar); return *this; }
//
// |Append()|, |operator+=()|
//
void Append( const basic_nsAReadableString<CharT>& aReadable ) { AppendFromReadable(aReadable); }
void Append( const nsPromiseReadable<CharT>& aReadable ) { AppendFromPromise(aReadable); }
void Append( const CharT* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); }
void Append( const CharT* aPtr, PRUint32 aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); }
void Append( CharT aChar ) { do_AppendFromElement(aChar); }
basic_nsAWritableString<CharT>& operator+=( const basic_nsAReadableString<CharT>& aReadable ) { Append(aReadable); return *this; }
basic_nsAWritableString<CharT>& operator+=( const nsPromiseReadable<CharT>& aReadable ) { Append(aReadable); return *this; }
basic_nsAWritableString<CharT>& operator+=( const CharT* aPtr ) { Append(aPtr); return *this; }
basic_nsAWritableString<CharT>& operator+=( CharT aChar ) { Append(aChar); return *this; }
/**
* The following index based routines need to be recast with iterators.
*/
//
// |Insert()|
// Note: I would really like to move the |atPosition| parameter to the front of the argument list
//
void Insert( const basic_nsAReadableString<CharT>& aReadable, PRUint32 atPosition ) { InsertFromReadable(aReadable, atPosition); }
void Insert( const nsPromiseReadable<CharT>& aReadable, PRUint32 atPosition ) { InsertFromPromise(aReadable, atPosition); }
void Insert( const CharT* aPtr, PRUint32 atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); }
void Insert( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); }
void Insert( CharT aChar, PRUint32 atPosition ) { do_InsertFromElement(aChar, atPosition); }
virtual void Cut( PRUint32 cutStart, PRUint32 cutLength );
void Replace( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString<CharT>& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); }
void Replace( PRUint32 cutStart, PRUint32 cutLength, const nsPromiseReadable<CharT>& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); }
private:
typedef typename nsCharTraits<CharT>::incompatible_char_type incompatible_char_type;
// NOT TO BE IMPLEMENTED
void operator= ( incompatible_char_type );
void Assign ( incompatible_char_type );
void operator+= ( incompatible_char_type );
void Append ( incompatible_char_type );
void Insert ( incompatible_char_type, PRUint32 );
protected:
void AssignFromReadable( const basic_nsAReadableString<CharT>& );
void AssignFromPromise( const basic_nsAReadableString<CharT>& );
virtual void do_AssignFromReadable( const basic_nsAReadableString<CharT>& );
virtual void do_AssignFromElementPtr( const CharT* );
virtual void do_AssignFromElementPtrLength( const CharT*, PRUint32 );
virtual void do_AssignFromElement( CharT );
void AppendFromReadable( const basic_nsAReadableString<CharT>& );
void AppendFromPromise( const basic_nsAReadableString<CharT>& );
virtual void do_AppendFromReadable( const basic_nsAReadableString<CharT>& );
virtual void do_AppendFromElementPtr( const CharT* );
virtual void do_AppendFromElementPtrLength( const CharT*, PRUint32 );
virtual void do_AppendFromElement( CharT );
void InsertFromReadable( const basic_nsAReadableString<CharT>&, PRUint32 );
void InsertFromPromise( const basic_nsAReadableString<CharT>&, PRUint32 );
virtual void do_InsertFromReadable( const basic_nsAReadableString<CharT>&, PRUint32 );
virtual void do_InsertFromElementPtr( const CharT*, PRUint32 );
virtual void do_InsertFromElementPtrLength( const CharT*, PRUint32, PRUint32 );
virtual void do_InsertFromElement( CharT, PRUint32 );
void ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString<CharT>& );
void ReplaceFromPromise( PRUint32, PRUint32, const basic_nsAReadableString<CharT>& );
virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString<CharT>& );
};
//
// |nsWritingIterator|s
//
template <class CharT>
inline
void
nsWritingIterator<CharT>::normalize_forward()
{
while ( mPosition == mFragment.mEnd
&& mOwningString->GetWritableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
template <class CharT>
inline
void
nsWritingIterator<CharT>::normalize_backward()
{
while ( mPosition == mFragment.mStart
&& mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
template <class CharT>
inline
PRBool
operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
{
return lhs.get() == rhs.get();
}
template <class CharT>
inline
PRBool
operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
{
return lhs.get() != rhs.get();
}
//
// |Assign()|
//
template <class CharT>
void
basic_nsAWritableString<CharT>::AssignFromReadable( const basic_nsAReadableString<CharT>& rhs )
{
if ( NS_STATIC_CAST(const basic_nsAReadableString<CharT>*, this) != &rhs )
do_AssignFromReadable(rhs);
// else, self-assign is a no-op
}
template <class CharT>
void
basic_nsAWritableString<CharT>::AssignFromPromise( const basic_nsAReadableString<CharT>& aReadable )
/*
...this function is only called when a promise that somehow references |this| is assigned _into_ |this|.
E.g.,
... writable& w ...
... readable& r ...
w = r + w;
In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before
anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents
of |r| before being retrieved to be appended.
We could have a really tricky solution where we tell the promise to resolve _just_ the data promised
by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g.,
in the case above, |Insert| could have special behavior with significantly better performance. Since
it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the
entire promise. If we measure and this turns out to show up on performance radar, we then have the
option to fix either the callers or this mechanism.
*/
{
if ( !aReadable.Promises(*this) )
do_AssignFromReadable(aReadable);
else
{
PRUint32 length = aReadable.Length();
CharT* buffer = new CharT[length];
if ( buffer )
{
// Note: not exception safe. We need something to manage temporary buffers like this
nsReadingIterator<CharT> fromBegin, fromEnd;
CharT* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AssignFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AssignFromReadable( const basic_nsAReadableString<CharT>& aReadable )
{
SetLength(0);
SetLength(aReadable.Length());
// first setting the length to |0| avoids copying characters only to be overwritten later
// in the case where the implementation decides to re-allocate
nsReadingIterator<CharT> fromBegin, fromEnd;
nsWritingIterator<CharT> toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AssignFromElementPtr( const CharT* aPtr )
{
do_AssignFromReadable(basic_nsLiteralString<CharT>(aPtr));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AssignFromElementPtrLength( const CharT* aPtr, PRUint32 aLength )
{
do_AssignFromReadable(basic_nsLiteralString<CharT>(aPtr, aLength));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AssignFromElement( CharT aChar )
{
do_AssignFromReadable(basic_nsLiteralChar<CharT>(aChar));
}
//
// |Append()|
//
template <class CharT>
void
basic_nsAWritableString<CharT>::AppendFromReadable( const basic_nsAReadableString<CharT>& aReadable )
{
if ( NS_STATIC_CAST(const basic_nsAReadableString<CharT>*, this) != &aReadable )
do_AppendFromReadable(aReadable);
else
AppendFromPromise(aReadable);
}
template <class CharT>
void
basic_nsAWritableString<CharT>::AppendFromPromise( const basic_nsAReadableString<CharT>& aReadable )
{
if ( !aReadable.Promises(*this) )
do_AppendFromReadable(aReadable);
else
{
PRUint32 length = aReadable.Length();
CharT* buffer = new CharT[length];
if ( buffer )
{
nsReadingIterator<CharT> fromBegin, fromEnd;
CharT* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AppendFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AppendFromReadable( const basic_nsAReadableString<CharT>& aReadable )
{
PRUint32 oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
nsReadingIterator<CharT> fromBegin, fromEnd;
nsWritingIterator<CharT> toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) );
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AppendFromElementPtr( const CharT* aChar )
{
do_AppendFromReadable(basic_nsLiteralString<CharT>(aChar));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AppendFromElementPtrLength( const CharT* aChar, PRUint32 aLength )
{
do_AppendFromReadable(basic_nsLiteralString<CharT>(aChar, aLength));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_AppendFromElement( CharT aChar )
{
do_AppendFromReadable(basic_nsLiteralChar<CharT>(aChar));
}
//
// |Insert()|
//
template <class CharT>
void
basic_nsAWritableString<CharT>::InsertFromReadable( const basic_nsAReadableString<CharT>& aReadable, PRUint32 atPosition )
{
if ( NS_STATIC_CAST(const basic_nsAReadableString<CharT>*, this) != &aReadable )
do_InsertFromReadable(aReadable, atPosition);
else
InsertFromPromise(aReadable, atPosition);
}
template <class CharT>
void
basic_nsAWritableString<CharT>::InsertFromPromise( const basic_nsAReadableString<CharT>& aReadable, PRUint32 atPosition )
{
if ( !aReadable.Promises(*this) )
do_InsertFromReadable(aReadable, atPosition);
else
{
PRUint32 length = aReadable.Length();
CharT* buffer = new CharT[length];
if ( buffer )
{
nsReadingIterator<CharT> fromBegin, fromEnd;
CharT* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_InsertFromElementPtrLength(buffer, atPosition, length);
delete buffer;
}
// else assert
}
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_InsertFromReadable( const basic_nsAReadableString<CharT>& aReadable, PRUint32 atPosition )
{
PRUint32 oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
nsReadingIterator<CharT> fromBegin, fromEnd;
nsWritingIterator<CharT> toBegin;
if ( atPosition < oldLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin));
else
atPosition = oldLength;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition)));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_InsertFromElementPtr( const CharT* aPtr, PRUint32 atPosition )
{
do_InsertFromReadable(basic_nsLiteralString<CharT>(aPtr), atPosition);
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_InsertFromElementPtrLength( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength )
{
do_InsertFromReadable(basic_nsLiteralString<CharT>(aPtr, aLength), atPosition);
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_InsertFromElement( CharT aChar, PRUint32 atPosition )
{
do_InsertFromReadable(basic_nsLiteralChar<CharT>(aChar), atPosition);
}
//
// |Cut()|
//
template <class CharT>
void
basic_nsAWritableString<CharT>::Cut( PRUint32 cutStart, PRUint32 cutLength )
{
PRUint32 myLength = this->Length();
cutLength = NS_MIN(cutLength, myLength-cutStart);
PRUint32 cutEnd = cutStart + cutLength;
nsReadingIterator<CharT> fromBegin, fromEnd;
nsWritingIterator<CharT> toBegin;
if ( cutEnd < myLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
SetLength(myLength-cutLength);
}
//
// |Replace()|
//
template <class CharT>
void
basic_nsAWritableString<CharT>::ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString<CharT>& aReplacement )
{
if ( NS_STATIC_CAST(const basic_nsAReadableString<CharT>*, this) != &aReplacement )
do_ReplaceFromReadable(cutStart, cutLength, aReplacement);
else
ReplaceFromPromise(cutStart, cutLength, aReplacement);
}
template <class CharT>
void
basic_nsAWritableString<CharT>::ReplaceFromPromise( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString<CharT>& aReadable )
{
if ( !aReadable.Promises(*this) )
do_ReplaceFromReadable(cutStart, cutLength, aReadable);
else
{
PRUint32 length = aReadable.Length();
CharT* buffer = new CharT[length];
if ( buffer )
{
nsReadingIterator<CharT> fromBegin, fromEnd;
CharT* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_ReplaceFromReadable(cutStart, cutLength, basic_nsLiteralString<CharT>(buffer, length));
delete buffer;
}
// else assert?
}
}
template <class CharT>
void
basic_nsAWritableString<CharT>::do_ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString<CharT>& aReplacement )
{
PRUint32 oldLength = this->Length();
cutStart = NS_MIN(cutStart, oldLength);
cutLength = NS_MIN(cutLength, oldLength-cutStart);
PRUint32 cutEnd = cutStart + cutLength;
PRUint32 replacementLength = aReplacement.Length();
PRUint32 replacementEnd = cutStart + replacementLength;
PRUint32 newLength = oldLength - cutLength + replacementLength;
nsReadingIterator<CharT> fromBegin, fromEnd;
nsWritingIterator<CharT> toBegin;
if ( cutLength > replacementLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
}
template <class CharT>
PRUint32
basic_nsAReadableString<CharT>::Mid( basic_nsAWritableString<CharT>& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const
{
// If we're just assigning our entire self, give |aResult| the opportunity to share
if ( aStartPos == 0 && aLengthToCopy >= Length() )
aResult = *this;
else
aResult = Substring(*this, aStartPos, aLengthToCopy);
return aResult.Length();
}
template <class CharT>
inline
PRUint32
basic_nsAReadableString<CharT>::Left( basic_nsAWritableString<CharT>& aResult, PRUint32 aLengthToCopy ) const
{
return Mid(aResult, 0, aLengthToCopy);
}
template <class CharT>
PRUint32
basic_nsAReadableString<CharT>::Right( basic_nsAWritableString<CharT>& aResult, PRUint32 aLengthToCopy ) const
{
PRUint32 myLength = Length();
aLengthToCopy = NS_MIN(myLength, aLengthToCopy);
return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy);
}
//
// Types
//
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
typedef nsAString nsAWritableString;
typedef nsACString nsAWritableCString;
#endif // !defined(nsAWritableString_h___)

View File

@ -163,13 +163,14 @@ class nsSharedBufferHandle
protected:
enum
{
kIsShared = 1<<31,
kIsSingleAllocationWithBuffer = 1<<30, // handle and buffer are one piece, no separate deallocation is possible for the buffer
kIsStorageDefinedSeparately = 1<<29, // i.e., we're using the ``flex'' structure defined below
kIsUserAllocator = 1<<28, // can't |delete|, call a hook instead
kIsShared = 0x8000000,
kIsSingleAllocationWithBuffer = 0x4000000, // handle and buffer are one piece, no separate deallocation is possible for the buffer
kIsStorageDefinedSeparately = 0x2000000, // i.e., we're using the ``flex'' structure defined below
kIsUserAllocator = 0x1000000, // can't |delete|, call a hook instead
kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately | kIsUserAllocator,
kRefCountMask = ~kFlagsMask
kImplementationFlagsMask = 0x0F00000,
kFlagsMask = 0xFF00000,
kRefCountMask = 0x00FFFFF
};
public:
@ -179,6 +180,14 @@ class nsSharedBufferHandle
mFlags = kIsShared;
}
nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT*, CharT*, PRBool isSingleAllocation )
: nsBufferHandle<CharT>(aDataStart, aDataEnd)
{
mFlags = kIsShared;
if ( isSingleAllocation )
mFlags |= kIsSingleAllocationWithBuffer;
}
~nsSharedBufferHandle();
void
@ -203,6 +212,18 @@ class nsSharedBufferHandle
return get_refcount() != 0;
}
PRUint32
GetImplementationFlags() const
{
return mFlags & kImplementationFlagsMask;
}
void
SetImplementationFlags( PRUint32 aNewFlags )
{
mFlags = (mFlags & ~kImplementationFlagsMask) | (aNewFlags & kImplementationFlagsMask);
}
protected:
PRUint32 mFlags;

View File

@ -25,15 +25,83 @@
#ifndef nsBufferHandleUtils_h___
#define nsBufferHandleUtils_h___
#ifndef nsAReadableString_h___
#include "nsAReadableString.h"
// for |basic_nsAReadableString|...
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
#include <new.h>
// for placement |new|
template <class CharT>
class nsAutoBufferHandle
{
public:
nsAutoBufferHandle() : mHandle(0) { }
nsAutoBufferHandle( const nsAutoBufferHandle<CharT>& aOther )
: mHandle(aOther.get())
{
if ( mHandle)
mHandle->AcquireReference();
}
explicit
nsAutoBufferHandle( const nsSharedBufferHandle<CharT>* aHandle )
: mHandle(aHandle)
{
if ( mHandle)
mHandle->AcquireReference();
}
~nsAutoBufferHandle()
{
if ( mHandle )
mHandle->ReleaseReference();
}
nsAutoBufferHandle<CharT>&
operator=( const nsSharedBufferHandle<CharT>* rhs )
{
nsSharedBufferHandle<CharT>* old_handle = mHandle;
if ( (mHandle = NS_CONST_CAST(nsSharedBufferHandle<CharT>*, rhs)) )
mHandle->AcquireReference();
if ( old_handle )
old_handle->ReleaseReference();
return *this;
}
nsAutoBufferHandle<CharT>&
operator=( const nsAutoBufferHandle<CharT>& rhs )
{
return operator=(rhs.get());
}
nsSharedBufferHandle<CharT>*
get() const
{
return mHandle;
}
operator nsSharedBufferHandle<CharT>*() const
{
return get();
}
nsSharedBufferHandle<CharT>*
operator->() const
{
return get();
}
private:
nsSharedBufferHandle<CharT>* mHandle;
};
template <class HandleT, class CharT>
inline
@ -62,21 +130,22 @@ NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
}
template <class HandleT, class CharT>
template <class HandleT, class StringT>
HandleT*
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic_nsAReadableString<CharT>& aDataSource, PRUint32 aAdditionalCapacity )
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity )
{
typedef CharT* CharT_ptr;
typedef typename StringT::char_type char_type;
typedef char_type* char_ptr;
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, CharT_ptr(0));
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, char_ptr(0));
// figure out how many |CharT|s wee need to fit in the data part
// figure out how many |char_type|s wee need to fit in the data part
size_t data_length = aDataSource.Length();
size_t buffer_length = data_length + aAdditionalCapacity;
// how many bytes is that (including a zero-terminator so we can claim to be flat)?
size_t buffer_size = buffer_length * sizeof(CharT);
size_t buffer_size = buffer_length * sizeof(char_type);
HandleT* result = 0;
@ -84,17 +153,17 @@ NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic
if ( handle_ptr )
{
CharT* data_start_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
CharT* data_end_ptr = data_start_ptr + data_length;
CharT* buffer_end_ptr = data_start_ptr + buffer_length;
char_ptr data_start_ptr = char_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
char_ptr data_end_ptr = data_start_ptr + data_length;
char_ptr buffer_end_ptr = data_start_ptr + buffer_length;
nsReadingIterator<CharT> fromBegin, fromEnd;
CharT* toBegin = data_start_ptr;
typename StringT::const_iterator fromBegin, fromEnd;
char_ptr toBegin = data_start_ptr;
copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin);
// and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate
if ( aAdditionalCapacity > 0 )
*toBegin = CharT(0);
*toBegin = char_type(0);
result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, data_start_ptr, buffer_end_ptr, PR_TRUE);
}

View File

@ -35,6 +35,9 @@
// for |PRUnichar|
#endif
#ifndef nsStringIteratorUtils_h___
#include "nsStringIteratorUtils.h"
#endif
#ifdef HAVE_CPP_BOOL
typedef bool nsCharTraits_bool;
@ -45,8 +48,8 @@
template <class CharT>
struct nsCharTraits
{
typedef CharT char_type;
typedef char incompatible_char_type;
typedef CharT char_type;
typedef char incompatible_char_type;
static
void
@ -210,8 +213,8 @@ struct nsCharTraits
NS_SPECIALIZE_TEMPLATE
struct nsCharTraits<char>
{
typedef char char_type;
typedef PRUnichar incompatible_char_type;
typedef char char_type;
typedef PRUnichar incompatible_char_type;
static
void
@ -337,7 +340,7 @@ struct nsCharTraits<char>
NS_SPECIALIZE_TEMPLATE
struct nsCharTraits<wchar_t>
{
typedef wchar_t char_type;
typedef wchar_t char_type;
static
void
@ -460,7 +463,6 @@ struct nsCharTraits<wchar_t>
};
#endif
template <class InputIterator>
struct nsCharSourceTraits
{

View File

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsCommonString.h --- a string implementation that shares its underlying storage */
#ifndef nsCommonString_h___
#define nsCommonString_h___
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
#ifndef nsBufferHandleUtils_h___
#include "nsBufferHandleUtils.h"
#endif
//-------1---------2---------3---------4---------5---------6---------7---------8
/**
* Not yet ready for non-|const| access
*/
class NS_COM nsCommonString
: public nsAFlatString
{
public:
typedef nsCommonString self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
public:
nsCommonString() { }
nsCommonString( const self_type& aOther ) : mBuffer(aOther.mBuffer) { }
nsCommonString( const string_type& aReadable ) { assign(aReadable); }
self_type&
operator=( const string_type& aReadable )
{
assign(aReadable);
return *this;
}
protected:
void assign( const string_type& );
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
nsAutoBufferHandle<char_type> mBuffer;
};
class NS_COM nsCommonCString
: public nsAFlatCString
{
public:
typedef nsCommonCString self_type;
typedef char char_type;
typedef nsACString string_type;
public:
nsCommonCString() { }
nsCommonCString( const self_type& aOther ) : mBuffer(aOther.mBuffer) { }
nsCommonCString( const string_type& aReadable ) { assign(aReadable); }
self_type&
operator=( const string_type& aReadable )
{
assign(aReadable);
return *this;
}
protected:
void assign( const string_type& );
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
nsAutoBufferHandle<char_type> mBuffer;
};
#endif /* !defined(nsCommonString_h___) */

View File

@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsPromiseConcatenation.h --- string concatenation machinery lives here, but don't include this file
directly, always get it by including either "nsAString.h" or one of the compatibility headers */
#ifndef nsPromiseConcatenation_h___
#define nsPromiseConcatenation_h___
/**
NOT FOR USE BY HUMANS
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
- left to right evaluation is required ... do not use parentheses to override this
In practice, neither of these is onerous. Parentheses do not change the semantics of the
concatenation, only the order in which the result is assembled ... so there's no reason
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetReadableFragment()|.
*/
class NS_COM nsPromiseConcatenation
: public nsAPromiseString
{
public:
typedef nsPromiseConcatenation self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
class NS_COM nsPromiseCConcatenation
: public nsAPromiseCString
{
public:
typedef nsPromiseCConcatenation self_type;
typedef char char_type;
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseCConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseCConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseCConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
/*
How shall we provide |operator+()|?
What would it return? It has to return a stack based object, because the client will
not be given an opportunity to handle memory management in an expression like
myWritableString = stringA + stringB + stringC;
...so the `obvious' answer of returning a new |nsSharedString| is no good. We could
return an |nsString|, if that name were in scope here, though there's no telling what the client
will really want to do with the result. What might be better, though,
is to return a `promise' to concatenate some strings...
By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle
assignment and other interesting uses within writable strings, plus we drastically reduce
the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings
in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work
to implement the virtual functions of readables.
*/
inline
const nsPromiseConcatenation
operator+( const nsPromiseConcatenation& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseCConcatenation
operator+( const nsPromiseCConcatenation& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseConcatenation
operator+( const nsAString& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs);
}
inline
const nsPromiseCConcatenation
operator+( const nsACString& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs);
}
#if 0
inline
const nsPromiseConcatenation
nsPromiseConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
inline
const nsPromiseCConcatenation
nsPromiseCConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseCConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
#endif
#endif /* !defined(nsPromiseConcatenation_h___) */

View File

@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsLocalString_h___
#define nsLocalString_h___
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
/*
...this class wraps a constant literal string and lets it act like an |nsAReadable...|.
Use it like this:
SomeFunctionTakingACString( nsLiteralCString("Hello, World!") );
With some tweaking, I think I can make this work as well...
SomeStringFunc( nsLiteralString( L"Hello, World!" ) );
This class just holds a pointer. If you don't supply the length, it must calculate it.
No copying or allocations are performed.
|const nsLocalString&| appears frequently in interfaces because it
allows the automatic conversion of a |PRUnichar*|.
*/
class NS_COM nsLocalString
: public nsAFlatString
{
public:
explicit
nsLocalString( const PRUnichar* aLiteral )
: mHandle(NS_CONST_CAST(PRUnichar*, aLiteral), aLiteral ? (NS_CONST_CAST(PRUnichar*, aLiteral)+nsCharTraits<PRUnichar>::length(aLiteral)) : NS_CONST_CAST(PRUnichar*, aLiteral))
{
// nothing else to do here
}
nsLocalString( const PRUnichar* aLiteral, PRUint32 aLength )
: mHandle(NS_CONST_CAST(PRUnichar*, aLiteral), NS_CONST_CAST(PRUnichar*, aLiteral)+aLength)
{
// This is an annoying hack. Callers should be fixed to use the other
// constructor if they don't really know the length.
if ( aLength == PRUint32(-1) )
{
// NS_WARNING("Tell scc: Caller constructing a string doesn't know the real length. Please use the other constructor.");
mHandle.DataEnd(aLiteral ? (NS_CONST_CAST(PRUnichar*, aLiteral)+nsCharTraits<PRUnichar>::length(aLiteral)) : NS_CONST_CAST(PRUnichar*, aLiteral));
}
}
// nsLocalString( const nsLocalString& ); // auto-generated copy-constructor OK
// ~nsLocalString(); // auto-generated destructor OK
virtual const nsBufferHandle<PRUnichar>* GetFlatBufferHandle() const { return &mHandle; }
virtual const nsBufferHandle<PRUnichar>* GetBufferHandle() const { return &mHandle; }
private:
nsBufferHandle<PRUnichar> mHandle;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsLocalString& ); // we're immutable
};
class NS_COM nsLocalCString
: public nsAFlatCString
{
public:
explicit
nsLocalCString( const char* aLiteral )
: mHandle(NS_CONST_CAST(char*, aLiteral), aLiteral ? (NS_CONST_CAST(char*, aLiteral)+nsCharTraits<char>::length(aLiteral)) : NS_CONST_CAST(char*, aLiteral))
{
// nothing else to do here
}
nsLocalCString( const char* aLiteral, PRUint32 aLength )
: mHandle(NS_CONST_CAST(char*, aLiteral), NS_CONST_CAST(char*, aLiteral)+aLength)
{
// This is an annoying hack. Callers should be fixed to use the other
// constructor if they don't really know the length.
if ( aLength == PRUint32(-1) )
{
// NS_WARNING("Tell scc: Caller constructing a string doesn't know the real length. Please use the other constructor.");
mHandle.DataEnd(aLiteral ? (NS_CONST_CAST(char*, aLiteral)+nsCharTraits<char>::length(aLiteral)) : NS_CONST_CAST(char*, aLiteral));
}
}
// nsLocalCString( const nsLocalCString& ); // auto-generated copy-constructor OK
// ~nsLocalCString(); // auto-generated destructor OK
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const { return &mHandle; }
virtual const nsBufferHandle<char>* GetBufferHandle() const { return &mHandle; }
private:
nsBufferHandle<char> mHandle;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsLocalCString& ); // we're immutable
};
#endif /* !defined(nsLocalString_h___) */

View File

@ -0,0 +1,182 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsPromiseSubstring_h___
#define nsPromiseSubstring_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
//
// nsPromiseSubstring
//
class NS_COM nsPromiseSubstring
: public nsAPromiseString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
class NS_COM nsPromiseCSubstring
: public nsAPromiseCString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseCSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseCSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseCSubstring( const nsPromiseCSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseCSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
inline
const nsPromiseCSubstring
Substring( const nsACString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseCSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseSubstring
Substring( const nsAString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseCSubstring
Substring( const nsReadingIterator<char>& aStart, const nsReadingIterator<char>& aEnd )
{
return nsPromiseCSubstring(aStart, aEnd);
}
inline
const nsPromiseSubstring
Substring( const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd )
{
return nsPromiseSubstring(aStart, aEnd);
}
#endif /* !defined(nsPromiseSubstring_h___) */

View File

@ -27,8 +27,8 @@
// WORK IN PROGRESS
#ifndef nsAWritableString_h___
#include "nsAWritableString.h"
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsSharedBufferList_h___
@ -37,7 +37,7 @@
class nsFragmentedString
: public basic_nsAWritableString<PRUnichar>
: public nsAString
/*
...
*/
@ -57,10 +57,10 @@ class nsFragmentedString
// virtual void Cut( PRUint32 cutStart, PRUint32 cutLength );
protected:
// virtual void do_AssignFromReadable( const basic_nsAReadableString<PRUnichar>& );
// virtual void do_AppendFromReadable( const basic_nsAReadableString<PRUnichar>& );
// virtual void do_InsertFromReadable( const basic_nsAReadableString<PRUnichar>&, PRUint32 );
// virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString<PRUnichar>& );
// virtual void do_AssignFromReadable( const nsAString& );
// virtual void do_AppendFromReadable( const nsAString& );
// virtual void do_InsertFromReadable( const nsAString&, PRUint32 );
// virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const nsAString& );
private:
nsSharedBufferList mBufferList;

View File

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsLiteralString_h___
#define nsLiteralString_h___
#ifndef nscore_h___
#include "nscore.h"
#endif
#ifndef nsLocalString_h___
#include "nsLocalString.h"
#endif
typedef const nsLocalString nsLiteralString;
typedef const nsLocalCString nsLiteralCString;
#if 0
inline
const nsLocalString
literal_string( const PRUnichar* aPtr )
{
return nsLocalString(aPtr);
}
inline
const nsLocalString
literal_string( const PRUnichar* aPtr, PRUint32 aLength )
{
return nsLocalString(aPtr, aLength);
}
inline
const nsLocalCString
literal_string( const char* aPtr )
{
return nsLocalCString(aPtr);
}
inline
const nsLocalCString
literal_string( const char* aPtr, PRUint32 aLength )
{
return nsLocalCString(aPtr, aLength);
}
#endif
#ifdef HAVE_CPP_2BYTE_WCHAR_T
#define NS_L(s) L##s
#define NS_MULTILINE_LITERAL_STRING(s) nsLiteralString(s, (sizeof(s)/sizeof(wchar_t))-1)
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) nsLiteralString n(s, (sizeof(s)/sizeof(wchar_t))-1)
#else
#define NS_L(s) s
#define NS_MULTILINE_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1)
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) NS_ConvertASCIItoUCS2 n(s, sizeof(s)-1)
#endif
#define NS_LITERAL_STRING(s) NS_MULTILINE_LITERAL_STRING(NS_L(s))
#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n,NS_L(s))
#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1)
#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1)
#endif /* !defined(nsLiteralString_h___) */

View File

@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsLocalString_h___
#define nsLocalString_h___
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
/*
...this class wraps a constant literal string and lets it act like an |nsAReadable...|.
Use it like this:
SomeFunctionTakingACString( nsLiteralCString("Hello, World!") );
With some tweaking, I think I can make this work as well...
SomeStringFunc( nsLiteralString( L"Hello, World!" ) );
This class just holds a pointer. If you don't supply the length, it must calculate it.
No copying or allocations are performed.
|const nsLocalString&| appears frequently in interfaces because it
allows the automatic conversion of a |PRUnichar*|.
*/
class NS_COM nsLocalString
: public nsAFlatString
{
public:
explicit
nsLocalString( const PRUnichar* aLiteral )
: mHandle(NS_CONST_CAST(PRUnichar*, aLiteral), aLiteral ? (NS_CONST_CAST(PRUnichar*, aLiteral)+nsCharTraits<PRUnichar>::length(aLiteral)) : NS_CONST_CAST(PRUnichar*, aLiteral))
{
// nothing else to do here
}
nsLocalString( const PRUnichar* aLiteral, PRUint32 aLength )
: mHandle(NS_CONST_CAST(PRUnichar*, aLiteral), NS_CONST_CAST(PRUnichar*, aLiteral)+aLength)
{
// This is an annoying hack. Callers should be fixed to use the other
// constructor if they don't really know the length.
if ( aLength == PRUint32(-1) )
{
// NS_WARNING("Tell scc: Caller constructing a string doesn't know the real length. Please use the other constructor.");
mHandle.DataEnd(aLiteral ? (NS_CONST_CAST(PRUnichar*, aLiteral)+nsCharTraits<PRUnichar>::length(aLiteral)) : NS_CONST_CAST(PRUnichar*, aLiteral));
}
}
// nsLocalString( const nsLocalString& ); // auto-generated copy-constructor OK
// ~nsLocalString(); // auto-generated destructor OK
virtual const nsBufferHandle<PRUnichar>* GetFlatBufferHandle() const { return &mHandle; }
virtual const nsBufferHandle<PRUnichar>* GetBufferHandle() const { return &mHandle; }
private:
nsBufferHandle<PRUnichar> mHandle;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsLocalString& ); // we're immutable
};
class NS_COM nsLocalCString
: public nsAFlatCString
{
public:
explicit
nsLocalCString( const char* aLiteral )
: mHandle(NS_CONST_CAST(char*, aLiteral), aLiteral ? (NS_CONST_CAST(char*, aLiteral)+nsCharTraits<char>::length(aLiteral)) : NS_CONST_CAST(char*, aLiteral))
{
// nothing else to do here
}
nsLocalCString( const char* aLiteral, PRUint32 aLength )
: mHandle(NS_CONST_CAST(char*, aLiteral), NS_CONST_CAST(char*, aLiteral)+aLength)
{
// This is an annoying hack. Callers should be fixed to use the other
// constructor if they don't really know the length.
if ( aLength == PRUint32(-1) )
{
// NS_WARNING("Tell scc: Caller constructing a string doesn't know the real length. Please use the other constructor.");
mHandle.DataEnd(aLiteral ? (NS_CONST_CAST(char*, aLiteral)+nsCharTraits<char>::length(aLiteral)) : NS_CONST_CAST(char*, aLiteral));
}
}
// nsLocalCString( const nsLocalCString& ); // auto-generated copy-constructor OK
// ~nsLocalCString(); // auto-generated destructor OK
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const { return &mHandle; }
virtual const nsBufferHandle<char>* GetBufferHandle() const { return &mHandle; }
private:
nsBufferHandle<char> mHandle;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsLocalCString& ); // we're immutable
};
#endif /* !defined(nsLocalString_h___) */

View File

@ -38,7 +38,9 @@
#ifndef nsPrintfCString_h___
#define nsPrintfCString_h___
#include "nsAWritableString.h"
#ifndef nsAString_h___
#include "nsAString.h"
#endif
/**
@ -66,7 +68,7 @@
*/
class nsPrintfCString
: public nsAReadableCString
: public nsACString
{
enum { kLocalBufferSize=15 };
// ought to be large enough for most things ... a |long long| needs at most 20 (so you'd better ask)
@ -81,7 +83,8 @@ class nsPrintfCString
virtual PRUint32 Length() const;
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const;
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 ) { return 0; }
// virtual PRBool GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest ) const;
private:

View File

@ -30,39 +30,53 @@
#endif
/**
* This class is (will be) part of the machinery that makes
* This class is part of the machinery that makes
* most string implementations in this family share their underlying buffers
* when convenient. It is _not_ part of the abstract string interface,
* though other machinery interested in sharing buffers will know about it.
*
* Normal string clients must _never_ call routines from this interface.
*/
template <class CharT>
class nsPrivateSharableString
class NS_COM nsPrivateSharableString
{
public:
virtual const nsBufferHandle<CharT>* GetBufferHandle() const;
virtual const nsSharedBufferHandle<CharT>* GetSharedBufferHandle() const;
typedef PRUnichar char_type;
public:
virtual ~nsPrivateSharableString() {}
virtual PRUint32 GetImplementationFlags() const;
virtual const nsBufferHandle<char_type>* GetFlatBufferHandle() const;
virtual const nsBufferHandle<char_type>* GetBufferHandle() const;
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
/**
* |GetBufferHandle()| will return either |0|, |1|, or a reasonable pointer.
* |GetBufferHandle()| will return either |0|, or a reasonable pointer.
* The meaning of |0| is that the string points to a non-contiguous or else empty representation.
* The meaning of |1| is implementation dependant.
* Otherwise |GetBufferHandle()| returns a pointer to the single contiguous hunk of characters
* that makes up this string.
* Otherwise |GetBufferHandle()| returns a handle that points to the single contiguous hunk of characters
* that make up this string.
*/
};
template <class CharT>
const nsSharedBufferHandle<CharT>*
nsPrivateSharableString<CharT>::GetSharedBufferHandle() const
class NS_COM nsPrivateSharableCString
{
return 0;
}
public:
typedef char char_type;
template <class CharT>
const nsBufferHandle<CharT>*
nsPrivateSharableString<CharT>::GetBufferHandle() const
{
return GetSharedBufferHandle();
}
public:
virtual ~nsPrivateSharableCString() {}
virtual PRUint32 GetImplementationFlags() const;
virtual const nsBufferHandle<char_type>* GetFlatBufferHandle() const;
virtual const nsBufferHandle<char_type>* GetBufferHandle() const;
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
/**
* |GetBufferHandle()| will return either |0|, or a reasonable pointer.
* The meaning of |0| is that the string points to a non-contiguous or else empty representation.
* Otherwise |GetBufferHandle()| returns a handle that points to the single contiguous hunk of characters
* that make up this string.
*/
};
#endif // !defined(nsPrivateSharableString_h___)

View File

@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsPromiseConcatenation.h --- string concatenation machinery lives here, but don't include this file
directly, always get it by including either "nsAString.h" or one of the compatibility headers */
#ifndef nsPromiseConcatenation_h___
#define nsPromiseConcatenation_h___
/**
NOT FOR USE BY HUMANS
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
- left to right evaluation is required ... do not use parentheses to override this
In practice, neither of these is onerous. Parentheses do not change the semantics of the
concatenation, only the order in which the result is assembled ... so there's no reason
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetReadableFragment()|.
*/
class NS_COM nsPromiseConcatenation
: public nsAPromiseString
{
public:
typedef nsPromiseConcatenation self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
class NS_COM nsPromiseCConcatenation
: public nsAPromiseCString
{
public:
typedef nsPromiseCConcatenation self_type;
typedef char char_type;
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char_type* GetReadableFragment( nsReadableFragment<char_type>&, nsFragmentRequest, PRUint32 ) const;
virtual char_type* GetWritableFragment( nsWritableFragment<char_type>&, nsFragmentRequest, PRUint32 ) { return 0; }
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const nsReadableFragment<char_type>& aFragment ) const
{
return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask);
return kLeftString;
}
int
SetRightStringInFragment( nsReadableFragment<char_type>& aFragment ) const
{
aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask);
return kRightString;
}
public:
nsPromiseCConcatenation( const string_type& aLeftString, const string_type& aRightString, PRUint32 aMask = 1 )
: mFragmentIdentifierMask(aMask)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
nsPromiseCConcatenation( const self_type& aLeftString, const string_type& aRightString )
: mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1)
{
mStrings[kLeftString] = &aLeftString;
mStrings[kRightString] = &aRightString;
}
// nsPromiseCConcatenation( const self_type& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCConcatenation(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const self_type& ); // we're immutable, you can't assign into a concatenation
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& ) const;
// virtual PRBool PromisesExactly( const string_type& ) const;
// const self_type operator+( const string_type& rhs ) const;
PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; }
private:
void operator+( const self_type& ); // NOT TO BE IMPLEMENTED
// making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)|
// which would break the algorithm for distributing bits in the fragment identifier
private:
const string_type* mStrings[2];
PRUint32 mFragmentIdentifierMask;
};
/*
How shall we provide |operator+()|?
What would it return? It has to return a stack based object, because the client will
not be given an opportunity to handle memory management in an expression like
myWritableString = stringA + stringB + stringC;
...so the `obvious' answer of returning a new |nsSharedString| is no good. We could
return an |nsString|, if that name were in scope here, though there's no telling what the client
will really want to do with the result. What might be better, though,
is to return a `promise' to concatenate some strings...
By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle
assignment and other interesting uses within writable strings, plus we drastically reduce
the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings
in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work
to implement the virtual functions of readables.
*/
inline
const nsPromiseConcatenation
operator+( const nsPromiseConcatenation& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseCConcatenation
operator+( const nsPromiseCConcatenation& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1);
}
inline
const nsPromiseConcatenation
operator+( const nsAString& lhs, const nsAString& rhs )
{
return nsPromiseConcatenation(lhs, rhs);
}
inline
const nsPromiseCConcatenation
operator+( const nsACString& lhs, const nsACString& rhs )
{
return nsPromiseCConcatenation(lhs, rhs);
}
#if 0
inline
const nsPromiseConcatenation
nsPromiseConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
inline
const nsPromiseCConcatenation
nsPromiseCConcatenation::operator+( const string_type& rhs ) const
{
return nsPromiseCConcatenation(*this, rhs, mFragmentIdentifierMask<<1);
}
#endif
#endif /* !defined(nsPromiseConcatenation_h___) */

View File

@ -0,0 +1,150 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsPromiseFlatString_h___
#define nsPromiseFlatString_h___
#ifndef nsCommonString_h___
#include "nsCommonString.h"
#endif
/**
* WARNING:
*
* Try to avoid flat strings. |PromiseFlat[C]String| will help you as a last resort,
* and this may be necessary when dealing with legacy or OS calls, but in general,
* requiring a zero-terminated contiguous hunk of characters kills many of the performance
* wins the string classes offer. Write your own code to use |nsA[C]String&|s for parameters.
* Write your string proccessing algorithms to exploit iterators. If you do this, you
* will benefit from being able to chain operations without copying or allocating and your
* code will be significantly more efficient. Remember, a function that takes an
* |const nsA[C]String&| can always be passed a raw character pointer by wrapping it (for free)
* in a |nsLocal[C]String|. But a function that takes a character pointer always has the
* potential to force allocation and copying.
*
*
* How to use it:
*
* Like all `promises', a |nsPromiseFlat[C]String| doesn't own the characters it promises.
* You must never use it to promise characters out of a string with a shorter lifespan.
* The typical use will be something like this
*
* SomeOSFunction( PromiseFlatCString(aCString).get() ); // GOOD
*
* Here's a BAD use:
*
* const char* buffer = PromiseFlatCString(aCString).get();
* SomeOSFunction(buffer); // BAD!! |buffer| is a dangling pointer
*
* A |nsPromiseFlat[C]String| doesn't support non-|const| access (you can't use it to make
* changes back into the original string). To help you avoid that, the only way to make
* one is with the function |PromiseFlat[C]String|, which produce a |const| instance.
* ``What if I need to keep a promise around for a little while?'' you might ask.
* In that case, you can keep a reference, like so
*
* const nsPromiseFlatString& flat = PromiseFlatString(aString);
* // this reference holds the anonymous temporary alive, but remember, it must _still_
* // have a lifetime shorter than that of |aString|
*
* SomeOSFunction(flat.get());
* SomeOtherOSFunction(flat.get());
*
*
* How does it work?
*
* A |nsPromiseFlat[C]String| is just a wrapper for another string. If you apply it to
* a string that happens to be flat, your promise is just a reference to that other string
* and all calls are forwarded through to it. If you apply it to a non-flat string,
* then a temporary flat string is created for you, by allocating and copying. In the unlikely
* event that you end up assigning the result into a sharing string (e.g., |nsCommon[C]String|),
* the right thing happens.
*/
class NS_COM nsPromiseFlatString
: public nsAFlatString /* , public nsAPromiseString */
{
friend const nsPromiseFlatString PromiseFlatString( const nsAString& );
public:
nsPromiseFlatString( const nsPromiseFlatString& );
virtual const PRUnichar* get() const; // this will be gone after we fix obsolete/nsString
protected:
nsPromiseFlatString() : mPromisedString(&mFlattenedString) { }
explicit nsPromiseFlatString( const nsAString& aString );
virtual const nsBufferHandle<char_type>* GetFlatBufferHandle() const;
virtual const nsBufferHandle<char_type>* GetBufferHandle() const;
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseFlatString& );
private:
nsCommonString mFlattenedString;
const nsAFlatString* mPromisedString;
};
class NS_COM nsPromiseFlatCString
: public nsAFlatCString /* , public nsAPromiseCString */
{
friend const nsPromiseFlatCString PromiseFlatCString( const nsACString& );
public:
nsPromiseFlatCString( const nsPromiseFlatCString& );
virtual const char* get() const; // this will be gone after we fix obsolete/nsString
protected:
nsPromiseFlatCString() : mPromisedString(&mFlattenedString) { }
explicit nsPromiseFlatCString( const nsACString& aString );
virtual const nsBufferHandle<char_type>* GetFlatBufferHandle() const;
virtual const nsBufferHandle<char_type>* GetBufferHandle() const;
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseFlatCString& );
private:
nsCommonCString mFlattenedString;
const nsAFlatCString* mPromisedString;
};
inline
const nsPromiseFlatString
PromiseFlatString( const nsAString& aString )
{
return nsPromiseFlatString(aString);
}
inline
const nsPromiseFlatCString
PromiseFlatCString( const nsACString& aString )
{
return nsPromiseFlatCString(aString);
}
#endif /* !defined(nsPromiseFlatString_h___) */

View File

@ -0,0 +1,182 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsPromiseSubstring_h___
#define nsPromiseSubstring_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
//
// nsPromiseSubstring
//
class NS_COM nsPromiseSubstring
: public nsAPromiseString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsAString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
class NS_COM nsPromiseCSubstring
: public nsAPromiseCString
/*
NOT FOR USE BY HUMANS (mostly)
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetReadableFragment()|.
*/
{
typedef nsACString string_type;
typedef string_type::const_iterator const_iterator;
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 ) { return 0; }
public:
nsPromiseCSubstring( const string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsPromiseCSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
// nsPromiseCSubstring( const nsPromiseCSubstring& ); // auto-generated copy-constructor should be OK
// ~nsPromiseCSubstring(); // auto-generated destructor OK
private:
// NOT TO BE IMPLEMENTED
void operator=( const nsPromiseCSubstring& ); // we're immutable, you can't assign into a substring
public:
virtual PRUint32 Length() const;
virtual PRBool Promises( const string_type& aString ) const { return mString.Promises(aString); }
private:
const string_type& mString;
PRUint32 mStartPos;
PRUint32 mLength;
};
inline
const nsPromiseCSubstring
Substring( const nsACString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseCSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseSubstring
Substring( const nsAString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength )
{
return nsPromiseSubstring(aString, aStartPos, aSubstringLength);
}
inline
const nsPromiseCSubstring
Substring( const nsReadingIterator<char>& aStart, const nsReadingIterator<char>& aEnd )
{
return nsPromiseCSubstring(aStart, aEnd);
}
inline
const nsPromiseSubstring
Substring( const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd )
{
return nsPromiseSubstring(aStart, aEnd);
}
#endif /* !defined(nsPromiseSubstring_h___) */

View File

@ -31,16 +31,16 @@
* According to our conventions, they should be |NS_xxx|.
*/
#ifndef nsAWritableString_h___
#include "nsAWritableString.h"
#ifndef nsAString_h___
#include "nsAString.h"
#endif
NS_COM size_t Distance( const nsReadingIterator<PRUnichar>&, const nsReadingIterator<PRUnichar>& );
NS_COM size_t Distance( const nsReadingIterator<char>&, const nsReadingIterator<char>& );
NS_COM void CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest );
NS_COM void CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest );
NS_COM void CopyUCS2toASCII( const nsAString& aSource, nsACString& aDest );
NS_COM void CopyASCIItoUCS2( const nsACString& aSource, nsAString& aDest );
/**
* Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
@ -53,7 +53,7 @@ NS_COM void CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableStrin
* @param aSource a 16-bit wide string
* @return a new |char| buffer you must free with |nsMemory::Free|.
*/
NS_COM char* ToNewCString( const nsAReadableString& aSource );
NS_COM char* ToNewCString( const nsAString& aSource );
/**
@ -65,7 +65,7 @@ NS_COM char* ToNewCString( const nsAReadableString& aSource );
* @param aSource an 8-bit wide string
* @return a new |char| buffer you must free with |nsMemory::Free|.
*/
NS_COM char* ToNewCString( const nsAReadableCString& aSource );
NS_COM char* ToNewCString( const nsACString& aSource );
/**
* Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
@ -78,7 +78,7 @@ NS_COM char* ToNewCString( const nsAReadableCString& aSource );
* @return a new |char| buffer you must free with |nsMemory::Free|.
*/
NS_COM char* ToNewUTF8String( const nsAReadableString& aSource );
NS_COM char* ToNewUTF8String( const nsAString& aSource );
/**
@ -90,7 +90,7 @@ NS_COM char* ToNewUTF8String( const nsAReadableString& aSource );
* @param aSource a 16-bit wide string
* @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
*/
NS_COM PRUnichar* ToNewUnicode( const nsAReadableString& aSource );
NS_COM PRUnichar* ToNewUnicode( const nsAString& aSource );
/**
@ -104,7 +104,7 @@ NS_COM PRUnichar* ToNewUnicode( const nsAReadableString& aSource );
* @param aSource an 8-bit wide string
* @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
*/
NS_COM PRUnichar* ToNewUnicode( const nsAReadableCString& aSource );
NS_COM PRUnichar* ToNewUnicode( const nsACString& aSource );
/**
* Copies |aLength| 16-bit characters from the start of |aSource| to the
@ -118,7 +118,7 @@ NS_COM PRUnichar* ToNewUnicode( const nsAReadableCString& aSource );
* @param aLength the number of 16-bit characters to copy
* @return pointer to destination buffer - identical to |aDest|
*/
NS_COM PRUnichar* CopyUnicodeTo( const nsAReadableString& aSource,
NS_COM PRUnichar* CopyUnicodeTo( const nsAString& aSource,
PRUint32 aSrcOffset,
PRUnichar* aDest,
PRUint32 aLength );
@ -137,7 +137,7 @@ NS_COM PRUnichar* CopyUnicodeTo( const nsAReadableString& aSource,
*/
NS_COM void CopyUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
const nsReadingIterator<PRUnichar>& aSrcEnd,
nsAWritableString& aDest );
nsAString& aDest );
/**
* Appends 16-bit characters between iterators |aSrcStart| and
@ -151,25 +151,25 @@ NS_COM void CopyUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
*/
NS_COM void AppendUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
const nsReadingIterator<PRUnichar>& aSrcEnd,
nsAWritableString& aDest );
nsAString& aDest );
/**
* Returns |PR_TRUE| if |aString| contains only ASCII characters, that is, characters in the range (0x00, 0x7F).
*
* @param aString a 16-bit wide string to scan
*/
NS_COM PRBool IsASCII( const nsAReadableString& aString );
NS_COM PRBool IsASCII( const nsAString& aString );
/**
* Converts case in place in the argument string.
*/
NS_COM void ToUpperCase( nsAWritableString& );
NS_COM void ToUpperCase( nsAWritableCString& );
NS_COM void ToUpperCase( nsAString& );
NS_COM void ToUpperCase( nsACString& );
NS_COM void ToLowerCase( nsAWritableString& );
NS_COM void ToLowerCase( nsAWritableCString& );
NS_COM void ToLowerCase( nsAString& );
NS_COM void ToLowerCase( nsACString& );
/**
* Finds the leftmost occurance of |aPattern|, if any in the range |aSearchStart|..|aSearchEnd|.
@ -180,8 +180,8 @@ NS_COM void ToLowerCase( nsAWritableCString& );
* Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|.
* If we need something faster; we can implement that later.
*/
NS_COM PRBool FindInReadable( const nsAReadableString& aPattern, nsReadingIterator<PRUnichar>&, nsReadingIterator<PRUnichar>& );
NS_COM PRBool FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator<char>&, nsReadingIterator<char>& );
NS_COM PRBool FindInReadable( const nsAString& aPattern, nsReadingIterator<PRUnichar>&, nsReadingIterator<PRUnichar>& );
NS_COM PRBool FindInReadable( const nsACString& aPattern, nsReadingIterator<char>&, nsReadingIterator<char>& );
/**
@ -192,8 +192,8 @@ NS_COM PRBool FindInReadable( const nsAReadableCString& aPattern, nsReadingItera
* Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|.
* If we need something faster; we can implement that later.
*/
NS_COM PRBool RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator<PRUnichar>&, nsReadingIterator<PRUnichar>& );
NS_COM PRBool RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator<char>&, nsReadingIterator<char>& );
NS_COM PRBool RFindInReadable( const nsAString& aPattern, nsReadingIterator<PRUnichar>&, nsReadingIterator<PRUnichar>& );
NS_COM PRBool RFindInReadable( const nsACString& aPattern, nsReadingIterator<char>&, nsReadingIterator<char>& );
/**
* Finds the leftmost occurance of |aChar|, if any in the range
@ -209,9 +209,9 @@ NS_COM PRBool FindCharInReadable( char aChar, nsReadingIterator<char>& aSearchSt
/**
* Finds the number of occurences of |aChar| in the string |aStr|
*/
NS_COM PRUint32 CountCharInReadable( const nsAReadableString& aStr,
NS_COM PRUint32 CountCharInReadable( const nsAString& aStr,
PRUnichar aChar );
NS_COM PRUint32 CountCharInReadable( const nsAReadableCString& aStr,
NS_COM PRUint32 CountCharInReadable( const nsACString& aStr,
char aChar );
#endif // !defined(nsReadableUtils_h___)

View File

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsCommonString.h --- a string implementation that shares its underlying storage */
#ifndef nsCommonString_h___
#define nsCommonString_h___
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
#ifndef nsBufferHandleUtils_h___
#include "nsBufferHandleUtils.h"
#endif
//-------1---------2---------3---------4---------5---------6---------7---------8
/**
* Not yet ready for non-|const| access
*/
class NS_COM nsCommonString
: public nsAFlatString
{
public:
typedef nsCommonString self_type;
typedef PRUnichar char_type;
typedef nsAString string_type;
public:
nsCommonString() { }
nsCommonString( const self_type& aOther ) : mBuffer(aOther.mBuffer) { }
nsCommonString( const string_type& aReadable ) { assign(aReadable); }
self_type&
operator=( const string_type& aReadable )
{
assign(aReadable);
return *this;
}
protected:
void assign( const string_type& );
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
nsAutoBufferHandle<char_type> mBuffer;
};
class NS_COM nsCommonCString
: public nsAFlatCString
{
public:
typedef nsCommonCString self_type;
typedef char char_type;
typedef nsACString string_type;
public:
nsCommonCString() { }
nsCommonCString( const self_type& aOther ) : mBuffer(aOther.mBuffer) { }
nsCommonCString( const string_type& aReadable ) { assign(aReadable); }
self_type&
operator=( const string_type& aReadable )
{
assign(aReadable);
return *this;
}
protected:
void assign( const string_type& );
virtual const nsSharedBufferHandle<char_type>* GetSharedBufferHandle() const;
private:
nsAutoBufferHandle<char_type> mBuffer;
};
#endif /* !defined(nsCommonString_h___) */

View File

@ -35,9 +35,12 @@
// for |PRUnichar|
#endif
#ifndef nsAReadableString_h___
#include "nsAReadableString.h"
// for |nsReadingIterator|
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsLocalString_h___
#include "nsLocalString.h"
#endif
#ifndef nsBufferHandleUtils_h___
@ -180,12 +183,12 @@ class NS_COM nsSharedBufferList
NewSingleAllocationBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalCapacity = 1 )
{
typedef Buffer* Buffer_ptr;
return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), NS_READABLE_CAST(PRUnichar, nsLiteralString(aData, aDataLength)), aAdditionalCapacity);
return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), nsLocalString(aData, aDataLength), aAdditionalCapacity);
}
static
Buffer*
NewSingleAllocationBuffer( const nsAReadableString& aReadable, PRUint32 aAdditionalCapacity = 1 )
NewSingleAllocationBuffer( const nsAString& aReadable, PRUint32 aAdditionalCapacity = 1 )
{
typedef Buffer* Buffer_ptr;
return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), aReadable, aAdditionalCapacity);

View File

@ -25,8 +25,13 @@
#ifndef nsSlidingString_h___
#define nsSlidingString_h___
#include "nsAReadableString.h"
#ifndef nsAString_h___
#include "nsAString.h"
#endif
#ifndef nsSharedBufferList_h___
#include "nsSharedBufferList.h"
#endif
/**
@ -69,7 +74,7 @@ class nsSlidingString;
* a substring over a buffer list, this
*/
class NS_COM nsSlidingSubstring
: virtual public nsPromiseReadable<PRUnichar>
: virtual public nsAPromiseString
{
friend class nsSlidingString;
@ -90,14 +95,14 @@ class NS_COM nsSlidingSubstring
nsSlidingSubstring( const nsSlidingSubstring& aString, const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd );
nsSlidingSubstring( const nsSlidingString& );
nsSlidingSubstring( const nsSlidingString& aString, const nsReadingIterator<PRUnichar>& aStart, const nsReadingIterator<PRUnichar>& aEnd );
explicit nsSlidingSubstring( const nsAReadableString& );
explicit nsSlidingSubstring( const nsAString& );
// copy the supplied string into a new buffer ... there will be no modifying instance over this buffer list
void Rebind( const nsSlidingSubstring& );
void Rebind( const nsSlidingSubstring&, const nsReadingIterator<PRUnichar>&, const nsReadingIterator<PRUnichar>& );
void Rebind( const nsSlidingString& );
void Rebind( const nsSlidingString&, const nsReadingIterator<PRUnichar>&, const nsReadingIterator<PRUnichar>& );
void Rebind( const nsAReadableString& );
void Rebind( const nsAString& );
~nsSlidingSubstring();
@ -106,6 +111,7 @@ class NS_COM nsSlidingSubstring
protected:
nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList );
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
private:
// can't assign into me, I'm a read-only reference
@ -154,7 +160,7 @@ class NS_COM nsSlidingSubstring
*
*/
class NS_COM nsSlidingString
: virtual public nsPromiseReadable<PRUnichar>,
: virtual public nsAPromiseString,
private nsSlidingSubstring
{
friend class nsSlidingSubstring;
@ -176,8 +182,9 @@ class NS_COM nsSlidingString
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
void InsertReadable( const nsAReadableString&, const nsReadingIterator<PRUnichar>& ); // ...to implement |nsScannerString::UngetReadable|
void InsertReadable( const nsAString&, const nsReadingIterator<PRUnichar>& ); // ...to implement |nsScannerString::UngetReadable|
private:

View File

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsStringFragment.h --- machinery that makes string iterators work */
#ifndef nsStringFragment_h___
#define nsStringFragment_h___
/**
* An |nsFragmentRequest| is used to tell |GetReadableFragment| and
* |GetWritableFragment| what to do.
*
* @see GetReadableFragment
*/
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
/**
* A |nsReadableFragment| provides |const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsReadableFragment| is the underlying machinery that lets
* |nsReadingIterator|s work.
*
* @see nsReadingIterator
*/
template <class CharT>
struct nsReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
const void* mFragmentIdentifier;
nsReadableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
}
};
/**
* A |nsWritableFragment| provides non-|const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsWritableFragment| is the underlying machinery that lets
* |nsWritingIterator|s work.
*
* @see nsWritingIterator
*/
template <class CharT>
struct nsWritableFragment
{
CharT* mStart;
CharT* mEnd;
void* mFragmentIdentifier;
nsWritableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
}
};
#endif /* !defined(nsStringFragment_h___) */

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsStringFwd.h --- forward declarations for string classes */
#ifndef nsStringFwd_h___
#define nsStringFwd_h___
/**
* @see nsAString.h
*/
class nsAString;
class nsACString;
/**
* @see nsAPromiseString.h
*/
class nsAPromiseString;
class nsAPromiseCString;
/**
* @see nsAFlatString.h
*/
class nsAFlatString;
class nsAFlatCString;
/**
* @see nsLocalString.h
*/
class nsLocalString;
class nsLocalCString;
#endif /* !defined(nsStringFwd_h___) */

View File

@ -0,0 +1,436 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsStringIterator_h___
#define nsStringIterator_h___
#ifndef nsStringFragment_h___
#include "nsStringFragment.h"
#endif
#ifndef nsCharTraits_h___
#include "nsCharTraits.h"
#endif
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
#ifndef nsAlgorithm_h___
#include "nsAlgorithm.h"
// for |NS_MIN|, |NS_MAX|, and |NS_COUNT|...
#endif
/**
*
* @see nsReadableFragment
* @see nsAString
*/
template <class CharT>
class nsReadingIterator
// : public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
typedef CharT value_type;
typedef const CharT* pointer;
typedef const CharT& reference;
// typedef bidirectional_iterator_tag iterator_category;
private:
friend class nsAString;
friend class nsACString;
typedef typename nsStringTraits<CharT>::abstract_string_type string_type;
nsReadableFragment<CharT> mFragment;
const CharT* mPosition;
const string_type* mOwningString;
public:
nsReadingIterator() { }
// nsReadingIterator( const nsReadingIterator<CharT>& ); // auto-generated copy-constructor OK
// nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); // auto-generated copy-assignment operator OK
inline void normalize_forward();
inline void normalize_backward();
pointer
get() const
{
return mPosition;
}
CharT
operator*() const
{
return *get();
}
#if 0
// An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2)
// don't like this when |CharT| is a type without members.
pointer
operator->() const
{
return get();
}
#endif
nsReadingIterator<CharT>&
operator++()
{
++mPosition;
normalize_forward();
return *this;
}
nsReadingIterator<CharT>
operator++( int )
{
nsReadingIterator<CharT> result(*this);
++mPosition;
normalize_forward();
return result;
}
nsReadingIterator<CharT>&
operator--()
{
normalize_backward();
--mPosition;
return *this;
}
nsReadingIterator<CharT>
operator--( int )
{
nsReadingIterator<CharT> result(*this);
normalize_backward();
--mPosition;
return result;
}
const nsReadableFragment<CharT>&
fragment() const
{
return mFragment;
}
const string_type&
string() const
{
NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)");
return *mOwningString;
}
difference_type
size_forward() const
{
return mFragment.mEnd - mPosition;
}
difference_type
size_backward() const
{
return mPosition - mFragment.mStart;
}
nsReadingIterator<CharT>&
advance( difference_type n )
{
while ( n > 0 )
{
difference_type one_hop = NS_MIN(n, size_forward());
NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
normalize_forward();
n -= one_hop;
}
while ( n < 0 )
{
normalize_backward();
difference_type one_hop = NS_MAX(n, -size_backward());
NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
n -= one_hop;
}
return *this;
}
};
template <class CharT>
class nsWritingIterator
// : public nsReadingIterator<CharT>
{
public:
typedef ptrdiff_t difference_type;
typedef CharT value_type;
typedef CharT* pointer;
typedef CharT& reference;
// typedef bidirectional_iterator_tag iterator_category;
private:
friend class nsAString;
friend class nsACString;
typedef typename nsStringTraits<CharT>::abstract_string_type string_type;
nsWritableFragment<CharT> mFragment;
CharT* mPosition;
string_type* mOwningString;
public:
nsWritingIterator() { }
// nsWritingIterator( const nsWritingIterator<CharT>& ); // auto-generated copy-constructor OK
// nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); // auto-generated copy-assignment operator OK
inline void normalize_forward();
inline void normalize_backward();
pointer
get() const
{
return mPosition;
}
reference
operator*() const
{
return *get();
}
#if 0
// An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2)
// don't like this when |CharT| is a type without members.
pointer
operator->() const
{
return get();
}
#endif
nsWritingIterator<CharT>&
operator++()
{
++mPosition;
normalize_forward();
return *this;
}
nsWritingIterator<CharT>
operator++( int )
{
nsWritingIterator<CharT> result(*this);
++mPosition;
normalize_forward();
return result;
}
nsWritingIterator<CharT>&
operator--()
{
normalize_backward();
--mPosition;
return *this;
}
nsWritingIterator<CharT>
operator--( int )
{
nsWritingIterator<CharT> result(*this);
normalize_backward();
--mPosition;
return result;
}
const nsWritableFragment<CharT>&
fragment() const
{
return mFragment;
}
nsWritableFragment<CharT>&
fragment()
{
return mFragment;
}
const string_type&
string() const
{
NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)");
return *mOwningString;
}
string_type&
string()
{
NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)");
return *mOwningString;
}
difference_type
size_forward() const
{
return mFragment.mEnd - mPosition;
}
difference_type
size_backward() const
{
return mPosition - mFragment.mStart;
}
nsWritingIterator<CharT>&
advance( difference_type n )
{
while ( n > 0 )
{
difference_type one_hop = NS_MIN(n, size_forward());
NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
normalize_forward();
n -= one_hop;
}
while ( n < 0 )
{
normalize_backward();
difference_type one_hop = NS_MAX(n, -size_backward());
NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string");
// perhaps I should |break| if |!one_hop|?
mPosition += one_hop;
n -= one_hop;
}
return *this;
}
PRUint32
write( const value_type* s, PRUint32 n )
{
NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!");
n = NS_MIN(n, PRUint32(size_forward()));
nsCharTraits<value_type>::move(mPosition, s, n);
advance( difference_type(n) );
return n;
}
};
template <class CharT>
inline
void
nsReadingIterator<CharT>::normalize_forward()
{
while ( mPosition == mFragment.mEnd
&& mOwningString->GetReadableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
template <class CharT>
inline
void
nsReadingIterator<CharT>::normalize_backward()
{
while ( mPosition == mFragment.mStart
&& mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
template <class CharT>
inline
PRBool
operator==( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs )
{
return lhs.get() == rhs.get();
}
template <class CharT>
inline
PRBool
operator!=( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs )
{
return lhs.get() != rhs.get();
}
//
// |nsWritingIterator|s
//
template <class CharT>
inline
void
nsWritingIterator<CharT>::normalize_forward()
{
while ( mPosition == mFragment.mEnd
&& mOwningString->GetWritableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
template <class CharT>
inline
void
nsWritingIterator<CharT>::normalize_backward()
{
while ( mPosition == mFragment.mStart
&& mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
template <class CharT>
inline
PRBool
operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
{
return lhs.get() == rhs.get();
}
template <class CharT>
inline
PRBool
operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
{
return lhs.get() != rhs.get();
}
#endif /* !defined(nsStringIterator_h___) */

View File

@ -0,0 +1,44 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#ifndef nsStringIteratorUtils_h___
#define nsStringIteratorUtils_h___
template <class Iterator>
inline
PRBool
SameFragment( const Iterator& lhs, const Iterator& rhs )
{
return lhs.fragment().mStart == rhs.fragment().mStart;
}
template <class CharT> class nsReadingIterator;
// NOTE: need to break iterators out into their own file (as with many classes here), need
// these routines, but can't currently |#include "nsReadableUtils.h"|, this hack is bad
// but we need it to get OS2 building again. Fix by splitting things into different files.
NS_COM size_t Distance( const nsReadingIterator<PRUnichar>&, const nsReadingIterator<PRUnichar>& );
NS_COM size_t Distance( const nsReadingIterator<char>&, const nsReadingIterator<char>& );
#endif /* !defined(nsStringIteratorUtils_h___) */

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsStringTraits.h --- declares specialized ``traits'' classes which allow templatized functions and classes to select appropriate non-template types */
#ifndef nsStringTraits_h___
#define nsStringTraits_h___
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nscore_h___
#include "nscore.h"
#endif
/**
*
*/
template <class CharT>
struct nsStringTraits
{
typedef nsAString abstract_string_type;
typedef nsAPromiseString abstract_promise_type;
typedef nsAFlatString abstract_flat_type;
typedef const nsLocalString literal_string_type;
};
#if 0
// for lame compilers, put these declarations into the general case
// so we only need to specialize for |char|
NS_SPECIALIZE_TEMPLATE
struct nsStringTraits<PRUnichar>
{
typedef nsAString abstract_string_type;
typedef nsAPromiseString abstract_promise_type;
typedef nsAFlatString abstract_flat_type;
typedef const nsLocalString literal_string_type;
};
#endif
NS_SPECIALIZE_TEMPLATE
struct nsStringTraits<char>
{
typedef nsACString abstract_string_type;
typedef nsAPromiseCString abstract_promise_type;
typedef nsAFlatCString abstract_flat_type;
typedef const nsLocalCString literal_string_type;
};
#endif /* !defined(nsStringTraits_h___) */

View File

@ -18,6 +18,7 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH = ../..
@ -33,8 +34,16 @@ LIBRARY_NAME = string_s
REQUIRES = xpcom
CPPSRCS = \
nsAFlatString.cpp \
nsAString.cpp \
nsCommonString.cpp \
nsFragmentedString.cpp \
nsLocalString.cpp \
nsPrintfCString.cpp \
nsPrivateSharableString.cpp \
nsPromiseConcatenation.cpp \
nsPromiseFlatString.cpp \
nsPromiseSubstring.cpp \
nsReadableUtils.cpp \
nsSharedBufferList.cpp \
nsSlidingString.cpp \

View File

@ -19,6 +19,7 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH=..\..
@ -28,8 +29,16 @@ LIBRARY_NAME=string_s
LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
CPP_OBJS = \
.\$(OBJDIR)\nsAFlatString.obj \
.\$(OBJDIR)\nsAString.obj \
.\$(OBJDIR)\nsCommonString.obj \
.\$(OBJDIR)\nsFragmentedString.obj \
.\$(OBJDIR)\nsLocalString.obj \
.\$(OBJDIR)\nsPrintfCString.obj \
.\$(OBJDIR)\nsPrivateSharableString.obj \
.\$(OBJDIR)\nsPromiseConcatenation.obj \
.\$(OBJDIR)\nsPromiseFlatString.obj \
.\$(OBJDIR)\nsPromiseSubstring.obj \
.\$(OBJDIR)\nsReadableUtils.obj \
.\$(OBJDIR)\nsSharedBufferList.obj \
.\$(OBJDIR)\nsSlidingString.obj \

View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsAFlatString.h"
const PRUnichar*
nsAFlatString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
const nsBufferHandle<PRUnichar>* buffer = GetBufferHandle();
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
PRUnichar*
nsAFlatString::GetWritableFragment( nsWritableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
nsBufferHandle<PRUnichar>* buffer = NS_CONST_CAST(nsBufferHandle<PRUnichar>*, GetBufferHandle());
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
const char*
nsAFlatCString::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
const nsBufferHandle<char>* buffer = GetBufferHandle();
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
char*
nsAFlatCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
nsBufferHandle<char>* buffer = NS_CONST_CAST(nsBufferHandle<char>*, GetBufferHandle());
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}

921
string/src/nsAString.cpp Normal file
View File

@ -0,0 +1,921 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsAString.h"
#include "nsPromiseSubstring.h"
#include "nsLocalString.h"
NS_COM
int
Compare( const nsAString& lhs, const nsAString& rhs )
{
typedef nsAString::size_type size_type;
if ( &lhs == &rhs )
return 0;
size_type lLength = lhs.Length();
size_type rLength = rhs.Length();
size_type lengthToCompare = NS_MIN(lLength, rLength);
nsAString::const_iterator leftIter, rightIter;
lhs.BeginReading(leftIter);
rhs.BeginReading(rightIter);
int result;
for (;;)
{
size_type lengthAvailable = size_type( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;
// Note: |result| should be declared in this |if| expression, but some compilers don't like that
if ( (result = nsCharTraits<PRUnichar>::compare(leftIter.get(), rightIter.get(), lengthAvailable)) != 0 )
return result;
if ( !(lengthToCompare -= lengthAvailable) )
break;
leftIter.advance( PRInt32(lengthAvailable) );
rightIter.advance( PRInt32(lengthAvailable) );
}
if ( lLength < rLength )
return -1;
else if ( rLength < lLength )
return 1;
else
return 0;
}
PRBool
nsAString::Equals( const char_type* rhs ) const
{
return Equals(nsLocalString(rhs));
}
nsAString::char_type
nsAString::First() const
{
NS_ASSERTION(Length()>0, "|First()| on an empty string");
const_iterator iter;
return *BeginReading(iter);
}
nsAString::char_type
nsAString::Last() const
{
NS_ASSERTION(Length()>0, "|Last()| on an empty string");
const_iterator iter;
if ( !IsEmpty() )
{
EndReading(iter);
iter.advance(-1);
}
return *iter; // Note: this has undefined results if |IsEmpty()|
}
nsAString::size_type
nsAString::CountChar( char_type c ) const
{
/*
re-write this to use a counting sink
*/
size_type result = 0;
size_type lengthToExamine = Length();
const_iterator iter;
for ( BeginReading(iter); ; )
{
PRInt32 lengthToExamineInThisFragment = iter.size_forward();
const char_type* fromBegin = iter.get();
result += size_type(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c));
if ( !(lengthToExamine -= lengthToExamineInThisFragment) )
return result;
iter.advance(lengthToExamineInThisFragment);
}
// never reached; quiets warnings
return 0;
}
nsAString::size_type
nsAString::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
{
// If we're just assigning our entire self, give |aResult| the opportunity to share
if ( aStartPos == 0 && aLengthToCopy >= Length() )
aResult = *this;
else
aResult = Substring(*this, aStartPos, aLengthToCopy);
return aResult.Length();
}
nsAString::size_type
nsAString::Right( self_type& aResult, size_type aLengthToCopy ) const
{
size_type myLength = Length();
aLengthToCopy = NS_MIN(myLength, aLengthToCopy);
return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy);
}
PRInt32
nsAString::FindChar( char_type aChar, PRUint32 aOffset ) const
{
const_iterator iter, done_searching;
BeginReading(iter).advance( PRInt32(aOffset) );
EndReading(done_searching);
size_type lengthSearched = 0;
while ( iter != done_searching )
{
PRInt32 fragmentLength = iter.size_forward();
const char_type* charFoundAt = nsCharTraits<char_type>::find(iter.get(), fragmentLength, aChar);
if ( charFoundAt )
return lengthSearched + (charFoundAt-iter.get()) + aOffset;
lengthSearched += fragmentLength;
iter.advance(fragmentLength);
}
return -1;
}
//
// |Assign()|
//
void
nsAString::AssignFromReadable( const self_type& rhs )
{
if ( this != &rhs )
do_AssignFromReadable(rhs);
// else, self-assign is a no-op
}
void
nsAString::AssignFromPromise( const self_type& aReadable )
/*
...this function is only called when a promise that somehow references |this| is assigned _into_ |this|.
E.g.,
... writable& w ...
... readable& r ...
w = r + w;
In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before
anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents
of |r| before being retrieved to be appended.
We could have a really tricky solution where we tell the promise to resolve _just_ the data promised
by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g.,
in the case above, |Insert| could have special behavior with significantly better performance. Since
it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the
entire promise. If we measure and this turns out to show up on performance radar, we then have the
option to fix either the callers or this mechanism.
*/
{
if ( !aReadable.Promises(*this) )
do_AssignFromReadable(aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
// Note: not exception safe. We need something to manage temporary buffers like this
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AssignFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
void
nsAString::do_AssignFromReadable( const self_type& aReadable )
{
SetLength(0);
SetLength(aReadable.Length());
// first setting the length to |0| avoids copying characters only to be overwritten later
// in the case where the implementation decides to re-allocate
const_iterator fromBegin, fromEnd;
iterator toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin));
}
void
nsAString::do_AssignFromElementPtr( const char_type* aPtr )
{
do_AssignFromReadable(nsLocalString(aPtr));
}
void
nsAString::do_AssignFromElementPtrLength( const char_type* aPtr, size_type aLength )
{
do_AssignFromReadable(nsLocalString(aPtr, aLength));
}
void
nsAString::do_AssignFromElement( char_type aChar )
{
do_AssignFromReadable(nsLocalString(&aChar, 1));
}
//
// |Append()|
//
void
nsAString::AppendFromReadable( const self_type& aReadable )
{
if ( this != &aReadable )
do_AppendFromReadable(aReadable);
else
AppendFromPromise(aReadable);
}
void
nsAString::AppendFromPromise( const self_type& aReadable )
{
if ( !aReadable.Promises(*this) )
do_AppendFromReadable(aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AppendFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
void
nsAString::do_AppendFromReadable( const self_type& aReadable )
{
size_type oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
const_iterator fromBegin, fromEnd;
iterator toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) );
}
void
nsAString::do_AppendFromElementPtr( const char_type* aChar )
{
do_AppendFromReadable(nsLocalString(aChar));
}
void
nsAString::do_AppendFromElementPtrLength( const char_type* aChar, size_type aLength )
{
do_AppendFromReadable(nsLocalString(aChar, aLength));
}
void
nsAString::do_AppendFromElement( char_type aChar )
{
do_AppendFromReadable(nsLocalString(&aChar, 1));
}
//
// |Insert()|
//
void
nsAString::InsertFromReadable( const self_type& aReadable, index_type atPosition )
{
if ( this != &aReadable )
do_InsertFromReadable(aReadable, atPosition);
else
InsertFromPromise(aReadable, atPosition);
}
void
nsAString::InsertFromPromise( const self_type& aReadable, index_type atPosition )
{
if ( !aReadable.Promises(*this) )
do_InsertFromReadable(aReadable, atPosition);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_InsertFromElementPtrLength(buffer, atPosition, length);
delete buffer;
}
// else assert
}
}
void
nsAString::do_InsertFromReadable( const self_type& aReadable, index_type atPosition )
{
size_type oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( atPosition < oldLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin));
else
atPosition = oldLength;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition)));
}
void
nsAString::do_InsertFromElementPtr( const char_type* aPtr, index_type atPosition )
{
do_InsertFromReadable(nsLocalString(aPtr), atPosition);
}
void
nsAString::do_InsertFromElementPtrLength( const char_type* aPtr, index_type atPosition, size_type aLength )
{
do_InsertFromReadable(nsLocalString(aPtr, aLength), atPosition);
}
void
nsAString::do_InsertFromElement( char_type aChar, index_type atPosition )
{
do_InsertFromReadable(nsLocalString(&aChar, 1), atPosition);
}
//
// |Cut()|
//
void
nsAString::Cut( index_type cutStart, size_type cutLength )
{
size_type myLength = this->Length();
cutLength = NS_MIN(cutLength, myLength-cutStart);
index_type cutEnd = cutStart + cutLength;
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( cutEnd < myLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
SetLength(myLength-cutLength);
}
//
// |Replace()|
//
void
nsAString::ReplaceFromReadable( index_type cutStart, size_type cutLength, const self_type& aReplacement )
{
if ( this != &aReplacement )
do_ReplaceFromReadable(cutStart, cutLength, aReplacement);
else
ReplaceFromPromise(cutStart, cutLength, aReplacement);
}
void
nsAString::ReplaceFromPromise( index_type cutStart, size_type cutLength, const self_type& aReadable )
{
if ( !aReadable.Promises(*this) )
do_ReplaceFromReadable(cutStart, cutLength, aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_ReplaceFromReadable(cutStart, cutLength, nsLocalString(buffer, length));
delete buffer;
}
// else assert?
}
}
void
nsAString::do_ReplaceFromReadable( index_type cutStart, size_type cutLength, const self_type& aReplacement )
{
size_type oldLength = this->Length();
cutStart = NS_MIN(cutStart, oldLength);
cutLength = NS_MIN(cutLength, oldLength-cutStart);
index_type cutEnd = cutStart + cutLength;
size_type replacementLength = aReplacement.Length();
index_type replacementEnd = cutStart + replacementLength;
size_type newLength = oldLength - cutLength + replacementLength;
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( cutLength > replacementLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
}
NS_COM
int
Compare( const nsACString& lhs, const nsACString& rhs )
{
typedef nsACString::size_type size_type;
if ( &lhs == &rhs )
return 0;
size_type lLength = lhs.Length();
size_type rLength = rhs.Length();
size_type lengthToCompare = NS_MIN(lLength, rLength);
nsACString::const_iterator leftIter, rightIter;
lhs.BeginReading(leftIter);
rhs.BeginReading(rightIter);
int result;
for (;;)
{
size_type lengthAvailable = size_type( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;
// Note: |result| should be declared in this |if| expression, but some compilers don't like that
if ( (result = nsCharTraits<char>::compare(leftIter.get(), rightIter.get(), lengthAvailable)) != 0 )
return result;
if ( !(lengthToCompare -= lengthAvailable) )
break;
leftIter.advance( PRInt32(lengthAvailable) );
rightIter.advance( PRInt32(lengthAvailable) );
}
if ( lLength < rLength )
return -1;
else if ( rLength < lLength )
return 1;
else
return 0;
}
PRBool
nsACString::Equals( const char_type* rhs ) const
{
return Equals(nsLocalCString(rhs));
}
nsACString::char_type
nsACString::First() const
{
NS_ASSERTION(Length()>0, "|First()| on an empty string");
const_iterator iter;
return *BeginReading(iter);
}
nsACString::char_type
nsACString::Last() const
{
NS_ASSERTION(Length()>0, "|Last()| on an empty string");
const_iterator iter;
if ( !IsEmpty() )
{
EndReading(iter);
iter.advance(-1);
}
return *iter; // Note: this has undefined results if |IsEmpty()|
}
nsACString::size_type
nsACString::CountChar( char_type c ) const
{
/*
re-write this to use a counting sink
*/
size_type result = 0;
size_type lengthToExamine = Length();
const_iterator iter;
for ( BeginReading(iter); ; )
{
PRInt32 lengthToExamineInThisFragment = iter.size_forward();
const char_type* fromBegin = iter.get();
result += size_type(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c));
if ( !(lengthToExamine -= lengthToExamineInThisFragment) )
return result;
iter.advance(lengthToExamineInThisFragment);
}
// never reached; quiets warnings
return 0;
}
nsACString::size_type
nsACString::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
{
// If we're just assigning our entire self, give |aResult| the opportunity to share
if ( aStartPos == 0 && aLengthToCopy >= Length() )
aResult = *this;
else
aResult = Substring(*this, aStartPos, aLengthToCopy);
return aResult.Length();
}
nsACString::size_type
nsACString::Right( self_type& aResult, size_type aLengthToCopy ) const
{
size_type myLength = Length();
aLengthToCopy = NS_MIN(myLength, aLengthToCopy);
return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy);
}
PRInt32
nsACString::FindChar( char_type aChar, PRUint32 aOffset ) const
{
const_iterator iter, done_searching;
BeginReading(iter).advance( PRInt32(aOffset) );
EndReading(done_searching);
size_type lengthSearched = 0;
while ( iter != done_searching )
{
PRInt32 fragmentLength = iter.size_forward();
const char_type* charFoundAt = nsCharTraits<char_type>::find(iter.get(), fragmentLength, aChar);
if ( charFoundAt )
return lengthSearched + (charFoundAt-iter.get()) + aOffset;
lengthSearched += fragmentLength;
iter.advance(fragmentLength);
}
return -1;
}
//
// |Assign()|
//
void
nsACString::AssignFromReadable( const self_type& rhs )
{
if ( this != &rhs )
do_AssignFromReadable(rhs);
// else, self-assign is a no-op
}
void
nsACString::AssignFromPromise( const self_type& aReadable )
/*
...this function is only called when a promise that somehow references |this| is assigned _into_ |this|.
E.g.,
... writable& w ...
... readable& r ...
w = r + w;
In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before
anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents
of |r| before being retrieved to be appended.
We could have a really tricky solution where we tell the promise to resolve _just_ the data promised
by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g.,
in the case above, |Insert| could have special behavior with significantly better performance. Since
it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the
entire promise. If we measure and this turns out to show up on performance radar, we then have the
option to fix either the callers or this mechanism.
*/
{
if ( !aReadable.Promises(*this) )
do_AssignFromReadable(aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
// Note: not exception safe. We need something to manage temporary buffers like this
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AssignFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
void
nsACString::do_AssignFromReadable( const self_type& aReadable )
{
SetLength(0);
SetLength(aReadable.Length());
// first setting the length to |0| avoids copying characters only to be overwritten later
// in the case where the implementation decides to re-allocate
const_iterator fromBegin, fromEnd;
iterator toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin));
}
void
nsACString::do_AssignFromElementPtr( const char_type* aPtr )
{
do_AssignFromReadable(nsLocalCString(aPtr));
}
void
nsACString::do_AssignFromElementPtrLength( const char_type* aPtr, size_type aLength )
{
do_AssignFromReadable(nsLocalCString(aPtr, aLength));
}
void
nsACString::do_AssignFromElement( char_type aChar )
{
do_AssignFromReadable(nsLocalCString(&aChar, 1));
}
//
// |Append()|
//
void
nsACString::AppendFromReadable( const self_type& aReadable )
{
if ( this != &aReadable )
do_AppendFromReadable(aReadable);
else
AppendFromPromise(aReadable);
}
void
nsACString::AppendFromPromise( const self_type& aReadable )
{
if ( !aReadable.Promises(*this) )
do_AppendFromReadable(aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_AppendFromElementPtrLength(buffer, length);
delete buffer;
}
// else assert?
}
}
void
nsACString::do_AppendFromReadable( const self_type& aReadable )
{
size_type oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
const_iterator fromBegin, fromEnd;
iterator toBegin;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) );
}
void
nsACString::do_AppendFromElementPtr( const char_type* aChar )
{
do_AppendFromReadable(nsLocalCString(aChar));
}
void
nsACString::do_AppendFromElementPtrLength( const char_type* aChar, size_type aLength )
{
do_AppendFromReadable(nsLocalCString(aChar, aLength));
}
void
nsACString::do_AppendFromElement( char_type aChar )
{
do_AppendFromReadable(nsLocalCString(&aChar, 1));
}
//
// |Insert()|
//
void
nsACString::InsertFromReadable( const self_type& aReadable, index_type atPosition )
{
if ( this != &aReadable )
do_InsertFromReadable(aReadable, atPosition);
else
InsertFromPromise(aReadable, atPosition);
}
void
nsACString::InsertFromPromise( const self_type& aReadable, index_type atPosition )
{
if ( !aReadable.Promises(*this) )
do_InsertFromReadable(aReadable, atPosition);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_InsertFromElementPtrLength(buffer, atPosition, length);
delete buffer;
}
// else assert
}
}
void
nsACString::do_InsertFromReadable( const self_type& aReadable, index_type atPosition )
{
size_type oldLength = this->Length();
SetLength(oldLength + aReadable.Length());
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( atPosition < oldLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin));
else
atPosition = oldLength;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition)));
}
void
nsACString::do_InsertFromElementPtr( const char_type* aPtr, index_type atPosition )
{
do_InsertFromReadable(nsLocalCString(aPtr), atPosition);
}
void
nsACString::do_InsertFromElementPtrLength( const char_type* aPtr, index_type atPosition, size_type aLength )
{
do_InsertFromReadable(nsLocalCString(aPtr, aLength), atPosition);
}
void
nsACString::do_InsertFromElement( char_type aChar, index_type atPosition )
{
do_InsertFromReadable(nsLocalCString(&aChar, 1), atPosition);
}
//
// |Cut()|
//
void
nsACString::Cut( index_type cutStart, size_type cutLength )
{
size_type myLength = this->Length();
cutLength = NS_MIN(cutLength, myLength-cutStart);
index_type cutEnd = cutStart + cutLength;
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( cutEnd < myLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
SetLength(myLength-cutLength);
}
//
// |Replace()|
//
void
nsACString::ReplaceFromReadable( index_type cutStart, size_type cutLength, const self_type& aReplacement )
{
if ( this != &aReplacement )
do_ReplaceFromReadable(cutStart, cutLength, aReplacement);
else
ReplaceFromPromise(cutStart, cutLength, aReplacement);
}
void
nsACString::ReplaceFromPromise( index_type cutStart, size_type cutLength, const self_type& aReadable )
{
if ( !aReadable.Promises(*this) )
do_ReplaceFromReadable(cutStart, cutLength, aReadable);
else
{
size_type length = aReadable.Length();
char_type* buffer = new char_type[length];
if ( buffer )
{
const_iterator fromBegin, fromEnd;
char_type* toBegin = buffer;
copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin);
do_ReplaceFromReadable(cutStart, cutLength, nsLocalCString(buffer, length));
delete buffer;
}
// else assert?
}
}
void
nsACString::do_ReplaceFromReadable( index_type cutStart, size_type cutLength, const self_type& aReplacement )
{
size_type oldLength = this->Length();
cutStart = NS_MIN(cutStart, oldLength);
cutLength = NS_MIN(cutLength, oldLength-cutStart);
index_type cutEnd = cutStart + cutLength;
size_type replacementLength = aReplacement.Length();
index_type replacementEnd = cutStart + replacementLength;
size_type newLength = oldLength - cutLength + replacementLength;
const_iterator fromBegin, fromEnd;
iterator toBegin;
if ( cutLength > replacementLength )
copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd)));
copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart)));
}

View File

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsCommonString.h"
// #include "nsBufferHandleUtils.h"
void
nsCommonString::assign( const string_type& aReadable )
{
const nsSharedBufferHandle<char_type>* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
handle = NS_AllocateContiguousHandleWithData(handle, aReadable, 1);
mBuffer = handle;
}
const nsSharedBufferHandle<PRUnichar>*
nsCommonString::GetSharedBufferHandle() const
{
return mBuffer.get();
}
void
nsCommonCString::assign( const string_type& aReadable )
{
const nsSharedBufferHandle<char_type>* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
handle = NS_AllocateContiguousHandleWithData(handle, aReadable, 1);
mBuffer = handle;
}
const nsSharedBufferHandle<char>*
nsCommonCString::GetSharedBufferHandle() const
{
return mBuffer.get();
}

View File

@ -0,0 +1,197 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsAString.h"
// remember, no one should include "nsPromiseConcatenation.h" themselves
// one always gets it through "nsAString.h"
PRUint32
nsPromiseConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const PRUnichar*
nsPromiseConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}
PRUint32
nsPromiseCConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseCConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseCConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const char*
nsPromiseCConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}

View File

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsLocalString.h"

View File

@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPromiseSubstring.h"
PRUint32
nsPromiseSubstring::Length() const
{
return mLength;
}
const PRUnichar*
nsPromiseSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const PRUnichar* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
PRUint32
nsPromiseCSubstring::Length() const
{
return mLength;
}
const char*
nsPromiseCSubstring::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}

View File

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsLocalString.h"

View File

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPrivateSharableString.h"
//-------1---------2---------3---------4---------5---------6---------7---------8
const nsSharedBufferHandle<PRUnichar>*
nsPrivateSharableString::GetSharedBufferHandle() const
{
return 0;
}
const nsBufferHandle<PRUnichar>*
nsPrivateSharableString::GetFlatBufferHandle() const
{
return GetSharedBufferHandle();
}
const nsBufferHandle<PRUnichar>*
nsPrivateSharableString::GetBufferHandle() const
{
return GetSharedBufferHandle();
}
PRUint32
nsPrivateSharableString::GetImplementationFlags() const
{
PRUint32 flags = 0;
const nsSharedBufferHandle<char_type>* handle = GetSharedBufferHandle();
if ( handle )
flags = handle->GetImplementationFlags();
return flags;
}
const nsSharedBufferHandle<char>*
nsPrivateSharableCString::GetSharedBufferHandle() const
{
return 0;
}
const nsBufferHandle<char>*
nsPrivateSharableCString::GetFlatBufferHandle() const
{
return GetSharedBufferHandle();
}
const nsBufferHandle<char>*
nsPrivateSharableCString::GetBufferHandle() const
{
return GetSharedBufferHandle();
}
PRUint32
nsPrivateSharableCString::GetImplementationFlags() const
{
PRUint32 flags = 0;
const nsSharedBufferHandle<char_type>* handle = GetSharedBufferHandle();
if ( handle )
flags = handle->GetImplementationFlags();
return flags;
}

View File

@ -0,0 +1,197 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsAString.h"
// remember, no one should include "nsPromiseConcatenation.h" themselves
// one always gets it through "nsAString.h"
PRUint32
nsPromiseConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const PRUnichar*
nsPromiseConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}
PRUint32
nsPromiseCConcatenation::Length() const
{
return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length();
}
PRBool
nsPromiseCConcatenation::Promises( const string_type& aString ) const
{
return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString);
}
#if 0
PRBool
nsPromiseCConcatenation::PromisesExactly( const string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString;
}
#endif
const char*
nsPromiseCConcatenation::GetReadableFragment( nsReadableFragment<char_type>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetLeftStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetRightStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kLeftString]->Length();
if ( aPosition < leftLength )
whichString = SetLeftStringInFragment(aFragment);
else
{
whichString = SetRightStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kLeftString )
{
aRequest = kFirstFragment;
whichString = SetRightStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kRightString )
{
aRequest = kLastFragment;
whichString = SetLeftStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}

View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPromiseFlatString.h"
nsPromiseFlatString::nsPromiseFlatString( const nsPromiseFlatString& aOther )
: mFlattenedString(aOther.mFlattenedString)
{
if ( aOther.mPromisedString == &aOther.mFlattenedString )
mPromisedString = &mFlattenedString;
else
mPromisedString = aOther.mPromisedString;
}
nsPromiseFlatString::nsPromiseFlatString( const nsAString& aString )
{
if ( aString.GetFlatBufferHandle() )
mPromisedString = NS_STATIC_CAST(const nsAFlatString*, &aString);
else
{
mFlattenedString = aString; // flatten |aString|
mPromisedString = &mFlattenedString;
}
}
const PRUnichar*
nsPromiseFlatString::get() const
{
return mPromisedString->get();
}
const nsBufferHandle<PRUnichar>*
nsPromiseFlatString::GetFlatBufferHandle() const
{
return mPromisedString->GetFlatBufferHandle();
}
const nsBufferHandle<PRUnichar>*
nsPromiseFlatString::GetBufferHandle() const
{
return mPromisedString->GetBufferHandle();
}
const nsSharedBufferHandle<PRUnichar>*
nsPromiseFlatString::GetSharedBufferHandle() const
{
return mPromisedString->GetSharedBufferHandle();
}
nsPromiseFlatCString::nsPromiseFlatCString( const nsPromiseFlatCString& aOther )
: mFlattenedString(aOther.mFlattenedString)
{
if ( aOther.mPromisedString == &aOther.mFlattenedString )
mPromisedString = &mFlattenedString;
else
mPromisedString = aOther.mPromisedString;
}
nsPromiseFlatCString::nsPromiseFlatCString( const nsACString& aString )
{
if ( aString.GetFlatBufferHandle() )
mPromisedString = NS_STATIC_CAST(const nsAFlatCString*, &aString);
else
{
mFlattenedString = aString; // flatten |aString|
mPromisedString = &mFlattenedString;
}
}
const char*
nsPromiseFlatCString::get() const
{
return mPromisedString->get();
}
const nsBufferHandle<char>*
nsPromiseFlatCString::GetFlatBufferHandle() const
{
return mPromisedString->GetFlatBufferHandle();
}
const nsBufferHandle<char>*
nsPromiseFlatCString::GetBufferHandle() const
{
return mPromisedString->GetBufferHandle();
}
const nsSharedBufferHandle<char>*
nsPromiseFlatCString::GetSharedBufferHandle() const
{
return mPromisedString->GetSharedBufferHandle();
}

View File

@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsPromiseSubstring.h"
PRUint32
nsPromiseSubstring::Length() const
{
return mLength;
}
const PRUnichar*
nsPromiseSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const PRUnichar* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
PRUint32
nsPromiseCSubstring::Length() const
{
return mLength;
}
const char*
nsPromiseCSubstring::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}

View File

@ -26,6 +26,9 @@
#include "nsString.h"
#include "nsCRT.h"
#ifndef nsStringTraits_h___
#include "nsStringTraits.h"
#endif
/**
* this allocator definition, and the global functions to access it need to move
@ -142,7 +145,7 @@ class LossyConvertEncoding
NS_COM
void
CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest )
CopyUCS2toASCII( const nsAString& aSource, nsACString& aDest )
{
// right now, this won't work on multi-fragment destinations
aDest.SetLength(aSource.Length());
@ -157,7 +160,7 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest )
NS_COM
void
CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest )
CopyASCIItoUCS2( const nsACString& aSource, nsAString& aDest )
{
// right now, this won't work on multi-fragment destinations
aDest.SetLength(aSource.Length());
@ -178,10 +181,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest )
* @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|.
*
*/
template <class FromCharT, class ToCharT>
template <class FromStringT, class ToCharT>
inline
ToCharT*
AllocateStringCopy( const basic_nsAReadableString<FromCharT>& aSource, ToCharT* )
AllocateStringCopy( const FromStringT& aSource, ToCharT* )
{
return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT)));
}
@ -189,7 +192,7 @@ AllocateStringCopy( const basic_nsAReadableString<FromCharT>& aSource, ToCharT*
NS_COM
char*
ToNewCString( const nsAReadableString& aSource )
ToNewCString( const nsAString& aSource )
{
char* result = AllocateStringCopy(aSource, (char*)0);
@ -201,7 +204,7 @@ ToNewCString( const nsAReadableString& aSource )
NS_COM
char*
ToNewUTF8String( const nsAReadableString& aSource )
ToNewUTF8String( const nsAString& aSource )
{
NS_ConvertUCS2toUTF8 temp(aSource);
@ -225,7 +228,7 @@ ToNewUTF8String( const nsAReadableString& aSource )
NS_COM
char*
ToNewCString( const nsAReadableCString& aSource )
ToNewCString( const nsACString& aSource )
{
// no conversion needed, just allocate a buffer of the correct length and copy into it
@ -239,7 +242,7 @@ ToNewCString( const nsAReadableCString& aSource )
NS_COM
PRUnichar*
ToNewUnicode( const nsAReadableString& aSource )
ToNewUnicode( const nsAString& aSource )
{
// no conversion needed, just allocate a buffer of the correct length and copy into it
@ -253,7 +256,7 @@ ToNewUnicode( const nsAReadableString& aSource )
NS_COM
PRUnichar*
ToNewUnicode( const nsAReadableCString& aSource )
ToNewUnicode( const nsACString& aSource )
{
PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0);
@ -265,7 +268,7 @@ ToNewUnicode( const nsAReadableCString& aSource )
NS_COM
PRUnichar*
CopyUnicodeTo( const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength )
CopyUnicodeTo( const nsAString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength )
{
nsReadingIterator<PRUnichar> fromBegin, fromEnd;
PRUnichar* toBegin = aDest;
@ -277,7 +280,7 @@ NS_COM
void
CopyUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
const nsReadingIterator<PRUnichar>& aSrcEnd,
nsAWritableString& aDest )
nsAString& aDest )
{
nsWritingIterator<PRUnichar> writer;
aDest.SetLength(Distance(aSrcStart, aSrcEnd));
@ -291,7 +294,7 @@ NS_COM
void
AppendUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
const nsReadingIterator<PRUnichar>& aSrcEnd,
nsAWritableString& aDest )
nsAString& aDest )
{
nsWritingIterator<PRUnichar> writer;
PRUint32 oldLength = aDest.Length();
@ -304,7 +307,7 @@ AppendUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
NS_COM
PRBool
IsASCII( const nsAReadableString& aString )
IsASCII( const nsAString& aString )
{
static const PRUnichar NOT_ASCII = PRUnichar(~0x007F);
@ -354,18 +357,18 @@ class ConvertToUpperCase
NS_COM
void
ToUpperCase( nsAWritableString& aString )
ToUpperCase( nsAString& aString )
{
nsAWritableString::iterator fromBegin, fromEnd;
nsAString::iterator fromBegin, fromEnd;
ConvertToUpperCase<PRUnichar> converter;
copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter);
}
NS_COM
void
ToUpperCase( nsAWritableCString& aCString )
ToUpperCase( nsACString& aCString )
{
nsAWritableCString::iterator fromBegin, fromEnd;
nsACString::iterator fromBegin, fromEnd;
ConvertToUpperCase<char> converter;
copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter);
}
@ -391,18 +394,18 @@ class ConvertToLowerCase
NS_COM
void
ToLowerCase( nsAWritableString& aString )
ToLowerCase( nsAString& aString )
{
nsAWritableString::iterator fromBegin, fromEnd;
nsAString::iterator fromBegin, fromEnd;
ConvertToLowerCase<PRUnichar> converter;
copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter);
}
NS_COM
void
ToLowerCase( nsAWritableCString& aCString )
ToLowerCase( nsACString& aCString )
{
nsAWritableCString::iterator fromBegin, fromEnd;
nsACString::iterator fromBegin, fromEnd;
ConvertToLowerCase<char> converter;
copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter);
}
@ -411,7 +414,7 @@ ToLowerCase( nsAWritableCString& aCString )
template <class CharT>
inline // probably wishful thinking
PRBool
FindInReadable_Impl( const basic_nsAReadableString<CharT>& aPattern,
FindInReadable_Impl( const typename nsStringTraits<CharT>::abstract_string_type& aPattern,
nsReadingIterator<CharT>& aSearchStart,
nsReadingIterator<CharT>& aSearchEnd )
{
@ -479,14 +482,14 @@ FindInReadable_Impl( const basic_nsAReadableString<CharT>& aPattern,
NS_COM
PRBool
FindInReadable( const nsAReadableString& aPattern, nsReadingIterator<PRUnichar>& aSearchStart, nsReadingIterator<PRUnichar>& aSearchEnd )
FindInReadable( const nsAString& aPattern, nsReadingIterator<PRUnichar>& aSearchStart, nsReadingIterator<PRUnichar>& aSearchEnd )
{
return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd);
}
NS_COM
PRBool
FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator<char>& aSearchStart, nsReadingIterator<char>& aSearchEnd )
FindInReadable( const nsACString& aPattern, nsReadingIterator<char>& aSearchStart, nsReadingIterator<char>& aSearchEnd )
{
return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd);
}
@ -499,7 +502,7 @@ FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator<char>& aSe
template <class CharT>
inline // probably wishful thinking
PRBool
RFindInReadable_Impl( const basic_nsAReadableString<CharT>& aPattern,
RFindInReadable_Impl( const typename nsStringTraits<CharT>::abstract_string_type& aPattern,
nsReadingIterator<CharT>& aSearchStart,
nsReadingIterator<CharT>& aSearchEnd )
{
@ -535,14 +538,14 @@ RFindInReadable_Impl( const basic_nsAReadableString<CharT>& aPattern,
NS_COM
PRBool
RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator<PRUnichar>& aSearchStart, nsReadingIterator<PRUnichar>& aSearchEnd )
RFindInReadable( const nsAString& aPattern, nsReadingIterator<PRUnichar>& aSearchStart, nsReadingIterator<PRUnichar>& aSearchEnd )
{
return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd);
}
NS_COM
PRBool
RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator<char>& aSearchStart, nsReadingIterator<char>& aSearchEnd )
RFindInReadable( const nsACString& aPattern, nsReadingIterator<char>& aSearchStart, nsReadingIterator<char>& aSearchEnd )
{
return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd);
}
@ -593,7 +596,7 @@ FindCharInReadable( char aChar, nsReadingIterator<char>& aSearchStart, const nsR
template <class CharT>
PRUint32
CountCharInReadable_Impl( const basic_nsAReadableString<CharT>& aStr,
CountCharInReadable_Impl( const typename nsStringTraits<CharT>::abstract_string_type& aStr,
CharT aChar )
{
PRUint32 count = 0;
@ -614,7 +617,7 @@ CountCharInReadable_Impl( const basic_nsAReadableString<CharT>& aStr,
NS_COM
PRUint32
CountCharInReadable( const nsAReadableString& aStr,
CountCharInReadable( const nsAString& aStr,
PRUnichar aChar )
{
return CountCharInReadable_Impl(aStr, aChar);
@ -622,7 +625,7 @@ CountCharInReadable( const nsAReadableString& aStr,
NS_COM
PRUint32
CountCharInReadable( const nsAReadableCString& aStr,
CountCharInReadable( const nsACString& aStr,
char aChar )
{
return CountCharInReadable_Impl(aStr, aChar);

View File

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsCommonString.h"
// #include "nsBufferHandleUtils.h"
void
nsCommonString::assign( const string_type& aReadable )
{
const nsSharedBufferHandle<char_type>* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
handle = NS_AllocateContiguousHandleWithData(handle, aReadable, 1);
mBuffer = handle;
}
const nsSharedBufferHandle<PRUnichar>*
nsCommonString::GetSharedBufferHandle() const
{
return mBuffer.get();
}
void
nsCommonCString::assign( const string_type& aReadable )
{
const nsSharedBufferHandle<char_type>* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
handle = NS_AllocateContiguousHandleWithData(handle, aReadable, 1);
mBuffer = handle;
}
const nsSharedBufferHandle<char>*
nsCommonCString::GetSharedBufferHandle() const
{
return mBuffer.get();
}

View File

@ -99,7 +99,7 @@ nsSlidingSubstring::nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList )
typedef const nsSharedBufferList::Buffer* Buffer_ptr;
static nsSharedBufferList::Buffer*
AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAReadableString& aDataSource )
AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAString& aDataSource )
{
typedef const PRUnichar* PRUnichar_ptr;
@ -131,7 +131,7 @@ AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAReadableS
return result;
}
nsSlidingSubstring::nsSlidingSubstring( const nsAReadableString& aSourceString )
nsSlidingSubstring::nsSlidingSubstring( const nsAString& aSourceString )
: mBufferList(new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString)))
{
init_range_from_buffer_list();
@ -189,7 +189,7 @@ nsSlidingSubstring::Rebind( const nsSlidingString& aString, const nsReadingItera
}
void
nsSlidingSubstring::Rebind( const nsAReadableString& aSourceString )
nsSlidingSubstring::Rebind( const nsAString& aSourceString )
{
release_ownership_of_buffer_list();
mBufferList = new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString));
@ -291,7 +291,7 @@ nsSlidingString::AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PR
}
void
nsSlidingString::InsertReadable( const nsAReadableString& aReadable, const nsReadingIterator<PRUnichar>& aInsertPoint )
nsSlidingString::InsertReadable( const nsAString& aReadable, const nsReadingIterator<PRUnichar>& aInsertPoint )
/*
* Warning: this routine manipulates the shared buffer list in an unexpected way.
* The original design did not really allow for insertions, but this call promises

View File

@ -364,7 +364,7 @@ nsDataObj :: GetDib ( nsAReadableCString& inFlavor, FORMATETC &, STGMEDIUM & aST
PRUint32 len = 0;
nsCOMPtr<nsISupports> genericDataWrapper;
mTransferable->GetTransferData(nsPromiseFlatCString(inFlavor).get(), getter_AddRefs(genericDataWrapper), &len);
mTransferable->GetTransferData(PromiseFlatCString(inFlavor).get(), getter_AddRefs(genericDataWrapper), &len);
nsCOMPtr<nsIImage> image ( do_QueryInterface(genericDataWrapper) );
if ( image ) {
// use a the helper class to build up a bitmap. We now own the bits,
@ -574,7 +574,7 @@ HRESULT nsDataObj::GetText(nsAReadableCString & aDataFlavor, FORMATETC& aFE, STG
// if someone asks for text/plain, look up text/unicode instead in the transferable.
const char* flavorStr;
nsPromiseFlatCString flat(aDataFlavor);
const nsPromiseFlatCString& flat = PromiseFlatCString(aDataFlavor);
if ( aDataFlavor.Equals("text/plain") )
flavorStr = kUnicodeMime;
else

View File

@ -169,7 +169,7 @@ NS_COM nsIAtom* NS_NewAtom( const nsAReadableString& aString )
(PLHashComparator)CompareKeys,
(PLHashComparator)0, 0, 0);
nsPromiseFlatString flat(aString);
const nsPromiseFlatString& flat = PromiseFlatString(aString);
const PRUnichar *str = flat.get();
PRUint32 hashCode = HashKey(str);

View File

@ -457,7 +457,7 @@ nsCStringKey::Clone() const
////////////////////////////////////////////////////////////////////////////////
nsStringKey::nsStringKey(const nsAReadableString& str)
: mStr(NS_CONST_CAST(PRUnichar*, NS_STATIC_CAST(const PRUnichar *, nsPromiseFlatString(str).get()))), mStrLen(str.Length()), mOwnership(OWN_CLONE)
: mStr(NS_CONST_CAST(PRUnichar*, NS_STATIC_CAST(const PRUnichar *, PromiseFlatString(str).get()))), mStrLen(str.Length()), mOwnership(OWN_CLONE)
{
NS_ASSERTION(mStr, "null string key");
#ifdef DEBUG

View File

@ -21,11 +21,9 @@
- Scott Collins <scc@mozilla.org> (original author)
-->
<body>
<h1><span class="LXRSHORTDESC">string code will be moving here soon</span></h1>
<h1><span class="LXRSHORTDESC">managing sequences of characters</span></h1>
<p>
<span class="LXRLONGDESC">The string code will be moving here soon;
in the meantime, you can find the bulk of it in
<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/">mozilla/xpcom/ds</a>.</span>
<span class="LXRLONGDESC"></span>
</p>
</body>
</html>

View File

@ -21,7 +21,7 @@
- Scott Collins <scc@mozilla.org> (original author)
-->
<body>
<h1><span class="LXRSHORTDESC">string doc will be moving here soon</span></h1>
<h1><span class="LXRSHORTDESC">documentation aimed at programmers who are clients of the string library</span></h1>
<p>
<span class="LXRLONGDESC"></span>
</p>

Binary file not shown.

View File

@ -17,10 +17,8 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Rick Gessner <rickg@netscape.com>
*
* Contributor(s):
* Rick Gessner <rickg@netscape.com> (original author)
* Scott Collins <scc@mozilla.org>
*/

View File

@ -42,6 +42,11 @@ static const char* kPossibleNull = "Error: possible unintended null in string";
static const char* kNullPointerError = "Error: unexpected null ptr";
static const char* kWhitespace="\b\t\r\n ";
const nsBufferHandle<char>*
nsCString::GetFlatBufferHandle() const
{
return NS_REINTERPRET_CAST(const nsBufferHandle<char>*, 1);
}
static void CSubsume(nsStr& aDest,nsStr& aSource){
if(aSource.mStr && aSource.mLength) {
@ -165,7 +170,7 @@ char* nsCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFra
}
}
nsCString::nsCString( const nsAReadableCString& aReadable ) {
nsCString::nsCString( const nsACString& aReadable ) {
Initialize(*this,eOneByte);
Assign(aReadable);
}
@ -774,7 +779,7 @@ void nsCString::AssignWithConversion( const nsString& aString ) {
AssignWithConversion(aString.GetUnicode(), aString.Length());
}
void nsCString::AssignWithConversion( const nsAReadableString& aString ) {
void nsCString::AssignWithConversion( const nsAString& aString ) {
nsStr::StrTruncate(*this,0);
PRInt32 count = aString.Length();
@ -792,13 +797,13 @@ void nsCString::AssignWithConversion( const nsAReadableString& aString ) {
temp.mLength=fraglen;
StrAppend(*this,temp,0,fraglen);
start += fraglen;
start.advance(fraglen);
}
}
}
void nsCString::AppendWithConversion( const nsAReadableString& aString ) {
void nsCString::AppendWithConversion( const nsAString& aString ) {
PRInt32 count = aString.Length();
if(count){
@ -816,7 +821,7 @@ void nsCString::AppendWithConversion( const nsAReadableString& aString ) {
StrAppend(*this,temp,0,fraglen);
start += fraglen;
start.advance(fraglen);
}
}
}
@ -832,14 +837,6 @@ void nsCString::AssignWithConversion(PRUnichar aChar) {
AppendWithConversion(aChar);
}
void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable )
{
if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) )
StrAppend(*this, NS_STATIC_CAST(const nsCString&, aReadable), 0, aReadable.Length());
else
nsAWritableCString::do_AppendFromReadable(aReadable);
}
/**
* append given char to this string
@ -962,14 +959,6 @@ void nsCString::InsertWithConversion(PRUnichar aChar,PRUint32 anOffset){
StrInsert(*this,anOffset,temp,0,1);
}
void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUint32 atPosition )
{
if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) )
StrInsert(*this, atPosition, NS_STATIC_CAST(const nsCString&, aReadable), 0, aReadable.Length());
else
nsAWritableCString::do_InsertFromReadable(aReadable, atPosition);
}
@ -1382,7 +1371,7 @@ void nsCString::DebugDump(void) const {
//----------------------------------------------------------------------
NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAReadableString& aString )
NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAString& aString )
{
nsReadingIterator<PRUnichar> start; aString.BeginReading(start);
nsReadingIterator<PRUnichar> end; aString.EndReading(end);
@ -1390,7 +1379,7 @@ NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAReadableString& aString )
while (start != end) {
nsReadableFragment<PRUnichar> frag(start.fragment());
Append(frag.mStart, frag.mEnd - frag.mStart);
start += start.size_forward();
start.advance(start.size_forward());
}
}
@ -1511,7 +1500,7 @@ nsCAutoString::nsCAutoString( const nsCString& aString ) : nsCString(){
Append(aString);
}
nsCAutoString::nsCAutoString( const nsAReadableCString& aString ) : nsCString(){
nsCAutoString::nsCAutoString( const nsACString& aString ) : nsCString(){
Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE);
AddNullTerminator(*this);
Append(aString);

View File

@ -50,17 +50,27 @@
#include "nsStr.h"
#include "nsIAtom.h"
#include "nsAString.h"
/* this file will one day be _only_ a compatibility header for clients using the names
|ns[C]String| et al ... which we probably want to support forever.
In the mean time, people are used to getting the names |nsAReadable[C]String| and friends
from here as well; so we must continue to include the other compatibility headers
even though we don't use them ourself.
*/
#include "nsAWritableString.h"
// for compatibility
class NS_COM nsSubsumeCStr;
class NS_COM nsCString :
public nsAWritableCString,
public nsAFlatCString,
public nsStr {
protected:
virtual const void* Implementation() const { return "nsCString"; }
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const;
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
@ -79,7 +89,7 @@ public:
*/
nsCString(const nsCString& aString);
explicit nsCString( const nsAReadableCString& );
explicit nsCString( const nsACString& );
explicit nsCString(const char*);
nsCString(const char*, PRInt32);
@ -298,14 +308,14 @@ public:
*/
nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; }
nsCString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
//nsCString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCString& operator=( char aChar ) { Assign(aChar); return *this; }
void AssignWithConversion(const PRUnichar*,PRInt32=-1);
void AssignWithConversion( const nsString& aString );
void AssignWithConversion( const nsAReadableString& aString );
void AssignWithConversion( const nsAString& aString );
void AssignWithConversion(PRUnichar);
/*
@ -320,18 +330,20 @@ public:
void AppendWithConversion(const nsString&, PRInt32=-1);
void AppendWithConversion(PRUnichar aChar);
void AppendWithConversion( const nsAReadableString& aString );
void AppendWithConversion( const nsAString& aString );
void AppendWithConversion(const PRUnichar*, PRInt32=-1);
// Why no |AppendWithConversion(const PRUnichar*, PRInt32)|? --- now I know, because implicit construction hid the need for this routine
void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
void AppendFloat( double aFloat );
virtual void do_AppendFromReadable( const nsAReadableCString& );
void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset);
// Why no |InsertWithConversion(PRUnichar*)|?
virtual void do_InsertFromReadable( const nsAReadableCString&, PRUint32 );
#if 0
virtual void do_AppendFromReadable( const nsACString& );
virtual void do_InsertFromReadable( const nsACString&, PRUint32 );
#endif
/**********************************************************************
@ -446,7 +458,7 @@ private:
};
// NS_DEF_STRING_COMPARISON_OPERATORS(nsCString, char)
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char)
extern NS_COM int fputs(const nsCString& aString, FILE* out);
//ostream& operator<<(ostream& aStream,const nsCString& aString);
@ -466,7 +478,7 @@ public:
nsCAutoString();
explicit nsCAutoString(const nsCString& );
explicit nsCAutoString(const nsAReadableCString& aString);
explicit nsCAutoString(const nsACString& aString);
explicit nsCAutoString(const char* aString);
nsCAutoString(const char* aString,PRInt32 aLength);
explicit nsCAutoString(const CBufDescriptor& aBuffer);
@ -482,8 +494,8 @@ public:
private:
void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED
public:
nsCAutoString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
// nsCAutoString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; }
@ -496,7 +508,7 @@ public:
char mBuffer[kDefaultStringSize];
};
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
/**
* A helper class that converts a UCS2 string to UTF8
@ -525,7 +537,7 @@ class NS_COM NS_ConvertUCS2toUTF8
Append( &aChar, 1 );
}
explicit NS_ConvertUCS2toUTF8( const nsAReadableString& aString );
explicit NS_ConvertUCS2toUTF8( const nsAString& aString );
protected:
void Append( const PRUnichar* aString, PRUint32 aLength );
@ -533,7 +545,7 @@ class NS_COM NS_ConvertUCS2toUTF8
private:
// NOT TO BE IMPLEMENTED
NS_ConvertUCS2toUTF8( char );
operator const char*() const; // use |get()|
operator const char*() const; // use |get()|
};
@ -557,8 +569,8 @@ public:
nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); return *this; }
nsSubsumeCStr& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
//nsSubsumeCStr& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeCStr& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsSubsumeCStr& operator=( char aChar ) { Assign(aChar); return *this; }
private:

View File

@ -39,6 +39,13 @@ static const char* kPossibleNull = "Error: possible unintended null in string";
static const char* kNullPointerError = "Error: unexpected null ptr";
static const char* kWhitespace="\b\t\r\n ";
const nsBufferHandle<PRUnichar>*
nsString::GetFlatBufferHandle() const
{
return NS_REINTERPRET_CAST(const nsBufferHandle<PRUnichar>*, 1);
}
static void Subsume(nsStr& aDest,nsStr& aSource){
if(aSource.mStr && aSource.mLength) {
@ -165,7 +172,7 @@ nsString::do_AppendFromElement( PRUnichar inChar )
}
nsString::nsString( const nsAReadableString& aReadable ) {
nsString::nsString( const nsAString& aReadable ) {
Initialize(*this,eTwoByte);
Assign(aReadable);
}
@ -1647,7 +1654,7 @@ nsAutoString::nsAutoString( const nsString& aString )
Append(aString);
}
nsAutoString::nsAutoString( const nsAReadableString& aString )
nsAutoString::nsAutoString( const nsAString& aString )
: nsString()
{
Initialize(*this, mBuffer, (sizeof(mBuffer)>>eTwoByte)-1, 0, eTwoByte, PR_FALSE);

View File

@ -52,11 +52,12 @@
#include "nsStr.h"
#include "nsCRT.h"
#include "nsAWritableString.h"
#ifndef nsAFlatString_h___
#include "nsAFlatString.h"
#endif
#ifdef STANDALONE_MI_STRING_TESTS
class nsAReadableString { public: virtual ~nsAReadableString() { } };
class nsAWritableString : public nsAReadableString { public: virtual ~nsAWritableString() { } };
class nsAFlatString { public: virtual ~nsAString() { } };
#endif
class nsISizeOfHandler;
@ -68,11 +69,11 @@ class nsISizeOfHandler;
class NS_COM nsSubsumeStr;
class NS_COM nsString :
public nsAWritableString,
public nsAFlatString,
public nsStr {
protected:
virtual const void* Implementation() const { return "nsString"; }
virtual const nsBufferHandle<PRUnichar>* GetFlatBufferHandle() const;
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
@ -91,7 +92,7 @@ public:
*/
nsString(const nsString& aString);
explicit nsString(const nsAReadableString&);
explicit nsString(const nsAString&);
explicit nsString(const PRUnichar*);
nsString(const PRUnichar*, PRInt32);
@ -342,8 +343,8 @@ public:
*/
nsString& operator=( const nsString& aString ) { Assign(aString); return *this; }
nsString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
//nsString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
@ -526,7 +527,7 @@ private:
};
// NS_DEF_STRING_COMPARISON_OPERATORS(nsString, PRUnichar)
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsString, PRUnichar)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsString, PRUnichar)
extern NS_COM int fputs(const nsString& aString, FILE* out);
//ostream& operator<<(ostream& aStream,const nsString& aString);
@ -544,7 +545,7 @@ public:
virtual ~nsAutoString();
nsAutoString();
nsAutoString(const nsAutoString& aString);
explicit nsAutoString(const nsAReadableString& aString);
explicit nsAutoString(const nsAString& aString);
explicit nsAutoString(const nsString& aString);
explicit nsAutoString(const PRUnichar* aString);
nsAutoString(const PRUnichar* aString,PRInt32 aLength);
@ -562,8 +563,8 @@ public:
private:
void operator=( char ); // NOT TO BE IMPLEMENTED
public:
nsAutoString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
// nsAutoString& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsAutoString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsAutoString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
@ -576,7 +577,7 @@ public:
char mBuffer[kDefaultStringSize<<eTwoByte];
};
NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsAutoString, PRUnichar)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsAutoString, PRUnichar)
class NS_COM NS_ConvertASCIItoUCS2
: public nsAutoString
@ -589,10 +590,12 @@ class NS_COM NS_ConvertASCIItoUCS2
NS_ConvertASCIItoUCS2( const char*, PRUint32 );
explicit NS_ConvertASCIItoUCS2( char );
operator const nsLiteralString() const
#if 0
operator const nsLocalString() const
{
return nsLiteralString(mUStr, mLength);
return nsLocalString(mUStr, mLength);
}
#endif
private:
// NOT TO BE IMPLEMENTED
@ -649,8 +652,8 @@ public:
int Subsume(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
nsSubsumeStr& operator=( const nsSubsumeStr& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const nsAString& aReadable ) { Assign(aReadable); return *this; }
//nsSubsumeStr& operator=( const nsPromiseReadable<PRUnichar>& aReadable ) { Assign(aReadable); return *this; }
nsSubsumeStr& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; }
nsSubsumeStr& operator=( PRUnichar aChar ) { Assign(aChar); return *this; }
private:

View File

@ -21,15 +21,29 @@
#
nsAFlatString.h
nsAlgorithm.h
nsAPromiseString.h
nsAReadableString.h
nsAString.h
nsAWritableString.h
nsBufferHandle.h
nsBufferHandleUtils.h
nsCharTraits.h
nsCommonString.h
nsFragmentedString.h
nsLiteralString.h
nsLocalString.h
nsPrintfCString.h
nsPrivateSharableString.h
nsPromiseConcatenation.h
nsPromiseFlatString.h
nsPromiseSubstring.h
nsReadableUtils.h
nsSharedBufferList.h
nsSlidingString.h
nsStringFragment.h
nsStringFwd.h
nsStringIterator.h
nsStringIteratorUtils.h
nsStringTraits.h

View File

@ -18,6 +18,7 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH = ../..
@ -30,18 +31,32 @@ include $(DEPTH)/config/autoconf.mk
MODULE = string
EXPORTS = \
nsAFlatString.h \
nsAlgorithm.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsPrivateSharableString.h \
nsAPromiseString.h \
nsAReadableString.h \
nsAString.h \
nsAWritableString.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsCharTraits.h \
nsAReadableString.h \
nsAWritableString.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsFragmentedString.h \
nsPrintfCString.h \
nsCommonString.h \
nsFragmentedString.h \
nsLiteralString.h \
nsLocalString.h \
nsPrintfCString.h \
nsPrivateSharableString.h \
nsPromiseConcatenation.h \
nsPromiseFlatString.h \
nsPromiseSubstring.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsStringFragment.h \
nsStringFwd.h \
nsStringIterator.h \
nsStringIteratorUtils.h \
nsStringTraits.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -19,23 +19,38 @@
#
# Contributor(s):
# Johnny Stenback <jst@netscape.com> (original author)
# Scott Collins <scc@mozilla.org>
#
DEPTH=..\..
EXPORTS = \
nsAFlatString.h \
nsAlgorithm.h \
nsAPromiseString.h \
nsAReadableString.h \
nsAString.h \
nsAWritableString.h \
nsBufferHandle.h \
nsBufferHandleUtils.h \
nsCharTraits.h \
nsCommonString.h \
nsFragmentedString.h \
nsLiteralString.h \
nsLocalString.h \
nsPrintfCString.h \
nsPrivateSharableString.h \
nsPromiseConcatenation.h \
nsPromiseFlatString.h \
nsPromiseSubstring.h \
nsReadableUtils.h \
nsSharedBufferList.h \
nsSlidingString.h \
nsStringFragment.h \
nsStringFwd.h \
nsStringIterator.h \
nsStringIteratorUtils.h \
nsStringTraits.h \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsAFlatString.h --- */
#ifndef nsAFlatString_h___
#define nsAFlatString_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
class NS_COM nsAFlatString
: public nsAString
{
public:
// don't really want this to be virtual, and won't after |obsolete_nsString| is really dead
virtual const PRUnichar* get() const { return GetBufferHandle()->DataStart(); }
PRUnichar operator[]( PRUint32 i ) const { return get()[ i ]; }
PRUnichar CharAt( PRUint32 ) const;
virtual PRUint32 Length() const { return PRUint32(GetBufferHandle()->DataLength()); }
protected:
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
};
class NS_COM nsAFlatCString
: public nsACString
{
public:
// don't really want this to be virtual, and won't after |obsolete_nsCString| is really dead
virtual const char* get() const { return GetBufferHandle()->DataStart(); }
char operator[]( PRUint32 i ) const { return get()[ i ]; }
char CharAt( PRUint32 ) const;
virtual PRUint32 Length() const { return PRUint32(GetBufferHandle()->DataLength()); }
protected:
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
};
inline
PRUnichar
nsAFlatString::CharAt( PRUint32 i ) const
{
NS_ASSERTION(i<Length(), "|CharAt| out-of-range");
return operator[](i);
}
inline
char
nsAFlatCString::CharAt( PRUint32 i ) const
{
NS_ASSERTION(i<Length(), "|CharAt| out-of-range");
return operator[](i);
}
#endif /* !defined(nsAFlatString_h___) */

View File

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
/* nsAPromiseString.h --- abstract base class for strings don't actually own their own characters, but proxy data from other strings */
#ifndef nsAPromiseString_h___
#define nsAPromiseString_h___
/**
* Don't |#include| this file yourself. You will get it automatically if you need it.
*
* Why is it a separate file? To make it easier to find the classes in your local tree.
*/
class NS_COM nsAPromiseString : public nsAString { };
class NS_COM nsAPromiseCString : public nsACString { };
#endif /* !defined(nsAPromiseString_h___) */

Some files were not shown because too many files have changed in this diff Show More