зеркало из https://github.com/mozilla/pjs.git
Merge backout; a=leak-fix
This commit is contained in:
Коммит
25fc6b7dc5
|
@ -242,8 +242,8 @@ interface nsIXMLHttpRequest : nsISupports
|
|||
*/
|
||||
[optional_argc] void open(in AUTF8String method, in AUTF8String url,
|
||||
[optional] in boolean async,
|
||||
[optional] in DOMString user,
|
||||
[optional] in DOMString password);
|
||||
[optional,Undefined(Empty)] in DOMString user,
|
||||
[optional,Undefined(Empty)] in DOMString password);
|
||||
|
||||
/**
|
||||
* Sends the request. If the request is asynchronous, returns
|
||||
|
|
|
@ -445,9 +445,8 @@ nsAttrValue::ToString(nsAString& aResult) const
|
|||
#endif
|
||||
case eFloatValue:
|
||||
{
|
||||
nsAutoString str;
|
||||
str.AppendFloat(GetFloatValue());
|
||||
aResult = str;
|
||||
aResult.Truncate();
|
||||
aResult.AppendFloat(GetFloatValue());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -4351,7 +4351,18 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
|||
nsIDOMElement** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult rv = CreateElementNS(aNamespaceURI, aQualifiedName,
|
||||
getter_AddRefs(content));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return CallQueryInterface(content, aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
nsIContent** aReturn)
|
||||
{
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
|
||||
aQualifiedName,
|
||||
|
@ -4359,13 +4370,9 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
|||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
PRInt32 ns = nodeInfo->NamespaceID();
|
||||
rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(),
|
||||
NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(content, aReturn);
|
||||
return NS_NewElement(aReturn, ns,
|
||||
nodeInfo.forget(), NOT_FROM_PARSER);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -859,6 +859,9 @@ public:
|
|||
|
||||
nsresult CreateElement(const nsAString& aTagName,
|
||||
nsIContent** aReturn);
|
||||
nsresult CreateElementNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aQualifiedName,
|
||||
nsIContent** aReturn);
|
||||
|
||||
nsresult CreateTextNode(const nsAString& aData, nsIContent** aReturn);
|
||||
|
||||
|
|
|
@ -1095,19 +1095,6 @@ nsIContent::IsEqual(nsIContent* aOther)
|
|||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Child nodes count.
|
||||
PRUint32 childCount = GetChildCount();
|
||||
if (childCount != element2->GetChildCount()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Iterate over child nodes.
|
||||
for (PRUint32 i = 0; i < childCount; ++i) {
|
||||
if (!GetChildAt(i)->IsEqual(element2->GetChildAt(i))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Node value check.
|
||||
nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(this);
|
||||
|
@ -1120,6 +1107,18 @@ nsIContent::IsEqual(nsIContent* aOther)
|
|||
}
|
||||
}
|
||||
|
||||
// Child nodes count.
|
||||
PRUint32 childCount = GetChildCount();
|
||||
if (childCount != aOther->GetChildCount()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Iterate over child nodes.
|
||||
for (PRUint32 i = 0; i < childCount; ++i) {
|
||||
if (!GetChildAt(i)->IsEqual(aOther->GetChildAt(i))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -370,17 +370,17 @@ _TEST_FILES2 = \
|
|||
file_CSP_main.html \
|
||||
file_CSP_main.html^headers^ \
|
||||
file_CSP_main.js \
|
||||
test_CSP_frameancestors.html \
|
||||
file_CSP_frameancestors.sjs \
|
||||
file_CSP_frameancestors_main.html \
|
||||
file_CSP_frameancestors_main.js \
|
||||
test_CSP_inlinescript.html \
|
||||
file_CSP_inlinescript_main.html \
|
||||
file_CSP_inlinescript_main.html^headers^ \
|
||||
test_CSP_evalscript.html \
|
||||
file_CSP_evalscript_main.html \
|
||||
file_CSP_evalscript_main.html^headers^ \
|
||||
file_CSP_evalscript_main.js \
|
||||
test_CSP_frameancestors.html \
|
||||
file_CSP_frameancestors.sjs \
|
||||
file_CSP_frameancestors_main.html \
|
||||
file_CSP_frameancestors_main.js \
|
||||
test_CSP_inlinescript.html \
|
||||
file_CSP_inlinescript_main.html \
|
||||
file_CSP_inlinescript_main.html^headers^ \
|
||||
test_CSP_evalscript.html \
|
||||
file_CSP_evalscript_main.html \
|
||||
file_CSP_evalscript_main.html^headers^ \
|
||||
file_CSP_evalscript_main.js \
|
||||
test_bug540854.html \
|
||||
bug540854.sjs \
|
||||
test_bug548463.html \
|
||||
|
@ -444,6 +444,7 @@ _TEST_FILES2 = \
|
|||
test_bug605982.html \
|
||||
test_bug606729.html \
|
||||
test_treewalker_nextsibling.xml \
|
||||
test_bug614058.html \
|
||||
$(NULL)
|
||||
|
||||
# This test fails on the Mac for some reason
|
||||
|
|
|
@ -16,7 +16,11 @@ window.addEventListener("message", function(e) {
|
|||
var res = {
|
||||
didFail: false,
|
||||
events: [],
|
||||
progressEvents: 0
|
||||
progressEvents: 0,
|
||||
status: 0,
|
||||
responseText: "",
|
||||
responseXML: null,
|
||||
sendThrew: false
|
||||
};
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
@ -72,14 +76,28 @@ window.addEventListener("message", function(e) {
|
|||
sendData = req.body;
|
||||
|
||||
res.events.push("opening");
|
||||
xhr.open(req.method, req.url, true);
|
||||
// Allow passign in falsy usernames/passwords so we can test them
|
||||
try {
|
||||
xhr.open(req.method, req.url, true,
|
||||
("username" in req) ? req.username : "",
|
||||
("password" in req) ? req.password : "aa");
|
||||
} catch (ex) {
|
||||
res.didFail = true;
|
||||
post(e, res);
|
||||
}
|
||||
|
||||
for (header in req.headers) {
|
||||
xhr.setRequestHeader(header, req.headers[header]);
|
||||
}
|
||||
|
||||
res.events.push("sending");
|
||||
xhr.send(sendData);
|
||||
try {
|
||||
xhr.send(sendData);
|
||||
} catch (ex) {
|
||||
res.didFail = true;
|
||||
res.sendThrew = true;
|
||||
post(e, res);
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
|
|
|
@ -49,6 +49,37 @@ function runTest() {
|
|||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// undefined username
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
noAllowPreflight: 1,
|
||||
username: undefined
|
||||
},
|
||||
|
||||
// undefined username and password
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
noAllowPreflight: 1,
|
||||
username: undefined,
|
||||
password: undefined
|
||||
},
|
||||
|
||||
// nonempty username
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
noAllowPreflight: 1,
|
||||
username: "user",
|
||||
},
|
||||
|
||||
// nonempty password
|
||||
// XXXbz this passes for now, because we ignore passwords
|
||||
// without usernames in most cases.
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
noAllowPreflight: 1,
|
||||
password: "password",
|
||||
},
|
||||
|
||||
// Default allowed headers
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
|
@ -557,6 +588,14 @@ function runTest() {
|
|||
"&requestMethod=" + test.method;
|
||||
}
|
||||
|
||||
if ("username" in test) {
|
||||
req.username = test.username;
|
||||
}
|
||||
|
||||
if ("password" in test) {
|
||||
req.password = test.password;
|
||||
}
|
||||
|
||||
if (test.noAllowPreflight)
|
||||
req.url += "&noAllowPreflight";
|
||||
|
||||
|
@ -653,9 +692,11 @@ function runTest() {
|
|||
"wrong responseXML in test for " + test.toSource());
|
||||
is(res.responseText, "",
|
||||
"wrong responseText in test for " + test.toSource());
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
|
||||
"wrong events in test for " + test.toSource());
|
||||
if (!res.sendThrew) {
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
|
||||
"wrong events in test for " + test.toSource());
|
||||
}
|
||||
is(res.progressEvents, 0,
|
||||
"wrong events in test for " + test.toSource());
|
||||
if (test.responseHeaders) {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=614058
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 614058</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614058">Mozilla Bug 614058</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 614058 **/
|
||||
var f1 = document.createDocumentFragment();
|
||||
f2 = f1.cloneNode(true);
|
||||
f1.appendChild(document.createElement("foo"));
|
||||
is(f1.isEqualNode(f2), false, "Fragments have different kids!");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -948,9 +948,7 @@ nsCanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString&
|
|||
NS_GET_G(aColor),
|
||||
NS_GET_B(aColor)),
|
||||
aStr);
|
||||
nsString tmp;
|
||||
tmp.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
|
||||
aStr.Append(tmp);
|
||||
aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
|
||||
aStr.Append(')');
|
||||
}
|
||||
}
|
||||
|
@ -2801,9 +2799,11 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
|||
|
||||
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
|
||||
|
||||
// back up path if stroking
|
||||
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE)
|
||||
// back up and clear path if stroking
|
||||
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
|
||||
pathSR.Save();
|
||||
mThebes->NewPath();
|
||||
}
|
||||
// doUseIntermediateSurface is mutually exclusive to op == STROKE
|
||||
else {
|
||||
if (doUseIntermediateSurface) {
|
||||
|
|
|
@ -122,9 +122,8 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
|
|||
void
|
||||
nsSVGNumber2::GetBaseValueString(nsAString & aValueAsString)
|
||||
{
|
||||
nsAutoString s;
|
||||
s.AppendFloat(mBaseVal);
|
||||
aValueAsString.Assign(s);
|
||||
aValueAsString.Truncate();
|
||||
aValueAsString.AppendFloat(mBaseVal);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -4004,7 +4004,7 @@ SetMemoryHighWaterMarkPrefChangedCallback(const char* aPrefName, void* aClosure)
|
|||
* In the browser, we don't cap the amount of GC-owned memory.
|
||||
*/
|
||||
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
|
||||
128L * 1024L * 1024L);
|
||||
80L * 1024L * 1024L);
|
||||
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
|
||||
0xffffffff);
|
||||
} else {
|
||||
|
|
|
@ -103,6 +103,7 @@ members = [
|
|||
'nsIDOMDocument.getElementById',
|
||||
'nsIDOMDocument.createDocumentFragment',
|
||||
'nsIDOMDocument.createElement',
|
||||
'nsIDOMDocument.createElementNS',
|
||||
'nsIDOMDocument.importNode',
|
||||
'nsIDOMDocument.createTextNode',
|
||||
'nsIDOMElement.removeAttributeNS',
|
||||
|
@ -427,8 +428,6 @@ members = [
|
|||
# nsIXMLHttpRequest.channel is not used on the web, and more
|
||||
# importantly relies on the CAPS check that quickstubs don't make.
|
||||
'-nsIXMLHttpRequest.channel',
|
||||
# nsIXMLHttpRequest.open uses the JS stack
|
||||
'-nsIXMLHttpRequest.open',
|
||||
# various XHR things use ACString and AUTF8String and [cstring]
|
||||
# which quickstubs don't handle as return values (or at all in the
|
||||
# case of AUTF8String) yet.
|
||||
|
@ -909,6 +908,11 @@ customMethodCalls = {
|
|||
'code': ' nsCOMPtr<nsIContent> result;\n'
|
||||
' rv = self->CreateElement(arg0, getter_AddRefs(result));'
|
||||
},
|
||||
'nsIDOMDocument_CreateElementNS': {
|
||||
'thisType': 'nsDocument',
|
||||
'code': ' nsCOMPtr<nsIContent> result;\n'
|
||||
' rv = self->CreateElementNS(arg0, arg1, getter_AddRefs(result));'
|
||||
},
|
||||
'nsIDOMDocument_CreateTextNode': {
|
||||
'thisType': 'nsDocument',
|
||||
'code': ' nsCOMPtr<nsIContent> result;\n'
|
||||
|
|
|
@ -496,6 +496,11 @@ argumentUnboxingTemplates = {
|
|||
" if (!${name}.IsValid())\n"
|
||||
" return JS_FALSE;\n",
|
||||
|
||||
'[utf8string]':
|
||||
" xpc_qsAUTF8String ${name}(cx, ${argVal}, ${argPtr});\n"
|
||||
" if (!${name}.IsValid())\n"
|
||||
" return JS_FALSE;\n",
|
||||
|
||||
'[jsval]':
|
||||
" jsval ${name} = ${argVal};\n"
|
||||
}
|
||||
|
@ -580,7 +585,7 @@ def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared,
|
|||
" }\n")
|
||||
return True
|
||||
|
||||
warn("Unable to unbox argument of type %s" % type.name)
|
||||
warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
|
||||
if i is None:
|
||||
src = '*vp'
|
||||
else:
|
||||
|
@ -1131,7 +1136,7 @@ traceableArgumentConversionTemplates = {
|
|||
" XPCReadableJSStringWrapper ${name}(${argVal});\n",
|
||||
'[domstring]':
|
||||
" XPCReadableJSStringWrapper ${name}(${argVal});\n",
|
||||
'[cstring]':
|
||||
'[utf8string]':
|
||||
" NS_ConvertUTF16toUTF8 ${name}("
|
||||
"(const PRUnichar *)JS_GetStringChars(${argVal}), "
|
||||
"JS_GetStringLength(${argVal}));\n",
|
||||
|
|
|
@ -694,83 +694,28 @@ xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
|
|||
StringificationBehavior nullBehavior,
|
||||
StringificationBehavior undefinedBehavior)
|
||||
{
|
||||
// From the T_DOMSTRING case in XPCConvert::JSData2Native.
|
||||
typedef implementation_type::char_traits traits;
|
||||
JSString *s;
|
||||
const PRUnichar *chars;
|
||||
size_t len;
|
||||
// From the T_DOMSTRING case in XPCConvert::JSData2Native.
|
||||
JSString *s = InitOrStringify<traits>(cx, v, pval, nullBehavior,
|
||||
undefinedBehavior);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
if(JSVAL_IS_STRING(v))
|
||||
{
|
||||
s = JSVAL_TO_STRING(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringificationBehavior behavior = eStringify;
|
||||
if(JSVAL_IS_NULL(v))
|
||||
{
|
||||
behavior = nullBehavior;
|
||||
}
|
||||
else if(JSVAL_IS_VOID(v))
|
||||
{
|
||||
behavior = undefinedBehavior;
|
||||
}
|
||||
|
||||
// If pval is null, that means the argument was optional and
|
||||
// not passed; turn those into void strings if they're
|
||||
// supposed to be stringified.
|
||||
if (behavior != eStringify || !pval)
|
||||
{
|
||||
// Here behavior == eStringify implies !pval, so both eNull and
|
||||
// eStringify should end up with void strings.
|
||||
(new(mBuf) implementation_type(
|
||||
traits::sEmptyBuffer, PRUint32(0)))->SetIsVoid(behavior != eEmpty);
|
||||
mValid = JS_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
s = JS_ValueToString(cx, v);
|
||||
if(!s)
|
||||
{
|
||||
mValid = JS_FALSE;
|
||||
return;
|
||||
}
|
||||
*pval = STRING_TO_JSVAL(s); // Root the new string.
|
||||
}
|
||||
|
||||
len = s->length();
|
||||
chars = (len == 0 ? traits::sEmptyBuffer :
|
||||
reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s)));
|
||||
size_t len = s->length();
|
||||
const PRUnichar* chars =
|
||||
(len == 0 ? traits::sEmptyBuffer :
|
||||
reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s)));
|
||||
new(mBuf) implementation_type(chars, len);
|
||||
mValid = JS_TRUE;
|
||||
}
|
||||
|
||||
xpc_qsACString::xpc_qsACString(JSContext *cx, jsval v, jsval *pval)
|
||||
{
|
||||
typedef implementation_type::char_traits traits;
|
||||
// From the T_CSTRING case in XPCConvert::JSData2Native.
|
||||
JSString *s;
|
||||
|
||||
if(JSVAL_IS_STRING(v))
|
||||
{
|
||||
s = JSVAL_TO_STRING(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
|
||||
{
|
||||
(new(mBuf) implementation_type())->SetIsVoid(PR_TRUE);
|
||||
mValid = JS_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
s = JS_ValueToString(cx, v);
|
||||
if(!s)
|
||||
{
|
||||
mValid = JS_FALSE;
|
||||
return;
|
||||
}
|
||||
*pval = STRING_TO_JSVAL(s); // Root the new string.
|
||||
}
|
||||
JSString *s = InitOrStringify<traits>(cx, v, pval, eNull, eNull);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
JSAutoByteString bytes(cx, s);
|
||||
if(!bytes)
|
||||
|
@ -783,6 +728,22 @@ xpc_qsACString::xpc_qsACString(JSContext *cx, jsval v, jsval *pval)
|
|||
mValid = JS_TRUE;
|
||||
}
|
||||
|
||||
xpc_qsAUTF8String::xpc_qsAUTF8String(JSContext *cx, jsval v, jsval *pval)
|
||||
{
|
||||
typedef nsCharTraits<PRUnichar> traits;
|
||||
// From the T_UTF8STRING case in XPCConvert::JSData2Native.
|
||||
JSString *s = InitOrStringify<traits>(cx, v, pval, eNull, eNull);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
size_t len = s->length();
|
||||
const PRUnichar* chars =
|
||||
reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s));
|
||||
|
||||
new(mBuf) implementation_type(chars, len);
|
||||
mValid = JS_TRUE;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
getNative(nsISupports *idobj,
|
||||
QITableEntry* entries,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -313,33 +313,6 @@ public:
|
|||
return *Ptr();
|
||||
}
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Neither field is initialized; that is left to the derived class
|
||||
* constructor. However, the destructor destroys the string object
|
||||
* stored in mBuf, if mValid is true.
|
||||
*/
|
||||
void *mBuf[JS_HOWMANY(sizeof(implementation_type), sizeof(void *))];
|
||||
JSBool mValid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class for converting a jsval to DOMString.
|
||||
*
|
||||
* xpc_qsDOMString arg0(cx, &argv[0]);
|
||||
* if (!arg0.IsValid())
|
||||
* return JS_FALSE;
|
||||
*
|
||||
* The second argument to the constructor is an in-out parameter. It must
|
||||
* point to a rooted jsval, such as a JSNative argument or return value slot.
|
||||
* The value in the jsval on entry is converted to a string. The constructor
|
||||
* may overwrite that jsval with a string value, to protect the characters of
|
||||
* the string from garbage collection. The caller must leave the jsval alone
|
||||
* for the lifetime of the xpc_qsDOMString.
|
||||
*/
|
||||
class xpc_qsDOMString : public xpc_qsBasicString<nsAString, nsDependentString>
|
||||
{
|
||||
public:
|
||||
/* Enum that defines how JS |null| and |undefined| should be treated. See
|
||||
* the WebIDL specification. eStringify means convert to the string "null"
|
||||
* or "undefined" respectively, via the standard JS ToString() operation;
|
||||
|
@ -360,6 +333,88 @@ public:
|
|||
eDefaultUndefinedBehavior = eStringify
|
||||
};
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Neither field is initialized; that is left to the derived class
|
||||
* constructor. However, the destructor destroys the string object
|
||||
* stored in mBuf, if mValid is true.
|
||||
*/
|
||||
void *mBuf[JS_HOWMANY(sizeof(implementation_type), sizeof(void *))];
|
||||
JSBool mValid;
|
||||
|
||||
/*
|
||||
* If null is returned, then we either failed or fully initialized
|
||||
* |this|; in either case the caller should return immediately
|
||||
* without doing anything else. Otherwise, the JSString* created
|
||||
* from |v| will be returned. It'll be rooted, as needed, in
|
||||
* *pval. nullBehavior and undefinedBehavior control what happens
|
||||
* when |v| is JSVAL_IS_NULL and JSVAL_IS_VOID respectively.
|
||||
*/
|
||||
template<class traits>
|
||||
JSString* InitOrStringify(JSContext* cx, jsval v, jsval* pval,
|
||||
StringificationBehavior nullBehavior,
|
||||
StringificationBehavior undefinedBehavior) {
|
||||
JSString *s;
|
||||
if(JSVAL_IS_STRING(v))
|
||||
{
|
||||
s = JSVAL_TO_STRING(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringificationBehavior behavior = eStringify;
|
||||
if(JSVAL_IS_NULL(v))
|
||||
{
|
||||
behavior = nullBehavior;
|
||||
}
|
||||
else if(JSVAL_IS_VOID(v))
|
||||
{
|
||||
behavior = undefinedBehavior;
|
||||
}
|
||||
|
||||
// If pval is null, that means the argument was optional and
|
||||
// not passed; turn those into void strings if they're
|
||||
// supposed to be stringified.
|
||||
if (behavior != eStringify || !pval)
|
||||
{
|
||||
// Here behavior == eStringify implies !pval, so both eNull and
|
||||
// eStringify should end up with void strings.
|
||||
(new(mBuf) implementation_type(
|
||||
traits::sEmptyBuffer, PRUint32(0)))->
|
||||
SetIsVoid(behavior != eEmpty);
|
||||
mValid = JS_TRUE;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
s = JS_ValueToString(cx, v);
|
||||
if(!s)
|
||||
{
|
||||
mValid = JS_FALSE;
|
||||
return nsnull;
|
||||
}
|
||||
*pval = STRING_TO_JSVAL(s); // Root the new string.
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class for converting a jsval to DOMString.
|
||||
*
|
||||
* xpc_qsDOMString arg0(cx, &argv[0]);
|
||||
* if (!arg0.IsValid())
|
||||
* return JS_FALSE;
|
||||
*
|
||||
* The second argument to the constructor is an in-out parameter. It must
|
||||
* point to a rooted jsval, such as a JSNative argument or return value slot.
|
||||
* The value in the jsval on entry is converted to a string. The constructor
|
||||
* may overwrite that jsval with a string value, to protect the characters of
|
||||
* the string from garbage collection. The caller must leave the jsval alone
|
||||
* for the lifetime of the xpc_qsDOMString.
|
||||
*/
|
||||
class xpc_qsDOMString : public xpc_qsBasicString<nsAString, nsDependentString>
|
||||
{
|
||||
public:
|
||||
xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
|
||||
StringificationBehavior nullBehavior,
|
||||
StringificationBehavior undefinedBehavior);
|
||||
|
@ -387,6 +442,16 @@ public:
|
|||
xpc_qsACString(JSContext *cx, jsval v, jsval *pval);
|
||||
};
|
||||
|
||||
/**
|
||||
* And similar for AUTF8String.
|
||||
*/
|
||||
class xpc_qsAUTF8String :
|
||||
public xpc_qsBasicString<nsACString, NS_ConvertUTF16toUTF8>
|
||||
{
|
||||
public:
|
||||
xpc_qsAUTF8String(JSContext* cx, jsval v, jsval *pval);
|
||||
};
|
||||
|
||||
struct xpc_qsSelfRef
|
||||
{
|
||||
xpc_qsSelfRef() : ptr(nsnull) {}
|
||||
|
|
|
@ -2468,8 +2468,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
|
|||
*aNewFrame = frameItems.FirstChild();
|
||||
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
|
||||
} else {
|
||||
contentFrame = NS_NewBlockFrame(mPresShell, styleContext,
|
||||
NS_BLOCK_FLOAT_MGR|NS_BLOCK_MARGIN_ROOT);
|
||||
contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
|
||||
if (!contentFrame)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsFrameItems frameItems;
|
||||
|
@ -3709,6 +3708,11 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
|||
CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_ALLOW_BLOCK_STYLES);
|
||||
CHECK_ONLY_ONE_BIT(FCDATA_MAY_NEED_SCROLLFRAME, FCDATA_FORCE_VIEW);
|
||||
#undef CHECK_ONLY_ONE_BIT
|
||||
NS_ASSERTION(!(bits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) ||
|
||||
((bits & FCDATA_FUNC_IS_FULL_CTOR) &&
|
||||
data->mFullConstructor ==
|
||||
&nsCSSFrameConstructor::ConstructNonScrollableBlock),
|
||||
"Unexpected FCDATA_FORCED_NON_SCROLLABLE_BLOCK flag");
|
||||
|
||||
// Don't create a subdocument frame for iframes if we're creating extra frames
|
||||
if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
|
||||
|
@ -4365,20 +4369,25 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
|
|||
"Shouldn't propagate scroll in paginated contexts");
|
||||
|
||||
// If the frame is a block-level frame and is scrollable, then wrap it in a
|
||||
// scroll frame. Except we don't want to do that for paginated contexts for
|
||||
// frames that are block-outside and aren't frames for native anonymous stuff.
|
||||
// The condition on skipping scrollframe construction in the
|
||||
// paginated case needs to match code in ConstructNonScrollableBlock
|
||||
// and in nsFrame::ApplyPaginatedOverflowClipping.
|
||||
// scroll frame.
|
||||
// XXX Ignore tables for the time being
|
||||
// XXXbz it would be nice to combine this with the other block
|
||||
// case... Think about how do do this?
|
||||
if (aDisplay->IsBlockInside() &&
|
||||
aDisplay->IsScrollableOverflow() &&
|
||||
!propagatedScrollToViewport &&
|
||||
(!mPresShell->GetPresContext()->IsPaginated() ||
|
||||
!aDisplay->IsBlockOutside() ||
|
||||
aContent->IsInNativeAnonymousSubtree())) {
|
||||
!propagatedScrollToViewport) {
|
||||
// Except we don't want to do that for paginated contexts for
|
||||
// frames that are block-outside and aren't frames for native
|
||||
// anonymous stuff.
|
||||
if (mPresShell->GetPresContext()->IsPaginated() &&
|
||||
aDisplay->IsBlockOutside() &&
|
||||
!aContent->IsInNativeAnonymousSubtree()) {
|
||||
static const FrameConstructionData sForcedNonScrollableBlockData =
|
||||
FULL_CTOR_FCDATA(FCDATA_FORCED_NON_SCROLLABLE_BLOCK,
|
||||
&nsCSSFrameConstructor::ConstructNonScrollableBlock);
|
||||
return &sForcedNonScrollableBlockData;
|
||||
}
|
||||
|
||||
static const FrameConstructionData sScrollableBlockData =
|
||||
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock);
|
||||
return &sScrollableBlockData;
|
||||
|
@ -4504,22 +4513,20 @@ nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aSta
|
|||
{
|
||||
nsStyleContext* const styleContext = aItem.mStyleContext;
|
||||
|
||||
// We want a block formatting context root in paginated contexts for
|
||||
// every block that would be scrollable in a non-paginated context.
|
||||
// We mark our blocks with a bit here if this condition is true, so
|
||||
// we can check it later in nsFrame::ApplyPaginatedOverflowClipping.
|
||||
PRBool clipPaginatedOverflow =
|
||||
(aItem.mFCData->mBits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) != 0;
|
||||
if (aDisplay->IsAbsolutelyPositioned() ||
|
||||
aDisplay->IsFloating() ||
|
||||
NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay ||
|
||||
// This check just needs to be the same as the check for using scrollable
|
||||
// blocks in FindDisplayData and the check for clipping in
|
||||
// nsFrame::ApplyPaginatedOverflowClipping; we want a block formatting
|
||||
// context root in paginated contexts for every block that would be
|
||||
// scrollable in a non-paginated context. Note that IsPaginated()
|
||||
// implies that no propagation to viewport has taken place, so we don't
|
||||
// need to check for propagation here.
|
||||
(mPresShell->GetPresContext()->IsPaginated() &&
|
||||
aDisplay->IsBlockInside() &&
|
||||
aDisplay->IsScrollableOverflow() &&
|
||||
aDisplay->IsBlockOutside() &&
|
||||
!aItem.mContent->IsInNativeAnonymousSubtree())) {
|
||||
clipPaginatedOverflow) {
|
||||
*aNewFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
|
||||
if (clipPaginatedOverflow) {
|
||||
(*aNewFrame)->AddStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW);
|
||||
}
|
||||
} else {
|
||||
*aNewFrame = NS_NewBlockFrame(mPresShell, styleContext);
|
||||
}
|
||||
|
|
|
@ -728,6 +728,10 @@ private:
|
|||
This can be used with or without FCDATA_FUNC_IS_FULL_CTOR.
|
||||
The child items might still need table pseudo processing. */
|
||||
#define FCDATA_USE_CHILD_ITEMS 0x20000
|
||||
/* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block
|
||||
would have been scrollable but has been forced to be
|
||||
non-scrollable due to being in a paginated context. */
|
||||
#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x40000
|
||||
|
||||
/* Structure representing information about how a frame should be
|
||||
constructed. */
|
||||
|
|
|
@ -378,7 +378,7 @@ protected:
|
|||
nsLineList::iterator* aEndIterator,
|
||||
PRBool* aInOverflowLines);
|
||||
|
||||
void SetFlags(PRUint32 aFlags) {
|
||||
void SetFlags(nsFrameState aFlags) {
|
||||
mState &= ~NS_BLOCK_FLAGS_MASK;
|
||||
mState |= aFlags;
|
||||
}
|
||||
|
|
|
@ -1231,20 +1231,13 @@ static inline PRBool ApplyOverflowHiddenClipping(nsIFrame* aFrame,
|
|||
static inline PRBool ApplyPaginatedOverflowClipping(nsIFrame* aFrame,
|
||||
const nsStyleDisplay* aDisp)
|
||||
{
|
||||
// These conditions on aDisp need to match the conditions for which in
|
||||
// non-paginated contexts we'd create a scrollframe for a block but in a
|
||||
// paginated context we don't. See nsCSSFrameConstructor::FindDisplayData
|
||||
// for the relevant conditions. These conditions must also match those in
|
||||
// nsCSSFrameConstructor::ConstructNonScrollableBlock for creating block
|
||||
// formatting context roots for forced-to-be-no-longer scrollable blocks in
|
||||
// paginated contexts.
|
||||
// If we're paginated and aFrame is a block, and it has
|
||||
// NS_BLOCK_CLIP_PAGINATED_OVERFLOW set, then we want to clip our
|
||||
// overflow.
|
||||
return
|
||||
aFrame->PresContext()->IsPaginated() &&
|
||||
aDisp->IsBlockInside() &&
|
||||
aDisp->IsScrollableOverflow() &&
|
||||
aDisp->IsBlockOutside() &&
|
||||
aFrame->GetType() == nsGkAtoms::blockFrame &&
|
||||
!aFrame->GetContent()->IsInNativeAnonymousSubtree();
|
||||
(aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0;
|
||||
}
|
||||
|
||||
static PRBool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
|
||||
|
|
|
@ -62,6 +62,10 @@ class nsTableColFrame;
|
|||
* Additional frame-state bits used by nsBlockFrame
|
||||
* See the meanings at http://www.mozilla.org/newlayout/doc/block-and-line.html
|
||||
*
|
||||
* NS_BLOCK_CLIP_PAGINATED_OVERFLOW is only set in paginated prescontexts, on
|
||||
* blocks which were forced to not have scrollframes but still need to clip
|
||||
* the display of their kids.
|
||||
*
|
||||
* NS_BLOCK_HAS_FIRST_LETTER_STYLE means that the block has first-letter style,
|
||||
* even if it has no actual first-letter frame among its descendants.
|
||||
*
|
||||
|
@ -72,6 +76,7 @@ class nsTableColFrame;
|
|||
*/
|
||||
#define NS_BLOCK_MARGIN_ROOT NS_FRAME_STATE_BIT(22)
|
||||
#define NS_BLOCK_FLOAT_MGR NS_FRAME_STATE_BIT(23)
|
||||
#define NS_BLOCK_CLIP_PAGINATED_OVERFLOW NS_FRAME_STATE_BIT(28)
|
||||
#define NS_BLOCK_HAS_FIRST_LETTER_STYLE NS_FRAME_STATE_BIT(29)
|
||||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET NS_FRAME_STATE_BIT(30)
|
||||
#define NS_BLOCK_HAS_FIRST_LETTER_CHILD NS_FRAME_STATE_BIT(31)
|
||||
|
@ -79,6 +84,7 @@ class nsTableColFrame;
|
|||
// next-in-flows and are not private to blocks
|
||||
#define NS_BLOCK_FLAGS_MASK (NS_BLOCK_MARGIN_ROOT | \
|
||||
NS_BLOCK_FLOAT_MGR | \
|
||||
NS_BLOCK_CLIP_PAGINATED_OVERFLOW | \
|
||||
NS_BLOCK_HAS_FIRST_LETTER_STYLE | \
|
||||
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \
|
||||
NS_BLOCK_HAS_FIRST_LETTER_CHILD)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-print">
|
||||
This text should show up
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-print" style="height: 0; overflow: hidden">
|
||||
This text should show up
|
||||
</html>
|
|
@ -1541,6 +1541,7 @@ fails-if(!haveTestPlugin) == 599476.html 599476-ref.html
|
|||
== 604737.html 604737-ref.html
|
||||
== 605138-1.html 605138-1-ref.html
|
||||
== 605157-1.xhtml 605157-1-ref.xhtml
|
||||
== 609272-1.html 609272-1-ref.html
|
||||
== 608636-1.html 608636-1-ref.html
|
||||
== 613433-1.html 613433-1-ref.html
|
||||
== 613433-1.html 613433-2-ref.html
|
||||
|
|
|
@ -39,3 +39,5 @@ asserts-if(cocoaWidget,0-2) == size-change-1.html size-change-1-ref.html
|
|||
== text-bidi-rtl-test.html text-bidi-rtl-ref.html
|
||||
|
||||
!= text-font-lang.html text-font-lang-notref.html
|
||||
|
||||
== strokeText-path.html strokeText-path-ref.html
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript"><!--
|
||||
window.onload = function () {
|
||||
var canvas = document.getElementById('testCanvas'),
|
||||
context = canvas.getContext('2d');
|
||||
|
||||
// draw some text
|
||||
context.font = 'bold 40px sans-serif';
|
||||
context.strokeText("Hello world!", 10, 50);
|
||||
};
|
||||
// --></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see only see "Hello world!" below, without any additional
|
||||
line. JavaScript is required.</p>
|
||||
|
||||
<p><canvas id="testCanvas" width="400" height="300">You need Canvas
|
||||
support.</canvas></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript"><!--
|
||||
window.onload = function () {
|
||||
var canvas = document.getElementById('testCanvas'),
|
||||
context = canvas.getContext('2d');
|
||||
|
||||
// draw a path
|
||||
context.beginPath();
|
||||
context.moveTo(10, 10);
|
||||
context.lineTo(200, 10);
|
||||
context.lineTo(200, 200);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// draw some text
|
||||
context.font = 'bold 40px sans-serif';
|
||||
context.strokeText("Hello world!", 10, 50);
|
||||
};
|
||||
// --></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see only see "Hello world!" below, without any additional
|
||||
line. JavaScript is required.</p>
|
||||
|
||||
<p><canvas id="testCanvas" width="400" height="300">You need Canvas
|
||||
support.</canvas></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -468,10 +468,7 @@ nsMediaQuery::AppendToString(nsAString& aString) const
|
|||
break;
|
||||
case nsMediaFeature::eResolution:
|
||||
{
|
||||
nsAutoString buffer;
|
||||
buffer.AppendFloat(expr.mValue.GetFloatValue());
|
||||
aString.Append(buffer);
|
||||
buffer.Truncate();
|
||||
aString.AppendFloat(expr.mValue.GetFloatValue());
|
||||
if (expr.mValue.GetUnit() == eCSSUnit_Inch) {
|
||||
aString.AppendLiteral("dpi");
|
||||
} else {
|
||||
|
|
|
@ -769,9 +769,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
|||
css::SerializeCalc(*this, ops);
|
||||
}
|
||||
else if (eCSSUnit_Integer == unit) {
|
||||
nsAutoString tmpStr;
|
||||
tmpStr.AppendInt(GetIntValue(), 10);
|
||||
aResult.Append(tmpStr);
|
||||
aResult.AppendInt(GetIntValue(), 10);
|
||||
}
|
||||
else if (eCSSUnit_Enumerated == unit) {
|
||||
if (eCSSProperty_text_decoration == aProperty) {
|
||||
|
@ -832,28 +830,25 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
|||
// round-tripping of all other rgba() values.
|
||||
aResult.AppendLiteral("transparent");
|
||||
} else {
|
||||
nsAutoString tmpStr;
|
||||
PRUint8 a = NS_GET_A(color);
|
||||
if (a < 255) {
|
||||
tmpStr.AppendLiteral("rgba(");
|
||||
aResult.AppendLiteral("rgba(");
|
||||
} else {
|
||||
tmpStr.AppendLiteral("rgb(");
|
||||
aResult.AppendLiteral("rgb(");
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(comma, ", ");
|
||||
|
||||
tmpStr.AppendInt(NS_GET_R(color), 10);
|
||||
tmpStr.Append(comma);
|
||||
tmpStr.AppendInt(NS_GET_G(color), 10);
|
||||
tmpStr.Append(comma);
|
||||
tmpStr.AppendInt(NS_GET_B(color), 10);
|
||||
aResult.AppendInt(NS_GET_R(color), 10);
|
||||
aResult.Append(comma);
|
||||
aResult.AppendInt(NS_GET_G(color), 10);
|
||||
aResult.Append(comma);
|
||||
aResult.AppendInt(NS_GET_B(color), 10);
|
||||
if (a < 255) {
|
||||
tmpStr.Append(comma);
|
||||
tmpStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
|
||||
aResult.Append(comma);
|
||||
aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
|
||||
}
|
||||
tmpStr.Append(PRUnichar(')'));
|
||||
|
||||
aResult.Append(tmpStr);
|
||||
aResult.Append(PRUnichar(')'));
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
|
||||
|
@ -871,14 +866,10 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
|||
aResult.Append(NS_LITERAL_STRING(")"));
|
||||
}
|
||||
else if (eCSSUnit_Percent == unit) {
|
||||
nsAutoString tmpStr;
|
||||
tmpStr.AppendFloat(GetPercentValue() * 100.0f);
|
||||
aResult.Append(tmpStr);
|
||||
aResult.AppendFloat(GetPercentValue() * 100.0f);
|
||||
}
|
||||
else if (eCSSUnit_Percent < unit) { // length unit
|
||||
nsAutoString tmpStr;
|
||||
tmpStr.AppendFloat(GetFloatValue());
|
||||
aResult.Append(tmpStr);
|
||||
aResult.AppendFloat(GetFloatValue());
|
||||
}
|
||||
else if (eCSSUnit_Gradient == unit) {
|
||||
nsCSSValueGradient* gradient = GetGradientValue();
|
||||
|
|
|
@ -174,7 +174,7 @@ PRUint32 nsIOService::gDefaultSegmentCount = 24;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsIOService::nsIOService()
|
||||
: mOffline(PR_TRUE)
|
||||
: mOffline(PR_FALSE)
|
||||
, mOfflineForProfileChange(PR_FALSE)
|
||||
, mManageOfflineStatus(PR_TRUE)
|
||||
, mSettingOffline(PR_FALSE)
|
||||
|
@ -191,11 +191,21 @@ nsIOService::Init()
|
|||
NS_TIME_FUNCTION;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// We need to get references to the DNS service so that we can shut it
|
||||
|
||||
// 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.
|
||||
|
||||
// TODO(darin): Load the Socket and DNS services lazily.
|
||||
|
||||
mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get socket transport service");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_TIME_FUNCTION_MARK("got SocketTransportService");
|
||||
|
||||
mDNSService = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get DNS service");
|
||||
|
@ -283,29 +293,7 @@ nsIOService::Init()
|
|||
nsIOService::~nsIOService()
|
||||
{
|
||||
gIOService = nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIOService::InitializeSocketTransportService()
|
||||
{
|
||||
NS_TIME_FUNCTION;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mSocketTransportService) {
|
||||
mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get socket transport service");
|
||||
}
|
||||
}
|
||||
|
||||
if (mSocketTransportService) {
|
||||
rv = mSocketTransportService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
nsIOService*
|
||||
nsIOService::GetInstance() {
|
||||
|
@ -754,7 +742,10 @@ nsIOService::SetOffline(PRBool offline)
|
|||
rv = mDNSService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
|
||||
}
|
||||
InitializeSocketTransportService();
|
||||
if (mSocketTransportService) {
|
||||
rv = mSocketTransportService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
|
||||
}
|
||||
mOffline = PR_FALSE; // indicate success only AFTER we've
|
||||
// brought up the services
|
||||
|
||||
|
|
|
@ -108,10 +108,6 @@ public:
|
|||
PRBool IsOffline() { return mOffline; }
|
||||
PRBool IsLinkUp();
|
||||
|
||||
PRBool IsComingOnline() const {
|
||||
return mOffline && mSettingOffline && !mSetOfflineValue;
|
||||
}
|
||||
|
||||
private:
|
||||
// These shouldn't be called directly:
|
||||
// - construct using GetInstance
|
||||
|
@ -133,8 +129,6 @@ private:
|
|||
NS_HIDDEN_(void) GetPrefBranch(nsIPrefBranch2 **);
|
||||
NS_HIDDEN_(void) ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove);
|
||||
|
||||
nsresult InitializeSocketTransportService();
|
||||
|
||||
private:
|
||||
PRPackedBool mOffline;
|
||||
PRPackedBool mOfflineForProfileChange;
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -396,10 +395,6 @@ nsSocketTransportService::Init()
|
|||
if (mShuttingDown)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// Don't initialize inside the offline mode
|
||||
if (gIOService->IsOffline() && !gIOService->IsComingOnline())
|
||||
return NS_ERROR_OFFLINE;
|
||||
|
||||
if (!mThreadEvent) {
|
||||
mThreadEvent = PR_NewPollableEvent();
|
||||
//
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include "prmon.h"
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -383,13 +382,6 @@ nsDNSService::Init()
|
|||
if (enableIDN)
|
||||
idn = do_GetService(NS_IDNSERVICE_CONTRACTID);
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
|
||||
// Don't initialize the resolver if we're in offline mode.
|
||||
// Later on, the IO service will reinitialize us when going online.
|
||||
if (gIOService->IsOffline() && !gIOService->IsComingOnline())
|
||||
return NS_OK;
|
||||
|
||||
nsRefPtr<nsHostResolver> res;
|
||||
nsresult rv = nsHostResolver::Create(maxCacheEntries,
|
||||
maxCacheLifetime,
|
||||
|
@ -405,6 +397,8 @@ nsDNSService::Init()
|
|||
// Disable prefetching either by explicit preference or if a manual proxy is configured
|
||||
mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
|
||||
}
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -577,8 +571,8 @@ nsDNSService::Observe(nsISupports *subject, const char *topic, const PRUnichar *
|
|||
|
||||
if (mResolver) {
|
||||
Shutdown();
|
||||
Init();
|
||||
}
|
||||
Init();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsAutoLock.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
|
@ -101,32 +100,6 @@ nsHttpConnectionMgr::~nsHttpConnectionMgr()
|
|||
nsAutoMonitor::DestroyMonitor(mMonitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::EnsureSocketThreadTargetIfOnline()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventTarget> sts;
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool offline = PR_TRUE;
|
||||
ioService->GetOffline(&offline);
|
||||
|
||||
if (!offline) {
|
||||
sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
// do nothing if already initialized
|
||||
if (mSocketThreadTarget)
|
||||
return NS_OK;
|
||||
|
||||
mSocketThreadTarget = sts;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::Init(PRUint16 maxConns,
|
||||
PRUint16 maxConnsPerHost,
|
||||
|
@ -138,19 +111,28 @@ nsHttpConnectionMgr::Init(PRUint16 maxConns,
|
|||
{
|
||||
LOG(("nsHttpConnectionMgr::Init\n"));
|
||||
|
||||
{
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mMaxConns = maxConns;
|
||||
mMaxConnsPerHost = maxConnsPerHost;
|
||||
mMaxConnsPerProxy = maxConnsPerProxy;
|
||||
mMaxPersistConnsPerHost = maxPersistConnsPerHost;
|
||||
mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
|
||||
mMaxRequestDelay = maxRequestDelay;
|
||||
mMaxPipelinedRequests = maxPipelinedRequests;
|
||||
}
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
return EnsureSocketThreadTargetIfOnline();
|
||||
// do nothing if already initialized
|
||||
if (mSocketThreadTarget)
|
||||
return NS_OK;
|
||||
|
||||
// no need to do any special synchronization here since there cannot be
|
||||
// any activity on the socket thread (because Shutdown is synchronous).
|
||||
mMaxConns = maxConns;
|
||||
mMaxConnsPerHost = maxConnsPerHost;
|
||||
mMaxConnsPerProxy = maxConnsPerProxy;
|
||||
mMaxPersistConnsPerHost = maxPersistConnsPerHost;
|
||||
mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
|
||||
mMaxRequestDelay = maxRequestDelay;
|
||||
mMaxPipelinedRequests = maxPipelinedRequests;
|
||||
|
||||
mSocketThreadTarget = sts;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -184,12 +166,6 @@ nsHttpConnectionMgr::Shutdown()
|
|||
nsresult
|
||||
nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
|
||||
{
|
||||
// This object doesn't get reinitialized if the offline state changes, so our
|
||||
// socket thread target might be uninitialized if we were offline when this
|
||||
// object was being initialized, and we go online later on. This call takes
|
||||
// care of initializing the socket thread target if that's the case.
|
||||
EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
nsresult rv;
|
||||
|
@ -309,12 +285,6 @@ nsHttpConnectionMgr::PruneDeadConnections()
|
|||
nsresult
|
||||
nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
|
||||
{
|
||||
// This object doesn't get reinitialized if the offline state changes, so our
|
||||
// socket thread target might be uninitialized if we were offline when this
|
||||
// object was being initialized, and we go online later on. This call takes
|
||||
// care of initializing the socket thread target if that's the case.
|
||||
EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
NS_IF_ADDREF(*target = mSocketThreadTarget);
|
||||
return NS_OK;
|
||||
|
|
|
@ -215,7 +215,6 @@ private:
|
|||
PRUint8 caps, nsHttpConnection *);
|
||||
PRBool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
|
||||
nsresult ProcessNewTransaction(nsHttpTransaction *);
|
||||
nsresult EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
// message handlers have this signature
|
||||
typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(PRInt32, void *);
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
function run_test() {
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
|
||||
var linkService = Components.classes["@mozilla.org/network/network-link-service;1"]
|
||||
.getService(Components.interfaces.nsINetworkLinkService);
|
||||
|
||||
// The offline status should depends on the link status
|
||||
do_check_neq(ioService.offline, linkService.isLinkUp);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
function run_test() {
|
||||
try {
|
||||
var sts = Components.classes["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Components.interfaces.nsISocketTransportService);
|
||||
} catch(e) {}
|
||||
|
||||
do_check_true(!!sts);
|
||||
}
|
|
@ -384,34 +384,6 @@ class nsTString_CharT : public nsTSubstring_CharT
|
|||
NS_COM void AppendWithConversion( const nsTAString_IncompatibleCharT& aString );
|
||||
NS_COM void AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
|
||||
|
||||
using nsTSubstring_CharT::AppendInt;
|
||||
|
||||
/**
|
||||
* Append the given integer to this string
|
||||
* @param aInteger The integer to append
|
||||
* @param aRadix The radix to use; can be 8, 10 or 16.
|
||||
* @deprecated Use AppendInt( PRInt32 aInteger ) or
|
||||
* AppendInt( PRUint32 aInteger, PRInt32 aRadix = 10 )
|
||||
*/
|
||||
NS_COM void AppendInt( PRInt32 aInteger, PRInt32 aRadix ); //radix=8,10 or 16
|
||||
|
||||
/**
|
||||
* Append the given 64-bit integer to this string.
|
||||
* @param aInteger The integer to append
|
||||
* @param aRadix The radix to use; can be 8, 10 or 16.
|
||||
* @deprecated Use AppendInt( PRInt64 aInteger ) or
|
||||
* AppendInt( PRUint64 aInteger, PRInt32 aRadix = 10 )
|
||||
*/
|
||||
NS_COM void AppendInt( PRInt64 aInteger, PRInt32 aRadix );
|
||||
|
||||
/**
|
||||
* Append the given float to this string
|
||||
*/
|
||||
|
||||
NS_COM void AppendFloat( float aFloat );
|
||||
|
||||
NS_COM void AppendFloat( double aFloat );
|
||||
|
||||
#endif // !MOZ_STRING_WITH_OBSOLETE_API
|
||||
|
||||
|
||||
|
|
|
@ -418,6 +418,17 @@ class nsTSubstring_CharT
|
|||
AppendPrintf( fmt, aInteger );
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the given float to this string
|
||||
*/
|
||||
void AppendFloat( float aFloat )
|
||||
{ DoAppendFloat(aFloat, 6); }
|
||||
void AppendFloat( double aFloat )
|
||||
{ DoAppendFloat(aFloat, 15); }
|
||||
private:
|
||||
NS_COM void NS_FASTCALL DoAppendFloat( double aFloat, int digits );
|
||||
public:
|
||||
|
||||
// AppendLiteral must ONLY be applied to an actual literal string.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a char
|
||||
// array variable. Use AppendASCII for those.
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
#include "prdtoa.h"
|
||||
#include "prprf.h"
|
||||
|
||||
/* ***** BEGIN RICKG BLOCK *****
|
||||
*
|
||||
|
@ -800,99 +799,6 @@ RFindCharInSet( const CharT* data, PRUint32 dataLen, const SetCharT* set )
|
|||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a copy of |PR_cnvtf| with a bug fixed. (The second argument
|
||||
* of PR_dtoa is 2 rather than 1.)
|
||||
*
|
||||
* XXX(darin): if this is the right thing, then why wasn't it fixed in NSPR?!?
|
||||
*/
|
||||
void
|
||||
Modified_cnvtf(char *buf, int bufsz, int prcsn, double fval)
|
||||
{
|
||||
PRIntn decpt, sign, numdigits;
|
||||
char *num, *nump;
|
||||
char *bufp = buf;
|
||||
char *endnum;
|
||||
|
||||
/* If anything fails, we store an empty string in 'buf' */
|
||||
num = (char*)malloc(bufsz);
|
||||
if (num == NULL) {
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
|
||||
== PR_FAILURE) {
|
||||
buf[0] = '\0';
|
||||
goto done;
|
||||
}
|
||||
numdigits = endnum - num;
|
||||
nump = num;
|
||||
|
||||
/*
|
||||
* The NSPR code had a fancy way of checking that we weren't dealing
|
||||
* with -0.0 or -NaN, but I'll just use < instead.
|
||||
* XXX Should we check !isnan(fval) as well? Is it portable? We
|
||||
* probably don't need to bother since NAN isn't portable.
|
||||
*/
|
||||
if (sign && fval < 0.0f) {
|
||||
*bufp++ = '-';
|
||||
}
|
||||
|
||||
if (decpt == 9999) {
|
||||
while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
|
||||
*bufp++ = *nump++;
|
||||
if (numdigits != 1) {
|
||||
*bufp++ = '.';
|
||||
}
|
||||
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
*bufp++ = 'e';
|
||||
PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
|
||||
}
|
||||
else if (decpt >= 0) {
|
||||
if (decpt == 0) {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
else {
|
||||
while (decpt--) {
|
||||
if (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
else {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*nump != '\0') {
|
||||
*bufp++ = '.';
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
}
|
||||
*bufp++ = '\0';
|
||||
}
|
||||
else if (decpt < 0) {
|
||||
*bufp++ = '0';
|
||||
*bufp++ = '.';
|
||||
while (decpt++) {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
*bufp++ = '\0';
|
||||
}
|
||||
done:
|
||||
free(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* this method changes the meaning of |offset| and |count|:
|
||||
*
|
||||
|
@ -1171,133 +1077,4 @@ nsString::AppendWithConversion( const nsACString& aData )
|
|||
AppendASCIItoUTF16(aData, *this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nsTString::AppendInt
|
||||
*/
|
||||
|
||||
void
|
||||
nsCString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
|
||||
{
|
||||
char buf[20];
|
||||
const char* fmt;
|
||||
switch (aRadix) {
|
||||
case 8:
|
||||
fmt = "%o";
|
||||
break;
|
||||
case 10:
|
||||
fmt = "%d";
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(aRadix == 16, "Invalid radix!");
|
||||
fmt = "%x";
|
||||
}
|
||||
PR_snprintf(buf, sizeof(buf), fmt, aInteger);
|
||||
Append(buf);
|
||||
}
|
||||
|
||||
void
|
||||
nsString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
|
||||
{
|
||||
char buf[20];
|
||||
const char* fmt;
|
||||
switch (aRadix) {
|
||||
case 8:
|
||||
fmt = "%o";
|
||||
break;
|
||||
case 10:
|
||||
fmt = "%d";
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(aRadix == 16, "Invalid radix!");
|
||||
fmt = "%x";
|
||||
}
|
||||
PR_snprintf(buf, sizeof(buf), fmt, aInteger);
|
||||
AppendASCIItoUTF16(buf, *this);
|
||||
}
|
||||
|
||||
void
|
||||
nsCString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
|
||||
{
|
||||
char buf[30];
|
||||
const char* fmt;
|
||||
switch (aRadix) {
|
||||
case 8:
|
||||
fmt = "%llo";
|
||||
break;
|
||||
case 10:
|
||||
fmt = "%lld";
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(aRadix == 16, "Invalid radix!");
|
||||
fmt = "%llx";
|
||||
}
|
||||
PR_snprintf(buf, sizeof(buf), fmt, aInteger);
|
||||
Append(buf);
|
||||
}
|
||||
|
||||
void
|
||||
nsString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
|
||||
{
|
||||
char buf[30];
|
||||
const char* fmt;
|
||||
switch (aRadix) {
|
||||
case 8:
|
||||
fmt = "%llo";
|
||||
break;
|
||||
case 10:
|
||||
fmt = "%lld";
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(aRadix == 16, "Invalid radix!");
|
||||
fmt = "%llx";
|
||||
}
|
||||
PR_snprintf(buf, sizeof(buf), fmt, aInteger);
|
||||
AppendASCIItoUTF16(buf, *this);
|
||||
}
|
||||
|
||||
/**
|
||||
* nsTString::AppendFloat
|
||||
*/
|
||||
|
||||
void
|
||||
nsCString::AppendFloat( float aFloat )
|
||||
{
|
||||
char buf[40];
|
||||
// Use Modified_cnvtf, which is locale-insensitive, instead of the
|
||||
// locale-sensitive PR_snprintf or sprintf(3)
|
||||
Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
|
||||
Append(buf);
|
||||
}
|
||||
|
||||
void
|
||||
nsString::AppendFloat( float aFloat )
|
||||
{
|
||||
char buf[40];
|
||||
// Use Modified_cnvtf, which is locale-insensitive, instead of the
|
||||
// locale-sensitive PR_snprintf or sprintf(3)
|
||||
Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
|
||||
AppendWithConversion(buf);
|
||||
}
|
||||
|
||||
void
|
||||
nsCString::AppendFloat( double aFloat )
|
||||
{
|
||||
char buf[40];
|
||||
// Use Modified_cnvtf, which is locale-insensitive, instead of the
|
||||
// locale-sensitive PR_snprintf or sprintf(3)
|
||||
Modified_cnvtf(buf, sizeof(buf), 15, aFloat);
|
||||
Append(buf);
|
||||
}
|
||||
|
||||
void
|
||||
nsString::AppendFloat( double aFloat )
|
||||
{
|
||||
char buf[40];
|
||||
// Use Modified_cnvtf, which is locale-insensitive, instead of the
|
||||
// locale-sensitive PR_snprintf or sprintf(3)
|
||||
Modified_cnvtf(buf, sizeof(buf), 15, aFloat);
|
||||
AppendWithConversion(buf);
|
||||
}
|
||||
|
||||
#endif // !MOZ_STRING_WITH_OBSOLETE_API
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "prdtoa.h"
|
||||
|
||||
#ifdef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
|
||||
nsTSubstring_CharT::nsTSubstring_CharT( char_type *data, size_type length,
|
||||
|
@ -742,3 +743,111 @@ void nsTSubstring_CharT::AppendPrintf( const char* format, ...)
|
|||
AppendASCII(buf, len);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/* hack to make sure we define Modified_cnvtf only once */
|
||||
#ifdef CharT_is_PRUnichar
|
||||
/**
|
||||
* This is a copy of |PR_cnvtf| with a bug fixed. (The second argument
|
||||
* of PR_dtoa is 2 rather than 1.)
|
||||
*
|
||||
* XXX(darin): if this is the right thing, then why wasn't it fixed in NSPR?!?
|
||||
*/
|
||||
static void
|
||||
Modified_cnvtf(char *buf, int bufsz, int prcsn, double fval)
|
||||
{
|
||||
PRIntn decpt, sign, numdigits;
|
||||
char *num, *nump;
|
||||
char *bufp = buf;
|
||||
char *endnum;
|
||||
|
||||
/* If anything fails, we store an empty string in 'buf' */
|
||||
num = (char*)malloc(bufsz);
|
||||
if (num == NULL) {
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
|
||||
== PR_FAILURE) {
|
||||
buf[0] = '\0';
|
||||
goto done;
|
||||
}
|
||||
numdigits = endnum - num;
|
||||
nump = num;
|
||||
|
||||
/*
|
||||
* The NSPR code had a fancy way of checking that we weren't dealing
|
||||
* with -0.0 or -NaN, but I'll just use < instead.
|
||||
* XXX Should we check !isnan(fval) as well? Is it portable? We
|
||||
* probably don't need to bother since NAN isn't portable.
|
||||
*/
|
||||
if (sign && fval < 0.0f) {
|
||||
*bufp++ = '-';
|
||||
}
|
||||
|
||||
if (decpt == 9999) {
|
||||
while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
|
||||
*bufp++ = *nump++;
|
||||
if (numdigits != 1) {
|
||||
*bufp++ = '.';
|
||||
}
|
||||
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
*bufp++ = 'e';
|
||||
PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
|
||||
}
|
||||
else if (decpt >= 0) {
|
||||
if (decpt == 0) {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
else {
|
||||
while (decpt--) {
|
||||
if (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
else {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*nump != '\0') {
|
||||
*bufp++ = '.';
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
}
|
||||
*bufp++ = '\0';
|
||||
}
|
||||
else if (decpt < 0) {
|
||||
*bufp++ = '0';
|
||||
*bufp++ = '.';
|
||||
while (decpt++) {
|
||||
*bufp++ = '0';
|
||||
}
|
||||
|
||||
while (*nump != '\0') {
|
||||
*bufp++ = *nump++;
|
||||
}
|
||||
*bufp++ = '\0';
|
||||
}
|
||||
done:
|
||||
free(num);
|
||||
}
|
||||
#endif /* CharT_is_PRUnichar */
|
||||
|
||||
void
|
||||
nsTSubstring_CharT::DoAppendFloat( double aFloat, int digits )
|
||||
{
|
||||
char buf[40];
|
||||
// Use Modified_cnvtf, which is locale-insensitive, instead of the
|
||||
// locale-sensitive PR_snprintf or sprintf(3)
|
||||
Modified_cnvtf(buf, sizeof(buf), digits, aFloat);
|
||||
AppendASCII(buf);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче