Compare commits
40 Commits
Bugzilla_P
...
STRING_081
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e1777f9b5 | ||
|
|
99efac3124 | ||
|
|
57ed42992f | ||
|
|
6f32510025 | ||
|
|
078567ca71 | ||
|
|
7791c7b9e8 | ||
|
|
b146859b40 | ||
|
|
a8da425a6f | ||
|
|
57e25da11d | ||
|
|
5200a8a8b9 | ||
|
|
9a0cd79226 | ||
|
|
73e8d36238 | ||
|
|
108dd9fe2a | ||
|
|
8c67e6b4b2 | ||
|
|
b8d0928720 | ||
|
|
7f66a9d19f | ||
|
|
9e0dc2526a | ||
|
|
ae85ae37da | ||
|
|
8b103cd7ba | ||
|
|
9ef69db463 | ||
|
|
aadc6198b4 | ||
|
|
011984fc48 | ||
|
|
051d24e674 | ||
|
|
a8a0fd0815 | ||
|
|
23166d3117 | ||
|
|
16352119a4 | ||
|
|
6433e6c15a | ||
|
|
2e8da224d5 | ||
|
|
ad33c0e9e3 | ||
|
|
413c10a73e | ||
|
|
b50526e4f9 | ||
|
|
ddcfe0fade | ||
|
|
d3f529a51a | ||
|
|
3088f582fe | ||
|
|
85cba8b3fa | ||
|
|
d9e607a0ab | ||
|
|
3ea67f16a2 | ||
|
|
c07e9e4c4d | ||
|
|
f4db0afc09 | ||
|
|
602920c9a5 |
15
mozilla/build/mac/build_scripts/MozillaCheckoutList.txt
Normal file
15
mozilla/build/mac/build_scripts/MozillaCheckoutList.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# List of modules to check out. Format is
|
||||
# module, (tag), (date)
|
||||
# where tag and date are optional (non-trailing commas are required)
|
||||
#
|
||||
# Examples:
|
||||
# mozilla/nsprpub, NSPRPUB_CLIENT_BRANCH
|
||||
# mozilla/gc, , 10/25/2000 12:00:00
|
||||
#
|
||||
|
||||
mozilla/nsprpub, NSPRPUB_CLIENT_BRANCH
|
||||
mozilla/security/nss, NSS_CLIENT_TAG
|
||||
mozilla/security/psm,
|
||||
DirectorySDKSourceC, LDAPCSDK_40_BRANCH
|
||||
mozilla/lib/mac/Instrumentation
|
||||
SeaMonkeyAll STRING_081_BRANCH
|
||||
1673
mozilla/content/base/src/nsDocumentEncoder.cpp
Normal file
1673
mozilla/content/base/src/nsDocumentEncoder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
792
mozilla/content/base/src/nsHTMLContentSerializer.cpp
Normal file
792
mozilla/content/base/src/nsHTMLContentSerializer.cpp
Normal file
@@ -0,0 +1,792 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsHTMLContentSerializer.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
|
||||
#define kIndentStr NS_LITERAL_STRING(" ")
|
||||
#define kMozStr "_moz"
|
||||
#define kLessThan NS_LITERAL_STRING("<")
|
||||
#define kGreaterThan NS_LITERAL_STRING(">")
|
||||
#define kEndTag NS_LITERAL_STRING("</")
|
||||
|
||||
static const PRInt32 kLongLineLen = 128;
|
||||
|
||||
nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
|
||||
{
|
||||
nsHTMLContentSerializer* it = new nsHTMLContentSerializer();
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(NS_GET_IID(nsIContentSerializer), (void**)aSerializer);
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::nsHTMLContentSerializer()
|
||||
{
|
||||
mColPos = 0;
|
||||
mIndent = 0;
|
||||
mInBody = PR_FALSE;
|
||||
mInCDATA = PR_FALSE;
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::~nsHTMLContentSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLContentSerializer::GetParserService(nsIParserService** aParserService)
|
||||
{
|
||||
if (!mParserService) {
|
||||
nsresult rv;
|
||||
mParserService = do_GetService(kParserServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CallQueryInterface(mParserService.get(), aParserService);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
|
||||
nsIAtom* aCharSet)
|
||||
{
|
||||
mFlags = aFlags;
|
||||
if (!aWrapColumn) {
|
||||
mMaxColumn = 72;
|
||||
}
|
||||
else {
|
||||
mMaxColumn = aWrapColumn;
|
||||
}
|
||||
|
||||
mDoFormat = (mFlags & nsIDocumentEncoder::OutputFormatted) ? PR_TRUE
|
||||
: PR_FALSE;
|
||||
mBodyOnly = (mFlags & nsIDocumentEncoder::OutputBodyOnly) ? PR_TRUE
|
||||
: PR_FALSE;
|
||||
// Set the line break character:
|
||||
if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak)
|
||||
&& (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows/mail
|
||||
mLineBreak.AssignWithConversion("\r\n");
|
||||
}
|
||||
else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) { // Mac
|
||||
mLineBreak.AssignWithConversion("\r");
|
||||
}
|
||||
else if (mFlags & nsIDocumentEncoder::OutputLFLineBreak) { // Unix/DOM
|
||||
mLineBreak.AssignWithConversion("\n");
|
||||
}
|
||||
else {
|
||||
mLineBreak.AssignWithConversion(NS_LINEBREAK); // Platform/default
|
||||
}
|
||||
|
||||
mPreLevel = 0;
|
||||
|
||||
mIsLatin1 = PR_FALSE;
|
||||
if (aCharSet) {
|
||||
const PRUnichar *charset;
|
||||
aCharSet->GetUnicode(&charset);
|
||||
|
||||
if (NS_LITERAL_STRING("ISO-8859-1").Equals(charset)) {
|
||||
mIsLatin1 = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLContentSerializer::AppendText(nsIDOMText* aText,
|
||||
PRInt32 aStartOffset,
|
||||
PRInt32 aEndOffset,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
NS_ENSURE_ARG(aText);
|
||||
|
||||
nsAutoString data;
|
||||
|
||||
nsresult rv;
|
||||
rv = AppendTextData((nsIDOMNode*)aText, aStartOffset,
|
||||
aEndOffset, data, PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 lastNewlineOffset = kNotFound;
|
||||
PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
|
||||
|
||||
if (mPreLevel || (!mDoFormat && !hasLongLines) ||
|
||||
(mFlags & nsIDocumentEncoder::OutputRaw)) {
|
||||
AppendToString(data, aStr);
|
||||
|
||||
if (lastNewlineOffset != kNotFound) {
|
||||
mColPos = data.Length() - lastNewlineOffset;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AppendToStringWrapped(data, aStr, PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
|
||||
nsIAtom* aTagName,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
nsresult rv;
|
||||
PRInt32 index, count;
|
||||
nsAutoString nameStr, valueStr;
|
||||
PRInt32 namespaceID;
|
||||
nsCOMPtr<nsIAtom> attrName, attrPrefix;
|
||||
|
||||
aContent->GetAttributeCount(count);
|
||||
|
||||
for (index = 0; index < count; index++) {
|
||||
aContent->GetAttributeNameAt(index,
|
||||
namespaceID,
|
||||
*getter_AddRefs(attrName),
|
||||
*getter_AddRefs(attrPrefix));
|
||||
|
||||
// Filter out any attribute starting with _moz
|
||||
nsXPIDLString sharedName;
|
||||
attrName->GetUnicode(getter_Shares(sharedName));
|
||||
if (nsCRT::strncmp(sharedName,
|
||||
NS_ConvertASCIItoUCS2(kMozStr),
|
||||
sizeof(kMozStr)-1) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aContent->GetAttribute(namespaceID, attrName, valueStr);
|
||||
|
||||
//
|
||||
// Filter out special case of <br type="_moz"> or <br _moz*>,
|
||||
// used by the editor. Bug 16988. Yuck.
|
||||
//
|
||||
if ((aTagName == nsHTMLAtoms::br) &&
|
||||
(attrName.get() == nsHTMLAtoms::type) &&
|
||||
(valueStr.EqualsWithConversion(kMozStr, PR_FALSE, sizeof(kMozStr)-1))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make all links absolute when converting only the selection:
|
||||
if ((mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) &&
|
||||
((attrName.get() == nsHTMLAtoms::href) ||
|
||||
(attrName.get() == nsHTMLAtoms::src))) {
|
||||
// Would be nice to handle OBJECT and APPLET tags,
|
||||
// but that gets more complicated since we have to
|
||||
// search the tag list for CODEBASE as well.
|
||||
// For now, just leave them relative.
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
aContent->GetDocument(*getter_AddRefs(document));
|
||||
if (document) {
|
||||
nsCOMPtr<nsIURI> uri = dont_AddRef(document->GetDocumentURL());
|
||||
if (uri) {
|
||||
nsAutoString absURI;
|
||||
rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
valueStr = absURI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attrName->ToString(nameStr);
|
||||
|
||||
SerializeAttr(nsAutoString(), nameStr, valueStr, aStr);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
NS_ENSURE_ARG(aElement);
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (!content) return NS_ERROR_FAILURE;
|
||||
|
||||
// The _moz_dirty attribute is emitted by the editor to
|
||||
// indicate that this element should be pretty printed
|
||||
// even if we're not in pretty printing mode
|
||||
PRBool hasDirtyAttr = HasDirtyAttr(content);
|
||||
|
||||
nsCOMPtr<nsIAtom> name;
|
||||
content->GetTag(*getter_AddRefs(name));
|
||||
|
||||
if (name.get() == nsHTMLAtoms::body) {
|
||||
mInBody = PR_TRUE;
|
||||
}
|
||||
|
||||
if (LineBreakBeforeOpen(name, hasDirtyAttr)) {
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
StartIndentation(name, hasDirtyAttr, aStr);
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::pre) ||
|
||||
(name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mPreLevel++;
|
||||
}
|
||||
|
||||
AppendToString(kLessThan, aStr);
|
||||
|
||||
nsXPIDLString sharedName;
|
||||
name->GetUnicode(getter_Shares(sharedName));
|
||||
AppendToString(sharedName, -1, aStr);
|
||||
|
||||
SerializeAttributes(content, name, aStr);
|
||||
|
||||
AppendToString(kGreaterThan, aStr);
|
||||
|
||||
if (LineBreakAfterOpen(name, hasDirtyAttr)) {
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style) ||
|
||||
(name.get() == nsHTMLAtoms::noscript)) {
|
||||
mInCDATA = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
NS_ENSURE_ARG(aElement);
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (!content) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool hasDirtyAttr = HasDirtyAttr(content);
|
||||
|
||||
nsCOMPtr<nsIAtom> name;
|
||||
content->GetTag(*getter_AddRefs(name));
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::pre) ||
|
||||
(name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mPreLevel--;
|
||||
}
|
||||
|
||||
nsXPIDLString sharedName;
|
||||
name->GetUnicode(getter_Shares(sharedName));
|
||||
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (parserService && (name.get() != nsHTMLAtoms::style)) {
|
||||
nsAutoString nameStr(sharedName);
|
||||
PRBool isContainer;
|
||||
PRInt32 id;
|
||||
|
||||
parserService->HTMLStringTagToId(nameStr, &id);
|
||||
parserService->IsContainer(id, isContainer);
|
||||
if (!isContainer) return NS_OK;
|
||||
}
|
||||
|
||||
if (LineBreakBeforeClose(name, hasDirtyAttr)) {
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
EndIndentation(name, hasDirtyAttr, aStr);
|
||||
|
||||
AppendToString(kEndTag, aStr);
|
||||
AppendToString(sharedName, -1, aStr);
|
||||
AppendToString(kGreaterThan, aStr);
|
||||
|
||||
if (LineBreakAfterClose(name, hasDirtyAttr)) {
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
mInCDATA = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToString(const PRUnichar* aStr,
|
||||
PRInt32 aLength,
|
||||
nsAWritableString& aOutputStr)
|
||||
{
|
||||
if (mBodyOnly && !mInBody) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 length = (aLength == -1) ? nsCRT::strlen(aStr) : aLength;
|
||||
|
||||
mColPos += length;
|
||||
|
||||
aOutputStr.Append(aStr, length);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToString(const PRUnichar aChar,
|
||||
nsAWritableString& aOutputStr)
|
||||
{
|
||||
if (mBodyOnly && !mInBody) {
|
||||
return;
|
||||
}
|
||||
|
||||
mColPos += 1;
|
||||
|
||||
aOutputStr.Append(aChar);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr,
|
||||
nsAWritableString& aOutputStr,
|
||||
PRBool aTranslateEntities)
|
||||
{
|
||||
PRInt32 length = aStr.Length();
|
||||
|
||||
nsAutoString line;
|
||||
PRBool done = PR_FALSE;
|
||||
PRInt32 indx = 0;
|
||||
PRInt32 strOffset = 0;
|
||||
PRInt32 lineLength, oldLineEnd;
|
||||
|
||||
// Make sure we haven't gone too far already
|
||||
if (mColPos > mMaxColumn) {
|
||||
AppendToString(mLineBreak, aOutputStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
// Find the end of the first old line
|
||||
oldLineEnd = aStr.FindChar(PRUnichar('\n'), 0);
|
||||
|
||||
while ((!done) && (strOffset < length)) {
|
||||
// This is how much is needed to fill up the new line
|
||||
PRInt32 leftInLine = mMaxColumn - mColPos;
|
||||
|
||||
// This is the last position in the current old line
|
||||
PRInt32 oldLineLimit;
|
||||
if (oldLineEnd == kNotFound) {
|
||||
oldLineLimit = length;
|
||||
}
|
||||
else {
|
||||
oldLineLimit = oldLineEnd;
|
||||
}
|
||||
|
||||
PRBool addLineBreak = PR_FALSE;
|
||||
|
||||
// if we can fill up the new line with less than what's
|
||||
// in the current old line...
|
||||
if ((strOffset + leftInLine) < oldLineLimit) {
|
||||
addLineBreak = PR_TRUE;
|
||||
|
||||
// Look for the next word end to break
|
||||
indx = aStr.FindChar(PRUnichar(' '), strOffset + leftInLine);
|
||||
|
||||
// If it's after the end of the current line, then break at
|
||||
// the current line
|
||||
if ((indx == kNotFound) ||
|
||||
((oldLineEnd != kNotFound) && (oldLineEnd < indx))) {
|
||||
indx = oldLineEnd;
|
||||
}
|
||||
}
|
||||
else {
|
||||
indx = oldLineEnd;
|
||||
}
|
||||
|
||||
// if there was no place to break, then just add the entire string
|
||||
if (indx == kNotFound) {
|
||||
if (strOffset == 0) {
|
||||
AppendToString(aStr, aOutputStr, aTranslateEntities);
|
||||
}
|
||||
else {
|
||||
lineLength = length - strOffset;
|
||||
aStr.Right(line, lineLength);
|
||||
AppendToString(line, aOutputStr, aTranslateEntities);
|
||||
}
|
||||
done = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
// Add the part of the current old line that's part of the
|
||||
// new line
|
||||
lineLength = indx - strOffset;
|
||||
aStr.Mid(line, strOffset, lineLength);
|
||||
AppendToString(line, aOutputStr, aTranslateEntities);
|
||||
|
||||
// if we've reached the end of an old line, don't add the
|
||||
// old line break and find the end of the next old line.
|
||||
if (indx == oldLineEnd) {
|
||||
oldLineEnd = aStr.FindChar(PRUnichar('\n'), indx+1);
|
||||
AppendToString(NS_LITERAL_STRING(" "), aOutputStr);
|
||||
}
|
||||
|
||||
if (addLineBreak) {
|
||||
AppendToString(mLineBreak, aOutputStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
strOffset = indx+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PRUint16 kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "amp", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "quot", "", "", "", "amp", "apos",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
nsAWritableString& aOutputStr,
|
||||
PRBool aTranslateEntities,
|
||||
PRBool aIncrColumn)
|
||||
{
|
||||
if (mBodyOnly && !mInBody) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aIncrColumn) {
|
||||
mColPos += aStr.Length();
|
||||
}
|
||||
|
||||
if (aTranslateEntities && !mInCDATA) {
|
||||
if (mFlags & nsIDocumentEncoder::OutputEncodeEntities) {
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (!parserService) {
|
||||
NS_ERROR("Can't get parser service");
|
||||
return;
|
||||
}
|
||||
|
||||
nsReadingIterator<PRUnichar> done_reading;
|
||||
aStr.EndReading(done_reading);
|
||||
|
||||
// for each chunk of |aString|...
|
||||
PRUint32 advanceLength = 0;
|
||||
nsReadingIterator<PRUnichar> iter;
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
iter.advance(PRInt32(advanceLength))) {
|
||||
PRUint32 fragmentLength = iter.size_forward();
|
||||
const PRUnichar* c = iter.get();
|
||||
const PRUnichar* fragmentStart = c;
|
||||
const PRUnichar* fragmentEnd = c + fragmentLength;
|
||||
const char* entityText = nsnull;
|
||||
nsCAutoString entityReplacement;
|
||||
|
||||
advanceLength = 0;
|
||||
// for each character in this chunk, check if it
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
PRUnichar val = *c;
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
break;
|
||||
} else if (mIsLatin1 && val > 127 && val < 256) {
|
||||
parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);
|
||||
|
||||
if (entityReplacement.Length() > 0) {
|
||||
entityText = entityReplacement.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aOutputStr.Append(fragmentStart, advanceLength);
|
||||
if (entityText) {
|
||||
aOutputStr.Append(PRUnichar('&'));
|
||||
aOutputStr.Append(NS_ConvertASCIItoUCS2(entityText));
|
||||
aOutputStr.Append(PRUnichar(';'));
|
||||
advanceLength++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsXMLContentSerializer::AppendToString(aStr, aOutputStr, aTranslateEntities, aIncrColumn);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
aOutputStr.Append(aStr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLContentSerializer::HasDirtyAttr(nsIContent* aContent)
|
||||
{
|
||||
nsAutoString val;
|
||||
|
||||
if (NS_CONTENT_ATTR_NOT_THERE != aContent->GetAttribute(kNameSpaceID_None,
|
||||
nsLayoutAtoms::mozdirty,
|
||||
val)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLContentSerializer::LineBreakBeforeOpen(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr)
|
||||
{
|
||||
if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
|
||||
(mFlags & nsIDocumentEncoder::OutputRaw)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (aName == nsHTMLAtoms::title ||
|
||||
aName == nsHTMLAtoms::meta ||
|
||||
aName == nsHTMLAtoms::link ||
|
||||
aName == nsHTMLAtoms::style ||
|
||||
aName == nsHTMLAtoms::script ||
|
||||
aName == nsHTMLAtoms::html) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (parserService) {
|
||||
nsAutoString str;
|
||||
aName->ToString(str);
|
||||
PRBool res;
|
||||
PRInt32 id;
|
||||
|
||||
parserService->HTMLStringTagToId(str, &id);
|
||||
parserService->IsBlock(id, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLContentSerializer::LineBreakAfterOpen(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr)
|
||||
{
|
||||
if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
|
||||
(mFlags & nsIDocumentEncoder::OutputRaw)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((aName == nsHTMLAtoms::html) ||
|
||||
(aName == nsHTMLAtoms::head) ||
|
||||
(aName == nsHTMLAtoms::body) ||
|
||||
(aName == nsHTMLAtoms::ul) ||
|
||||
(aName == nsHTMLAtoms::ol) ||
|
||||
(aName == nsHTMLAtoms::dl) ||
|
||||
(aName == nsHTMLAtoms::table) ||
|
||||
(aName == nsHTMLAtoms::tbody) ||
|
||||
(aName == nsHTMLAtoms::tr) ||
|
||||
(aName == nsHTMLAtoms::br) ||
|
||||
(aName == nsHTMLAtoms::meta) ||
|
||||
(aName == nsHTMLAtoms::link) ||
|
||||
(aName == nsHTMLAtoms::script) ||
|
||||
(aName == nsHTMLAtoms::style)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLContentSerializer::LineBreakBeforeClose(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr)
|
||||
{
|
||||
if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel || !mColPos ||
|
||||
(mFlags & nsIDocumentEncoder::OutputRaw)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((aName == nsHTMLAtoms::html) ||
|
||||
(aName == nsHTMLAtoms::head) ||
|
||||
(aName == nsHTMLAtoms::body) ||
|
||||
(aName == nsHTMLAtoms::ul) ||
|
||||
(aName == nsHTMLAtoms::ol) ||
|
||||
(aName == nsHTMLAtoms::dl) ||
|
||||
(aName == nsHTMLAtoms::table) ||
|
||||
(aName == nsHTMLAtoms::tbody)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLContentSerializer::LineBreakAfterClose(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr)
|
||||
{
|
||||
if ((!mDoFormat && !aHasDirtyAttr) || mPreLevel ||
|
||||
(mFlags & nsIDocumentEncoder::OutputRaw)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if ((aName == nsHTMLAtoms::html) ||
|
||||
(aName == nsHTMLAtoms::head) ||
|
||||
(aName == nsHTMLAtoms::body) ||
|
||||
(aName == nsHTMLAtoms::tr) ||
|
||||
(aName == nsHTMLAtoms::th) ||
|
||||
(aName == nsHTMLAtoms::td) ||
|
||||
(aName == nsHTMLAtoms::pre) ||
|
||||
(aName == nsHTMLAtoms::title) ||
|
||||
(aName == nsHTMLAtoms::li) ||
|
||||
(aName == nsHTMLAtoms::dt) ||
|
||||
(aName == nsHTMLAtoms::dd) ||
|
||||
(aName == nsHTMLAtoms::blockquote) ||
|
||||
(aName == nsHTMLAtoms::p) ||
|
||||
(aName == nsHTMLAtoms::div)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (parserService) {
|
||||
nsAutoString str;
|
||||
aName->ToString(str);
|
||||
PRBool res;
|
||||
PRInt32 id;
|
||||
|
||||
parserService->HTMLStringTagToId(str, &id);
|
||||
parserService->IsBlock(id, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::StartIndentation(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
if ((mDoFormat || aHasDirtyAttr) && !mPreLevel && !mColPos) {
|
||||
for (PRInt32 i = mIndent; --i >= 0; ) {
|
||||
AppendToString(kIndentStr.get(), -1,
|
||||
aStr);
|
||||
}
|
||||
}
|
||||
|
||||
if ((aName == nsHTMLAtoms::head) ||
|
||||
(aName == nsHTMLAtoms::table) ||
|
||||
(aName == nsHTMLAtoms::tr) ||
|
||||
(aName == nsHTMLAtoms::ul) ||
|
||||
(aName == nsHTMLAtoms::ol) ||
|
||||
(aName == nsHTMLAtoms::tbody) ||
|
||||
(aName == nsHTMLAtoms::form) ||
|
||||
(aName == nsHTMLAtoms::frameset) ||
|
||||
(aName == nsHTMLAtoms::blockquote) ||
|
||||
(aName == nsHTMLAtoms::li) ||
|
||||
(aName == nsHTMLAtoms::dt) ||
|
||||
(aName == nsHTMLAtoms::dd)) {
|
||||
mIndent++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::EndIndentation(nsIAtom* aName,
|
||||
PRBool aHasDirtyAttr,
|
||||
nsAWritableString& aStr)
|
||||
{
|
||||
if ((aName == nsHTMLAtoms::head) ||
|
||||
(aName == nsHTMLAtoms::table) ||
|
||||
(aName == nsHTMLAtoms::tr) ||
|
||||
(aName == nsHTMLAtoms::ul) ||
|
||||
(aName == nsHTMLAtoms::ol) ||
|
||||
(aName == nsHTMLAtoms::li) ||
|
||||
(aName == nsHTMLAtoms::tbody) ||
|
||||
(aName == nsHTMLAtoms::form) ||
|
||||
(aName == nsHTMLAtoms::frameset)) {
|
||||
mIndent--;
|
||||
}
|
||||
|
||||
if ((mDoFormat || aHasDirtyAttr) && !mPreLevel && !mColPos) {
|
||||
for (PRInt32 i = mIndent; --i >= 0; ) {
|
||||
AppendToString(kIndentStr.get(), -1,
|
||||
aStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if the string has any lines longer than longLineLen:
|
||||
// if so, we presume formatting is wonky (e.g. the node has been edited)
|
||||
// and we'd better rewrap the whole text node.
|
||||
PRBool
|
||||
nsHTMLContentSerializer::HasLongLines(const nsString& text, PRInt32& aLastNewlineOffset)
|
||||
{
|
||||
PRUint32 start=0;
|
||||
PRUint32 theLen=text.Length();
|
||||
PRBool rv = PR_FALSE;
|
||||
aLastNewlineOffset = kNotFound;
|
||||
for (start = 0; start < theLen; )
|
||||
{
|
||||
PRInt32 eol = text.FindChar('\n', PR_FALSE, start);
|
||||
if (eol < 0) {
|
||||
eol = text.Length();
|
||||
}
|
||||
else {
|
||||
aLastNewlineOffset = eol;
|
||||
}
|
||||
if (PRInt32(eol - start) > kLongLineLen)
|
||||
rv = PR_TRUE;
|
||||
start = eol+1;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
1778
mozilla/content/base/src/nsPlainTextSerializer.cpp
Normal file
1778
mozilla/content/base/src/nsPlainTextSerializer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1453
mozilla/content/xbl/src/nsBindingManager.cpp
Normal file
1453
mozilla/content/xbl/src/nsBindingManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
332
mozilla/content/xbl/src/nsXBLWindowHandler.cpp
Normal file
332
mozilla/content/xbl/src/nsXBLWindowHandler.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* - David W. Hyatt (hyatt@netscape.com)
|
||||
* - Mike Pinkerton (pinkerton@netscape.com)
|
||||
* - Akkana Peck (akkana@netscape.com)
|
||||
*/
|
||||
|
||||
|
||||
#include "nsXBLWindowHandler.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsIXBLPrototypeBinding.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIXBLDocumentInfo.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
class nsXBLSpecialDocInfo
|
||||
{
|
||||
public:
|
||||
nsCOMPtr<nsIXBLDocumentInfo> mHTMLBindings;
|
||||
nsCOMPtr<nsIXBLDocumentInfo> mPlatformHTMLBindings;
|
||||
nsCOMPtr<nsIXBLDocumentInfo> mUserHTMLBindings;
|
||||
|
||||
nsCString mHTMLBindingStr;
|
||||
nsCString mPlatformHTMLBindingStr;
|
||||
nsCString mUserHTMLBindingStr;
|
||||
|
||||
static char* sHTMLBindingStr;
|
||||
static char* sPlatformHTMLBindingStr;
|
||||
static char* sUserHTMLBindingStr;
|
||||
|
||||
PRBool mInitialized;
|
||||
|
||||
public:
|
||||
void LoadDocInfo();
|
||||
void GetAllHandlers(const char* aType,
|
||||
nsIXBLPrototypeHandler** handler,
|
||||
nsIXBLPrototypeHandler** platformHandler,
|
||||
nsIXBLPrototypeHandler** userHandler);
|
||||
void GetHandlers(nsIXBLDocumentInfo* aInfo,
|
||||
const nsAReadableCString& aRef,
|
||||
nsIXBLPrototypeHandler** aResult);
|
||||
|
||||
nsXBLSpecialDocInfo() : mInitialized(PR_FALSE) {};
|
||||
};
|
||||
|
||||
char* nsXBLSpecialDocInfo::sHTMLBindingStr = "resource:///res/builtin/htmlBindings.xml";
|
||||
char* nsXBLSpecialDocInfo::sPlatformHTMLBindingStr = "resource:///res/builtin/platformHTMLBindings.xml";
|
||||
// Allow for a userHTMLBindings.xml.
|
||||
// XXX Should be in the user profile directory, when we have a urlspec for that
|
||||
char* nsXBLSpecialDocInfo::sUserHTMLBindingStr = "resource:///res/builtin/userHTMLBindings.xml";
|
||||
|
||||
void nsXBLSpecialDocInfo::LoadDocInfo()
|
||||
{
|
||||
if (mInitialized)
|
||||
return;
|
||||
mInitialized = PR_TRUE;
|
||||
|
||||
mHTMLBindingStr = sHTMLBindingStr;
|
||||
mPlatformHTMLBindingStr = sPlatformHTMLBindingStr;
|
||||
mUserHTMLBindingStr = sUserHTMLBindingStr;
|
||||
|
||||
if (mHTMLBindings && mPlatformHTMLBindings && mUserHTMLBindings)
|
||||
return;
|
||||
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIXBLService, xblService, "@mozilla.org/xbl;1", &rv);
|
||||
if (NS_FAILED(rv) || !xblService)
|
||||
return;
|
||||
|
||||
// Obtain the XP and platform doc infos
|
||||
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
|
||||
mHTMLBindingStr,
|
||||
nsCAutoString(""), PR_TRUE,
|
||||
getter_AddRefs(mHTMLBindings));
|
||||
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
|
||||
mPlatformHTMLBindingStr,
|
||||
nsCAutoString(""), PR_TRUE,
|
||||
getter_AddRefs(mPlatformHTMLBindings));
|
||||
xblService->LoadBindingDocumentInfo(nsnull, nsnull,
|
||||
mUserHTMLBindingStr,
|
||||
nsCAutoString(""), PR_TRUE,
|
||||
getter_AddRefs(mUserHTMLBindings));
|
||||
}
|
||||
|
||||
//
|
||||
// GetHandlers
|
||||
//
|
||||
//
|
||||
void
|
||||
nsXBLSpecialDocInfo::GetHandlers(nsIXBLDocumentInfo* aInfo,
|
||||
const nsAReadableCString& aRef,
|
||||
nsIXBLPrototypeHandler** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIXBLPrototypeBinding> binding;
|
||||
aInfo->GetPrototypeBinding(aRef, getter_AddRefs(binding));
|
||||
if (!binding) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aInfo->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsIContent> root = getter_AddRefs(doc->GetRootContent());
|
||||
if (root) { // no root, no handlers. don't crash please.
|
||||
PRInt32 childCount;
|
||||
root->ChildCount(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIContent> child;
|
||||
root->ChildAt(i, *getter_AddRefs(child));
|
||||
nsAutoString id;
|
||||
child->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
|
||||
if (id.EqualsWithConversion(nsPromiseFlatCString(aRef).get())) {
|
||||
NS_NewXBLPrototypeBinding(aRef, child, aInfo, getter_AddRefs(binding));
|
||||
aInfo->SetPrototypeBinding(aRef, binding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (binding) {
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> dummy;
|
||||
binding->GetPrototypeHandlers(aResult, getter_AddRefs(dummy)); // Addref happens here.
|
||||
}
|
||||
} // GetHandlers
|
||||
|
||||
void
|
||||
nsXBLSpecialDocInfo::GetAllHandlers(const char* aType,
|
||||
nsIXBLPrototypeHandler** aHandler,
|
||||
nsIXBLPrototypeHandler** aPlatformHandler,
|
||||
nsIXBLPrototypeHandler** aUserHandler)
|
||||
{
|
||||
if (mUserHTMLBindings) {
|
||||
nsCAutoString type(aType);
|
||||
type.Append("User");
|
||||
GetHandlers(mUserHTMLBindings, type, aUserHandler);
|
||||
}
|
||||
if (mPlatformHTMLBindings) {
|
||||
nsCAutoString type(aType);
|
||||
GetHandlers(mPlatformHTMLBindings, type, aPlatformHandler);
|
||||
}
|
||||
if (mHTMLBindings) {
|
||||
nsCAutoString type(aType);
|
||||
type.Append("Base");
|
||||
GetHandlers(mHTMLBindings, type, aHandler);
|
||||
}
|
||||
}
|
||||
|
||||
// Init statics
|
||||
nsXBLSpecialDocInfo* nsXBLWindowHandler::sXBLSpecialDocInfo = nsnull;
|
||||
PRUint32 nsXBLWindowHandler::sRefCnt = 0;
|
||||
|
||||
|
||||
//
|
||||
// nsXBLWindowHandler ctor
|
||||
//
|
||||
// Increment the refcount
|
||||
//
|
||||
nsXBLWindowHandler :: nsXBLWindowHandler (nsIDOMElement* aElement, nsIDOMEventReceiver* aReceiver)
|
||||
: mElement(aElement), mReceiver(aReceiver)
|
||||
{
|
||||
++sRefCnt;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsXBLWindowHandler dtor
|
||||
//
|
||||
// Decrement the refcount. If we get to zero, get rid of the static XBL doc
|
||||
// info.
|
||||
//
|
||||
nsXBLWindowHandler :: ~nsXBLWindowHandler ( )
|
||||
{
|
||||
--sRefCnt;
|
||||
if ( !sRefCnt ) {
|
||||
delete sXBLSpecialDocInfo;
|
||||
sXBLSpecialDocInfo = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// IsEditor
|
||||
//
|
||||
// Determine if the document we're working with is Editor or Browser
|
||||
//
|
||||
PRBool
|
||||
nsXBLWindowHandler :: IsEditor()
|
||||
{
|
||||
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(mReceiver));
|
||||
nsCOMPtr<nsIFocusController> focusController;
|
||||
windowRoot->GetFocusController(getter_AddRefs(focusController));
|
||||
if (!focusController) {
|
||||
NS_WARNING("********* Something went wrong! No focus controller on the root!!!\n");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
|
||||
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
|
||||
if (!focusedWindow)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> obj(do_QueryInterface(focusedWindow));
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
obj->GetDocShell(getter_AddRefs(docShell));
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
if (docShell)
|
||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
PRBool isEditor;
|
||||
presShell->GetDisplayNonTextSelection(&isEditor);
|
||||
return isEditor;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
} // IsEditor
|
||||
|
||||
|
||||
//
|
||||
// WalkHandlersInternal
|
||||
//
|
||||
// Given a particular DOM event and a pointer to the first handler in the list,
|
||||
// scan through the list to find something to handle the event and then make it
|
||||
// so.
|
||||
//
|
||||
nsresult
|
||||
nsXBLWindowHandler::WalkHandlersInternal(nsIDOMEvent* aEvent, nsIAtom* aEventType,
|
||||
nsIXBLPrototypeHandler* aHandler)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> currHandler = aHandler;
|
||||
while (currHandler) {
|
||||
|
||||
PRBool stopped;
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aEvent));
|
||||
privateEvent->IsDispatchStopped(&stopped);
|
||||
if (stopped)
|
||||
return NS_OK;
|
||||
|
||||
// if the handler says it wants the event, execute it
|
||||
if ( EventMatched(currHandler, aEventType, aEvent) ) {
|
||||
// ...but don't exectute if it is disabled.
|
||||
nsAutoString disabled;
|
||||
|
||||
nsCOMPtr<nsIContent> elt;
|
||||
currHandler->GetHandlerElement(getter_AddRefs(elt));
|
||||
|
||||
elt->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::disabled, disabled);
|
||||
if (!disabled.Equals(NS_LITERAL_STRING("true"))) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec = mReceiver;
|
||||
if (mElement)
|
||||
rec = do_QueryInterface(elt);
|
||||
rv = currHandler->ExecuteHandler(rec, aEvent);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// the current handler didn't want it, try the next one.
|
||||
nsCOMPtr<nsIXBLPrototypeHandler> nextHandler;
|
||||
currHandler->GetNextHandler(getter_AddRefs(nextHandler));
|
||||
currHandler = nextHandler;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
} // WalkHandlersInternal
|
||||
|
||||
|
||||
|
||||
//
|
||||
// EnsureHandlers
|
||||
//
|
||||
// Lazily load the XP and platform-specific bindings
|
||||
//
|
||||
nsresult
|
||||
nsXBLWindowHandler::EnsureHandlers()
|
||||
{
|
||||
if (!sXBLSpecialDocInfo)
|
||||
sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
|
||||
if (!sXBLSpecialDocInfo)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
sXBLSpecialDocInfo->LoadDocInfo();
|
||||
|
||||
// Now determine which handlers we should be using.
|
||||
if (IsEditor()) {
|
||||
sXBLSpecialDocInfo->GetAllHandlers("editor",
|
||||
getter_AddRefs(mHandler),
|
||||
getter_AddRefs(mPlatformHandler),
|
||||
getter_AddRefs(mUserHandler));
|
||||
}
|
||||
else {
|
||||
sXBLSpecialDocInfo->GetAllHandlers("browser",
|
||||
getter_AddRefs(mHandler),
|
||||
getter_AddRefs(mPlatformHandler),
|
||||
getter_AddRefs(mUserHandler));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
} // EnsureHandlers
|
||||
|
||||
1461
mozilla/docshell/base/nsWebShell.cpp
Normal file
1461
mozilla/docshell/base/nsWebShell.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4594
mozilla/dom/src/base/nsGlobalWindow.cpp
Normal file
4594
mozilla/dom/src/base/nsGlobalWindow.cpp
Normal file
File diff suppressed because it is too large
Load Diff
259
mozilla/editor/base/TextEditorTest.cpp
Normal file
259
mozilla/editor/base/TextEditorTest.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
/* -*- Mode: C++ tab-width: 2 indent-tabs-mode: nil c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "TextEditorTest.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIEditProperty.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
||||
#define TEST_RESULT(r) { if (NS_FAILED(r)) {printf("FAILURE result=%X\n", r); return r; } }
|
||||
#define TEST_POINTER(p) { if (!p) {printf("FAILURE null pointer\n"); return NS_ERROR_NULL_POINTER; } }
|
||||
|
||||
TextEditorTest::TextEditorTest()
|
||||
{
|
||||
printf("constructed a TextEditorTest\n");
|
||||
}
|
||||
|
||||
TextEditorTest::~TextEditorTest()
|
||||
{
|
||||
printf("destroyed a TextEditorTest\n");
|
||||
}
|
||||
|
||||
void TextEditorTest::Run(nsIEditor *aEditor, PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
{
|
||||
if (!aEditor) return;
|
||||
mTextEditor = do_QueryInterface(aEditor);
|
||||
mEditor = do_QueryInterface(aEditor);
|
||||
RunUnitTest(outNumTests, outNumTestsFailed);
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::RunUnitTest(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
if (!outNumTests || !outNumTestsFailed)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*outNumTests = 0;
|
||||
*outNumTestsFailed = 0;
|
||||
|
||||
result = InitDoc();
|
||||
TEST_RESULT(result);
|
||||
// shouldn't we just bail on error here?
|
||||
|
||||
// insert some simple text
|
||||
result = mTextEditor->InsertText(NS_LITERAL_STRING("1234567890abcdefghij1234567890").get());
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
// insert some more text
|
||||
result = mTextEditor->InsertText(NS_LITERAL_STRING("Moreover, I am cognizant of the interrelatedness of all communities and states. I cannot sit idly by in Atlanta and not be concerned about what happens in Birmingham. Injustice anywhere is a threat to justice everywhere").get());
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
result = TestInsertBreak();
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
result = TestTextProperties();
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
// get us back to the original document
|
||||
result = mEditor->Undo(12);
|
||||
TEST_RESULT(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::InitDoc()
|
||||
{
|
||||
nsresult result = mEditor->SelectAll();
|
||||
TEST_RESULT(result);
|
||||
result = mEditor->DeleteSelection(nsIEditor::eNext);
|
||||
TEST_RESULT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::TestInsertBreak()
|
||||
{
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
nsresult result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(selection.get());
|
||||
nsCOMPtr<nsIDOMNode>anchor;
|
||||
result = selection->GetAnchorNode(getter_AddRefs(anchor));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(anchor.get());
|
||||
selection->Collapse(anchor, 0);
|
||||
// insert one break
|
||||
printf("inserting a break\n");
|
||||
result = mTextEditor->InsertLineBreak();
|
||||
TEST_RESULT(result);
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// insert a second break adjacent to the first
|
||||
printf("inserting a second break\n");
|
||||
result = mTextEditor->InsertLineBreak();
|
||||
TEST_RESULT(result);
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::TestTextProperties()
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
nsresult result = mEditor->GetDocument(getter_AddRefs(doc));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(doc.get());
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString textTag; textTag.AssignWithConversion("__moz_text");
|
||||
result = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(nodeList.get());
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(0!=count, "there are no text nodes in the document!");
|
||||
nsCOMPtr<nsIDOMNode>textNode;
|
||||
result = nodeList->Item(count-1, getter_AddRefs(textNode));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(textNode.get());
|
||||
|
||||
// set the whole text node to bold
|
||||
printf("set the whole first text node to bold\n");
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(selection.get());
|
||||
nsCOMPtr<nsIDOMCharacterData>textData;
|
||||
textData = do_QueryInterface(textNode);
|
||||
PRUint32 length;
|
||||
textData->GetLength(&length);
|
||||
selection->Collapse(textNode, 0);
|
||||
selection->Extend(textNode, length);
|
||||
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor (do_QueryInterface(mTextEditor));
|
||||
if (!htmlEditor)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first=PR_FALSE;
|
||||
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_FALSE==first, "first should be false");
|
||||
NS_ASSERTION(PR_FALSE==any, "any should be false");
|
||||
NS_ASSERTION(PR_FALSE==all, "all should be false");
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::b, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// remove the bold we just set
|
||||
printf("set the whole first text node to not bold\n");
|
||||
result = htmlEditor->RemoveInlineProperty(nsIEditProperty::b, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_FALSE==first, "first should be false");
|
||||
NS_ASSERTION(PR_FALSE==any, "any should be false");
|
||||
NS_ASSERTION(PR_FALSE==all, "all should be false");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// set all but the first and last character to bold
|
||||
printf("set the first text node (1, length-1) to bold and italic, and (2, length-1) to underline.\n");
|
||||
selection->Collapse(textNode, 1);
|
||||
selection->Extend(textNode, length-1);
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::b, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
// make all that same text italic
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::i, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::i, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// make all the text underlined, except for the first 2 and last 2 characters
|
||||
result = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(nodeList.get());
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(0!=count, "there are no text nodes in the document!");
|
||||
result = nodeList->Item(count-2, getter_AddRefs(textNode));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(textNode.get());
|
||||
textData = do_QueryInterface(textNode);
|
||||
textData->GetLength(&length);
|
||||
NS_ASSERTION(length==915, "wrong text node");
|
||||
selection->Collapse(textNode, 1);
|
||||
selection->Extend(textNode, length-2);
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::u, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::u, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
5508
mozilla/editor/base/nsEditor.cpp
Normal file
5508
mozilla/editor/base/nsEditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5427
mozilla/editor/base/nsEditorShell.cpp
Normal file
5427
mozilla/editor/base/nsEditorShell.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3895
mozilla/editor/base/nsHTMLEditor.cpp
Normal file
3895
mozilla/editor/base/nsHTMLEditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5427
mozilla/editor/composer/src/nsEditorShell.cpp
Normal file
5427
mozilla/editor/composer/src/nsEditorShell.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5508
mozilla/editor/libeditor/base/nsEditor.cpp
Normal file
5508
mozilla/editor/libeditor/base/nsEditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
259
mozilla/editor/libeditor/html/TextEditorTest.cpp
Normal file
259
mozilla/editor/libeditor/html/TextEditorTest.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
/* -*- Mode: C++ tab-width: 2 indent-tabs-mode: nil c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "TextEditorTest.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIEditProperty.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
||||
#define TEST_RESULT(r) { if (NS_FAILED(r)) {printf("FAILURE result=%X\n", r); return r; } }
|
||||
#define TEST_POINTER(p) { if (!p) {printf("FAILURE null pointer\n"); return NS_ERROR_NULL_POINTER; } }
|
||||
|
||||
TextEditorTest::TextEditorTest()
|
||||
{
|
||||
printf("constructed a TextEditorTest\n");
|
||||
}
|
||||
|
||||
TextEditorTest::~TextEditorTest()
|
||||
{
|
||||
printf("destroyed a TextEditorTest\n");
|
||||
}
|
||||
|
||||
void TextEditorTest::Run(nsIEditor *aEditor, PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
{
|
||||
if (!aEditor) return;
|
||||
mTextEditor = do_QueryInterface(aEditor);
|
||||
mEditor = do_QueryInterface(aEditor);
|
||||
RunUnitTest(outNumTests, outNumTestsFailed);
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::RunUnitTest(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
{
|
||||
nsresult result;
|
||||
|
||||
if (!outNumTests || !outNumTestsFailed)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*outNumTests = 0;
|
||||
*outNumTestsFailed = 0;
|
||||
|
||||
result = InitDoc();
|
||||
TEST_RESULT(result);
|
||||
// shouldn't we just bail on error here?
|
||||
|
||||
// insert some simple text
|
||||
result = mTextEditor->InsertText(NS_LITERAL_STRING("1234567890abcdefghij1234567890").get());
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
// insert some more text
|
||||
result = mTextEditor->InsertText(NS_LITERAL_STRING("Moreover, I am cognizant of the interrelatedness of all communities and states. I cannot sit idly by in Atlanta and not be concerned about what happens in Birmingham. Injustice anywhere is a threat to justice everywhere").get());
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
result = TestInsertBreak();
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
result = TestTextProperties();
|
||||
TEST_RESULT(result);
|
||||
(*outNumTests)++;
|
||||
(*outNumTestsFailed) += (NS_FAILED(result) != NS_OK);
|
||||
|
||||
// get us back to the original document
|
||||
result = mEditor->Undo(12);
|
||||
TEST_RESULT(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::InitDoc()
|
||||
{
|
||||
nsresult result = mEditor->SelectAll();
|
||||
TEST_RESULT(result);
|
||||
result = mEditor->DeleteSelection(nsIEditor::eNext);
|
||||
TEST_RESULT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::TestInsertBreak()
|
||||
{
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
nsresult result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(selection.get());
|
||||
nsCOMPtr<nsIDOMNode>anchor;
|
||||
result = selection->GetAnchorNode(getter_AddRefs(anchor));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(anchor.get());
|
||||
selection->Collapse(anchor, 0);
|
||||
// insert one break
|
||||
printf("inserting a break\n");
|
||||
result = mTextEditor->InsertLineBreak();
|
||||
TEST_RESULT(result);
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// insert a second break adjacent to the first
|
||||
printf("inserting a second break\n");
|
||||
result = mTextEditor->InsertLineBreak();
|
||||
TEST_RESULT(result);
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult TextEditorTest::TestTextProperties()
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument>doc;
|
||||
nsresult result = mEditor->GetDocument(getter_AddRefs(doc));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(doc.get());
|
||||
nsCOMPtr<nsIDOMNodeList>nodeList;
|
||||
nsAutoString textTag; textTag.AssignWithConversion("__moz_text");
|
||||
result = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(nodeList.get());
|
||||
PRUint32 count;
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(0!=count, "there are no text nodes in the document!");
|
||||
nsCOMPtr<nsIDOMNode>textNode;
|
||||
result = nodeList->Item(count-1, getter_AddRefs(textNode));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(textNode.get());
|
||||
|
||||
// set the whole text node to bold
|
||||
printf("set the whole first text node to bold\n");
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(selection.get());
|
||||
nsCOMPtr<nsIDOMCharacterData>textData;
|
||||
textData = do_QueryInterface(textNode);
|
||||
PRUint32 length;
|
||||
textData->GetLength(&length);
|
||||
selection->Collapse(textNode, 0);
|
||||
selection->Extend(textNode, length);
|
||||
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor (do_QueryInterface(mTextEditor));
|
||||
if (!htmlEditor)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool any = PR_FALSE;
|
||||
PRBool all = PR_FALSE;
|
||||
PRBool first=PR_FALSE;
|
||||
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_FALSE==first, "first should be false");
|
||||
NS_ASSERTION(PR_FALSE==any, "any should be false");
|
||||
NS_ASSERTION(PR_FALSE==all, "all should be false");
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::b, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// remove the bold we just set
|
||||
printf("set the whole first text node to not bold\n");
|
||||
result = htmlEditor->RemoveInlineProperty(nsIEditProperty::b, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_FALSE==first, "first should be false");
|
||||
NS_ASSERTION(PR_FALSE==any, "any should be false");
|
||||
NS_ASSERTION(PR_FALSE==all, "all should be false");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// set all but the first and last character to bold
|
||||
printf("set the first text node (1, length-1) to bold and italic, and (2, length-1) to underline.\n");
|
||||
selection->Collapse(textNode, 1);
|
||||
selection->Extend(textNode, length-1);
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::b, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
// make all that same text italic
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::i, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::i, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::b, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
// make all the text underlined, except for the first 2 and last 2 characters
|
||||
result = doc->GetElementsByTagName(textTag, getter_AddRefs(nodeList));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(nodeList.get());
|
||||
nodeList->GetLength(&count);
|
||||
NS_ASSERTION(0!=count, "there are no text nodes in the document!");
|
||||
result = nodeList->Item(count-2, getter_AddRefs(textNode));
|
||||
TEST_RESULT(result);
|
||||
TEST_POINTER(textNode.get());
|
||||
textData = do_QueryInterface(textNode);
|
||||
textData->GetLength(&length);
|
||||
NS_ASSERTION(length==915, "wrong text node");
|
||||
selection->Collapse(textNode, 1);
|
||||
selection->Extend(textNode, length-2);
|
||||
result = htmlEditor->SetInlineProperty(nsIEditProperty::u, nsnull, nsnull);
|
||||
TEST_RESULT(result);
|
||||
result = htmlEditor->GetInlineProperty(nsIEditProperty::u, nsnull, nsnull, first, any, all);
|
||||
TEST_RESULT(result);
|
||||
NS_ASSERTION(PR_TRUE==first, "first should be true");
|
||||
NS_ASSERTION(PR_TRUE==any, "any should be true");
|
||||
NS_ASSERTION(PR_TRUE==all, "all should be true");
|
||||
mEditor->DebugDumpContent();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
3895
mozilla/editor/libeditor/html/nsHTMLEditor.cpp
Normal file
3895
mozilla/editor/libeditor/html/nsHTMLEditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
423
mozilla/embedding/browser/powerplant/source/CProfileManager.cpp
Executable file
423
mozilla/embedding/browser/powerplant/source/CProfileManager.cpp
Executable file
@@ -0,0 +1,423 @@
|
||||
/* -*- Mode: C++; tab-width: 4; 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 the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Conrad Carlen <ccarlen@netscape.com>
|
||||
*/
|
||||
|
||||
// PPBrowser
|
||||
#include "CProfileManager.h"
|
||||
#include "ApplIDs.h"
|
||||
#include "UMacUnicode.h"
|
||||
|
||||
// PowerPlant
|
||||
#include <LEditText.h>
|
||||
#include <LTextTableView.h>
|
||||
#include <LPushButton.h>
|
||||
#include <LTableMonoGeometry.h>
|
||||
#include <LTableArrayStorage.h>
|
||||
#include <LTableSingleSelector.h>
|
||||
#include <LCheckBox.h>
|
||||
|
||||
|
||||
// Mozilla
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIRegistry.h"
|
||||
|
||||
// Constants
|
||||
|
||||
const MessageT msg_OnNewProfile = 2000;
|
||||
const MessageT msg_OnDeleteProfile = 2001;
|
||||
const MessageT msg_OnRenameProfile = 2002;
|
||||
|
||||
#define kRegistryGlobalPrefsSubtreeString (NS_LITERAL_STRING("global-prefs"))
|
||||
#define kRegistryShowProfilesAtStartup "start-show-dialog"
|
||||
|
||||
//*****************************************************************************
|
||||
//*** CProfileManager
|
||||
//*****************************************************************************
|
||||
|
||||
CProfileManager::CProfileManager() :
|
||||
LAttachment(msg_AnyMessage,true)
|
||||
{
|
||||
}
|
||||
|
||||
CProfileManager::~CProfileManager()
|
||||
{
|
||||
}
|
||||
|
||||
void CProfileManager::StartUp()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIProfile, profileService, NS_PROFILE_CONTRACTID, &rv);
|
||||
ThrowIfNil_(profileService);
|
||||
|
||||
PRInt32 profileCount;
|
||||
rv = profileService->GetProfileCount(&profileCount);
|
||||
ThrowIfError_(rv);
|
||||
if (profileCount == 0)
|
||||
{
|
||||
// Make a new default profile
|
||||
NS_NAMED_LITERAL_STRING(newProfileName, "default");
|
||||
|
||||
rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
|
||||
ThrowIfError_(rv);
|
||||
rv = profileService->SetCurrentProfile(newProfileName.get());
|
||||
ThrowIfError_(rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use our flag here to check for whether to show profile mgr UI. If the flag
|
||||
// says don't show it, just start with the last used profile.
|
||||
|
||||
PRBool showIt;
|
||||
rv = GetShowDialogOnStart(&showIt);
|
||||
|
||||
if (NS_FAILED(rv) || (profileCount > 1 && showIt))
|
||||
{
|
||||
DoManageProfilesDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
// GetCurrentProfile returns the profile which was last used but is not nescesarily
|
||||
// active. Call SetCurrentProfile to make it installed and active.
|
||||
|
||||
nsXPIDLString currProfileName;
|
||||
rv = profileService->GetCurrentProfile(getter_Copies(currProfileName));
|
||||
ThrowIfError_(rv);
|
||||
rv = profileService->SetCurrentProfile(currProfileName);
|
||||
ThrowIfError_(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Boolean CProfileManager::DoNewProfileDialog(char *outName, UInt32 bufSize)
|
||||
{
|
||||
Boolean confirmed;
|
||||
StDialogHandler theHandler(dlog_NewProfile, LCommander::GetTopCommander());
|
||||
LWindow *theDialog = theHandler.GetDialog();
|
||||
|
||||
ThrowIfNil_(theDialog);
|
||||
LEditText *responseText = dynamic_cast<LEditText*>(theDialog->FindPaneByID('Name'));
|
||||
ThrowIfNil_(responseText);
|
||||
theDialog->SetLatentSub(responseText);
|
||||
|
||||
theDialog->Show();
|
||||
theDialog->Select();
|
||||
|
||||
while (true) // This is our modal dialog event loop
|
||||
{
|
||||
MessageT hitMessage = theHandler.DoDialog();
|
||||
|
||||
if (hitMessage == msg_OK)
|
||||
{
|
||||
Str255 pStr;
|
||||
UInt32 outLen;
|
||||
|
||||
responseText->GetDescriptor(pStr);
|
||||
outLen = pStr[0] >= bufSize ? bufSize - 1 : pStr[0];
|
||||
memcpy(outName, &pStr[1], outLen);
|
||||
outName[outLen] = '\0';
|
||||
confirmed = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
else if (hitMessage == msg_Cancel)
|
||||
{
|
||||
confirmed = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return confirmed;
|
||||
}
|
||||
|
||||
|
||||
void CProfileManager::DoManageProfilesDialog()
|
||||
{
|
||||
nsresult rv;
|
||||
StDialogHandler theHandler(dlog_ManageProfiles, LCommander::GetTopCommander());
|
||||
LWindow *theDialog = theHandler.GetDialog();
|
||||
|
||||
NS_WITH_SERVICE(nsIProfile, profileService, NS_PROFILE_CONTRACTID, &rv);
|
||||
ThrowIfNil_(profileService);
|
||||
|
||||
// Set up the dialog by filling the list of current profiles
|
||||
LTextTableView *table = (LTextTableView*) theDialog->FindPaneByID('List');
|
||||
ThrowIfNil_(table);
|
||||
LPushButton *deleteButton = (LPushButton *) theDialog->FindPaneByID('Dele');
|
||||
ThrowIfNil_(deleteButton);
|
||||
|
||||
//Str255 pascalStr;
|
||||
nsAutoString unicodeStr;
|
||||
nsCAutoString cStr;
|
||||
char dataBuf[256];
|
||||
UInt32 dataSize;
|
||||
|
||||
// PowerPlant stuff to set up the list view
|
||||
STableCell selectedCell(1, 1);
|
||||
SDimension16 tableSize;
|
||||
TableIndexT rows, cols;
|
||||
|
||||
table->GetFrameSize(tableSize);
|
||||
table->SetTableGeometry(new LTableMonoGeometry(table, tableSize.width, 16));
|
||||
table->SetTableStorage(new LTableArrayStorage(table, 0UL));
|
||||
table->SetTableSelector(new LTableSingleSelector(table));
|
||||
table->InsertCols(1, 0);
|
||||
|
||||
// Get the name of the current profile so we can select it
|
||||
nsXPIDLString currProfileName;
|
||||
profileService->GetCurrentProfile(getter_Copies(currProfileName));
|
||||
|
||||
// Get the list of profile names and add them to the list
|
||||
PRUint32 listLen;
|
||||
PRUnichar **profileList;
|
||||
rv = profileService->GetProfileList(&listLen, &profileList);
|
||||
ThrowIfError_(rv);
|
||||
|
||||
for (PRUint32 index = 0; index < listLen; index++)
|
||||
{
|
||||
CPlatformUCSConversion::GetInstance()->UCSToPlatform(nsLiteralString(profileList[index]), cStr);
|
||||
table->InsertRows(1, LONG_MAX, cStr.get(), cStr.Length(), true);
|
||||
|
||||
if (nsCRT::strcmp(profileList[index], currProfileName.get()) == 0)
|
||||
selectedCell.row = index + 1;
|
||||
}
|
||||
|
||||
PRInt32 numProfiles;
|
||||
rv = profileService->GetProfileCount(&numProfiles);
|
||||
ThrowIfError_(rv);
|
||||
(numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
|
||||
table->SelectCell(selectedCell);
|
||||
|
||||
|
||||
// Handle the "Ask At StartUp" checkbox
|
||||
LCheckBox *showAtStartCheck = (LCheckBox*) theDialog->FindPaneByID('Show');
|
||||
ThrowIfNil_(showAtStartCheck);
|
||||
PRBool showIt;
|
||||
rv = GetShowDialogOnStart(&showIt);
|
||||
if (NS_FAILED(rv))
|
||||
showIt = PR_TRUE;
|
||||
showAtStartCheck->SetValue(showIt);
|
||||
|
||||
|
||||
theDialog->Show();
|
||||
theDialog->Select();
|
||||
|
||||
while (true) // This is our modal dialog event loop
|
||||
{
|
||||
MessageT hitMessage = theHandler.DoDialog();
|
||||
|
||||
if (hitMessage == msg_OK)
|
||||
{
|
||||
theDialog->Hide();
|
||||
SetShowDialogOnStart(showAtStartCheck->GetValue());
|
||||
selectedCell = table->GetFirstSelectedCell();
|
||||
if (selectedCell.row > 0)
|
||||
{
|
||||
dataSize = sizeof(dataBuf) - 1;
|
||||
table->GetCellData(selectedCell, dataBuf, dataSize);
|
||||
dataBuf[dataSize] = '\0';
|
||||
CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsLiteralCString(dataBuf), unicodeStr);
|
||||
rv = profileService->SetCurrentProfile(unicodeStr.GetUnicode());
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (hitMessage == msg_Cancel)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (hitMessage == msg_OnNewProfile)
|
||||
{
|
||||
if (DoNewProfileDialog(dataBuf, sizeof(dataBuf)))
|
||||
{
|
||||
CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsLiteralCString(dataBuf), unicodeStr);
|
||||
rv = profileService->CreateNewProfile(unicodeStr.GetUnicode(), nsnull, nsnull, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
table->InsertRows(1, LONG_MAX, dataBuf, strlen(dataBuf), true);
|
||||
table->GetTableSize(rows, cols);
|
||||
table->SelectCell(STableCell(rows, cols));
|
||||
|
||||
rv = profileService->GetProfileCount(&numProfiles);
|
||||
(NS_SUCCEEDED(rv) && numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
|
||||
}
|
||||
}
|
||||
else if (hitMessage == msg_OnDeleteProfile)
|
||||
{
|
||||
selectedCell = table->GetFirstSelectedCell();
|
||||
if (selectedCell.row > 0)
|
||||
{
|
||||
dataSize = sizeof(dataBuf) - 1;
|
||||
table->GetCellData(selectedCell, dataBuf, dataSize);
|
||||
dataBuf[dataSize] = '\0';
|
||||
CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsLiteralCString(dataBuf), unicodeStr);
|
||||
|
||||
rv = profileService->DeleteProfile(unicodeStr.GetUnicode(), PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
table->RemoveRows(1, selectedCell.row, true);
|
||||
table->GetTableSize(rows, cols);
|
||||
if (selectedCell.row >= rows)
|
||||
selectedCell.row = rows - 1;
|
||||
table->SelectCell(selectedCell);
|
||||
|
||||
rv = profileService->GetProfileCount(&numProfiles);
|
||||
(NS_SUCCEEDED(rv) && numProfiles > 1) ? deleteButton->Enable() : deleteButton->Disable();
|
||||
}
|
||||
}
|
||||
else if (hitMessage == msg_OnRenameProfile)
|
||||
{
|
||||
nsAutoString oldName;
|
||||
|
||||
selectedCell = table->GetFirstSelectedCell();
|
||||
dataSize = sizeof(dataBuf) - 1;
|
||||
table->GetCellData(selectedCell, dataBuf, dataSize);
|
||||
dataBuf[dataSize] = '\0';
|
||||
CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsLiteralCString(dataBuf), oldName);
|
||||
|
||||
if (DoNewProfileDialog(dataBuf, sizeof(dataBuf)))
|
||||
{
|
||||
CPlatformUCSConversion::GetInstance()->PlatformToUCS(nsLiteralCString(dataBuf), unicodeStr);
|
||||
profileService->RenameProfile(oldName.GetUnicode(), unicodeStr.GetUnicode());
|
||||
table->SetCellData(selectedCell, dataBuf, strlen(dataBuf));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The following three methods have nothing to do with profile management per se.
|
||||
They use the registry to store a flag which allows the user to choose whether
|
||||
to show the profile manager dialog at startup. After all, since we can switch
|
||||
it at any time - why must we deal with the dialog every time we start the app?
|
||||
*/
|
||||
|
||||
nsresult CProfileManager::GetShowDialogOnStart(PRBool* showIt)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
*showIt = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIRegistry> registry;
|
||||
rv = OpenAppRegistry(getter_AddRefs(registry));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRegistryKey profilesTreeKey;
|
||||
|
||||
rv = registry->GetKey(nsIRegistry::Common,
|
||||
kRegistryGlobalPrefsSubtreeString.get(),
|
||||
&profilesTreeKey);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
PRInt32 flagValue;
|
||||
rv = registry->GetInt(profilesTreeKey,
|
||||
kRegistryShowProfilesAtStartup,
|
||||
&flagValue);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
*showIt = (flagValue != 0);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult CProfileManager::SetShowDialogOnStart(PRBool showIt)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIRegistry> registry;
|
||||
rv = OpenAppRegistry(getter_AddRefs(registry));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRegistryKey profilesTreeKey;
|
||||
|
||||
rv = registry->GetKey(nsIRegistry::Common,
|
||||
kRegistryGlobalPrefsSubtreeString.get(),
|
||||
&profilesTreeKey);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
rv = registry->AddKey(nsIRegistry::Common,
|
||||
kRegistryGlobalPrefsSubtreeString.get(),
|
||||
&profilesTreeKey);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
|
||||
rv = registry->SetInt(profilesTreeKey,
|
||||
kRegistryShowProfilesAtStartup,
|
||||
showIt);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult CProfileManager::OpenAppRegistry(nsIRegistry **aRegistry)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRegistry);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> regFile;
|
||||
nsXPIDLCString regFilePath;
|
||||
|
||||
rv = NS_GetSpecialDirectory(NS_APP_APPLICATION_REGISTRY_FILE, getter_AddRefs(regFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = regFile->GetPath(getter_Copies(regFilePath));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIRegistry> registry(do_CreateInstance(NS_REGISTRY_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = registry->Open(regFilePath);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aRegistry = registry;
|
||||
NS_IF_ADDREF(*aRegistry);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//*** CProfileManager::LAttachment
|
||||
//*****************************************************************************
|
||||
|
||||
void CProfileManager::ExecuteSelf(MessageT inMessage, void *ioParam)
|
||||
{
|
||||
mExecuteHost = true;
|
||||
// update status
|
||||
if (inMessage == msg_CommandStatus) {
|
||||
SCommandStatus *status = (SCommandStatus *)ioParam;
|
||||
if (status->command == cmd_ManageProfiles) {
|
||||
*status->enabled = true;
|
||||
*status->usesMark = false;
|
||||
mExecuteHost = false; // we handled it
|
||||
}
|
||||
}
|
||||
else if (inMessage == cmd_ManageProfiles) {
|
||||
DoManageProfilesDialog();
|
||||
mExecuteHost = false; // we handled it
|
||||
}
|
||||
}
|
||||
1508
mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
Normal file
1508
mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4017
mozilla/extensions/wallet/src/wallet.cpp
Normal file
4017
mozilla/extensions/wallet/src/wallet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1330
mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp
Normal file
1330
mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1034
mozilla/htmlparser/src/nsHTMLTokenizer.cpp
Normal file
1034
mozilla/htmlparser/src/nsHTMLTokenizer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
789
mozilla/htmlparser/src/nsLoggingSink.cpp
Normal file
789
mozilla/htmlparser/src/nsLoggingSink.cpp
Normal file
@@ -0,0 +1,789 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Notes:
|
||||
* The logging sink is now both a sink and a proxy.
|
||||
* If you want to dump the calls from the parser to the sink,
|
||||
* create a content sink as usual and hand it to the parser.
|
||||
*
|
||||
* If you want to use a normal sink AND simultaneously have a
|
||||
* parse-log generated, you can set an environment variable
|
||||
* and a logging sink will be created. It will act as a proxy
|
||||
* to the REAL sink you are using after it logs the call. This
|
||||
* form of the loggingsink is constructed using the version
|
||||
* that accepts an nsIHTMLContentSink*.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsLoggingSink.h"
|
||||
#include "nsHTMLTags.h"
|
||||
#include "nsString.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID);
|
||||
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
|
||||
static NS_DEFINE_IID(kILoggingSinkIID, NS_ILOGGING_SINK_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
// list of tags that have skipped content
|
||||
static char gSkippedContentTags[] = {
|
||||
eHTMLTag_style,
|
||||
eHTMLTag_script,
|
||||
eHTMLTag_server,
|
||||
eHTMLTag_textarea,
|
||||
eHTMLTag_title,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLLoggingSink(nsIContentSink** aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsLoggingSink* it = new nsLoggingSink();
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return it->QueryInterface(kIContentSinkIID, (void**) aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsLoggingSink::nsLoggingSink() {
|
||||
NS_INIT_REFCNT();
|
||||
mOutput = 0;
|
||||
mLevel=-1;
|
||||
mSink=0;
|
||||
}
|
||||
|
||||
nsLoggingSink::~nsLoggingSink() {
|
||||
mSink=0;
|
||||
if(mOutput && mAutoDeleteOutput) {
|
||||
delete mOutput;
|
||||
}
|
||||
mOutput=0;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsLoggingSink)
|
||||
NS_IMPL_RELEASE(nsLoggingSink)
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtr, "null ptr");
|
||||
if (nsnull == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
nsISupports* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kIContentSinkIID)) {
|
||||
nsIContentSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kIHTMLContentSinkIID)) {
|
||||
nsIHTMLContentSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kILoggingSinkIID)) {
|
||||
nsILoggingSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else {
|
||||
*aInstancePtr = nsnull;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetOutputStream(PRFileDesc *aStream,PRBool autoDeleteOutput) {
|
||||
mOutput = aStream;
|
||||
mAutoDeleteOutput=autoDeleteOutput;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static
|
||||
void WriteTabs(PRFileDesc * out,int aTabCount) {
|
||||
int tabs;
|
||||
for(tabs=0;tabs<aTabCount;tabs++)
|
||||
PR_fprintf(out, " ");
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillBuildModel() {
|
||||
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
PR_fprintf(mOutput, "<begin>\n");
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
mSink->WillBuildModel();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::DidBuildModel(PRInt32 aQualityLevel) {
|
||||
|
||||
WriteTabs(mOutput,--mLevel);
|
||||
PR_fprintf(mOutput, "</begin>\n");
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
nsresult theResult=NS_OK;
|
||||
if(mSink) {
|
||||
theResult=mSink->DidBuildModel(aQualityLevel);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillInterrupt() {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->WillInterrupt();
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillResume() {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->WillResume();
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetParser(nsIParser* aParser) {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->SetParser(aParser);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenContainer(const nsIParserNode& aNode) {
|
||||
|
||||
OpenNode("container", aNode); //do the real logging work...
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenContainer(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseContainer(const nsIParserNode& aNode) {
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
theResult=CloseNode(tag);
|
||||
}
|
||||
else theResult= CloseNode("???");
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseContainer(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddLeaf(const nsIParserNode& aNode) {
|
||||
LeafNode(aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddLeaf(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::NotifyError(const nsParserError* aError) {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->NotifyError(aError);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This gets called by the parser when you want to add
|
||||
* a PI node to the current container in the content
|
||||
* model.
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddProcessingInstruction(const nsIParserNode& aNode){
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddProcessingInstruction(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called by the parser when it encounters
|
||||
* a DOCTYPE declaration in the HTML document.
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode) {
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddDocTypeDecl(aNode,aMode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called by the parser when you want to add
|
||||
* a comment node to the current container in the content
|
||||
* model.
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddComment(const nsIParserNode& aNode){
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddComment(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetTitle(const nsString& aValue) {
|
||||
|
||||
char* tmp;
|
||||
GetNewCString(aValue, &tmp);
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
if(tmp) {
|
||||
PR_fprintf(mOutput, "<title value=\"%s\"/>\n", tmp);
|
||||
nsMemory::Free(tmp);
|
||||
}
|
||||
--mLevel;
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->SetTitle(aValue);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHTML(const nsIParserNode& aNode) {
|
||||
OpenNode("html", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenHTML(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseHTML(const nsIParserNode& aNode) {
|
||||
CloseNode("html");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseHTML(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHead(const nsIParserNode& aNode) {
|
||||
OpenNode("head", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenHead(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseHead(const nsIParserNode& aNode) {
|
||||
CloseNode("head");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseHead(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenBody(const nsIParserNode& aNode) {
|
||||
OpenNode("body", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenBody(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseBody(const nsIParserNode& aNode) {
|
||||
CloseNode("body");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseBody(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenForm(const nsIParserNode& aNode) {
|
||||
OpenNode("form", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenForm(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseForm(const nsIParserNode& aNode) {
|
||||
CloseNode("form");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseForm(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenMap(const nsIParserNode& aNode) {
|
||||
OpenNode("map", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenMap(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseMap(const nsIParserNode& aNode) {
|
||||
CloseNode("map");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseMap(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenFrameset(const nsIParserNode& aNode) {
|
||||
OpenNode("frameset", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenFrameset(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseFrameset(const nsIParserNode& aNode) {
|
||||
CloseNode("frameset");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseFrameset(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::OpenNode(const char* aKind, const nsIParserNode& aNode) {
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
|
||||
PR_fprintf(mOutput,"<open container=");
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
PR_fprintf(mOutput, "\"%s\"", tag);
|
||||
}
|
||||
else {
|
||||
char* text;
|
||||
GetNewCString(aNode.GetText(), &text);
|
||||
if(text) {
|
||||
PR_fprintf(mOutput, "\"%s\"", text);
|
||||
nsMemory::Free(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (WillWriteAttributes(aNode)) {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
WriteAttributes(aNode);
|
||||
PR_fprintf(mOutput, "</open>\n");
|
||||
}
|
||||
else {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::CloseNode(const char* aKind) {
|
||||
WriteTabs(mOutput,mLevel--);
|
||||
PR_fprintf(mOutput, "<close container=\"%s\">\n", aKind);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
|
||||
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsAutoString tmp;
|
||||
PRInt32 ac = aNode.GetAttributeCount();
|
||||
for (PRInt32 i = 0; i < ac; i++) {
|
||||
char* key=nsnull;
|
||||
char* value=nsnull;
|
||||
const nsAReadableString& k = aNode.GetKeyAt(i);
|
||||
const nsString& v = aNode.GetValueAt(i);
|
||||
|
||||
GetNewCString(k, &key);
|
||||
if(key) {
|
||||
PR_fprintf(mOutput, " <attr key=\"%s\" value=\"", key);
|
||||
nsMemory::Free(key);
|
||||
}
|
||||
|
||||
tmp.Truncate();
|
||||
tmp.Append(v);
|
||||
if(tmp.Length() > 0) {
|
||||
PRUnichar first = tmp.First();
|
||||
if ((first == '"') || (first == '\'')) {
|
||||
if (tmp.Last() == first) {
|
||||
tmp.Cut(0, 1);
|
||||
PRInt32 pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
} else {
|
||||
// Mismatched quotes - leave them in
|
||||
}
|
||||
}
|
||||
GetNewCString(tmp, &value);
|
||||
|
||||
if(value) {
|
||||
PR_fprintf(mOutput, "%s\"/>\n", value);
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsMemory::Free(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
char* content;
|
||||
GetNewCString(aNode.GetSkippedContent(), &content);
|
||||
if(content) {
|
||||
PR_fprintf(mOutput, " <content value=\"");
|
||||
PR_fprintf(mOutput, "%s\"/>\n", content) ;
|
||||
nsMemory::Free(content);
|
||||
}
|
||||
}
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode)
|
||||
{
|
||||
PRInt32 ac = aNode.GetAttributeCount();
|
||||
if (0 != ac) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
const nsString& content = aNode.GetSkippedContent();
|
||||
if (content.Length() > 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::LeafNode(const nsIParserNode& aNode)
|
||||
{
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
|
||||
if(tag)
|
||||
PR_fprintf(mOutput, "<leaf tag=\"%s\"", tag);
|
||||
else PR_fprintf(mOutput, "<leaf tag=\"???\"");
|
||||
|
||||
if (WillWriteAttributes(aNode)) {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
WriteAttributes(aNode);
|
||||
PR_fprintf(mOutput, "</leaf>\n");
|
||||
}
|
||||
else {
|
||||
PR_fprintf(mOutput, "/>\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRInt32 pos;
|
||||
nsAutoString tmp;
|
||||
char* str;
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
GetNewCString(aNode.GetText(), &str);
|
||||
if(str) {
|
||||
PR_fprintf(mOutput, "<text value=\"%s\"/>\n", str);
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_newline:
|
||||
PR_fprintf(mOutput, "<newline/>\n");
|
||||
break;
|
||||
|
||||
case eHTMLTag_entity:
|
||||
tmp.Append(aNode.GetText());
|
||||
tmp.Cut(0, 1);
|
||||
pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
PR_fprintf(mOutput, "<entity value=\"%s\"/>\n", tmp.GetBuffer());
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("unsupported leaf node type");
|
||||
}//switch
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
|
||||
aResult.Truncate();
|
||||
/*
|
||||
if you're stepping through the string anyway, why not use iterators instead of forcing the string to copy?
|
||||
*/
|
||||
nsPromiseFlatString flat(aValue);
|
||||
const PRUnichar* cp = flat.get();
|
||||
const PRUnichar* end = cp + aValue.Length();
|
||||
while (cp < end) {
|
||||
PRUnichar ch = *cp++;
|
||||
if (ch == '"') {
|
||||
aResult.AppendWithConversion(""");
|
||||
}
|
||||
else if (ch == '&') {
|
||||
aResult.AppendWithConversion("&");
|
||||
}
|
||||
else if ((ch < 32) || (ch >= 127)) {
|
||||
aResult.AppendWithConversion("&#");
|
||||
aResult.AppendInt(PRInt32(ch), 10);
|
||||
aResult.AppendWithConversion(';');
|
||||
}
|
||||
else {
|
||||
aResult.Append(ch);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to convert nsString to char*.
|
||||
* REMEMBER: Match this call with nsMemory::Free(aResult);
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aValue - The string value
|
||||
* @param aResult - String coverted to char*.
|
||||
*/
|
||||
nsresult
|
||||
nsLoggingSink::GetNewCString(const nsAReadableString& aValue, char** aResult)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
nsAutoString temp;
|
||||
result=QuoteText(aValue,temp);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(temp.Length()>0) {
|
||||
*aResult=temp.ToNewCString();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::DoFragment(PRBool aFlag)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when handling illegal contents, especially
|
||||
* in dealing with tables. This method creates a new context.
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aPosition - The position from where the new context begins.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::BeginContext(PRInt32 aPosition)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method terminates any new context that got created by
|
||||
* BeginContext and switches back to the main context.
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aPosition - Validates the end of a context.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::EndContext(PRInt32 aPosition)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
1146
mozilla/layout/html/document/src/nsFrameFrame.cpp
Normal file
1146
mozilla/layout/html/document/src/nsFrameFrame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3237
mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp
Normal file
3237
mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
411
mozilla/layout/xul/base/src/nsBoxObject.cpp
Normal file
411
mozilla/layout/xul/base/src/nsBoxObject.cpp
Normal file
@@ -0,0 +1,411 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsBoxObject.h"
|
||||
#include "nsIBoxLayoutManager.h"
|
||||
#include "nsIBoxPaintManager.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
// Implementation /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Static member variable initialization
|
||||
|
||||
// Implement our nsISupports methods
|
||||
NS_IMPL_ISUPPORTS3(nsBoxObject, nsIBoxObject, nsPIBoxObject, nsISecurityCheckedComponent)
|
||||
|
||||
// Constructors/Destructors
|
||||
nsBoxObject::nsBoxObject(void)
|
||||
:mContent(nsnull), mPresShell(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsBoxObject::~nsBoxObject(void)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetLayoutManager(nsIBoxLayoutManager** aResult)
|
||||
{
|
||||
*aResult = mLayoutManager;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::SetLayoutManager(nsIBoxLayoutManager* aLayoutManager)
|
||||
{
|
||||
mLayoutManager = aLayoutManager;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetPaintManager(nsIBoxPaintManager** aResult)
|
||||
{
|
||||
*aResult = mPaintManager;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::SetPaintManager(nsIBoxPaintManager* aPaintManager)
|
||||
{
|
||||
mPaintManager = aPaintManager;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsPIBoxObject //////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::Init(nsIContent* aContent, nsIPresShell* aShell)
|
||||
{
|
||||
mContent = aContent;
|
||||
mPresShell = aShell;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::SetDocument(nsIDocument* aDocument)
|
||||
{
|
||||
mPresState = nsnull;
|
||||
if (aDocument) {
|
||||
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(aDocument->GetShellAt(0));
|
||||
mPresShell = shell;
|
||||
}
|
||||
else {
|
||||
mPresShell = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBoxObject::GetFrame()
|
||||
{
|
||||
nsIFrame* frame = nsnull;
|
||||
if (mPresShell)
|
||||
mPresShell->GetPrimaryFrameFor(mContent, &frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBoxObject::GetOffsetRect(nsRect& aRect)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
|
||||
aRect.x = aRect.y = 0;
|
||||
aRect.Empty();
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
mContent->GetDocument(*getter_AddRefs(doc));
|
||||
|
||||
if (doc) {
|
||||
// Get Presentation shell 0
|
||||
nsCOMPtr<nsIPresShell> presShell = getter_AddRefs(doc->GetShellAt(0));
|
||||
|
||||
if(presShell) {
|
||||
// Flush all pending notifications so that our frames are uptodate
|
||||
presShell->FlushPendingNotifications();
|
||||
|
||||
// Get the Frame for our content
|
||||
nsIFrame* frame = nsnull;
|
||||
presShell->GetPrimaryFrameFor(mContent, &frame);
|
||||
if(frame != nsnull) {
|
||||
// Get its origin
|
||||
nsPoint origin;
|
||||
frame->GetOrigin(origin);
|
||||
|
||||
// Get the union of all rectangles in this and continuation frames
|
||||
nsRect rcFrame;
|
||||
nsIFrame* next = frame;
|
||||
do {
|
||||
nsRect rect;
|
||||
next->GetRect(rect);
|
||||
rcFrame.UnionRect(rcFrame, rect);
|
||||
next->GetNextInFlow(&next);
|
||||
} while (nsnull != next);
|
||||
|
||||
|
||||
// Find the frame parent whose content's tagName either matches
|
||||
// the tagName passed in or is the document element.
|
||||
nsCOMPtr<nsIContent> docElement = getter_AddRefs(doc->GetRootContent());
|
||||
nsIFrame* parent = frame;
|
||||
nsCOMPtr<nsIContent> parentContent;
|
||||
frame->GetParent(&parent);
|
||||
while (parent) {
|
||||
parent->GetContent(getter_AddRefs(parentContent));
|
||||
if (parentContent) {
|
||||
// If we've hit the document element, break here
|
||||
if (parentContent.get() == docElement.get()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the parent's origin to our own to get to the
|
||||
// right coordinate system
|
||||
nsPoint parentOrigin;
|
||||
parent->GetOrigin(parentOrigin);
|
||||
origin += parentOrigin;
|
||||
|
||||
parent->GetParent(&parent);
|
||||
}
|
||||
|
||||
// For the origin, add in the border for the frame
|
||||
const nsStyleBorder* border;
|
||||
nsStyleCoord coord;
|
||||
frame->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border);
|
||||
if (border) {
|
||||
if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
|
||||
origin.x += border->mBorder.GetLeft(coord).GetCoordValue();
|
||||
}
|
||||
if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
|
||||
origin.y += border->mBorder.GetTop(coord).GetCoordValue();
|
||||
}
|
||||
}
|
||||
|
||||
// And subtract out the border for the parent
|
||||
if (parent) {
|
||||
const nsStyleBorder* parentBorder;
|
||||
parent->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)parentBorder);
|
||||
if (parentBorder) {
|
||||
if (eStyleUnit_Coord == parentBorder->mBorder.GetLeftUnit()) {
|
||||
origin.x -= parentBorder->mBorder.GetLeft(coord).GetCoordValue();
|
||||
}
|
||||
if (eStyleUnit_Coord == parentBorder->mBorder.GetTopUnit()) {
|
||||
origin.y -= parentBorder->mBorder.GetTop(coord).GetCoordValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the Presentation Context from the Shell
|
||||
nsCOMPtr<nsIPresContext> context;
|
||||
presShell->GetPresContext(getter_AddRefs(context));
|
||||
|
||||
if(context) {
|
||||
// Get the scale from that Presentation Context
|
||||
float scale;
|
||||
context->GetTwipsToPixels(&scale);
|
||||
|
||||
// Convert to pixels using that scale
|
||||
aRect.x = NSTwipsToIntPixels(origin.x, scale);
|
||||
aRect.y = NSTwipsToIntPixels(origin.y, scale);
|
||||
aRect.width = NSTwipsToIntPixels(rcFrame.width, scale);
|
||||
aRect.height = NSTwipsToIntPixels(rcFrame.height, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetX(PRInt32* aResult)
|
||||
{
|
||||
nsRect rect;
|
||||
GetOffsetRect(rect);
|
||||
*aResult = rect.x;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetY(PRInt32* aResult)
|
||||
{
|
||||
nsRect rect;
|
||||
GetOffsetRect(rect);
|
||||
*aResult = rect.y;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetWidth(PRInt32* aResult)
|
||||
{
|
||||
nsRect rect;
|
||||
GetOffsetRect(rect);
|
||||
*aResult = rect.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetHeight(PRInt32* aResult)
|
||||
{
|
||||
nsRect rect;
|
||||
GetOffsetRect(rect);
|
||||
*aResult = rect.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetLookAndFeelMetric(const PRUnichar* aPropertyName,
|
||||
PRUnichar** aResult)
|
||||
{
|
||||
nsCOMPtr<nsILookAndFeel> lookAndFeel(do_GetService(kLookAndFeelCID));
|
||||
if (!lookAndFeel)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString property(aPropertyName);
|
||||
if (property.EqualsIgnoreCase("scrollbarStyle")) {
|
||||
PRInt32 metricResult;
|
||||
lookAndFeel->GetMetric(nsILookAndFeel::eMetric_ScrollArrowStyle, metricResult);
|
||||
switch (metricResult) {
|
||||
case nsILookAndFeel::eMetric_ScrollArrowStyleBothAtBottom:
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("doublebottom").get());
|
||||
break;
|
||||
case nsILookAndFeel::eMetric_ScrollArrowStyleBothAtEachEnd:
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("double").get());
|
||||
break;
|
||||
case nsILookAndFeel::eMetric_ScrollArrowStyleBothAtTop:
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("doubletop").get());
|
||||
break;
|
||||
default:
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("single").get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (property.EqualsIgnoreCase("thumbStyle")) {
|
||||
PRInt32 metricResult;
|
||||
lookAndFeel->GetMetric(nsILookAndFeel::eMetric_ScrollSliderStyle, metricResult);
|
||||
if ( metricResult == nsILookAndFeel::eMetric_ScrollThumbStyleNormal )
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("fixed").get());
|
||||
else
|
||||
*aResult = nsXPIDLString::Copy(NS_LITERAL_STRING("proportional").get());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports** aResult)
|
||||
{
|
||||
if (!mPresState) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString propertyName(aPropertyName);
|
||||
return mPresState->GetStatePropertyAsSupports(propertyName, aResult); // Addref here.
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::SetPropertyAsSupports(const PRUnichar* aPropertyName, nsISupports* aValue)
|
||||
{
|
||||
if (!mPresState)
|
||||
NS_NewPresState(getter_AddRefs(mPresState));
|
||||
|
||||
nsAutoString propertyName(aPropertyName);
|
||||
return mPresState->SetStatePropertyAsSupports(propertyName, aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::GetProperty(const PRUnichar* aPropertyName, PRUnichar** aResult)
|
||||
{
|
||||
if (!mPresState) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString propertyName(aPropertyName);
|
||||
nsAutoString result;
|
||||
nsresult rv = mPresState->GetStateProperty(propertyName, result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
*aResult = nsXPIDLString::Copy(result.GetUnicode());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::SetProperty(const PRUnichar* aPropertyName, const PRUnichar* aPropertyValue)
|
||||
{
|
||||
if (!mPresState)
|
||||
NS_NewPresState(getter_AddRefs(mPresState));
|
||||
|
||||
nsAutoString propertyName(aPropertyName);
|
||||
nsAutoString propertyValue(aPropertyValue);
|
||||
return mPresState->SetStateProperty(propertyName, propertyValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBoxObject::RemoveProperty(const PRUnichar* aPropertyName)
|
||||
{
|
||||
if (!mPresState)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString propertyName(aPropertyName);
|
||||
return mPresState->RemoveStateProperty(propertyName);
|
||||
}
|
||||
|
||||
/* string canCreateWrapper (in nsIIDPtr iid); */
|
||||
NS_IMETHODIMP nsBoxObject::CanCreateWrapper(const nsIID * iid, char **_retval)
|
||||
{
|
||||
nsCAutoString str("AllAccess");
|
||||
*_retval = str.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
|
||||
NS_IMETHODIMP nsBoxObject::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
|
||||
{
|
||||
nsCAutoString str("AllAccess");
|
||||
*_retval = str.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
|
||||
NS_IMETHODIMP nsBoxObject::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
|
||||
{
|
||||
nsCAutoString str("AllAccess");
|
||||
*_retval = str.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
|
||||
NS_IMETHODIMP nsBoxObject::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
|
||||
{
|
||||
nsCAutoString str("AllAccess");
|
||||
*_retval = str.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewBoxObject(nsIBoxObject** aResult)
|
||||
{
|
||||
*aResult = new nsBoxObject;
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
1227
mozilla/mailnews/base/util/nsMsgIncomingServer.cpp
Normal file
1227
mozilla/mailnews/base/util/nsMsgIncomingServer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
585
mozilla/mailnews/import/src/nsImportFieldMap.cpp
Normal file
585
mozilla/mailnews/import/src/nsImportFieldMap.cpp
Normal file
@@ -0,0 +1,585 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsImportFieldMap.h"
|
||||
#include "nsImportStringBundle.h"
|
||||
|
||||
#include "ImportDebug.h"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
NS_METHOD nsImportFieldMap::Create( nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsImportFieldMap *it = new nsImportFieldMap();
|
||||
if (it == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF( it);
|
||||
nsresult rv = it->QueryInterface( aIID, aResult);
|
||||
NS_RELEASE( it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsImportFieldMap, nsIImportFieldMap)
|
||||
|
||||
nsImportFieldMap::nsImportFieldMap()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
m_numFields = 0;
|
||||
m_pFields = nsnull;
|
||||
m_pActive = nsnull;
|
||||
m_allocated = 0;
|
||||
// need to init the description array
|
||||
m_mozFieldCount = 0;
|
||||
nsIStringBundle *pBundle = nsImportStringBundle::GetStringBundleProxy();
|
||||
|
||||
nsString *pStr;
|
||||
for (PRInt32 i = IMPORT_FIELD_DESC_START; i <= IMPORT_FIELD_DESC_END; i++, m_mozFieldCount++) {
|
||||
pStr = new nsString();
|
||||
if (pBundle) {
|
||||
nsImportStringBundle::GetStringByID( i, *pStr, pBundle);
|
||||
}
|
||||
else
|
||||
pStr->AppendInt( i);
|
||||
m_descriptions.AppendElement( (void *)pStr);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE( pBundle);
|
||||
}
|
||||
|
||||
nsImportFieldMap::~nsImportFieldMap()
|
||||
{
|
||||
if (m_pFields)
|
||||
delete [] m_pFields;
|
||||
if (m_pActive)
|
||||
delete [] m_pActive;
|
||||
|
||||
nsString * pStr;
|
||||
for (PRInt32 i = 0; i < m_mozFieldCount; i++) {
|
||||
pStr = (nsString *) m_descriptions.ElementAt( i);
|
||||
delete pStr;
|
||||
}
|
||||
m_descriptions.Clear();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetNumMozFields(PRInt32 *aNumFields)
|
||||
{
|
||||
NS_PRECONDITION(aNumFields != nsnull, "null ptr");
|
||||
if (!aNumFields)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aNumFields = m_mozFieldCount;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetMapSize(PRInt32 *aNumFields)
|
||||
{
|
||||
NS_PRECONDITION(aNumFields != nsnull, "null ptr");
|
||||
if (!aNumFields)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aNumFields = m_numFields;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldDescription(PRInt32 index, PRUnichar **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*_retval = nsnull;
|
||||
if ((index < 0) || (index >= m_descriptions.Count()))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
*_retval = ((nsString *)m_descriptions.ElementAt( index))->ToNewUnicode();
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldMapSize(PRInt32 size)
|
||||
{
|
||||
nsresult rv = Allocate( size);
|
||||
if (NS_FAILED( rv))
|
||||
return( rv);
|
||||
|
||||
m_numFields = size;
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::DefaultFieldMap(PRInt32 size)
|
||||
{
|
||||
nsresult rv = SetFieldMapSize( size);
|
||||
if (NS_FAILED( rv))
|
||||
return( rv);
|
||||
for (PRInt32 i = 0; i < size; i++) {
|
||||
m_pFields[i] = i;
|
||||
m_pActive[i] = PR_TRUE;
|
||||
}
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldMap(PRInt32 index, PRInt32 *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
if (!_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
*_retval = m_pFields[index];
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldMap(PRInt32 index, PRInt32 fieldNum)
|
||||
{
|
||||
if (index == -1) {
|
||||
nsresult rv = Allocate( m_numFields + 1);
|
||||
if (NS_FAILED( rv))
|
||||
return( rv);
|
||||
index = m_numFields;
|
||||
m_numFields++;
|
||||
}
|
||||
else {
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return( NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if ((fieldNum != -1) && ((fieldNum < 0) || (fieldNum >= m_mozFieldCount)))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
m_pFields[index] = fieldNum;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldMapByDescription(PRInt32 index, const PRUnichar *fieldDesc)
|
||||
{
|
||||
NS_PRECONDITION(fieldDesc != nsnull, "null ptr");
|
||||
if (!fieldDesc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRInt32 i = FindFieldNum( fieldDesc);
|
||||
if (i == -1)
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
return( SetFieldMap( index, i));
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldActive(PRInt32 index, PRBool *active)
|
||||
{
|
||||
NS_PRECONDITION(active != nsnull, "null ptr");
|
||||
if (!active)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
*active = m_pActive[index];
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldActive(PRInt32 index, PRBool active)
|
||||
{
|
||||
if ((index < 0) || (index >= m_numFields))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
m_pActive[index] = active;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldValue(nsIAddrDatabase *database, nsIMdbRow *row, PRInt32 fieldNum, const PRUnichar *value)
|
||||
{
|
||||
NS_PRECONDITION(database != nsnull, "null ptr");
|
||||
NS_PRECONDITION(row != nsnull, "null ptr");
|
||||
NS_PRECONDITION(value != nsnull, "null ptr");
|
||||
if (!database || !row || !value)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Allow the special value for a null field
|
||||
if (fieldNum == -1)
|
||||
return( NS_OK);
|
||||
|
||||
if ((fieldNum < 0) || (fieldNum >= m_mozFieldCount))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
// UGGG!!!!! lot's of typing here!
|
||||
nsresult rv;
|
||||
|
||||
nsString str(value);
|
||||
char *pVal = str.ToNewUTF8String();
|
||||
|
||||
switch( fieldNum) {
|
||||
case 0:
|
||||
rv = database->AddFirstName( row, pVal);
|
||||
break;
|
||||
case 1:
|
||||
rv = database->AddLastName( row, pVal);
|
||||
break;
|
||||
case 2:
|
||||
rv = database->AddDisplayName( row, pVal);
|
||||
break;
|
||||
case 3:
|
||||
rv = database->AddNickName( row, pVal);
|
||||
break;
|
||||
case 4:
|
||||
rv = database->AddPrimaryEmail( row, pVal);
|
||||
break;
|
||||
case 5:
|
||||
rv = database->Add2ndEmail( row, pVal);
|
||||
break;
|
||||
case 6:
|
||||
rv = database->AddWorkPhone( row, pVal);
|
||||
break;
|
||||
case 7:
|
||||
rv = database->AddHomePhone( row, pVal);
|
||||
break;
|
||||
case 8:
|
||||
rv = database->AddFaxNumber( row, pVal);
|
||||
break;
|
||||
case 9:
|
||||
rv = database->AddPagerNumber( row, pVal);
|
||||
break;
|
||||
case 10:
|
||||
rv = database->AddCellularNumber( row, pVal);
|
||||
break;
|
||||
case 11:
|
||||
rv = database->AddHomeAddress( row, pVal);
|
||||
break;
|
||||
case 12:
|
||||
rv = database->AddHomeAddress2( row, pVal);
|
||||
break;
|
||||
case 13:
|
||||
rv = database->AddHomeCity( row, pVal);
|
||||
break;
|
||||
case 14:
|
||||
rv = database->AddHomeState( row, pVal);
|
||||
break;
|
||||
case 15:
|
||||
rv = database->AddHomeZipCode( row, pVal);
|
||||
break;
|
||||
case 16:
|
||||
rv = database->AddHomeCountry( row, pVal);
|
||||
break;
|
||||
case 17:
|
||||
rv = database->AddWorkAddress( row, pVal);
|
||||
break;
|
||||
case 18:
|
||||
rv = database->AddWorkAddress2( row, pVal);
|
||||
break;
|
||||
case 19:
|
||||
rv = database->AddWorkCity( row, pVal);
|
||||
break;
|
||||
case 20:
|
||||
rv = database->AddWorkState( row, pVal);
|
||||
break;
|
||||
case 21:
|
||||
rv = database->AddWorkZipCode( row, pVal);
|
||||
break;
|
||||
case 22:
|
||||
rv = database->AddWorkCountry( row, pVal);
|
||||
break;
|
||||
case 23:
|
||||
rv = database->AddJobTitle(row, pVal);
|
||||
break;
|
||||
case 24:
|
||||
rv = database->AddDepartment(row, pVal);
|
||||
break;
|
||||
case 25:
|
||||
rv = database->AddCompany(row, pVal);
|
||||
break;
|
||||
case 26:
|
||||
rv = database->AddWebPage1(row, pVal);
|
||||
break;
|
||||
case 27:
|
||||
rv = database->AddWebPage2(row, pVal);
|
||||
break;
|
||||
case 28:
|
||||
rv = database->AddBirthYear(row, pVal);
|
||||
break;
|
||||
case 29:
|
||||
rv = database->AddBirthMonth(row, pVal);
|
||||
break;
|
||||
case 30:
|
||||
rv = database->AddBirthDay(row, pVal);
|
||||
break;
|
||||
case 31:
|
||||
rv = database->AddCustom1(row, pVal);
|
||||
break;
|
||||
case 32:
|
||||
rv = database->AddCustom2(row, pVal);
|
||||
break;
|
||||
case 33:
|
||||
rv = database->AddCustom3(row, pVal);
|
||||
break;
|
||||
case 34:
|
||||
rv = database->AddCustom4(row, pVal);
|
||||
break;
|
||||
case 35:
|
||||
rv = database->AddNotes(row, pVal);
|
||||
break;
|
||||
default:
|
||||
/* Get the field description, and add it as an anonymous attr? */
|
||||
/* OR WHAT???? */
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCRT::free( pVal);
|
||||
|
||||
return( rv);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::SetFieldValueByDescription(nsIAddrDatabase *database, nsIMdbRow *row, const PRUnichar *fieldDesc, const PRUnichar *value)
|
||||
{
|
||||
NS_PRECONDITION(fieldDesc != nsnull, "null ptr");
|
||||
if (!fieldDesc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
PRInt32 i = FindFieldNum( fieldDesc);
|
||||
if (i == -1)
|
||||
return( NS_ERROR_FAILURE);
|
||||
return( SetFieldValue( database, row, i, value));
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldValue(nsIAbCard *card, PRInt32 fieldNum, PRUnichar **_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
NS_PRECONDITION(card != nsnull, "null ptr");
|
||||
if (!_retval || !card)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (fieldNum == -1) {
|
||||
PRUnichar c = 0;
|
||||
*_retval = nsCRT::strdup( &c);
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
if ((fieldNum < 0) || (fieldNum >= m_mozFieldCount))
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
// ARRGGG!!! Lots of typing again
|
||||
// get the field from the card
|
||||
nsresult rv;
|
||||
PRUnichar * pVal = nsnull;
|
||||
|
||||
switch (fieldNum) {
|
||||
case 0:
|
||||
rv = card->GetFirstName( &pVal);
|
||||
break;
|
||||
case 1:
|
||||
rv = card->GetLastName( &pVal);
|
||||
break;
|
||||
case 2:
|
||||
rv = card->GetDisplayName( &pVal);
|
||||
break;
|
||||
case 3:
|
||||
rv = card->GetNickName( &pVal);
|
||||
break;
|
||||
case 4:
|
||||
rv = card->GetPrimaryEmail( &pVal);
|
||||
break;
|
||||
case 5:
|
||||
rv = card->GetSecondEmail( &pVal);
|
||||
break;
|
||||
case 6:
|
||||
rv = card->GetWorkPhone( &pVal);
|
||||
break;
|
||||
case 7:
|
||||
rv = card->GetHomePhone( &pVal);
|
||||
break;
|
||||
case 8:
|
||||
rv = card->GetFaxNumber( &pVal);
|
||||
break;
|
||||
case 9:
|
||||
rv = card->GetPagerNumber( &pVal);
|
||||
break;
|
||||
case 10:
|
||||
rv = card->GetCellularNumber( &pVal);
|
||||
break;
|
||||
case 11:
|
||||
rv = card->GetHomeAddress( &pVal);
|
||||
break;
|
||||
case 12:
|
||||
rv = card->GetHomeAddress2( &pVal);
|
||||
break;
|
||||
case 13:
|
||||
rv = card->GetHomeCity( &pVal);
|
||||
break;
|
||||
case 14:
|
||||
rv = card->GetHomeState( &pVal);
|
||||
break;
|
||||
case 15:
|
||||
rv = card->GetHomeZipCode( &pVal);
|
||||
break;
|
||||
case 16:
|
||||
rv = card->GetHomeCountry( &pVal);
|
||||
break;
|
||||
case 17:
|
||||
rv = card->GetWorkAddress( &pVal);
|
||||
break;
|
||||
case 18:
|
||||
rv = card->GetWorkAddress2( &pVal);
|
||||
break;
|
||||
case 19:
|
||||
rv = card->GetWorkCity( &pVal);
|
||||
break;
|
||||
case 20:
|
||||
rv = card->GetWorkState( &pVal);
|
||||
break;
|
||||
case 21:
|
||||
rv = card->GetWorkZipCode( &pVal);
|
||||
break;
|
||||
case 22:
|
||||
rv = card->GetWorkCountry( &pVal);
|
||||
break;
|
||||
case 23:
|
||||
rv = card->GetJobTitle( &pVal);
|
||||
break;
|
||||
case 24:
|
||||
rv = card->GetDepartment( &pVal);
|
||||
break;
|
||||
case 25:
|
||||
rv = card->GetCompany( &pVal);
|
||||
break;
|
||||
case 26:
|
||||
rv = card->GetWebPage1( &pVal);
|
||||
break;
|
||||
case 27:
|
||||
rv = card->GetWebPage2( &pVal);
|
||||
break;
|
||||
case 28:
|
||||
rv = card->GetBirthYear( &pVal);
|
||||
break;
|
||||
case 29:
|
||||
rv = card->GetBirthMonth( &pVal);
|
||||
break;
|
||||
case 30:
|
||||
rv = card->GetBirthDay( &pVal);
|
||||
break;
|
||||
case 31:
|
||||
rv = card->GetCustom1( &pVal);
|
||||
break;
|
||||
case 32:
|
||||
rv = card->GetCustom2( &pVal);
|
||||
break;
|
||||
case 33:
|
||||
rv = card->GetCustom3( &pVal);
|
||||
break;
|
||||
case 34:
|
||||
rv = card->GetCustom4( &pVal);
|
||||
break;
|
||||
case 35:
|
||||
rv = card->GetNotes( &pVal);
|
||||
break;
|
||||
default:
|
||||
/* Get the field description, and add it as an anonymous attr? */
|
||||
/* OR WHAT???? */
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*_retval = pVal;
|
||||
|
||||
return( rv);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImportFieldMap::GetFieldValueByDescription(nsIAbCard *card, const PRUnichar *fieldDesc, PRUnichar **_retval)
|
||||
{
|
||||
NS_PRECONDITION(fieldDesc != nsnull, "null ptr");
|
||||
if (!fieldDesc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
PRInt32 i = FindFieldNum( fieldDesc);
|
||||
if (i == -1)
|
||||
return( NS_ERROR_FAILURE);
|
||||
return( GetFieldValue( card, i, _retval));
|
||||
}
|
||||
|
||||
|
||||
nsresult nsImportFieldMap::Allocate( PRInt32 newSize)
|
||||
{
|
||||
if (newSize <= m_allocated)
|
||||
return( NS_OK);
|
||||
|
||||
PRInt32 sz = m_allocated;
|
||||
while (sz < newSize)
|
||||
sz += 30;
|
||||
|
||||
PRInt32 *pData = new PRInt32[ sz];
|
||||
if (!pData)
|
||||
return( NS_ERROR_FAILURE);
|
||||
PRBool *pActive = new PRBool[sz];
|
||||
if (!pActive)
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
PRInt32 i;
|
||||
for (i = 0; i < sz; i++) {
|
||||
pData[i] = -1;
|
||||
pActive[i] = PR_TRUE;
|
||||
}
|
||||
if (m_numFields) {
|
||||
for (i = 0; i < m_numFields; i++) {
|
||||
pData[i] = m_pFields[i];
|
||||
pActive[i] = m_pActive[i];
|
||||
}
|
||||
delete [] m_pFields;
|
||||
delete [] m_pActive;
|
||||
}
|
||||
m_allocated = sz;
|
||||
m_pFields = pData;
|
||||
m_pActive = pActive;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
PRInt32 nsImportFieldMap::FindFieldNum( const PRUnichar *pDesc)
|
||||
{
|
||||
nsString * pStr;
|
||||
for (PRInt32 i = 0; i < m_mozFieldCount; i++) {
|
||||
pStr = (nsString *)m_descriptions.ElementAt( i);
|
||||
if (!Compare(*pStr, nsAutoString(pDesc)))
|
||||
return( i);
|
||||
}
|
||||
|
||||
return( -1);
|
||||
}
|
||||
|
||||
|
||||
795
mozilla/mailnews/import/text/src/nsTextImport.cpp
Normal file
795
mozilla/mailnews/import/text/src/nsTextImport.cpp
Normal file
@@ -0,0 +1,795 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Text import addressbook interfaces
|
||||
|
||||
*/
|
||||
#include "nscore.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIImportService.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsTextImport.h"
|
||||
#include "nsIMemory.h"
|
||||
#include "nsIImportGeneric.h"
|
||||
#include "nsIImportAddressBooks.h"
|
||||
#include "nsIImportABDescriptor.h"
|
||||
#include "nsIImportFieldMap.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAddrDatabase.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsTextStringBundle.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsTextAddress.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsProxiedService.h"
|
||||
#include "TextDebugLog.h"
|
||||
|
||||
|
||||
static NS_DEFINE_CID(kImportServiceCID, NS_IMPORTSERVICE_CID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
|
||||
|
||||
class ImportAddressImpl : public nsIImportAddressBooks
|
||||
{
|
||||
public:
|
||||
ImportAddressImpl();
|
||||
virtual ~ImportAddressImpl();
|
||||
|
||||
static nsresult Create(nsIImportAddressBooks** aImport);
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIImportAddressBooks interface
|
||||
|
||||
/* PRBool GetSupportsMultiple (); */
|
||||
NS_IMETHOD GetSupportsMultiple(PRBool *_retval) { *_retval = PR_FALSE; return( NS_OK);}
|
||||
|
||||
/* PRBool GetAutoFind (out wstring description); */
|
||||
NS_IMETHOD GetAutoFind(PRUnichar **description, PRBool *_retval);
|
||||
|
||||
/* PRBool GetNeedsFieldMap (nsIFileSpec *location); */
|
||||
NS_IMETHOD GetNeedsFieldMap(nsIFileSpec *location, PRBool *_retval);
|
||||
|
||||
/* void GetDefaultLocation (out nsIFileSpec location, out boolean found, out boolean userVerify); */
|
||||
NS_IMETHOD GetDefaultLocation(nsIFileSpec **location, PRBool *found, PRBool *userVerify);
|
||||
|
||||
/* nsISupportsArray FindAddressBooks (in nsIFileSpec location); */
|
||||
NS_IMETHOD FindAddressBooks(nsIFileSpec *location, nsISupportsArray **_retval);
|
||||
|
||||
/* nsISupports InitFieldMap(nsIFileSpec location, nsIImportFieldMap fieldMap); */
|
||||
NS_IMETHOD InitFieldMap(nsIFileSpec *location, nsIImportFieldMap *fieldMap);
|
||||
|
||||
/* void ImportAddressBook (in nsIImportABDescriptor source, in nsISupports destination, in nsISupports fieldMap, out boolean fatalError); */
|
||||
NS_IMETHOD ImportAddressBook( nsIImportABDescriptor *source,
|
||||
nsIAddrDatabase * destination,
|
||||
nsIImportFieldMap * fieldMap,
|
||||
PRUnichar ** errorLog,
|
||||
PRUnichar ** successLog,
|
||||
PRBool * fatalError);
|
||||
|
||||
/* unsigned long GetImportProgress (); */
|
||||
NS_IMETHOD GetImportProgress(PRUint32 *_retval);
|
||||
|
||||
NS_IMETHOD GetSampleData( PRInt32 index, PRBool *pFound, PRUnichar **pStr);
|
||||
|
||||
NS_IMETHOD SetSampleLocation( nsIFileSpec *);
|
||||
|
||||
private:
|
||||
void ClearSampleFile( void);
|
||||
void SaveFieldMap( nsIImportFieldMap *pMap);
|
||||
|
||||
static void ReportSuccess( nsString& name, nsString *pStream);
|
||||
static void SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess);
|
||||
static void ReportError( PRInt32 errorNum, nsString& name, nsString *pStream);
|
||||
static void SanitizeSampleData( nsCString& val);
|
||||
|
||||
private:
|
||||
nsTextAddress m_text;
|
||||
PRBool m_haveDelim;
|
||||
nsIFileSpec * m_fileLoc;
|
||||
char m_delim;
|
||||
PRUint32 m_bytesImported;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
nsTextImport::nsTextImport()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
IMPORT_LOG0( "nsTextImport Module Created\n");
|
||||
|
||||
nsTextStringBundle::GetStringBundle();
|
||||
}
|
||||
|
||||
|
||||
nsTextImport::~nsTextImport()
|
||||
{
|
||||
|
||||
IMPORT_LOG0( "nsTextImport Module Deleted\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsTextImport, nsIImportModule)
|
||||
|
||||
|
||||
NS_IMETHODIMP nsTextImport::GetName( PRUnichar **name)
|
||||
{
|
||||
NS_PRECONDITION(name != nsnull, "null ptr");
|
||||
if (! name)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*name = nsTextStringBundle::GetStringByID( TEXTIMPORT_NAME);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextImport::GetDescription( PRUnichar **name)
|
||||
{
|
||||
NS_PRECONDITION(name != nsnull, "null ptr");
|
||||
if (! name)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*name = nsTextStringBundle::GetStringByID( TEXTIMPORT_DESCRIPTION);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextImport::GetSupports( char **supports)
|
||||
{
|
||||
NS_PRECONDITION(supports != nsnull, "null ptr");
|
||||
if (! supports)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*supports = nsCRT::strdup( kTextSupportsString);
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextImport::GetSupportsUpgrade( PRBool *pUpgrade)
|
||||
{
|
||||
NS_PRECONDITION(pUpgrade != nsnull, "null ptr");
|
||||
if (! pUpgrade)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*pUpgrade = PR_FALSE;
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsTextImport::GetImportInterface( const char *pImportType, nsISupports **ppInterface)
|
||||
{
|
||||
NS_PRECONDITION(pImportType != nsnull, "null ptr");
|
||||
if (! pImportType)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
NS_PRECONDITION(ppInterface != nsnull, "null ptr");
|
||||
if (! ppInterface)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*ppInterface = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
if (!nsCRT::strcmp( pImportType, "addressbook")) {
|
||||
// create the nsIImportMail interface and return it!
|
||||
nsIImportAddressBooks * pAddress = nsnull;
|
||||
nsIImportGeneric * pGeneric = nsnull;
|
||||
rv = ImportAddressImpl::Create( &pAddress);
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
rv = impSvc->CreateNewGenericAddressBooks( &pGeneric);
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
pGeneric->SetData( "addressInterface", pAddress);
|
||||
rv = pGeneric->QueryInterface( kISupportsIID, (void **)ppInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE( pAddress);
|
||||
NS_IF_RELEASE( pGeneric);
|
||||
return( rv);
|
||||
}
|
||||
|
||||
return( NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
nsresult ImportAddressImpl::Create(nsIImportAddressBooks** aImport)
|
||||
{
|
||||
NS_PRECONDITION(aImport != nsnull, "null ptr");
|
||||
if (! aImport)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aImport = new ImportAddressImpl();
|
||||
if (! *aImport)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aImport);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ImportAddressImpl::ImportAddressImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
m_fileLoc = nsnull;
|
||||
m_haveDelim = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ImportAddressImpl::~ImportAddressImpl()
|
||||
{
|
||||
if (m_fileLoc) {
|
||||
PRBool open = PR_FALSE;
|
||||
m_fileLoc->IsStreamOpen( &open);
|
||||
if (open)
|
||||
m_fileLoc->CloseStream();
|
||||
NS_RELEASE( m_fileLoc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(ImportAddressImpl, nsIImportAddressBooks)
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::GetAutoFind(PRUnichar **addrDescription, PRBool *_retval)
|
||||
{
|
||||
NS_PRECONDITION(addrDescription != nsnull, "null ptr");
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
if (! addrDescription || !_retval)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsString str;
|
||||
*_retval = PR_FALSE;
|
||||
nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_NAME, str);
|
||||
*addrDescription = str.ToNewUnicode();
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::GetDefaultLocation(nsIFileSpec **ppLoc, PRBool *found, PRBool *userVerify)
|
||||
{
|
||||
NS_PRECONDITION(found != nsnull, "null ptr");
|
||||
NS_PRECONDITION(ppLoc != nsnull, "null ptr");
|
||||
NS_PRECONDITION(userVerify != nsnull, "null ptr");
|
||||
if (! found || !userVerify || !ppLoc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*ppLoc = nsnull;
|
||||
*found = PR_FALSE;
|
||||
*userVerify = PR_TRUE;
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::FindAddressBooks(nsIFileSpec *pLoc, nsISupportsArray **ppArray)
|
||||
{
|
||||
NS_PRECONDITION(pLoc != nsnull, "null ptr");
|
||||
NS_PRECONDITION(ppArray != nsnull, "null ptr");
|
||||
if (!pLoc || !ppArray)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
ClearSampleFile();
|
||||
|
||||
*ppArray = nsnull;
|
||||
PRBool exists = PR_FALSE;
|
||||
nsresult rv = pLoc->Exists( &exists);
|
||||
if (NS_FAILED( rv) || !exists)
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
PRBool isFile = PR_FALSE;
|
||||
rv = pLoc->IsFile( &isFile);
|
||||
if (NS_FAILED( rv) || !isFile)
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
rv = m_text.DetermineDelim( pLoc);
|
||||
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "*** Error determining delimitter\n");
|
||||
return( rv);
|
||||
}
|
||||
m_haveDelim = PR_TRUE;
|
||||
m_delim = m_text.GetDelim();
|
||||
|
||||
m_fileLoc = pLoc;
|
||||
NS_ADDREF( m_fileLoc);
|
||||
|
||||
/* Build an address book descriptor based on the file passed in! */
|
||||
nsCOMPtr<nsISupportsArray> array;
|
||||
rv = NS_NewISupportsArray( getter_AddRefs( array));
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "FAILED to allocate the nsISupportsArray\n");
|
||||
return( rv);
|
||||
}
|
||||
|
||||
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "*** Failed to obtain the import service\n");
|
||||
return( rv);
|
||||
}
|
||||
|
||||
nsXPIDLCString pName;
|
||||
rv = pLoc->GetLeafName(getter_Copies(pName));
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "*** Failed getting leaf name of file\n");
|
||||
return( rv);
|
||||
}
|
||||
|
||||
// for get unicode leafname. If it uses nsILocalFile interface,
|
||||
// these codes do not need due to nsILocalFile->GetUnicodeLeafName()
|
||||
nsString name;
|
||||
rv = impSvc->SystemStringToUnicode((const char*) pName, name);
|
||||
if (NS_FAILED(rv))
|
||||
name.AssignWithConversion((const char*) pName);
|
||||
|
||||
PRInt32 idx = name.RFindChar( '.');
|
||||
if ((idx != -1) && (idx > 0) && ((name.Length() - idx - 1) < 5)) {
|
||||
nsString t;
|
||||
name.Left( t, idx);
|
||||
name = t;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIImportABDescriptor> desc;
|
||||
nsISupports * pInterface;
|
||||
|
||||
rv = impSvc->CreateNewABDescriptor( getter_AddRefs( desc));
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
PRUint32 sz = 0;
|
||||
pLoc->GetFileSize( &sz);
|
||||
desc->SetPreferredName( name.GetUnicode());
|
||||
desc->SetSize( sz);
|
||||
nsIFileSpec *pSpec = nsnull;
|
||||
desc->GetFileSpec( &pSpec);
|
||||
if (pSpec) {
|
||||
pSpec->FromFileSpec( pLoc);
|
||||
NS_RELEASE( pSpec);
|
||||
}
|
||||
rv = desc->QueryInterface( kISupportsIID, (void **) &pInterface);
|
||||
array->AppendElement( pInterface);
|
||||
pInterface->Release();
|
||||
}
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "*** Error creating address book descriptor for text import\n");
|
||||
}
|
||||
else {
|
||||
rv = array->QueryInterface( NS_GET_IID(nsISupportsArray), (void **) ppArray);
|
||||
}
|
||||
|
||||
return( rv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ImportAddressImpl::ReportSuccess( nsString& name, nsString *pStream)
|
||||
{
|
||||
if (!pStream)
|
||||
return;
|
||||
// load the success string
|
||||
nsIStringBundle *pBundle = nsTextStringBundle::GetStringBundleProxy();
|
||||
PRUnichar *pFmt = nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_SUCCESS, pBundle);
|
||||
PRUnichar *pText = nsTextFormatter::smprintf( pFmt, name.GetUnicode());
|
||||
pStream->Append( pText);
|
||||
nsTextFormatter::smprintf_free( pText);
|
||||
nsTextStringBundle::FreeString( pFmt);
|
||||
pStream->AppendWithConversion( LF);
|
||||
NS_IF_RELEASE( pBundle);
|
||||
}
|
||||
|
||||
void ImportAddressImpl::ReportError( PRInt32 errorNum, nsString& name, nsString *pStream)
|
||||
{
|
||||
if (!pStream)
|
||||
return;
|
||||
// load the error string
|
||||
nsIStringBundle *pBundle = nsTextStringBundle::GetStringBundleProxy();
|
||||
PRUnichar *pFmt = nsTextStringBundle::GetStringByID( errorNum, pBundle);
|
||||
PRUnichar *pText = nsTextFormatter::smprintf( pFmt, name.GetUnicode());
|
||||
pStream->Append( pText);
|
||||
nsTextFormatter::smprintf_free( pText);
|
||||
nsTextStringBundle::FreeString( pFmt);
|
||||
pStream->AppendWithConversion( LF);
|
||||
NS_IF_RELEASE( pBundle);
|
||||
}
|
||||
|
||||
void ImportAddressImpl::SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess)
|
||||
{
|
||||
if (pError)
|
||||
*pError = error.ToNewUnicode();
|
||||
if (pSuccess)
|
||||
*pSuccess = success.ToNewUnicode();
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::ImportAddressBook( nsIImportABDescriptor *pSource,
|
||||
nsIAddrDatabase * pDestination,
|
||||
nsIImportFieldMap * fieldMap,
|
||||
PRUnichar ** pErrorLog,
|
||||
PRUnichar ** pSuccessLog,
|
||||
PRBool * fatalError)
|
||||
{
|
||||
NS_PRECONDITION(pSource != nsnull, "null ptr");
|
||||
NS_PRECONDITION(pDestination != nsnull, "null ptr");
|
||||
NS_PRECONDITION(fatalError != nsnull, "null ptr");
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle( dont_AddRef( nsTextStringBundle::GetStringBundleProxy()));
|
||||
m_bytesImported = 0;
|
||||
|
||||
nsString success;
|
||||
nsString error;
|
||||
if (!pSource || !pDestination || !fatalError) {
|
||||
IMPORT_LOG0( "*** Bad param passed to text address import\n");
|
||||
nsTextStringBundle::GetStringByID( TEXTIMPORT_ADDRESS_BADPARAM, error, bundle);
|
||||
if (fatalError)
|
||||
*fatalError = PR_TRUE;
|
||||
SetLogs( success, error, pErrorLog, pSuccessLog);
|
||||
return( NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
ClearSampleFile();
|
||||
|
||||
PRBool addrAbort = PR_FALSE;
|
||||
nsString name;
|
||||
PRUnichar * pName;
|
||||
if (NS_SUCCEEDED( pSource->GetPreferredName( &pName))) {
|
||||
name = pName;
|
||||
nsCRT::free( pName);
|
||||
}
|
||||
|
||||
PRUint32 addressSize = 0;
|
||||
pSource->GetSize( &addressSize);
|
||||
if (addressSize == 0) {
|
||||
IMPORT_LOG0( "Address book size is 0, skipping import.\n");
|
||||
ReportSuccess( name, &success);
|
||||
SetLogs( success, error, pErrorLog, pSuccessLog);
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
nsIFileSpec * inFile;
|
||||
if (NS_FAILED( pSource->GetFileSpec( &inFile))) {
|
||||
ReportError( TEXTIMPORT_ADDRESS_BADSOURCEFILE, name, &error);
|
||||
SetLogs( success, error, pErrorLog, pSuccessLog);
|
||||
return( NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef IMPORT_DEBUG
|
||||
char *pPath;
|
||||
inFile->GetNativePath( &pPath);
|
||||
IMPORT_LOG1( "Import address book: %s\n", pPath);
|
||||
nsCRT::free( pPath);
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
PRBool isLDIF = PR_FALSE;
|
||||
rv = nsTextAddress::IsLDIFFile( inFile, &isLDIF);
|
||||
if (NS_FAILED( rv)) {
|
||||
inFile->Release();
|
||||
ReportError( TEXTIMPORT_ADDRESS_CONVERTERROR, name, &error);
|
||||
SetLogs( success, error, pErrorLog, pSuccessLog);
|
||||
return( rv);
|
||||
}
|
||||
|
||||
if (isLDIF) {
|
||||
// This get's tricky, the database really requires the thing
|
||||
// to have an .ldi extension so if it doesn't we may need to
|
||||
// copy the file to a temp file with the correct name, then
|
||||
// import it!
|
||||
rv = m_text.ImportLDIF( &addrAbort, name.GetUnicode(), inFile, pDestination, error);
|
||||
}
|
||||
else {
|
||||
rv = m_text.ImportAddresses( &addrAbort, name.GetUnicode(), inFile, pDestination, fieldMap, error, &m_bytesImported);
|
||||
SaveFieldMap( fieldMap);
|
||||
}
|
||||
|
||||
inFile->Release();
|
||||
|
||||
|
||||
if (NS_SUCCEEDED( rv) && error.IsEmpty()) {
|
||||
ReportSuccess( name, &success);
|
||||
}
|
||||
else {
|
||||
ReportError( TEXTIMPORT_ADDRESS_CONVERTERROR, name, &error);
|
||||
}
|
||||
|
||||
SetLogs( success, error, pErrorLog, pSuccessLog);
|
||||
|
||||
IMPORT_LOG0( "*** Text address import done\n");
|
||||
|
||||
return( rv);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::GetImportProgress(PRUint32 *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
if (!_retval)
|
||||
return( NS_ERROR_NULL_POINTER);
|
||||
|
||||
*_retval = m_bytesImported;
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::GetNeedsFieldMap(nsIFileSpec *location, PRBool *_retval)
|
||||
{
|
||||
NS_PRECONDITION(_retval != nsnull, "null ptr");
|
||||
NS_PRECONDITION(location != nsnull, "null ptr");
|
||||
if (!location || !_retval)
|
||||
return( NS_ERROR_NULL_POINTER);
|
||||
|
||||
*_retval = PR_TRUE;
|
||||
PRBool exists = PR_FALSE;
|
||||
PRBool isFile = PR_FALSE;
|
||||
|
||||
nsresult rv = location->Exists( &exists);
|
||||
rv = location->IsFile( &isFile);
|
||||
|
||||
if (!exists || !isFile)
|
||||
return( NS_ERROR_FAILURE);
|
||||
|
||||
PRBool isLDIF = PR_FALSE;
|
||||
rv = nsTextAddress::IsLDIFFile( location, &isLDIF);
|
||||
if (NS_FAILED( rv)) {
|
||||
IMPORT_LOG0( "*** Error determining if file is of type LDIF\n");
|
||||
return( rv);
|
||||
}
|
||||
|
||||
if (isLDIF)
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
void ImportAddressImpl::SanitizeSampleData( nsCString& val)
|
||||
{
|
||||
// remove any line-feeds...
|
||||
val.ReplaceSubstring( "\x0D\x0A", ", ");
|
||||
val.ReplaceChar( 13, ',');
|
||||
val.ReplaceChar( 10, ',');
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::GetSampleData( PRInt32 index, PRBool *pFound, PRUnichar **pStr)
|
||||
{
|
||||
NS_PRECONDITION(pFound != nsnull, "null ptr");
|
||||
NS_PRECONDITION(pStr != nsnull, "null ptr");
|
||||
if (!pFound || !pStr)
|
||||
return( NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (!m_fileLoc) {
|
||||
IMPORT_LOG0( "*** Error, called GetSampleData before SetSampleLocation\n");
|
||||
return( NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
*pStr = nsnull;
|
||||
PRBool open = PR_FALSE;
|
||||
PRUnichar term = 0;
|
||||
|
||||
if (!m_haveDelim) {
|
||||
rv = m_fileLoc->IsStreamOpen( &open);
|
||||
if (open) {
|
||||
m_fileLoc->CloseStream();
|
||||
open = PR_FALSE;
|
||||
}
|
||||
rv = m_text.DetermineDelim( m_fileLoc);
|
||||
if (NS_FAILED( rv))
|
||||
return( rv);
|
||||
m_haveDelim = PR_TRUE;
|
||||
m_delim = m_text.GetDelim();
|
||||
}
|
||||
else {
|
||||
rv = m_fileLoc->IsStreamOpen( &open);
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
rv = m_fileLoc->OpenStreamForReading();
|
||||
if (NS_FAILED( rv)) {
|
||||
*pFound = PR_FALSE;
|
||||
*pStr = nsCRT::strdup( &term);
|
||||
return( NS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 lineLen;
|
||||
PRInt32 bufSz = 10240;
|
||||
char *pLine = new char[bufSz];
|
||||
|
||||
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
|
||||
|
||||
rv = nsTextAddress::ReadRecordNumber( m_fileLoc, pLine, bufSz, m_delim, &lineLen, index);
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
nsString str;
|
||||
nsCString field;
|
||||
nsString uField;
|
||||
PRInt32 fNum = 0;
|
||||
while (nsTextAddress::GetField( pLine, lineLen, fNum, field, m_delim)) {
|
||||
if (fNum)
|
||||
str.AppendWithConversion( "\n");
|
||||
SanitizeSampleData( field);
|
||||
if (impSvc)
|
||||
impSvc->SystemStringToUnicode( field, uField);
|
||||
else
|
||||
uField.AssignWithConversion( field);
|
||||
|
||||
str.Append( uField);
|
||||
fNum++;
|
||||
field.Truncate();
|
||||
}
|
||||
|
||||
*pStr = nsCRT::strdup( str.GetUnicode());
|
||||
*pFound = PR_TRUE;
|
||||
|
||||
/* IMPORT_LOG1( "Sample data: %S\n", str.GetUnicode()); */
|
||||
}
|
||||
else {
|
||||
*pFound = PR_FALSE;
|
||||
*pStr = nsCRT::strdup( &term);
|
||||
}
|
||||
|
||||
delete [] pLine;
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::SetSampleLocation( nsIFileSpec *pLocation)
|
||||
{
|
||||
NS_IF_RELEASE( m_fileLoc);
|
||||
m_haveDelim = PR_FALSE;
|
||||
m_fileLoc = pLocation;
|
||||
NS_IF_ADDREF( m_fileLoc);
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
void ImportAddressImpl::ClearSampleFile( void)
|
||||
{
|
||||
if (m_fileLoc) {
|
||||
PRBool open = PR_FALSE;
|
||||
m_fileLoc->IsStreamOpen( &open);
|
||||
if (open)
|
||||
m_fileLoc->CloseStream();
|
||||
NS_RELEASE( m_fileLoc);
|
||||
m_fileLoc = nsnull;
|
||||
m_haveDelim = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP ImportAddressImpl::InitFieldMap(nsIFileSpec *location, nsIImportFieldMap *fieldMap)
|
||||
{
|
||||
// Let's remember the last one the user used!
|
||||
// This should be normal for someone importing multiple times, it's usually
|
||||
// from the same file format.
|
||||
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE( nsIPref, prefs, kPrefServiceCID, &rv);
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
nsXPIDLCString prefStr;
|
||||
rv = prefs->CopyCharPref( "mailnews.import.text.fieldmap", getter_Copies(prefStr));
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
const char *pStr = (const char *)prefStr;
|
||||
if (pStr) {
|
||||
fieldMap->SetFieldMapSize( 0);
|
||||
long fNum;
|
||||
PRBool active;
|
||||
long fIndex = 0;
|
||||
while (*pStr) {
|
||||
while (*pStr && (*pStr != '+') && (*pStr != '-'))
|
||||
pStr++;
|
||||
if (*pStr == '+')
|
||||
active = PR_TRUE;
|
||||
else if (*pStr == '-')
|
||||
active = PR_FALSE;
|
||||
else
|
||||
break;
|
||||
fNum = 0;
|
||||
while (*pStr && ((*pStr < '0') || (*pStr > '9')))
|
||||
pStr++;
|
||||
if (!(*pStr))
|
||||
break;
|
||||
while (*pStr && (*pStr >= '0') && (*pStr <= '9')) {
|
||||
fNum *= 10;
|
||||
fNum += (*pStr - '0');
|
||||
pStr++;
|
||||
}
|
||||
while (*pStr && (*pStr != ','))
|
||||
pStr++;
|
||||
if (*pStr == ',')
|
||||
pStr++;
|
||||
fieldMap->SetFieldMap( -1, fNum);
|
||||
fieldMap->SetFieldActive( fIndex, active);
|
||||
fIndex++;
|
||||
}
|
||||
if (!fIndex) {
|
||||
int num;
|
||||
fieldMap->GetNumMozFields( &num);
|
||||
fieldMap->DefaultFieldMap( num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( NS_OK);
|
||||
}
|
||||
|
||||
|
||||
void ImportAddressImpl::SaveFieldMap( nsIImportFieldMap *pMap)
|
||||
{
|
||||
if (!pMap)
|
||||
return;
|
||||
|
||||
int size;
|
||||
int index;
|
||||
PRBool active;
|
||||
nsCString str;
|
||||
|
||||
pMap->GetMapSize( &size);
|
||||
for (long i = 0; i < size; i++) {
|
||||
index = i;
|
||||
active = PR_FALSE;
|
||||
pMap->GetFieldMap( i, &index);
|
||||
pMap->GetFieldActive( i, &active);
|
||||
if (active)
|
||||
str.Append( '+');
|
||||
else
|
||||
str.Append( '-');
|
||||
|
||||
str.AppendInt( index);
|
||||
str.Append( ',');
|
||||
}
|
||||
|
||||
PRBool done = PR_FALSE;
|
||||
nsresult rv;
|
||||
// NS_WITH_PROXIED_SERVICE( nsIPref, prefs, kPrefServiceCID, NS_UI_THREAD_EVENTQ, &rv);
|
||||
NS_WITH_SERVICE( nsIPref, prefs, kPrefServiceCID, &rv);
|
||||
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
nsXPIDLCString prefStr;
|
||||
rv = prefs->CopyCharPref( "mailnews.import.text.fieldmap", getter_Copies(prefStr));
|
||||
if (NS_SUCCEEDED( rv)) {
|
||||
if (!Compare(str, nsCAutoString((const char *)prefStr)))
|
||||
done = PR_TRUE;
|
||||
}
|
||||
if (!done) {
|
||||
rv = prefs->SetCharPref( "mailnews.import.text.fieldmap", str);
|
||||
}
|
||||
}
|
||||
}
|
||||
1081
mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp
Normal file
1081
mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5552
mozilla/mailnews/news/src/nsNNTPProtocol.cpp
Normal file
5552
mozilla/mailnews/news/src/nsNNTPProtocol.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1966
mozilla/modules/libpref/src/nsPref.cpp
Normal file
1966
mozilla/modules/libpref/src/nsPref.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4252
mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp
Normal file
4252
mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4252
mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp
Normal file
4252
mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
501
mozilla/netwerk/base/src/nsIOService.cpp
Normal file
501
mozilla/netwerk/base/src/nsIOService.cpp
Normal file
@@ -0,0 +1,501 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIOService.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nscore.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIFileTransportService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "prprf.h"
|
||||
#include "nsLoadGroup.h"
|
||||
#include "nsInputStreamChannel.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIErrorService.h"
|
||||
#include "netCore.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
|
||||
static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsIOService::nsIOService()
|
||||
: mOffline(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIOService::Init()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Hold onto the eventQueue service. We do not want any eventqueues to go away
|
||||
// when we shutdown until we process all remaining transports
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mEventQueueService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
|
||||
|
||||
// We need to get references to these services so that we can shut them
|
||||
// down later. If we wait until the nsIOService is being shut down,
|
||||
// GetService will fail at that point.
|
||||
rv = nsServiceManager::GetService(kSocketTransportServiceCID,
|
||||
NS_GET_IID(nsISocketTransportService),
|
||||
getter_AddRefs(mSocketTransportService));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsServiceManager::GetService(kFileTransportService,
|
||||
NS_GET_IID(nsIFileTransportService),
|
||||
getter_AddRefs(mFileTransportService));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = nsServiceManager::GetService(kDNSServiceCID,
|
||||
NS_GET_IID(nsIDNSService),
|
||||
getter_AddRefs(mDNSService));
|
||||
|
||||
// XXX hack until xpidl supports error info directly (http://bugzilla.mozilla.org/show_bug.cgi?id=13423)
|
||||
nsCOMPtr<nsIErrorService> errorService = do_GetService(kErrorServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_READ_FROM, "ReadFrom");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_WROTE_TO, "WroteTo");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RESOLVING_HOST, "ResolvingHost");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTED_TO, "ConnectedTo");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_SENDING_TO, "SendingTo");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_RECEIVING_FROM, "ReceivingFrom");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = errorService->RegisterErrorStringBundleKey(NS_NET_STATUS_CONNECTING_TO, "ConnectingTo");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsIOService::~nsIOService()
|
||||
{
|
||||
(void)SetOffline(PR_TRUE);
|
||||
if (mFileTransportService)
|
||||
(void)mFileTransportService->Shutdown();
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsIOService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
static nsISupports *_rValue = nsnull;
|
||||
|
||||
nsresult rv;
|
||||
NS_ENSURE_NO_AGGREGATION(aOuter);
|
||||
|
||||
if (_rValue)
|
||||
{
|
||||
NS_ADDREF (_rValue);
|
||||
*aResult = _rValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIOService* _ios = new nsIOService();
|
||||
if (_ios == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(_ios);
|
||||
rv = _ios->Init();
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete _ios;
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = _ios->QueryInterface(aIID, aResult);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete _ios;
|
||||
return rv;
|
||||
}
|
||||
|
||||
_rValue = NS_STATIC_CAST (nsISupports*, *aResult);
|
||||
NS_RELEASE (_rValue);
|
||||
_rValue = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsIOService, nsIIOService);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_SCHEME_LENGTH 64 // XXX big enough?
|
||||
|
||||
#define MAX_NET_CONTRACTID_LENGTH (MAX_SCHEME_LENGTH + NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH + 1)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::CacheProtocolHandler(const char *scheme, nsIProtocolHandler *handler)
|
||||
{
|
||||
for (unsigned int i=0; i<NS_N(gScheme); i++)
|
||||
{
|
||||
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(!mWeakHandler[i], "Protocol handler already cached");
|
||||
// Make sure the handler supports weak references.
|
||||
nsCOMPtr<nsISupportsWeakReference> factoryPtr = do_QueryInterface(handler, &rv);
|
||||
if (!factoryPtr)
|
||||
{
|
||||
// Dont cache handlers that dont support weak reference as
|
||||
// there is real danger of a circular reference.
|
||||
#ifdef DEBUG_dp
|
||||
printf("DEBUG: %s protcol handler doesn't support weak ref. Not cached.\n", scheme);
|
||||
#endif /* DEBUG_dp */
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mWeakHandler[i] = getter_AddRefs(NS_GetWeakReference(handler));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::GetCachedProtocolHandler(const char *scheme, nsIProtocolHandler **result)
|
||||
{
|
||||
for (unsigned int i=0; i<NS_N(gScheme); i++)
|
||||
{
|
||||
if (!nsCRT::strcasecmp(scheme, gScheme[i]))
|
||||
if (mWeakHandler[i])
|
||||
{
|
||||
nsCOMPtr<nsIProtocolHandler> temp = do_QueryReferent(mWeakHandler[i]);
|
||||
if (temp)
|
||||
{
|
||||
*result = temp.get();
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::GetProtocolHandler(const char* scheme, nsIProtocolHandler* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH
|
||||
== nsCRT::strlen(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX),
|
||||
"need to fix NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX_LENGTH");
|
||||
|
||||
NS_ENSURE_ARG_POINTER(scheme);
|
||||
// XXX we may want to speed this up by introducing our own protocol
|
||||
// scheme -> protocol handler mapping, avoiding the string manipulation
|
||||
// and service manager stuff
|
||||
|
||||
rv = GetCachedProtocolHandler(scheme, result);
|
||||
if (NS_SUCCEEDED(rv)) return NS_OK;
|
||||
|
||||
char buf[MAX_NET_CONTRACTID_LENGTH];
|
||||
nsCAutoString contractID(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX);
|
||||
contractID += scheme;
|
||||
contractID.ToLowerCase();
|
||||
contractID.ToCString(buf, MAX_NET_CONTRACTID_LENGTH);
|
||||
|
||||
rv = nsServiceManager::GetService(buf, NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// okay we don't have a protocol handler to handle this url type, so use the default protocol handler.
|
||||
// this will cause urls to get dispatched out to the OS ('cause we can't do anything with them) when
|
||||
// we try to read from a channel created by the default protocol handler.
|
||||
|
||||
rv = nsServiceManager::GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", NS_GET_IID(nsIProtocolHandler), (nsISupports **)result);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_UNKNOWN_PROTOCOL;
|
||||
}
|
||||
|
||||
CacheProtocolHandler(scheme, *result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::ExtractScheme(const char* inURI, PRUint32 *startPos,
|
||||
PRUint32 *endPos, char* *scheme)
|
||||
{
|
||||
return ExtractURLScheme(inURI, startPos, endPos, scheme);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
|
||||
nsIURI* *result, nsIProtocolHandler* *hdlrResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIURI* base;
|
||||
NS_ENSURE_ARG_POINTER(aSpec);
|
||||
char* scheme;
|
||||
rv = ExtractScheme(aSpec, nsnull, nsnull, &scheme);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// then aSpec is absolute
|
||||
// ignore aBaseURI in this case
|
||||
base = nsnull;
|
||||
}
|
||||
else {
|
||||
// then aSpec is relative
|
||||
if (aBaseURI == nsnull)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
rv = aBaseURI->GetScheme(&scheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
base = aBaseURI;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
|
||||
nsCRT::free(scheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (hdlrResult) {
|
||||
*hdlrResult = handler;
|
||||
NS_ADDREF(*hdlrResult);
|
||||
}
|
||||
return handler->NewURI(aSpec, base, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::NewURI(const char* aSpec, nsIURI* aBaseURI,
|
||||
nsIURI* *result)
|
||||
{
|
||||
return NewURI(aSpec, aBaseURI, result, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
|
||||
nsXPIDLCString scheme;
|
||||
rv = aURI->GetScheme(getter_Copies(scheme));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = GetProtocolHandler((const char*)scheme, getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = handler->NewChannel(aURI, result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::NewChannel(const char *aSpec, nsIURI *aBaseURI, nsIChannel **result)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = NewURI(aSpec, aBaseURI, getter_AddRefs(uri), getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = handler->NewChannel(uri, result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::GetOffline(PRBool *offline)
|
||||
{
|
||||
*offline = mOffline;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetOffline(PRBool offline)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService>
|
||||
observerService(do_GetService(NS_OBSERVERSERVICE_CONTRACTID));
|
||||
|
||||
nsresult rv1 = NS_OK;
|
||||
nsresult rv2 = NS_OK;
|
||||
if (offline) {
|
||||
mOffline = PR_TRUE; // indicate we're trying to shutdown
|
||||
// be sure to try and shutdown both (even if the first fails)
|
||||
if (mDNSService)
|
||||
rv1 = mDNSService->Shutdown(); // shutdown dns service first, because it has callbacks for socket transport
|
||||
if (mSocketTransportService)
|
||||
rv2 = mSocketTransportService->Shutdown();
|
||||
if (NS_FAILED(rv1)) return rv1;
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
|
||||
// don't care if notification fails
|
||||
if (observerService)
|
||||
(void)observerService->Notify(this,
|
||||
NS_LITERAL_STRING("network:offline-status-changed").get(),
|
||||
NS_LITERAL_STRING("offline").get());
|
||||
}
|
||||
else if (!offline && mOffline) {
|
||||
// go online
|
||||
if (mDNSService)
|
||||
rv1 = mDNSService->Init();
|
||||
if (NS_FAILED(rv2)) return rv1;
|
||||
|
||||
if (mSocketTransportService)
|
||||
rv2 = mSocketTransportService->Init(); //XXX should we shutdown the dns service?
|
||||
if (NS_FAILED(rv2)) return rv1;
|
||||
mOffline = PR_FALSE; // indicate success only AFTER we've
|
||||
// brought up the services
|
||||
// don't care if notification fails
|
||||
if (observerService)
|
||||
(void)observerService->Notify(this,
|
||||
NS_LITERAL_STRING("network:offline-status-changed").get(),
|
||||
NS_LITERAL_STRING("online").get());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// URL parsing utilities
|
||||
|
||||
/* encode characters into % escaped hexcodes */
|
||||
|
||||
/* use the following masks to specify which
|
||||
part of an URL you want to escape:
|
||||
|
||||
url_Scheme = 1
|
||||
url_Username = 2
|
||||
url_Password = 4
|
||||
url_Host = 8
|
||||
url_Directory = 16
|
||||
url_FileBaseName = 32
|
||||
url_FileExtension = 64
|
||||
url_Param = 128
|
||||
url_Query = 256
|
||||
url_Ref = 512
|
||||
*/
|
||||
|
||||
/* by default this function will not escape parts of a string
|
||||
that already look escaped, which means it already includes
|
||||
a valid hexcode. This is done to avoid multiple escapes of
|
||||
a string. Use the following mask to force escaping of a
|
||||
string:
|
||||
|
||||
url_Forced = 1024
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsIOService::Escape(const char *str, PRInt16 mask, char** result)
|
||||
{
|
||||
nsCAutoString esc_str;
|
||||
nsresult rv = nsURLEscape((char*)str,mask,esc_str);
|
||||
CRTFREEIF(*result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
*result = esc_str.ToNewCString();
|
||||
if (!*result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::Unescape(const char *str, char **result)
|
||||
{
|
||||
return nsURLUnescape((char*)str,result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::ExtractPort(const char *str, PRInt32 *result)
|
||||
{
|
||||
PRInt32 returnValue = -1;
|
||||
*result = (0 < PR_sscanf(str, "%d", &returnValue)) ? returnValue : -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::ResolveRelativePath(const char *relativePath, const char* basePath,
|
||||
char **result)
|
||||
{
|
||||
nsCAutoString name;
|
||||
nsCAutoString path(basePath);
|
||||
PRBool needsDelim = PR_FALSE;
|
||||
|
||||
if ( !path.IsEmpty() ) {
|
||||
PRUnichar last = path.Last();
|
||||
needsDelim = !(last == '/' || last == '\\' );
|
||||
}
|
||||
|
||||
PRBool end = PR_FALSE;
|
||||
char c;
|
||||
while (!end) {
|
||||
c = *relativePath++;
|
||||
switch (c) {
|
||||
case '\0':
|
||||
case '#':
|
||||
case ';':
|
||||
case '?':
|
||||
end = PR_TRUE;
|
||||
// fall through...
|
||||
case '/':
|
||||
case '\\':
|
||||
// delimiter found
|
||||
if (name.Equals("..")) {
|
||||
// pop path
|
||||
PRInt32 pos = path.RFind("/");
|
||||
if (pos > 0) {
|
||||
path.Truncate(pos + 1);
|
||||
path += name;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
}
|
||||
}
|
||||
else if (name.Equals(".") || name.Equals("")) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
// append name to path
|
||||
if (needsDelim)
|
||||
path += "/";
|
||||
path += name;
|
||||
needsDelim = PR_TRUE;
|
||||
}
|
||||
name = "";
|
||||
break;
|
||||
|
||||
default:
|
||||
// append char to name
|
||||
name += c;
|
||||
}
|
||||
}
|
||||
// append anything left on relativePath (e.g. #..., ;..., ?...)
|
||||
if (c != '\0')
|
||||
path += --relativePath;
|
||||
|
||||
*result = path.ToNewCString();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
1330
mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp
Normal file
1330
mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1034
mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp
Normal file
1034
mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
789
mozilla/parser/htmlparser/src/nsLoggingSink.cpp
Normal file
789
mozilla/parser/htmlparser/src/nsLoggingSink.cpp
Normal file
@@ -0,0 +1,789 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Notes:
|
||||
* The logging sink is now both a sink and a proxy.
|
||||
* If you want to dump the calls from the parser to the sink,
|
||||
* create a content sink as usual and hand it to the parser.
|
||||
*
|
||||
* If you want to use a normal sink AND simultaneously have a
|
||||
* parse-log generated, you can set an environment variable
|
||||
* and a logging sink will be created. It will act as a proxy
|
||||
* to the REAL sink you are using after it logs the call. This
|
||||
* form of the loggingsink is constructed using the version
|
||||
* that accepts an nsIHTMLContentSink*.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsLoggingSink.h"
|
||||
#include "nsHTMLTags.h"
|
||||
#include "nsString.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID);
|
||||
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
|
||||
static NS_DEFINE_IID(kILoggingSinkIID, NS_ILOGGING_SINK_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
// list of tags that have skipped content
|
||||
static char gSkippedContentTags[] = {
|
||||
eHTMLTag_style,
|
||||
eHTMLTag_script,
|
||||
eHTMLTag_server,
|
||||
eHTMLTag_textarea,
|
||||
eHTMLTag_title,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLLoggingSink(nsIContentSink** aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if (nsnull == aInstancePtrResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsLoggingSink* it = new nsLoggingSink();
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return it->QueryInterface(kIContentSinkIID, (void**) aInstancePtrResult);
|
||||
}
|
||||
|
||||
nsLoggingSink::nsLoggingSink() {
|
||||
NS_INIT_REFCNT();
|
||||
mOutput = 0;
|
||||
mLevel=-1;
|
||||
mSink=0;
|
||||
}
|
||||
|
||||
nsLoggingSink::~nsLoggingSink() {
|
||||
mSink=0;
|
||||
if(mOutput && mAutoDeleteOutput) {
|
||||
delete mOutput;
|
||||
}
|
||||
mOutput=0;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsLoggingSink)
|
||||
NS_IMPL_RELEASE(nsLoggingSink)
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtr, "null ptr");
|
||||
if (nsnull == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
nsISupports* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kIContentSinkIID)) {
|
||||
nsIContentSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kIHTMLContentSinkIID)) {
|
||||
nsIHTMLContentSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else if (aIID.Equals(kILoggingSinkIID)) {
|
||||
nsILoggingSink* tmp = this;
|
||||
*aInstancePtr = (void*) tmp;
|
||||
}
|
||||
else {
|
||||
*aInstancePtr = nsnull;
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetOutputStream(PRFileDesc *aStream,PRBool autoDeleteOutput) {
|
||||
mOutput = aStream;
|
||||
mAutoDeleteOutput=autoDeleteOutput;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static
|
||||
void WriteTabs(PRFileDesc * out,int aTabCount) {
|
||||
int tabs;
|
||||
for(tabs=0;tabs<aTabCount;tabs++)
|
||||
PR_fprintf(out, " ");
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillBuildModel() {
|
||||
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
PR_fprintf(mOutput, "<begin>\n");
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
mSink->WillBuildModel();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::DidBuildModel(PRInt32 aQualityLevel) {
|
||||
|
||||
WriteTabs(mOutput,--mLevel);
|
||||
PR_fprintf(mOutput, "</begin>\n");
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
nsresult theResult=NS_OK;
|
||||
if(mSink) {
|
||||
theResult=mSink->DidBuildModel(aQualityLevel);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillInterrupt() {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->WillInterrupt();
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::WillResume() {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->WillResume();
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetParser(nsIParser* aParser) {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->SetParser(aParser);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenContainer(const nsIParserNode& aNode) {
|
||||
|
||||
OpenNode("container", aNode); //do the real logging work...
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenContainer(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseContainer(const nsIParserNode& aNode) {
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
theResult=CloseNode(tag);
|
||||
}
|
||||
else theResult= CloseNode("???");
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseContainer(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddLeaf(const nsIParserNode& aNode) {
|
||||
LeafNode(aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddLeaf(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::NotifyError(const nsParserError* aError) {
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->NotifyError(aError);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This gets called by the parser when you want to add
|
||||
* a PI node to the current container in the content
|
||||
* model.
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddProcessingInstruction(const nsIParserNode& aNode){
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddProcessingInstruction(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called by the parser when it encounters
|
||||
* a DOCTYPE declaration in the HTML document.
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode) {
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddDocTypeDecl(aNode,aMode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called by the parser when you want to add
|
||||
* a comment node to the current container in the content
|
||||
* model.
|
||||
*
|
||||
* @updated gess 3/25/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddComment(const nsIParserNode& aNode){
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
DebugDump("<",aNode.GetText(),(mNodeStackPos)*2);
|
||||
#endif
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddComment(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetTitle(const nsString& aValue) {
|
||||
|
||||
char* tmp;
|
||||
GetNewCString(aValue, &tmp);
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
if(tmp) {
|
||||
PR_fprintf(mOutput, "<title value=\"%s\"/>\n", tmp);
|
||||
nsMemory::Free(tmp);
|
||||
}
|
||||
--mLevel;
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->SetTitle(aValue);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHTML(const nsIParserNode& aNode) {
|
||||
OpenNode("html", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenHTML(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseHTML(const nsIParserNode& aNode) {
|
||||
CloseNode("html");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseHTML(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHead(const nsIParserNode& aNode) {
|
||||
OpenNode("head", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenHead(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseHead(const nsIParserNode& aNode) {
|
||||
CloseNode("head");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseHead(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenBody(const nsIParserNode& aNode) {
|
||||
OpenNode("body", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenBody(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseBody(const nsIParserNode& aNode) {
|
||||
CloseNode("body");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseBody(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenForm(const nsIParserNode& aNode) {
|
||||
OpenNode("form", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenForm(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseForm(const nsIParserNode& aNode) {
|
||||
CloseNode("form");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseForm(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenMap(const nsIParserNode& aNode) {
|
||||
OpenNode("map", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenMap(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseMap(const nsIParserNode& aNode) {
|
||||
CloseNode("map");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseMap(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenFrameset(const nsIParserNode& aNode) {
|
||||
OpenNode("frameset", aNode);
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenFrameset(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseFrameset(const nsIParserNode& aNode) {
|
||||
CloseNode("frameset");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->CloseFrameset(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::OpenNode(const char* aKind, const nsIParserNode& aNode) {
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
|
||||
PR_fprintf(mOutput,"<open container=");
|
||||
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
PR_fprintf(mOutput, "\"%s\"", tag);
|
||||
}
|
||||
else {
|
||||
char* text;
|
||||
GetNewCString(aNode.GetText(), &text);
|
||||
if(text) {
|
||||
PR_fprintf(mOutput, "\"%s\"", text);
|
||||
nsMemory::Free(text);
|
||||
}
|
||||
}
|
||||
|
||||
if (WillWriteAttributes(aNode)) {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
WriteAttributes(aNode);
|
||||
PR_fprintf(mOutput, "</open>\n");
|
||||
}
|
||||
else {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::CloseNode(const char* aKind) {
|
||||
WriteTabs(mOutput,mLevel--);
|
||||
PR_fprintf(mOutput, "<close container=\"%s\">\n", aKind);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
|
||||
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsAutoString tmp;
|
||||
PRInt32 ac = aNode.GetAttributeCount();
|
||||
for (PRInt32 i = 0; i < ac; i++) {
|
||||
char* key=nsnull;
|
||||
char* value=nsnull;
|
||||
const nsAReadableString& k = aNode.GetKeyAt(i);
|
||||
const nsString& v = aNode.GetValueAt(i);
|
||||
|
||||
GetNewCString(k, &key);
|
||||
if(key) {
|
||||
PR_fprintf(mOutput, " <attr key=\"%s\" value=\"", key);
|
||||
nsMemory::Free(key);
|
||||
}
|
||||
|
||||
tmp.Truncate();
|
||||
tmp.Append(v);
|
||||
if(tmp.Length() > 0) {
|
||||
PRUnichar first = tmp.First();
|
||||
if ((first == '"') || (first == '\'')) {
|
||||
if (tmp.Last() == first) {
|
||||
tmp.Cut(0, 1);
|
||||
PRInt32 pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
} else {
|
||||
// Mismatched quotes - leave them in
|
||||
}
|
||||
}
|
||||
GetNewCString(tmp, &value);
|
||||
|
||||
if(value) {
|
||||
PR_fprintf(mOutput, "%s\"/>\n", value);
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsMemory::Free(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
char* content;
|
||||
GetNewCString(aNode.GetSkippedContent(), &content);
|
||||
if(content) {
|
||||
PR_fprintf(mOutput, " <content value=\"");
|
||||
PR_fprintf(mOutput, "%s\"/>\n", content) ;
|
||||
nsMemory::Free(content);
|
||||
}
|
||||
}
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode)
|
||||
{
|
||||
PRInt32 ac = aNode.GetAttributeCount();
|
||||
if (0 != ac) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
const nsString& content = aNode.GetSkippedContent();
|
||||
if (content.Length() > 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::LeafNode(const nsIParserNode& aNode)
|
||||
{
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const char* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
|
||||
if(tag)
|
||||
PR_fprintf(mOutput, "<leaf tag=\"%s\"", tag);
|
||||
else PR_fprintf(mOutput, "<leaf tag=\"???\"");
|
||||
|
||||
if (WillWriteAttributes(aNode)) {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
WriteAttributes(aNode);
|
||||
PR_fprintf(mOutput, "</leaf>\n");
|
||||
}
|
||||
else {
|
||||
PR_fprintf(mOutput, "/>\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRInt32 pos;
|
||||
nsAutoString tmp;
|
||||
char* str;
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
GetNewCString(aNode.GetText(), &str);
|
||||
if(str) {
|
||||
PR_fprintf(mOutput, "<text value=\"%s\"/>\n", str);
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_newline:
|
||||
PR_fprintf(mOutput, "<newline/>\n");
|
||||
break;
|
||||
|
||||
case eHTMLTag_entity:
|
||||
tmp.Append(aNode.GetText());
|
||||
tmp.Cut(0, 1);
|
||||
pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
PR_fprintf(mOutput, "<entity value=\"%s\"/>\n", tmp.GetBuffer());
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("unsupported leaf node type");
|
||||
}//switch
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::QuoteText(const nsAReadableString& aValue, nsString& aResult) {
|
||||
aResult.Truncate();
|
||||
/*
|
||||
if you're stepping through the string anyway, why not use iterators instead of forcing the string to copy?
|
||||
*/
|
||||
nsPromiseFlatString flat(aValue);
|
||||
const PRUnichar* cp = flat.get();
|
||||
const PRUnichar* end = cp + aValue.Length();
|
||||
while (cp < end) {
|
||||
PRUnichar ch = *cp++;
|
||||
if (ch == '"') {
|
||||
aResult.AppendWithConversion(""");
|
||||
}
|
||||
else if (ch == '&') {
|
||||
aResult.AppendWithConversion("&");
|
||||
}
|
||||
else if ((ch < 32) || (ch >= 127)) {
|
||||
aResult.AppendWithConversion("&#");
|
||||
aResult.AppendInt(PRInt32(ch), 10);
|
||||
aResult.AppendWithConversion(';');
|
||||
}
|
||||
else {
|
||||
aResult.Append(ch);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to convert nsString to char*.
|
||||
* REMEMBER: Match this call with nsMemory::Free(aResult);
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aValue - The string value
|
||||
* @param aResult - String coverted to char*.
|
||||
*/
|
||||
nsresult
|
||||
nsLoggingSink::GetNewCString(const nsAReadableString& aValue, char** aResult)
|
||||
{
|
||||
nsresult result=NS_OK;
|
||||
nsAutoString temp;
|
||||
result=QuoteText(aValue,temp);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
if(temp.Length()>0) {
|
||||
*aResult=temp.ToNewCString();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::DoFragment(PRBool aFlag)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when handling illegal contents, especially
|
||||
* in dealing with tables. This method creates a new context.
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aPosition - The position from where the new context begins.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::BeginContext(PRInt32 aPosition)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method terminates any new context that got created by
|
||||
* BeginContext and switches back to the main context.
|
||||
*
|
||||
* @update 04/04/99 harishd
|
||||
* @param aPosition - Validates the end of a context.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::EndContext(PRInt32 aPosition)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
2339
mozilla/profile/src/nsProfile.cpp
Normal file
2339
mozilla/profile/src/nsProfile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1643
mozilla/profile/src/nsProfileAccess.cpp
Normal file
1643
mozilla/profile/src/nsProfileAccess.cpp
Normal file
File diff suppressed because it is too large
Load Diff
37
mozilla/string/Makefile.in
Normal file
37
mozilla/string/Makefile.in
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
#
|
||||
|
||||
DEPTH = ..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src obsolete
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
#DIRS += \
|
||||
# tests
|
||||
#endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
29
mozilla/string/README.html
Normal file
29
mozilla/string/README.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<!--
|
||||
- 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)
|
||||
-->
|
||||
<body>
|
||||
<h1><span class="LXRSHORTDESC">managing sequences of characters</span></h1>
|
||||
<p>
|
||||
<span class="LXRLONGDESC"></span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
29
mozilla/string/doc/README.html
Normal file
29
mozilla/string/doc/README.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<!--
|
||||
- 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)
|
||||
-->
|
||||
<body>
|
||||
<h1><span class="LXRSHORTDESC">documentation aimed at programmers who are clients of the string library</span></h1>
|
||||
<p>
|
||||
<span class="LXRLONGDESC"></span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
30
mozilla/string/macbuild/String.Prefix
Normal file
30
mozilla/string/macbuild/String.Prefix
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mac build settings for the release string library
|
||||
*/
|
||||
|
||||
#include "MacPrefix.h"
|
||||
|
||||
// while we're still a part of xpcom, make stuff get exported
|
||||
#define _IMPL_NS_COM 1
|
||||
30
mozilla/string/macbuild/StringDebug.Prefix
Normal file
30
mozilla/string/macbuild/StringDebug.Prefix
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mac build settings for the debug string library
|
||||
*/
|
||||
|
||||
#include "MacPrefix_debug.h"
|
||||
|
||||
// while we're still a part of xpcom, make stuff get exported
|
||||
#define _IMPL_NS_COM 1
|
||||
BIN
mozilla/string/macbuild/string.mcp
Normal file
BIN
mozilla/string/macbuild/string.mcp
Normal file
Binary file not shown.
34
mozilla/string/makefile.win
Normal file
34
mozilla/string/makefile.win
Normal file
@@ -0,0 +1,34 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
#
|
||||
|
||||
DEPTH=..
|
||||
|
||||
DIRS= public \
|
||||
src \
|
||||
obsolete \
|
||||
#!if !defined(DISABLE_TESTS)
|
||||
# tests \
|
||||
#!endif
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
27
mozilla/string/obsolete/MANIFEST
Normal file
27
mozilla/string/obsolete/MANIFEST
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
|
||||
|
||||
nsStr.h
|
||||
nsString.h
|
||||
nsString2.h
|
||||
nsXPIDLString.h
|
||||
58
mozilla/string/obsolete/Makefile.in
Normal file
58
mozilla/string/obsolete/Makefile.in
Normal file
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = string
|
||||
LIBRARY_NAME = string_obsolete_s
|
||||
|
||||
REQUIRES = unicharutil xpcom
|
||||
|
||||
CPPSRCS = \
|
||||
nsStr.cpp \
|
||||
nsString.cpp \
|
||||
nsString2.cpp \
|
||||
nsXPIDLString.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsXPIDLString.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
35
mozilla/string/obsolete/README.html
Normal file
35
mozilla/string/obsolete/README.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<html>
|
||||
<!--
|
||||
- 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)
|
||||
-->
|
||||
<body>
|
||||
<h1><span class="LXRSHORTDESC">original string implementations soon to be replaced (the names you are using will still be good)</span></h1>
|
||||
<p>
|
||||
<span class="LXRLONGDESC">These are the original string implementations by rickg and others.
|
||||
Most of the code here will be made obsolete by the new shared-buffer string (see bug <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=53065">#53065</a>).
|
||||
For the most part, this change is intended to be transparent to clients.
|
||||
The type names you are using for strings now, e.g., nsString, nsAutoString, nsXPIDLString, will still be good,
|
||||
they will just refer to better, but compatible, implementations.
|
||||
If you're interested in learning how strings work, you probably want to start with
|
||||
<a href="http://lxr.mozilla.org/seamonkey/source/string/public/nsAReadableString.h">nsAReadableString</a>.</span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
971
mozilla/string/obsolete/bufferRoutines.h
Normal file
971
mozilla/string/obsolete/bufferRoutines.h
Normal file
@@ -0,0 +1,971 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
/* bufferRoutines.h --- rickg's original string manipulation underpinnings;
|
||||
this code will be made obsolete by the new shared-buffer string (see bug #53065)
|
||||
*/
|
||||
|
||||
#ifndef _BUFFERROUTINES_H
|
||||
#define _BUFFERROUTINES_H
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the workhorse copy and shift functions used in nsStrStruct.
|
||||
Ultimately, I plan to make the function pointers in this system available for
|
||||
use by external modules. They'll be able to install their own "handlers".
|
||||
Not so, today though.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "nsCRT.h"
|
||||
|
||||
#ifndef XPCOM_STANDALONE
|
||||
#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS)
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICaseConversion.h"
|
||||
#endif
|
||||
#endif /* XPCOM_STANDALONE */
|
||||
|
||||
#define KSHIFTLEFT (0)
|
||||
#define KSHIFTRIGHT (1)
|
||||
|
||||
// uncomment the following line to caught nsString char* casting problem
|
||||
//#define DEBUG_ILLEGAL_CAST_UP
|
||||
//#define DEBUG_ILLEGAL_CAST_DOWN
|
||||
|
||||
#if defined(DEBUG_ILLEGAL_CAST_UP) || defined(DEBUG_ILLEGAL_CAST_DOWN)
|
||||
|
||||
static PRBool track_illegal = PR_TRUE;
|
||||
static PRBool track_latin1 = PR_TRUE;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include "nsTraceRefcnt.h"
|
||||
class CTraceFile {
|
||||
public:
|
||||
CTraceFile() {
|
||||
mFile = fopen("nsStringTrace.txt" , "a+");
|
||||
}
|
||||
~CTraceFile() {
|
||||
fflush(mFile);
|
||||
fclose(mFile);
|
||||
}
|
||||
void ReportCastUp(const char* data, const char* msg)
|
||||
{
|
||||
if(mFile) {
|
||||
fprintf(mFile, "ERRORTEXT= %s\n", msg);
|
||||
fprintf(mFile, "BEGINDATA\n");
|
||||
const char* s=data;
|
||||
while(*s) {
|
||||
if(*s & 0x80) {
|
||||
fprintf(mFile, "[%2X]", (char)*s);
|
||||
} else {
|
||||
fprintf(mFile, "%c", *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
fprintf(mFile, "\n");
|
||||
fprintf(mFile, "ENDDATA\n");
|
||||
fprintf(mFile, "BEGINSTACK\n");
|
||||
nsTraceRefcnt::WalkTheStack(mFile);
|
||||
fprintf(mFile, "\n");
|
||||
fprintf(mFile, "ENDSTACK\n");
|
||||
fflush(mFile);
|
||||
}
|
||||
}
|
||||
void ReportCastDown(const PRUnichar* data, const char* msg)
|
||||
{
|
||||
if(mFile) {
|
||||
fprintf(mFile, "ERRORTEXT=%s\n", msg);
|
||||
fprintf(mFile, "BEGINDATA\n");
|
||||
const PRUnichar* s=data;
|
||||
while(*s) {
|
||||
if(*s & 0xFF80) {
|
||||
fprintf(mFile, "\\u%X", *s);
|
||||
} else {
|
||||
fprintf(mFile, "%c", *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
fprintf(mFile, "\n");
|
||||
fprintf(mFile, "ENDDATA\n");
|
||||
fprintf(mFile, "BEGINSTACK\n");
|
||||
nsTraceRefcnt::WalkTheStack(mFile);
|
||||
fprintf(mFile, "\n");
|
||||
fprintf(mFile, "ENDSTACK\n");
|
||||
fflush(mFile);
|
||||
}
|
||||
}
|
||||
private:
|
||||
FILE* mFile;
|
||||
};
|
||||
static CTraceFile gTrace;
|
||||
#define TRACE_ILLEGAL_CAST_UP(c, s, m) if(!(c)) gTrace.ReportCastUp(s,m);
|
||||
#define TRACE_ILLEGAL_CAST_DOWN(c, s, m) if(!(c)) gTrace.ReportCastDown(s,m);
|
||||
|
||||
#else // XP_UNIX
|
||||
|
||||
#define TRACE_ILLEGAL_CAST_UP(c, s, m) NS_ASSERTION((c), (m))
|
||||
#define TRACE_ILLEGAL_CAST_DOWN(c, s, m) NS_ASSERTION((c), (m))
|
||||
|
||||
#endif //XP_UNIX
|
||||
|
||||
#endif
|
||||
|
||||
inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) {
|
||||
return ((PRUnichar*)aString)[anIndex];
|
||||
}
|
||||
|
||||
inline PRUnichar GetCharAt(const char* aString,PRUint32 anIndex) {
|
||||
return (PRUnichar)aString[anIndex];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to shift the contents of a char buffer.
|
||||
// The functions are differentiated by shift direction and the underlying charsize.
|
||||
//
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters left by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where left-shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* dst = aDest+anOffset;
|
||||
char* src = aDest+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,aLength-(aCount+anOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters right by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* src = aDest+anOffset;
|
||||
char* dst = aDest+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,aLength-anOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftDoubleCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* root=(PRUnichar*)aDest;
|
||||
PRUnichar* dst = root+anOffset;
|
||||
PRUnichar* src = root+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,(aLength-(aCount+anOffset))*sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftDoubleCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* root=(PRUnichar*)aDest;
|
||||
PRUnichar* src = root+anOffset;
|
||||
PRUnichar* dst = root+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,sizeof(PRUnichar)*(aLength-anOffset));
|
||||
}
|
||||
|
||||
|
||||
typedef void (*ShiftChars)(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount);
|
||||
ShiftChars gShiftChars[2][2]= {
|
||||
{&ShiftCharsLeft,&ShiftCharsRight},
|
||||
{&ShiftDoubleCharsLeft,&ShiftDoubleCharsRight}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to copy one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Going 1 to 1 is easy, since we assume ascii. No conversions are necessary.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
char* dst = aDest+anDestOffset;
|
||||
char* src = (char*)aSource+anOffset;
|
||||
|
||||
memcpy(dst,src,aCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 1 to 2 requires a conversion from ascii to unicode. This can be expensive.
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
const unsigned char* first= (const unsigned char*)aSource+anOffset;
|
||||
const unsigned char* last = first+aCount;
|
||||
|
||||
#ifdef DEBUG_ILLEGAL_CAST_UP
|
||||
PRBool illegal= PR_FALSE;
|
||||
#endif
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
*to=(PRUnichar)(*first);
|
||||
#ifdef DEBUG_ILLEGAL_CAST_UP
|
||||
if(track_illegal && track_latin1 && ((*to)& 0x80))
|
||||
illegal= PR_TRUE;
|
||||
#endif
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
#ifdef DEBUG_ILLEGAL_CAST_UP
|
||||
TRACE_ILLEGAL_CAST_UP((!illegal), aSource, "illegal cast up in CopyChars1To2");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Going 2 to 1 requires a conversion from unicode down to ascii. This can be lossy.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* to = aDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
const PRUnichar* first= theSource+anOffset;
|
||||
const PRUnichar* last = first+aCount;
|
||||
|
||||
#ifdef DEBUG_ILLEGAL_CAST_DOWN
|
||||
PRBool illegal= PR_FALSE;
|
||||
#endif
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
if(*first<256)
|
||||
*to=(char)*first;
|
||||
else {
|
||||
*to='.';
|
||||
NS_ASSERTION( (*first < 256), "data in U+0100-U+FFFF will be lost");
|
||||
}
|
||||
#ifdef DEBUG_ILLEGAL_CAST_DOWN
|
||||
if(track_illegal) {
|
||||
if(track_latin1) {
|
||||
if(*first & 0xFF80)
|
||||
illegal = PR_TRUE;
|
||||
} else {
|
||||
if(*first & 0xFF00)
|
||||
illegal = PR_TRUE;
|
||||
} // track_latin1
|
||||
} // track_illegal
|
||||
#endif
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
#ifdef DEBUG_ILLEGAL_CAST_DOWN
|
||||
TRACE_ILLEGAL_CAST_DOWN((!illegal), theSource, "illegal cast down in CopyChars2To1");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 2 to 2 is fast and efficient.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
PRUnichar* from= theSource+anOffset;
|
||||
|
||||
memcpy((void*)to,(void*)from,aCount*sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef void (*CopyChars)(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount);
|
||||
|
||||
CopyChars gCopyChars[2][2]={
|
||||
{&CopyChars1To1,&CopyChars1To2},
|
||||
{&CopyChars2To1,&CopyChars2To2}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to search a buffer looking for a char.
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 02/17/00
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aDestLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar1(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase,PRInt32 aCount) {
|
||||
|
||||
if(anOffset<0)
|
||||
anOffset=0;
|
||||
|
||||
if(aCount<0)
|
||||
aCount = (PRInt32)aDestLength;
|
||||
|
||||
if((aChar<256) && (0<aDestLength) && ((PRUint32)anOffset<aDestLength)) {
|
||||
|
||||
//We'll only search if the given aChar is within the normal ascii a range,
|
||||
//(Since this string is definitely within the ascii range).
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
const char* left= aDest+anOffset;
|
||||
const char* last= left+aCount;
|
||||
const char* max = aDest+aDestLength;
|
||||
const char* end = (last<max) ? last : max;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
|
||||
char theChar=(char)nsCRT::ToUpper(aChar);
|
||||
while(left<end){
|
||||
if(nsCRT::ToUpper(*left)==theChar)
|
||||
return left-aDest;
|
||||
++left;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
PRInt32 theMax = end-left;
|
||||
if(0<theMax) {
|
||||
unsigned char theChar = (unsigned char) aChar;
|
||||
const char* result=(const char*)memchr(left, (int)theChar, theMax);
|
||||
if(result) {
|
||||
return result-aDest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aDestLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar2(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase,PRInt32 aCount) {
|
||||
|
||||
if(anOffset<0)
|
||||
anOffset=0;
|
||||
|
||||
if(aCount<0)
|
||||
aCount = (PRInt32)aDestLength;
|
||||
|
||||
if((0<aDestLength) && ((PRUint32)anOffset<aDestLength)) {
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
const PRUnichar* root = (PRUnichar*)aDest;
|
||||
const PRUnichar* left = root+anOffset;
|
||||
const PRUnichar* last = left+aCount;
|
||||
const PRUnichar* max = root+aDestLength;
|
||||
const PRUnichar* end = (last<max) ? last : max;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
PRUnichar theChar=nsCRT::ToUpper(aChar);
|
||||
while(left<end){
|
||||
if(nsCRT::ToUpper(*left)==theChar)
|
||||
return left-root;
|
||||
++left;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(left<end){
|
||||
if(*left==aChar)
|
||||
return (left-root);
|
||||
++left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer (in reverse) for the given char
|
||||
*
|
||||
* @update gess 02/17/00
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aDestLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
|
||||
inline PRInt32 RFindChar1(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase,PRInt32 aCount) {
|
||||
|
||||
if(anOffset<0)
|
||||
anOffset=(PRInt32)aDestLength-1;
|
||||
|
||||
if(aCount<0)
|
||||
aCount = aDestLength;
|
||||
|
||||
if((aChar<256) && (0<aDestLength) && ((PRUint32)anOffset<aDestLength)) {
|
||||
|
||||
//We'll only search if the given aChar is within the normal ascii a range,
|
||||
//(Since this string is definitely within the ascii range).
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
const char* rightmost = aDest+anOffset;
|
||||
const char* min = rightmost-aCount+1;
|
||||
const char* leftmost = (min<aDest) ? aDest: min;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
|
||||
char theChar=(char)nsCRT::ToUpper(aChar);
|
||||
while(leftmost<rightmost){
|
||||
if(nsCRT::ToUpper(*rightmost)==theChar)
|
||||
return rightmost-aDest;
|
||||
--rightmost;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
char theChar=(char)aChar;
|
||||
while(leftmost<=rightmost){
|
||||
if((*rightmost)==theChar)
|
||||
return rightmost-aDest;
|
||||
--rightmost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aDestLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 RFindChar2(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase,PRInt32 aCount) {
|
||||
|
||||
if(anOffset<0)
|
||||
anOffset=(PRInt32)aDestLength-1;
|
||||
|
||||
if(aCount<0)
|
||||
aCount = aDestLength;
|
||||
|
||||
if((0<aDestLength) && ((PRUint32)anOffset<aDestLength)) {
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
const PRUnichar* root = (PRUnichar*)aDest;
|
||||
const PRUnichar* rightmost = root+anOffset;
|
||||
const PRUnichar* min = rightmost-aCount+1;
|
||||
const PRUnichar* leftmost = (min<root) ? root: min;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
|
||||
PRUnichar theChar=nsCRT::ToUpper(aChar);
|
||||
while(leftmost<rightmost){
|
||||
if(nsCRT::ToUpper(*rightmost)==theChar)
|
||||
return rightmost-root;
|
||||
--rightmost;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
while(leftmost<=rightmost){
|
||||
if((*rightmost)==aChar)
|
||||
return rightmost-root;
|
||||
--rightmost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*FindChars)(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase,PRInt32 aCount);
|
||||
FindChars gFindChars[]={&FindChar1,&FindChar2};
|
||||
FindChars gRFindChars[]={&RFindChar1,&RFindChar2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to compare one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp(aStr1,aStr2,aCount);
|
||||
else result=memcmp(aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
typedef PRInt32 (*CompareChars)(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase);
|
||||
CompareChars gCompare[2][2]={
|
||||
{&Compare1To1,&Compare1To2},
|
||||
{&Compare2To1,&Compare2To2},
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to convert the case of strings...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase1(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef char chartype;
|
||||
chartype* cp = (chartype*)aString;
|
||||
chartype* end = cp + aCount-1;
|
||||
while (cp <= end) {
|
||||
chartype ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef XPCOM_STANDALONE
|
||||
#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS)
|
||||
class HandleCaseConversionShutdown3 : public nsIShutdownListener {
|
||||
public :
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
HandleCaseConversionShutdown3(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleCaseConversionShutdown3(void) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
|
||||
static nsICaseConversion * gCaseConv = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(HandleCaseConversionShutdown3, nsIShutdownListener);
|
||||
|
||||
nsresult HandleCaseConversionShutdown3::OnShutdown(const nsCID& cid, nsISupports* service) {
|
||||
if (cid.Equals(kUnicharUtilCID)) {
|
||||
NS_ASSERTION(service == gCaseConv, "wrong service!");
|
||||
if(gCaseConv){
|
||||
gCaseConv->Release();
|
||||
gCaseConv = 0;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
class CCaseConversionServiceInitializer {
|
||||
public:
|
||||
CCaseConversionServiceInitializer(){
|
||||
HandleCaseConversionShutdown3* listener =
|
||||
new HandleCaseConversionShutdown3();
|
||||
if(listener){
|
||||
nsServiceManager::GetService(kUnicharUtilCID, NS_GET_IID(nsICaseConversion),(nsISupports**) &gCaseConv, listener);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* XPCOM_STANDALONE */
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase2(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRUnichar* cp = (PRUnichar*)aString;
|
||||
PRUnichar* end = cp + aCount-1;
|
||||
PRInt32 result=0;
|
||||
|
||||
#ifndef XPCOM_STANDALONE
|
||||
#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS)
|
||||
static CCaseConversionServiceInitializer gCaseConversionServiceInitializer;
|
||||
|
||||
// I18N code begin
|
||||
if(gCaseConv) {
|
||||
nsresult err=(aToUpper) ? gCaseConv->ToUpper(cp, cp, aCount) : gCaseConv->ToLower(cp, cp, aCount);
|
||||
if(NS_SUCCEEDED(err))
|
||||
return 0;
|
||||
}
|
||||
// I18N code end
|
||||
#endif
|
||||
#endif /* XPCOM_STANDALONE */
|
||||
|
||||
|
||||
while (cp <= end) {
|
||||
PRUnichar ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CaseConverters)(char*,PRUint32,PRBool);
|
||||
CaseConverters gCaseConverters[]={&ConvertCase1,&ConvertCase2};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used compress char sequences in a buffer...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update rickg 03.23.2000
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
char* from = aString;
|
||||
char* end = aString + aLength;
|
||||
char* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
|
||||
while (from < end) {
|
||||
char theChar = *from++;
|
||||
|
||||
*to++=theChar; //always copy this char...
|
||||
|
||||
if((kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen))){
|
||||
while (from < end) {
|
||||
theChar = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){
|
||||
*to++ = theChar;
|
||||
break;
|
||||
}
|
||||
} //while
|
||||
} //if
|
||||
} //if
|
||||
*to = 0;
|
||||
}
|
||||
return to - aString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update rickg 03.23.2000
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
PRUnichar* from = (PRUnichar*)aString;
|
||||
PRUnichar* end = from + aLength;
|
||||
PRUnichar* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
|
||||
while (from < end) {
|
||||
PRUnichar theChar = *from++;
|
||||
|
||||
*to++=theChar; //always copy this char...
|
||||
|
||||
if((theChar<256) && (kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen))){
|
||||
while (from < end) {
|
||||
theChar = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){
|
||||
*to++ = theChar;
|
||||
break;
|
||||
}
|
||||
} //while
|
||||
} //if
|
||||
} //if
|
||||
*to = 0;
|
||||
}
|
||||
return to - (PRUnichar*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CompressChars)(char* aString,PRUint32 aCount,const char* aSet);
|
||||
CompressChars gCompressChars[]={&CompressChars1,&CompressChars2};
|
||||
|
||||
/**
|
||||
* This method strips chars in a given set from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars1(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
char* to = aString;
|
||||
char* from = aString-1;
|
||||
char* end = aString + aLength;
|
||||
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (++from < end) {
|
||||
char theChar = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (char*)aString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method strips chars in a given set from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars2(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
PRUnichar* to = (PRUnichar*)aString;
|
||||
PRUnichar* from = (PRUnichar*)aString-1;
|
||||
PRUnichar* end = to + aLength;
|
||||
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (++from < end) {
|
||||
PRUnichar theChar = *from;
|
||||
//Note the test for ascii range below. If you have a real unicode char,
|
||||
//and you're searching for chars in the (given) ascii string, there's no
|
||||
//point in doing the real search since it's out of the ascii range.
|
||||
if((255<theChar) || (kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen))){
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (PRUnichar*)aString;
|
||||
}
|
||||
|
||||
|
||||
typedef PRInt32 (*StripChars)(char* aString,PRUint32 aCount,const char* aSet);
|
||||
StripChars gStripChars[]={&StripChars1,&StripChars2};
|
||||
|
||||
#endif
|
||||
50
mozilla/string/obsolete/makefile.win
Normal file
50
mozilla/string/obsolete/makefile.win
Normal file
@@ -0,0 +1,50 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
#
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
EXPORTS = \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsXPIDLString.h \
|
||||
$(NULL)
|
||||
|
||||
LIBRARY_NAME=string_obsolete_s
|
||||
|
||||
LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsStr.obj \
|
||||
.\$(OBJDIR)\nsString.obj \
|
||||
.\$(OBJDIR)\nsString2.obj \
|
||||
.\$(OBJDIR)\nsXPIDLString.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
921
mozilla/string/obsolete/nsStr.cpp
Normal file
921
mozilla/string/obsolete/nsStr.cpp
Normal 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 Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rick Gessner <rickg@netscape.com> (original author)
|
||||
* Scott Collins <scc@mozilla.org>
|
||||
*/
|
||||
|
||||
#include "nsStr.h"
|
||||
#include "bufferRoutines.h"
|
||||
#include <stdio.h> //only used for printf
|
||||
#include "nsCRT.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the nsStr data structure.
|
||||
This general purpose buffer management class is used as the basis for our strings.
|
||||
It's benefits include:
|
||||
1. An efficient set of library style functions for manipulating nsStrs
|
||||
2. Support for 1 and 2 byte character strings (which can easily be increased to n)
|
||||
3. Unicode awareness and interoperability.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
//static const char* kCallFindChar = "For better performance, call FindChar() for targets whose length==1.";
|
||||
//static const char* kCallRFindChar = "For better performance, call RFindChar() for targets whose length==1.";
|
||||
|
||||
static const PRUnichar gCommonEmptyBuffer[1] = {0};
|
||||
static PRBool gStringAcquiredMemory = PR_TRUE;
|
||||
|
||||
/**
|
||||
* This method initializes all the members of the nsStr structure
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) {
|
||||
aDest.mStr=(char*)gCommonEmptyBuffer;
|
||||
aDest.mLength=0;
|
||||
aDest.mCapacity=0;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes all the members of the nsStr structure
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){
|
||||
aDest.mStr=(aCString) ? aCString : (char*)gCommonEmptyBuffer;
|
||||
aDest.mLength=aLength;
|
||||
aDest.mCapacity=aCapacity;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=aOwnsBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This member destroys the memory buffer owned by an nsStr object (if it actually owns it)
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Destroy(nsStr& aDest) {
|
||||
if((aDest.mStr) && (aDest.mStr!=(char*)gCommonEmptyBuffer)) {
|
||||
Free(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents are not preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
PRBool nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength) {
|
||||
PRBool result=PR_TRUE;
|
||||
if(aNewLength>aString.mCapacity) {
|
||||
result=Realloc(aString,aNewLength);
|
||||
if(aString.mStr)
|
||||
AddNullTerminator(aString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents ARE preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
PRBool nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength) {
|
||||
PRBool result=PR_TRUE;
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
#ifndef NS_USE_OLD_STRING_ALLOCATION_STRATEGY
|
||||
// the new strategy is, allocate exact size, double on grows
|
||||
if ( aDest.mCapacity ) {
|
||||
PRUint32 newCapacity = aDest.mCapacity;
|
||||
while ( newCapacity < aNewLength )
|
||||
newCapacity <<= 1;
|
||||
aNewLength = newCapacity;
|
||||
}
|
||||
#endif
|
||||
|
||||
result=EnsureCapacity(theTempStr,aNewLength);
|
||||
if(result) {
|
||||
if(aDest.mLength) {
|
||||
StrAppend(theTempStr,aDest,0,aDest.mLength);
|
||||
}
|
||||
Free(aDest);
|
||||
aDest.mStr = theTempStr.mStr;
|
||||
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
|
||||
aDest.mLength=theTempStr.mLength;
|
||||
aDest.mCapacity=theTempStr.mCapacity;
|
||||
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of aDest with aSource, up to aCount of chars.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed.
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::StrAssign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){
|
||||
if(&aDest!=&aSource){
|
||||
StrTruncate(aDest,0);
|
||||
StrAppend(aDest,aSource,anOffset,aCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends the given nsStr to this one. Note that we have to
|
||||
* pay attention to the underlying char-size of both structs.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aSource is where char are copied from
|
||||
* @aCount is the number of bytes to be copied
|
||||
*/
|
||||
void nsStr::StrAppend(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){
|
||||
if(anOffset<aSource.mLength){
|
||||
PRUint32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRUint32 theLength=(anOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-anOffset);
|
||||
if(0<theLength){
|
||||
|
||||
PRBool isBigEnough=PR_TRUE;
|
||||
if(aDest.mLength+theLength > aDest.mCapacity) {
|
||||
isBigEnough=GrowCapacity(aDest,aDest.mLength+theLength);
|
||||
}
|
||||
|
||||
if(isBigEnough) {
|
||||
//now append new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDest.mLength,aSource.mStr,anOffset,theLength);
|
||||
|
||||
aDest.mLength+=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
NSSTR_SEEN(aDest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method inserts up to "aCount" chars from a source nsStr into a dest nsStr.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed
|
||||
* @param aDestOffset is where in aDest the insertion is to occur
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aSrcOffset is where in aSource chars are copied from
|
||||
* @param aCount is the number of chars from aSource to be inserted into aDest
|
||||
*/
|
||||
void nsStr::StrInsert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount){
|
||||
//there are a few cases for insert:
|
||||
// 1. You're inserting chars into an empty string (assign)
|
||||
// 2. You're inserting onto the end of a string (append)
|
||||
// 3. You're inserting onto the 1..n-1 pos of a string (the hard case).
|
||||
if(0<aSource.mLength){
|
||||
if(aDest.mLength){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
PRInt32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRInt32 theLength=(aSrcOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-aSrcOffset);
|
||||
|
||||
if(aSrcOffset<aSource.mLength) {
|
||||
//here's the only new case we have to handle.
|
||||
//chars are really being inserted into our buffer...
|
||||
|
||||
if(aDest.mLength+theLength > aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
PRBool isBigEnough=EnsureCapacity(theTempStr,aDest.mLength+theLength); //grow the temp buffer to the right size
|
||||
|
||||
if(isBigEnough) {
|
||||
if(aDestOffset) {
|
||||
StrAppend(theTempStr,aDest,0,aDestOffset); //first copy leftmost data...
|
||||
}
|
||||
|
||||
StrAppend(theTempStr,aSource,0,aSource.mLength); //next copy inserted (new) data
|
||||
|
||||
PRUint32 theRemains=aDest.mLength-aDestOffset;
|
||||
if(theRemains) {
|
||||
StrAppend(theTempStr,aDest,aDestOffset,theRemains); //next copy rightmost data
|
||||
}
|
||||
|
||||
Free(aDest);
|
||||
aDest.mStr = theTempStr.mStr;
|
||||
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
|
||||
aDest.mCapacity=theTempStr.mCapacity;
|
||||
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
}
|
||||
|
||||
//finally, make sure to update the string length...
|
||||
aDest.mLength+=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
NSSTR_SEEN(aDest);
|
||||
}//if
|
||||
//else nothing to do!
|
||||
}
|
||||
else StrAppend(aDest,aSource,0,aCount);
|
||||
}
|
||||
else StrAppend(aDest,aSource,0,aCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method deletes up to aCount chars from aDest
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aDestOffset is where in aDest deletion is to occur
|
||||
* @param aCount is the number of chars to be deleted in aDest
|
||||
*/
|
||||
void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
|
||||
PRUint32 theDelta=aDest.mLength-aDestOffset;
|
||||
PRUint32 theLength=(theDelta<aCount) ? theDelta : aCount;
|
||||
|
||||
if(aDestOffset+theLength<aDest.mLength) {
|
||||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
NSSTR_SEEN(aDest);
|
||||
}
|
||||
else StrTruncate(aDest,aDestOffset);
|
||||
}//if
|
||||
}
|
||||
|
||||
/**
|
||||
* This method truncates the given nsStr at given offset
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be truncated
|
||||
* @param aDestOffset is where in aDest truncation is to occur
|
||||
*/
|
||||
void nsStr::StrTruncate(nsStr& aDest,PRUint32 aDestOffset){
|
||||
if(aDest.mCapacity && aDestOffset<=aDest.mCapacity){
|
||||
aDest.mLength=aDestOffset;
|
||||
AddNullTerminator(aDest);
|
||||
NSSTR_SEEN(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method forces the given string to upper or lowercase
|
||||
* @update gess1/7/99
|
||||
* @param aDest is the string you're going to change
|
||||
* @param aToUpper: if TRUE, then we go uppercase, otherwise we go lowercase
|
||||
* @return
|
||||
*/
|
||||
void nsStr::ChangeCase(nsStr& aDest,PRBool aToUpper) {
|
||||
// somehow UnicharUtil return failed, fallback to the old ascii only code
|
||||
gCaseConverters[aDest.mCharSize](aDest.mStr,aDest.mLength,aToUpper);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes characters from the given set from this string.
|
||||
* NOTE: aSet is a char*, and it's length is computed using strlen, which assumes null termination.
|
||||
*
|
||||
* @update gess 11/7/99
|
||||
* @param aDest
|
||||
* @param aSet
|
||||
* @param aEliminateLeading
|
||||
* @param aEliminateTrailing
|
||||
* @return nothing
|
||||
*/
|
||||
void nsStr::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
|
||||
if((aDest.mLength>0) && aSet){
|
||||
PRInt32 theIndex=-1;
|
||||
PRInt32 theMax=aDest.mLength;
|
||||
PRInt32 theSetLen=nsCRT::strlen(aSet);
|
||||
|
||||
if(aEliminateLeading) {
|
||||
while(++theIndex<=theMax) {
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE,theSetLen);
|
||||
if(kNotFound==thePos)
|
||||
break;
|
||||
}
|
||||
if(0<theIndex) {
|
||||
if(theIndex<theMax) {
|
||||
Delete(aDest,0,theIndex);
|
||||
}
|
||||
else StrTruncate(aDest,0);
|
||||
}
|
||||
}
|
||||
|
||||
if(aEliminateTrailing) {
|
||||
theIndex=aDest.mLength;
|
||||
PRInt32 theNewLen=theIndex;
|
||||
while(--theIndex>=0) {
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex); //read at end now...
|
||||
PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE,theSetLen);
|
||||
if(kNotFound<thePos)
|
||||
theNewLen=theIndex;
|
||||
else break;
|
||||
}
|
||||
if(theNewLen<theMax) {
|
||||
StrTruncate(aDest,theNewLen);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
Trim(aDest,aSet,aEliminateLeading,aEliminateTrailing);
|
||||
PRUint32 aNewLen=gCompressChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet);
|
||||
aDest.mLength=aNewLen;
|
||||
NSSTR_SEEN(aDest);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::StripChars(nsStr& aDest,const char* aSet){
|
||||
if((0<aDest.mLength) && (aSet)) {
|
||||
PRUint32 aNewLen=gStripChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet);
|
||||
aDest.mLength=aNewLen;
|
||||
NSSTR_SEEN(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a given substring
|
||||
*
|
||||
* @update gess 2/04/00: added aCount argument to restrict search
|
||||
* @param aDest string to search
|
||||
* @param aTarget is the substring you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @param aCount tells us how many iterations to make from offset; -1 means the full length of the string
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount) {
|
||||
PRInt32 theMaxPos = aDest.mLength-aTarget.mLength; //this is the last pos that is feasible for starting the search, with given lengths...
|
||||
|
||||
if(0<=theMaxPos) {
|
||||
|
||||
if(anOffset<0)
|
||||
anOffset=0;
|
||||
|
||||
if((0<aDest.mLength) && (anOffset<=theMaxPos) && (aTarget.mLength)) {
|
||||
|
||||
if(aCount<0)
|
||||
aCount = MaxInt(theMaxPos,1);
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
PRInt32 aDelta= (aDest.mCharSize == eOneByte) ? 1 : 2;
|
||||
const char* root = aDest.mStr;
|
||||
const char* left = root+(anOffset*aDelta);
|
||||
const char* last = left+((aCount)*aDelta);
|
||||
const char* max = root+(theMaxPos*aDelta);
|
||||
const char* right = (last<max) ? last : max;
|
||||
|
||||
while(left<=right){
|
||||
PRInt32 cmp=(*gCompare[aDest.mCharSize][aTarget.mCharSize])(left,aTarget.mStr,aTarget.mLength,aIgnoreCase);
|
||||
if(0==cmp) {
|
||||
return (left-root)/aDelta;
|
||||
}
|
||||
left+=aDelta;
|
||||
} //while
|
||||
|
||||
} //if
|
||||
}
|
||||
} //if
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a given character
|
||||
*
|
||||
* @update gess 2/04/00: added aCount argument to restrict search
|
||||
* @param aDest string to search
|
||||
* @param char is the character you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @param aCount tell us how many chars to search from offset
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount) {
|
||||
return gFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase,aCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a character found in aSet.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aSet contains a list of chars to be searched for
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
//NS_PRECONDITION(aSet.mLength!=1,kCallFindChar);
|
||||
|
||||
PRInt32 index=(0<=anOffset) ? anOffset-1 : -1;
|
||||
PRInt32 thePos;
|
||||
|
||||
//Note that the search is inverted here. We're scanning aDest, one char at a time
|
||||
//but doing the search against the given set. That's why we use 0 as the offset below.
|
||||
if((0<aDest.mLength) && (0<aSet.mLength)){
|
||||
while(++index<(PRInt32)aDest.mLength) {
|
||||
PRUnichar theChar=GetCharAt(aDest,index);
|
||||
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase,aSet.mLength);
|
||||
if(kNotFound!=thePos)
|
||||
return index;
|
||||
} //while
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Reverse Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverse) for a given substring
|
||||
*
|
||||
* @update gess 2/18/00
|
||||
* @param aDest string to search
|
||||
* @param aTarget is the substring you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search (counting from left)
|
||||
* @param aCount tell us how many iterations to perform from offset
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount) {
|
||||
if(anOffset<0)
|
||||
anOffset=(PRInt32)aDest.mLength-1;
|
||||
|
||||
if(aCount<0)
|
||||
aCount = aDest.mLength;
|
||||
|
||||
if((0<aDest.mLength) && ((PRUint32)anOffset<aDest.mLength) && (aTarget.mLength)) {
|
||||
|
||||
if(0<aCount) {
|
||||
|
||||
PRInt32 aDelta = (aDest.mCharSize == eOneByte) ? 1 : 2;
|
||||
const char* root = aDest.mStr;
|
||||
const char* destLast = root+(aDest.mLength*aDelta); //pts to last char in aDest (likely null)
|
||||
|
||||
const char* rightmost = root+(anOffset*aDelta);
|
||||
const char* min = rightmost-((aCount-1)*aDelta);
|
||||
|
||||
const char* leftmost = (min<root) ? root: min;
|
||||
|
||||
while(leftmost<=rightmost) {
|
||||
//don't forget to divide by delta in next text (bug found by rhp)...
|
||||
if(aTarget.mLength<=PRUint32((destLast-rightmost)/aDelta)) {
|
||||
PRInt32 result=(*gCompare[aDest.mCharSize][aTarget.mCharSize])(rightmost,aTarget.mStr,aTarget.mLength,aIgnoreCase);
|
||||
|
||||
if(0==result) {
|
||||
return (rightmost-root)/aDelta;
|
||||
}
|
||||
} //if
|
||||
rightmost-=aDelta;
|
||||
} //while
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverse) for a given character
|
||||
*
|
||||
* @update gess 2/04/00
|
||||
* @param aDest string to search
|
||||
* @param char is the character you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search; -1 means start at very end (mLength)
|
||||
* @param aCount tell us how many iterations to perform from offset; -1 means use full length.
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount) {
|
||||
return gRFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase,aCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverese) for a character found in aSet.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aSet contains a list of chars to be searched for
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
//NS_PRECONDITION(aSet.mLength!=1,kCallRFindChar);
|
||||
|
||||
PRInt32 index=(0<=anOffset) ? anOffset : aDest.mLength;
|
||||
PRInt32 thePos;
|
||||
|
||||
//note that the search is inverted here. We're scanning aDest, one char at a time
|
||||
//but doing the search against the given set. That's why we use 0 as the offset below.
|
||||
if(0<aDest.mLength) {
|
||||
while(--index>=0) {
|
||||
PRUnichar theChar=GetCharAt(aDest,index);
|
||||
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase,aSet.mLength);
|
||||
if(kNotFound!=thePos)
|
||||
return index;
|
||||
} //while
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare source and dest strings, up to an (optional max) number of chars
|
||||
* @param aDest is the first str to compare
|
||||
* @param aSource is the second str to compare
|
||||
* @param aCount -- if (-1), then we use length of longer string; if (0<aCount) then it gives the max # of chars to compare
|
||||
* @param aIgnorecase tells us whether to search with case sensitivity
|
||||
* @return aDest<aSource=-1;aDest==aSource==0;aDest>aSource=1
|
||||
*/
|
||||
PRInt32 nsStr::StrCompare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) {
|
||||
PRInt32 result=0;
|
||||
|
||||
if(aCount) {
|
||||
PRInt32 minlen=(aSource.mLength<aDest.mLength) ? aSource.mLength : aDest.mLength;
|
||||
|
||||
if(0==minlen) {
|
||||
if ((aDest.mLength == 0) && (aSource.mLength == 0))
|
||||
return 0;
|
||||
if (aDest.mLength == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
PRInt32 theCount = (aCount<0) ? minlen: MinInt(aCount,minlen);
|
||||
result=(*gCompare[aDest.mCharSize][aSource.mCharSize])(aDest.mStr,aSource.mStr,theCount,aIgnoreCase);
|
||||
|
||||
if (0==result) {
|
||||
if(-1==aCount) {
|
||||
|
||||
//Since the caller didn't give us a length to test, and minlen characters matched,
|
||||
//we have to assume that the longer string is greater.
|
||||
|
||||
if (aDest.mLength != aSource.mLength) {
|
||||
//we think they match, but we've only compared minlen characters.
|
||||
//if the string lengths are different, then they don't really match.
|
||||
result = (aDest.mLength<aSource.mLength) ? -1 : 1;
|
||||
}
|
||||
} //if
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the contents of dest at offset with contents of aSource
|
||||
*
|
||||
* @param aDest is the first str to compare
|
||||
* @param aSource is the second str to compare
|
||||
* @param aDestOffset is the offset within aDest where source should be copied
|
||||
* @return error code
|
||||
*/
|
||||
void nsStr::Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 aDestOffset) {
|
||||
if(aDest.mLength && aSource.mLength) {
|
||||
if((aDest.mLength-aDestOffset)>=aSource.mLength) {
|
||||
//if you're here, then both dest and source have valid lengths
|
||||
//and there's enough room in dest (at offset) to contain source.
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,0,aSource.mLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
PRBool nsStr::Alloc(nsStr& aDest,PRUint32 aCount) {
|
||||
|
||||
static int mAllocCount=0;
|
||||
mAllocCount++;
|
||||
|
||||
#ifdef NS_USE_OLD_STRING_ALLOCATION_STRATEGY
|
||||
//we're given the acount value in charunits; now scale up to next multiple.
|
||||
PRUint32 theNewCapacity=kDefaultStringSize;
|
||||
while(theNewCapacity<aCount){
|
||||
theNewCapacity<<=1;
|
||||
}
|
||||
|
||||
aDest.mCapacity=theNewCapacity++;
|
||||
PRUint32 theSize=(theNewCapacity<<aDest.mCharSize);
|
||||
aDest.mStr = (char*)nsMemory::Alloc(theSize);
|
||||
#else
|
||||
// the new strategy is, allocate exact size, double on grows
|
||||
aDest.mCapacity = aCount;
|
||||
aDest.mStr = (char*)nsMemory::Alloc((aCount+1)<<aDest.mCharSize);
|
||||
#endif
|
||||
|
||||
if(aDest.mStr) {
|
||||
aDest.mOwnsBuffer=1;
|
||||
gStringAcquiredMemory=PR_TRUE;
|
||||
}
|
||||
else gStringAcquiredMemory=PR_FALSE;
|
||||
return gStringAcquiredMemory;
|
||||
}
|
||||
|
||||
PRBool nsStr::Free(nsStr& aDest){
|
||||
if(aDest.mStr){
|
||||
if(aDest.mOwnsBuffer){
|
||||
nsMemory::Free(aDest.mStr);
|
||||
}
|
||||
aDest.mStr=0;
|
||||
aDest.mOwnsBuffer=0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsStr::Realloc(nsStr& aDest,PRUint32 aCount){
|
||||
|
||||
nsStr temp;
|
||||
memcpy(&temp,&aDest,sizeof(aDest));
|
||||
|
||||
PRBool result=Alloc(temp,aCount);
|
||||
if(result) {
|
||||
Free(aDest);
|
||||
aDest.mStr=temp.mStr;
|
||||
aDest.mCapacity=temp.mCapacity;
|
||||
aDest.mOwnsBuffer=temp.mOwnsBuffer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve last memory error
|
||||
*
|
||||
* @update gess 10/11/99
|
||||
* @return memory error (usually returns PR_TRUE)
|
||||
*/
|
||||
PRBool nsStr::DidAcquireMemory(void) {
|
||||
return gStringAcquiredMemory;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
CBufDescriptor::CBufDescriptor(char* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=aString;
|
||||
mCharSize=eOneByte;
|
||||
mStackBased=aStackBased;
|
||||
mIsConst=PR_FALSE;
|
||||
mLength=mCapacity=0;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
CBufDescriptor::CBufDescriptor(const char* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eOneByte;
|
||||
mStackBased=aStackBased;
|
||||
mIsConst=PR_TRUE;
|
||||
mLength=mCapacity=0;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CBufDescriptor::CBufDescriptor(PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eTwoByte;
|
||||
mStackBased=aStackBased;
|
||||
mLength=mCapacity=0;
|
||||
mIsConst=PR_FALSE;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
CBufDescriptor::CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eTwoByte;
|
||||
mStackBased=aStackBased;
|
||||
mLength=mCapacity=0;
|
||||
mIsConst=PR_TRUE;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
PRUint32
|
||||
nsStr::HashCode(const nsStr& aDest)
|
||||
{
|
||||
if (aDest.mCharSize == eTwoByte)
|
||||
return nsCRT::HashCode(aDest.mUStr);
|
||||
else
|
||||
return nsCRT::HashCode(aDest.mStr);
|
||||
}
|
||||
|
||||
#ifdef NS_STR_STATS
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef XP_MAC
|
||||
#define isascii(c) ((unsigned)(c) < 0x80)
|
||||
#endif
|
||||
|
||||
void
|
||||
nsStr::Print(const nsStr& aDest, FILE* out, PRBool truncate)
|
||||
{
|
||||
PRInt32 printLen = (PRInt32)aDest.mLength;
|
||||
|
||||
if (aDest.mCharSize == eOneByte) {
|
||||
const char* chars = aDest.mStr;
|
||||
while (printLen-- && (!truncate || *chars != '\n')) {
|
||||
fputc(*chars++, out);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const PRUnichar* chars = aDest.mUStr;
|
||||
while (printLen-- && (!truncate || *chars != '\n')) {
|
||||
if (isascii(*chars))
|
||||
fputc((char)(*chars++), out);
|
||||
else
|
||||
fputc('-', out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// String Usage Statistics Routines
|
||||
|
||||
static PLHashTable* gStringInfo = nsnull;
|
||||
PRLock* gStringInfoLock = nsnull;
|
||||
PRBool gNoStringInfo = PR_FALSE;
|
||||
|
||||
nsStringInfo::nsStringInfo(nsStr& str)
|
||||
: mCount(0)
|
||||
{
|
||||
nsStr::Initialize(mStr, str.mCharSize);
|
||||
nsStr::StrAssign(mStr, str, 0, -1);
|
||||
// nsStr::Print(mStr, stdout);
|
||||
// fputc('\n', stdout);
|
||||
}
|
||||
|
||||
PR_EXTERN(PRHashNumber)
|
||||
nsStr_Hash(const void* key)
|
||||
{
|
||||
nsStr* str = (nsStr*)key;
|
||||
return nsStr::HashCode(*str);
|
||||
}
|
||||
|
||||
PR_EXTERN(PRIntn)
|
||||
nsStr_Compare(const void *v1, const void *v2)
|
||||
{
|
||||
nsStr* str1 = (nsStr*)v1;
|
||||
nsStr* str2 = (nsStr*)v2;
|
||||
return nsStr::StrCompare(*str1, *str2, -1, PR_FALSE) == 0;
|
||||
}
|
||||
|
||||
nsStringInfo*
|
||||
nsStringInfo::GetInfo(nsStr& str)
|
||||
{
|
||||
if (gStringInfo == nsnull) {
|
||||
gStringInfo = PL_NewHashTable(1024,
|
||||
nsStr_Hash,
|
||||
nsStr_Compare,
|
||||
PL_CompareValues,
|
||||
NULL, NULL);
|
||||
gStringInfoLock = PR_NewLock();
|
||||
}
|
||||
PR_Lock(gStringInfoLock);
|
||||
nsStringInfo* info =
|
||||
(nsStringInfo*)PL_HashTableLookup(gStringInfo, &str);
|
||||
if (info == NULL) {
|
||||
gNoStringInfo = PR_TRUE;
|
||||
info = new nsStringInfo(str);
|
||||
if (info) {
|
||||
PLHashEntry* e = PL_HashTableAdd(gStringInfo, &info->mStr, info);
|
||||
if (e == NULL) {
|
||||
delete info;
|
||||
info = NULL;
|
||||
}
|
||||
}
|
||||
gNoStringInfo = PR_FALSE;
|
||||
}
|
||||
PR_Unlock(gStringInfoLock);
|
||||
return info;
|
||||
}
|
||||
|
||||
void
|
||||
nsStringInfo::Seen(nsStr& str)
|
||||
{
|
||||
if (!gNoStringInfo) {
|
||||
nsStringInfo* info = GetInfo(str);
|
||||
info->mCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsStringInfo::Report(FILE* out)
|
||||
{
|
||||
if (gStringInfo) {
|
||||
fprintf(out, "\n== String Stats\n");
|
||||
PL_HashTableEnumerateEntries(gStringInfo, nsStringInfo::ReportEntry, out);
|
||||
}
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsStringInfo::ReportEntry(PLHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
nsStringInfo* entry = (nsStringInfo*)he->value;
|
||||
FILE* out = (FILE*)arg;
|
||||
|
||||
fprintf(out, "%d ==> (%d) ", entry->mCount, entry->mStr.mLength);
|
||||
nsStr::Print(entry->mStr, out, PR_TRUE);
|
||||
fputc('\n', out);
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
#endif // NS_STR_STATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
527
mozilla/string/obsolete/nsStr.h
Normal file
527
mozilla/string/obsolete/nsStr.h
Normal file
@@ -0,0 +1,527 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rick Gessner <rickg@netscape.com> (original author)
|
||||
* Scott Collins <scc@mozilla.org>
|
||||
*/
|
||||
|
||||
/* nsStr.h --- the underlying buffer for rickg's original string implementations;
|
||||
these classes will be replaced by the new shared-buffer string (see bug #53065)
|
||||
*/
|
||||
|
||||
#ifndef _nsStr
|
||||
#define _nsStr
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
1. There are two philosophies to building string classes:
|
||||
A. Hide the underlying buffer & offer API's allow indirect iteration
|
||||
B. Reveal underlying buffer, risk corruption, but gain performance
|
||||
|
||||
We chose the option B for performance reasons.
|
||||
|
||||
2 Our internal buffer always holds capacity+1 bytes.
|
||||
|
||||
The nsStr struct is a simple structure (no methods) that contains
|
||||
the necessary info to be described as a string. This simple struct
|
||||
is manipulated by the static methods provided in this class.
|
||||
(Which effectively makes this a library that works on structs).
|
||||
|
||||
There are also object-based versions called nsString and nsAutoString
|
||||
which use nsStr but makes it look at feel like an object.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
ASSUMPTIONS:
|
||||
|
||||
1. nsStrings and nsAutoString are always null terminated. However,
|
||||
since it maintains a length byte, you can store NULL's inside
|
||||
the string. Just be careful passing such buffers to 3rd party
|
||||
API's that assume that NULL always terminate the buffer.
|
||||
|
||||
2. nsCStrings can be upsampled into nsString without data loss
|
||||
|
||||
3. Char searching is faster than string searching. Use char interfaces
|
||||
if your needs will allow it.
|
||||
|
||||
4. It's easy to use the stack for nsAutostring buffer storage (fast too!).
|
||||
See the CBufDescriptor class in this file.
|
||||
|
||||
5. If you don't provide the optional count argument to Append() and Insert(),
|
||||
the method will assume that the given buffer is terminated by the first
|
||||
NULL it encounters.
|
||||
|
||||
6. Downsampling from nsString to nsCString can be lossy -- avoid it if possible!
|
||||
|
||||
7. Calls to ToNewCString() and ToNewUnicode() should be matched with calls to nsMemory::Free().
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
|
||||
AND NOW FOR SOME GENERAL DOCUMENTATION ON STRING USAGE...
|
||||
|
||||
The fundamental datatype in the string library is nsStr. It's a structure that
|
||||
provides the buffer storage and meta-info. It also provides a C-style library
|
||||
of functions for direct manipulation (for those of you who prefer K&R to Bjarne).
|
||||
|
||||
Here's a diagram of the class hierarchy:
|
||||
|
||||
nsStr
|
||||
|___nsString
|
||||
| |
|
||||
| ------nsAutoString
|
||||
|
|
||||
|___nsCString
|
||||
|
|
||||
------nsCAutoString
|
||||
|
||||
Why so many string classes? The 4 variants give you the control you need to
|
||||
determine the best class for your purpose. There are 2 dimensions to this
|
||||
flexibility: 1) stack vs. heap; and 2) 1-byte chars vs. 2-byte chars.
|
||||
|
||||
Note: While nsAutoString and nsCAutoString begin life using stack-based storage,
|
||||
they may not stay that way. Like all nsString classes, autostrings will
|
||||
automatically grow to contain the data you provide. When autostrings
|
||||
grow beyond their intrinsic buffer, they switch to heap based allocations.
|
||||
(We avoid alloca to avoid considerable platform difficulties; see the
|
||||
GNU documentation for more details).
|
||||
|
||||
I should also briefly mention that all the string classes use a "memory agent"
|
||||
object to perform memory operations. This class proxies the standard nsMemory
|
||||
for actual memory calls, but knows the structure of nsStr making heap operations
|
||||
more localized.
|
||||
|
||||
|
||||
CHOOSING A STRING CLASS:
|
||||
|
||||
In order to choose a string class for you purpose, use this handy table:
|
||||
|
||||
heap-based stack-based
|
||||
-----------------------------------
|
||||
ascii data | nsCString nsCAutoString |
|
||||
|----------------------------------
|
||||
unicode data | nsString nsAutoString |
|
||||
-----------------------------------
|
||||
|
||||
|
||||
Note: The i18n folks will stenuously object if we get too carried away with the
|
||||
use of nsCString's that pass interface boundaries. Try to limit your
|
||||
use of these to external interfaces that demand them, or for your own
|
||||
private purposes in cases where they'll never be seen by humans.
|
||||
|
||||
|
||||
--- FAQ ---
|
||||
|
||||
Q. When should I use nsCString instead of nsString?
|
||||
|
||||
A. You should really try to stick with nsString, so that we stay as unicode
|
||||
compliant as possible. But there are cases where an interface you use requires
|
||||
a char*. In such cases, it's fair to use nsCString.
|
||||
|
||||
Q. I know that my string is going to be a certain size. Can I pre-size my nsString?
|
||||
|
||||
A. Yup, here's how:
|
||||
|
||||
{
|
||||
nsString mBuffer;
|
||||
mBuffer.SetCapacity(aReasonableSize);
|
||||
}
|
||||
|
||||
Q. Should nsAutoString or nsCAutoString ever live on the heap?
|
||||
|
||||
A. That would be counterproductive. The point of nsAutoStrings is to preallocate your
|
||||
buffers, and to auto-destroy the string when it goes out of scope.
|
||||
|
||||
Q. I already have a char*. Can I use the nsString functionality on that buffer?
|
||||
|
||||
A. Yes you can -- by using an intermediate class called CBufDescriptor.
|
||||
The CBufDescriptor class is used to tell nsString about an external buffer (heap or stack) to use
|
||||
instead of it's own internal buffers. Here's an example:
|
||||
|
||||
{
|
||||
char theBuffer[256];
|
||||
CBufDescritor theBufDecriptor( theBuffer, PR_TRUE, sizeof(theBuffer), 0);
|
||||
nsCAutoString s3( theBufDescriptor );
|
||||
s3="HELLO, my name is inigo montoya, you killed my father, prepare to die!.";
|
||||
}
|
||||
|
||||
The assignment statment to s3 will cause the given string to be written to your
|
||||
stack-based buffer via the normal nsString/nsCString interfaces. Cool, huh?
|
||||
Note however that just like any other nsStringXXX use, if you write more data
|
||||
than will fit in the buffer, a visit to the heap manager will be in order.
|
||||
|
||||
|
||||
Q. What is the simplest way to get from a char* to PRUnichar*?
|
||||
|
||||
A. The simplest way is by construction (or assignment):
|
||||
|
||||
{
|
||||
char* theBuf = "hello there";
|
||||
nsAutoString foo(theBuf);
|
||||
}
|
||||
|
||||
If you don't want the char* to be copied into the nsAutoString, the use a
|
||||
CBufDescriptor instead.
|
||||
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsMemory.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "plhash.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
enum eCharSize {eOneByte=0,eTwoByte=1};
|
||||
#define kDefaultCharSize eTwoByte
|
||||
#define kRadix10 (10)
|
||||
#define kRadix16 (16)
|
||||
#define kAutoDetect (100)
|
||||
#define kRadixUnknown (kAutoDetect+1)
|
||||
#define IGNORE_CASE (PR_TRUE)
|
||||
|
||||
const PRInt32 kDefaultStringSize = 64;
|
||||
const PRInt32 kNotFound = -1;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
class NS_COM CBufDescriptor {
|
||||
public:
|
||||
CBufDescriptor(char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(const char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(PRUnichar* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
|
||||
char* mBuffer;
|
||||
eCharSize mCharSize;
|
||||
PRUint32 mCapacity;
|
||||
PRInt32 mLength;
|
||||
PRBool mStackBased;
|
||||
PRBool mIsConst;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
struct NS_COM nsStr {
|
||||
|
||||
nsStr() {
|
||||
MOZ_COUNT_CTOR(nsStr);
|
||||
}
|
||||
|
||||
~nsStr() {
|
||||
MOZ_COUNT_DTOR(nsStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,eCharSize aCharSize);
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer);
|
||||
|
||||
/**
|
||||
* This method destroys the given nsStr, and *MAY*
|
||||
* deallocate it's memory depending on the setting
|
||||
* of the internal mOwnsBUffer flag.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used to the nsStr
|
||||
*/
|
||||
static void Destroy(nsStr& aDest);
|
||||
|
||||
/**
|
||||
* These methods are where memory allocation/reallocation occur.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used on the nsStr
|
||||
* @return
|
||||
*/
|
||||
static PRBool EnsureCapacity(nsStr& aString,PRUint32 aNewLength);
|
||||
static PRBool GrowCapacity(nsStr& aString,PRUint32 aNewLength);
|
||||
|
||||
/**
|
||||
* These methods are used to append content to the given nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void StrAppend(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* These methods are used to assign contents of a source string to dest string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void StrAssign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* These methods are used to insert content from source string to the dest nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to insert
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void StrInsert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* This method deletes chars from the given str.
|
||||
* The given allocator may choose to resize the str as well.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be deleted from
|
||||
* @param aDestOffset tells us where in dest to start deleting
|
||||
* @param aCount tells us the (max) # of chars to delete
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount);
|
||||
|
||||
/**
|
||||
* This method is used to truncate the given string.
|
||||
* The given allocator may choose to resize the str as well (but it's not likely).
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void StrTruncate(nsStr& aDest,PRUint32 aDestOffset);
|
||||
|
||||
/**
|
||||
* This method is used to perform a case conversion on the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be case shifted
|
||||
* @param toUpper tells us to go upper vs. lower
|
||||
*/
|
||||
static void ChangeCase(nsStr& aDest,PRBool aToUpper);
|
||||
|
||||
|
||||
/**
|
||||
* This method trims chars (given in aSet) from the edges of given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aChar is the replacement char
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void CompressSet(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method removes all occurances of chars in given set from aDest
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aChar is the replacement char
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void StripChars(nsStr& aDest,const char* aSet);
|
||||
|
||||
/**
|
||||
* This method compares the data bewteen two nsStr's
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
static PRInt32 StrCompare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase);
|
||||
|
||||
/**
|
||||
* These methods scan the given string for 1 or more chars in a given direction
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be searched to
|
||||
* @param aSource (or aChar) is the substr we're looking to find
|
||||
* @param aIgnoreCase tells us whether to search in a case-sensitive manner
|
||||
* @param anOffset tells us where in the dest string to start searching
|
||||
* @return the index of the source (substr) in dest, or -1 (kNotFound) if not found.
|
||||
*/
|
||||
static PRInt32 FindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
|
||||
static PRInt32 FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
|
||||
static PRInt32 FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
|
||||
static PRInt32 RFindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
|
||||
static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
|
||||
static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
|
||||
static void Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 anOffset);
|
||||
|
||||
static PRBool DidAcquireMemory(void);
|
||||
|
||||
/**
|
||||
* Returns a hash code for the string for use in a PLHashTable.
|
||||
*/
|
||||
static PRUint32 HashCode(const nsStr& aDest);
|
||||
|
||||
#ifdef NS_STR_STATS
|
||||
/**
|
||||
* Prints an nsStr. If truncate is true, the string is only printed up to
|
||||
* the first newline. (Note: The current implementation doesn't handle
|
||||
* non-ascii unicode characters.)
|
||||
*/
|
||||
static void Print(const nsStr& aDest, FILE* out, PRBool truncate = PR_FALSE);
|
||||
#endif
|
||||
|
||||
PRUint32 mLength;
|
||||
PRUint32 mCapacity;
|
||||
eCharSize mCharSize;
|
||||
PRBool mOwnsBuffer;
|
||||
|
||||
union {
|
||||
char* mStr;
|
||||
PRUnichar* mUStr;
|
||||
};
|
||||
|
||||
private:
|
||||
static PRBool Alloc(nsStr& aString,PRUint32 aCount);
|
||||
static PRBool Realloc(nsStr& aString,PRUint32 aCount);
|
||||
static PRBool Free(nsStr& aString);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************************************************
|
||||
A couple of tiny helper methods used in the string classes.
|
||||
**************************************************************/
|
||||
|
||||
inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt1 : anInt2;
|
||||
}
|
||||
|
||||
inline PRInt32 MaxInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt2 : anInt1;
|
||||
}
|
||||
|
||||
inline void AddNullTerminator(nsStr& aDest) {
|
||||
if(eTwoByte==aDest.mCharSize)
|
||||
aDest.mUStr[aDest.mLength]=0;
|
||||
else aDest.mStr[aDest.mLength]=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: don't use |Recycle|, just call |nsMemory::Free| directly
|
||||
*
|
||||
* Return the given buffer to the heap manager. Calls allocator::Free()
|
||||
* @return string length
|
||||
*/
|
||||
inline void Recycle( char* aBuffer) { nsMemory::Free(aBuffer); }
|
||||
inline void Recycle( PRUnichar* aBuffer) { nsMemory::Free(aBuffer); }
|
||||
|
||||
/**
|
||||
* This method is used to access a given char in the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param anIndex tells us where in dest to get the char from
|
||||
* @return the given char, or 0 if anIndex is out of range
|
||||
*/
|
||||
inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex) {
|
||||
if(anIndex<aDest.mLength) {
|
||||
return (eTwoByte==aDest.mCharSize) ? aDest.mUStr[anIndex] : (PRUnichar)aDest.mStr[anIndex];
|
||||
}//if
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NS_STR_STATS
|
||||
|
||||
class nsStringInfo {
|
||||
public:
|
||||
nsStringInfo(nsStr& str);
|
||||
~nsStringInfo() {}
|
||||
|
||||
static nsStringInfo* GetInfo(nsStr& str);
|
||||
|
||||
static void Seen(nsStr& str);
|
||||
|
||||
static void Report(FILE* out = stdout);
|
||||
|
||||
static PRIntn ReportEntry(PLHashEntry *he, PRIntn i, void *arg);
|
||||
|
||||
protected:
|
||||
nsStr mStr;
|
||||
PRUint32 mCount;
|
||||
};
|
||||
|
||||
#define NSSTR_SEEN(str) nsStringInfo::Seen(str)
|
||||
|
||||
#else // !NS_STR_STATS
|
||||
|
||||
#define NSSTR_SEEN(str) /* nothing */
|
||||
|
||||
#endif // !NS_STR_STATS
|
||||
|
||||
#endif // _nsStr
|
||||
1620
mozilla/string/obsolete/nsString.cpp
Normal file
1620
mozilla/string/obsolete/nsString.cpp
Normal file
File diff suppressed because it is too large
Load Diff
583
mozilla/string/obsolete/nsString.h
Normal file
583
mozilla/string/obsolete/nsString.h
Normal file
@@ -0,0 +1,583 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rick Gessner <rickg@netscape.com> (original author)
|
||||
* Scott Collins <scc@mozilla.org>
|
||||
*/
|
||||
|
||||
/* nsString.h --- rickg's original strings of 1-byte chars, |nsCString| and |nsCAutoString|;
|
||||
these classes will be replaced by the new shared-buffer string (see bug #53065)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _nsCString_
|
||||
#define _nsCString_
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
See nsStr.h for a more general description of string classes.
|
||||
|
||||
This version of the nsString class offers many improvements over the
|
||||
original version:
|
||||
1. Wide and narrow chars
|
||||
2. Allocators
|
||||
3. Much smarter autostrings
|
||||
4. Subsumable strings
|
||||
***********************************************************************/
|
||||
|
||||
#include "nsString2.h"
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <stdio.h>
|
||||
#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 nsAFlatCString,
|
||||
public nsStr {
|
||||
|
||||
protected:
|
||||
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const;
|
||||
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
virtual const char* get() const { return mStr; }
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
nsCString();
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsCString
|
||||
*/
|
||||
nsCString(const nsCString& aString);
|
||||
|
||||
explicit nsCString( const nsACString& );
|
||||
|
||||
explicit nsCString(const char*);
|
||||
nsCString(const char*, PRInt32);
|
||||
|
||||
/**
|
||||
* This constructor takes a subsumestr
|
||||
* @param reference to subsumestr
|
||||
*/
|
||||
explicit nsCString(nsSubsumeCStr& aSubsumeStr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
*/
|
||||
virtual ~nsCString();
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual PRUint32 Length() const { return mLength; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
|
||||
/**
|
||||
* Call this method if you want to force a different string capacity
|
||||
* @update gess7/30/98
|
||||
* @param aLength -- contains new length for mStr
|
||||
* @return
|
||||
*/
|
||||
void SetLength(PRUint32 aLength);
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetCapacity(PRUint32 aLength);
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
|
||||
|
||||
/**********************************************************************
|
||||
Lexomorphic transforms...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in aOut
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToLowerCase(nsCString& aString) const;
|
||||
|
||||
/**
|
||||
* Converts chars in this to uppercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in a given output string
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToUpperCase(nsCString& aString) const;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
void StripChars(const char* aSet);
|
||||
void StripChar(PRUnichar aChar,PRInt32 anOffset=0);
|
||||
void StripChar(char aChar,PRInt32 anOffset=0) { StripChar((PRUnichar) (unsigned char)aChar,anOffset); }
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
void StripWhitespace();
|
||||
|
||||
/**
|
||||
* swaps occurence of 1 string for another
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
void ReplaceChar(PRUnichar aOldChar,PRUnichar aNewChar);
|
||||
void ReplaceChar(const char* aSet,PRUnichar aNewChar);
|
||||
|
||||
void ReplaceSubstring(const nsCString& aTarget,const nsCString& aNewValue);
|
||||
void ReplaceSubstring(const char* aTarget,const char* aNewValue);
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @param aEliminateLeading
|
||||
* @param aEliminateTrailing
|
||||
* @param aIgnoreQuotes
|
||||
* @return this
|
||||
*/
|
||||
void Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE,PRBool aIgnoreQuotes=PR_FALSE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
void CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**********************************************************************
|
||||
string conversion methods...
|
||||
*********************************************************************/
|
||||
//#ifndef STANDALONE_STRING_TESTS
|
||||
operator const char*() const {return (const char*)mStr;}
|
||||
//#endif
|
||||
|
||||
/**
|
||||
* This method constructs a new nsCString that is a clone
|
||||
* of this string.
|
||||
*
|
||||
*/
|
||||
nsCString* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ISOLatin1 clone of this string
|
||||
* Note that calls to this method should be matched with calls to
|
||||
* |nsMemory::Free|.
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Creates a unicode clone of this string
|
||||
* Note that calls to this method should be matched with calls to
|
||||
* |nsMemory::Free|.
|
||||
* @return ptr to new unicode string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* NOTE: This only copies as many chars as will fit in given buffer (clips)
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
|
||||
* @return int rep of string value, and possible (out) error code
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* assign given string to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param aCount is the length of the given str (or -1) if you want me to determine its length
|
||||
* NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
|
||||
nsCString& operator=( const nsCString& aString ) { Assign(aString); 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 nsAString& aString );
|
||||
void AssignWithConversion(PRUnichar);
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @param aCount -- number of chars to copy; -1 tells us to compute the strlen for you
|
||||
* NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated.
|
||||
*
|
||||
* @return number of chars copied
|
||||
*/
|
||||
|
||||
void AppendWithConversion(const nsString&, PRInt32=-1);
|
||||
void AppendWithConversion(PRUnichar aChar);
|
||||
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 );
|
||||
|
||||
|
||||
void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset);
|
||||
// Why no |InsertWithConversion(PRUnichar*)|?
|
||||
|
||||
#if 0
|
||||
virtual void do_AppendFromReadable( const nsACString& );
|
||||
virtual void do_InsertFromReadable( const nsACString&, PRUint32 );
|
||||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given charset
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=0) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @param aCount tells us how many chars to compare
|
||||
* @return -1,0,1
|
||||
*/
|
||||
PRInt32 CompareWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRInt32 CompareWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
PRBool EqualsWithConversion(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsIgnoreCase(const PRUnichar* aString,PRInt32 aCount=-1) const;
|
||||
|
||||
|
||||
void DebugDump(void) const;
|
||||
|
||||
private:
|
||||
// NOT TO BE IMPLEMENTED
|
||||
// these signatures help clients not accidentally call the wrong thing helped by C++ automatic integral promotion
|
||||
void operator=( PRUnichar );
|
||||
void AssignWithConversion( char );
|
||||
void AssignWithConversion( const char*, PRInt32=-1 );
|
||||
void AppendWithConversion( char );
|
||||
void InsertWithConversion( char, PRUint32 );
|
||||
};
|
||||
|
||||
// NS_DEF_STRING_COMPARISON_OPERATORS(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);
|
||||
//virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Here comes the AutoString class which uses internal memory
|
||||
(typically found on the stack) for its default buffer.
|
||||
If the buffer needs to grow, it gets reallocated on the heap.
|
||||
**************************************************************/
|
||||
|
||||
class NS_COM nsCAutoString : public nsCString {
|
||||
public:
|
||||
|
||||
virtual ~nsCAutoString();
|
||||
|
||||
nsCAutoString();
|
||||
explicit nsCAutoString(const nsCString& );
|
||||
explicit nsCAutoString(const nsACString& aString);
|
||||
explicit nsCAutoString(const char* aString);
|
||||
nsCAutoString(const char* aString,PRInt32 aLength);
|
||||
explicit nsCAutoString(const CBufDescriptor& aBuffer);
|
||||
|
||||
#if defined(AIX) || defined(XP_OS2_VACPP)
|
||||
explicit nsCAutoString(const nsSubsumeCStr& aSubsumeStr); // AIX and VAC++ require a const
|
||||
#else
|
||||
explicit nsCAutoString(nsSubsumeCStr& aSubsumeStr);
|
||||
#endif // AIX || XP_OS2_VACPP
|
||||
|
||||
|
||||
nsCAutoString& operator=( const nsCAutoString& aString ) { Assign(aString); return *this; }
|
||||
private:
|
||||
void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED
|
||||
public:
|
||||
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; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
char mBuffer[kDefaultStringSize];
|
||||
};
|
||||
|
||||
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
|
||||
|
||||
/**
|
||||
* A helper class that converts a UCS2 string to UTF8
|
||||
*/
|
||||
class NS_COM NS_ConvertUCS2toUTF8
|
||||
: public nsCAutoString
|
||||
/*
|
||||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
NS_ConvertUCS2toUTF8( const PRUnichar* aString )
|
||||
{
|
||||
Append( aString, ~PRUint32(0) /* MAXINT */);
|
||||
}
|
||||
|
||||
NS_ConvertUCS2toUTF8( const PRUnichar* aString, PRUint32 aLength )
|
||||
{
|
||||
Append( aString, aLength );
|
||||
}
|
||||
|
||||
explicit
|
||||
NS_ConvertUCS2toUTF8( PRUnichar aChar )
|
||||
{
|
||||
Append( &aChar, 1 );
|
||||
}
|
||||
|
||||
explicit NS_ConvertUCS2toUTF8( const nsAString& aString );
|
||||
|
||||
protected:
|
||||
void Append( const PRUnichar* aString, PRUint32 aLength );
|
||||
|
||||
private:
|
||||
// NOT TO BE IMPLEMENTED
|
||||
NS_ConvertUCS2toUTF8( char );
|
||||
operator const char*() const; // use |get()|
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
It differs from a normal string in that it doesn't use normal
|
||||
copy semantics when another string is assign to this.
|
||||
Instead, it "steals" the contents of the source string.
|
||||
|
||||
This is very handy for returning nsString classes as part of
|
||||
an operator+(...) for example, in that it cuts down the number
|
||||
of copy operations that must occur.
|
||||
|
||||
You should probably not use this class unless you really know
|
||||
what you're doing.
|
||||
***************************************************************/
|
||||
class NS_COM nsSubsumeCStr : public nsCString {
|
||||
public:
|
||||
explicit nsSubsumeCStr(nsStr& aString);
|
||||
nsSubsumeCStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
|
||||
nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); 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:
|
||||
void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1913
mozilla/string/obsolete/nsString2.cpp
Normal file
1913
mozilla/string/obsolete/nsString2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
666
mozilla/string/obsolete/nsString2.h
Normal file
666
mozilla/string/obsolete/nsString2.h
Normal file
@@ -0,0 +1,666 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rick Gessner <rickg@netscape.com> (original author)
|
||||
* Scott Collins <scc@mozilla.org>
|
||||
*/
|
||||
|
||||
/* nsString2.h --- rickg's original strings of 2-byte chars, |nsString| and |nsAutoString|;
|
||||
these classes will be replaced by the new shared-buffer string (see bug #53065)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _nsString_
|
||||
#define _nsString_
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
See nsStr.h for a more general description of string classes.
|
||||
|
||||
This version of the nsString class offers many improvements over the
|
||||
original version:
|
||||
1. Wide and narrow chars
|
||||
2. Allocators
|
||||
3. Much smarter autostrings
|
||||
4. Subsumable strings
|
||||
***********************************************************************/
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <stdio.h>
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsStr.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#ifndef nsAFlatString_h___
|
||||
#include "nsAFlatString.h"
|
||||
#endif
|
||||
|
||||
#ifdef STANDALONE_MI_STRING_TESTS
|
||||
class nsAFlatString { public: virtual ~nsAString() { } };
|
||||
#endif
|
||||
|
||||
class nsISizeOfHandler;
|
||||
|
||||
|
||||
#define nsString2 nsString
|
||||
#define nsAutoString2 nsAutoString
|
||||
|
||||
class NS_COM nsSubsumeStr;
|
||||
|
||||
class NS_COM nsString :
|
||||
public nsAFlatString,
|
||||
public nsStr {
|
||||
|
||||
protected:
|
||||
virtual const nsBufferHandle<PRUnichar>* GetFlatBufferHandle() const;
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
virtual const PRUnichar* get() const { return GetUnicode(); }
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
nsString();
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsString
|
||||
*/
|
||||
nsString(const nsString& aString);
|
||||
|
||||
explicit nsString(const nsAString&);
|
||||
|
||||
explicit nsString(const PRUnichar*);
|
||||
nsString(const PRUnichar*, PRInt32);
|
||||
|
||||
|
||||
/**
|
||||
* This constructor takes a subsumestr
|
||||
* @param reference to subsumestr
|
||||
*/
|
||||
#if defined(AIX) || defined(XP_OS2_VACPP)
|
||||
explicit nsString(const nsSubsumeStr& aSubsumeStr); // AIX and VAC++ require a const here
|
||||
#else
|
||||
explicit nsString(nsSubsumeStr& aSubsumeStr);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
*/
|
||||
virtual ~nsString();
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual PRUint32 Length() const { return mLength; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
/**
|
||||
* Call this method if you want to force a different string length
|
||||
* @update gess7/30/98
|
||||
* @param aLength -- contains new length for mStr
|
||||
* @return
|
||||
*/
|
||||
void SetLength(PRUint32 aLength);
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetCapacity(PRUint32 aLength);
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsUnicode(void) const {
|
||||
PRBool result=PRBool(mCharSize==eTwoByte);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Getters/Setters...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Retrieve const ptr to internal buffer; DO NOT TRY TO FREE IT!
|
||||
*/
|
||||
const char* GetBuffer(void) const;
|
||||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
/**
|
||||
* Set nth character.
|
||||
*/
|
||||
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Lexomorphic transforms...
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in aOut
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToLowerCase(nsString& aString) const;
|
||||
|
||||
/**
|
||||
* Converts chars in this to uppercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in a given output string
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToUpperCase(nsString& aString) const;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
void StripChars( const char* aSet );
|
||||
void StripChar( PRUnichar aChar, PRInt32 anOffset=0 );
|
||||
void StripChar( char aChar, PRInt32 anOffset=0 ) { StripChar((PRUnichar) (unsigned char)aChar,anOffset); }
|
||||
void StripChar( PRInt32 anInt, PRInt32 anOffset=0 ) { StripChar((PRUnichar)anInt,anOffset); }
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
void StripWhitespace();
|
||||
|
||||
/**
|
||||
* swaps occurence of 1 string for another
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
void ReplaceChar( PRUnichar anOldChar, PRUnichar aNewChar );
|
||||
void ReplaceChar( const char* aSet, PRUnichar aNewChar );
|
||||
|
||||
void ReplaceSubstring( const nsString& aTarget, const nsString& aNewValue );
|
||||
void ReplaceSubstring( const PRUnichar* aTarget, const PRUnichar* aNewValue );
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @param aEliminateLeading
|
||||
* @param aEliminateTrailing
|
||||
* @param aIgnoreQuotes
|
||||
* @return this
|
||||
*/
|
||||
void Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE,PRBool aIgnoreQuotes=PR_FALSE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
void CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**********************************************************************
|
||||
string conversion methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* This method constructs a new nsString is a clone of this string.
|
||||
*
|
||||
*/
|
||||
nsString* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ISOLatin1 clone of this string
|
||||
* Note that calls to this method should be matched with calls to
|
||||
* |nsMemory::Free|.
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Creates an UTF8 clone of this string
|
||||
* Note that calls to this method should be matched with calls to
|
||||
* |nsMemory::Free|.
|
||||
* @return ptr to new null-terminated UTF8 string
|
||||
*/
|
||||
char* ToNewUTF8String() const;
|
||||
|
||||
/**
|
||||
* Creates a unicode clone of this string
|
||||
* Note that calls to this method should be matched with calls to
|
||||
* |nsMemory::Free|.
|
||||
* @return ptr to new unicode string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* NOTE: This only copies as many chars as will fit in given buffer (clips)
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
|
||||
* @return int rep of string value, and possible (out) error code
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* assign given string to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param aCount is the length of the given str (or -1) if you want me to determine its length
|
||||
* NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated.
|
||||
|
||||
* @return this
|
||||
*/
|
||||
|
||||
nsString& operator=( const nsString& aString ) { Assign(aString); 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; }
|
||||
|
||||
void AssignWithConversion(char);
|
||||
void AssignWithConversion(const char*);
|
||||
void AssignWithConversion(const char*, PRInt32);
|
||||
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
* This version computes the length of your given string
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @return number of chars copied
|
||||
*/
|
||||
|
||||
void AppendInt(PRInt32, PRInt32=10); //radix=8,10 or 16
|
||||
void AppendFloat(double);
|
||||
void AppendWithConversion(const char*, PRInt32=-1);
|
||||
void AppendWithConversion(char);
|
||||
|
||||
virtual void do_AppendFromElement( PRUnichar );
|
||||
|
||||
|
||||
//void InsertWithConversion(char);
|
||||
void InsertWithConversion(const char*, PRUint32, PRInt32=-1);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
//PRInt32 Find(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given charset
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const;
|
||||
PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=0) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
PRInt32 RFind(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param aCount tells us how many iterations to make starting at the given offset
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
//PRInt32 RFind(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @param aCount tells us how many chars to compare
|
||||
* @return -1,0,1
|
||||
*/
|
||||
|
||||
PRInt32 CompareWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRInt32 CompareWithConversion(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRInt32 CompareWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
PRBool EqualsWithConversion(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsAtom(/*FIX: const */nsIAtom* anAtom,PRBool aIgnoreCase) const;
|
||||
|
||||
PRBool EqualsIgnoreCase(const nsString& aString) const;
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsIgnoreCase(/*FIX: const */nsIAtom *aAtom) const;
|
||||
|
||||
|
||||
/**
|
||||
* Determine if given buffer is plain ascii
|
||||
*
|
||||
* @param aBuffer -- if null, then we test *this, otherwise we test given buffer
|
||||
* @return TRUE if is all ascii chars or if strlen==0
|
||||
*/
|
||||
PRBool IsASCII(const PRUnichar* aBuffer=0);
|
||||
|
||||
void DebugDump(void) const;
|
||||
|
||||
/**
|
||||
* Determine if given char is a valid space character
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if is valid space char
|
||||
*/
|
||||
static PRBool IsSpace(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char in valid alpha range
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if in alpha range
|
||||
*/
|
||||
static PRBool IsAlpha(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char is valid digit
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if char is a valid digit
|
||||
*/
|
||||
static PRBool IsDigit(PRUnichar ch);
|
||||
|
||||
private:
|
||||
// NOT TO BE IMPLEMENTED
|
||||
// these signatures help clients not accidentally call the wrong thing helped by C++ automatic integral promotion
|
||||
void operator=( char );
|
||||
void AssignWithConversion( PRUnichar );
|
||||
void AssignWithConversion( const PRUnichar*, PRInt32=-1 );
|
||||
void AppendWithConversion( PRUnichar );
|
||||
void AppendWithConversion( const PRUnichar*, PRInt32=-1 );
|
||||
void InsertWithConversion( const PRUnichar*, PRUint32, PRInt32=-1 );
|
||||
};
|
||||
|
||||
// NS_DEF_STRING_COMPARISON_OPERATORS(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);
|
||||
//virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
/**************************************************************
|
||||
Here comes the AutoString class which uses internal memory
|
||||
(typically found on the stack) for its default buffer.
|
||||
If the buffer needs to grow, it gets reallocated on the heap.
|
||||
**************************************************************/
|
||||
|
||||
class NS_COM nsAutoString : public nsString {
|
||||
public:
|
||||
|
||||
virtual ~nsAutoString();
|
||||
nsAutoString();
|
||||
nsAutoString(const nsAutoString& aString);
|
||||
explicit nsAutoString(const nsAString& aString);
|
||||
explicit nsAutoString(const nsString& aString);
|
||||
explicit nsAutoString(const PRUnichar* aString);
|
||||
nsAutoString(const PRUnichar* aString,PRInt32 aLength);
|
||||
explicit nsAutoString(PRUnichar aChar);
|
||||
explicit nsAutoString(const CBufDescriptor& aBuffer);
|
||||
|
||||
#if defined(AIX) || defined(XP_OS2_VACPP)
|
||||
explicit nsAutoString(const nsSubsumeStr& aSubsumeStr); // AIX and VAC++ requires a const
|
||||
#else
|
||||
explicit nsAutoString(nsSubsumeStr& aSubsumeStr);
|
||||
#endif // AIX || XP_OS2_VACPP
|
||||
|
||||
|
||||
nsAutoString& operator=( const nsAutoString& aString ) { Assign(aString); return *this; }
|
||||
private:
|
||||
void operator=( char ); // NOT TO BE IMPLEMENTED
|
||||
public:
|
||||
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; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
char mBuffer[kDefaultStringSize<<eTwoByte];
|
||||
};
|
||||
|
||||
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsAutoString, PRUnichar)
|
||||
|
||||
class NS_COM NS_ConvertASCIItoUCS2
|
||||
: public nsAutoString
|
||||
/*
|
||||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
explicit NS_ConvertASCIItoUCS2( const char* );
|
||||
NS_ConvertASCIItoUCS2( const char*, PRUint32 );
|
||||
explicit NS_ConvertASCIItoUCS2( char );
|
||||
|
||||
#if 0
|
||||
operator const nsLocalString() const
|
||||
{
|
||||
return nsLocalString(mUStr, mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
// NOT TO BE IMPLEMENTED
|
||||
NS_ConvertASCIItoUCS2( PRUnichar );
|
||||
};
|
||||
|
||||
class NS_COM NS_ConvertUTF8toUCS2
|
||||
: public nsAutoString
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
NS_ConvertUTF8toUCS2( const char* aCString )
|
||||
{
|
||||
Init( aCString, ~PRUint32(0) /* MAXINT */ );
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUCS2( const char* aCString, PRUint32 aLength )
|
||||
{
|
||||
Init( aCString, aLength );
|
||||
}
|
||||
|
||||
explicit
|
||||
NS_ConvertUTF8toUCS2( char aChar )
|
||||
{
|
||||
Init( &aChar, 1 );
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init( const char* aCString, PRUint32 aLength );
|
||||
|
||||
private:
|
||||
NS_ConvertUTF8toUCS2( PRUnichar );
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
It differs from a normal string in that it doesn't use normal
|
||||
copy semantics when another string is assign to this.
|
||||
Instead, it "steals" the contents of the source string.
|
||||
|
||||
This is very handy for returning nsString classes as part of
|
||||
an operator+(...) for example, in that it cuts down the number
|
||||
of copy operations that must occur.
|
||||
|
||||
You should probably not use this class unless you really know
|
||||
what you're doing.
|
||||
***************************************************************/
|
||||
class NS_COM nsSubsumeStr : public nsString {
|
||||
public:
|
||||
nsSubsumeStr();
|
||||
explicit nsSubsumeStr(nsStr& aString);
|
||||
nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
int Subsume(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
|
||||
nsSubsumeStr& operator=( const nsSubsumeStr& 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:
|
||||
void operator=( char ); // NOT TO BE IMPLEMENTED
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
163
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
163
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsDebug.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
// If the allocator changes, fix it here.
|
||||
#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsMemory::Alloc((__len) * sizeof(PRUnichar)))
|
||||
#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsMemory::Alloc((__len) * sizeof(char)))
|
||||
#define XPIDL_FREE(__ptr) (nsMemory::Free(__ptr))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
|
||||
nsXPIDLString::~nsXPIDLString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
PRUnichar*
|
||||
nsXPIDLString::Copy(const PRUnichar* aString)
|
||||
{
|
||||
NS_ASSERTION(aString, "null ptr");
|
||||
if (! aString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = 0;
|
||||
|
||||
{
|
||||
const PRUnichar* p = aString;
|
||||
while (*p++)
|
||||
len++;
|
||||
}
|
||||
|
||||
PRUnichar* result = XPIDL_STRING_ALLOC(len + 1);
|
||||
if (result) {
|
||||
PRUnichar* q = result;
|
||||
while (*aString) {
|
||||
*q = *aString;
|
||||
q++;
|
||||
aString++;
|
||||
}
|
||||
*q = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const PRUnichar**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
|
||||
nsXPIDLCString::~nsXPIDLCString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString& nsXPIDLCString::operator =(const char* aCString)
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
if (aCString) {
|
||||
mBuf = Copy(aCString);
|
||||
mBufOwner = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
nsXPIDLCString::Copy(const char* aCString)
|
||||
{
|
||||
NS_ASSERTION(aCString, "null ptr");
|
||||
if (! aCString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = PL_strlen(aCString);
|
||||
char* result = XPIDL_CSTRING_ALLOC(len + 1);
|
||||
if (result)
|
||||
PL_strcpy(result, aCString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char**
|
||||
nsXPIDLCString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const char**
|
||||
nsXPIDLCString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const char**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
389
mozilla/string/obsolete/nsXPIDLString.h
Normal file
389
mozilla/string/obsolete/nsXPIDLString.h
Normal file
@@ -0,0 +1,389 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* nsXPIDLString.h --- an `|auto_ptr|' for character buffers, this functionality will be replaced
|
||||
by the new shared-buffer string (see bug #53065)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef nsXPIDLString_h__
|
||||
#define nsXPIDLString_h__
|
||||
|
||||
/*
|
||||
|
||||
A set of string wrapper classes that ease transition to use of XPIDL
|
||||
interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring'
|
||||
and `string' out params as nsCOMPtr is to generic XPCOM interface
|
||||
pointers. They help you deal with object ownership.
|
||||
|
||||
Consider the following interface:
|
||||
|
||||
interface nsIFoo {
|
||||
attribute string Bar;
|
||||
};
|
||||
|
||||
This will generate the following C++ header file:
|
||||
|
||||
class nsIFoo {
|
||||
NS_IMETHOD SetBar(const PRUnichar* aValue);
|
||||
NS_IMETHOD GetBar(PRUnichar* *aValue);
|
||||
};
|
||||
|
||||
The GetBar() method will allocate a copy of the nsIFoo object's
|
||||
"bar" attribute, and leave you to deal with freeing it:
|
||||
|
||||
nsIFoo* aFoo; // assume we get this somehow
|
||||
PRUnichar* bar;
|
||||
aFoo->GetFoo(&bar);
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", bar);
|
||||
nsMemory::Free(bar);
|
||||
|
||||
This makes your life harder, because you need to convolute your code
|
||||
to ensure that you don't leak `bar'.
|
||||
|
||||
Enter nsXPIDLString, which manages the ownership of the allocated
|
||||
string, and automatically destroys it when the nsXPIDLString goes
|
||||
out of scope:
|
||||
|
||||
nsIFoo* aFoo;
|
||||
nsXPIDLString bar;
|
||||
aFoo->GetFoo( getter_Copies(bar) );
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", (const char*) bar);
|
||||
// no need to remember to nsMemory::Free().
|
||||
|
||||
Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it
|
||||
painfully clear exactly what the code expects. You need to wrap an
|
||||
nsXPIDLString object with either `getter_Copies()' or
|
||||
`getter_Shares()' before passing it to a getter: these tell the
|
||||
nsXPIDLString how ownership is being handled.
|
||||
|
||||
In the case of `getter_Copies()', the callee is allocating a copy
|
||||
(which is usually the case). In the case of `getter_Shares()', the
|
||||
callee is returning a const reference to `the real deal' (this can
|
||||
be done using the [shared] attribute in XPIDL).
|
||||
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCom.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifndef __PRUNICHAR__
|
||||
#define __PRUNICHAR__
|
||||
typedef PRUint16 PRUnichar;
|
||||
#endif /* __PRUNICHAR__ */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |PRUnichar*| interface for |wstring| parameters in
|
||||
// XPIDL interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLString {
|
||||
private:
|
||||
PRUnichar* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
PRUnichar** StartAssignmentByValue();
|
||||
const PRUnichar** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a Unicode string.
|
||||
*/
|
||||
nsXPIDLString() : mBuf(0), mBufOwner(PR_FALSE) {}
|
||||
|
||||
virtual ~nsXPIDLString();
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable Unicode string.
|
||||
*/
|
||||
operator const PRUnichar*() const { return get(); }
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable Unicode string.
|
||||
*/
|
||||
const PRUnichar* get() const { return mBuf; }
|
||||
|
||||
/**
|
||||
* Make a copy of the Unicode string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static PRUnichar* Copy(const PRUnichar* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLString(nsXPIDLString& /* aXPIDLString */) {}
|
||||
void operator=(nsXPIDLString& /* aXPIDLString */) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterCopies
|
||||
getter_Copies(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterShares
|
||||
getter_Shares(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
// XXX THESE ARE NOT strcmp()! DON'T TRY TO USE THEM AS SUCH!
|
||||
inline
|
||||
PRBool
|
||||
operator==(const PRUnichar* lhs, const nsXPIDLString& rhs)
|
||||
{
|
||||
return lhs == NS_STATIC_CAST(const PRUnichar*, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(const nsXPIDLString& lhs, const PRUnichar* rhs)
|
||||
{
|
||||
return NS_STATIC_CAST(const PRUnichar*, lhs) == rhs;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(int lhs, const nsXPIDLString& rhs)
|
||||
{
|
||||
return NS_REINTERPRET_CAST(PRUnichar*, lhs) == NS_STATIC_CAST(const PRUnichar*, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(const nsXPIDLString& lhs, int rhs)
|
||||
{
|
||||
return NS_STATIC_CAST(const PRUnichar*, lhs) == NS_REINTERPRET_CAST(PRUnichar*, rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |char*| interface for |string| parameters in XPIDL
|
||||
// interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLCString {
|
||||
private:
|
||||
char* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
char** StartAssignmentByValue();
|
||||
const char** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a single-byte string.
|
||||
*/
|
||||
nsXPIDLCString() : mBuf(0), mBufOwner(PR_FALSE) {}
|
||||
|
||||
virtual ~nsXPIDLCString();
|
||||
|
||||
/**
|
||||
* Assign a single-byte string to this wrapper. Copies
|
||||
* and owns the result.
|
||||
*/
|
||||
nsXPIDLCString& operator=(const char* aString);
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable single-byte string.
|
||||
*/
|
||||
operator const char*() const { return get(); }
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable single-byte string.
|
||||
*/
|
||||
const char* get() const { return mBuf; }
|
||||
|
||||
/**
|
||||
* Make a copy of the single-byte string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static char* Copy(const char* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator char**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const char**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLCString(nsXPIDLCString& /* aXPIDLString */) {}
|
||||
void operator=(nsXPIDLCString& /* aXPIDLCString */) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterCopies
|
||||
getter_Copies(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterShares
|
||||
getter_Shares(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
// XXX THESE ARE NOT strcmp()! DON'T TRY TO USE THEM AS SUCH!
|
||||
inline
|
||||
PRBool
|
||||
operator==(const char* lhs, const nsXPIDLCString& rhs)
|
||||
{
|
||||
return lhs == NS_STATIC_CAST(const char*, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(const nsXPIDLCString& lhs, const char* rhs)
|
||||
{
|
||||
return NS_STATIC_CAST(const char*, lhs) == rhs;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(int lhs, const nsXPIDLCString& rhs)
|
||||
{
|
||||
return NS_REINTERPRET_CAST(char*, lhs) == NS_STATIC_CAST(const char*, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
PRBool
|
||||
operator==(const nsXPIDLCString& lhs, int rhs)
|
||||
{
|
||||
return NS_STATIC_CAST(const char*, lhs) == NS_REINTERPRET_CAST(char*, rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // nsXPIDLString_h__
|
||||
49
mozilla/string/public/MANIFEST
Normal file
49
mozilla/string/public/MANIFEST
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# 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
|
||||
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
|
||||
64
mozilla/string/public/Makefile.in
Normal file
64
mozilla/string/public/Makefile.in
Normal file
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
# Scott Collins <scc@mozilla.org>
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = string
|
||||
|
||||
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)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
56
mozilla/string/public/makefile.win
Normal file
56
mozilla/string/public/makefile.win
Normal file
@@ -0,0 +1,56 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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):
|
||||
# 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>
|
||||
83
mozilla/string/public/nsAFlatString.h
Normal file
83
mozilla/string/public/nsAFlatString.h
Normal 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___) */
|
||||
38
mozilla/string/public/nsAPromiseString.h
Normal file
38
mozilla/string/public/nsAPromiseString.h
Normal 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___) */
|
||||
54
mozilla/string/public/nsAReadableString.h
Normal file
54
mozilla/string/public/nsAReadableString.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*/
|
||||
|
||||
/* nsAReadableString.h --- a compatibility header for clients still using the names |nsAReadable[C]String| et al */
|
||||
|
||||
#ifndef nsAReadableString_h___
|
||||
#define nsAReadableString_h___
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
typedef const nsAString nsAReadableString;
|
||||
typedef const nsACString nsAReadableCString;
|
||||
|
||||
#ifndef nsLiteralString_h___
|
||||
#include "nsLiteralString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsPromiseSubstring_h___
|
||||
#include "nsPromiseSubstring.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsPromiseFlatString_h___
|
||||
#include "nsPromiseFlatString.h"
|
||||
#endif
|
||||
|
||||
#ifdef NEED_CPP_TEMPLATE_CAST_TO_BASE
|
||||
#define NS_READABLE_CAST(CharT, expr) (NS_STATIC_CAST(const nsStringTraits<CharT>::abstract_string_type&, (expr)))
|
||||
#else
|
||||
#define NS_READABLE_CAST(CharT, expr) (expr)
|
||||
#endif
|
||||
|
||||
#endif // !defined(nsAReadableString_h___)
|
||||
772
mozilla/string/public/nsAString.h
Normal file
772
mozilla/string/public/nsAString.h
Normal 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___)
|
||||
36
mozilla/string/public/nsAWritableString.h
Normal file
36
mozilla/string/public/nsAWritableString.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* 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___
|
||||
|
||||
#ifndef nsAReadableString_h___
|
||||
#include "nsAReadableString.h"
|
||||
#endif
|
||||
|
||||
typedef nsAString nsAWritableString;
|
||||
typedef nsACString nsAWritableCString;
|
||||
|
||||
#endif // !defined(nsAWritableString_h___)
|
||||
112
mozilla/string/public/nsAlgorithm.h
Executable file
112
mozilla/string/public/nsAlgorithm.h
Executable file
@@ -0,0 +1,112 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsAlgorithm_h___
|
||||
#define nsAlgorithm_h___
|
||||
|
||||
#ifndef nsCharTraits_h___
|
||||
#include "nsCharTraits.h"
|
||||
// for |nsCharSourceTraits|, |nsCharSinkTraits|
|
||||
#endif
|
||||
|
||||
#ifndef prtypes_h___
|
||||
#include "prtypes.h"
|
||||
// for |PRUint32|...
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const T&
|
||||
NS_MIN( const T& a, const T& b )
|
||||
{
|
||||
return b < a ? b : a;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const T&
|
||||
NS_MAX( const T& a, const T& b )
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template <class InputIterator, class T>
|
||||
inline
|
||||
PRUint32
|
||||
NS_COUNT( InputIterator& first, const InputIterator& last, const T& value )
|
||||
{
|
||||
PRUint32 result = 0;
|
||||
for ( ; first != last; ++first )
|
||||
if ( *first == value )
|
||||
++result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class InputIterator, class OutputIterator>
|
||||
inline
|
||||
OutputIterator&
|
||||
copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result )
|
||||
{
|
||||
typedef nsCharSourceTraits<InputIterator> source_traits;
|
||||
typedef nsCharSinkTraits<OutputIterator> sink_traits;
|
||||
|
||||
while ( first != last )
|
||||
{
|
||||
PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last)));
|
||||
NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate");
|
||||
source_traits::advance(first, count_copied);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class InputIterator, class OutputIterator>
|
||||
OutputIterator&
|
||||
copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
last.normalize_backward();
|
||||
result.normalize_backward();
|
||||
PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
|
||||
if ( first.fragment().mStart == last.fragment().mStart )
|
||||
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.get() - first.get()));
|
||||
|
||||
NS_ASSERTION(lengthToCopy, "|copy_string_backward| will never terminate");
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// XXX Visual C++ can't stomach 'typename' where it rightfully should
|
||||
nsCharTraits<OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
|
||||
#else
|
||||
nsCharTraits<typename OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
|
||||
#endif
|
||||
|
||||
last.advance( -PRInt32(lengthToCopy) );
|
||||
result.advance( -PRInt32(lengthToCopy) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // !defined(nsAlgorithm_h___)
|
||||
350
mozilla/string/public/nsBufferHandle.h
Executable file
350
mozilla/string/public/nsBufferHandle.h
Executable file
@@ -0,0 +1,350 @@
|
||||
/* -*- 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 strings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
/* nsBufferHandle.h --- the collection of classes that describe the atomic hunks of strings */
|
||||
|
||||
#ifndef nsBufferHandle_h___
|
||||
#define nsBufferHandle_h___
|
||||
|
||||
#include <stddef.h>
|
||||
// for |ptrdiff_t|
|
||||
|
||||
#include "prtypes.h"
|
||||
// for |PRBool|
|
||||
|
||||
#include "nsDebug.h"
|
||||
// for |NS_ASSERTION|
|
||||
|
||||
#include "nscore.h"
|
||||
// for |PRUnichar|, |NS_REINTERPRET_CAST|
|
||||
|
||||
|
||||
/**
|
||||
The classes in this file are collectively called `buffer handles'.
|
||||
All buffer handles begin with a pointer-tuple that delimits the useful content of a
|
||||
hunk of string. A buffer handle that points to a sharable hunk of string data
|
||||
additionally has a field which multiplexes some flags and a reference count.
|
||||
|
||||
|
||||
ns[Const]BufferHandle nsSharedBufferHandle mFlexBufferHandle
|
||||
+-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+
|
||||
| mDataStart | | mDataStart | | mDataStart |
|
||||
+-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+
|
||||
| mDataEnd | | mDataEnd | | mDataEnd |
|
||||
+-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+
|
||||
| mFlags | | mFlags |
|
||||
+-----+-----+-----+-----+ +-----+-----+-----+-----+
|
||||
. mAllocator . | mStorageStart |
|
||||
......................... +-----+-----+-----+-----+
|
||||
| mStorageEnd |
|
||||
+-----+-----+-----+-----+
|
||||
. mAllocator .
|
||||
.........................
|
||||
|
||||
Given only a |ns[Const]BufferHandle|, there is no legal way to tell if it is sharable.
|
||||
In all cases, the data might immediately follow the handle in the same allocated block.
|
||||
From the |mFlags| field, you can tell exactly what configuration of a handle you
|
||||
actually have.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
template <class CharT>
|
||||
class nsBufferHandle
|
||||
{
|
||||
public:
|
||||
nsBufferHandle( CharT* aDataStart, CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { }
|
||||
|
||||
void DataStart( CharT* aNewDataStart ) { mDataStart = aNewDataStart; }
|
||||
CharT* DataStart() { return mDataStart; }
|
||||
const CharT* DataStart() const { return mDataStart; }
|
||||
|
||||
void DataEnd( CharT* aNewDataEnd ) { mDataEnd = aNewDataEnd; }
|
||||
CharT* DataEnd() { return mDataEnd; }
|
||||
const CharT* DataEnd() const { return mDataEnd; }
|
||||
|
||||
ptrdiff_t DataLength() const { return mDataEnd - mDataStart; }
|
||||
|
||||
protected:
|
||||
CharT* mDataStart;
|
||||
CharT* mDataEnd;
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsConstBufferHandle
|
||||
{
|
||||
public:
|
||||
nsConstBufferHandle( const CharT* aDataStart, const CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { }
|
||||
|
||||
const CharT* DataStart() const { return mDataStart; }
|
||||
const CharT* DataEnd() const { return mDataEnd; }
|
||||
ptrdiff_t DataLength() const { return mDataEnd - mDataStart; }
|
||||
|
||||
protected:
|
||||
const CharT* mDataStart;
|
||||
const CharT* mDataEnd;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* string allocator stuff needs to move to its own file
|
||||
* also see http://bugzilla.mozilla.org/show_bug.cgi?id=70087
|
||||
*/
|
||||
|
||||
template <class CharT>
|
||||
class nsStringAllocator
|
||||
{
|
||||
public:
|
||||
// more later
|
||||
virtual void Deallocate( CharT* ) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* the following two routines must be provided by the client embedding strings
|
||||
*/
|
||||
NS_COM nsStringAllocator<char>& StringAllocator_char();
|
||||
NS_COM nsStringAllocator<PRUnichar>& StringAllocator_wchar_t();
|
||||
|
||||
|
||||
/**
|
||||
* this traits class lets templated clients pick the appropriate non-template global allocator
|
||||
*/
|
||||
template <class T>
|
||||
struct nsStringAllocatorTraits
|
||||
{
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsStringAllocatorTraits<char>
|
||||
{
|
||||
static nsStringAllocator<char>& global_string_allocator() { return StringAllocator_char(); }
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsStringAllocatorTraits<PRUnichar>
|
||||
{
|
||||
static nsStringAllocator<PRUnichar>& global_string_allocator() { return StringAllocator_wchar_t(); }
|
||||
};
|
||||
|
||||
// end of string allocator stuff that needs to move
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
template <class CharT>
|
||||
class nsSharedBufferHandle
|
||||
: public nsBufferHandle<CharT>
|
||||
{
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
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
|
||||
|
||||
kImplementationFlagsMask = 0x0F00000,
|
||||
kFlagsMask = 0xFF00000,
|
||||
kRefCountMask = 0x00FFFFF
|
||||
};
|
||||
|
||||
public:
|
||||
nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd )
|
||||
: nsBufferHandle<CharT>(aDataStart, aDataEnd)
|
||||
{
|
||||
mFlags = kIsShared;
|
||||
}
|
||||
|
||||
nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT*, CharT*, PRBool isSingleAllocation )
|
||||
: nsBufferHandle<CharT>(aDataStart, aDataEnd)
|
||||
{
|
||||
mFlags = kIsShared;
|
||||
if ( isSingleAllocation )
|
||||
mFlags |= kIsSingleAllocationWithBuffer;
|
||||
}
|
||||
|
||||
~nsSharedBufferHandle();
|
||||
|
||||
void
|
||||
AcquireReference() const
|
||||
{
|
||||
nsSharedBufferHandle<CharT>* mutable_this = NS_CONST_CAST(nsSharedBufferHandle<CharT>*, this);
|
||||
mutable_this->set_refcount( get_refcount()+1 );
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseReference() const
|
||||
{
|
||||
nsSharedBufferHandle<CharT>* mutable_this = NS_CONST_CAST(nsSharedBufferHandle<CharT>*, this);
|
||||
if ( !mutable_this->set_refcount( get_refcount()-1 ) )
|
||||
delete mutable_this;
|
||||
// hmm, what if |kIsUserAllocator| and |kIsSingleAllocationWithBuffer|?
|
||||
}
|
||||
|
||||
PRBool
|
||||
IsReferenced() const
|
||||
{
|
||||
return get_refcount() != 0;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
GetImplementationFlags() const
|
||||
{
|
||||
return mFlags & kImplementationFlagsMask;
|
||||
}
|
||||
|
||||
void
|
||||
SetImplementationFlags( PRUint32 aNewFlags )
|
||||
{
|
||||
mFlags = (mFlags & ~kImplementationFlagsMask) | (aNewFlags & kImplementationFlagsMask);
|
||||
}
|
||||
|
||||
protected:
|
||||
PRUint32 mFlags;
|
||||
|
||||
PRUint32
|
||||
get_refcount() const
|
||||
{
|
||||
return mFlags & kRefCountMask;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
set_refcount( PRUint32 aNewRefCount )
|
||||
{
|
||||
NS_ASSERTION(aNewRefCount <= kRefCountMask, "aNewRefCount <= kRefCountMask");
|
||||
|
||||
mFlags = (mFlags & kFlagsMask) | aNewRefCount;
|
||||
return aNewRefCount;
|
||||
}
|
||||
|
||||
nsStringAllocator<CharT>& get_allocator() const;
|
||||
};
|
||||
|
||||
|
||||
template <class CharT>
|
||||
class nsFlexBufferHandle
|
||||
: public nsSharedBufferHandle<CharT>
|
||||
{
|
||||
public:
|
||||
nsFlexBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT* aStorageStart, CharT* aStorageEnd )
|
||||
: nsSharedBufferHandle<CharT>(aDataStart, aDataEnd),
|
||||
mStorageStart(aStorageStart),
|
||||
mStorageEnd(aStorageEnd)
|
||||
{
|
||||
this->mFlags |= this->kIsStorageDefinedSeparately;
|
||||
}
|
||||
|
||||
void StorageStart( CharT* aNewStorageStart ) { mStorageStart = aNewStorageStart; }
|
||||
CharT* StorageStart() { return mStorageStart; }
|
||||
const CharT* StorageStart() const { return mStorageStart; }
|
||||
|
||||
void StorageEnd( CharT* aNewStorageEnd ) { mStorageEnd = aNewStorageEnd; }
|
||||
CharT* StorageEnd() { return mStorageEnd; }
|
||||
const CharT* StorageEnd() const { return mStorageEnd; }
|
||||
|
||||
ptrdiff_t StorageLength() const { return mStorageEnd - mStorageStart; }
|
||||
|
||||
protected:
|
||||
CharT* mStorageStart;
|
||||
CharT* mStorageEnd;
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsSharedBufferHandleWithAllocator
|
||||
: public nsSharedBufferHandle<CharT>
|
||||
{
|
||||
public:
|
||||
nsSharedBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd, nsStringAllocator<CharT>& aAllocator )
|
||||
: nsSharedBufferHandle<CharT>(aDataStart, aDataEnd),
|
||||
mAllocator(aAllocator)
|
||||
{
|
||||
this->mFlags |= this->kIsUserAllocator;
|
||||
}
|
||||
|
||||
nsStringAllocator<CharT>& get_allocator() const { return mAllocator; }
|
||||
|
||||
protected:
|
||||
nsStringAllocator<CharT>& mAllocator;
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsFlexBufferHandleWithAllocator
|
||||
: public nsFlexBufferHandle<CharT>
|
||||
{
|
||||
public:
|
||||
nsFlexBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd,
|
||||
CharT* aStorageStart, CharT* aStorageEnd,
|
||||
nsStringAllocator<CharT>& aAllocator )
|
||||
: nsFlexBufferHandle<CharT>(aDataStart, aDataEnd, aStorageStart, aStorageEnd),
|
||||
mAllocator(aAllocator)
|
||||
{
|
||||
this->mFlags |= this->kIsUserAllocator;
|
||||
}
|
||||
|
||||
nsStringAllocator<CharT>& get_allocator() const { return mAllocator; }
|
||||
|
||||
protected:
|
||||
nsStringAllocator<CharT>& mAllocator;
|
||||
};
|
||||
|
||||
|
||||
template <class CharT>
|
||||
nsStringAllocator<CharT>&
|
||||
nsSharedBufferHandle<CharT>::get_allocator() const
|
||||
// really don't want this to be |inline|
|
||||
{
|
||||
if ( mFlags & kIsUserAllocator )
|
||||
{
|
||||
if ( mFlags & kIsStorageDefinedSeparately )
|
||||
return NS_REINTERPRET_CAST(const nsFlexBufferHandleWithAllocator<CharT>*, this)->get_allocator();
|
||||
else
|
||||
return NS_REINTERPRET_CAST(const nsSharedBufferHandleWithAllocator<CharT>*, this)->get_allocator();
|
||||
}
|
||||
|
||||
return nsStringAllocatorTraits<CharT>::global_string_allocator();
|
||||
}
|
||||
|
||||
|
||||
template <class CharT>
|
||||
nsSharedBufferHandle<CharT>::~nsSharedBufferHandle()
|
||||
// really don't want this to be |inline|
|
||||
{
|
||||
NS_ASSERTION(!IsReferenced(), "!IsReferenced()");
|
||||
|
||||
if ( !(mFlags & kIsSingleAllocationWithBuffer) )
|
||||
{
|
||||
CharT* string_storage = this->mDataStart;
|
||||
if ( mFlags & kIsStorageDefinedSeparately )
|
||||
string_storage = NS_REINTERPRET_CAST(nsFlexBufferHandle<CharT>*, this)->StorageStart();
|
||||
|
||||
get_allocator().Deallocate(string_storage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(nsBufferHandle_h___)
|
||||
174
mozilla/string/public/nsBufferHandleUtils.h
Normal file
174
mozilla/string/public/nsBufferHandleUtils.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/* -*- 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 strings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsBufferHandleUtils_h___
|
||||
#define nsBufferHandleUtils_h___
|
||||
|
||||
#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
|
||||
size_t
|
||||
NS_AlignedHandleSize( const HandleT*, const CharT* )
|
||||
{
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
return ((sizeof(HandleT) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT);
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
const CharT*
|
||||
NS_DataAfterHandle( const HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef const CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(const unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
CharT*
|
||||
NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class StringT>
|
||||
HandleT*
|
||||
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity )
|
||||
{
|
||||
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, char_ptr(0));
|
||||
|
||||
// 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(char_type);
|
||||
|
||||
|
||||
HandleT* result = 0;
|
||||
void* handle_ptr = ::operator new(handle_size + buffer_size);
|
||||
|
||||
if ( handle_ptr )
|
||||
{
|
||||
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;
|
||||
|
||||
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 = char_type(0);
|
||||
|
||||
result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, data_start_ptr, buffer_end_ptr, PR_TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // !defined(nsBufferHandleUtils_h___)
|
||||
705
mozilla/string/public/nsCharTraits.h
Normal file
705
mozilla/string/public/nsCharTraits.h
Normal file
@@ -0,0 +1,705 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*/
|
||||
|
||||
#ifndef nsCharTraits_h___
|
||||
#define nsCharTraits_h___
|
||||
|
||||
#include <ctype.h>
|
||||
// for |EOF|, |WEOF|
|
||||
|
||||
#include <string.h>
|
||||
// for |memcpy|, et al
|
||||
|
||||
#ifndef nscore_h___
|
||||
#include "nscore.h"
|
||||
// for |PRUnichar|
|
||||
#endif
|
||||
|
||||
#ifndef nsStringIteratorUtils_h___
|
||||
#include "nsStringIteratorUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPP_BOOL
|
||||
typedef bool nsCharTraits_bool;
|
||||
#else
|
||||
typedef PRBool nsCharTraits_bool;
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
struct nsCharTraits
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef char incompatible_char_type;
|
||||
|
||||
static
|
||||
void
|
||||
assign( char_type& lhs, const char_type& rhs )
|
||||
{
|
||||
lhs = rhs;
|
||||
}
|
||||
|
||||
|
||||
// integer representation of characters:
|
||||
|
||||
typedef int int_type;
|
||||
|
||||
static
|
||||
char_type
|
||||
to_char_type( const int_type& c )
|
||||
{
|
||||
return char_type(c);
|
||||
}
|
||||
|
||||
static
|
||||
int_type
|
||||
to_int_type( const char_type& c )
|
||||
{
|
||||
return int_type(c);
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq_int_type( const int_type& lhs, const int_type& rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
// |char_type| comparisons:
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq( const char_type& lhs, const char_type& rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
lt( const char_type& lhs, const char_type& rhs )
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
|
||||
|
||||
// operations on s[n] arrays:
|
||||
|
||||
static
|
||||
char_type*
|
||||
copy( char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
char_type* result = s1;
|
||||
while ( n-- )
|
||||
assign(*s1++, *s2++);
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
char_type*
|
||||
move( char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
char_type* result = s1;
|
||||
|
||||
if ( n )
|
||||
{
|
||||
if ( s2 > s1 )
|
||||
copy(s1, s2, n);
|
||||
else
|
||||
{
|
||||
s1 += n;
|
||||
s2 += n;
|
||||
while ( n-- )
|
||||
assign(*--s1, *--s2);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
char_type*
|
||||
assign( char_type* s, size_t n, const char_type& c )
|
||||
{
|
||||
char_type* result = s;
|
||||
while ( n-- )
|
||||
assign(*s++, c);
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
compare( const char_type* s1, const char_type* s2, size_t n )
|
||||
{
|
||||
for ( ; n--; ++s1, ++s2 )
|
||||
{
|
||||
if ( lt(*s1, *s2) )
|
||||
return -1;
|
||||
if ( lt(*s2, *s1) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
size_t
|
||||
length( const char_type* s )
|
||||
{
|
||||
size_t result = 0;
|
||||
while ( !eq(*s++, CharT(0)) )
|
||||
++result;
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
const char_type*
|
||||
find( const char_type* s, size_t n, const char_type& c )
|
||||
{
|
||||
while ( n-- )
|
||||
{
|
||||
if ( eq(*s, c) )
|
||||
return s;
|
||||
++s;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// I/O related:
|
||||
|
||||
typedef streamoff off_type;
|
||||
typedef streampos pos_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
static
|
||||
int_type
|
||||
eof()
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static
|
||||
int_type
|
||||
not_eof( const int_type& c )
|
||||
{
|
||||
return eq_int_type(c, eof()) ? ~eof() : c;
|
||||
}
|
||||
|
||||
// static state_type get_state( pos_type );
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharTraits<char>
|
||||
{
|
||||
typedef char char_type;
|
||||
typedef PRUnichar incompatible_char_type;
|
||||
|
||||
static
|
||||
void
|
||||
assign( char& lhs, char rhs )
|
||||
{
|
||||
lhs = rhs;
|
||||
}
|
||||
|
||||
|
||||
// integer representation of characters:
|
||||
|
||||
typedef int int_type;
|
||||
|
||||
static
|
||||
char
|
||||
to_char_type( int c )
|
||||
{
|
||||
return char(c);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
to_int_type( char c )
|
||||
{
|
||||
return int( NS_STATIC_CAST(unsigned char, c) );
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq_int_type( int lhs, int rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
// |char_type| comparisons:
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq( char lhs, char rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
lt( char lhs, char rhs )
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
|
||||
|
||||
// operations on s[n] arrays:
|
||||
|
||||
static
|
||||
char*
|
||||
move( char* s1, const char* s2, size_t n )
|
||||
{
|
||||
return NS_STATIC_CAST(char*, memmove(s1, s2, n));
|
||||
}
|
||||
|
||||
static
|
||||
char*
|
||||
copy( char* s1, const char* s2, size_t n )
|
||||
{
|
||||
return NS_STATIC_CAST(char*, memcpy(s1, s2, n));
|
||||
}
|
||||
|
||||
static
|
||||
char*
|
||||
assign( char* s, size_t n, char c )
|
||||
{
|
||||
return NS_STATIC_CAST(char*, memset(s, to_int_type(c), n));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
compare( const char* s1, const char* s2, size_t n )
|
||||
{
|
||||
return memcmp(s1, s2, n);
|
||||
}
|
||||
|
||||
static
|
||||
size_t
|
||||
length( const char* s )
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
||||
|
||||
static
|
||||
const char*
|
||||
find( const char* s, size_t n, char c )
|
||||
{
|
||||
return NS_REINTERPRET_CAST(const char*, memchr(s, to_int_type(c), n));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// I/O related:
|
||||
|
||||
typedef streamoff off_type;
|
||||
typedef streampos pos_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
static
|
||||
int_type
|
||||
eof()
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
not_eof( int c )
|
||||
{
|
||||
return c==eof() ? ~eof() : c;
|
||||
}
|
||||
|
||||
// static state_type get_state( pos_type );
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharTraits<wchar_t>
|
||||
{
|
||||
typedef wchar_t char_type;
|
||||
|
||||
static
|
||||
void
|
||||
assign( wchar_t& lhs, wchar_t rhs )
|
||||
{
|
||||
lhs = rhs;
|
||||
}
|
||||
|
||||
|
||||
// integer representation of characters:
|
||||
|
||||
typedef wint_t int_type;
|
||||
|
||||
static
|
||||
wchar_t
|
||||
to_char_type( int_type c )
|
||||
{
|
||||
return wchar_t(c);
|
||||
}
|
||||
|
||||
static
|
||||
int_type
|
||||
to_int_type( wchar_t c )
|
||||
{
|
||||
return int_type(c);
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq_int_type( int_type lhs, int_type rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
// |char_type| comparisons:
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
eq( wchar_t lhs, wchar_t rhs )
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
static
|
||||
nsCharTraits_bool
|
||||
lt( wchar_t lhs, wchar_t rhs )
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
|
||||
|
||||
// operations on s[n] arrays:
|
||||
|
||||
static
|
||||
wchar_t*
|
||||
move( wchar_t* s1, const wchar_t* s2, size_t n )
|
||||
{
|
||||
return NS_STATIC_CAST(wchar_t*, wmemmove(s1, s2, n));
|
||||
}
|
||||
|
||||
static
|
||||
wchar_t*
|
||||
copy( wchar_t* s1, const wchar_t* s2, size_t n )
|
||||
{
|
||||
return NS_STATIC_CAST(wchar_t*, wmemcpy(s1, s2, n));
|
||||
}
|
||||
|
||||
static
|
||||
wchar_t*
|
||||
assign( wchar_t* s, size_t n, wchar_t c )
|
||||
{
|
||||
return NS_STATIC_CAST(wchar_t*, wmemset(s, to_int_type(c), n));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
compare( const wchar_t* s1, const wchar_t* s2, size_t n )
|
||||
{
|
||||
return wmemcmp(s1, s2, n);
|
||||
}
|
||||
|
||||
static
|
||||
size_t
|
||||
length( const wchar_t* s )
|
||||
{
|
||||
return wcslen(s);
|
||||
}
|
||||
|
||||
static
|
||||
const wchar_t*
|
||||
find( const wchar_t* s, size_t n, wchar_t c )
|
||||
{
|
||||
return NS_REINTERPRET_CAST(const wchar_t*, wmemchr(s, to_int_type(c), n));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// I/O related:
|
||||
|
||||
typedef streamoff off_type;
|
||||
typedef streampos pos_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
static
|
||||
int_type
|
||||
eof()
|
||||
{
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
static
|
||||
int_type
|
||||
not_eof( int_type c )
|
||||
{
|
||||
return c==eof() ? ~eof() : c;
|
||||
}
|
||||
|
||||
// static state_type get_state( pos_type );
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class InputIterator>
|
||||
struct nsCharSourceTraits
|
||||
{
|
||||
typedef typename InputIterator::difference_type difference_type;
|
||||
|
||||
#if 0
|
||||
static
|
||||
PRUint32
|
||||
distance( const InputIterator& first, const InputIterator& last )
|
||||
{
|
||||
// ...
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const InputIterator& iter )
|
||||
{
|
||||
return iter.size_forward();
|
||||
}
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const InputIterator& first, const InputIterator& last )
|
||||
{
|
||||
return PRUint32(SameFragment(first, last) ? last.get()-first.get() : first.size_forward());
|
||||
}
|
||||
|
||||
static
|
||||
const typename InputIterator::value_type*
|
||||
read( const InputIterator& iter )
|
||||
{
|
||||
return iter.get();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
advance( InputIterator& s, difference_type n )
|
||||
{
|
||||
s.advance(n);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class CharT>
|
||||
struct nsCharSourceTraits<CharT*>
|
||||
{
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
#if 0
|
||||
static
|
||||
PRUint32
|
||||
distance( CharT* first, CharT* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( CharT* s )
|
||||
{
|
||||
return PRUint32(nsCharTraits<CharT>::length(s));
|
||||
// return numeric_limits<PRUint32>::max();
|
||||
}
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( CharT* first, CharT* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
|
||||
static
|
||||
const CharT*
|
||||
read( CharT* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
advance( CharT*& s, difference_type n )
|
||||
{
|
||||
s += n;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharSourceTraits<const char*>
|
||||
{
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
#if 0
|
||||
static
|
||||
PRUint32
|
||||
distance( const char* first, const char* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const char* s )
|
||||
{
|
||||
return PRUint32(nsCharTraits<char>::length(s));
|
||||
// return numeric_limits<PRUint32>::max();
|
||||
}
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const char* first, const char* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
|
||||
static
|
||||
const char*
|
||||
read( const char* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
advance( const char*& s, difference_type n )
|
||||
{
|
||||
s += n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharSourceTraits<const PRUnichar*>
|
||||
{
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
#if 0
|
||||
static
|
||||
PRUint32
|
||||
distance( const PRUnichar* first, const PRUnichar* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const PRUnichar* s )
|
||||
{
|
||||
return PRUint32(nsCharTraits<PRUnichar>::length(s));
|
||||
// return numeric_limits<PRUint32>::max();
|
||||
}
|
||||
|
||||
static
|
||||
PRUint32
|
||||
readable_distance( const PRUnichar* first, const PRUnichar* last )
|
||||
{
|
||||
return PRUint32(last-first);
|
||||
}
|
||||
|
||||
static
|
||||
const PRUnichar*
|
||||
read( const PRUnichar* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
advance( const PRUnichar*& s, difference_type n )
|
||||
{
|
||||
s += n;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
template <class OutputIterator>
|
||||
struct nsCharSinkTraits
|
||||
{
|
||||
static
|
||||
PRUint32
|
||||
write( OutputIterator& iter, const typename OutputIterator::value_type* s, PRUint32 n )
|
||||
{
|
||||
return iter.write(s, n);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class CharT>
|
||||
struct nsCharSinkTraits<CharT*>
|
||||
{
|
||||
static
|
||||
PRUint32
|
||||
write( CharT*& iter, const CharT* s, PRUint32 n )
|
||||
{
|
||||
nsCharTraits<CharT>::move(iter, s, n);
|
||||
iter += n;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharSinkTraits<char*>
|
||||
{
|
||||
static
|
||||
PRUint32
|
||||
write( char*& iter, const char* s, PRUint32 n )
|
||||
{
|
||||
nsCharTraits<char>::move(iter, s, n);
|
||||
iter += n;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct nsCharSinkTraits<PRUnichar*>
|
||||
{
|
||||
static
|
||||
PRUint32
|
||||
write( PRUnichar*& iter, const PRUnichar* s, PRUint32 n )
|
||||
{
|
||||
nsCharTraits<PRUnichar>::move(iter, s, n);
|
||||
iter += n;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(nsCharTraits_h___)
|
||||
102
mozilla/string/public/nsCommonString.h
Normal file
102
mozilla/string/public/nsCommonString.h
Normal 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___) */
|
||||
269
mozilla/string/public/nsDependentConcatenation.h
Normal file
269
mozilla/string/public/nsDependentConcatenation.h
Normal 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___) */
|
||||
127
mozilla/string/public/nsDependentString.h
Normal file
127
mozilla/string/public/nsDependentString.h
Normal 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___) */
|
||||
182
mozilla/string/public/nsDependentSubstring.h
Normal file
182
mozilla/string/public/nsDependentSubstring.h
Normal 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___) */
|
||||
69
mozilla/string/public/nsFragmentedString.h
Normal file
69
mozilla/string/public/nsFragmentedString.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- 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 XPCOM.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsFragmentedString_h___
|
||||
#define nsFragmentedString_h___
|
||||
|
||||
// WORK IN PROGRESS
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsSharedBufferList_h___
|
||||
#include "nsSharedBufferList.h"
|
||||
#endif
|
||||
|
||||
|
||||
class nsFragmentedString
|
||||
: public nsAString
|
||||
/*
|
||||
...
|
||||
*/
|
||||
{
|
||||
protected:
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsFragmentedString() { }
|
||||
|
||||
virtual PRUint32 Length() const;
|
||||
|
||||
virtual void SetLength( PRUint32 aNewLength );
|
||||
// virtual void SetCapacity( PRUint32 aNewCapacity );
|
||||
|
||||
// virtual void Cut( PRUint32 cutStart, PRUint32 cutLength );
|
||||
|
||||
protected:
|
||||
// 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;
|
||||
};
|
||||
|
||||
#endif // !defined(nsFragmentedString_h___)
|
||||
84
mozilla/string/public/nsLiteralString.h
Normal file
84
mozilla/string/public/nsLiteralString.h
Normal 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___) */
|
||||
127
mozilla/string/public/nsLocalString.h
Normal file
127
mozilla/string/public/nsLocalString.h
Normal 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___) */
|
||||
96
mozilla/string/public/nsPrintfCString.h
Executable file
96
mozilla/string/public/nsPrintfCString.h
Executable file
@@ -0,0 +1,96 @@
|
||||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author:
|
||||
* Scott Collins <scc@mozilla.org>
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef nsPrintfCString_h___
|
||||
#define nsPrintfCString_h___
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* |nsPrintfCString| lets you use a formated |printf| string as an |nsAReadableCString|.
|
||||
*
|
||||
* myCStr += nsPrintfCString("%f", 13.917);
|
||||
* // ...a general purpose substitute for |AppendFloat|
|
||||
*
|
||||
* For longer patterns, you'll want to use the constructor that takes a length
|
||||
*
|
||||
* nsPrintfCString(128, "%f, %f, %f, %f, %f, %f, %f, %i, %f", x, y, z, 3.2, j, k, l, 3, 3.1);
|
||||
*
|
||||
* Exceding the default size (which you must specify in the constructor, it is not determined)
|
||||
* causes an allocation, so avoid that. If your formatted string exceeds the allocated space, it is
|
||||
* cut off at the size of the buffer, no error is reported (and no out-of-bounds writing occurs).
|
||||
* This class is intended to be useful for numbers and short
|
||||
* strings, not arbitrary formatting of other strings (e.g., with %s). There is currently no
|
||||
* wide version of this class, since wide |printf| is not generally available. That means
|
||||
* to get a wide version of your formatted data, you must, e.g.,
|
||||
*
|
||||
* CopyASCIItoUCS2(nsPrintfCString("%f", 13.917"), myStr);
|
||||
*
|
||||
* That's another good reason to avoid this class for anything but numbers ... as strings can be
|
||||
* much more efficiently handled with |NS_LITERAL_[C]STRING| and |nsLiteral[C]String|.
|
||||
*/
|
||||
|
||||
class nsPrintfCString
|
||||
: 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)
|
||||
// pinkerton suggests 7. We should measure and decide what's appropriate
|
||||
|
||||
|
||||
public:
|
||||
explicit nsPrintfCString( const char* format, ... );
|
||||
nsPrintfCString( size_t n, const char* format, ...);
|
||||
~nsPrintfCString();
|
||||
|
||||
virtual PRUint32 Length() const;
|
||||
|
||||
protected:
|
||||
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:
|
||||
char* mStart;
|
||||
PRUint32 mLength;
|
||||
char mLocalBuffer[ kLocalBufferSize + 1 ];
|
||||
};
|
||||
|
||||
#endif // !defined(nsPrintfCString_h___)
|
||||
82
mozilla/string/public/nsPrivateSharableString.h
Executable file
82
mozilla/string/public/nsPrivateSharableString.h
Executable file
@@ -0,0 +1,82 @@
|
||||
/* -*- 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 strings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsPrivateSharableString_h___
|
||||
#define nsPrivateSharableString_h___
|
||||
|
||||
#ifndef nsBufferHandle_h___
|
||||
#include "nsBufferHandle.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
class NS_COM nsPrivateSharableString
|
||||
{
|
||||
public:
|
||||
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|, 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.
|
||||
*/
|
||||
};
|
||||
|
||||
class NS_COM nsPrivateSharableCString
|
||||
{
|
||||
public:
|
||||
typedef char char_type;
|
||||
|
||||
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___)
|
||||
269
mozilla/string/public/nsPromiseConcatenation.h
Normal file
269
mozilla/string/public/nsPromiseConcatenation.h
Normal 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___) */
|
||||
150
mozilla/string/public/nsPromiseFlatString.h
Normal file
150
mozilla/string/public/nsPromiseFlatString.h
Normal 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___) */
|
||||
182
mozilla/string/public/nsPromiseSubstring.h
Normal file
182
mozilla/string/public/nsPromiseSubstring.h
Normal 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___) */
|
||||
217
mozilla/string/public/nsReadableUtils.h
Executable file
217
mozilla/string/public/nsReadableUtils.h
Executable file
@@ -0,0 +1,217 @@
|
||||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
* Johnny Stenbeck <jst@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsReadableUtils_h___
|
||||
#define nsReadableUtils_h___
|
||||
|
||||
/**
|
||||
* I guess all the routines in this file are all mis-named.
|
||||
* According to our conventions, they should be |NS_xxx|.
|
||||
*/
|
||||
|
||||
#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 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|.
|
||||
*
|
||||
* Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
|
||||
* Performs a lossy encoding conversion by chopping 16-bit wide characters down to 8-bits wide while copying |aSource| to your new buffer.
|
||||
* This conversion is not well defined; but it reproduces legacy string behavior.
|
||||
* The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
|
||||
*
|
||||
* @param aSource a 16-bit wide string
|
||||
* @return a new |char| buffer you must free with |nsMemory::Free|.
|
||||
*/
|
||||
NS_COM char* ToNewCString( const nsAString& aSource );
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
|
||||
*
|
||||
* Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
|
||||
* The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
|
||||
*
|
||||
* @param aSource an 8-bit wide string
|
||||
* @return a new |char| buffer you must free with |nsMemory::Free|.
|
||||
*/
|
||||
NS_COM char* ToNewCString( const nsACString& aSource );
|
||||
|
||||
/**
|
||||
* Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
|
||||
*
|
||||
* Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
|
||||
* Performs a encoding conversion by converting 16-bit wide characters down to UTF8 encoded 8-bits wide string copying |aSource| to your new buffer.
|
||||
* The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
|
||||
*
|
||||
* @param aSource a 16-bit wide string
|
||||
* @return a new |char| buffer you must free with |nsMemory::Free|.
|
||||
*/
|
||||
|
||||
NS_COM char* ToNewUTF8String( const nsAString& aSource );
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new |PRUnichar| buffer containing a zero-terminated copy of |aSource|.
|
||||
*
|
||||
* Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
|
||||
* The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
|
||||
*
|
||||
* @param aSource a 16-bit wide string
|
||||
* @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
|
||||
*/
|
||||
NS_COM PRUnichar* ToNewUnicode( const nsAString& aSource );
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new |PRUnichar| buffer containing a zero-terminated copy of |aSource|.
|
||||
*
|
||||
* Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
|
||||
* Performs an encoding conversion by 0-padding 8-bit wide characters up to 16-bits wide while copying |aSource| to your new buffer.
|
||||
* This conversion is not well defined; but it reproduces legacy string behavior.
|
||||
* The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
|
||||
*
|
||||
* @param aSource an 8-bit wide string
|
||||
* @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
|
||||
*/
|
||||
NS_COM PRUnichar* ToNewUnicode( const nsACString& aSource );
|
||||
|
||||
/**
|
||||
* Copies |aLength| 16-bit characters from the start of |aSource| to the
|
||||
* |PRUnichar| buffer |aDest|.
|
||||
*
|
||||
* After this operation |aDest| is not null terminated.
|
||||
*
|
||||
* @param aSource a 16-bit wide string
|
||||
* @param aSrcOffset start offset in the source string
|
||||
* @param aDest a |PRUnichar| buffer
|
||||
* @param aLength the number of 16-bit characters to copy
|
||||
* @return pointer to destination buffer - identical to |aDest|
|
||||
*/
|
||||
NS_COM PRUnichar* CopyUnicodeTo( const nsAString& aSource,
|
||||
PRUint32 aSrcOffset,
|
||||
PRUnichar* aDest,
|
||||
PRUint32 aLength );
|
||||
|
||||
|
||||
/**
|
||||
* Copies 16-bit characters between iterators |aSrcStart| and
|
||||
* |aSrcEnd| to the writable string |aDest|. Similar to the
|
||||
* |nsString::Mid| method.
|
||||
*
|
||||
* After this operation |aDest| is not null terminated.
|
||||
*
|
||||
* @param aSrcStart start source iterator
|
||||
* @param aSrcEnd end source iterator
|
||||
* @param aDest destination for the copy
|
||||
*/
|
||||
NS_COM void CopyUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
|
||||
const nsReadingIterator<PRUnichar>& aSrcEnd,
|
||||
nsAString& aDest );
|
||||
|
||||
/**
|
||||
* Appends 16-bit characters between iterators |aSrcStart| and
|
||||
* |aSrcEnd| to the writable string |aDest|.
|
||||
*
|
||||
* After this operation |aDest| is not null terminated.
|
||||
*
|
||||
* @param aSrcStart start source iterator
|
||||
* @param aSrcEnd end source iterator
|
||||
* @param aDest destination for the copy
|
||||
*/
|
||||
NS_COM void AppendUnicodeTo( const nsReadingIterator<PRUnichar>& aSrcStart,
|
||||
const nsReadingIterator<PRUnichar>& aSrcEnd,
|
||||
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 nsAString& aString );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts case in place in the argument string.
|
||||
*/
|
||||
NS_COM void ToUpperCase( nsAString& );
|
||||
NS_COM void ToUpperCase( nsACString& );
|
||||
|
||||
NS_COM void ToLowerCase( nsAString& );
|
||||
NS_COM void ToLowerCase( nsACString& );
|
||||
|
||||
/**
|
||||
* Finds the leftmost occurance of |aPattern|, if any in the range |aSearchStart|..|aSearchEnd|.
|
||||
*
|
||||
* Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to
|
||||
* point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|.
|
||||
*
|
||||
* 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 nsAString& aPattern, nsReadingIterator<PRUnichar>&, nsReadingIterator<PRUnichar>& );
|
||||
NS_COM PRBool FindInReadable( const nsACString& aPattern, nsReadingIterator<char>&, nsReadingIterator<char>& );
|
||||
|
||||
|
||||
/**
|
||||
* Finds the rightmost occurance of |aPattern|
|
||||
* Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to
|
||||
* point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|.
|
||||
*
|
||||
* 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 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
|
||||
* |aSearchStart|..|aSearchEnd|.
|
||||
*
|
||||
* Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| to
|
||||
* point to the match. If no match was found, returns |PR_FALSE| and
|
||||
* makes |aSearchStart == aSearchEnd|.
|
||||
*/
|
||||
NS_COM PRBool FindCharInReadable( PRUnichar aChar, nsReadingIterator<PRUnichar>& aSearchStart, const nsReadingIterator<PRUnichar>& aSearchEnd );
|
||||
NS_COM PRBool FindCharInReadable( char aChar, nsReadingIterator<char>& aSearchStart, const nsReadingIterator<char>& aSearchEnd );
|
||||
|
||||
/**
|
||||
* Finds the number of occurences of |aChar| in the string |aStr|
|
||||
*/
|
||||
NS_COM PRUint32 CountCharInReadable( const nsAString& aStr,
|
||||
PRUnichar aChar );
|
||||
NS_COM PRUint32 CountCharInReadable( const nsACString& aStr,
|
||||
char aChar );
|
||||
|
||||
#endif // !defined(nsReadableUtils_h___)
|
||||
102
mozilla/string/public/nsSharableString.h
Normal file
102
mozilla/string/public/nsSharableString.h
Normal 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___) */
|
||||
224
mozilla/string/public/nsSharedBufferList.h
Executable file
224
mozilla/string/public/nsSharedBufferList.h
Executable file
@@ -0,0 +1,224 @@
|
||||
/* -*- 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 strings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsSharedBufferList_h___
|
||||
#define nsSharedBufferList_h___
|
||||
|
||||
#ifndef nsBufferHandle_h___
|
||||
#include "nsBufferHandle.h"
|
||||
// for |nsSharedBufferHandle|
|
||||
#endif
|
||||
|
||||
#ifndef nscore_h___
|
||||
#include "nscore.h"
|
||||
// for |PRUnichar|
|
||||
#endif
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsLocalString_h___
|
||||
#include "nsLocalString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsBufferHandleUtils_h___
|
||||
#include "nsBufferHandleUtils.h"
|
||||
// for |NS_AllocateContiguousHandleWithData|
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* This class forms the basis for several multi-fragment string classes, in
|
||||
* particular: |nsFragmentedString| (though not yet), and |nsSlidingString|/|nsSlidingSubstring|.
|
||||
*
|
||||
* This class is not templated. It is provided only for |PRUnichar|-based strings.
|
||||
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
|
||||
* or else duplicate this class.
|
||||
*/
|
||||
class NS_COM nsSharedBufferList
|
||||
{
|
||||
public:
|
||||
|
||||
class Buffer
|
||||
: public nsFlexBufferHandle<PRUnichar>
|
||||
{
|
||||
public:
|
||||
Buffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageStart, PRUnichar* aStorageEnd, PRBool aIsSingleAllocation=PR_FALSE )
|
||||
: nsFlexBufferHandle<PRUnichar>(aDataStart, aDataEnd, aStorageStart, aStorageEnd)
|
||||
{
|
||||
if ( aIsSingleAllocation )
|
||||
this->mFlags |= this->kIsSingleAllocationWithBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* These buffers will be `owned' by the list, and only the
|
||||
* the list itself will be allowed to delete member |Buffer|s,
|
||||
* therefore, we cannot use the inherited |AcquireReference|
|
||||
* and |ReleaseReference|, as they use the model that the
|
||||
* buffer manages its own lifetime.
|
||||
*/
|
||||
void
|
||||
AcquireNonOwningReference() const
|
||||
{
|
||||
Buffer* mutable_this = NS_CONST_CAST(Buffer*, this);
|
||||
mutable_this->set_refcount( get_refcount()+1 );
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseNonOwningReference() const
|
||||
{
|
||||
Buffer* mutable_this = NS_CONST_CAST(Buffer*, this);
|
||||
mutable_this->set_refcount( get_refcount()-1 );
|
||||
}
|
||||
|
||||
Buffer* mPrev;
|
||||
Buffer* mNext;
|
||||
|
||||
private:
|
||||
// pass-by-value is explicitly denied
|
||||
Buffer( const Buffer& ); // NOT TO BE IMPLEMENTED
|
||||
void operator=( const Buffer& ); // NOT TO BE IMPLEMENTED
|
||||
};
|
||||
|
||||
struct Position
|
||||
{
|
||||
Buffer* mBuffer;
|
||||
PRUnichar* mPosInBuffer;
|
||||
|
||||
Position() { }
|
||||
Position( Buffer* aBuffer, PRUnichar* aPosInBuffer ) : mBuffer(aBuffer), mPosInBuffer(aPosInBuffer) { }
|
||||
|
||||
// Position( const Position& ); -- auto-generated copy-constructor OK
|
||||
// Position& operator=( const Position& ); -- auto-generated copy-assignment OK
|
||||
// ~Position(); -- auto-generated destructor OK
|
||||
|
||||
// iff |aIter| is a valid iterator into a |nsSharedBufferList|
|
||||
explicit
|
||||
Position( const nsReadingIterator<PRUnichar>& aIter )
|
||||
: mBuffer( NS_CONST_CAST(Buffer*, NS_REINTERPRET_CAST(const Buffer*, aIter.fragment().mFragmentIdentifier)) ),
|
||||
mPosInBuffer( NS_CONST_CAST(PRUnichar*, aIter.get()) )
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
// iff |aIter| is a valid iterator into a |nsSharedBufferList|
|
||||
Position&
|
||||
operator=( const nsReadingIterator<PRUnichar>& aIter )
|
||||
{
|
||||
mBuffer = NS_CONST_CAST(Buffer*, NS_REINTERPRET_CAST(const Buffer*, aIter.fragment().mFragmentIdentifier));
|
||||
mPosInBuffer = NS_CONST_CAST(PRUnichar*, aIter.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PointTo( Buffer* aBuffer, PRUnichar* aPosInBuffer ) { mBuffer=aBuffer; mPosInBuffer=aPosInBuffer; }
|
||||
void PointBefore( Buffer* aBuffer ) { PointTo(aBuffer, aBuffer->DataStart()); }
|
||||
void PointAfter( Buffer* aBuffer ) { PointTo(aBuffer, aBuffer->DataEnd()); }
|
||||
|
||||
// Position( const Position& ); -- automatically generated copy-constructor is OK
|
||||
// Position& operator=( const Position& ); -- automatically generated copy-assignment operator is OK
|
||||
|
||||
// don't want to provide this as |operator-|, since that might imply O(1)
|
||||
static ptrdiff_t Distance( const Position&, const Position& );
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
nsSharedBufferList( Buffer* aBuffer = 0 )
|
||||
: mFirstBuffer(aBuffer),
|
||||
mLastBuffer(aBuffer),
|
||||
mTotalDataLength(0)
|
||||
{
|
||||
if ( aBuffer )
|
||||
{
|
||||
aBuffer->mPrev = aBuffer->mNext = 0;
|
||||
mTotalDataLength = aBuffer->DataLength();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~nsSharedBufferList();
|
||||
|
||||
private:
|
||||
// pass-by-value is explicitly denied
|
||||
nsSharedBufferList( const nsSharedBufferList& ); // NOT TO BE IMPLEMENTED
|
||||
void operator=( const nsSharedBufferList& ); // NOT TO BE IMPLEMENTED
|
||||
|
||||
public:
|
||||
void LinkBuffer( Buffer*, Buffer*, Buffer* );
|
||||
Buffer* UnlinkBuffer( Buffer* );
|
||||
|
||||
enum SplitDisposition // when splitting a buffer in two...
|
||||
{
|
||||
kSplitCopyRightData, // copy the data right of the split point to a new buffer
|
||||
kSplitCopyLeastData, // copy the smaller amount of data to the new buffer
|
||||
kSplitCopyLeftData // copy the data left of the split point to a new buffer
|
||||
};
|
||||
|
||||
void SplitBuffer( const Position&, SplitDisposition = kSplitCopyLeastData );
|
||||
|
||||
static
|
||||
Buffer*
|
||||
NewSingleAllocationBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalCapacity = 1 )
|
||||
{
|
||||
typedef Buffer* Buffer_ptr;
|
||||
return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), nsLocalString(aData, aDataLength), aAdditionalCapacity);
|
||||
}
|
||||
|
||||
static
|
||||
Buffer*
|
||||
NewSingleAllocationBuffer( const nsAString& aReadable, PRUint32 aAdditionalCapacity = 1 )
|
||||
{
|
||||
typedef Buffer* Buffer_ptr;
|
||||
return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), aReadable, aAdditionalCapacity);
|
||||
}
|
||||
|
||||
static
|
||||
Buffer*
|
||||
NewWrappingBuffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd )
|
||||
{
|
||||
return new Buffer(aDataStart, aDataEnd, aDataStart, aStorageEnd);
|
||||
}
|
||||
|
||||
void DiscardSuffix( PRUint32 );
|
||||
// need other discards: prefix, and by iterator or pointer or something
|
||||
|
||||
Buffer* GetFirstBuffer() { return mFirstBuffer; }
|
||||
const Buffer* GetFirstBuffer() const { return mFirstBuffer; }
|
||||
|
||||
Buffer* GetLastBuffer() { return mLastBuffer; }
|
||||
const Buffer* GetLastBuffer() const { return mLastBuffer; }
|
||||
|
||||
ptrdiff_t GetDataLength() const { return mTotalDataLength; }
|
||||
|
||||
protected:
|
||||
void DestroyBuffers();
|
||||
|
||||
protected:
|
||||
Buffer* mFirstBuffer;
|
||||
Buffer* mLastBuffer;
|
||||
ptrdiff_t mTotalDataLength;
|
||||
};
|
||||
|
||||
#endif // !defined(nsSharedBufferList_h___)
|
||||
203
mozilla/string/public/nsSlidingString.h
Executable file
203
mozilla/string/public/nsSlidingString.h
Executable file
@@ -0,0 +1,203 @@
|
||||
/* -*- 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 strings.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scott Collins <scc@mozilla.org> (original author)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsSlidingString_h___
|
||||
#define nsSlidingString_h___
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsSharedBufferList_h___
|
||||
#include "nsSharedBufferList.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Maintains the sequence from the prev-most referenced buffer to the last buffer.
|
||||
* As prev-most buffers become un-referenced, they are unlinked from the list
|
||||
* and destroyed.
|
||||
*
|
||||
* One or more |nsSlidingSubstring|s may reference into the list. Each |nsSlidingSubstring|
|
||||
* holds a reference into the prev-most buffer intersecting the
|
||||
* substring it describes. The destructor of a |nsSlidingSubstring| releases this
|
||||
* reference, allowing the buffer list to destroy the contiguous prefix of
|
||||
* unreferenced buffers.
|
||||
*
|
||||
* A single instance of |nsSlidingString| may reference this list.
|
||||
* Through that interface, new data can be appended onto the next-most end
|
||||
* of the list. |nsSlidingString| also the client to advance its starting point.
|
||||
*
|
||||
*/
|
||||
class NS_COM nsSlidingSharedBufferList
|
||||
: public nsSharedBufferList
|
||||
{
|
||||
public:
|
||||
nsSlidingSharedBufferList( Buffer* aBuffer ) : nsSharedBufferList(aBuffer), mRefCount(0) { }
|
||||
|
||||
void AcquireReference() { ++mRefCount; }
|
||||
void ReleaseReference() { if ( !--mRefCount ) delete this; }
|
||||
|
||||
void DiscardUnreferencedPrefix( Buffer* );
|
||||
|
||||
private:
|
||||
PRUint32 mRefCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class nsSlidingString;
|
||||
|
||||
/**
|
||||
* a substring over a buffer list, this
|
||||
*/
|
||||
class NS_COM nsSlidingSubstring
|
||||
: virtual public nsAPromiseString
|
||||
{
|
||||
friend class nsSlidingString;
|
||||
|
||||
public:
|
||||
typedef nsSlidingSharedBufferList::Buffer Buffer;
|
||||
typedef nsSlidingSharedBufferList::Position Position;
|
||||
|
||||
nsSlidingSubstring()
|
||||
: mStart(0,0),
|
||||
mEnd(0,0),
|
||||
mBufferList(0),
|
||||
mLength(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
nsSlidingSubstring( const nsSlidingSubstring& ); // copy-constructor
|
||||
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 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 nsAString& );
|
||||
|
||||
~nsSlidingSubstring();
|
||||
|
||||
virtual PRUint32 Length() const { return mLength; }
|
||||
|
||||
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
|
||||
void operator=( const nsSlidingSubstring& ); // NOT TO BE IMPLEMENTED
|
||||
|
||||
void
|
||||
init_range_from_buffer_list()
|
||||
// used only from constructors
|
||||
{
|
||||
mStart.PointBefore(mBufferList->GetFirstBuffer());
|
||||
mEnd.PointAfter(mBufferList->GetLastBuffer());
|
||||
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
||||
}
|
||||
|
||||
void
|
||||
acquire_ownership_of_buffer_list() const
|
||||
// used only from constructors and |Rebind|, requires |mStart| already be initialized
|
||||
{
|
||||
mBufferList->AcquireReference();
|
||||
mStart.mBuffer->AcquireNonOwningReference();
|
||||
}
|
||||
|
||||
void
|
||||
release_ownership_of_buffer_list()
|
||||
{
|
||||
if ( mBufferList )
|
||||
{
|
||||
mStart.mBuffer->ReleaseNonOwningReference();
|
||||
mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer);
|
||||
mBufferList->ReleaseReference();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Position mStart;
|
||||
Position mEnd;
|
||||
nsSlidingSharedBufferList* mBufferList;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An |nsSlidingSharedBufferList| may be modified by zero or one instances of this class.
|
||||
*
|
||||
*/
|
||||
class NS_COM nsSlidingString
|
||||
: virtual public nsAPromiseString,
|
||||
private nsSlidingSubstring
|
||||
{
|
||||
friend class nsSlidingSubstring;
|
||||
|
||||
public:
|
||||
nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd );
|
||||
// ...created by consuming ownership of a buffer ... |aStorageStart| must point to something
|
||||
// that it will be OK for the slidking string to call |nsMemory::Free| on
|
||||
|
||||
virtual PRUint32 Length() const { return mLength; }
|
||||
|
||||
// you are giving ownership to the string, it takes and keeps your buffer, deleting it (with |nsMemory::Free|) when done
|
||||
void AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd );
|
||||
|
||||
// void Append( ... ); do you want some |Append|s that copy the supplied data?
|
||||
|
||||
void DiscardPrefix( const nsReadingIterator<PRUnichar>& );
|
||||
// any other way you want to do this?
|
||||
|
||||
protected:
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
|
||||
|
||||
void InsertReadable( const nsAString&, const nsReadingIterator<PRUnichar>& ); // ...to implement |nsScannerString::UngetReadable|
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
acquire_ownership_of_buffer_list() const
|
||||
// used only from constructors and |Rebind|, requires |mStart| already be initialized
|
||||
{
|
||||
mBufferList->AcquireReference();
|
||||
mStart.mBuffer->AcquireNonOwningReference();
|
||||
}
|
||||
|
||||
nsSlidingString( const nsSlidingString& ); // NOT TO BE IMPLEMENTED
|
||||
void operator=( const nsSlidingString& ); // NOT TO BE IMPLEMENTED
|
||||
};
|
||||
|
||||
#endif // !defined(nsSlidingString_h___)
|
||||
94
mozilla/string/public/nsStringFragment.h
Normal file
94
mozilla/string/public/nsStringFragment.h
Normal 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___) */
|
||||
61
mozilla/string/public/nsStringFwd.h
Normal file
61
mozilla/string/public/nsStringFwd.h
Normal 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___) */
|
||||
436
mozilla/string/public/nsStringIterator.h
Normal file
436
mozilla/string/public/nsStringIterator.h
Normal 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___) */
|
||||
44
mozilla/string/public/nsStringIteratorUtils.h
Normal file
44
mozilla/string/public/nsStringIteratorUtils.h
Normal 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___) */
|
||||
76
mozilla/string/public/nsStringTraits.h
Normal file
76
mozilla/string/public/nsStringTraits.h
Normal 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___) */
|
||||
61
mozilla/string/src/Makefile.in
Normal file
61
mozilla/string/src/Makefile.in
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
# Scott Collins <scc@mozilla.org>
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = string
|
||||
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 \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
53
mozilla/string/src/makefile.win
Normal file
53
mozilla/string/src/makefile.win
Normal file
@@ -0,0 +1,53 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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):
|
||||
# Johnny Stenback <jst@netscape.com> (original author)
|
||||
# Scott Collins <scc@mozilla.org>
|
||||
#
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
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 \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
116
mozilla/string/src/nsAFlatString.cpp
Normal file
116
mozilla/string/src/nsAFlatString.cpp
Normal 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
mozilla/string/src/nsAString.cpp
Normal file
921
mozilla/string/src/nsAString.cpp
Normal 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)));
|
||||
}
|
||||
|
||||
58
mozilla/string/src/nsCommonString.cpp
Normal file
58
mozilla/string/src/nsCommonString.cpp
Normal 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();
|
||||
}
|
||||
|
||||
197
mozilla/string/src/nsDependentConcatenation.cpp
Normal file
197
mozilla/string/src/nsDependentConcatenation.cpp
Normal 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;
|
||||
}
|
||||
25
mozilla/string/src/nsDependentString.cpp
Normal file
25
mozilla/string/src/nsDependentString.cpp
Normal 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"
|
||||
|
||||
123
mozilla/string/src/nsDependentSubstring.cpp
Normal file
123
mozilla/string/src/nsDependentSubstring.cpp
Normal 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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user