diff --git a/CLOBBER b/CLOBBER
index bae4fc725937..052f81594103 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Clobber to work around bug 959928 / bug 1020776.
+Clobber for bug 1022262.
diff --git a/addon-sdk/source/lib/sdk/indexed-db.js b/addon-sdk/source/lib/sdk/indexed-db.js
index 73a4e820b1fc..3440c114e5d7 100644
--- a/addon-sdk/source/lib/sdk/indexed-db.js
+++ b/addon-sdk/source/lib/sdk/indexed-db.js
@@ -27,18 +27,6 @@ let sanitizeId = function(id){
const PSEUDOURI = "indexeddb://" + sanitizeId(id) // https://bugzilla.mozilla.org/show_bug.cgi?id=779197
-// Firefox 26 and earlier releases don't support `indexedDB` in sandboxes
-// automatically, so we need to inject `indexedDB` to `this` scope ourselves.
-if (typeof(indexedDB) === "undefined") {
- Cc["@mozilla.org/dom/indexeddb/manager;1"].
- getService(Ci.nsIIndexedDatabaseManager).
- initWindowless(this);
-
- // Firefox 14 gets this with a prefix
- if (typeof(indexedDB) === "undefined")
- this.indexedDB = mozIndexedDB;
-}
-
// Use XPCOM because `require("./url").URL` doesn't expose the raw uri object.
let principaluri = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
@@ -50,8 +38,9 @@ let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
exports.indexedDB = Object.freeze({
open: indexedDB.openForPrincipal.bind(indexedDB, principal),
+ openForPrincipal: indexedDB.openForPrincipal.bind(indexedDB),
deleteDatabase: indexedDB.deleteForPrincipal.bind(indexedDB, principal),
- cmp: indexedDB.cmp
+ cmp: indexedDB.cmp.bind(indexedDB)
});
exports.IDBKeyRange = IDBKeyRange;
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index d34fc7120430..01beb7513f24 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 7654fedea0a6..b798c759a24d 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index fd95e8c2b62e..2cc3a25e538a 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index d34fc7120430..01beb7513f24 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 0c53fb79b52b..2feb6e0c7592 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 480fe75fca59..5a21d3524463 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "d25f3c113e3543c8f15143a858f8e9d880dfc071",
+ "revision": "371393ff791d599fe41e90ed64e17d2055605966",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 634ac83dfc17..39b0af2fe08a 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 81b4688febed..2727bef1b231 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 469ee86bfbd8..c09c5bff3b80 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index fb670fc4217d..70082c489621 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
index 17d433ccdf1d..754aa097c55c 100644
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -188,7 +188,6 @@
#endif
@BINPATH@/components/dom_notification.xpt
@BINPATH@/components/dom_html.xpt
-@BINPATH@/components/dom_indexeddb.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_payment.xpt
@BINPATH@/components/dom_json.xpt
diff --git a/browser/devtools/app-manager/app-projects.js b/browser/devtools/app-manager/app-projects.js
index 23c1a3cadbfc..f1466c8f1419 100644
--- a/browser/devtools/app-manager/app-projects.js
+++ b/browser/devtools/app-manager/app-projects.js
@@ -5,6 +5,7 @@ const promise = require("devtools/toolkit/deprecated-sync-thenables");
const {EventEmitter} = Cu.import("resource://gre/modules/devtools/event-emitter.js");
const {generateUUID} = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
+const { indexedDB } = require("sdk/indexed-db");
/**
* IndexedDB wrapper that just save project objects
@@ -20,10 +21,6 @@ const IDB = {
open: function () {
let deferred = promise.defer();
- var idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"]
- .getService(Ci.nsIIndexedDatabaseManager);
- idbManager.initWindowless(global);
-
let request = global.indexedDB.open("AppProjects", 5);
request.onerror = function(event) {
deferred.reject("Unable to open AppProjects indexedDB. " +
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index eb282c779cdf..913d27bf1696 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -202,7 +202,6 @@
@BINPATH@/components/dom_network.xpt
@BINPATH@/components/dom_notification.xpt
@BINPATH@/components/dom_html.xpt
-@BINPATH@/components/dom_indexeddb.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_json.xpt
@BINPATH@/components/dom_power.xpt
diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h
index 7c1ddf2f64ce..e3354c66d76a 100644
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1945,8 +1945,8 @@ GK_ATOM(onratechange, "onratechange")
GK_ATOM(ondurationchange, "ondurationchange")
GK_ATOM(onvolumechange, "onvolumechange")
GK_ATOM(onaddtrack, "onaddtrack")
+GK_ATOM(oncontrollerchange, "oncontrollerchange")
GK_ATOM(oncuechange, "oncuechange")
-GK_ATOM(oncurrentchange, "oncurrentchange")
GK_ATOM(onenter, "onenter")
GK_ATOM(onexit, "onexit")
GK_ATOM(onneedkey, "onneedkey")
diff --git a/content/svg/content/src/SVGMatrix.cpp b/content/svg/content/src/SVGMatrix.cpp
index 4a3c6337cbe0..0a43cbe61dc2 100644
--- a/content/svg/content/src/SVGMatrix.cpp
+++ b/content/svg/content/src/SVGMatrix.cpp
@@ -40,7 +40,7 @@ SVGMatrix::SetA(float aA, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.xx = aA;
+ mx._11 = aA;
SetMatrix(mx);
}
@@ -53,7 +53,7 @@ SVGMatrix::SetB(float aB, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.yx = aB;
+ mx._12 = aB;
SetMatrix(mx);
}
@@ -66,7 +66,7 @@ SVGMatrix::SetC(float aC, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.xy = aC;
+ mx._21 = aC;
SetMatrix(mx);
}
@@ -79,7 +79,7 @@ SVGMatrix::SetD(float aD, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.yy = aD;
+ mx._22 = aD;
SetMatrix(mx);
}
@@ -92,7 +92,7 @@ SVGMatrix::SetE(float aE, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.x0 = aE;
+ mx._31 = aE;
SetMatrix(mx);
}
@@ -105,7 +105,7 @@ SVGMatrix::SetF(float aF, ErrorResult& rv)
}
gfxMatrix mx = GetMatrix();
- mx.y0 = aF;
+ mx._32 = aF;
SetMatrix(mx);
}
@@ -176,7 +176,7 @@ SVGMatrix::FlipX()
{
const gfxMatrix& mx = GetMatrix();
nsRefPtr matrix =
- new SVGMatrix(gfxMatrix(-mx.xx, -mx.yx, mx.xy, mx.yy, mx.x0, mx.y0));
+ new SVGMatrix(gfxMatrix(-mx._11, -mx._12, mx._21, mx._22, mx._31, mx._32));
return matrix.forget();
}
@@ -185,7 +185,7 @@ SVGMatrix::FlipY()
{
const gfxMatrix& mx = GetMatrix();
nsRefPtr matrix =
- new SVGMatrix(gfxMatrix(mx.xx, mx.yx, -mx.xy, -mx.yy, mx.x0, mx.y0));
+ new SVGMatrix(gfxMatrix(mx._11, mx._12, -mx._21, -mx._22, mx._31, mx._32));
return matrix.forget();
}
@@ -199,9 +199,9 @@ SVGMatrix::SkewX(float angle, ErrorResult& rv)
}
const gfxMatrix& mx = GetMatrix();
- gfxMatrix skewMx(mx.xx, mx.yx,
- (float) (mx.xy + mx.xx*ta), (float) (mx.yy + mx.yx*ta),
- mx.x0, mx.y0);
+ gfxMatrix skewMx(mx._11, mx._12,
+ (float) (mx._21 + mx._11*ta), (float) (mx._22 + mx._12*ta),
+ mx._31, mx._32);
nsRefPtr matrix = new SVGMatrix(skewMx);
return matrix.forget();
}
@@ -216,9 +216,9 @@ SVGMatrix::SkewY(float angle, ErrorResult& rv)
}
const gfxMatrix& mx = GetMatrix();
- gfxMatrix skewMx((float) (mx.xx + mx.xy*ta), (float) (mx.yx + mx.yy*ta),
- mx.xy, mx.yy,
- mx.x0, mx.y0);
+ gfxMatrix skewMx((float) (mx._11 + mx._21*ta), (float) (mx._12 + mx._22*ta),
+ mx._21, mx._22,
+ mx._31, mx._32);
nsRefPtr matrix = new SVGMatrix(skewMx);
return matrix.forget();
diff --git a/content/svg/content/src/SVGMatrix.h b/content/svg/content/src/SVGMatrix.h
index 567ca29d87dd..794b4e189ae9 100644
--- a/content/svg/content/src/SVGMatrix.h
+++ b/content/svg/content/src/SVGMatrix.h
@@ -83,17 +83,17 @@ public:
SVGTransform* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
- float A() const { return static_cast(GetMatrix().xx); }
+ float A() const { return static_cast(GetMatrix()._11); }
void SetA(float aA, ErrorResult& rv);
- float B() const { return static_cast(GetMatrix().yx); }
+ float B() const { return static_cast(GetMatrix()._12); }
void SetB(float aB, ErrorResult& rv);
- float C() const { return static_cast(GetMatrix().xy); }
+ float C() const { return static_cast(GetMatrix()._21); }
void SetC(float aC, ErrorResult& rv);
- float D() const { return static_cast(GetMatrix().yy); }
+ float D() const { return static_cast(GetMatrix()._22); }
void SetD(float aD, ErrorResult& rv);
- float E() const { return static_cast(GetMatrix().x0); }
+ float E() const { return static_cast(GetMatrix()._31); }
void SetE(float aE, ErrorResult& rv);
- float F() const { return static_cast(GetMatrix().y0); }
+ float F() const { return static_cast(GetMatrix()._32); }
void SetF(float aF, ErrorResult& rv);
already_AddRefed Multiply(SVGMatrix& aMatrix);
already_AddRefed Inverse(ErrorResult& aRv);
diff --git a/content/svg/content/src/SVGTransform.cpp b/content/svg/content/src/SVGTransform.cpp
index 9b251aab282c..e9893be78b38 100644
--- a/content/svg/content/src/SVGTransform.cpp
+++ b/content/svg/content/src/SVGTransform.cpp
@@ -206,7 +206,7 @@ SVGTransform::SetTranslate(float tx, float ty, ErrorResult& rv)
}
if (Transform().Type() == SVG_TRANSFORM_TRANSLATE &&
- Matrixgfx().x0 == tx && Matrixgfx().y0 == ty) {
+ Matrixgfx()._31 == tx && Matrixgfx()._32 == ty) {
return;
}
@@ -223,7 +223,7 @@ SVGTransform::SetScale(float sx, float sy, ErrorResult& rv)
}
if (Transform().Type() == SVG_TRANSFORM_SCALE &&
- Matrixgfx().xx == sx && Matrixgfx().yy == sy) {
+ Matrixgfx()._11 == sx && Matrixgfx()._22 == sy) {
return;
}
AutoChangeTransformNotifier notifier(this);
diff --git a/content/svg/content/src/nsSVGTransform.cpp b/content/svg/content/src/nsSVGTransform.cpp
index 8d68e6327f7d..3de17621f229 100644
--- a/content/svg/content/src/nsSVGTransform.cpp
+++ b/content/svg/content/src/nsSVGTransform.cpp
@@ -23,14 +23,14 @@ nsSVGTransform::GetValueAsString(nsAString& aValue) const
switch (mType) {
case SVG_TRANSFORM_TRANSLATE:
// The spec say that if Y is not provided, it is assumed to be zero.
- if (mMatrix.y0 != 0)
+ if (mMatrix._32 != 0)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
MOZ_UTF16("translate(%g, %g)"),
- mMatrix.x0, mMatrix.y0);
+ mMatrix._31, mMatrix._32);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
MOZ_UTF16("translate(%g)"),
- mMatrix.x0);
+ mMatrix._31);
break;
case SVG_TRANSFORM_ROTATE:
if (mOriginX != 0.0f || mOriginY != 0.0f)
@@ -42,12 +42,12 @@ nsSVGTransform::GetValueAsString(nsAString& aValue) const
MOZ_UTF16("rotate(%g)"), mAngle);
break;
case SVG_TRANSFORM_SCALE:
- if (mMatrix.xx != mMatrix.yy)
+ if (mMatrix._11 != mMatrix._22)
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- MOZ_UTF16("scale(%g, %g)"), mMatrix.xx, mMatrix.yy);
+ MOZ_UTF16("scale(%g, %g)"), mMatrix._11, mMatrix._22);
else
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- MOZ_UTF16("scale(%g)"), mMatrix.xx);
+ MOZ_UTF16("scale(%g)"), mMatrix._11);
break;
case SVG_TRANSFORM_SKEWX:
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
@@ -60,9 +60,9 @@ nsSVGTransform::GetValueAsString(nsAString& aValue) const
case SVG_TRANSFORM_MATRIX:
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
MOZ_UTF16("matrix(%g, %g, %g, %g, %g, %g)"),
- mMatrix.xx, mMatrix.yx,
- mMatrix.xy, mMatrix.yy,
- mMatrix.x0, mMatrix.y0);
+ mMatrix._11, mMatrix._12,
+ mMatrix._21, mMatrix._22,
+ mMatrix._31, mMatrix._32);
break;
default:
buf[0] = '\0';
@@ -90,8 +90,8 @@ nsSVGTransform::SetTranslate(float aTx, float aTy)
{
mType = SVG_TRANSFORM_TRANSLATE;
mMatrix.Reset();
- mMatrix.x0 = aTx;
- mMatrix.y0 = aTy;
+ mMatrix._31 = aTx;
+ mMatrix._32 = aTy;
mAngle = 0.f;
mOriginX = 0.f;
mOriginY = 0.f;
@@ -102,8 +102,8 @@ nsSVGTransform::SetScale(float aSx, float aSy)
{
mType = SVG_TRANSFORM_SCALE;
mMatrix.Reset();
- mMatrix.xx = aSx;
- mMatrix.yy = aSy;
+ mMatrix._11 = aSx;
+ mMatrix._22 = aSy;
mAngle = 0.f;
mOriginX = 0.f;
mOriginY = 0.f;
@@ -130,7 +130,7 @@ nsSVGTransform::SetSkewX(float aAngle)
mType = SVG_TRANSFORM_SKEWX;
mMatrix.Reset();
- mMatrix.xy = ta;
+ mMatrix._21 = ta;
mAngle = aAngle;
mOriginX = 0.f;
mOriginY = 0.f;
@@ -145,7 +145,7 @@ nsSVGTransform::SetSkewY(float aAngle)
mType = SVG_TRANSFORM_SKEWY;
mMatrix.Reset();
- mMatrix.yx = ta;
+ mMatrix._12 = ta;
mAngle = aAngle;
mOriginX = 0.f;
mOriginY = 0.f;
@@ -167,24 +167,24 @@ SVGTransformSMILData::SVGTransformSMILData(const nsSVGTransform& aTransform)
switch (mTransformType) {
case SVG_TRANSFORM_MATRIX: {
const gfxMatrix& mx = aTransform.GetMatrix();
- mParams[0] = static_cast(mx.xx);
- mParams[1] = static_cast(mx.yx);
- mParams[2] = static_cast(mx.xy);
- mParams[3] = static_cast(mx.yy);
- mParams[4] = static_cast(mx.x0);
- mParams[5] = static_cast(mx.y0);
+ mParams[0] = static_cast(mx._11);
+ mParams[1] = static_cast(mx._12);
+ mParams[2] = static_cast(mx._21);
+ mParams[3] = static_cast(mx._22);
+ mParams[4] = static_cast(mx._31);
+ mParams[5] = static_cast(mx._32);
break;
}
case SVG_TRANSFORM_TRANSLATE: {
const gfxMatrix& mx = aTransform.GetMatrix();
- mParams[0] = static_cast(mx.x0);
- mParams[1] = static_cast(mx.y0);
+ mParams[0] = static_cast(mx._31);
+ mParams[1] = static_cast(mx._32);
break;
}
case SVG_TRANSFORM_SCALE: {
const gfxMatrix& mx = aTransform.GetMatrix();
- mParams[0] = static_cast(mx.xx);
- mParams[1] = static_cast(mx.yy);
+ mParams[0] = static_cast(mx._11);
+ mParams[1] = static_cast(mx._22);
break;
}
case SVG_TRANSFORM_ROTATE:
diff --git a/content/svg/content/src/nsSVGTransform.h b/content/svg/content/src/nsSVGTransform.h
index b27b514c2f44..3116aad1ed71 100644
--- a/content/svg/content/src/nsSVGTransform.h
+++ b/content/svg/content/src/nsSVGTransform.h
@@ -75,12 +75,12 @@ public:
static bool MatricesEqual(const gfxMatrix& a, const gfxMatrix& b)
{
- return a.xx == b.xx &&
- a.yx == b.yx &&
- a.xy == b.xy &&
- a.yy == b.yy &&
- a.x0 == b.x0 &&
- a.y0 == b.y0;
+ return a._11 == b._11 &&
+ a._12 == b._12 &&
+ a._21 == b._21 &&
+ a._22 == b._22 &&
+ a._31 == b._31 &&
+ a._32 == b._32;
}
protected:
diff --git a/dom/bluetooth2/BluetoothService.cpp b/dom/bluetooth2/BluetoothService.cpp
index 799786e6b761..e1576db439d6 100644
--- a/dom/bluetooth2/BluetoothService.cpp
+++ b/dom/bluetooth2/BluetoothService.cpp
@@ -167,7 +167,7 @@ BluetoothService::ToggleBtAck::Run()
return NS_OK;
}
-class BluetoothService::StartupTask : public nsISettingsServiceCallback
+class BluetoothService::StartupTask MOZ_FINAL : public nsISettingsServiceCallback
{
public:
NS_DECL_ISUPPORTS
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
index e1d3b79c41f3..c952908efa01 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -67,6 +67,8 @@ static nsTArray > sUnbondingRunnableArray;
// Atomic static variables
static Atomic sAdapterDiscoverable(false);
+static Atomic sAdapterDiscovering(false);
+static Atomic sAdapterEnabled(false);
static Atomic sAdapterDiscoverableTimeout(0);
/**
@@ -303,23 +305,22 @@ AdapterStateChangeCallback(bt_state_t aStatus)
MOZ_ASSERT(!NS_IsMainThread());
BT_LOGR("BT_STATE: %d", aStatus);
+ sAdapterEnabled = (aStatus == BT_STATE_ON);
- bool isBtEnabled = (aStatus == BT_STATE_ON);
-
- if (!isBtEnabled &&
+ if (!sAdapterEnabled &&
NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
BT_WARNING("Failed to dispatch to main thread!");
return;
}
nsRefPtr runnable =
- new BluetoothService::ToggleBtAck(isBtEnabled);
+ new BluetoothService::ToggleBtAck(sAdapterEnabled);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
return;
}
- if (isBtEnabled &&
+ if (sAdapterEnabled &&
NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
BT_WARNING("Failed to dispatch to main thread!");
return;
@@ -381,13 +382,8 @@ AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties,
BT_APPEND_NAMED_VALUE(props, "Name", propertyValue);
} else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) {
bt_scan_mode_t newMode = *(bt_scan_mode_t*)p.val;
-
- if (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- propertyValue = sAdapterDiscoverable = true;
- } else {
- propertyValue = sAdapterDiscoverable = false;
- }
-
+ propertyValue = sAdapterDiscoverable =
+ (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
BT_APPEND_NAMED_VALUE(props, "Discoverable", propertyValue);
} else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
propertyValue = sAdapterDiscoverableTimeout = *(uint32_t*)p.val;
@@ -598,6 +594,8 @@ DiscoveryStateChangedCallback(bt_discovery_state_t aState)
{
MOZ_ASSERT(!NS_IsMainThread());
+ sAdapterDiscovering = (aState == BT_DISCOVERY_STARTED);
+
// Redirect to main thread to avoid racing problem
NS_DispatchToMainThread(new DiscoveryStateChangedCallbackTask());
}
@@ -714,19 +712,15 @@ BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
nsAutoString remoteBdAddress;
BdAddressTypeToString(aRemoteBdAddress, remoteBdAddress);
- if (aState == BT_BOND_STATE_BONDED &&
- sAdapterBondedAddressArray.Contains(remoteBdAddress)) {
- // See bug 940271 for more details about this case.
- return;
- }
-
- bool bonded;
- if (aState == BT_BOND_STATE_NONE) {
- bonded = false;
- sAdapterBondedAddressArray.RemoveElement(remoteBdAddress);
- } else if (aState == BT_BOND_STATE_BONDED) {
- bonded = true;
+ bool bonded = (aState == BT_BOND_STATE_BONDED);
+ if (bonded) {
+ if (sAdapterBondedAddressArray.Contains(remoteBdAddress)) {
+ // See bug 940271 for more details about this case.
+ return;
+ }
sAdapterBondedAddressArray.AppendElement(remoteBdAddress);
+ } else {
+ sAdapterBondedAddressArray.RemoveElement(remoteBdAddress);
}
// Update bonded address list to BluetoothAdapter
@@ -952,24 +946,20 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
uint32_t numAdapters = 1; // Bluedroid supports single adapter only
for (uint32_t i = 0; i < numAdapters; i++) {
- // Since Atomic<*> is not acceptable for BT_APPEND_NAMED_VALUE(),
- // create another variable to store data.
- bool discoverable = sAdapterDiscoverable;
- uint32_t discoverableTimeout = sAdapterDiscoverableTimeout;
-
BluetoothValue properties = InfallibleTArray();
- // TODO: Revise here based on new BluetoothAdapter interface
+ BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
+ "State", BluetoothValue(sAdapterEnabled));
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
"Address", sAdapterBdAddress);
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
"Name", sAdapterBdName);
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
- "Discoverable", discoverable);
+ "Discoverable",
+ BluetoothValue(sAdapterDiscoverable));
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
- "DiscoverableTimeout", discoverableTimeout);
- BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
- "Devices", sAdapterBondedAddressArray);
+ "Discovering",
+ BluetoothValue(sAdapterDiscovering));
BT_APPEND_NAMED_VALUE(adaptersProperties.get_ArrayOfBluetoothNamedValue(),
"Adapter", properties);
@@ -1274,29 +1264,16 @@ BluetoothServiceBluedroid::SetPairingConfirmationInternal(
return true;
}
-bool
-BluetoothServiceBluedroid::SetAuthorizationInternal(
- const nsAString& aDeviceAddress, bool aAllow,
- BluetoothReplyRunnable* aRunnable)
-{
- return true;
-}
-
-nsresult
-BluetoothServiceBluedroid::PrepareAdapterInternal()
-{
- return NS_OK;
-}
-
static void
NextBluetoothProfileController()
{
MOZ_ASSERT(NS_IsMainThread());
- // First, remove the task at the front which has been already done.
+ // Remove the completed task at the head
NS_ENSURE_FALSE_VOID(sControllerArray.IsEmpty());
sControllerArray.RemoveElementAt(0);
- // Re-check if the task array is empty, if it's not, the next task will begin.
+
+ // Start the next task if task array is not empty
if (!sControllerArray.IsEmpty()) {
sControllerArray[0]->StartSession();
}
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
index 1e7fb6ea14be..5430ce39c93a 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
@@ -74,13 +74,6 @@ public:
SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable);
- virtual bool
- SetAuthorizationInternal(const nsAString& aDeviceAddress, bool aAllow,
- BluetoothReplyRunnable* aRunnable);
-
- virtual nsresult
- PrepareAdapterInternal();
-
virtual void
Connect(const nsAString& aDeviceAddress,
uint32_t aCod,
diff --git a/dom/datastore/DataStoreChangeNotifier.jsm b/dom/datastore/DataStoreChangeNotifier.jsm
index 21409ec9f138..ca12fc182e3e 100644
--- a/dom/datastore/DataStoreChangeNotifier.jsm
+++ b/dom/datastore/DataStoreChangeNotifier.jsm
@@ -114,7 +114,7 @@ this.DataStoreChangeNotifier = {
this.children[i].windows.splice(pos, 1);
}
- if (this.children[i].window.length) {
+ if (this.children[i].windows.length) {
continue;
}
diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp
index 6c6dd44cc4a7..c4665992a64a 100644
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -252,17 +252,6 @@ IndexedDatabaseManager::Get()
return gDBManager;
}
-// static
-IndexedDatabaseManager*
-IndexedDatabaseManager::FactoryCreate()
-{
- // Returns a raw pointer that carries an owning reference! Lame, but the
- // singleton factory macros force this.
- IndexedDatabaseManager* mgr = GetOrCreate();
- NS_IF_ADDREF(mgr);
- return mgr;
-}
-
nsresult
IndexedDatabaseManager::Init()
{
@@ -646,36 +635,7 @@ IndexedDatabaseManager::BlockAndGetFileReferences(
NS_IMPL_ADDREF(IndexedDatabaseManager)
NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
-NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIIndexedDatabaseManager,
- nsIObserver)
-
-NS_IMETHODIMP
-IndexedDatabaseManager::InitWindowless(JS::Handle aGlobal, JSContext* aCx)
-{
- NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
-
- JS::Rooted global(aCx, aGlobal.toObjectOrNull());
- if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
- NS_WARNING("Passed object is not a global object!");
- return NS_ERROR_FAILURE;
- }
-
- bool hasIndexedDB;
- if (!JS_HasProperty(aCx, global, IDB_STR, &hasIndexedDB)) {
- return NS_ERROR_FAILURE;
- }
-
- if (hasIndexedDB) {
- NS_WARNING("Passed object already has an 'indexedDB' property!");
- return NS_ERROR_FAILURE;
- }
-
- if (!DefineIndexedDB(aCx, global)) {
- return NS_ERROR_FAILURE;
- }
-
- return NS_OK;
-}
+NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver)
NS_IMETHODIMP
IndexedDatabaseManager::Observe(nsISupports* aSubject, const char* aTopic,
diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h
index 111828e6c3df..27bad25a8749 100644
--- a/dom/indexedDB/IndexedDatabaseManager.h
+++ b/dom/indexedDB/IndexedDatabaseManager.h
@@ -9,7 +9,6 @@
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
-#include "nsIIndexedDatabaseManager.h"
#include "nsIObserver.h"
#include "js/TypeDecls.h"
@@ -19,8 +18,6 @@
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
-#define INDEXEDDB_MANAGER_CONTRACTID "@mozilla.org/dom/indexeddb/manager;1"
-
class nsPIDOMWindow;
namespace mozilla {
@@ -38,15 +35,13 @@ BEGIN_INDEXEDDB_NAMESPACE
class FileManager;
class FileManagerInfo;
-class IndexedDatabaseManager MOZ_FINAL : public nsIIndexedDatabaseManager,
- public nsIObserver
+class IndexedDatabaseManager MOZ_FINAL : public nsIObserver
{
typedef mozilla::dom::quota::OriginOrPatternString OriginOrPatternString;
typedef mozilla::dom::quota::PersistenceType PersistenceType;
public:
NS_DECL_ISUPPORTS
- NS_DECL_NSIINDEXEDDATABASEMANAGER
NS_DECL_NSIOBSERVER
// Returns a non-owning reference.
@@ -57,10 +52,6 @@ public:
static IndexedDatabaseManager*
Get();
- // Returns an owning reference! No one should call this but the factory.
- static IndexedDatabaseManager*
- FactoryCreate();
-
static bool
IsClosed();
diff --git a/dom/indexedDB/moz.build b/dom/indexedDB/moz.build
index ac32053995cd..3fac14650b2f 100644
--- a/dom/indexedDB/moz.build
+++ b/dom/indexedDB/moz.build
@@ -7,12 +7,6 @@
DIRS += ['ipc']
TEST_DIRS += ['test']
-XPIDL_SOURCES += [
- 'nsIIndexedDatabaseManager.idl',
-]
-
-XPIDL_MODULE = 'dom_indexeddb'
-
EXPORTS.mozilla.dom.indexedDB += [
'Client.h',
'DatabaseInfo.h',
diff --git a/dom/indexedDB/nsIIndexedDatabaseManager.idl b/dom/indexedDB/nsIIndexedDatabaseManager.idl
deleted file mode 100644
index ae93abc7d00f..000000000000
--- a/dom/indexedDB/nsIIndexedDatabaseManager.idl
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, builtinclass, uuid(538d1085-517e-405a-a0f0-eb575cb0b8e5)]
-interface nsIIndexedDatabaseManager : nsISupports
-{
- /**
- * Defines indexedDB and IDBKeyRange with its static functions on aGlobal.
- *
- * This method might go away some time in the future, indexedDB and
- * IDBKeyRange should now be defined in all the spots (content windows,
- * chrome windows, xpcshell, JS modules, JS components, JS sandboxes,
- * ipcshell, bootstrapped extensions and Jetpack)
- *
- * @param aGlobal
- * The global object, indexedDB and IDBKeyRange should be defined on.
- */
- [implicit_jscontext]
- void initWindowless(in jsval aGlobal);
-};
diff --git a/dom/mobileconnection/tests/marionette/manifest.ini b/dom/mobileconnection/tests/marionette/manifest.ini
index 69b419689816..63ac1d123665 100644
--- a/dom/mobileconnection/tests/marionette/manifest.ini
+++ b/dom/mobileconnection/tests/marionette/manifest.ini
@@ -28,10 +28,9 @@ qemu = true
[test_mobile_data_ipv6.js]
disabled = Bug 979137
[test_mobile_supported_network_types.js]
-[test_mobile_call_forwarding_set.js]
-disabled = Bug 861725
-[test_mobile_call_forwarding_get.js]
-disabled = Bug 861725
+[test_mobile_call_forwarding.js]
+[test_mobile_call_forwarding_set_error.js]
+[test_mobile_call_forwarding_get_error.js]
[test_mobile_voice_privacy.js]
[test_dsds_mobile_data_connection.js]
[test_mobile_clir.js]
diff --git a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding.js b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding.js
new file mode 100644
index 000000000000..b57897f39c48
--- /dev/null
+++ b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding.js
@@ -0,0 +1,105 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
+
+const TEST_DATA = [
+ {
+ action: MozMobileConnection.CALL_FORWARD_ACTION_REGISTRATION,
+ reason: MozMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY,
+ number: "0912345678",
+ timeSeconds: 5,
+ // Currently gecko only support ICC_SERVICE_CLASS_VOICE.
+ serviceClass: MozMobileConnection.ICC_SERVICE_CLASS_VOICE
+ }, {
+ action: MozMobileConnection.CALL_FORWARD_ACTION_ENABLE,
+ reason: MozMobileConnection.CALL_FORWARD_REASON_NO_REPLY,
+ number: "+886912345678",
+ timeSeconds: 20,
+ // Currently gecko only support ICC_SERVICE_CLASS_VOICE.
+ serviceClass: MozMobileConnection.ICC_SERVICE_CLASS_VOICE
+ }
+];
+
+function testSetCallForwardingOption(aOptions) {
+ log("Test setting call forwarding to " + JSON.stringify(aOptions));
+
+ let promises = [];
+
+ // Check cfstatechange event.
+ promises.push(waitForManagerEvent("cfstatechange").then(function(aEvent) {
+ is(aEvent.success, true, "check success");
+ is(aEvent.action, aOptions.action, "check action");
+ is(aEvent.reason, aOptions.reason, "check reason");
+ is(aEvent.number, aOptions.number, "check number");
+ is(aEvent.timeSeconds, aOptions.timeSeconds, "check timeSeconds");
+ is(aEvent.serviceClass, aOptions.serviceClass, "check serviceClass");
+ }));
+ // Check DOMRequest's result.
+ promises.push(setCallForwardingOption(aOptions).then(null, (aError) => {
+ ok(false, "got '" + aError.name + "' error");
+ }));
+
+ return Promise.all(promises);
+}
+
+function testGetCallForwardingOption(aReason, aExpectedResult) {
+ log("Test getting call forwarding for " + aReason);
+
+ return getCallForwardingOption(aReason)
+ .then(function resolve(aResults) {
+ is(Array.isArray(aResults), true, "results should be an array");
+
+ for (let i = 0; i < aResults.length; i++) {
+ let result = aResults[i];
+
+ // Only need to check the result containing the serviceClass that we are
+ // interesting in.
+ if (!(result.serviceClass & aExpectedResult.serviceClass)) {
+ continue;
+ }
+
+ let expectedActive =
+ aExpectedResult.action === MozMobileConnection.CALL_FORWARD_ACTION_ENABLE ||
+ aExpectedResult.action === MozMobileConnection.CALL_FORWARD_ACTION_REGISTRATION;
+ is(result.active, expectedActive, "check active");
+ is(result.reason, aExpectedResult.reason, "check reason");
+ is(result.number, aExpectedResult.number, "check number");
+ is(result.timeSeconds, aExpectedResult.timeSeconds, "check timeSeconds");
+ }
+ }, function reject(aError) {
+ ok(false, "got '" + aError.name + "' error");
+ });
+}
+
+function clearAllCallForwardingSettings() {
+ log("Clear all call forwarding settings");
+
+ let promise = Promise.resolve();
+ for (let reason = MozMobileConnection.CALL_FORWARD_REASON_UNCONDITIONAL;
+ reason <= MozMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING;
+ reason++) {
+ let options = {
+ reason: reason,
+ action: MozMobileConnection.CALL_FORWARD_ACTION_ERASURE
+ };
+ promise =
+ promise.then(() => setCallForwardingOption(options).then(null, () => {}));
+ }
+ return promise;
+}
+
+// Start tests
+startTestCommon(function() {
+ let promise = Promise.resolve();
+ for (let i = 0; i < TEST_DATA.length; i++) {
+ let data = TEST_DATA[i];
+ promise = promise.then(() => testSetCallForwardingOption(data))
+ .then(() => testGetCallForwardingOption(data.reason, data));
+ }
+ // reset call forwarding settings.
+ return promise.then(null, () => {})
+ .then(() => clearAllCallForwardingSettings());
+});
+
diff --git a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get.js b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get.js
deleted file mode 100644
index 67c49b613e05..000000000000
--- a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 60000;
-MARIONETTE_HEAD_JS = "head.js";
-
-const TEST_DATA = [
- // Test get calling forwarding.
- // TODO: Bug 861725 - B2G Emulator: support call forwarding
- // Currently emulator doesn't support REQUEST_QUERY_CALL_FORWARD_STATUS, so
- // we expect to get a 'RequestNotSupported' error here.
- {
- reason: MozMobileConnection.CALL_FORWARD_REASON_UNCONDITIONAL,
- expectedErrorMsg: "RequestNotSupported"
- }, {
- reason: MozMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY,
- expectedErrorMsg: "RequestNotSupported"
- }, {
- reason: MozMobileConnection.CALL_FORWARD_REASON_NO_REPLY,
- expectedErrorMsg: "RequestNotSupported"
- }, {
- reason: MozMobileConnection.CALL_FORWARD_REASON_NOT_REACHABLE,
- expectedErrorMsg: "RequestNotSupported"
- }, {
- reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CALL_FORWARDING,
- expectedErrorMsg: "RequestNotSupported"
- }, {
- reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING,
- expectedErrorMsg: "RequestNotSupported"
- },
- // Test passing invalid reason
- {
- reason: 10 /* Invalid reason */,
- expectedErrorMsg: "InvalidParameter"
- }
-];
-
-function testGetCallForwardingOption(aReason, aExpectedErrorMsg) {
- log("Test getting call forwarding for " + aReason);
-
- return getCallForwardingOption(aReason)
- .then(function resolve() {
- ok(!aExpectedErrorMsg, "getCallForwardingOption success");
- }, function reject(aError) {
- is(aError.name, aExpectedErrorMsg, "failed to getCallForwardingOption");
- });
-}
-
-// Start tests
-startTestCommon(function() {
- let promise = Promise.resolve();
- for (let i = 0; i < TEST_DATA.length; i++) {
- let data = TEST_DATA[i];
- promise = promise.then(() => testGetCallForwardingOption(data.reason,
- data.expectedErrorMsg));
- }
- return promise;
-});
diff --git a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get_error.js b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get_error.js
new file mode 100644
index 000000000000..445cc22ee759
--- /dev/null
+++ b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_get_error.js
@@ -0,0 +1,45 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
+
+const TEST_DATA = [
+ // Currently emulator doesn't support CALL_FORWARD_REASON_ALL_CALL_FORWARDING
+ // and CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING, so
+ // we expect to get a 'GenericFailure' error here.
+ {
+ reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CALL_FORWARDING,
+ errorMsg: "GenericFailure"
+ }, {
+ reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING,
+ errorMsg: "GenericFailure"
+ },
+ // Test passing invalid reason
+ {
+ reason: 10 /* Invalid reason */,
+ errorMsg: "InvalidParameter"
+ }
+];
+
+function testGetCallForwardingOptionError(aReason, aErrorMsg) {
+ log("Test getting call forwarding for " + aReason);
+
+ return getCallForwardingOption(aReason)
+ .then(function resolve() {
+ ok(false, "getCallForwardingOption success");
+ }, function reject(aError) {
+ is(aError.name, aErrorMsg, "failed to getCallForwardingOption");
+ });
+}
+
+// Start tests
+startTestCommon(function() {
+ let promise = Promise.resolve();
+ for (let i = 0; i < TEST_DATA.length; i++) {
+ let data = TEST_DATA[i];
+ promise = promise.then(() => testGetCallForwardingOptionError(data.reason,
+ data.errorMsg));
+ }
+ return promise;
+});
diff --git a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set.js b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set_error.js
similarity index 67%
rename from dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set.js
rename to dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set_error.js
index d62808e4572e..76690083b84e 100644
--- a/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set.js
+++ b/dom/mobileconnection/tests/marionette/test_mobile_call_forwarding_set_error.js
@@ -7,22 +7,21 @@ MARIONETTE_HEAD_JS = "head.js";
const TEST_NUMBER = "0912345678";
const TEST_TIME_SECONDS = 5;
const TEST_DATA = [
- // Test get calling forwarding.
- // TODO: Bug 861725 - B2G Emulator: support call forwarding
- // Currently emulator doesn't support REQUEST_QUERY_CALL_FORWARD_STATUS, so
- // we expect to get a 'RequestNotSupported' error here.
+ // Currently emulator doesn't support CALL_FORWARD_REASON_ALL_CALL_FORWARDING
+ // and CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING, so
+ // we expect to get a 'GenericFailure' error here.
{
options: {
action: MozMobileConnection.CALL_FORWARD_ACTION_DISABLE,
- reason: MozMobileConnection.CALL_FORWARD_REASON_UNCONDITIONAL,
+ reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CALL_FORWARDING,
},
- expectedErrorMsg: "RequestNotSupported"
+ errorMsg: "GenericFailure"
}, {
options: {
action: MozMobileConnection.CALL_FORWARD_ACTION_ENABLE,
- reason: MozMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY,
+ reason: MozMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING,
},
- expectedErrorMsg: "RequestNotSupported"
+ errorMsg: "GenericFailure"
},
// Test passing invalid action. We expect to get a 'InvalidParameter' error.
{
@@ -31,13 +30,13 @@ const TEST_DATA = [
action: MozMobileConnection.CALL_FORWARD_ACTION_QUERY_STATUS,
reason: MozMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY,
},
- expectedErrorMsg: "InvalidParameter"
+ errorMsg: "InvalidParameter"
}, {
options: {
action: 10 /* Invalid action */,
reason: MozMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY,
},
- expectedErrorMsg: "InvalidParameter"
+ errorMsg: "InvalidParameter"
},
// Test passing invalid reason. We expect to get a 'InvalidParameter' error.
{
@@ -45,11 +44,11 @@ const TEST_DATA = [
action: MozMobileConnection.CALL_FORWARD_ACTION_DISABLE,
reason: 10 /*Invalid reason*/,
},
- expectedErrorMsg: "InvalidParameter"
+ errorMsg: "InvalidParameter"
}
];
-function testSetCallForwardingOption(aOptions, aExpectedErrorMsg) {
+function testSetCallForwardingOption(aOptions, aErrorMsg) {
log("Test setting call forwarding to " + JSON.stringify(aOptions));
aOptions.number = TEST_NUMBER;
@@ -57,9 +56,9 @@ function testSetCallForwardingOption(aOptions, aExpectedErrorMsg) {
return setCallForwardingOption(aOptions)
.then(function resolve() {
- ok(!aExpectedErrorMsg, "setCallForwardingOption success");
+ ok(false, "setCallForwardingOption success");
}, function reject(aError) {
- is(aError.name, aExpectedErrorMsg, "failed to setCallForwardingOption");
+ is(aError.name, aErrorMsg, "failed to setCallForwardingOption");
});
}
@@ -69,7 +68,7 @@ startTestCommon(function() {
for (let i = 0; i < TEST_DATA.length; i++) {
let data = TEST_DATA[i];
promise = promise.then(() => testSetCallForwardingOption(data.options,
- data.expectedErrorMsg));
+ data.errorMsg));
}
return promise;
});
diff --git a/dom/nfc/tests/marionette/head.js b/dom/nfc/tests/marionette/head.js
index 167281bdd85f..f8fdfa9a4a91 100644
--- a/dom/nfc/tests/marionette/head.js
+++ b/dom/nfc/tests/marionette/head.js
@@ -22,6 +22,7 @@ let emulator = (function() {
};
function run(cmd, callback) {
+ log("Executing emulator command '" + cmd + "'");
pendingCmdCount++;
originalRunEmulatorCmd(cmd, function(result) {
pendingCmdCount--;
@@ -29,10 +30,66 @@ let emulator = (function() {
callback(result);
}
});
- }
+ };
+
+ function activateRE(re) {
+ let deferred = Promise.defer();
+ let cmd = 'nfc nci rf_intf_activated_ntf ' + re;
+
+ this.run(cmd, function(result) {
+ is(result.pop(), 'OK', 'check activation of RE' + re);
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+ };
+
+ function notifyDiscoverRE(re, type) {
+ let deferred = Promise.defer();
+ let cmd = 'nfc nci rf_discover_ntf ' + re + ' ' + type;
+
+ this.run(cmd, function(result) {
+ is(result.pop(), 'OK', 'check discovery of RE' + re);
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+ };
+
+ function setTagData(re, flag, tnf, type, payload) {
+ let deferred = Promise.defer();
+ let cmd = "nfc tag set " + re +
+ " [" + flag + "," + tnf + "," + type + "," + payload + ",]";
+
+ this.run(cmd, function(result) {
+ is(result.pop(), "OK", "set NDEF data of tag" + re);
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+ };
+
+ function snepPutNdef(dsap, ssap, flags, tnf, type, payload, id) {
+ let deferred = Promise.defer();
+ let cmd = "nfc snep put " + dsap + " " + ssap + " [" + flags + "," +
+ tnf + "," +
+ type + "," +
+ payload + "," +
+ id + "]";
+ this.run(cmd, function(result) {
+ is(result.pop(), "OK", "send SNEP PUT");
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+ };
return {
- run: run
+ run: run,
+ activateRE: activateRE,
+ notifyDiscoverRE: notifyDiscoverRE,
+ setTagData: setTagData,
+ snepPutNdef: snepPutNdef
};
}());
diff --git a/dom/nfc/tests/marionette/manifest.ini b/dom/nfc/tests/marionette/manifest.ini
index 8e82500883dc..351bb0b8b66e 100644
--- a/dom/nfc/tests/marionette/manifest.ini
+++ b/dom/nfc/tests/marionette/manifest.ini
@@ -6,6 +6,7 @@ qemu=true
[test_ndef.js]
[test_nfc_enabled.js]
[test_nfc_manager_tech_discovered.js]
+[test_nfc_manager_tech_discovered_ndef.js]
[test_nfc_peer.js]
[test_nfc_peer_sendndef.js]
[test_nfc_tag.js]
diff --git a/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered.js b/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered.js
index 995feddc677e..ace07aeba762 100644
--- a/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered.js
+++ b/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered.js
@@ -16,36 +16,12 @@ function handleTechnologyDiscoveredRE0(msg) {
toggleNFC(false).then(runNextTest);
}
-function activateRE(re) {
- let deferred = Promise.defer();
- let cmd = 'nfc nci rf_intf_activated_ntf ' + re;
-
- emulator.run(cmd, function(result) {
- is(result.pop(), 'OK', 'check activation of RE' + re);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
-function notifyDiscoverRE(re, type) {
- let deferred = Promise.defer();
- let cmd = 'nfc nci rf_discover_ntf ' + re + ' ' + type;
-
- emulator.run(cmd, function(result) {
- is(result.pop(), 'OK', 'check discover of RE' + re);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
function testActivateRE0() {
log('Running \'testActivateRE0\'');
window.navigator.mozSetMessageHandler(
'nfc-manager-tech-discovered', handleTechnologyDiscoveredRE0);
- toggleNFC(true).then(() => activateRE(0));
+ toggleNFC(true).then(() => emulator.activateRE(0));
}
// Check NCI Spec 5.2, this will change NCI state from
@@ -56,9 +32,9 @@ function testRfDiscover() {
'nfc-manager-tech-discovered', handleTechnologyDiscoveredRE0);
toggleNFC(true)
- .then(() => notifyDiscoverRE(0, NCI_MORE_NOTIFICATIONS))
- .then(() => notifyDiscoverRE(1, NCI_LAST_NOTIFICATION))
- .then(() => activateRE(0));
+ .then(() => emulator.notifyDiscoverRE(0, NCI_MORE_NOTIFICATIONS))
+ .then(() => emulator.notifyDiscoverRE(1, NCI_LAST_NOTIFICATION))
+ .then(() => emulator.activateRE(0));
}
let tests = [
diff --git a/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered_ndef.js b/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered_ndef.js
new file mode 100644
index 000000000000..4e26f949b1c2
--- /dev/null
+++ b/dom/nfc/tests/marionette/test_nfc_manager_tech_discovered_ndef.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 30000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+let tnf = NDEF.TNF_WELL_KNOWN;
+let type = "U";
+let payload = "https://www.example.com";
+let id = "";
+
+let ndef = null;
+
+// See nfc-nci.h.
+const NCI_LAST_NOTIFICATION = 0;
+const NCI_LIMIT_NOTIFICATION = 1;
+const NCI_MORE_NOTIFICATIONS = 2;
+
+function handleTechnologyDiscoveredRE0(msg) {
+ log("Received 'nfc-manager-tech-discovered'");
+ is(msg.type, "techDiscovered", "check for correct message type");
+ is(msg.techList[0], "P2P", "check for correct tech type");
+
+ if (msg.records) {
+ isnot(msg.techList.indexOf("NDEF"), -1, "check for correct tech type");
+ // validate received NDEF message against reference
+ let ndef = [new MozNDEFRecord(tnf,
+ new Uint8Array(NfcUtils.fromUTF8(type)),
+ new Uint8Array(NfcUtils.fromUTF8(id)),
+ new Uint8Array(NfcUtils.fromUTF8(payload)))];
+ NDEF.compare(ndef, msg.records);
+ toggleNFC(false).then(runNextTest);
+ }
+}
+
+function testReceiveNDEF() {
+ log("Running 'testReceiveNDEF'");
+ window.navigator.mozSetMessageHandler(
+ "nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0);
+ toggleNFC(true)
+ .then(() => emulator.activateRE(0))
+ .then(() => emulator.snepPutNdef(4, 4, 0, tnf, btoa(type),
+ btoa(payload), btoa(id)));
+}
+
+let tests = [
+ testReceiveNDEF
+];
+
+SpecialPowers.pushPermissions(
+ [{'type': 'nfc', 'allow': true,
+ 'read': true, 'write': true, context: document},
+ {'type': 'nfc-manager', 'allow': true, context: document}], runTests);
diff --git a/dom/nfc/tests/marionette/test_nfc_tag.js b/dom/nfc/tests/marionette/test_nfc_tag.js
index f38727fee301..653d18a6af08 100644
--- a/dom/nfc/tests/marionette/test_nfc_tag.js
+++ b/dom/nfc/tests/marionette/test_nfc_tag.js
@@ -10,32 +10,6 @@ let url = "http://www.mozilla.org";
const T1T_RE_INDEX = 2;
const T2T_RE_INDEX = 3;
-function activateRE(re) {
- let deferred = Promise.defer();
- let cmd = "nfc nci rf_intf_activated_ntf " + re;
-
- emulator.run(cmd, function(result) {
- is(result.pop(), "OK", "check activation of RE" + re);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
-function setTagData(re, flag, tnf, type, payload) {
- let deferred = Promise.defer();
- let cmd = "nfc tag set " + re +
- " [" + flag + "," + tnf + "," + type + "," + payload + ",]";
-
- log("Executing \'" + cmd + "\'");
- emulator.run(cmd, function(result) {
- is(result.pop(), "OK", "set NDEF data of tag" + re);
- deferred.resolve();
- });
-
- return deferred.promise;
-}
-
function testUrlTagDiscover(re) {
log("Running \'testUrlTagDiscover\'");
// TODO : Make flag value readable.
diff --git a/dom/promise/PromiseCallback.cpp b/dom/promise/PromiseCallback.cpp
index 6fb36e57367c..896278c60c2a 100644
--- a/dom/promise/PromiseCallback.cpp
+++ b/dom/promise/PromiseCallback.cpp
@@ -30,12 +30,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
PromiseCallback::PromiseCallback()
{
- MOZ_COUNT_CTOR(PromiseCallback);
}
PromiseCallback::~PromiseCallback()
{
- MOZ_COUNT_DTOR(PromiseCallback);
}
// ResolvePromiseCallback
@@ -71,13 +69,11 @@ ResolvePromiseCallback::ResolvePromiseCallback(Promise* aPromise,
{
MOZ_ASSERT(aPromise);
MOZ_ASSERT(aGlobal);
- MOZ_COUNT_CTOR(ResolvePromiseCallback);
HoldJSObjects(this);
}
ResolvePromiseCallback::~ResolvePromiseCallback()
{
- MOZ_COUNT_DTOR(ResolvePromiseCallback);
DropJSObjects(this);
}
@@ -131,13 +127,11 @@ RejectPromiseCallback::RejectPromiseCallback(Promise* aPromise,
{
MOZ_ASSERT(aPromise);
MOZ_ASSERT(mGlobal);
- MOZ_COUNT_CTOR(RejectPromiseCallback);
HoldJSObjects(this);
}
RejectPromiseCallback::~RejectPromiseCallback()
{
- MOZ_COUNT_DTOR(RejectPromiseCallback);
DropJSObjects(this);
}
@@ -194,13 +188,11 @@ WrapperPromiseCallback::WrapperPromiseCallback(Promise* aNextPromise,
{
MOZ_ASSERT(aNextPromise);
MOZ_ASSERT(aGlobal);
- MOZ_COUNT_CTOR(WrapperPromiseCallback);
HoldJSObjects(this);
}
WrapperPromiseCallback::~WrapperPromiseCallback()
{
- MOZ_COUNT_DTOR(WrapperPromiseCallback);
DropJSObjects(this);
}
@@ -325,12 +317,10 @@ NativePromiseCallback::NativePromiseCallback(PromiseNativeHandler* aHandler,
, mState(aState)
{
MOZ_ASSERT(aHandler);
- MOZ_COUNT_CTOR(NativePromiseCallback);
}
NativePromiseCallback::~NativePromiseCallback()
{
- MOZ_COUNT_DTOR(NativePromiseCallback);
}
void
diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp
index 5acac21c7e7a..b0e5d7d10a4f 100644
--- a/dom/system/gonk/AutoMounter.cpp
+++ b/dom/system/gonk/AutoMounter.cpp
@@ -177,17 +177,10 @@ public:
VolumeManager::RegisterStateObserver(&mVolumeManagerStateObserver);
Volume::RegisterObserver(&mVolumeEventObserver);
- VolumeManager::VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
- VolumeManager::VolumeArray::index_type i;
- for (i = 0; i < numVolumes; i++) {
- RefPtr vol = VolumeManager::GetVolume(i);
- if (vol) {
- vol->RegisterObserver(&mVolumeEventObserver);
- // We need to pick up the intial value of the
- // ums.volume.NAME.enabled setting.
- AutoMounterSetting::CheckVolumeSettings(vol->Name());
- }
- }
+ // It's possible that the VolumeManager is already in the READY state,
+ // so we call CheckVolumeSettings here to cover that case. Otherwise,
+ // we'll pick it up when the VolumeManage state changes to VOLUMES_READY.
+ CheckVolumeSettings();
DBG("Calling UpdateState from constructor");
UpdateState();
@@ -207,6 +200,35 @@ public:
VolumeManager::UnregisterStateObserver(&mVolumeManagerStateObserver);
}
+ void CheckVolumeSettings()
+ {
+ if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
+ DBG("CheckVolumeSettings: VolumeManager is NOT READY yet");
+ return;
+ }
+ DBG("CheckVolumeSettings: VolumeManager is READY");
+
+ // The VolumeManager knows about all of the volumes from vold. We now
+ // know the names of all of the volumes, so we can find out what the
+ // initial sharing settings are set to.
+
+ VolumeManager::VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
+ VolumeManager::VolumeArray::index_type i;
+ for (i = 0; i < numVolumes; i++) {
+ RefPtr vol = VolumeManager::GetVolume(i);
+ if (vol) {
+ vol->RegisterObserver(&mVolumeEventObserver);
+ // We need to pick up the intial value of the
+ // ums.volume.NAME.enabled setting.
+ AutoMounterSetting::CheckVolumeSettings(vol->Name());
+
+ // Note: eventually CheckVolumeSettings will call
+ // AutoMounter::SetSharingMode, which will in turn call
+ // UpdateState if needed.
+ }
+ }
+ }
+
void UpdateState();
const char* ModeStr(int32_t aMode)
@@ -262,7 +284,7 @@ public:
vol->SetUnmountRequested(false);
vol->SetMountRequested(false);
vol->SetSharingEnabled(aAllowSharing);
- DBG("Calling UpdateState due to volume %s shareing set to %d",
+ DBG("Calling UpdateState due to volume %s sharing set to %d",
vol->NameStr(), (int)aAllowSharing);
UpdateState();
}
@@ -336,6 +358,13 @@ AutoVolumeManagerStateObserver::Notify(const VolumeManager::StateChangedEvent &)
if (!sAutoMounter) {
return;
}
+
+ // In the event that the VolumeManager just entered the VOLUMES_READY state,
+ // we call CheckVolumeSettings here (it's possible that this method never
+ // gets called if the VolumeManager was already in the VOLUMES_READY state
+ // by the time the AutoMounter was constructed).
+ sAutoMounter->CheckVolumeSettings();
+
DBG("Calling UpdateState due to VolumeManagerStateObserver");
sAutoMounter->UpdateState();
}
diff --git a/dom/tests/mochitest/chrome/test_sandbox_bindings.xul b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul
index 04989e99b68e..4ee779245342 100644
--- a/dom/tests/mochitest/chrome/test_sandbox_bindings.xul
+++ b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul
@@ -21,6 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
+ readonly attribute Promise ready;
+
+ // Promise?>
[Throws]
Promise getAll();
+ // Promise
[Throws]
Promise register(DOMString url, optional RegistrationOptionList options);
+ // Promise
[Throws]
Promise unregister(DOMString? scope);
- // Promise
- [Throws]
- Promise whenReady();
-
attribute EventHandler onupdatefound;
- attribute EventHandler oncurrentchange;
+ attribute EventHandler oncontrollerchange;
attribute EventHandler onreloadpage;
attribute EventHandler onerror;
};
@@ -46,5 +49,5 @@ partial interface ServiceWorkerContainer {
};
dictionary RegistrationOptionList {
- DOMString scope = "*";
+ DOMString scope = "/*";
};
diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js
index 528e2b054834..ab7acda27115 100644
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -1547,7 +1547,7 @@ function getNetworkKey(network)
if (key_mgmt == "WPA-PSK") {
encryption = "WPA-PSK";
- } else if (key_mgmt == "WPA-EAP") {
+ } else if (key_mgmt.indexOf("WPA-EAP") != -1) {
encryption = "WPA-EAP";
} else if (key_mgmt == "NONE" && auth_alg === "OPEN SHARED") {
encryption = "WEP";
@@ -1850,7 +1850,7 @@ function WifiWorker() {
netToDOM = function(net) {
var ssid = dequote(net.ssid);
var security = (net.key_mgmt === "NONE" && net.wep_key0) ? ["WEP"] :
- (net.key_mgmt && net.key_mgmt !== "NONE") ? [net.key_mgmt] :
+ (net.key_mgmt && net.key_mgmt !== "NONE") ? [net.key_mgmt.split(" ")[0]] :
[];
var password;
if (("psk" in net && net.psk) ||
@@ -1900,6 +1900,8 @@ function WifiWorker() {
if (net.keyManagement === "WEP") {
wep = true;
net.keyManagement = "NONE";
+ } else if (net.keyManagement === "WPA-EAP") {
+ net.keyManagement += " IEEE8021X";
}
configured.key_mgmt = net.key_mgmt = net.keyManagement; // WPA2-PSK, WPA-PSK, etc.
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index c65784f63b04..a693d515ffec 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2100,9 +2100,6 @@ RuntimeService::CreateServiceWorker(const GlobalObject& aGlobal,
nsRefPtr serviceWorker =
new ServiceWorker(window, sharedWorker);
- // While it hasn't been parsed, the intention is to only expose ServiceWorkers
- // to content after it has indeed been parsed.
- serviceWorker->mState = ServiceWorkerState::Parsed;
serviceWorker->mURL = aScriptURL;
serviceWorker->mScope = NS_ConvertUTF8toUTF16(aScope);
diff --git a/dom/workers/ServiceWorkerContainer.cpp b/dom/workers/ServiceWorkerContainer.cpp
index 064b49eec09d..e81989650221 100644
--- a/dom/workers/ServiceWorkerContainer.cpp
+++ b/dom/workers/ServiceWorkerContainer.cpp
@@ -97,7 +97,14 @@ ServiceWorkerContainer::GetWaiting()
}
already_AddRefed
-ServiceWorkerContainer::GetCurrent()
+ServiceWorkerContainer::GetActive()
+{
+ // FIXME(nsm): Bug 1002570
+ return nullptr;
+}
+
+already_AddRefed
+ServiceWorkerContainer::GetController()
{
// FIXME(nsm): Bug 1002570
return nullptr;
@@ -112,11 +119,12 @@ ServiceWorkerContainer::GetAll(ErrorResult& aRv)
}
already_AddRefed
-ServiceWorkerContainer::WhenReady(ErrorResult& aRv)
+ServiceWorkerContainer::Ready()
{
- // FIXME(nsm): Bug 984048
- aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return nullptr;
+ // FIXME(nsm): Bug 1025077
+ nsCOMPtr global = do_QueryInterface(mWindow);
+ nsRefPtr promise = new Promise(global);
+ return promise.forget();
}
// Testing only.
diff --git a/dom/workers/ServiceWorkerContainer.h b/dom/workers/ServiceWorkerContainer.h
index 62cf01ee3554..875c55df1651 100644
--- a/dom/workers/ServiceWorkerContainer.h
+++ b/dom/workers/ServiceWorkerContainer.h
@@ -29,7 +29,7 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
IMPL_EVENT_HANDLER(updatefound)
- IMPL_EVENT_HANDLER(currentchange)
+ IMPL_EVENT_HANDLER(controllerchange)
IMPL_EVENT_HANDLER(reloadpage)
IMPL_EVENT_HANDLER(error)
@@ -64,13 +64,16 @@ public:
GetWaiting();
already_AddRefed
- GetCurrent();
+ GetActive();
+
+ already_AddRefed
+ GetController();
already_AddRefed
GetAll(ErrorResult& aRv);
already_AddRefed
- WhenReady(ErrorResult& aRv);
+ Ready();
// Testing only.
already_AddRefed
diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp
index 4857100d17db..36c74a812ff3 100644
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -227,7 +227,7 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow, const nsAString& aScope,
}
nsCString cleanedScope;
- rv = scopeURI->GetSpec(cleanedScope);
+ rv = scopeURI->GetSpecIgnoringRef(cleanedScope);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
diff --git a/dom/workers/test/serviceworkers/test_navigator.html b/dom/workers/test/serviceworkers/test_navigator.html
index b11732b56bff..2b3ad7ed87e5 100644
--- a/dom/workers/test/serviceworkers/test_navigator.html
+++ b/dom/workers/test/serviceworkers/test_navigator.html
@@ -20,10 +20,11 @@
ok(typeof navigator.serviceWorker.register === "function", "navigator.serviceWorker.register() should be a function.");
ok(typeof navigator.serviceWorker.unregister === "function", "navigator.serviceWorker.unregister() should be a function.");
ok(typeof navigator.serviceWorker.getAll === "function", "navigator.serviceWorker.getAll() should be a function.");
- ok(typeof navigator.serviceWorker.whenReady === "function", "navigator.serviceWorker.whenReady() should be a function.");
- ok(navigator.serviceWorker.installing === null, "There should be no installing worker for an uncontrolled document.");
- ok(navigator.serviceWorker.waiting === null, "There should be no waiting worker for an uncontrolled document.");
- ok(navigator.serviceWorker.current === null, "There should be no current worker for an uncontrolled document.");
+ ok(navigator.serviceWorker.ready instanceof Promise, "navigator.serviceWorker.ready should be a Promise.");
+ ok(navigator.serviceWorker.installing === null, "There should be no installing worker for an uncontrolled scope.");
+ ok(navigator.serviceWorker.waiting === null, "There should be no waiting worker for an uncontrolled scope.");
+ ok(navigator.serviceWorker.active === null, "There should be no active worker for an uncontrolled scope.");
+ ok(navigator.serviceWorker.controller === null, "There should be no active worker for an uncontrolled document.");
}
SimpleTest.waitForExplicitFinish();
diff --git a/extensions/spellcheck/hunspell/src/README b/extensions/spellcheck/hunspell/src/README
new file mode 100644
index 000000000000..8289413f3d08
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/README
@@ -0,0 +1,182 @@
+About Hunspell
+--------------
+
+Hunspell is a spell checker and morphological analyzer library and program
+designed for languages with rich morphology and complex word compounding or
+character encoding. Hunspell interfaces: Ispell-like terminal interface
+using Curses library, Ispell pipe interface, OpenOffice.org UNO module.
+
+Hunspell's code base comes from the OpenOffice.org MySpell
+(http://lingucomponent.openoffice.org/MySpell-3.zip). See README.MYSPELL,
+AUTHORS.MYSPELL and license.myspell files.
+Hunspell is designed to eventually replace Myspell in OpenOffice.org.
+
+Main features of Hunspell spell checker and morphological analyzer:
+
+- Unicode support (affix rules work only with the first 65535 Unicode characters)
+
+- Morphological analysis (in custom item and arrangement style) and stemming
+
+- Max. 65535 affix classes and twofold affix stripping (for agglutinative
+ languages, like Azeri, Basque, Estonian, Finnish, Hungarian, Turkish, etc.)
+
+- Support complex compoundings (for example, Hungarian and German)
+
+- Support language specific features (for example, special casing of
+ Azeri and Turkish dotted i, or German sharp s)
+
+- Handle conditional affixes, circumfixes, fogemorphemes,
+ forbidden words, pseudoroots and homonyms.
+
+- Free software (LGPL, GPL, MPL tri-license)
+
+Compiling on Unix/Linux
+-----------------------
+
+./configure
+make
+make install
+
+For dictionary development, use the --with-warnings option of configure.
+
+For interactive user interface of Hunspell executable, use the --with-ui option.
+
+The developer packages you need to compile Hunspell's interface:
+
+glibc-devel
+
+optional developer packages:
+
+ncurses (need for --with-ui), eg. libncursesw5 for UTF-8
+readline (for fancy input line editing,
+ configure parameter: --with-readline)
+locale and gettext (but you can also use the
+ --with-included-gettext configure parameter)
+
+Hunspell distribution uses new Autoconf (2.59) and Automake (1.9).
+
+Compiling on Windows
+--------------------
+
+1. Compiling with Windows SDK
+
+Download the free Windows SDK of Microsoft, open a command prompt
+window and cd into hunspell/src/win_api. Use the following command
+to compile hunspell:
+
+vcbuild
+
+2. Compiling in Cygwin environment
+
+Download and install Cygwin environment for Windows with the following
+extra packages:
+
+make
+gcc-g++ development package
+mingw development package (for cygwin.dll free native Windows compilation)
+ncurses, readline (for user interface)
+iconv (character conversion)
+
+2.1. Cygwin1.dll dependent compiling
+
+Open a Cygwin shell, cd into the hunspell root directory:
+
+./configure
+make
+make install
+
+For dictionary development, use the --with-warnings option of configure.
+
+For interactive user interface of Hunspell executable, use the --with-ui option.
+
+readline configure parameter: --with-readline (for fancy input line editing)
+
+1.2. Cygwin1.dll free compiling
+
+Open a Cygwin shell, cd into the hunspell/src/win_api and
+
+make -f Makefile.cygwin
+
+Testing
+-------
+
+Testing Hunspell (see tests in tests/ subdirectory):
+
+make check
+
+or with Valgrind debugger:
+
+make check
+VALGRIND=[Valgrind_tool] make check
+
+For example:
+
+make check
+VALGRIND=memcheck make check
+
+Documentation
+-------------
+
+features and dictionary format:
+man 5 hunspell
+
+man hunspell
+hunspell -h
+http://hunspell.sourceforge.net
+
+Usage
+-----
+
+The src/tools dictionary contains ten executables after compiling
+(or some of them are in the src/win_api):
+
+affixcompress: dictionary generation from large (millions of words) vocabularies
+ analyze: example of spell checking, stemming and morphological analysis
+ chmorph: example of automatic morphological generation and conversion
+ example: example of spell checking and suggestion
+ hunspell: main program for spell checking and others (see manual)
+ hunzip: decompressor of hzip format
+ hzip: compressor of hzip format
+makealias: alias compression (Hunspell only, not back compatible with MySpell)
+ munch: dictionary generation from vocabularies (it needs an affix file, too).
+ unmunch: list all recognized words of a MySpell dictionary
+wordforms: word generation (Hunspell version of unmunch)
+
+After compiling and installing (see INSTALL) you can
+run the Hunspell spell checker (compiled with user interface)
+with a Hunspell or Myspell dictionary:
+
+hunspell -d en_US text.txt
+
+or without interface:
+
+hunspell
+hunspell -d en_UK -l
+
+Linking with Hunspell static library:
+g++ -lhunspell example.cxx
+
+Dictionaries
+------------
+
+Myspell & Hunspell dictionaries:
+http://extensions.libreoffice.org
+http://cgit.freedesktop.org/libreoffice/dictionaries
+http://extensions.openoffice.org
+http://wiki.services.openoffice.org/wiki/Dictionaries
+
+Aspell dictionaries (need some conversion):
+ftp://ftp.gnu.org/gnu/aspell/dict
+Conversion steps: see relevant feature request at http://hunspell.sf.net.
+
+László Németh
+nemeth at numbertext org
diff --git a/extensions/spellcheck/hunspell/src/README.hunspell b/extensions/spellcheck/hunspell/src/README.hunspell
deleted file mode 100644
index a1f38f62973a..000000000000
--- a/extensions/spellcheck/hunspell/src/README.hunspell
+++ /dev/null
@@ -1,61 +0,0 @@
-******* BEGIN LICENSE BLOCK *******
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
-* and László Németh (Hunspell). Portions created by the Initial Developers
-* are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
-*
-* Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
-* David Einstein (deinst@world.std.com)
-* László Németh (nemethl@gyorsposta.hu)
-* Ryan VanderMeulen (ryanvm@gmail.com)
-* Caolan McNamara (caolanm@redhat.com)
-*
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-******* END LICENSE BLOCK *******
-
-Hunspell Version: 1.3.2
-Additional Patches: 694002, 710967, 710940, 784776
-
-Hunspell Author: László Németh
-MySpell Author: Kevin Hendricks & David Einstein
-
-Hunspell is a spell checker and morphological analyser library. Hunspell
-is based on OpenOffice.org's Myspell. Documentation, tests, and examples
-are available at http://hunspell.sourceforge.net.
-
-A special thanks and credit goes to Geoff Kuenning, the creator of Ispell.
-MySpell's affix algorithms were based on those of Ispell, which should be
-noted is copyright Geoff Kuenning et al and now available under a BSD-style
-license. For more information on Ispell and affix compression in general,
-please see: http://lasr.cs.ucla.edu/geoff/ispell.html (Ispell homepage)
-
-An almost complete rewrite of MySpell for use by the Mozilla project was
-developed by David Einstein. David was a significant help in improving MySpell.
-
-Special thanks also goes to László Németh, who is the author of the Hungarian
-dictionary and who developed and contributed the code to support compound words
-in MySpell and fixed numerous problems with the encoding case conversion tables
-along with rewriting MySpell as Hunspell and ensuring compatibility with the
-Mozilla codebase.
diff --git a/extensions/spellcheck/hunspell/src/README.mozilla b/extensions/spellcheck/hunspell/src/README.mozilla
new file mode 100644
index 000000000000..09700ea7581d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/README.mozilla
@@ -0,0 +1,2 @@
+Hunspell Version: 1.3.3
+Additional Patches: See patches directory.
diff --git a/extensions/spellcheck/hunspell/src/affentry.cpp b/extensions/spellcheck/hunspell/src/affentry.cxx
similarity index 87%
rename from extensions/spellcheck/hunspell/src/affentry.cpp
rename to extensions/spellcheck/hunspell/src/affentry.cxx
index 13247560cae3..ab92bb7fc127 100644
--- a/extensions/spellcheck/hunspell/src/affentry.cpp
+++ b/extensions/spellcheck/hunspell/src/affentry.cxx
@@ -1,59 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
@@ -63,13 +9,17 @@
#include "affentry.hxx"
#include "csutil.hxx"
+#define MAXTEMPWORDLEN (MAXWORDUTF8LEN + 4)
+
PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp)
+ // register affix manager
+ : pmyMgr(pmgr)
+ , next(NULL)
+ , nexteq(NULL)
+ , nextne(NULL)
+ , flgnxt(NULL)
{
- // register affix manager
- pmyMgr = pmgr;
-
// set up its initial values
-
aflag = dp->aflag; // flag
strip = dp->strip; // string to strip
appnd = dp->appnd; // string to append
@@ -82,9 +32,6 @@ PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp)
memcpy(c.conds, dp->c.l.conds1, MAXCONDLEN_1);
c.l.conds2 = dp->c.l.conds2;
} else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
- next = NULL;
- nextne = NULL;
- nexteq = NULL;
morphcode = dp->morphcode;
contclass = dp->contclass;
contclasslen = dp->contclasslen;
@@ -107,16 +54,17 @@ PfxEntry::~PfxEntry()
// add prefix to this word assuming conditions hold
char * PfxEntry::add(const char * word, int len)
{
- char tword[MAXWORDUTF8LEN + 4];
+ char tword[MAXTEMPWORDLEN];
if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) &&
(len >= numconds) && test_condition(word) &&
(!stripl || (strncmp(word, strip, stripl) == 0)) &&
- ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
+ ((MAXTEMPWORDLEN) > (len + appndl - stripl))) {
/* we have a match so add prefix */
char * pp = tword;
if (appndl) {
- strcpy(tword,appnd);
+ strncpy(tword, appnd, MAXTEMPWORDLEN-1);
+ tword[MAXTEMPWORDLEN-1] = '\0';
pp += appndl;
}
strcpy(pp, (word + stripl));
@@ -164,13 +112,15 @@ inline int PfxEntry::test_condition(const char * st)
if (*st == '\0' && p) return 0; // word <= condition
break;
}
- case '.': if (!pos) { // dots are not metacharacters in groups: [.]
+ case '.':
+ if (!pos) { // dots are not metacharacters in groups: [.]
p = nextchar(p);
// skip the next character
for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++);
if (*st == '\0' && p) return 0; // word <= condition
break;
}
+ /* FALLTHROUGH */
default: {
if (*st == *p) {
st++;
@@ -187,11 +137,11 @@ inline int PfxEntry::test_condition(const char * st)
}
if (pos && st != pos) {
ingroup = true;
- while (p && *p != ']' && (p = nextchar(p)));
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL));
}
} else if (pos) {
ingroup = true;
- while (p && *p != ']' && (p = nextchar(p)));
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL));
}
} else if (pos) { // group
p = nextchar(p);
@@ -207,7 +157,7 @@ struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
@@ -221,7 +171,10 @@ struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
- if (stripl) strcpy (tmpword, strip);
+ if (stripl) {
+ strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
+ }
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
@@ -268,7 +221,7 @@ struct hentry * PfxEntry::check_twosfx(const char * word, int len,
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
@@ -283,7 +236,10 @@ struct hentry * PfxEntry::check_twosfx(const char * word, int len,
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
- if (stripl) strcpy (tmpword, strip);
+ if (stripl) {
+ strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
+ }
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
@@ -315,7 +271,7 @@ char * PfxEntry::check_twosfx_morph(const char * word, int len,
char in_compound, const FLAG needflag)
{
int tmpl; // length of tmpword
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
@@ -330,7 +286,10 @@ char * PfxEntry::check_twosfx_morph(const char * word, int len,
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
- if (stripl) strcpy (tmpword, strip);
+ if (stripl) {
+ strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
+ }
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
@@ -362,7 +321,7 @@ char * PfxEntry::check_morph(const char * word, int len, char in_compound, const
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
char result[MAXLNLEN];
char * st;
@@ -381,7 +340,10 @@ char * PfxEntry::check_morph(const char * word, int len, char in_compound, const
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
- if (stripl) strcpy (tmpword, strip);
+ if (stripl) {
+ strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
+ }
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
@@ -449,10 +411,15 @@ char * PfxEntry::check_morph(const char * word, int len, char in_compound, const
}
SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp)
+ : pmyMgr(pmgr) // register affix manager
+ , next(NULL)
+ , nexteq(NULL)
+ , nextne(NULL)
+ , flgnxt(NULL)
+ , l_morph(NULL)
+ , r_morph(NULL)
+ , eq_morph(NULL)
{
- // register affix manager
- pmyMgr = pmgr;
-
// set up its initial values
aflag = dp->aflag; // char flag
strip = dp->strip; // string to strip
@@ -467,9 +434,6 @@ SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp)
memcpy(c.l.conds1, dp->c.l.conds1, MAXCONDLEN_1);
c.l.conds2 = dp->c.l.conds2;
} else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
- next = NULL;
- nextne = NULL;
- nexteq = NULL;
rappnd = myrevstrdup(appnd);
morphcode = dp->morphcode;
contclass = dp->contclass;
@@ -494,15 +458,16 @@ SfxEntry::~SfxEntry()
// add suffix to this word assuming conditions hold
char * SfxEntry::add(const char * word, int len)
{
- char tword[MAXWORDUTF8LEN + 4];
+ char tword[MAXTEMPWORDLEN];
/* make sure all conditions match */
if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) &&
(len >= numconds) && test_condition(word + len, word) &&
(!stripl || (strcmp(word + len - stripl, strip) == 0)) &&
- ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
+ ((MAXTEMPWORDLEN) > (len + appndl - stripl))) {
/* we have a match so add suffix */
- strcpy(tword,word);
+ strncpy(tword, word, MAXTEMPWORDLEN-1);
+ tword[MAXTEMPWORDLEN-1] = '\0';
if (appndl) {
strcpy(tword + len - stripl, appnd);
} else {
@@ -537,24 +502,37 @@ inline int SfxEntry::test_condition(const char * st, const char * beg)
int i = 1;
while (1) {
switch (*p) {
- case '\0': return 1;
- case '[': { p = nextchar(p); pos = st; break; }
- case '^': { p = nextchar(p); neg = true; break; }
- case ']': { if (!neg && !ingroup) return 0;
- i++;
- // skip the next character
- if (!ingroup) {
- for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
- st--;
- }
- pos = NULL;
- neg = false;
- ingroup = false;
- p = nextchar(p);
- if (st < beg && p) return 0; // word <= condition
- break;
- }
- case '.': if (!pos) { // dots are not metacharacters in groups: [.]
+ case '\0':
+ return 1;
+ case '[':
+ p = nextchar(p);
+ pos = st;
+ break;
+ case '^':
+ p = nextchar(p);
+ neg = true;
+ break;
+ case ']':
+ if (!neg && !ingroup)
+ return 0;
+ i++;
+ // skip the next character
+ if (!ingroup)
+ {
+ for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
+ st--;
+ }
+ pos = NULL;
+ neg = false;
+ ingroup = false;
+ p = nextchar(p);
+ if (st < beg && p)
+ return 0; // word <= condition
+ break;
+ case '.':
+ if (!pos)
+ {
+ // dots are not metacharacters in groups: [.]
p = nextchar(p);
// skip the next character
for (st--; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
@@ -569,6 +547,7 @@ inline int SfxEntry::test_condition(const char * st, const char * beg)
}
break;
}
+ /* FALLTHROUGH */
default: {
if (*st == *p) {
p = nextchar(p);
@@ -589,7 +568,7 @@ inline int SfxEntry::test_condition(const char * st, const char * beg)
if (neg) return 0;
else if (i == numconds) return 1;
ingroup = true;
- while (p && *p != ']' && (p = nextchar(p)));
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL));
st--;
}
if (p && *p != ']') p = nextchar(p);
@@ -597,8 +576,8 @@ inline int SfxEntry::test_condition(const char * st, const char * beg)
if (neg) return 0;
else if (i == numconds) return 1;
ingroup = true;
- while (p && *p != ']' && (p = nextchar(p)))
- ;
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL))
+ ;
// if (p && *p != ']') p = nextchar(p);
st--;
}
@@ -624,7 +603,7 @@ struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
int tmpl; // length of tmpword
struct hentry * he; // hash entry pointer
unsigned char * cp;
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
PfxEntry* ep = ppfx;
// if this suffix is being cross checked with a prefix
@@ -649,7 +628,8 @@ struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
// back any characters that would have been stripped or
// or null terminating the shorter string
- strcpy (tmpword, word);
+ strncpy (tmpword, word, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
@@ -702,7 +682,10 @@ struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
} else if (wlst && (*ns < maxSug)) {
int cwrd = 1;
for (int k=0; k < *ns; k++)
- if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0;
+ if (strcmp(tmpword, wlst[k]) == 0) {
+ cwrd = 0;
+ break;
+ }
if (cwrd) {
wlst[*ns] = mystrdup(tmpword);
if (wlst[*ns] == NULL) {
@@ -725,7 +708,7 @@ struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,
int tmpl; // length of tmpword
struct hentry * he; // hash entry pointer
unsigned char * cp;
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
PfxEntry* ep = ppfx;
@@ -749,7 +732,8 @@ struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,
// back any characters that would have been stripped or
// or null terminating the shorter string
- strcpy (tmpword, word);
+ strncpy(tmpword, word, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
@@ -786,7 +770,7 @@ char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags,
{
int tmpl; // length of tmpword
unsigned char * cp;
- char tmpword[MAXWORDUTF8LEN + 4];
+ char tmpword[MAXTEMPWORDLEN];
PfxEntry* ep = ppfx;
char * st;
@@ -814,7 +798,8 @@ char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags,
// back any characters that would have been stripped or
// or null terminating the shorter string
- strcpy (tmpword, word);
+ strncpy(tmpword, word, MAXTEMPWORDLEN-1);
+ tmpword[MAXTEMPWORDLEN-1] = '\0';
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
diff --git a/extensions/spellcheck/hunspell/src/affentry.hxx b/extensions/spellcheck/hunspell/src/affentry.hxx
index d0f0c71106eb..c67c09825ca4 100644
--- a/extensions/spellcheck/hunspell/src/affentry.hxx
+++ b/extensions/spellcheck/hunspell/src/affentry.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _AFFIX_HXX_
#define _AFFIX_HXX_
@@ -68,6 +11,10 @@
class LIBHUNSPELL_DLL_EXPORTED PfxEntry : protected AffEntry
{
+private:
+ PfxEntry(const PfxEntry&);
+ PfxEntry& operator = (const PfxEntry&);
+private:
AffixMgr* pmyMgr;
PfxEntry * next;
@@ -124,6 +71,10 @@ public:
class LIBHUNSPELL_DLL_EXPORTED SfxEntry : protected AffEntry
{
+private:
+ SfxEntry(const SfxEntry&);
+ SfxEntry& operator = (const SfxEntry&);
+private:
AffixMgr* pmyMgr;
char * rappnd;
diff --git a/extensions/spellcheck/hunspell/src/affixmgr.cpp b/extensions/spellcheck/hunspell/src/affixmgr.cxx
similarity index 97%
rename from extensions/spellcheck/hunspell/src/affixmgr.cpp
rename to extensions/spellcheck/hunspell/src/affixmgr.cxx
index 3dd557f462bf..ee74ee47becf 100644
--- a/extensions/spellcheck/hunspell/src/affixmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/affixmgr.cxx
@@ -1,59 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
@@ -102,6 +48,7 @@ AffixMgr::AffixMgr(const char * affpath, HashMgr** ptr, int * md, const char * k
compoundroot = FLAG_NULL; // compound word signing flag
compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word
compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word
+ compoundmoresuffixes = 0; // allow more suffixes within compound words
checkcompounddup = 0; // forbid double words in compounds
checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution)
checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds
@@ -307,6 +254,14 @@ AffixMgr::~AffixMgr()
#endif
}
+void AffixMgr::finishFileMgr(FileMgr *afflst)
+{
+ delete afflst;
+
+ // convert affix trees to sorted list
+ process_pfx_tree_to_list();
+ process_sfx_tree_to_list();
+}
// read in aff file and build up prefix and suffix entry objects
int AffixMgr::parse_file(const char * affpath, const char * key)
@@ -333,7 +288,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
// read in each line ignoring any that do not
// start with a known line type indicator
- while ((line = afflst->getline())) {
+ while ((line = afflst->getline()) != NULL) {
mychomp(line);
/* remove byte order mark */
@@ -348,7 +303,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the keyboard string */
if (strncmp(line,"KEY",3) == 0) {
if (parse_string(line, &keystring, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -356,7 +311,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the try string */
if (strncmp(line,"TRY",3) == 0) {
if (parse_string(line, &trystring, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -364,7 +319,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the name of the character set used by the .dict and .aff */
if (strncmp(line,"SET",3) == 0) {
if (parse_string(line, &encoding, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
if (strcmp(encoding, "UTF-8") == 0) {
@@ -384,7 +339,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by the controlled compound words */
if (strncmp(line,"COMPOUNDFLAG",12) == 0) {
if (parse_flag(line, &compoundflag, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -393,12 +348,12 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
if (strncmp(line,"COMPOUNDBEGIN",13) == 0) {
if (complexprefixes) {
if (parse_flag(line, &compoundend, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
} else {
if (parse_flag(line, &compoundbegin, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -407,7 +362,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by compound words */
if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) {
if (parse_flag(line, &compoundmiddle, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -415,12 +370,12 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
if (strncmp(line,"COMPOUNDEND",11) == 0) {
if (complexprefixes) {
if (parse_flag(line, &compoundbegin, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
} else {
if (parse_flag(line, &compoundend, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -429,7 +384,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the data used by compound_check() method */
if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) {
if (parse_num(line, &cpdwordmax, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -437,7 +392,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag sign compounds in dictionary */
if (strncmp(line,"COMPOUNDROOT",12) == 0) {
if (parse_flag(line, &compoundroot, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -445,7 +400,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by compound_check() method */
if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) {
if (parse_flag(line, &compoundpermitflag, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -453,11 +408,15 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by compound_check() method */
if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) {
if (parse_flag(line, &compoundforbidflag, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
+ if (strncmp(line,"COMPOUNDMORESUFFIXES",20) == 0) {
+ compoundmoresuffixes = 1;
+ }
+
if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) {
checkcompounddup = 1;
}
@@ -480,14 +439,14 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
if (strncmp(line,"NOSUGGEST",9) == 0) {
if (parse_flag(line, &nosuggest, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
if (strncmp(line,"NONGRAMSUGGEST",14) == 0) {
if (parse_flag(line, &nongramsuggest, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -495,7 +454,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by forbidden words */
if (strncmp(line,"FORBIDDENWORD",13) == 0) {
if (parse_flag(line, &forbiddenword, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -503,7 +462,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by forbidden words */
if (strncmp(line,"LEMMA_PRESENT",13) == 0) {
if (parse_flag(line, &lemma_present, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -511,7 +470,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by circumfixes */
if (strncmp(line,"CIRCUMFIX",9) == 0) {
if (parse_flag(line, &circumfix, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -519,7 +478,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by fogemorphemes */
if (strncmp(line,"ONLYINCOMPOUND",14) == 0) {
if (parse_flag(line, &onlyincompound, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -527,7 +486,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by `needaffixs' */
if (strncmp(line,"PSEUDOROOT",10) == 0) {
if (parse_flag(line, &needaffix, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -535,7 +494,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by `needaffixs' */
if (strncmp(line,"NEEDAFFIX",9) == 0) {
if (parse_flag(line, &needaffix, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -543,7 +502,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the minimal length for words in compounds */
if (strncmp(line,"COMPOUNDMIN",11) == 0) {
if (parse_num(line, &cpdmin, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
if (cpdmin < 1) cpdmin = 1;
@@ -552,7 +511,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the max. words and syllables in compounds */
if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) {
if (parse_cpdsyllable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -560,7 +519,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by compound_check() method */
if (strncmp(line,"SYLLABLENUM",11) == 0) {
if (parse_string(line, &cpdsyllablenum, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -573,7 +532,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the extra word characters */
if (strncmp(line,"WORDCHARS",9) == 0) {
if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, utf8, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -581,7 +540,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the ignored characters (for example, Arabic optional diacretics charachters */
if (strncmp(line,"IGNORE",6) == 0) {
if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, utf8, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -589,7 +548,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the typical fault correcting table */
if (strncmp(line,"REP",3) == 0) {
if (parse_reptable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -597,7 +556,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the input conversion table */
if (strncmp(line,"ICONV",5) == 0) {
if (parse_convtable(line, afflst, &iconvtable, "ICONV")) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -605,7 +564,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the input conversion table */
if (strncmp(line,"OCONV",5) == 0) {
if (parse_convtable(line, afflst, &oconvtable, "OCONV")) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -613,7 +572,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the phonetic translation table */
if (strncmp(line,"PHONE",5) == 0) {
if (parse_phonetable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -621,7 +580,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the checkcompoundpattern table */
if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) {
if (parse_checkcpdtable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -629,7 +588,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the defcompound table */
if (strncmp(line,"COMPOUNDRULE",12) == 0) {
if (parse_defcpdtable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -637,7 +596,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the related character map table */
if (strncmp(line,"MAP",3) == 0) {
if (parse_maptable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -645,7 +604,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the word breakpoints table */
if (strncmp(line,"BREAK",5) == 0) {
if (parse_breaktable(line, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -653,7 +612,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the language for language specific codes */
if (strncmp(line,"LANG",4) == 0) {
if (parse_string(line, &lang, afflst->getlinenum())) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
langnum = get_lang_num(lang);
@@ -666,7 +625,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
if (strncmp(line,"MAXNGRAMSUGS",12) == 0) {
if (parse_num(line, &maxngramsugs, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -676,14 +635,14 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
if (strncmp(line,"MAXDIFF",7) == 0) {
if (parse_num(line, &maxdiff, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
if (strncmp(line,"MAXCPDSUGS",10) == 0) {
if (parse_num(line, &maxcpdsugs, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -703,7 +662,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by forbidden words */
if (strncmp(line,"KEEPCASE",8) == 0) {
if (parse_flag(line, &keepcase, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -711,7 +670,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by `forceucase' */
if (strncmp(line,"FORCEUCASE",10) == 0) {
if (parse_flag(line, &forceucase, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -719,7 +678,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by `warn' */
if (strncmp(line,"WARN",4) == 0) {
if (parse_flag(line, &warn, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -731,7 +690,7 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
/* parse in the flag used by the affix generator */
if (strncmp(line,"SUBSTANDARD",11) == 0) {
if (parse_flag(line, &substandard, afflst)) {
- delete afflst;
+ finishFileMgr(afflst);
return 1;
}
}
@@ -750,19 +709,14 @@ int AffixMgr::parse_file(const char * affpath, const char * key)
dupflags_ini = 0;
}
if (parse_affix(line, ft, afflst, dupflags)) {
- delete afflst;
- process_pfx_tree_to_list();
- process_sfx_tree_to_list();
+ finishFileMgr(afflst);
return 1;
}
}
-
}
- delete afflst;
- // convert affix trees to sorted list
- process_pfx_tree_to_list();
- process_sfx_tree_to_list();
+ finishFileMgr(afflst);
+ // affix trees are sorted now
// now we can speed up performance greatly taking advantage of the
// relationship between the affixes and the idea of "subsets".
@@ -1373,7 +1327,7 @@ int AffixMgr::cpdrep_check(const char * word, int wl)
}
// forbid compoundings when there are special patterns at word bound
-int AffixMgr::cpdpat_check(const char * word, int pos, hentry * r1, hentry * r2, const char affixed)
+int AffixMgr::cpdpat_check(const char * word, int pos, hentry * r1, hentry * r2, const char /*affixed*/)
{
int len;
for (int i = 0; i < numcheckcpd; i++) {
@@ -1386,7 +1340,7 @@ int AffixMgr::cpdpat_check(const char * word, int pos, hentry * r1, hentry * r2,
// zero pattern (0/flag) => unmodified stem (zero affixes allowed)
(!*(checkcpdtable[i].pattern) || (
(*(checkcpdtable[i].pattern)=='0' && r1->blen <= pos && strncmp(word + pos - r1->blen, r1->word, r1->blen) == 0) ||
- (*(checkcpdtable[i].pattern)!='0' && (len = strlen(checkcpdtable[i].pattern)) &&
+ (*(checkcpdtable[i].pattern)!='0' && ((len = strlen(checkcpdtable[i].pattern)) != 0) &&
strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)))) {
return 1;
}
@@ -1447,7 +1401,10 @@ int AffixMgr::defcpd_check(hentry *** words, short wnum, hentry * rv, hentry **
for (i = 0; i < numdefcpd; i++) {
for (j = 0; j < defcpdtable[i].len; j++) {
if (defcpdtable[i].def[j] != '*' && defcpdtable[i].def[j] != '?' &&
- TESTAFF(rv->astr, defcpdtable[i].def[j], rv->alen)) ok = 1;
+ TESTAFF(rv->astr, defcpdtable[i].def[j], rv->alen)) {
+ ok = 1;
+ break;
+ }
}
}
if (ok == 0) {
@@ -1598,7 +1555,7 @@ struct hentry * AffixMgr::compound_check(const char * word, int len,
int oldlen = 0;
int checkedstriple = 0;
int onlycpdrule;
- int affixed = 0;
+ char affixed = 0;
hentry ** oldwords = words;
int checked_prefix;
@@ -1680,8 +1637,9 @@ struct hentry * AffixMgr::compound_check(const char * word, int len,
if (onlycpdrule) break;
if (compoundflag &&
!(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
- if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
- FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
+ if (((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
+ FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundflag)))) && !hu_mov_rule &&
sfx->getCont() &&
((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag,
sfx->getContLen())) || (compoundend &&
@@ -1694,9 +1652,11 @@ struct hentry * AffixMgr::compound_check(const char * word, int len,
if (rv ||
(((wordnum == 0) && compoundbegin &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundbegin))) || // twofold suffixes + compound
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
((wordnum > 0) && compoundmiddle &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundmiddle))) || // twofold suffixes + compound
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
) checked_prefix = 1;
// else check forbiddenwords and needaffix
@@ -2099,7 +2059,7 @@ int AffixMgr::compound_check_morph(const char * word, int len,
int cmax;
int onlycpdrule;
- int affixed = 0;
+ char affixed = 0;
hentry ** oldwords = words;
setcminmax(&cmin, &cmax, word, len);
@@ -2169,11 +2129,12 @@ int AffixMgr::compound_check_morph(const char * word, int len,
}
if (!rv) {
- if (onlycpdrule) break;
+ if (onlycpdrule && strlen(*result) > MAXLNLEN/10) break;
if (compoundflag &&
!(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
- if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
- FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
+ if (((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
+ FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundflag)))) && !hu_mov_rule &&
sfx->getCont() &&
((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag,
sfx->getContLen())) || (compoundend &&
@@ -2186,9 +2147,11 @@ int AffixMgr::compound_check_morph(const char * word, int len,
if (rv ||
(((wordnum == 0) && compoundbegin &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundbegin))) || // twofold suffix+compound
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
((wordnum > 0) && compoundmiddle &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+ (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundmiddle))) || // twofold suffix+compound
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
) {
// char * p = prefix_check_morph(st, i, 0, compound);
@@ -3608,7 +3571,7 @@ int AffixMgr::parse_reptable(char * line, FileMgr * af)
/* now parse the numrep lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numrep; j++) {
- if (!(nl = af->getline())) return 1;
+ if ((nl = af->getline()) == NULL) return 1;
mychomp(nl);
tp = nl;
i = 0;
@@ -4312,7 +4275,7 @@ int AffixMgr::parse_affix(char * line, const char at, FileMgr * af, char * dupf
std::vector::iterator start = affentries.begin();
std::vector::iterator end = affentries.end();
for (std::vector::iterator entry = start; entry != end; ++entry) {
- if (!(nl = af->getline())) return 1;
+ if ((nl = af->getline()) == NULL) return 1;
mychomp(nl);
tp = nl;
i = 0;
diff --git a/extensions/spellcheck/hunspell/src/affixmgr.hxx b/extensions/spellcheck/hunspell/src/affixmgr.hxx
index 2ab64884822b..736816f04eb9 100644
--- a/extensions/spellcheck/hunspell/src/affixmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/affixmgr.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _AFFIXMGR_HXX_
#define _AFFIXMGR_HXX_
@@ -98,6 +41,7 @@ class LIBHUNSPELL_DLL_EXPORTED AffixMgr
FLAG compoundroot;
FLAG compoundforbidflag;
FLAG compoundpermitflag;
+ int compoundmoresuffixes;
int checkcompounddup;
int checkcompoundrep;
int checkcompoundcase;
@@ -301,6 +245,7 @@ private:
int process_sfx_tree_to_list();
int redundant_condition(char, char * strip, int stripl,
const char * cond, int);
+ void finishFileMgr(FileMgr *afflst);
};
#endif
diff --git a/extensions/spellcheck/hunspell/src/atypes.hxx b/extensions/spellcheck/hunspell/src/atypes.hxx
index b41e38a91dfc..61c59d5ff990 100644
--- a/extensions/spellcheck/hunspell/src/atypes.hxx
+++ b/extensions/spellcheck/hunspell/src/atypes.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _ATYPES_HXX_
#define _ATYPES_HXX_
@@ -114,7 +57,7 @@ static inline void HUNSPELL_WARNING(FILE *, const char *, ...) {}
#define FLAG_NULL 0x00
#define FREE_FLAG(a) a = 0
-#define TESTAFF( a, b , c ) flag_bsearch((unsigned short *) a, (unsigned short) b, c)
+#define TESTAFF( a, b , c ) (flag_bsearch((unsigned short *) a, (unsigned short) b, c))
struct affentry
{
diff --git a/extensions/spellcheck/hunspell/src/baseaffix.hxx b/extensions/spellcheck/hunspell/src/baseaffix.hxx
index ca0a28ac19a3..f417acaa440b 100644
--- a/extensions/spellcheck/hunspell/src/baseaffix.hxx
+++ b/extensions/spellcheck/hunspell/src/baseaffix.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _BASEAFF_HXX_
#define _BASEAFF_HXX_
@@ -62,7 +5,11 @@
class LIBHUNSPELL_DLL_EXPORTED AffEntry
{
+private:
+ AffEntry(const AffEntry&);
+ AffEntry& operator = (const AffEntry&);
protected:
+ AffEntry() {}
char * appnd;
char * strip;
unsigned char appndl;
diff --git a/extensions/spellcheck/hunspell/src/csutil.cpp b/extensions/spellcheck/hunspell/src/csutil.cxx
similarity index 97%
rename from extensions/spellcheck/hunspell/src/csutil.cpp
rename to extensions/spellcheck/hunspell/src/csutil.cxx
index f79b3db8b26a..0b8476f06a82 100644
--- a/extensions/spellcheck/hunspell/src/csutil.cpp
+++ b/extensions/spellcheck/hunspell/src/csutil.cxx
@@ -1,60 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * L. David Baron (dbaron@dbaron.org)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
@@ -72,6 +17,11 @@ struct unicode_info {
unsigned short clower;
};
+#ifdef _WIN32
+#include
+#include
+#endif
+
#ifdef OPENOFFICEORG
# include
#else
@@ -100,6 +50,21 @@ struct unicode_info2 {
static struct unicode_info2 * utf_tbl = NULL;
static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances
+FILE * myfopen(const char * path, const char * mode) {
+#ifdef _WIN32
+#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
+ if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
+ int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+ wchar_t *buff = (wchar_t *) malloc(len * sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
+ FILE * f = _wfopen(buff, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
+ free(buff);
+ return f;
+ }
+#endif
+ return fopen(path, mode);
+}
+
/* only UTF-16 (BMP) implementation */
char * u16_u8(char * dest, int size, const w_char * src, int srclen) {
signed char * u8 = (signed char *)dest;
@@ -396,7 +361,10 @@ char * line_uniq(char * text, char breakchar) {
for ( i = 1; i < linenum; i++ ) {
int dup = 0;
for (int j = 0; j < i; j++) {
- if (strcmp(lines[i], lines[j]) == 0) dup = 1;
+ if (strcmp(lines[i], lines[j]) == 0) {
+ dup = 1;
+ break;
+ }
}
if (!dup) {
if ((i > 1) || (*(lines[0]) != '\0')) {
@@ -5531,6 +5499,7 @@ struct cs_info * get_current_cs(const char * es) {
ccs[i].cupper = i;
}
+
nsCOMPtr encoder;
nsCOMPtr decoder;
@@ -5707,7 +5676,7 @@ unsigned short unicodetoupper(unsigned short c, int langnum)
if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr)))
return 0x0130;
#ifdef OPENOFFICEORG
- return u_toupper(c);
+ return static_cast(u_toupper(c));
#else
#ifdef MOZILLA_CLIENT
return ToUpperCase((char16_t) c);
@@ -5725,7 +5694,7 @@ unsigned short unicodetolower(unsigned short c, int langnum)
if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr)))
return 0x0131;
#ifdef OPENOFFICEORG
- return u_tolower(c);
+ return static_cast(u_tolower(c));
#else
#ifdef MOZILLA_CLIENT
return ToLowerCase((char16_t) c);
diff --git a/extensions/spellcheck/hunspell/src/csutil.hxx b/extensions/spellcheck/hunspell/src/csutil.hxx
index 48f26be2a146..e034b53fd277 100644
--- a/extensions/spellcheck/hunspell/src/csutil.hxx
+++ b/extensions/spellcheck/hunspell/src/csutil.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef __CSUTILHXX__
#define __CSUTILHXX__
@@ -109,6 +52,9 @@
#define FORBIDDENWORD 65510
#define ONLYUPCASEFLAG 65511
+// fopen or optional _wfopen to fix long pathname problem of WIN32
+LIBHUNSPELL_DLL_EXPORTED FILE * myfopen(const char * path, const char * mode);
+
// convert UTF-16 characters to UTF-8
LIBHUNSPELL_DLL_EXPORTED char * u16_u8(char * dest, int size, const w_char * src, int srclen);
diff --git a/extensions/spellcheck/hunspell/src/dictmgr.cpp b/extensions/spellcheck/hunspell/src/dictmgr.cxx
similarity index 69%
rename from extensions/spellcheck/hunspell/src/dictmgr.cpp
rename to extensions/spellcheck/hunspell/src/dictmgr.cxx
index a103c12f89dd..a94429e593a0 100644
--- a/extensions/spellcheck/hunspell/src/dictmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/dictmgr.cxx
@@ -1,36 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
#include
#include
@@ -38,6 +5,7 @@
#include
#include "dictmgr.hxx"
+#include "csutil.hxx"
DictMgr::DictMgr(const char * dictpath, const char * etype) : numdict(0)
{
@@ -90,7 +58,7 @@ int DictMgr::parse_file(const char * dictpath, const char * etype)
// open the dictionary list file
FILE * dictlst;
- dictlst = fopen(dictpath,"r");
+ dictlst = myfopen(dictpath,"r");
if (!dictlst) {
return 1;
}
@@ -133,7 +101,8 @@ int DictMgr::parse_file(const char * dictpath, const char * etype)
case 3:
free(pdict->region);
pdict->region=NULL;
- case 2: //deliberate fallthrough
+ /* FALLTHROUGH */
+ case 2:
free(pdict->lang);
pdict->lang=NULL;
default:
diff --git a/extensions/spellcheck/hunspell/src/dictmgr.hxx b/extensions/spellcheck/hunspell/src/dictmgr.hxx
index 5e789e177e17..692ed964c321 100644
--- a/extensions/spellcheck/hunspell/src/dictmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/dictmgr.hxx
@@ -1,37 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _DICTMGR_HXX_
#define _DICTMGR_HXX_
@@ -49,7 +15,10 @@ struct dictentry {
class LIBHUNSPELL_DLL_EXPORTED DictMgr
{
-
+private:
+ DictMgr(const DictMgr&);
+ DictMgr& operator = (const DictMgr&);
+private:
int numdict;
dictentry * pdentry;
diff --git a/extensions/spellcheck/hunspell/src/filemgr.cpp b/extensions/spellcheck/hunspell/src/filemgr.cpp
deleted file mode 100644
index 4f1097dd4135..000000000000
--- a/extensions/spellcheck/hunspell/src/filemgr.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
-#include
-#include
-#include
-
-#include "filemgr.hxx"
-
-int FileMgr::fail(const char * err, const char * par) {
- fprintf(stderr, err, par);
- return -1;
-}
-
-FileMgr::FileMgr(const char * file, const char * key) {
- linenum = 0;
- hin = NULL;
- fin = fopen(file, "r");
- if (!fin) {
- // check hzipped file
- char * st = (char *) malloc(strlen(file) + strlen(HZIP_EXTENSION) + 1);
- if (st) {
- strcpy(st, file);
- strcat(st, HZIP_EXTENSION);
- hin = new Hunzip(st, key);
- free(st);
- }
- }
- if (!fin && !hin) fail(MSG_OPEN, file);
-}
-
-FileMgr::~FileMgr()
-{
- if (fin) fclose(fin);
- if (hin) delete hin;
-}
-
-char * FileMgr::getline() {
- const char * l;
- linenum++;
- if (fin) return fgets(in, BUFSIZE - 1, fin);
- if (hin && (l = hin->getline())) return strcpy(in, l);
- linenum--;
- return NULL;
-}
-
-int FileMgr::getlinenum() {
- return linenum;
-}
diff --git a/extensions/spellcheck/hunspell/src/filemgr.cxx b/extensions/spellcheck/hunspell/src/filemgr.cxx
new file mode 100644
index 000000000000..e1fb80d9228d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/filemgr.cxx
@@ -0,0 +1,53 @@
+#include "license.hunspell"
+#include "license.myspell"
+
+#include
+#include
+#include
+
+#include "filemgr.hxx"
+#include "csutil.hxx"
+
+int FileMgr::fail(const char * err, const char * par) {
+ fprintf(stderr, err, par);
+ return -1;
+}
+
+FileMgr::FileMgr(const char * file, const char * key)
+ : hin(NULL)
+ , linenum(0)
+{
+ in[0] = '\0';
+
+ fin = myfopen(file, "r");
+ if (!fin) {
+ // check hzipped file
+ char * st = (char *) malloc(strlen(file) + strlen(HZIP_EXTENSION) + 1);
+ if (st) {
+ strcpy(st, file);
+ strcat(st, HZIP_EXTENSION);
+ hin = new Hunzip(st, key);
+ free(st);
+ }
+ }
+ if (!fin && !hin) fail(MSG_OPEN, file);
+}
+
+FileMgr::~FileMgr()
+{
+ if (fin) fclose(fin);
+ if (hin) delete hin;
+}
+
+char * FileMgr::getline() {
+ const char * l;
+ linenum++;
+ if (fin) return fgets(in, BUFSIZE - 1, fin);
+ if (hin && ((l = hin->getline()) != NULL)) return strcpy(in, l);
+ linenum--;
+ return NULL;
+}
+
+int FileMgr::getlinenum() {
+ return linenum;
+}
diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellcheck/hunspell/src/filemgr.hxx
index d15f4d986191..37b2ae9ea163 100644
--- a/extensions/spellcheck/hunspell/src/filemgr.hxx
+++ b/extensions/spellcheck/hunspell/src/filemgr.hxx
@@ -1,37 +1,4 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
+/* file manager class - read lines of files [filename] OR [filename.hz] */
#ifndef _FILEMGR_HXX_
#define _FILEMGR_HXX_
@@ -42,6 +9,9 @@
class LIBHUNSPELL_DLL_EXPORTED FileMgr
{
+private:
+ FileMgr(const FileMgr&);
+ FileMgr& operator = (const FileMgr&);
protected:
FILE * fin;
Hunzip * hin;
diff --git a/extensions/spellcheck/hunspell/src/hashmgr.cpp b/extensions/spellcheck/hunspell/src/hashmgr.cxx
similarity index 87%
rename from extensions/spellcheck/hunspell/src/hashmgr.cpp
rename to extensions/spellcheck/hunspell/src/hashmgr.cxx
index 3d10e67f20ce..12adf420d462 100644
--- a/extensions/spellcheck/hunspell/src/hashmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/hashmgr.cxx
@@ -1,64 +1,11 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
#include
#include
+#include
#include "hashmgr.hxx"
#include "csutil.hxx"
@@ -67,12 +14,19 @@
// build a hash table from a munched word list
HashMgr::HashMgr(const char * tpath, const char * apath, const char * key)
+ : tablesize(0)
+ , tableptr(NULL)
+ , userword(0)
+ , flag_mode(FLAG_CHAR)
+ , complexprefixes(0)
+ , utf8(0)
+ , forbiddenword(FORBIDDENWORD) // forbidden word signing flag
+ , numaliasf(0)
+ , aliasf(NULL)
+ , aliasflen(0)
+ , numaliasm(0)
+ , aliasm(NULL)
{
- tablesize = 0;
- tableptr = NULL;
- flag_mode = FLAG_CHAR;
- complexprefixes = 0;
- utf8 = 0;
langnum = 0;
lang = NULL;
enc = NULL;
@@ -80,11 +34,6 @@ HashMgr::HashMgr(const char * tpath, const char * apath, const char * key)
ignorechars = NULL;
ignorechars_utf16 = NULL;
ignorechars_utf16_len = 0;
- numaliasf = 0;
- aliasf = NULL;
- numaliasm = 0;
- aliasm = NULL;
- forbiddenword = FORBIDDENWORD; // forbidden word signing flag
load_config(apath, key);
int ec = load_tables(tpath, key);
if (ec) {
@@ -170,7 +119,7 @@ int HashMgr::add_word(const char * word, int wbl, int wcl, unsigned short * aff,
int al, const char * desc, bool onlyupcase)
{
bool upcasehomonym = false;
- int descl = desc ? (aliasm ? sizeof(short) : strlen(desc) + 1) : 0;
+ int descl = desc ? (aliasm ? sizeof(char *) : strlen(desc) + 1) : 0;
// variable-length hash record with word and optional fields
struct hentry* hp =
(struct hentry *) malloc (sizeof(struct hentry) + wbl + descl);
@@ -264,18 +213,21 @@ int HashMgr::add_word(const char * word, int wbl, int wcl, unsigned short * aff,
}
int HashMgr::add_hidden_capitalized_word(char * word, int wbl, int wcl,
- unsigned short * flags, int al, char * dp, int captype)
+ unsigned short * flags, int flagslen, char * dp, int captype)
{
+ if (flags == NULL)
+ flagslen = 0;
+
// add inner capitalized forms to handle the following allcap forms:
// Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
// Allcaps with suffixes: CIA's -> CIA'S
if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
- ((captype == ALLCAP) && (flags != NULL))) &&
- !((flags != NULL) && TESTAFF(flags, forbiddenword, al))) {
- unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (al+1));
+ ((captype == ALLCAP) && (flagslen != 0))) &&
+ !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
+ unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (flagslen+1));
if (!flags2) return 1;
- if (al) memcpy(flags2, flags, al * sizeof(unsigned short));
- flags2[al] = ONLYUPCASEFLAG;
+ if (flagslen) memcpy(flags2, flags, flagslen * sizeof(unsigned short));
+ flags2[flagslen] = ONLYUPCASEFLAG;
if (utf8) {
char st[BUFSIZE];
w_char w[BUFSIZE];
@@ -283,11 +235,11 @@ int HashMgr::add_hidden_capitalized_word(char * word, int wbl, int wcl,
mkallsmall_utf(w, wlen, langnum);
mkallcap_utf(w, 1, langnum);
u16_u8(st, BUFSIZE, w, wlen);
- return add_word(st,wbl,wcl,flags2,al+1,dp, true);
+ return add_word(st,wbl,wcl,flags2,flagslen+1,dp, true);
} else {
mkallsmall(word, csconv);
mkinitcap(word, csconv);
- return add_word(word,wbl,wcl,flags2,al+1,dp, true);
+ return add_word(word,wbl,wcl,flags2,flagslen+1,dp, true);
}
}
return 0;
@@ -417,8 +369,8 @@ int HashMgr::load_tables(const char * tpath, const char * key)
if (dict == NULL) return 1;
// first read the first line of file to get hash table size */
- if (!(ts = dict->getline())) {
- HUNSPELL_WARNING(stderr, "error: empty dic file\n");
+ if ((ts = dict->getline()) == NULL) {
+ HUNSPELL_WARNING(stderr, "error: empty dic file %s\n", tpath);
delete dict;
return 2;
}
@@ -431,30 +383,32 @@ int HashMgr::load_tables(const char * tpath, const char * key)
}
tablesize = atoi(ts);
- if (tablesize == 0) {
+
+ int nExtra = 5 + USERWORD;
+
+ if (tablesize <= 0 || (tablesize >= (std::numeric_limits::max() - 1 - nExtra) / int(sizeof(struct hentry *)))) {
HUNSPELL_WARNING(stderr, "error: line 1: missing or bad word count in the dic file\n");
delete dict;
return 4;
}
- tablesize = tablesize + 5 + USERWORD;
- if ((tablesize %2) == 0) tablesize++;
+ tablesize += nExtra;
+ if ((tablesize % 2) == 0) tablesize++;
// allocate the hash table
- tableptr = (struct hentry **) malloc(tablesize * sizeof(struct hentry *));
+ tableptr = (struct hentry **) calloc(tablesize, sizeof(struct hentry *));
if (! tableptr) {
delete dict;
return 3;
}
- for (int i=0; igetline())) {
+ while ((ts = dict->getline()) != NULL) {
mychomp(ts);
// split each line into word and morphological description
dp = ts;
- while ((dp = strchr(dp, ':'))) {
+ while ((dp = strchr(dp, ':')) != NULL) {
if ((dp > ts + 3) && (*(dp - 3) == ' ' || *(dp - 3) == '\t')) {
for (dp -= 4; dp >= ts && (*dp == ' ' || *dp == '\t'); dp--);
if (dp < ts) { // missing word
@@ -670,7 +624,7 @@ int HashMgr::load_config(const char * affpath, const char * key)
// read in each line ignoring any that do not
// start with a known line type indicator
- while ((line = afflst->getline())) {
+ while ((line = afflst->getline()) != NULL) {
mychomp(line);
/* remove byte order mark */
@@ -810,7 +764,7 @@ int HashMgr::parse_aliasf(char * line, FileMgr * af)
/* now parse the numaliasf lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numaliasf; j++) {
- if (!(nl = af->getline())) return 1;
+ if ((nl = af->getline()) == NULL) return 1;
mychomp(nl);
tp = nl;
i = 0;
@@ -917,7 +871,7 @@ int HashMgr::parse_aliasm(char * line, FileMgr * af)
/* now parse the numaliasm lines to read in the remainder of the table */
char * nl = line;
for (int j=0; j < numaliasm; j++) {
- if (!(nl = af->getline())) return 1;
+ if ((nl = af->getline()) == NULL) return 1;
mychomp(nl);
tp = nl;
i = 0;
diff --git a/extensions/spellcheck/hunspell/src/hashmgr.hxx b/extensions/spellcheck/hunspell/src/hashmgr.hxx
index e2429f480e87..341b08131c3b 100644
--- a/extensions/spellcheck/hunspell/src/hashmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/hashmgr.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _HASHMGR_HXX_
#define _HASHMGR_HXX_
diff --git a/extensions/spellcheck/hunspell/src/htypes.hxx b/extensions/spellcheck/hunspell/src/htypes.hxx
index d69345b3c514..5b6c90966b7d 100644
--- a/extensions/spellcheck/hunspell/src/htypes.hxx
+++ b/extensions/spellcheck/hunspell/src/htypes.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _HTYPES_HXX_
#define _HTYPES_HXX_
diff --git a/extensions/spellcheck/hunspell/src/hunspell.cpp b/extensions/spellcheck/hunspell/src/hunspell.cxx
similarity index 94%
rename from extensions/spellcheck/hunspell/src/hunspell.cpp
rename to extensions/spellcheck/hunspell/src/hunspell.cxx
index b503d17b6d22..7dbcd2f914c3 100644
--- a/extensions/spellcheck/hunspell/src/hunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/hunspell.cxx
@@ -1,59 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
@@ -66,6 +12,8 @@
#endif
#include "csutil.hxx"
+#include
+
Hunspell::Hunspell(const char * affpath, const char * dpath, const char * key)
{
encoding = NULL;
@@ -382,6 +330,10 @@ int Hunspell::spell(const char * word, int * info, char ** root)
char cw[MAXWORDUTF8LEN];
char wspace[MAXWORDUTF8LEN];
w_char unicw[MAXWORDLEN];
+
+ int info2 = 0;
+ if (!info) info = &info2; else *info = 0;
+
// Hunspell supports XML input of the simplified API (see manual)
if (strcmp(word, SPELL_XML) == 0) return 1;
int nc = strlen(word);
@@ -400,7 +352,6 @@ int Hunspell::spell(const char * word, int * info, char ** root)
if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
- int info2 = 0;
if (wl == 0 || maxdic == 0) return 1;
if (root) *root = NULL;
@@ -418,13 +369,14 @@ int Hunspell::spell(const char * word, int * info, char ** root)
} else break;
}
if ((i == wl) && (nstate == NNUM)) return 1;
- if (!info) info = &info2; else *info = 0;
switch(captype) {
case HUHCAP:
+ /* FALLTHROUGH */
case HUHINITCAP:
*info += SPELL_ORIGCAP;
- case NOCAP: {
+ /* FALLTHROUGH */
+ case NOCAP:
rv = checkword(cw, info, root);
if ((abbv) && !(rv)) {
memcpy(wspace,cw,wl);
@@ -433,7 +385,6 @@ int Hunspell::spell(const char * word, int * info, char ** root)
rv = checkword(wspace, info, root);
}
break;
- }
case ALLCAP: {
*info += SPELL_ORIGCAP;
rv = checkword(cw, info, root);
@@ -457,7 +408,7 @@ int Hunspell::spell(const char * word, int * info, char ** root)
*apostrophe = '\0';
wl2 = u8_u16(tmpword, MAXWORDLEN, cw);
*apostrophe = '\'';
- if (wl2 < nc) {
+ if (wl2 >= 0 && wl2 < nc) {
mkinitcap2(apostrophe + 1, unicw + wl2 + 1, nc - wl2 - 1);
rv = checkword(cw, info, root);
if (rv) break;
@@ -804,19 +755,28 @@ int Hunspell::suggest(char*** slst, const char * word)
char * dot = strchr(cw, '.');
if (dot && (dot > cw)) {
int captype_;
- if (utf8) {
+ if (utf8)
+ {
w_char w_[MAXWORDLEN];
int wl_ = u8_u16(w_, MAXWORDLEN, dot + 1);
captype_ = get_captype_utf8(w_, wl_, langnum);
} else captype_ = get_captype(dot+1, strlen(dot+1), csconv);
- if (captype_ == INITCAP) {
+ if (captype_ == INITCAP)
+ {
char * st = mystrdup(cw);
- if (st) st = (char *) realloc(st, wl + 2);
- if (st) {
- st[(dot - cw) + 1] = ' ';
- strcpy(st + (dot - cw) + 2, dot + 1);
- ns = insert_sug(slst, st, ns);
- free(st);
+ if (st)
+ {
+ char *newst = (char *) realloc(st, wl + 2);
+ if (newst == NULL)
+ free(st);
+ st = newst;
+ }
+ if (st)
+ {
+ st[(dot - cw) + 1] = ' ';
+ strcpy(st + (dot - cw) + 2, dot + 1);
+ ns = insert_sug(slst, st, ns);
+ free(st);
}
}
}
@@ -902,7 +862,7 @@ int Hunspell::suggest(char*** slst, const char * word)
*pos = '\0';
strcpy(w, (*slst)[j]);
strcat(w, pos + 1);
- spell(w, &info, NULL);
+ (void)spell(w, &info, NULL);
if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) {
*pos = ' ';
} else *pos = '-';
@@ -1724,6 +1684,13 @@ int Hunspell::get_langnum() const
return langnum;
}
+int Hunspell::input_conv(const char * word, char * dest)
+{
+ RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+ return (rl && rl->conv(word, dest));
+}
+
+
// return the beginning of the element (attr == NULL) or the attribute
const char * Hunspell::get_xml_pos(const char * s, const char * attr)
{
@@ -1748,11 +1715,11 @@ int Hunspell::get_xml_list(char ***slst, char * list, const char * tag) {
int n = 0;
char * p;
if (!list) return 0;
- for (p = list; (p = strstr(p, tag)); p++) n++;
+ for (p = list; ((p = strstr(p, tag)) != NULL); p++) n++;
if (n == 0) return 0;
*slst = (char **) malloc(sizeof(char *) * n);
if (!*slst) return 0;
- for (p = list, n = 0; (p = strstr(p, tag)); p++, n++) {
+ for (p = list, n = 0; ((p = strstr(p, tag)) != NULL); p++, n++) {
int l = strlen(p);
(*slst)[n] = (char *) malloc(l + 1);
if (!(*slst)[n]) return n;
@@ -1764,6 +1731,19 @@ int Hunspell::get_xml_list(char ***slst, char * list, const char * tag) {
return n;
}
+namespace
+{
+ void myrep(std::string& str, const std::string& search, const std::string& replace)
+ {
+ size_t pos = 0;
+ while ((pos = str.find(search, pos)) != std::string::npos)
+ {
+ str.replace(pos, search.length(), replace);
+ pos += replace.length();
+ }
+ }
+}
+
int Hunspell::spellml(char*** slst, const char * word)
{
char *q, *q2;
@@ -1775,26 +1755,26 @@ int Hunspell::spellml(char*** slst, const char * word)
q2 = strstr(q2, "'), MAXWORDUTF8LEN - 10)) n = analyze(slst, cw);
if (n == 0) return 0;
// convert the result to ana1ana2
format
- for (int i = 0; i < n; i++) s+= strlen((*slst)[i]);
- char * r = (char *) malloc(6 + 5 * s + 7 * n + 7 + 1); // XXX 5*s->&->&
- if (!r) return 0;
- strcpy(r, "");
+ std::string r;
+ r.append("");
for (int i = 0; i < n; i++) {
- int l = strlen(r);
- strcpy(r + l, "");
- strcpy(r + l + 3, (*slst)[i]);
- mystrrep(r + l + 3, "\t", " ");
- mystrrep(r + l + 3, "<", "<");
- mystrrep(r + l + 3, "&", "&");
- strcat(r, "");
+ r.append("");
+
+ std::string entry((*slst)[i]);
free((*slst)[i]);
+ myrep(entry, "\t", " ");
+ myrep(entry, "&", "&");
+ myrep(entry, "<", "<");
+ r.append(entry);
+
+ r.append("");
}
- strcat(r, "
");
- (*slst)[0] = r;
+ r.append("
");
+ (*slst)[0] = mystrdup(r.c_str());
return 1;
} else if (check_xml_par(q, "type=", "stem")) {
if (get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN - 1)) return stem(slst, cw);
@@ -1807,9 +1787,9 @@ int Hunspell::spellml(char*** slst, const char * word)
return generate(slst, cw, cw2);
}
} else {
- if ((q2 = strstr(q2 + 1, "'), ""))) {
+ if ((n = get_xml_list(&slst2, strchr(q2, '>'), "")) != 0) {
int n2 = generate(slst, cw, slst2, n);
freelist(&slst2, n);
return uniqlist(*slst, n2);
diff --git a/extensions/spellcheck/hunspell/src/hunspell.h b/extensions/spellcheck/hunspell/src/hunspell.h
index 85e8805047be..627968a3da8f 100644
--- a/extensions/spellcheck/hunspell/src/hunspell.h
+++ b/extensions/spellcheck/hunspell/src/hunspell.h
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _MYSPELLMGR_H_
#define _MYSPELLMGR_H_
diff --git a/extensions/spellcheck/hunspell/src/hunspell.hxx b/extensions/spellcheck/hunspell/src/hunspell.hxx
index 648f66c579f7..1c119fd05677 100644
--- a/extensions/spellcheck/hunspell/src/hunspell.hxx
+++ b/extensions/spellcheck/hunspell/src/hunspell.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#include "hunvisapi.h"
#include "hashmgr.hxx"
@@ -76,6 +19,10 @@
class LIBHUNSPELL_DLL_EXPORTED Hunspell
{
+private:
+ Hunspell(const Hunspell&);
+ Hunspell& operator = (const Hunspell&);
+private:
AffixMgr* pAMgr;
HashMgr* pHMgr[MAXDIC];
int maxdic;
@@ -92,6 +39,11 @@ public:
/* Hunspell(aff, dic) - constructor of Hunspell class
* input: path of affix file and dictionary file
+ *
+ * In WIN32 environment, use UTF-8 encoded paths started with the long path
+ * prefix \\\\?\\ to handle system-independent character encoding and very
+ * long path names (without the long path prefix Hunspell will use fopen()
+ * with system-dependent character encoding instead of _wfopen()).
*/
Hunspell(const char * affpath, const char * dpath, const char * key = NULL);
@@ -188,6 +140,9 @@ public:
const char * get_version();
int get_langnum() const;
+
+ /* need for putdic */
+ int input_conv(const char * word, char * dest);
/* experimental and deprecated functions */
diff --git a/extensions/spellcheck/hunspell/src/hunvisapi.h b/extensions/spellcheck/hunspell/src/hunvisapi.h
index 8c92c2641aa2..503c20f664e2 100644
--- a/extensions/spellcheck/hunspell/src/hunvisapi.h
+++ b/extensions/spellcheck/hunspell/src/hunvisapi.h
@@ -1,36 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code is Caolan McNamara.
- * Portions created by the Initial Developer are Copyright (C) 2010 the
- * Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _HUNSPELL_VISIBILITY_H_
#define _HUNSPELL_VISIBILITY_H_
@@ -42,7 +9,7 @@
# else
# define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport)
# endif
-#elif BUILDING_LIBHUNSPELL && 1
+#elif defined(BUILDING_LIBHUNSPELL) && 1
# define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default")))
#else
# define LIBHUNSPELL_DLL_EXPORTED
diff --git a/extensions/spellcheck/hunspell/src/hunzip.cpp b/extensions/spellcheck/hunspell/src/hunzip.cxx
similarity index 71%
rename from extensions/spellcheck/hunspell/src/hunzip.cpp
rename to extensions/spellcheck/hunspell/src/hunzip.cxx
index 72919309c76e..db5a881af2c3 100644
--- a/extensions/spellcheck/hunspell/src/hunzip.cpp
+++ b/extensions/spellcheck/hunspell/src/hunzip.cxx
@@ -1,42 +1,9 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#include
#include
#include
#include "hunzip.hxx"
+#include "csutil.hxx"
#define CODELEN 65536
#define BASEBITREC 5000
@@ -51,15 +18,17 @@ int Hunzip::fail(const char * err, const char * par) {
return -1;
}
-Hunzip::Hunzip(const char * file, const char * key) {
- bufsiz = 0;
- lastbit = 0;
- inc = 0;
- outc = 0;
- dec = NULL;
- fin = NULL;
- filename = (char *) malloc(strlen(file) + 1);
- if (filename) strcpy(filename, file);
+Hunzip::Hunzip(const char * file, const char * key)
+ : fin(NULL)
+ , bufsiz(0)
+ , lastbit(0)
+ , inc(0)
+ , inbits(0)
+ , outc(0)
+ , dec(NULL)
+{
+ in[0] = out[0] = line[0] = '\0';
+ filename = mystrdup(file);
if (getcode(key) == -1) bufsiz = -1;
else bufsiz = getbuf();
}
@@ -72,7 +41,7 @@ int Hunzip::getcode(const char * key) {
if (!filename) return -1;
- fin = fopen(filename, "rb");
+ fin = myfopen(filename, "rb");
if (!fin) return -1;
// read magic number
diff --git a/extensions/spellcheck/hunspell/src/hunzip.hxx b/extensions/spellcheck/hunspell/src/hunzip.hxx
index 9c6a8c4f3f83..bd02fd8f108d 100644
--- a/extensions/spellcheck/hunspell/src/hunzip.hxx
+++ b/extensions/spellcheck/hunspell/src/hunzip.hxx
@@ -1,36 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+/* hunzip: file decompression for sorted dictionaries with optional encryption,
+ * algorithm: prefix-suffix encoding and 16-bit Huffman encoding */
#ifndef _HUNZIP_HXX_
#define _HUNZIP_HXX_
@@ -54,7 +23,9 @@ struct bit {
class LIBHUNSPELL_DLL_EXPORTED Hunzip
{
-
+private:
+ Hunzip(const Hunzip&);
+ Hunzip& operator = (const Hunzip&);
protected:
char * filename;
FILE * fin;
diff --git a/extensions/spellcheck/hunspell/src/langnum.hxx b/extensions/spellcheck/hunspell/src/langnum.hxx
index b492e89b7bbe..1d140a701b4b 100644
--- a/extensions/spellcheck/hunspell/src/langnum.hxx
+++ b/extensions/spellcheck/hunspell/src/langnum.hxx
@@ -1,59 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _LANGNUM_HXX_
#define _LANGNUM_HXX_
diff --git a/extensions/spellcheck/hunspell/src/license.hunspell b/extensions/spellcheck/hunspell/src/license.hunspell
new file mode 100644
index 000000000000..dc2ce9c1e875
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/license.hunspell
@@ -0,0 +1,61 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 Hunspell, based on MySpell.
+ *
+ * The Initial Developers of the Original Code are
+ * Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
+ * Portions created by the Initial Developers are Copyright (C) 2002-2005
+ * the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s):
+ * David Einstein
+ * Davide Prina
+ * Giuseppe Modugno
+ * Gianluca Turconi
+ * Simon Brouwer
+ * Noll Janos
+ * Biro Arpad
+ * Goldman Eleonora
+ * Sarlos Tamas
+ * Bencsath Boldizsar
+ * Halacsy Peter
+ * Dvornik Laszlo
+ * Gefferth Andras
+ * Nagy Viktor
+ * Varga Daniel
+ * Chris Halls
+ * Rene Engelhard
+ * Bram Moolenaar
+ * Dafydd Jones
+ * Harri Pitkanen
+ * Andras Timar
+ * Tor Lillqvist
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_CLIENT
+# include "config.h"
+#endif
diff --git a/extensions/spellcheck/hunspell/src/moz.build b/extensions/spellcheck/hunspell/src/moz.build
index a7e39bf4e8e3..123cad787ba4 100644
--- a/extensions/spellcheck/hunspell/src/moz.build
+++ b/extensions/spellcheck/hunspell/src/moz.build
@@ -11,17 +11,17 @@ UNIFIED_SOURCES += [
if not CONFIG['MOZ_NATIVE_HUNSPELL']:
SOURCES += [
- 'affentry.cpp',
- 'affixmgr.cpp',
- 'csutil.cpp',
- 'dictmgr.cpp',
- 'filemgr.cpp',
- 'hashmgr.cpp',
- 'hunspell.cpp',
- 'hunzip.cpp',
- 'phonet.cpp',
- 'replist.cpp',
- 'suggestmgr.cpp',
+ 'affentry.cxx',
+ 'affixmgr.cxx',
+ 'csutil.cxx',
+ 'dictmgr.cxx',
+ 'filemgr.cxx',
+ 'hashmgr.cxx',
+ 'hunspell.cxx',
+ 'hunzip.cxx',
+ 'phonet.cxx',
+ 'replist.cxx',
+ 'suggestmgr.cxx',
]
# This variable is referenced in configure.in. Make sure to change that file
# too if you need to change this variable.
diff --git a/extensions/spellcheck/hunspell/src/patches/01-675553.diff b/extensions/spellcheck/hunspell/src/patches/01-675553.diff
new file mode 100755
index 000000000000..ffaf45647f40
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/01-675553.diff
@@ -0,0 +1,24 @@
+Bug 675553 - Switch from PRBool to bool.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5517,17 +5517,17 @@ struct cs_info * get_current_cs(const ch
+ if (NS_FAILED(rv))
+ return ccs;
+ decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+
+ if (NS_FAILED(rv))
+ return ccs;
+
+ for (unsigned int i = 0; i <= 0xff; ++i) {
+- PRBool success = PR_FALSE;
++ bool success = false;
+ // We want to find the upper/lowercase equivalents of each byte
+ // in this 1-byte character encoding. Call our encoding/decoding
+ // APIs separately for each byte since they may reject some of the
+ // bytes, and we want to handle errors separately for each byte.
+ char lower, upper;
+ do {
+ if (i == 0)
+ break;
diff --git a/extensions/spellcheck/hunspell/src/patches/02-690892.diff b/extensions/spellcheck/hunspell/src/patches/02-690892.diff
new file mode 100755
index 000000000000..4f250939076c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/02-690892.diff
@@ -0,0 +1,24 @@
+Bug 690892 - Replace PR_TRUE/PR_FALSE with true/false.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5549,17 +5549,17 @@ struct cs_info * get_current_cs(const ch
+
+ uniCased = ToUpperCase(uni);
+ rv = encoder->Convert(&uniCased, &uniLength, &upper, &charLength);
+ // Explicitly check NS_OK because we don't want to allow
+ // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+ if (rv != NS_OK || charLength != 1 || uniLength != 1)
+ break;
+
+- success = PR_TRUE;
++ success = true;
+ } while (0);
+
+ if (success) {
+ ccs[i].cupper = upper;
+ ccs[i].clower = lower;
+ } else {
+ ccs[i].cupper = i;
+ ccs[i].clower = i;
diff --git a/extensions/spellcheck/hunspell/src/patches/03-clang.diff b/extensions/spellcheck/hunspell/src/patches/03-clang.diff
new file mode 100755
index 000000000000..c28b622bc7ee
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/03-clang.diff
@@ -0,0 +1,25 @@
+Silence the warning about empty while body loop in clang.
+
+diff --git a/extensions/spellcheck/hunspell/src/affentry.cxx b/extensions/spellcheck/hunspell/src/affentry.cxx
+--- a/extensions/spellcheck/hunspell/src/affentry.cxx
++++ b/extensions/spellcheck/hunspell/src/affentry.cxx
+@@ -571,17 +571,18 @@ inline int SfxEntry::test_condition(cons
+ while (p && *p != ']' && ((p = nextchar(p)) != NULL));
+ st--;
+ }
+ if (p && *p != ']') p = nextchar(p);
+ } else if (pos) {
+ if (neg) return 0;
+ else if (i == numconds) return 1;
+ ingroup = true;
+- while (p && *p != ']' && ((p = nextchar(p)) != NULL));
++ while (p && *p != ']' && ((p = nextchar(p)) != NULL))
++ ;
+ // if (p && *p != ']') p = nextchar(p);
+ st--;
+ }
+ if (!pos) {
+ i++;
+ st--;
+ }
+ if (st < beg && p && *p != ']') return 0; // word <= condition
diff --git a/extensions/spellcheck/hunspell/src/patches/04-777292.diff b/extensions/spellcheck/hunspell/src/patches/04-777292.diff
new file mode 100755
index 000000000000..b588858bbe76
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/04-777292.diff
@@ -0,0 +1,24 @@
+Bug 777292 - Change nsnull to nullptr.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5507,17 +5507,17 @@ struct cs_info * get_current_cs(const ch
+ nsresult rv;
+ nsCOMPtr ccm = do_GetService(kCharsetConverterManagerCID, &rv);
+ if (NS_FAILED(rv))
+ return ccs;
+
+ rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder));
+ if (NS_FAILED(rv))
+ return ccs;
+- encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nsnull, '?');
++ encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nullptr, '?');
+ rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder));
+ if (NS_FAILED(rv))
+ return ccs;
+ decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+
+ if (NS_FAILED(rv))
+ return ccs;
+
diff --git a/extensions/spellcheck/hunspell/src/patches/05-579517.diff b/extensions/spellcheck/hunspell/src/patches/05-579517.diff
new file mode 100755
index 000000000000..1a736aba3981
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/05-579517.diff
@@ -0,0 +1,24 @@
+Bug 579517 - Convert NSPR numeric types to stdint types.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5528,17 +5528,17 @@ struct cs_info * get_current_cs(const ch
+ // APIs separately for each byte since they may reject some of the
+ // bytes, and we want to handle errors separately for each byte.
+ char lower, upper;
+ do {
+ if (i == 0)
+ break;
+ const char source = char(i);
+ PRUnichar uni, uniCased;
+- PRInt32 charLength = 1, uniLength = 1;
++ int32_t charLength = 1, uniLength = 1;
+
+ rv = decoder->Convert(&source, &charLength, &uni, &uniLength);
+ // Explicitly check NS_OK because we don't want to allow
+ // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+ if (rv != NS_OK || charLength != 1 || uniLength != 1)
+ break;
+ uniCased = ToLowerCase(uni);
+ rv = encoder->Convert(&uniCased, &uniLength, &lower, &charLength);
diff --git a/extensions/spellcheck/hunspell/src/patches/06-784776.diff b/extensions/spellcheck/hunspell/src/patches/06-784776.diff
new file mode 100755
index 000000000000..8d9d66b72550
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/06-784776.diff
@@ -0,0 +1,43 @@
+Bug 784776 - Don't assume NULL is numeric in Hunspell code.
+
+diff --git a/extensions/spellcheck/hunspell/src/affentry.hxx b/extensions/spellcheck/hunspell/src/affentry.hxx
+--- a/extensions/spellcheck/hunspell/src/affentry.hxx
++++ b/extensions/spellcheck/hunspell/src/affentry.hxx
+@@ -26,17 +26,17 @@ public:
+
+ PfxEntry(AffixMgr* pmgr, affentry* dp );
+ ~PfxEntry();
+
+ inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); }
+ struct hentry * checkword(const char * word, int len, char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+- struct hentry * check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL);
++ struct hentry * check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = FLAG_NULL);
+
+ char * check_morph(const char * word, int len, char in_compound,
+ const FLAG needflag = FLAG_NULL);
+
+ char * check_twosfx_morph(const char * word, int len,
+ char in_compound, const FLAG needflag = FLAG_NULL);
+
+ inline FLAG getFlag() { return aflag; }
+@@ -93,17 +93,17 @@ public:
+ ~SfxEntry();
+
+ inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); }
+ struct hentry * checkword(const char * word, int len, int optflags,
+ PfxEntry* ppfx, char ** wlst, int maxSug, int * ns,
+ // const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT);
+ const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0);
+
+- struct hentry * check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = NULL);
++ struct hentry * check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
+
+ char * check_twosfx_morph(const char * word, int len, int optflags,
+ PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
+ struct hentry * get_next_homonym(struct hentry * he);
+ struct hentry * get_next_homonym(struct hentry * word, int optflags, PfxEntry* ppfx,
+ const FLAG cclass, const FLAG needflag);
+
+
diff --git a/extensions/spellcheck/hunspell/src/patches/07-927728.diff b/extensions/spellcheck/hunspell/src/patches/07-927728.diff
new file mode 100755
index 000000000000..41620371262c
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/07-927728.diff
@@ -0,0 +1,62 @@
+Bug 927728 - Replace PRUnichar with char16_t.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5527,17 +5527,17 @@ struct cs_info * get_current_cs(const ch
+ // in this 1-byte character encoding. Call our encoding/decoding
+ // APIs separately for each byte since they may reject some of the
+ // bytes, and we want to handle errors separately for each byte.
+ char lower, upper;
+ do {
+ if (i == 0)
+ break;
+ const char source = char(i);
+- PRUnichar uni, uniCased;
++ char16_t uni, uniCased;
+ int32_t charLength = 1, uniLength = 1;
+
+ rv = decoder->Convert(&source, &charLength, &uni, &uniLength);
+ // Explicitly check NS_OK because we don't want to allow
+ // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+ if (rv != NS_OK || charLength != 1 || uniLength != 1)
+ break;
+ uniCased = ToLowerCase(uni);
+@@ -5680,17 +5680,17 @@ unsigned short unicodetoupper(unsigned s
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr)))
+ return 0x0130;
+ #ifdef OPENOFFICEORG
+ return static_cast(u_toupper(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+- return ToUpperCase((PRUnichar) c);
++ return ToUpperCase((char16_t) c);
+ #else
+ return (utf_tbl) ? utf_tbl[c].cupper : c;
+ #endif
+ #endif
+ }
+
+ unsigned short unicodetolower(unsigned short c, int langnum)
+ {
+@@ -5698,17 +5698,17 @@ unsigned short unicodetolower(unsigned s
+ // There are a dotless lower case i pair of upper `I',
+ // and an upper I with dot pair of lower `i'.
+ if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr)))
+ return 0x0131;
+ #ifdef OPENOFFICEORG
+ return static_cast(u_tolower(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+- return ToLowerCase((PRUnichar) c);
++ return ToLowerCase((char16_t) c);
+ #else
+ return (utf_tbl) ? utf_tbl[c].clower : c;
+ #endif
+ #endif
+ }
+
+ int unicodeisalpha(unsigned short c)
+ {
diff --git a/extensions/spellcheck/hunspell/src/patches/08-943268.diff b/extensions/spellcheck/hunspell/src/patches/08-943268.diff
new file mode 100755
index 000000000000..97aee28fcd3d
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/08-943268.diff
@@ -0,0 +1,71 @@
+Bug 943268 - Remove nsCharsetAlias and nsCharsetConverterManager.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -28,23 +28,22 @@ struct unicode_info {
+ # ifndef MOZILLA_CLIENT
+ # include "utf_info.cxx"
+ # define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
+ # endif
+ #endif
+
+ #ifdef MOZILLA_CLIENT
+ #include "nsCOMPtr.h"
+-#include "nsServiceManagerUtils.h"
+ #include "nsIUnicodeEncoder.h"
+ #include "nsIUnicodeDecoder.h"
+ #include "nsUnicharUtils.h"
+-#include "nsICharsetConverterManager.h"
++#include "mozilla/dom/EncodingUtils.h"
+
+-static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
++using mozilla::dom::EncodingUtils;
+ #endif
+
+ struct unicode_info2 {
+ char cletter;
+ unsigned short cupper;
+ unsigned short clower;
+ };
+
+@@ -5500,32 +5499,27 @@ struct cs_info * get_current_cs(const ch
+ ccs[i].cupper = i;
+ }
+
+
+ nsCOMPtr encoder;
+ nsCOMPtr decoder;
+
+ nsresult rv;
+- nsCOMPtr ccm = do_GetService(kCharsetConverterManagerCID, &rv);
+- if (NS_FAILED(rv))
++
++ nsAutoCString label(es);
++ nsAutoCString encoding;
++ if (!EncodingUtils::FindEncodingForLabelNoReplacement(label, encoding)) {
+ return ccs;
+-
+- rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder));
+- if (NS_FAILED(rv))
+- return ccs;
++ }
++ encoder = EncodingUtils::EncoderForEncoding(encoding);
++ decoder = EncodingUtils::DecoderForEncoding(encoding);
+ encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nullptr, '?');
+- rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder));
+- if (NS_FAILED(rv))
+- return ccs;
+ decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+
+- if (NS_FAILED(rv))
+- return ccs;
+-
+ for (unsigned int i = 0; i <= 0xff; ++i) {
+ bool success = false;
+ // We want to find the upper/lowercase equivalents of each byte
+ // in this 1-byte character encoding. Call our encoding/decoding
+ // APIs separately for each byte since they may reject some of the
+ // bytes, and we want to handle errors separately for each byte.
+ char lower, upper;
+ do {
diff --git a/extensions/spellcheck/hunspell/src/patches/09-license.diff b/extensions/spellcheck/hunspell/src/patches/09-license.diff
new file mode 100644
index 000000000000..c0622b2c1fba
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/09-license.diff
@@ -0,0 +1,18 @@
+Don't include config.h in license.hunspell if MOZILLA_CLIENT is set.
+
+diff --git a/extensions/spellcheck/hunspell/src/license.hunspell b/extensions/spellcheck/hunspell/src/license.hunspell
+--- a/extensions/spellcheck/hunspell/src/license.hunspell
++++ b/extensions/spellcheck/hunspell/src/license.hunspell
+@@ -51,9 +51,11 @@
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+-#include "config.h"
++#ifndef MOZILLA_CLIENT
++# include "config.h"
++#endif
diff --git a/extensions/spellcheck/hunspell/src/phonet.cpp b/extensions/spellcheck/hunspell/src/phonet.cxx
similarity index 77%
rename from extensions/spellcheck/hunspell/src/phonet.cpp
rename to extensions/spellcheck/hunspell/src/phonet.cxx
index c40b4bfe4f28..b33edeb02336 100644
--- a/extensions/spellcheck/hunspell/src/phonet.cpp
+++ b/extensions/spellcheck/hunspell/src/phonet.cxx
@@ -1,48 +1,31 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developer of the Original Code is Björn Jacke. Portions created
- * by the Initial Developers are Copyright (C) 2000-2007 the Initial
- * Developers. All Rights Reserved.
- *
- * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * Changelog:
- * 2000-01-05 Björn Jacke
- * Initial Release insprired by the article about phonetic
- * transformations out of c't 25/1999
- *
- * 2007-07-26 Björn Jacke
- * Released under MPL/GPL/LGPL tri-license for Hunspell
- *
- * 2007-08-23 László Németh
- * Porting from Aspell to Hunspell using C-like structs
- *
- ******* END LICENSE BLOCK *******/
+/* phonetic.c - generic replacement aglogithms for phonetic transformation
+ Copyright (C) 2000 Bjoern Jacke
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation;
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; If not, see
+ .
+
+ Changelog:
+
+ 2000-01-05 Bjoern Jacke
+ Initial Release insprired by the article about phonetic
+ transformations out of c't 25/1999
+
+ 2007-07-26 Bjoern Jacke
+ Released under MPL/GPL/LGPL tri-license for Hunspell
+
+ 2007-08-23 Laszlo Nemeth
+ Porting from Aspell to Hunspell using C-like structs
+*/
#include
#include
@@ -104,7 +87,8 @@ int phonet (const char * inword, char * target,
char word[MAXPHONETUTF8LEN + 1];
if (len == -1) len = strlen(inword);
if (len > MAXPHONETUTF8LEN) return 0;
- strcpy(word, inword);
+ strncpy(word, inword, MAXPHONETUTF8LEN);
+ word[MAXPHONETUTF8LEN] = '\0';
/** check word **/
i = j = z = 0;
diff --git a/extensions/spellcheck/hunspell/src/phonet.hxx b/extensions/spellcheck/hunspell/src/phonet.hxx
index b921e17cf932..f91d3b02b893 100644
--- a/extensions/spellcheck/hunspell/src/phonet.hxx
+++ b/extensions/spellcheck/hunspell/src/phonet.hxx
@@ -1,48 +1,31 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developer of the Original Code is Björn Jacke. Portions created
- * by the Initial Developers are Copyright (C) 2000-2007 the Initial
- * Developers. All Rights Reserved.
- *
- * Contributor(s): Björn Jacke (bjoern.jacke@gmx.de)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * Changelog:
- * 2000-01-05 Björn Jacke
- * Initial Release insprired by the article about phonetic
- * transformations out of c't 25/1999
- *
- * 2007-07-20 Björn Jacke
- * Released under MPL/GPL/LGPL tri-license for Hunspell
- *
- * 2007-08-22 László Németh
- * Porting from Aspell to Hunspell by little modifications
- *
- ******* END LICENSE BLOCK *******/
+/* phonetic.c - generic replacement aglogithms for phonetic transformation
+ Copyright (C) 2000 Bjoern Jacke
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation;
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; If not, see
+ .
+
+ Changelog:
+
+ 2000-01-05 Bjoern Jacke
+ Initial Release insprired by the article about phonetic
+ transformations out of c't 25/1999
+
+ 2007-07-26 Bjoern Jacke
+ Released under MPL/GPL/LGPL tri-license for Hunspell
+
+ 2007-08-23 Laszlo Nemeth
+ Porting from Aspell to Hunspell using C-like structs
+*/
#ifndef __PHONETHXX__
#define __PHONETHXX__
diff --git a/extensions/spellcheck/hunspell/src/replist.cpp b/extensions/spellcheck/hunspell/src/replist.cxx
similarity index 52%
rename from extensions/spellcheck/hunspell/src/replist.cpp
rename to extensions/spellcheck/hunspell/src/replist.cxx
index 85cdddb039f1..080cd68abf05 100644
--- a/extensions/spellcheck/hunspell/src/replist.cpp
+++ b/extensions/spellcheck/hunspell/src/replist.cxx
@@ -1,36 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
diff --git a/extensions/spellcheck/hunspell/src/replist.hxx b/extensions/spellcheck/hunspell/src/replist.hxx
index 14c6c11dca7c..2dbc0160bd96 100644
--- a/extensions/spellcheck/hunspell/src/replist.hxx
+++ b/extensions/spellcheck/hunspell/src/replist.hxx
@@ -1,37 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
/* string replacement list class */
#ifndef _REPLIST_HXX_
#define _REPLIST_HXX_
@@ -42,6 +8,9 @@
class LIBHUNSPELL_DLL_EXPORTED RepList
{
+private:
+ RepList(const RepList&);
+ RepList& operator = (const RepList&);
protected:
replentry ** dat;
int size;
diff --git a/extensions/spellcheck/hunspell/src/suggestmgr.cpp b/extensions/spellcheck/hunspell/src/suggestmgr.cxx
similarity index 95%
rename from extensions/spellcheck/hunspell/src/suggestmgr.cpp
rename to extensions/spellcheck/hunspell/src/suggestmgr.cxx
index 3fec33fb95e7..f0e336c9747d 100644
--- a/extensions/spellcheck/hunspell/src/suggestmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.cxx
@@ -1,59 +1,5 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
#include
#include
@@ -161,7 +107,10 @@ int SuggestMgr::testsug(char** wlst, const char * candidate, int wl, int ns, int
int cwrd = 1;
if (ns == maxSug) return maxSug;
for (int k=0; k < ns; k++) {
- if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+ if (strcmp(candidate,wlst[k]) == 0) {
+ cwrd = 0;
+ break;
+ }
}
if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) {
wlst[ns] = mystrdup(candidate);
@@ -418,8 +367,12 @@ int SuggestMgr::map_related(const char * word, char * candidate, int wn, int cn,
int cwrd = 1;
*(candidate + cn) = '\0';
int wl = strlen(candidate);
- for (int m=0; m < ns; m++)
- if (strcmp(candidate, wlst[m]) == 0) cwrd = 0;
+ for (int m=0; m < ns; m++) {
+ if (strcmp(candidate, wlst[m]) == 0) {
+ cwrd = 0;
+ break;
+ }
+ }
if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) {
if (ns < maxSug) {
wlst[ns] = mystrdup(candidate);
@@ -732,7 +685,7 @@ int SuggestMgr::extrachar(char** wlst, const char * word, int ns, int cpdsuggest
// error is missing a letter it needs
int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
- char candidate[MAXSWUTF8L];
+ char candidate[MAXSWUTF8L + 4];
char * p;
clock_t timelimit = clock();
int timer = MINTIMER;
@@ -754,8 +707,8 @@ int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsugge
// error is missing a letter it needs
int SuggestMgr::forgotchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
- w_char candidate_utf[MAXSWL];
- char candidate[MAXSWUTF8L];
+ w_char candidate_utf[MAXSWL + 1];
+ char candidate[MAXSWUTF8L + 4];
w_char * p;
clock_t timelimit = clock();
int timer = MINTIMER;
@@ -815,8 +768,12 @@ int SuggestMgr::twowords(char ** wlst, const char * word, int ns, int cpdsuggest
((c1 == 3) && (c2 >= 2)))) *p = '-';
cwrd = 1;
- for (int k=0; k < ns; k++)
- if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+ for (int k=0; k < ns; k++) {
+ if (strcmp(candidate,wlst[k]) == 0) {
+ cwrd = 0;
+ break;
+ }
+ }
if (ns < maxSug) {
if (cwrd) {
wlst[ns] = mystrdup(candidate);
@@ -831,8 +788,12 @@ int SuggestMgr::twowords(char ** wlst, const char * word, int ns, int cpdsuggest
mystrlen(p + 1) > 1 &&
mystrlen(candidate) - mystrlen(p) > 1) {
*p = '-';
- for (int k=0; k < ns; k++)
- if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+ for (int k=0; k < ns; k++) {
+ if (strcmp(candidate,wlst[k]) == 0) {
+ cwrd = 0;
+ break;
+ }
+ }
if (ns < maxSug) {
if (cwrd) {
wlst[ns] = mystrdup(candidate);
@@ -1387,7 +1348,10 @@ int SuggestMgr::ngsuggest(char** wlst, char * w, int ns, HashMgr** pHMgr, int md
if ((!guessorig[i] && strstr(guess[i], wlst[j])) ||
(guessorig[i] && strstr(guessorig[i], wlst[j])) ||
// check forbidden words
- !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) unique = 0;
+ !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) {
+ unique = 0;
+ break;
+ }
}
if (unique) {
wlst[ns++] = guess[i];
@@ -1415,7 +1379,10 @@ int SuggestMgr::ngsuggest(char** wlst, char * w, int ns, HashMgr** pHMgr, int md
// don't suggest previous suggestions or a previous suggestion with prefixes or affixes
if (strstr(rootsphon[i], wlst[j]) ||
// check forbidden words
- !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) unique = 0;
+ !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) {
+ unique = 0;
+ break;
+ }
}
if (unique) {
wlst[ns++] = mystrdup(rootsphon[i]);
@@ -1909,6 +1876,10 @@ int SuggestMgr::commoncharacterpositions(char * s1, const char * s2, int * is_sw
w_char su2[MAXSWL];
int l1 = u8_u16(su1, MAXSWL, s1);
int l2 = u8_u16(su2, MAXSWL, s2);
+
+ if (l1 <= 0 || l2 <= 0)
+ return 0;
+
// decapitalize dictionary word
if (complexprefixes) {
mkallsmall_utf(su2+l2-1, 1, langnum);
diff --git a/extensions/spellcheck/hunspell/src/suggestmgr.hxx b/extensions/spellcheck/hunspell/src/suggestmgr.hxx
index 195699ea906c..8456b5b3e244 100644
--- a/extensions/spellcheck/hunspell/src/suggestmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.hxx
@@ -1,60 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- * David Einstein (deinst@world.std.com)
- * László Németh (nemethl@gyorsposta.hu)
- * Caolan McNamara (caolanm@redhat.com)
- * Davide Prina
- * Giuseppe Modugno
- * Gianluca Turconi
- * Simon Brouwer
- * Noll Janos
- * Biro Arpad
- * Goldman Eleonora
- * Sarlos Tamas
- * Bencsath Boldizsar
- * Halacsy Peter
- * Dvornik Laszlo
- * Gefferth Andras
- * Nagy Viktor
- * Varga Daniel
- * Chris Halls
- * Rene Engelhard
- * Bram Moolenaar
- * Dafydd Jones
- * Harri Pitkanen
- * Andras Timar
- * Tor Lillqvist
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef _SUGGESTMGR_HXX_
#define _SUGGESTMGR_HXX_
@@ -89,6 +32,10 @@ enum { LCS_UP, LCS_LEFT, LCS_UPLEFT };
class LIBHUNSPELL_DLL_EXPORTED SuggestMgr
{
+private:
+ SuggestMgr(const SuggestMgr&);
+ SuggestMgr& operator = (const SuggestMgr&);
+private:
char * ckey;
int ckeyl;
w_char * ckey_utf;
diff --git a/extensions/spellcheck/hunspell/src/w_char.hxx b/extensions/spellcheck/hunspell/src/w_char.hxx
index 82cfa762d7fb..3719dd3b77d9 100644
--- a/extensions/spellcheck/hunspell/src/w_char.hxx
+++ b/extensions/spellcheck/hunspell/src/w_char.hxx
@@ -1,36 +1,3 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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 Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and László Németh (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- *
- * Contributor(s): László Németh (nemethl@gyorsposta.hu)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
#ifndef __WCHARHXX__
#define __WCHARHXX__
diff --git a/gfx/cairo/libpixman/src/pixman-x86.c b/gfx/cairo/libpixman/src/pixman-x86.c
index 57e4d1f351b1..feea23e7904e 100644
--- a/gfx/cairo/libpixman/src/pixman-x86.c
+++ b/gfx/cairo/libpixman/src/pixman-x86.c
@@ -106,6 +106,10 @@ have_cpuid (void)
#endif
}
+#ifdef _MSC_VER
+#include /* for __cpuid */
+#endif
+
static void
pixman_cpuid (uint32_t feature,
uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
diff --git a/gfx/gl/GLReadTexImageHelper.cpp b/gfx/gl/GLReadTexImageHelper.cpp
index 9096b26fe67b..6e26c59e0e0c 100644
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -8,8 +8,6 @@
#include "GLContext.h"
#include "OGLShaderProgram.h"
#include "gfxTypes.h"
-#include "gfxContext.h"
-#include "gfxImageSurface.h"
#include "ScopedGLHelpers.h"
#include "mozilla/gfx/2D.h"
#include "gfx2DGlue.h"
@@ -491,24 +489,29 @@ static TemporaryRef YInvertImageSurface(DataSourceSurface* aS
Factory::CreateDataSourceSurfaceWithStride(aSurf->GetSize(),
aSurf->GetFormat(),
aSurf->Stride());
+ if (!temp) {
+ return nullptr;
+ }
+ DataSourceSurface::MappedSurface map;
+ if (!temp->Map(DataSourceSurface::MapType::WRITE, &map)) {
+ return nullptr;
+ }
RefPtr dt =
Factory::CreateDrawTargetForData(BackendType::CAIRO,
- temp->GetData(),
+ map.mData,
temp->GetSize(),
- temp->Stride(),
+ map.mStride,
temp->GetFormat());
- nsRefPtr ctx = new gfxContext(dt);
- ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
- ctx->Scale(1.0, -1.0);
- ctx->Translate(-gfxPoint(0.0, aSurf->GetSize().height));
-
- nsRefPtr thebesSurf =
- new gfxImageSurface(aSurf->GetData(),
- ThebesIntSize(aSurf->GetSize()),
- aSurf->Stride(),
- SurfaceFormatToImageFormat(aSurf->GetFormat()));
- ctx->SetSource(thebesSurf);
- ctx->Paint();
+ if (!dt) {
+ temp->Unmap();
+ return nullptr;
+ }
+ dt->SetTransform(Matrix::Translation(0.0, aSurf->GetSize().height) *
+ Matrix::Scaling(1.0, -1.0));
+ Rect rect(0, 0, aSurf->GetSize().width, aSurf->GetSize().height);
+ dt->DrawSurface(aSurf, rect, rect, DrawSurfaceOptions(),
+ DrawOptions(1.0, CompositionOp::OP_SOURCE, AntialiasMode::NONE));
+ temp->Unmap();
return temp.forget();
}
diff --git a/gfx/gl/GLReadTexImageHelper.h b/gfx/gl/GLReadTexImageHelper.h
index 9ea177778d96..38f4ca3bfc74 100644
--- a/gfx/gl/GLReadTexImageHelper.h
+++ b/gfx/gl/GLReadTexImageHelper.h
@@ -14,8 +14,6 @@
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/Types.h"
-class gfxImageSurface;
-
namespace mozilla {
namespace gfx {
diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp
index 8dd4642e8db2..8deba1578bef 100755
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -6,7 +6,6 @@
#include "GLScreenBuffer.h"
#include
-#include "gfxImageSurface.h"
#include "GLContext.h"
#include "GLBlitHelper.h"
#include "GLReadTexImageHelper.h"
diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h
index 8c039ba10835..cfe04dccd11d 100644
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -22,9 +22,6 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Point.h"
-// Forwards:
-class gfxImageSurface;
-
namespace mozilla {
namespace gfx {
class SurfaceStream;
diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp
index 45b6fc9f8c5f..91b51be7e809 100644
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -6,11 +6,11 @@
#include "GLTextureImage.h"
#include "GLContext.h"
#include "gfxContext.h"
-#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
#include "gfx2DGlue.h"
#include "gfxImageSurface.h"
+#include "mozilla/gfx/2D.h"
#include "ScopedGLHelpers.h"
#include "GLUploadHelpers.h"
@@ -19,6 +19,8 @@
#include "TextureImageCGL.h"
#endif
+using namespace mozilla::gfx;
+
namespace mozilla {
namespace gl {
@@ -516,10 +518,6 @@ TiledTextureImage::EndUpdate()
RefPtr updateSnapshot = mUpdateDrawTarget->Snapshot();
RefPtr updateData = updateSnapshot->GetDataSurface();
- nsRefPtr updateSurface = new gfxImageSurface(updateData->GetData(),
- gfx::ThebesIntSize(updateData->GetSize()),
- updateData->Stride(),
- gfx::SurfaceFormatToImageFormat(updateData->GetFormat()));
// upload tiles from temp surface
for (unsigned i = 0; i < mImages.Length(); i++) {
@@ -535,11 +533,18 @@ TiledTextureImage::EndUpdate()
subregion.MoveBy(-xPos, -yPos); // Tile-local space
// copy tile from temp target
gfx::DrawTarget* drawTarget = mImages[i]->BeginUpdate(subregion);
- nsRefPtr ctx = new gfxContext(drawTarget);
- gfxUtils::ClipToRegion(ctx, subregion);
- ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
- ctx->SetSource(updateSurface, gfxPoint(-xPos, -yPos));
- ctx->Paint();
+ MOZ_ASSERT(drawTarget->GetType() == BackendType::CAIRO,
+ "updateSnapshot should not have been converted to data");
+ gfxUtils::ClipToRegion(drawTarget, subregion);
+ Size size(updateData->GetSize().width,
+ updateData->GetSize().height);
+ drawTarget->DrawSurface(updateData,
+ Rect(Point(-xPos, -yPos), size),
+ Rect(Point(0, 0), size),
+ DrawSurfaceOptions(),
+ DrawOptions(1.0, CompositionOp::OP_SOURCE,
+ AntialiasMode::NONE));
+ drawTarget->PopClip();
mImages[i]->EndUpdate();
}
diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp
index b701b1275e0a..8d84dc640bf7 100644
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -7,7 +7,6 @@
#include "GLContext.h"
#include "GLBlitHelper.h"
#include "ScopedGLHelpers.h"
-#include "gfxImageSurface.h"
#include "mozilla/gfx/2D.h"
#include "GLReadTexImageHelper.h"
diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h
index 319daf8ee551..7c5bbe1fa6a1 100644
--- a/gfx/gl/SharedSurfaceIO.h
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -6,7 +6,6 @@
#ifndef SHARED_SURFACEIO_H_
#define SHARED_SURFACEIO_H_
-#include "gfxImageSurface.h"
#include "SharedSurfaceGL.h"
#include "mozilla/RefPtr.h"
@@ -54,7 +53,6 @@ private:
SharedSurface_IOSurface(MacIOSurface* surface, GLContext* gl, const gfx::IntSize& size, bool hasAlpha);
RefPtr mSurface;
- nsRefPtr mImageSurface;
GLuint mProdTex;
const GLContext* mCurConsGL;
GLuint mConsTex;
diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp
index ecb9e50f743c..33adf818a07e 100644
--- a/gfx/layers/ImageDataSerializer.cpp
+++ b/gfx/layers/ImageDataSerializer.cpp
@@ -5,7 +5,6 @@
#include "ImageDataSerializer.h"
#include "gfx2DGlue.h" // for SurfaceFormatToImageFormat
-#include "gfxImageSurface.h" // for gfxImageSurface
#include "gfxPoint.h" // for gfxIntSize
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
@@ -127,17 +126,6 @@ ImageDataSerializerBase::GetFormat() const
return GetBufferInfo(mData, mDataSize)->format;
}
-TemporaryRef
-ImageDataSerializerBase::GetAsThebesSurface()
-{
- MOZ_ASSERT(IsValid());
- IntSize size = GetSize();
- return new gfxImageSurface(GetData(),
- gfxIntSize(size.width, size.height),
- GetStride(),
- SurfaceFormatToImageFormat(GetFormat()));
-}
-
TemporaryRef
ImageDataSerializerBase::GetAsDrawTarget(gfx::BackendType aBackend)
{
diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h
index 90567925bdfa..33f8e2616789 100644
--- a/gfx/layers/ImageDataSerializer.h
+++ b/gfx/layers/ImageDataSerializer.h
@@ -14,8 +14,6 @@
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Types.h" // for SurfaceFormat
-class gfxImageSurface;
-
namespace mozilla {
namespace gfx {
class DataSourceSurface;
@@ -36,7 +34,6 @@ public:
gfx::IntSize GetSize() const;
gfx::SurfaceFormat GetFormat() const;
TemporaryRef GetAsSurface();
- TemporaryRef GetAsThebesSurface();
TemporaryRef GetAsDrawTarget(gfx::BackendType aBackend);
static uint32_t ComputeMinBufferSize(gfx::IntSize aSize,
diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp
index 8292117a9856..b5737d379720 100644
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -18,7 +18,6 @@
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxUtils.h" // for gfxUtils, etc
#include "gfx2DGlue.h"
-#include "gfxImageSurface.h"
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/Telemetry.h" // for Accumulate
#include "mozilla/gfx/2D.h" // for DrawTarget
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp
index dbb0ebd18df8..3aecc60c5065 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1974,8 +1974,8 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
return false;
}
-void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) const {
- // The overscroll effect applied here is a combination of a translation in
+void AsyncPanZoomController::GetOverscrollTransform(ViewTransform* aTransform) const {
+ // The overscroll effect is a combination of a translation in
// the direction of overscroll, and shrinking in both directions.
// With the effect applied, we can think of the composited region as being
// made up of the following subregions.
@@ -2066,8 +2066,9 @@ void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) co
}
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
- ViewTransform* aNewTransform,
- ScreenPoint& aScrollOffset) {
+ ViewTransform* aOutTransform,
+ ScreenPoint& aScrollOffset,
+ ViewTransform* aOutOverscrollTransform) {
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
// fling is happening, it has to keep compositing so that the animation is
@@ -2082,12 +2083,22 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
requestAnimationFrame = UpdateAnimation(aSampleTime, &deferredTasks);
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
- *aNewTransform = GetCurrentAsyncTransform();
+ *aOutTransform = GetCurrentAsyncTransform();
- if (IsOverscrolled()) {
- // GetCurrentAsyncTransform() does not consider any overscroll we may have.
- // Adjust the transform to account for that.
- ApplyOverscrollEffect(aNewTransform);
+ // If we are overscrolled, we would like the compositor to apply an
+ // additional transform that produces an overscroll effect.
+ if (aOutOverscrollTransform && IsOverscrolled()) {
+ GetOverscrollTransform(aOutOverscrollTransform);
+
+ // Since the caller will apply aOverscrollTransform after aNewTransform,
+ // aOverscrollTransform's translation will be not be scaled by
+ // aNewTransform's scale. Since the resulting transform is then
+ // multiplied by the CSS transform, which cancels out the non-transient
+ // part of aNewTransform->mScale, this results in an overscroll
+ // translation whose magnitude varies with the zoom. To avoid this,
+ // we adjust for that here.
+ aOutOverscrollTransform->mTranslation.x *= aOutTransform->mScale.scale;
+ aOutOverscrollTransform->mTranslation.y *= aOutTransform->mScale.scale;
}
LogRendertraceRect(GetGuid(), "viewport", "red",
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h
index 35e2b85d8918..55f0f60b9a41 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -154,21 +154,26 @@ public:
Vector* aOutDeferredTasks);
/**
- * The compositor calls this when it's about to draw pannable/zoomable content
- * and is setting up transforms for compositing the layer tree. This is not
- * idempotent. For example, a fling transform can be applied each time this is
- * called (though not necessarily). |aSampleTime| is the time that this is
- * sampled at; this is used for interpolating animations. Calling this sets a
- * new transform in |aNewTransform| which should be multiplied to the transform
- * in the shadow layer corresponding to this APZC.
+ * RQuery the transforms that should be applied to the layer corresponding
+ * to this APZC due to asynchronous panning and zooming.
+ * |aSampleTime| is the time that this is sampled at; this is used for
+ * interpolating animations.
+ * This function returns two transforms via out parameters:
+ * |aOutTransform| is the transform due to regular panning and zooming
+ * |aOverscrollTransform| is the transform due to overscrolling
+ * The two are separated because some clients want to ignore the overscroll
+ * transform for some purposes (and for convenience to these clients, the
+ * overscroll transform parameter may be nullptr). Clients who do not want
+ * to ignore the overscroll transform should multiply the two transforms
+ * together.
*
- * Return value indicates whether or not any currently running animation
- * should continue. That is, if true, the compositor should schedule another
- * composite.
+ * The return value indicates whether or not any currently running animation
+ * should continue. If true, the compositor should schedule another composite.
*/
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
- ViewTransform* aNewTransform,
- ScreenPoint& aScrollOffset);
+ ViewTransform* aOutTransform,
+ ScreenPoint& aScrollOffset,
+ ViewTransform* aOutOverscrollTransform = nullptr);
/**
* A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics
@@ -643,10 +648,10 @@ private:
bool IsPanningState(PanZoomState mState);
/**
- * Apply to |aTransform| a visual effect that reflects this apzc's
+ * Return in |aTransform| a visual effect that reflects this apzc's
* overscrolled state, if any.
*/
- void ApplyOverscrollEffect(ViewTransform* aTransform) const;
+ void GetOverscrollTransform(ViewTransform* aTransform) const;
enum AxisLockMode {
FREE, /* No locking at all */
diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp
index 9827deb2d0ff..db80a57f9d91 100644
--- a/gfx/layers/client/ClientTiledThebesLayer.cpp
+++ b/gfx/layers/client/ClientTiledThebesLayer.cpp
@@ -155,15 +155,6 @@ ClientTiledThebesLayer::BeginPaint()
ApplyParentLayerToLayerTransform(mPaintData.mTransformDisplayPortToLayer, criticalDisplayPort));
TILING_PRLOG_OBJ(("TILING 0x%p: Critical displayport %s\n", this, tmpstr.get()), mPaintData.mCriticalDisplayPort);
- // Compute the viewport that applies to this layer in the LayoutDevice
- // space of this layer.
- ParentLayerRect viewport =
- (displayportMetrics.mViewport * displayportMetrics.GetZoomToParent())
- + displayportMetrics.mCompositionBounds.TopLeft();
- mPaintData.mViewport = ApplyParentLayerToLayerTransform(
- mPaintData.mTransformDisplayPortToLayer, viewport);
- TILING_PRLOG_OBJ(("TILING 0x%p: Viewport %s\n", this, tmpstr.get()), mPaintData.mViewport);
-
// Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
// before any async transforms have occurred, we can use the zoom for this.
mPaintData.mResolution = displayportMetrics.GetZoomToParent();
@@ -273,13 +264,15 @@ ClientTiledThebesLayer::RenderLowPrecision(nsIntRegion& aInvalidRegion,
aInvalidRegion.Sub(aInvalidRegion, mValidRegion);
TILING_PRLOG_OBJ(("TILING 0x%p: Progressive paint: low-precision invalid region is %s\n", this, tmpstr.get()), aInvalidRegion);
- TILING_PRLOG_OBJ(("TILING 0x%p: Progressive paint: low-precision new valid region is %s\n", this, tmpstr.get()), mLowPrecisionValidRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive paint: low-precision old valid region is %s\n", this, tmpstr.get()), oldValidRegion);
if (!aInvalidRegion.IsEmpty()) {
updatedBuffer = mContentClient->mLowPrecisionTiledBuffer.ProgressiveUpdate(
mLowPrecisionValidRegion, aInvalidRegion, oldValidRegion,
&mPaintData, aCallback, aCallbackData);
}
+
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive paint: low-precision new valid region is %s\n", this, tmpstr.get()), mLowPrecisionValidRegion);
return updatedBuffer;
}
if (!mLowPrecisionValidRegion.IsEmpty()) {
diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp
index e5d48951cc7e..25264bb2a312 100644
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -3,6 +3,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// Uncomment this to enable the TILING_PRLOG stuff in this file
+// for release builds. To get the output you need to have
+// NSPR_LOG_MODULES=tiling:5 in your environment at runtime.
+// #define FORCE_PR_LOG
+
#include "mozilla/layers/TiledContentClient.h"
#include // for ceil, ceilf, floor
#include "ClientTiledThebesLayer.h" // for ClientTiledThebesLayer
@@ -25,6 +30,7 @@
#include "gfxReusableSharedImageSurfaceWrapper.h"
#include "nsMathUtils.h" // for NS_roundf
#include "gfx2DGlue.h"
+#include "LayersLogging.h"
// This is the minimum area that we deem reasonable to copy from the front buffer to the
// back buffer on tile updates. If the valid region is smaller than this, we just
@@ -629,6 +635,9 @@ ClientTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData)
{
+ TILING_PRLOG_OBJ(("TILING 0x%p: PaintThebes painting region %s\n", mThebesLayer, tmpstr.get()), aPaintRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: PaintThebes new valid region %s\n", mThebesLayer, tmpstr.get()), aNewValidRegion);
+
mCallback = aCallback;
mCallbackData = aCallbackData;
@@ -940,6 +949,8 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
nsIntRegion staleRegion;
staleRegion.And(aInvalidRegion, aOldValidRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update stale region %s\n", mThebesLayer, tmpstr.get()), staleRegion);
+
// Find out the current view transform to determine which tiles to draw
// first, and see if we should just abort this paint. Aborting is usually
// caused by there being an incoming, more relevant paint.
@@ -963,6 +974,8 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
zoom);
#endif
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update compositor bounds %s zoom %f abort %d\n", mThebesLayer, tmpstr.get(), zoom.scale, abortPaint), compositionBounds);
+
if (abortPaint) {
// We ignore if front-end wants to abort if this is the first,
// non-low-precision paint, as in that situation, we're about to override
@@ -980,6 +993,10 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
TransformCompositionBounds(compositionBounds, zoom, aPaintData->mScrollOffset,
aPaintData->mResolution, aPaintData->mTransformDisplayPortToLayer);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update transformed compositor bounds %s using resolution %f and scroll (%f,%f)\n",
+ mThebesLayer, tmpstr.get(), aPaintData->mResolution.scale, aPaintData->mScrollOffset.x, aPaintData->mScrollOffset.y),
+ transformedCompositionBounds);
+
// Paint tiles that have stale content or that intersected with the screen
// at the time of issuing the draw command in a single transaction first.
// This is to avoid rendering glitches on animated page content, and when
@@ -987,15 +1004,14 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
LayerRect typedCoherentUpdateRect =
transformedCompositionBounds.Intersect(aPaintData->mCompositionBounds);
- // Offset by the viewport origin, as the composition bounds are stored in
- // Layer space and not LayoutDevice space.
- // TODO(kats): does this make sense?
- typedCoherentUpdateRect.MoveBy(aPaintData->mViewport.TopLeft());
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update intersected coherency rect %s\n", mThebesLayer, tmpstr.get()), typedCoherentUpdateRect);
// Convert to untyped to intersect with the invalid region.
nsIntRect untypedCoherentUpdateRect(LayerIntRect::ToUntyped(
RoundedOut(typedCoherentUpdateRect)));
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update final coherency rect %s\n", mThebesLayer, tmpstr.get()), untypedCoherentUpdateRect);
+
aRegionToPaint.And(aInvalidRegion, untypedCoherentUpdateRect);
aRegionToPaint.Or(aRegionToPaint, staleRegion);
bool drawingStale = !aRegionToPaint.IsEmpty();
@@ -1010,6 +1026,8 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
paintVisible = true;
}
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update final paint region %s\n", mThebesLayer, tmpstr.get()), aRegionToPaint);
+
// Paint area that's visible and overlaps previously valid content to avoid
// visible glitches in animated elements, such as gifs.
bool paintInSingleTransaction = paintVisible && (drawingStale || aPaintData->mFirstPaint);
@@ -1085,6 +1103,10 @@ ClientTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData)
{
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update valid region %s\n", mThebesLayer, tmpstr.get()), aValidRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update invalid region %s\n", mThebesLayer, tmpstr.get()), aInvalidRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update old valid region %s\n", mThebesLayer, tmpstr.get()), aOldValidRegion);
+
bool repeat = false;
bool isBufferChanged = false;
do {
@@ -1097,6 +1119,8 @@ ClientTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion,
aPaintData,
repeat);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update computed paint region %s repeat %d\n", mThebesLayer, tmpstr.get(), repeat), regionToPaint);
+
// There's no further work to be done.
if (regionToPaint.IsEmpty()) {
break;
@@ -1118,6 +1142,9 @@ ClientTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion,
aInvalidRegion.Sub(aInvalidRegion, regionToPaint);
} while (repeat);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update final valid region %s buffer changed %d\n", mThebesLayer, tmpstr.get(), isBufferChanged), aValidRegion);
+ TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update final invalid region %s\n", mThebesLayer, tmpstr.get()), aInvalidRegion);
+
// Return false if nothing has been drawn, or give what has been drawn
// to the shadow layer to upload.
return isBufferChanged;
diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h
index 2bb33930ebdb..bdccdfc3a882 100644
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -267,12 +267,6 @@ struct BasicTiledLayerPaintData {
*/
LayerIntRect mCriticalDisplayPort;
- /*
- * The viewport of the content from the nearest ancestor layer that
- * represents scrollable content with a display port set.
- */
- LayerRect mViewport;
-
/*
* The render resolution of the document that the content this layer
* represents is in.
diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp
index f768e08474fa..1e270aa281a7 100644
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -239,6 +239,7 @@ void
AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
Layer* aTransformedSubtreeRoot,
const Matrix4x4& aPreviousTransformForRoot,
+ const Matrix4x4& aCurrentTransformForRoot,
const LayerMargin& aFixedLayerMargins)
{
bool isRootFixed = aLayer->GetIsFixedPosition() &&
@@ -262,7 +263,7 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
Matrix oldRootTransform;
Matrix newRootTransform;
if (!aPreviousTransformForRoot.Is2D(&oldRootTransform) ||
- !aTransformedSubtreeRoot->GetLocalTransform().Is2D(&newRootTransform)) {
+ !aCurrentTransformForRoot.Is2D(&newRootTransform)) {
return;
}
@@ -335,19 +336,20 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer,
}
// Fixed layers are relative to their nearest scrollable layer, so when we
- // encounter a scrollable layer, reset the transform to that layer and remove
- // the fixed margins.
+ // encounter a scrollable layer, bail. ApplyAsyncContentTransformToTree will
+ // have already recursed on this layer and called AlignFixedAndStickyLayers
+ // on it with its own transforms.
if (aLayer->AsContainerLayer() &&
aLayer->AsContainerLayer()->GetFrameMetrics().IsScrollable() &&
aLayer != aTransformedSubtreeRoot) {
- AlignFixedAndStickyLayers(aLayer, aLayer, aLayer->GetTransform(), LayerMargin(0, 0, 0, 0));
return;
}
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
AlignFixedAndStickyLayers(child, aTransformedSubtreeRoot,
- aPreviousTransformForRoot, aFixedLayerMargins);
+ aPreviousTransformForRoot,
+ aCurrentTransformForRoot, aFixedLayerMargins);
}
}
@@ -498,6 +500,15 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
return activeAnimations;
}
+Matrix4x4
+CombineWithCSSTransform(const gfx3DMatrix& treeTransform, Layer* aLayer)
+{
+ Matrix4x4 result;
+ ToMatrix4x4(treeTransform, result);
+ result = result * aLayer->GetTransform();
+ return result;
+}
+
bool
AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
Layer *aLayer,
@@ -519,12 +530,13 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
LayerComposite* layerComposite = aLayer->AsLayerComposite();
Matrix4x4 oldTransform = aLayer->GetTransform();
- ViewTransform treeTransform;
+ ViewTransform treeTransformWithoutOverscroll, overscrollTransform;
ScreenPoint scrollOffset;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
- &treeTransform,
- scrollOffset);
+ &treeTransformWithoutOverscroll,
+ scrollOffset,
+ &overscrollTransform);
const FrameMetrics& metrics = container->GetFrameMetrics();
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
@@ -532,9 +544,9 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
LayerMargin fixedLayerMargins(0, 0, 0, 0);
ScreenPoint offset(0, 0);
- SyncFrameMetrics(scrollOffset, treeTransform.mScale.scale, metrics.mScrollableRect,
- mLayersUpdated, displayPort, paintScale,
- mIsFirstPaint, fixedLayerMargins, offset);
+ SyncFrameMetrics(scrollOffset, treeTransformWithoutOverscroll.mScale.scale,
+ metrics.mScrollableRect, mLayersUpdated, displayPort,
+ paintScale, mIsFirstPaint, fixedLayerMargins, offset);
mIsFirstPaint = false;
mLayersUpdated = false;
@@ -542,9 +554,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
// Apply the render offset
mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);
- Matrix4x4 transform;
- ToMatrix4x4(gfx3DMatrix(treeTransform), transform);
- transform = transform * aLayer->GetTransform();
+ Matrix4x4 transform = CombineWithCSSTransform(
+ treeTransformWithoutOverscroll * overscrollTransform, aLayer);
// GetTransform already takes the pre- and post-scale into account. Since we
// will apply the pre- and post-scale again when computing the effective
@@ -564,7 +575,14 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
LayoutDeviceToLayerScale resolution = metrics.mCumulativeResolution;
oldTransform.Scale(resolution.scale, resolution.scale, 1);
- AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform, fixedLayerMargins);
+ // For the purpose of aligning fixed and sticky layers, we disregard
+ // the overscroll transform when computing the 'aCurrentTransformForRoot'
+ // parameter. This ensures that the overscroll transform is not unapplied,
+ // and therefore that the visual effect applies to fixed and sticky layers.
+ Matrix4x4 transformWithoutOverscroll = CombineWithCSSTransform(
+ treeTransformWithoutOverscroll, aLayer);
+ AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
+ transformWithoutOverscroll, fixedLayerMargins);
appliedTransform = true;
}
@@ -867,7 +885,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
// Make sure fixed position layers don't move away from their anchor points
// when we're asynchronously panning or zooming
- AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform, fixedLayerMargins);
+ AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
+ aLayer->GetLocalTransform(), fixedLayerMargins);
}
bool
diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h
index 0ce44feef8d9..65940dea570f 100644
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -41,6 +41,12 @@ struct ViewTransform {
gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1);
}
+ // For convenience, to avoid writing the cumbersome
+ // "gfx3dMatrix(a) * gfx3DMatrix(b)".
+ friend gfx3DMatrix operator*(const ViewTransform& a, const ViewTransform& b) {
+ return gfx3DMatrix(a) * gfx3DMatrix(b);
+ }
+
bool operator==(const ViewTransform& rhs) const {
return mTranslation == rhs.mTranslation && mScale == rhs.mScale;
}
@@ -155,14 +161,18 @@ private:
* aTransformedSubtreeRoot. The translation is chosen so that the layer's
* anchor point relative to aTransformedSubtreeRoot's parent layer is the same
* as it was when aTransformedSubtreeRoot's GetLocalTransform() was
- * aPreviousTransformForRoot. For sticky position layers, the translation is
- * further intersected with the layer's sticky scroll ranges.
+ * aPreviousTransformForRoot. aCurrentTransformForRoot is
+ * aTransformedSubtreeRoot's current GetLocalTransform() modulo any
+ * overscroll-related transform, which we don't want to adjust for.
+ * For sticky position layers, the translation is further intersected with
+ * the layer's sticky scroll ranges.
* This function will also adjust layers so that the given content document
* fixed position margins will be respected during asynchronous panning and
* zooming.
*/
void AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot,
const gfx::Matrix4x4& aPreviousTransformForRoot,
+ const gfx::Matrix4x4& aCurrentTransformForRoot,
const LayerMargin& aFixedLayerMargins);
/**
diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp
index facc62ad0cf3..a4ea522c4f1e 100644
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -311,6 +311,14 @@ LayerManagerComposite::RootLayer() const
return ToLayerComposite(mRoot);
}
+#ifdef MOZ_PROFILING
+// Only build the QR feature when profiling to avoid bloating
+// our data section.
+// This table was generated using qrencode and is a binary
+// encoding of the qrcodes 0-255.
+#include "qrcode_table.h"
+#endif
+
static uint16_t sFrameCount = 0;
void
LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
@@ -342,30 +350,48 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
gfx::Matrix4x4());
}
+#ifdef MOZ_PROFILING
if (drawFrameCounter) {
profiler_set_frame_number(sFrameCount);
+ const char* qr = sQRCodeTable[sFrameCount%256];
- uint16_t frameNumber = sFrameCount;
- const uint16_t bitWidth = 3;
+ int size = 21;
+ int padding = 2;
float opacity = 1.0;
- gfx::Rect clip(0,0, bitWidth*16, bitWidth);
- for (size_t i = 0; i < 16; i++) {
+ const uint16_t bitWidth = 5;
+ gfx::Rect clip(0,0, bitWidth*640, bitWidth*640);
- gfx::Color bitColor;
- if ((frameNumber >> i) & 0x1) {
- bitColor = gfx::Color(0, 0, 0, 1.0);
- } else {
- bitColor = gfx::Color(1.0, 1.0, 1.0, 1.0);
+ // Draw the white squares at once
+ gfx::Color bitColor(1.0, 1.0, 1.0, 1.0);
+ EffectChain effects;
+ effects.mPrimaryEffect = new EffectSolidColor(bitColor);
+ int totalSize = (size + padding * 2) * bitWidth;
+ mCompositor->DrawQuad(gfx::Rect(0, 0, totalSize, totalSize),
+ clip,
+ effects,
+ opacity,
+ gfx::Matrix4x4());
+
+ // Draw a black square for every bit set in qr[index]
+ effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0, 0, 0, 1.0));
+ for (int y = 0; y < size; y++) {
+ for (int x = 0; x < size; x++) {
+ // Select the right bit from the binary encoding
+ int currBit = 128 >> ((x + y * 21) % 8);
+ int i = (x + y * 21) / 8;
+ if (qr[i] & currBit) {
+ mCompositor->DrawQuad(gfx::Rect(bitWidth * (x + padding),
+ bitWidth * (y + padding),
+ bitWidth, bitWidth),
+ clip,
+ effects,
+ opacity,
+ gfx::Matrix4x4());
+ }
}
- EffectChain effects;
- effects.mPrimaryEffect = new EffectSolidColor(bitColor);
- mCompositor->DrawQuad(gfx::Rect(bitWidth*i, 0, bitWidth, bitWidth),
- clip,
- effects,
- opacity,
- gfx::Matrix4x4());
}
}
+#endif
if (drawFrameColorBars || drawFrameCounter) {
// We intentionally overflow at 2^16.
diff --git a/gfx/layers/composite/qrcode_table.h b/gfx/layers/composite/qrcode_table.h
new file mode 100644
index 000000000000..553be28c10a8
--- /dev/null
+++ b/gfx/layers/composite/qrcode_table.h
@@ -0,0 +1,259 @@
+const char * const sQRCodeTable[] = {
+ "\xFE\x5B\xFC\x16\x90\x6E\xB2\xBB\x74\xA5\xDB\xA8\xAE\xC1\x4D\x7\xFA\xAF\xE0\x1F\x0\xD3\x63\xB2\xC7\x11\x94\xE3\x6\x63\xA0\xF1\x74\xAA\x80\x78\xE3\xFA\x94\xD0\x43\xBA\xBA\x73\xFD\xD4\x83\xEE\x8A\x23\x5\x4D\x6F\xEF\x8E\x0",
+ "\xFE\x5B\xFC\x13\x90\x6E\xB6\xBB\x74\xA5\xDB\xA2\xAE\xC1\x5\x7\xFA\xAF\xE0\x1B\x0\xEF\xF6\x20\xA5\x11\xB4\xF2\x22\x6A\x84\x62\xF0\xAB\x80\x5A\xAB\xFA\x5D\xF0\x53\xBA\xBA\x97\x6D\xD2\x11\xAE\xA2\x23\x5\x84\x4F\xEA\xAA\x1",
+ "\xFE\x5B\xFC\x16\x90\x6E\xB2\xBB\x74\xA5\xDB\xA8\xAE\xC1\x4D\x7\xFA\xAF\xE0\x1F\x0\xD3\x63\xB7\xE4\x11\xAB\xCB\x7\x9B\xA0\xF8\xB6\xAA\x0\x48\xE3\xFB\x94\xD0\x4F\xBA\xBA\x13\xFD\xD7\x83\xEE\x8A\x23\x5\xD\x6F\xED\x8E\x0",
+ "\xFE\x5B\xFC\x13\x90\x6E\xB6\xBB\x74\xA5\xDB\xA2\xAE\xC1\x5\x7\xFA\xAF\xE0\x1B\x0\xEF\xF6\x25\x86\x11\x8B\xDA\x23\x92\x84\x6B\x32\xAB\x0\x6A\xAB\xFB\x5D\xF0\x5F\xBA\xBA\xF7\x6D\xD1\x11\xAE\xA2\x23\x5\xC4\x4F\xE8\xAA\x1",
+ "\xFE\x5B\xFC\x16\x90\x6E\xB2\xBB\x74\xA5\xDB\xA8\xAE\xC1\x4D\x7\xFA\xAF\xE0\x1F\x0\xD3\x63\xB1\xAD\x11\xAF\xC3\x7\xC8\x20\xFB\x6C\xAA\x80\x68\xEB\xFB\x14\xD0\x4F\xBA\xBA\x13\xFD\xD4\x83\xEE\x82\x23\x5\x4D\x6F\xE9\x8E\x0",
+ "\xFE\xFB\xFC\x15\x50\x6E\xA0\xBB\x75\xE5\xDB\xA0\xAE\xC1\x69\x7\xFA\xAF\xE0\xF\x0\xCE\x51\x7E\x69\xCA\xE2\xE4\xF9\x53\x4D\x4C\x7A\xE2\x80\x67\x17\xF8\xB0\x50\x5B\x28\xBA\xD3\xFD\xD0\xCA\xEE\x9C\xF9\x5\xCD\x6F\xEE\xE3\x1",
+ "\xFE\x5B\xFC\x13\x90\x6E\xB6\xBB\x74\xA5\xDB\xA2\xAE\xC1\x5\x7\xFA\xAF\xE0\x1B\x0\xEF\xF6\x24\x8E\x11\x82\xA2\x22\x79\x4\x62\xAE\xAA\x0\x4A\xA3\xFA\x5D\xF0\x53\xBA\xBA\xD7\x6D\xD3\x11\xAE\xA2\x23\x5\x44\x4F\xEA\xAA\x1",
+ "\xFE\x5B\xFC\x13\x90\x6E\xB6\xBB\x74\xA5\xDB\xA2\xAE\xC1\x5\x7\xFA\xAF\xE0\x1B\x0\xEF\xF6\x26\xEC\x11\xB0\xFA\x22\x39\x4\x61\x2A\xAB\x0\x7A\xA3\xFA\xDD\xF0\x53\xBA\xBA\x97\x6D\xD1\x11\xAE\xAA\x23\x5\xC4\x4F\xEE\xAA\x1",
+ "\xFE\x5B\xFC\x16\x90\x6E\xB2\xBB\x74\xA5\xDB\xA8\xAE\xC1\x4D\x7\xFA\xAF\xE0\x1F\x0\xD3\x63\xB6\x2A\x11\x81\x83\x7\x7A\xE0\xFE\xEC\xAA\x80\x58\xE7\xFA\x14\xD0\x43\xBA\xBA\x13\xFD\xD6\x83\xEE\x8A\x23\x5\xCD\x6F\xED\x8E\x0",
+ "\xFE\x5B\xFC\x13\x90\x6E\xB6\xBB\x74\xA5\xDB\xA2\xAE\xC1\x5\x7\xFA\xAF\xE0\x1B\x0\xEF\xF6\x24\x48\x11\xA1\x92\x23\x73\xC4\x6D\x68\xAB\x80\x7A\xAF\xFA\xDD\xF0\x53\xBA\xBA\xF7\x6D\xD0\x11\xAE\xA2\x23\x5\x4\x4F\xE8\xAA\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xB\xAA\x82\xDD\xCA\xAB\x3B\x86\xED\x73\x80\x71\x1B\xFA\xA2\x10\x58\x46\xBA\x8A\xAD\xD3\xAA\xAE\xB5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xAE\xAA\xA5\xB5\xC9\xFB\x3B\x82\x23\x73\x80\x61\x1B\xFB\x22\x10\x58\x46\xBA\xCA\xAD\xD3\xAA\xAE\xBD\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x24\xAA\xBC\xD5\xCB\xFB\xFB\xB4\x69\x73\x80\x61\x1B\xFA\xA2\x10\x58\x46\xBA\xCA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB3\x81\xAA\x89\xF4\xEC\xE2\xDF\x20\xA7\x73\x80\x63\x53\xFB\x6B\x30\x48\x46\xBA\x2E\x3D\xD4\x38\xEE\x95\xDB\x5\xB2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x6E\xAA\xA7\xC5\xCA\x1B\xBB\x94\xAF\x73\x80\x41\x1B\xFB\x22\x10\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xAD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xCB\xAA\x80\xAD\xC9\x4B\xBB\x90\x61\x73\x80\x51\x1B\xFA\xA2\x10\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x0\xAA\x94\xBD\xCA\xF3\x7B\xAC\x6D\x72\x0\x51\x1B\xFA\xA2\x10\x58\x46\xBA\xCA\xAD\xD0\xAA\xAE\xAD\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xA5\xAA\xB3\xD5\xC9\xA3\x7B\xA8\xA3\x72\x0\x41\x1B\xFB\x22\x10\x58\x46\xBA\x8A\xAD\xD0\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x4A\xAA\x8F\xAD\xCB\x13\x3B\x8C\xAB\x72\x0\x71\x1B\xFB\x22\x10\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xBD\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xEF\xAA\xA8\xC5\xC8\x43\x3B\x88\x65\x72\x0\x61\x1B\xFA\xA2\x10\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x65\xAA\xB1\xA5\xCA\x43\xFB\xBE\x2F\x72\x0\x61\x1B\xFB\x22\x10\x54\x46\xBA\xEA\xAD\xD1\xAA\xAE\xB5\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xC0\xAA\x96\xCD\xC9\x13\xFB\xBA\xE1\x72\x0\x71\x1B\xFA\xA2\x10\x54\x46\xBA\xAA\xAD\xD1\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x2F\xAA\xAA\xB5\xCB\xA3\xBB\x9E\xE9\x72\x0\x41\x1B\xFA\xA2\x10\x58\x46\xBA\x8A\xAD\xD3\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x8A\xAA\x8D\xDD\xC8\xF3\xBB\x9A\x27\x72\x0\x51\x1B\xFB\x22\x10\x58\x46\xBA\xCA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x62\xAA\xA6\xE5\xCA\xB3\x7B\xAF\xE9\x73\x0\x61\x1B\xFA\x22\x10\x58\x46\xBA\x8A\xAD\xD2\xAA\xAE\xA5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\xC7\xAA\x93\xC4\xED\xAA\x5F\x3B\x27\x73\x0\x63\x53\xFB\xEB\x30\x48\x46\xBA\x6E\x3D\xD6\x38\xEE\x8D\xDB\x5\x32\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x28\xAA\xBD\xF5\xCB\x53\x3B\x8F\x2F\x73\x0\x41\x1B\xFB\xA2\x10\x54\x46\xBA\xEA\xAD\xD0\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x8D\xAA\x9A\x9D\xC8\x3\x3B\x8B\xE1\x73\x0\x51\x1B\xFA\x22\x10\x54\x46\xBA\xAA\xAD\xD0\xAA\xAE\xBD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x7\xAA\x83\xFD\xCA\x3\xFB\xBD\xAB\x73\x0\x51\x1B\xFB\xA2\x10\x54\x46\xBA\xAA\xAD\xD3\xAA\xAE\xBD\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xA2\xAA\xA4\x95\xC9\x53\xFB\xB9\x65\x73\x0\x41\x1B\xFA\x22\x10\x54\x46\xBA\xEA\xAD\xD3\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x4D\xAA\x98\xED\xCB\xE3\xBB\x9D\x6D\x73\x0\x71\x1B\xFA\x22\x10\x58\x46\xBA\xCA\xAD\xD1\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xE8\xAA\xBF\x85\xC8\xB3\xBB\x99\xA3\x73\x0\x61\x1B\xFB\xA2\x10\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xA5\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x49\xAA\x90\xB5\xCA\xA0\xFB\xAF\xB7\x72\x80\x71\x13\xFA\x22\x10\x58\x46\xBA\xCA\xAD\xD3\xAA\xAE\xA5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x50\xC4\x49\x39\xE5\x2A\x7A\xC3\x48\xF7\x4A\x0\x6F\x2B\xFA\x2C\x30\x4B\xC8\xBA\xE9\x25\xD7\x49\x2E\xB5\x39\x5\x83\x6F\xE9\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x3\xAA\x8B\xA5\xCB\x40\xBB\x8F\x71\x72\x80\x51\x13\xFB\xA2\x10\x54\x46\xBA\xAA\xAD\xD1\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xA6\xAA\xAC\xCD\xC8\x10\xBB\x8B\xBF\x72\x80\x41\x13\xFA\x22\x10\x54\x46\xBA\xEA\xAD\xD1\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x2C\xAA\xB5\xAD\xCA\x10\x7B\xBD\xF5\x72\x80\x41\x13\xFB\xA2\x10\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xBD\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x89\xAA\x92\xC5\xC9\x40\x7B\xB9\x3B\x72\x80\x51\x13\xFA\x22\x10\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x66\xAA\xBC\xF4\xEF\xB9\x1F\xD\x33\x72\x80\x73\x5B\xFA\x6B\x30\x48\x46\xBA\x2E\x3D\xD4\x38\xEE\x8D\xDB\x5\x32\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xC3\xAA\x89\xD5\xC8\xA0\x3B\x99\xFD\x72\x80\x71\x13\xFB\xA2\x10\x58\x46\xBA\xCA\xAD\xD0\xAA\xAE\xA5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x2B\xAA\xA2\xED\xCA\xE0\xFB\xAC\x33\x73\x80\x41\x13\xFA\xA2\x10\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xAD\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x8E\xAA\x85\x85\xC9\xB0\xFB\xA8\xFD\x73\x80\x51\x13\xFB\x22\x10\x58\x46\xBA\xCA\xAD\xD1\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x61\xAA\xAB\xB4\xEF\x49\x9F\x1C\xF5\x73\x80\x73\x5B\xFB\x6B\x30\x44\x46\xBA\x4E\x3D\xD7\x38\xEE\x9D\xDB\x5\x72\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xC4\xAA\x9E\x95\xC8\x50\xBB\x88\x3B\x73\x80\x71\x13\xFA\xA2\x10\x54\x46\xBA\xAA\xAD\xD3\xAA\xAE\xB5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x4E\xAA\x87\xF5\xCA\x50\x7B\xBE\x71\x73\x80\x71\x13\xFB\x22\x10\x54\x46\xBA\xAA\xAD\xD0\xAA\xAE\xB5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\xEB\xAA\xB2\xD4\xED\x49\x5F\x2A\xBF\x73\x80\x73\x5B\xFA\xEB\x30\x44\x46\xBA\x4E\x3D\xD4\x38\xEE\x9D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\x4\xAA\x8E\xAC\xEF\xF9\x1F\xE\xB7\x73\x80\x43\x5B\xFA\xEB\x30\x48\x46\xBA\x6E\x3D\xD6\x38\xEE\x85\xDB\x5\xB2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\xA1\xAA\xA9\xC4\xEC\xA9\x1F\xA\x79\x73\x80\x53\x5B\xFB\x6B\x30\x48\x46\xBA\x2E\x3D\xD6\x38\xEE\x8D\xDB\x5\x72\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x6A\xAA\xAF\x9D\xCB\x58\xFB\xA6\x75\x72\x0\x41\x13\xFB\x22\x10\x54\x46\xBA\xAA\xAD\xD0\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xCF\xAA\x88\xF5\xC8\x8\xFB\xA2\xBB\x72\x0\x51\x13\xFA\xA2\x10\x54\x46\xBA\xEA\xAD\xD0\xAA\xAE\xAD\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x20\xAA\xB4\x8D\xCA\xB8\xBB\x86\xB3\x72\x0\x61\x13\xFA\xA2\x10\x58\x46\xBA\xCA\xAD\xD2\xAA\xAE\xB5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\xFB\xFC\x12\x90\x6E\x98\xBB\x74\xE5\xDB\xA2\xAE\xC1\xD\x7\xFA\xAF\xE0\x1F\x0\xDA\x6A\xC\x6A\x55\x54\xF9\xB8\x5A\x60\xE7\x28\x27\x0\x5C\xA7\xF8\x3E\x70\x47\xB9\xBA\xFB\x6D\xD5\xC7\x2E\x88\x8F\x5\x8D\x5F\xEB\x7\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xF\xAA\x8A\x85\xCB\xE8\x7B\xB4\x37\x72\x0\x71\x13\xFA\xA2\x10\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xBD\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xAA\xAA\xAD\xED\xC8\xB8\x7B\xB0\xF9\x72\x0\x61\x13\xFB\x22\x10\x58\x46\xBA\xCA\xAD\xD1\xAA\xAE\xB5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x7B\xFC\x12\x90\x6E\x90\xBB\x75\xE5\xDB\xAB\xAE\xC1\x15\x7\xFA\xAF\xE0\xF\x0\xC7\x48\xC0\xAA\x55\x5F\xAD\x29\xA2\x81\x71\xA4\x27\x0\x7F\xAB\xFA\xAC\x30\x5B\xB9\xBA\x9\x25\xD1\x41\x2E\x98\x8F\x5\x81\x6F\xEF\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xE0\xAA\xB6\xFD\xC9\x58\x3B\x90\x3F\x72\x0\x41\x13\xFA\xA2\x10\x54\x46\xBA\xAA\xAD\xD3\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x8\xAA\x9D\xC5\xCB\x18\xFB\xA5\xF1\x73\x0\x71\x13\xFB\xA2\x10\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xAD\xAA\xBA\xAD\xC8\x48\xFB\xA1\x3F\x73\x0\x61\x13\xFA\x22\x10\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xA5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x42\xAA\x86\xD5\xCA\xF8\xBB\x85\x37\x73\x0\x51\x13\xFA\x22\x10\x58\x46\xBA\x8A\xAD\xD0\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xE7\xAA\xA1\xBD\xC9\xA8\xBB\x81\xF9\x73\x0\x41\x13\xFB\xA2\x10\x58\x46\xBA\xCA\xAD\xD0\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\x6D\xAA\xAA\x94\xEF\xE1\x5F\x27\xB3\x73\x0\x53\x5B\xFA\x6B\x30\x48\x46\xBA\x6E\x3D\xD7\x38\xEE\x95\xDB\x5\x32\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xC8\xAA\x8D\xFC\xEC\xB1\x5F\x23\x7D\x73\x0\x43\x5B\xFB\xEB\x30\x48\x46\xBA\x2E\x3D\xD7\x38\xEE\x9D\xDB\x5\xF2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x27\xAA\xA3\xCD\xCA\x48\x3B\x97\x75\x73\x0\x61\x13\xFB\xA2\x10\x54\x46\xBA\xAA\xAD\xD1\xAA\xAE\xA5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x82\xAA\x84\xA5\xC9\x18\x3B\x93\xBB\x73\x0\x71\x13\xFA\x22\x10\x54\x46\xBA\xEA\xAD\xD1\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xCE\xAA\xBE\xF5\xCA\x12\x3B\xAA\x37\x72\x80\x41\x1F\xFB\x22\x10\x54\x46\xBA\xCA\xAD\xD1\xAA\xAE\xAD\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\x6B\xAA\x8B\xD4\xED\xB\x1F\x3E\xF9\x72\x80\x43\x57\xFA\xEB\x30\x44\x46\xBA\x2E\x3D\xD5\x38\xEE\x85\xDB\x5\x72\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x84\xAA\xA5\xE5\xCB\xF2\x7B\x8A\xF1\x72\x80\x61\x1F\xFA\xA2\x10\x58\x46\xBA\xAA\xAD\xD3\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x57\x9\x49\xC\xB5\x2B\x28\x43\x6D\xB1\x4A\x0\x7F\x27\xFA\xAC\x30\x4B\xC8\xBA\x89\x25\xD7\x49\x2E\xAD\x39\x5\xC3\x6F\xEF\x4E\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xAB\xAA\x89\xA4\xEE\xEB\x9F\x28\x75\x72\x80\x63\x57\xFA\xEB\x30\x48\x46\xBA\x4E\x3D\xD4\x38\xEE\x95\xDB\x5\x72\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xE\xAA\xAE\xCC\xED\xBB\x9F\x2C\xBB\x72\x80\x73\x57\xFB\x6B\x30\x48\x46\xBA\xE\x3D\xD4\x38\xEE\x9D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xE1\xAA\x80\xFD\xCB\x42\xFB\x98\xB3\x72\x80\x51\x1F\xFB\x22\x10\x54\x46\xBA\x8A\xAD\xD2\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x44\xAA\xA7\x95\xC8\x12\xFB\x9C\x7D\x72\x80\x41\x1F\xFA\xA2\x10\x54\x46\xBA\xCA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xAC\xAA\x8C\xAD\xCA\x52\x3B\xA9\xB3\x73\x80\x71\x1F\xFB\xA2\x10\x54\x46\xBA\x8A\xAD\xD3\xAA\xAE\xA5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x9\xAA\xAB\xC5\xC9\x2\x3B\xAD\x7D\x73\x80\x61\x1F\xFA\x22\x10\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xE6\xAA\x97\xBD\xCB\xB2\x7B\x89\x75\x73\x80\x51\x1F\xFA\x22\x10\x58\x46\xBA\xEA\xAD\xD1\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x43\xAA\xB0\xD5\xC8\xE2\x7B\x8D\xBB\x73\x80\x41\x1F\xFB\xA2\x10\x58\x46\xBA\xAA\xAD\xD1\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xC9\xAA\xA9\xB5\xCA\xE2\xBB\xBB\xF1\x73\x80\x41\x1F\xFA\x22\x10\x58\x46\xBA\xAA\xAD\xD2\xAA\xAE\xBD\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x6C\xAA\x8E\xDD\xC9\xB2\xBB\xBF\x3F\x73\x80\x51\x1F\xFB\xA2\x10\x58\x46\xBA\xEA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x83\xAA\xB2\xA5\xCB\x2\xFB\x9B\x37\x73\x80\x61\x1F\xFB\xA2\x10\x54\x46\xBA\xCA\xAD\xD0\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\xFB\xFC\x12\x90\x6E\x98\xBB\x74\xE5\xDB\xA2\xAE\xC1\xD\x7\xFA\xAF\xE0\x1F\x0\xDA\x6A\x8\xC9\x55\x52\xD1\xB9\xE0\x20\xFA\xAC\x26\x80\x5C\xAB\xF9\x3E\x70\x4B\xB9\xBA\xFB\x6D\xD7\xC7\x2E\x90\x8F\x5\xD\x5F\xE9\x7\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xED\xAA\x81\xDD\xCB\xEA\x3B\xA3\xF5\x72\x0\x71\x1F\xFA\x22\x10\x58\x46\xBA\xAA\xAD\xD2\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x48\xAA\xA6\xB5\xC8\xBA\x3B\xA7\x3B\x72\x0\x61\x1F\xFB\xA2\x10\x58\x46\xBA\xEA\xAD\xD2\xAA\xAE\xA5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xA7\xAA\x9A\xCD\xCA\xA\x7B\x83\x33\x72\x0\x51\x1F\xFB\xA2\x10\x54\x46\xBA\xCA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x2\xAA\xAF\xEC\xED\x13\x5F\x17\xFD\x72\x0\x53\x57\xFA\x6B\x30\x44\x46\xBA\x2E\x3D\xD4\x38\xEE\x95\xDB\x5\xF2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x88\xAA\xA4\xC5\xCB\x5A\xBB\xB1\xB7\x72\x0\x41\x1F\xFB\xA2\x10\x54\x46\xBA\x8A\xAD\xD3\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x2D\xAA\x83\xAD\xC8\xA\xBB\xB5\x79\x72\x0\x51\x1F\xFA\x22\x10\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xBD\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\xC2\xAA\xAD\x9C\xEE\xF3\xDF\x1\x71\x72\x0\x73\x57\xFA\x6B\x30\x48\x46\xBA\x4E\x3D\xD5\x38\xEE\x85\xDB\x5\xF2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\x67\xAA\x8A\xF4\xED\xA3\xDF\x5\xBF\x72\x0\x63\x57\xFB\xEB\x30\x48\x46\xBA\xE\x3D\xD5\x38\xEE\x8D\xDB\x5\x32\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB6\x8F\xAA\xA1\xCC\xEF\xE3\x1F\x30\x71\x73\x0\x53\x57\xFA\xEB\x30\x48\x46\xBA\x4E\x3D\xD4\x38\xEE\x85\xDB\x5\x72\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x2A\xAA\x94\xED\xC8\xFA\x3B\xA4\xBF\x73\x0\x51\x1F\xFB\x22\x10\x58\x46\xBA\xAA\xAD\xD0\xAA\xAE\xAD\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xC5\xAA\xA8\x95\xCA\x4A\x7B\x80\xB7\x73\x0\x61\x1F\xFB\x22\x10\x54\x46\xBA\x8A\xAD\xD2\xAA\xAE\xB5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x60\xAA\x8F\xFD\xC9\x1A\x7B\x84\x79\x73\x0\x71\x1F\xFA\xA2\x10\x54\x46\xBA\xCA\xAD\xD2\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xEA\xAA\x96\x9D\xCB\x1A\xBB\xB2\x33\x73\x0\x71\x1F\xFB\x22\x10\x54\x46\xBA\xCA\xAD\xD1\xAA\xAE\xBD\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x4F\xAA\xA3\xBC\xEC\x3\x9F\x26\xFD\x73\x0\x73\x57\xFA\xEB\x30\x44\x46\xBA\x2E\x3D\xD5\x38\xEE\x95\xDB\x5\x72\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xA0\xAA\x8D\x8D\xCA\xFA\xFB\x92\xF5\x73\x0\x51\x1F\xFA\xA2\x10\x58\x46\xBA\xAA\xAD\xD3\xAA\xAE\xAD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x5\xAA\xAA\xE5\xC9\xAA\xFB\x96\x3B\x73\x0\x41\x1F\xFB\x22\x10\x58\x46\xBA\xEA\xAD\xD3\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xA4\xAA\x85\xD5\xCB\xB9\xBB\xA0\x2F\x72\x80\x51\x17\xFA\xA2\x10\x58\x46\xBA\xAA\xAD\xD1\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x1\xAA\xA2\xBD\xC8\xE9\xBB\xA4\xE1\x72\x80\x41\x17\xFB\x22\x10\x58\x46\xBA\xEA\xAD\xD1\xAA\xAE\xAD\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xEE\xAA\x9E\xC5\xCA\x59\xFB\x80\xE9\x72\x80\x71\x17\xFB\x22\x10\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xB5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x8B\xFC\x16\x90\x6E\xBE\xBB\x75\x55\xDB\xA7\xAE\xC1\x55\x7\xFA\xAF\xE0\x0\x0\xCE\x9\x7F\xED\x71\xD4\x9B\x13\x9B\xB2\xA0\xB5\x3B\x80\x4C\xA3\xF9\xCF\xB0\x50\xD4\xBA\xAE\x3D\xD1\x71\xEE\x8B\x1\x5\xB2\xAF\xED\x3F\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\x27\xAA\xA4\xCC\xEA\xB2\xDF\x2D\x23\x73\x80\x73\x53\xFB\xEB\x70\x48\x46\xBA\x6E\x3D\xD4\x38\xEE\x8D\xDB\x5\xF2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x64\xAA\x3D\xBD\xCE\x79\x3B\xB3\x79\x73\x80\x71\x1B\xFA\x22\x50\x5C\x46\xBA\xAA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x4C\xAA\xF3\xED\xCE\x6A\xFB\xB0\x2F\x73\x80\x41\x1B\xFB\x22\x50\x5C\x46\xBA\xAA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\xF\xAA\x6A\x9C\xEA\xA1\x1F\x2E\x75\x73\x80\x43\x53\xFA\xEB\x70\x48\x46\xBA\x6E\x3D\xD5\x38\xEE\x85\xDB\x5\xF2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xED\xAA\x9F\xBD\xC9\x3B\x3B\xB5\x7B\x73\x80\x41\x1B\xFB\x22\x50\x50\x46\xBA\xAA\xAD\xD1\xAA\xAE\xB5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xAE\xAA\x14\x85\xC9\xB9\xFB\xBB\x21\x73\x80\x51\x1B\xFA\xA2\x50\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xBD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x86\xAA\xDA\xD5\xC9\xAA\x3B\xB8\x77\x73\x80\x61\x1B\xFB\xA2\x50\x54\x46\xBA\xCA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xC5\xAA\x51\xED\xC9\x28\xFB\xB6\x2D\x73\x80\x71\x1B\xFA\x22\x50\x50\x46\xBA\xAA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x53\xAA\x49\x1F\xD5\x2E\x21\xC3\x5A\x63\x4B\x0\x7F\x23\xFB\xAC\x70\x4B\xC8\xBA\xE9\x25\xD4\x49\x2E\xBD\x39\x5\x43\x6F\xEF\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xC1\xAA\x1A\xD5\xCD\x29\x3B\xB7\xB7\x73\x80\x61\x1B\xFB\xA2\x50\x5C\x46\xBA\xEA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\xE9\xAA\xC6\xCC\xE9\x73\xDF\x24\xE1\x73\x80\x43\x53\xFA\xEB\x70\x4C\x46\xBA\x4E\x3D\xD7\x38\xEE\x85\xDB\x5\x32\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xAA\xAA\x5F\xBD\xCD\xB8\x3B\xBA\xBB\x73\x80\x41\x1B\xFB\x22\x50\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x2\xAA\xA3\xC5\xCB\x8B\x7B\x91\x73\x73\x80\x71\x1B\xFB\x22\x50\x5C\x46\xBA\x8A\xAD\xD3\xAA\xAE\xAD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x41\xAA\x28\xFD\xCB\x9\xBB\x9F\x29\x73\x80\x61\x1B\xFA\xA2\x50\x58\x46\xBA\xEA\xAD\xD1\xAA\xAE\xA5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x69\xAA\xE6\xAD\xCB\x1A\x7B\x9C\x7F\x73\x80\x51\x1B\xFB\xA2\x50\x58\x46\xBA\xEA\xAD\xD0\xAA\xAE\xAD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x2A\xAA\x6D\x95\xCB\x98\xBB\x92\x25\x73\x80\x41\x1B\xFA\x22\x50\x5C\x46\xBA\x8A\xAD\xD2\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x6D\xAA\xAD\x95\xCF\x1B\xBB\x9D\xE5\x73\x80\x41\x1B\xFA\x22\x50\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x2E\xAA\x26\xAD\xCF\x99\x7B\x93\xBF\x73\x80\x51\x1B\xFB\xA2\x50\x50\x46\xBA\xCA\xAD\xD0\xAA\xAE\xB5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x6\xAA\xE8\xFD\xCF\x8A\xBB\x90\xE9\x73\x80\x61\x1B\xFA\xA2\x50\x50\x46\xBA\xCA\xAD\xD1\xAA\xAE\xBD\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x45\xAA\x63\xC5\xCF\x8\x7B\x9E\xB3\x73\x80\x71\x1B\xFB\x22\x50\x54\x46\xBA\xAA\xAD\xD3\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xA7\xAA\x84\xAD\xC8\xDB\x7B\x95\xBD\x73\x80\x61\x1B\xFA\xA2\x50\x5C\x46\xBA\xCA\xAD\xD3\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\xE4\xAA\x1D\xDC\xEC\x10\x9F\xB\xE7\x73\x80\x63\x53\xFB\x6B\x70\x48\x46\xBA\xE\x3D\xD5\x38\xEE\x8D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xCC\xAA\xC1\xC5\xC8\x4A\x7B\x98\xB1\x73\x80\x41\x1B\xFA\x22\x50\x58\x46\xBA\xAA\xAD\xD0\xAA\xAE\xA5\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x8F\xAA\x4A\xFD\xC8\xC8\xBB\x96\xEB\x73\x80\x51\x1B\xFB\xA2\x50\x5C\x46\xBA\xCA\xAD\xD2\xAA\xAE\xAD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xC8\xAA\x8A\xFD\xCC\x4B\xBB\x99\x2B\x73\x80\x51\x1B\xFB\xA2\x50\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x8B\xFC\x16\x90\x6E\xBE\xBB\x75\x55\xDB\xA7\xAE\xC1\x55\x7\xFA\xAF\xE0\x0\x0\xCE\x9\x7E\x2D\x71\x6C\xF3\x16\x5B\x32\xB3\xE3\x3A\x80\x6C\xAF\xF9\x4F\xF0\x54\xD4\xBA\xAE\x3D\xD2\x71\xEE\x8B\x1\x5\xF2\xAF\xED\x3F\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xA3\xAA\xCF\x95\xCC\xDA\xBB\x94\x27\x73\x80\x71\x1B\xFB\x22\x50\x50\x46\xBA\x8A\xAD\xD1\xAA\xAE\xB5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xE0\xAA\x44\xAD\xCC\x58\x7B\x9A\x7D\x73\x80\x61\x1B\xFA\xA2\x50\x54\x46\xBA\xEA\xAD\xD3\xAA\xAE\xBD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\x6C\xAA\x82\xF4\xEF\x2A\x9F\x39\xB1\x72\x0\x73\x53\xFA\xEB\x70\x40\x46\xBA\x4E\x3D\xD5\x38\xEE\x8D\xDB\x5\xB2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\x2F\xAA\x9\xCC\xEF\xA8\x5F\x37\xEB\x72\x0\x63\x53\xFB\x6B\x70\x44\x46\xBA\x2E\x3D\xD7\x38\xEE\x85\xDB\x5\xB2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\x7\xAA\xC7\x9C\xEF\xBB\x9F\x34\xBD\x72\x0\x53\x53\xFA\x6B\x70\x44\x46\xBA\x2E\x3D\xD6\x38\xEE\x8D\xDB\x5\xB2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB3\x44\xAA\x4C\xA4\xEF\x39\x5F\x3A\xE7\x72\x0\x43\x53\xFB\xEB\x70\x40\x46\xBA\x4E\x3D\xD4\x38\xEE\x85\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x3\xAA\x9E\xED\xCF\xF3\x7B\xA5\x27\x72\x0\x51\x1B\xFB\xA2\x50\x58\x46\xBA\xCA\xAD\xD0\xAA\xAE\xBD\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x40\xAA\x15\xD5\xCF\x71\xBB\xAB\x7D\x72\x0\x41\x1B\xFA\x22\x50\x5C\x46\xBA\xAA\xAD\xD2\xAA\xAE\xB5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x68\xAA\xDB\x85\xCF\x62\x7B\xA8\x2B\x72\x0\x71\x1B\xFB\x22\x50\x5C\x46\xBA\xAA\xAD\xD3\xAA\xAE\xBD\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x2B\xAA\x50\xBD\xCF\xE0\xBB\xA6\x71\x72\x0\x61\x1B\xFA\xA2\x50\x58\x46\xBA\xCA\xAD\xD1\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\xC9\xAA\xA5\x9C\xEC\x7A\x9F\x3D\x7F\x72\x0\x63\x53\xFB\x6B\x70\x40\x46\xBA\xE\x3D\xD5\x38\xEE\x85\xDB\x5\x72\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x8A\xAA\x3C\xED\xC8\xB1\x7B\xA3\x25\x72\x0\x61\x1B\xFA\xA2\x50\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xAD\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xA2\xAA\xF2\xBD\xC8\xA2\xBB\xA0\x73\x72\x0\x51\x1B\xFB\xA2\x50\x54\x46\xBA\xCA\xAD\xD2\xAA\xAE\xA5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x8B\xFC\x16\x90\x6E\xBE\xBB\x75\x55\xDB\xA7\xAE\xC1\x55\x7\xFA\xAF\xE0\x0\x0\xCE\x9\x7E\x47\x71\x14\xB3\x12\xB2\x32\x8A\xBB\x3B\x0\x6C\xAF\xF9\x4F\xF0\x54\xD4\xBA\x8E\x3D\xD2\x71\xEE\x9B\x1\x5\x72\xAF\xEF\x3F\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB6\xA6\xAA\xAB\xCC\xE8\xEA\x5F\x31\xE9\x72\x0\x53\x53\xFA\x6B\x70\x48\x46\xBA\x2E\x3D\xD4\x38\xEE\x95\xDB\x5\x32\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xE5\xAA\x32\xBD\xCC\x21\xBB\xAF\xB3\x72\x0\x51\x1B\xFB\xA2\x50\x5C\x46\xBA\xEA\xAD\xD2\xAA\xAE\xBD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xCD\xAA\xFC\xED\xCC\x32\x7B\xAC\xE5\x72\x0\x61\x1B\xFA\xA2\x50\x5C\x46\xBA\xEA\xAD\xD3\xAA\xAE\xB5\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x8E\xAA\x77\xD5\xCC\xB0\xBB\xA2\xBF\x72\x0\x71\x1B\xFB\x22\x50\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xBD\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\x26\xAA\x99\xE4\xEE\xCA\xDF\x19\x77\x72\x0\x53\x53\xFB\x6B\x70\x4C\x46\xBA\x2E\x3D\xD7\x38\xEE\x9D\xDB\x5\x72\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\x65\xAA\x12\xDC\xEE\x48\x1F\x17\x2D\x72\x0\x43\x53\xFA\xEB\x70\x48\x46\xBA\x4E\x3D\xD5\x38\xEE\x95\xDB\x5\x72\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x4D\xAA\xCE\xC5\xCA\x12\xFB\x84\x7B\x72\x0\x61\x1B\xFB\xA2\x50\x58\x46\xBA\xEA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xE\xAA\x45\xFD\xCA\x90\x3B\x8A\x21\x72\x0\x71\x1B\xFA\x22\x50\x5C\x46\xBA\x8A\xAD\xD2\xAA\xAE\xB5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x49\xAA\x85\xFD\xCE\x13\x3B\x85\xE1\x72\x0\x71\x1B\xFA\x22\x50\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xA\xAA\xE\xC5\xCE\x91\xFB\x8B\xBB\x72\x0\x61\x1B\xFB\xA2\x50\x50\x46\xBA\xCA\xAD\xD0\xAA\xAE\xA5\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x22\xAA\xD2\xDC\xEA\xCB\x1F\x18\xED\x72\x0\x43\x53\xFA\xEB\x70\x40\x46\xBA\x6E\x3D\xD5\x38\xEE\x8D\xDB\x5\x32\xAF\xE8\x52\x0",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x54\x49\x49\xC5\x95\x2D\x8A\xC3\x65\x39\x4A\x80\x4F\x23\xFA\xAC\x70\x47\xC8\xBA\xC9\x25\xD7\x49\x2E\xBD\x39\x5\x43\x6F\xEB\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x83\xAA\xAC\xC5\xC9\xD3\xFB\x8D\xB9\x72\x0\x51\x1B\xFA\xA2\x50\x5C\x46\xBA\xCA\xAD\xD3\xAA\xAE\xB5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\xC0\xAA\x35\xB4\xED\x18\x1F\x13\xE3\x72\x0\x53\x53\xFB\x6B\x70\x48\x46\xBA\xE\x3D\xD5\x38\xEE\x9D\xDB\x5\xB2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xE8\xAA\xE9\xAD\xC9\x42\xFB\x80\xB5\x72\x0\x71\x1B\xFA\x22\x50\x58\x46\xBA\xAA\xAD\xD0\xAA\xAE\xB5\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x55\x83\x49\xEC\xAD\x2A\x4A\x3\x6D\x61\x4A\x80\x6F\x23\xFA\x2C\x70\x4F\xC8\xBA\xA9\x25\xD6\x49\x2E\xA5\x39\x5\xC3\x6F\xE9\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xEC\xAA\xA2\x95\xCD\x43\x3B\x81\x2F\x72\x0\x61\x1B\xFB\xA2\x50\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x56\x87\x49\xA7\x95\x2E\x4B\xC3\x6C\xFB\x4A\x80\x7F\x23\xFB\xAC\x70\x43\xC8\xBA\xE9\x25\xD4\x49\x2E\xB5\x39\x5\x83\x6F\xEF\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x87\xAA\xE7\xFD\xCD\xD2\x3B\x8C\x23\x72\x0\x41\x1B\xFB\x22\x50\x50\x46\xBA\x8A\xAD\xD1\xAA\xAE\xA5\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xC4\xAA\x6C\xC5\xCD\x50\xFB\x82\x79\x72\x0\x51\x1B\xFA\xA2\x50\x54\x46\xBA\xEA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x9\xAA\xB5\xA5\xCB\xD3\x3B\xBB\xF3\x72\x0\x51\x1B\xFB\x22\x50\x5C\x46\xBA\xCA\xAD\xD0\xAA\xAE\xB5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\x4A\xAA\x2C\xD4\xEF\x18\xDF\x25\xA9\x72\x0\x53\x53\xFA\xEB\x70\x48\x46\xBA\xE\x3D\xD6\x38\xEE\x9D\xDB\x5\x72\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x62\xAA\xF0\xCD\xCB\x42\x3B\xB6\xFF\x72\x0\x71\x1B\xFB\xA2\x50\x58\x46\xBA\xAA\xAD\xD3\xAA\xAE\xB5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x51\x9\x49\xF5\xCD\x28\x4A\xC3\x5B\x2B\x4A\x80\x6F\x23\xFB\xAC\x70\x4F\xC8\xBA\xA9\x25\xD5\x49\x2E\xA5\x39\x5\x3\x6F\xED\x4E\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x66\xAA\xA9\xBC\xEB\xA\xDF\x27\x65\x72\x0\x73\x53\xFA\x6B\x70\x44\x46\xBA\x4E\x3D\xD5\x38\xEE\x85\xDB\x5\x32\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x25\xAA\x30\xCD\xCF\xC1\x3B\xB9\x3F\x72\x0\x71\x1B\xFB\xA2\x50\x50\x46\xBA\x8A\xAD\xD3\xAA\xAE\xAD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xD\xAA\xFE\x9D\xCF\xD2\xFB\xBA\x69\x72\x0\x41\x1B\xFA\xA2\x50\x50\x46\xBA\x8A\xAD\xD2\xAA\xAE\xA5\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB6\x4E\xAA\x67\xEC\xEB\x19\x1F\x24\x33\x72\x0\x43\x53\xFB\x6B\x70\x44\x46\xBA\x4E\x3D\xD4\x38\xEE\x8D\xDB\x5\x32\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB3\xAC\xAA\x80\x84\xEC\xCA\x1F\x2F\x3D\x72\x0\x53\x53\xFA\xEB\x70\x4C\x46\xBA\x2E\x3D\xD4\x38\xEE\x9D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xEF\xAA\xB\xBC\xEC\x48\xDF\x21\x67\x72\x0\x43\x53\xFB\x6B\x70\x48\x46\xBA\x4E\x3D\xD6\x38\xEE\x95\xDB\x5\xB2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\xC7\xAA\xC5\xEC\xEC\x5B\x1F\x22\x31\x72\x0\x73\x53\xFA\x6B\x70\x48\x46\xBA\x4E\x3D\xD7\x38\xEE\x9D\xDB\x5\xB2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\x84\xAA\x4E\xD4\xEC\xD9\xDF\x2C\x6B\x72\x0\x63\x53\xFB\xEB\x70\x4C\x46\xBA\x2E\x3D\xD5\x38\xEE\x95\xDB\x5\xB2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xC3\xAA\x9C\x9D\xCC\x13\xFB\xB3\xAB\x72\x0\x71\x1B\xFB\xA2\x50\x54\x46\xBA\xAA\xAD\xD1\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x80\xAA\x17\xA5\xCC\x91\x3B\xBD\xF1\x72\x0\x61\x1B\xFA\x22\x50\x50\x46\xBA\xCA\xAD\xD3\xAA\xAE\xA5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xA8\xAA\xD9\xF5\xCC\x82\xFB\xBE\xA7\x72\x0\x51\x1B\xFB\x22\x50\x50\x46\xBA\xCA\xAD\xD2\xAA\xAE\xAD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xEB\xAA\x52\xCD\xCC\x0\x3B\xB0\xFD\x72\x0\x41\x1B\xFA\xA2\x50\x54\x46\xBA\xAA\xAD\xD0\xAA\xAE\xA5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x43\xAA\xAE\xB5\xCA\x33\x7B\x9B\x35\x72\x0\x71\x1B\xFA\xA2\x50\x50\x46\xBA\xAA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x0\xAA\x25\x8D\xCA\xB1\xBB\x95\x6F\x72\x0\x61\x1B\xFB\x22\x50\x54\x46\xBA\xCA\xAD\xD0\xAA\xAE\xAD\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x28\xAA\xEB\xDD\xCA\xA2\x7B\x96\x39\x72\x0\x51\x1B\xFA\x22\x50\x54\x46\xBA\xCA\xAD\xD1\xAA\xAE\xA5\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x6B\xAA\x60\xE5\xCA\x20\xBB\x98\x63\x72\x0\x41\x1B\xFB\xA2\x50\x50\x46\xBA\xAA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x2C\xAA\xA0\xE5\xCE\xA3\xBB\x97\xA3\x72\x0\x41\x1B\xFB\xA2\x50\x58\x46\xBA\x8A\xAD\xD3\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x6F\xAA\x39\x94\xEA\x68\x5F\x9\xF9\x72\x0\x43\x53\xFA\x6B\x70\x4C\x46\xBA\x4E\x3D\xD5\x38\xEE\x9D\xDB\x5\xF2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x47\xAA\xE5\x8D\xCE\x32\xBB\x9A\xAF\x72\x0\x61\x1B\xFB\x22\x50\x5C\x46\xBA\xEA\xAD\xD0\xAA\xAE\xB5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x4\xAA\x6E\xB5\xCE\xB0\x7B\x94\xF5\x72\x0\x71\x1B\xFA\xA2\x50\x58\x46\xBA\x8A\xAD\xD2\xAA\xAE\xBD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xE6\xAA\x89\xDD\xC9\x63\x7B\x9F\xFB\x72\x0\x61\x1B\xFB\x22\x50\x50\x46\xBA\xEA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xA5\xAA\x2\xE5\xC9\xE1\xBB\x91\xA1\x72\x0\x71\x1B\xFA\xA2\x50\x54\x46\xBA\x8A\xAD\xD0\xAA\xAE\xA5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x8D\xAA\xCC\xB5\xC9\xF2\x7B\x92\xF7\x72\x0\x41\x1B\xFB\xA2\x50\x54\x46\xBA\x8A\xAD\xD1\xAA\xAE\xAD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xCE\xAA\x47\x8D\xC9\x70\xBB\x9C\xAD\x72\x0\x51\x1B\xFA\x22\x50\x50\x46\xBA\xEA\xAD\xD3\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x89\xAA\x87\x8D\xCD\xF3\xBB\x93\x6D\x72\x0\x51\x1B\xFA\x22\x50\x58\x46\xBA\xCA\xAD\xD3\xAA\xAE\xBD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xCA\xAA\xC\xB5\xCD\x71\x7B\x9D\x37\x72\x0\x41\x1B\xFB\xA2\x50\x5C\x46\xBA\xAA\xAD\xD1\xAA\xAE\xB5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xE2\xAA\xC2\xE5\xCD\x62\xBB\x9E\x61\x72\x0\x71\x1B\xFA\xA2\x50\x5C\x46\xBA\xAA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xA1\xAA\x49\xDD\xCD\xE0\x7B\x90\x3B\x72\x0\x61\x1B\xFB\x22\x50\x58\x46\xBA\xCA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xE\xAA\xA2\xE5\xCB\x23\xBB\xAA\x35\x73\x0\x51\x1B\xFA\x22\x50\x50\x46\xBA\xAA\xAD\xD3\xAA\xAE\xA5\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x4D\xAA\x29\xDD\xCB\xA1\x7B\xA4\x6F\x73\x0\x41\x1B\xFB\xA2\x50\x54\x46\xBA\xCA\xAD\xD1\xAA\xAE\xAD\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x65\xAA\xE7\x8D\xCB\xB2\xBB\xA7\x39\x73\x0\x71\x1B\xFA\xA2\x50\x54\x46\xBA\xCA\xAD\xD0\xAA\xAE\xA5\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x26\xAA\x6C\xB5\xCB\x30\x7B\xA9\x63\x73\x0\x61\x1B\xFB\x22\x50\x50\x46\xBA\xAA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x61\xAA\xAC\xB5\xCF\xB3\x7B\xA6\xA3\x73\x0\x61\x1B\xFB\x22\x50\x58\x46\xBA\x8A\xAD\xD2\xAA\xAE\xB5\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x22\xAA\x35\xC4\xEB\x78\x9F\x38\xF9\x73\x0\x63\x53\xFA\xEB\x70\x4C\x46\xBA\x4E\x3D\xD4\x38\xEE\x9D\xDB\x5\x72\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xA\xAA\xE9\xDD\xCF\x22\x7B\xAB\xAF\x73\x0\x41\x1B\xFB\xA2\x50\x5C\x46\xBA\xEA\xAD\xD1\xAA\xAE\xB5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x49\xAA\x62\xE5\xCF\xA0\xBB\xA5\xF5\x73\x0\x51\x1B\xFA\x22\x50\x58\x46\xBA\x8A\xAD\xD3\xAA\xAE\xBD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xAB\xAA\x97\xC4\xEC\x3A\x9F\x3E\xFB\x73\x0\x53\x53\xFB\xEB\x70\x40\x46\xBA\x4E\x3D\xD7\x38\xEE\x8D\xDB\x5\xF2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xE8\xAA\xE\xB5\xC8\xF1\x7B\xA0\xA1\x73\x0\x51\x1B\xFA\x22\x50\x54\x46\xBA\x8A\xAD\xD1\xAA\xAE\xA5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\xC0\xAA\xC0\xE5\xC8\xE2\xBB\xA3\xF7\x73\x0\x61\x1B\xFB\x22\x50\x54\x46\xBA\x8A\xAD\xD0\xAA\xAE\xAD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x83\xAA\x4B\xDD\xC8\x60\x7B\xAD\xAD\x73\x0\x71\x1B\xFA\xA2\x50\x50\x46\xBA\xEA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\xC4\xAA\x99\x94\xE8\xAA\x5F\x32\x6D\x73\x0\x63\x53\xFA\xEB\x70\x48\x46\xBA\x6E\x3D\xD6\x38\xEE\x9D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x87\xAA\x0\xE5\xCC\x61\xBB\xAC\x37\x73\x0\x61\x1B\xFB\x22\x50\x5C\x46\xBA\xAA\xAD\xD0\xAA\xAE\xB5\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xAF\xAA\xCE\xB5\xCC\x72\x7B\xAF\x61\x73\x0\x51\x1B\xFA\x22\x50\x5C\x46\xBA\xAA\xAD\xD1\xAA\xAE\xBD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xEC\xAA\x45\x8D\xCC\xF0\xBB\xA1\x3B\x73\x0\x41\x1B\xFB\xA2\x50\x58\x46\xBA\xCA\xAD\xD3\xAA\xAE\xB5\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x44\xAA\xB9\xF5\xCA\xC3\xFB\x8A\xF3\x73\x0\x71\x1B\xFB\xA2\x50\x5C\x46\xBA\xCA\xAD\xD1\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\xFB\xFC\x16\xD0\x6E\x9C\xBB\x74\xB5\xDB\xA8\xAE\xC1\x51\x7\xFA\xAF\xE0\x1E\x0\xE6\xFF\x99\xAD\x0\xA7\x98\x9E\xEB\x91\x21\xFC\x26\x0\x4B\xB3\xF9\x77\x10\x52\xEC\xBA\x7F\xFD\xD1\x0\x2E\xA8\x8F\x5\x11\x2F\xEA\x23\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x2F\xAA\xFC\x9D\xCA\x52\xFB\x87\xFF\x73\x0\x51\x1B\xFB\x22\x50\x58\x46\xBA\xAA\xAD\xD2\xAA\xAE\xB5\xDB\x5\xBB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x6C\xAA\x77\xA5\xCA\xD0\x3B\x89\xA5\x73\x0\x41\x1B\xFA\xA2\x50\x5C\x46\xBA\xCA\xAD\xD0\xAA\xAE\xBD\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x2B\xAA\xA5\xEC\xEA\x1A\x1F\x16\x65\x73\x0\x53\x53\xFA\xEB\x70\x44\x46\xBA\x4E\x3D\xD4\x38\xEE\x85\xDB\x5\xB2\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x68\xAA\x2E\xD4\xEA\x98\xDF\x18\x3F\x73\x0\x43\x53\xFB\x6B\x70\x40\x46\xBA\x2E\x3D\xD6\x38\xEE\x8D\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x40\xAA\xF2\xCD\xCE\xC2\x3B\x8B\x69\x73\x0\x61\x1B\xFA\x22\x50\x50\x46\xBA\x8A\xAD\xD3\xAA\xAE\xA5\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x3\xAA\x79\xF5\xCE\x40\xFB\x85\x33\x73\x0\x71\x1B\xFB\xA2\x50\x54\x46\xBA\xEA\xAD\xD1\xAA\xAE\xAD\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB5\xE1\xAA\x8C\xD4\xED\xDA\xDF\x1E\x3D\x73\x0\x73\x53\xFA\x6B\x70\x4C\x46\xBA\x2E\x3D\xD5\x38\xEE\x9D\xDB\x5\x32\xAF\xEC\x52\x0",
+ "\xFE\x4B\xFC\x14\x90\x6E\x90\xBB\x75\x25\xDB\xA3\xAE\xC1\x75\x7\xFA\xAF\xE0\x7\x0\xFB\xCD\x55\x8A\x49\x9B\x9D\x2A\x9B\x3\x63\xE9\x4B\x80\x7F\x23\xFA\x2C\x70\x4B\xC8\xBA\x89\x25\xD7\x49\x2E\xAD\x39\x5\x43\x6F\xEF\x4E\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x8A\xAA\xDB\xF5\xC9\x2\xFB\x83\x31\x73\x0\x41\x1B\xFA\xA2\x50\x58\x46\xBA\xEA\xAD\xD2\xAA\xAE\xBD\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\xC9\xAA\x42\x84\xED\xC9\x1F\x1D\x6B\x73\x0\x43\x53\xFB\x6B\x70\x4C\x46\xBA\x2E\x3D\xD4\x38\xEE\x95\xDB\x5\x32\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x8E\xAA\x90\xCD\xCD\x3\x3B\x82\xAB\x73\x0\x51\x1B\xFB\x22\x50\x54\x46\xBA\xAA\xAD\xD0\xAA\xAE\xAD\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\xCD\xAA\x9\xBC\xE9\xC8\xDF\x1C\xF1\x73\x0\x53\x53\xFA\xEB\x70\x40\x46\xBA\x6E\x3D\xD6\x38\xEE\x85\xDB\x5\x72\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xE5\xAA\xD5\xA5\xCD\x92\x3B\x8F\xA7\x73\x0\x71\x1B\xFB\xA2\x50\x50\x46\xBA\xCA\xAD\xD3\xAA\xAE\xAD\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xA6\xAA\x5E\x9D\xCD\x10\xFB\x81\xFD\x73\x0\x61\x1B\xFA\x22\x50\x54\x46\xBA\xAA\xAD\xD1\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB1\x6B\xAA\x95\xB4\xEF\xDA\x1F\x28\x77\x73\x0\x73\x53\xFB\xEB\x70\x4C\x46\xBA\x2E\x3D\xD6\x38\xEE\x9D\xDB\x5\xF2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x28\xAA\xC\xC5\xCB\x11\xFB\xB6\x2D\x73\x0\x71\x1B\xFA\x22\x50\x58\x46\xBA\xEA\xAD\xD0\xAA\xAE\xB5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x0\xAA\xC2\x95\xCB\x2\x3B\xB5\x7B\x73\x0\x41\x1B\xFB\x22\x50\x58\x46\xBA\xEA\xAD\xD1\xAA\xAE\xBD\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x43\xAA\x49\xAD\xCB\x80\xFB\xBB\x21\x73\x0\x51\x1B\xFA\xA2\x50\x5C\x46\xBA\x8A\xAD\xD3\xAA\xAE\xB5\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\x4\xAA\x89\xAD\xCF\x3\xFB\xB4\xE1\x73\x0\x51\x1B\xFA\xA2\x50\x54\x46\xBA\xAA\xAD\xD3\xAA\xAE\xAD\xDB\x5\xFB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\x47\xAA\x2\x95\xCF\x81\x3B\xBA\xBB\x73\x0\x41\x1B\xFB\x22\x50\x50\x46\xBA\xCA\xAD\xD1\xAA\xAE\xA5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x6F\xAA\xCC\xC5\xCF\x92\xFB\xB9\xED\x73\x0\x71\x1B\xFA\x22\x50\x50\x46\xBA\xCA\xAD\xD0\xAA\xAE\xAD\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x2C\xAA\x47\xFD\xCF\x10\x3B\xB7\xB7\x73\x0\x61\x1B\xFB\xA2\x50\x54\x46\xBA\xAA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xFB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\xCE\xAA\xA0\x95\xC8\xC3\x3B\xBC\xB9\x73\x0\x71\x1B\xFA\x22\x50\x5C\x46\xBA\xCA\xAD\xD2\xAA\xAE\xB5\xDB\x5\x7B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x27\x8D\xAA\x2B\xAD\xC8\x41\xFB\xB2\xE3\x73\x0\x61\x1B\xFB\xA2\x50\x58\x46\xBA\xAA\xAD\xD0\xAA\xAE\xBD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xA5\xAA\xE5\xFD\xC8\x52\x3B\xB1\xB5\x73\x0\x51\x1B\xFA\xA2\x50\x58\x46\xBA\xAA\xAD\xD1\xAA\xAE\xB5\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xE6\xAA\x6E\xC5\xC8\xD0\xFB\xBF\xEF\x73\x0\x41\x1B\xFB\x22\x50\x5C\x46\xBA\xCA\xAD\xD3\xAA\xAE\xBD\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xA1\xAA\xAE\xC5\xCC\x53\xFB\xB0\x2F\x73\x0\x41\x1B\xFB\x22\x50\x54\x46\xBA\xEA\xAD\xD3\xAA\xAE\xA5\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xE2\xAA\x25\xFD\xCC\xD1\x3B\xBE\x75\x73\x0\x51\x1B\xFA\xA2\x50\x50\x46\xBA\x8A\xAD\xD1\xAA\xAE\xAD\xDB\x5\x3B\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\xCA\xAA\xEB\xAD\xCC\xC2\xFB\xBD\x23\x73\x0\x61\x1B\xFB\xA2\x50\x50\x46\xBA\x8A\xAD\xD0\xAA\xAE\xA5\xDB\x5\x3B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\x89\xAA\x60\x95\xCC\x40\x3B\xB3\x79\x73\x0\x71\x1B\xFA\x22\x50\x54\x46\xBA\xEA\xAD\xD2\xAA\xAE\xAD\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x21\xAA\x9C\xED\xCA\x73\x7B\x98\xB1\x73\x0\x41\x1B\xFA\x22\x50\x50\x46\xBA\xEA\xAD\xD0\xAA\xAE\xAD\xDB\x5\x7B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\x62\xAA\x5\x9C\xEE\xB8\x9F\x6\xEB\x73\x0\x43\x53\xFB\xEB\x70\x44\x46\xBA\x2E\x3D\xD6\x38\xEE\x85\xDB\x5\x32\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\x4A\xAA\xD9\x85\xCA\xE2\x7B\x95\xBD\x73\x0\x61\x1B\xFA\xA2\x50\x54\x46\xBA\x8A\xAD\xD3\xAA\xAE\xAD\xDB\x5\x7B\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\x9\xAA\x52\xBD\xCA\x60\xBB\x9B\xE7\x73\x0\x71\x1B\xFB\x22\x50\x50\x46\xBA\xEA\xAD\xD1\xAA\xAE\xA5\xDB\x5\x7B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB0\x4E\xAA\x80\xF4\xEA\xAA\x9F\x4\x27\x73\x0\x63\x53\xFB\x6B\x70\x48\x46\xBA\x6E\x3D\xD5\x38\xEE\x9D\xDB\x5\x72\xAF\xEE\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x26\xD\xAA\x19\x85\xCE\x61\x7B\x9A\x7D\x73\x0\x61\x1B\xFA\xA2\x50\x5C\x46\xBA\xAA\xAD\xD3\xAA\xAE\xB5\xDB\x5\x3B\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x22\x25\xAA\xD7\xD5\xCE\x72\xBB\x99\x2B\x73\x0\x51\x1B\xFB\xA2\x50\x5C\x46\xBA\xAA\xAD\xD2\xAA\xAE\xBD\xDB\x5\x3B\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB4\x66\xAA\x4E\xA4\xEA\xB9\x5F\x7\x71\x73\x0\x53\x53\xFA\x6B\x70\x48\x46\xBA\x6E\x3D\xD4\x38\xEE\x95\xDB\x5\x72\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x84\xAA\xBB\x85\xC9\x23\x7B\x9C\x7F\x73\x0\x51\x1B\xFB\xA2\x50\x50\x46\xBA\xAA\xAD\xD0\xAA\xAE\xA5\xDB\x5\xBB\x8F\xED\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB7\xC7\xAA\x22\xF4\xED\xE8\x9F\x2\x25\x73\x0\x53\x53\xFA\x6B\x70\x44\x46\xBA\x6E\x3D\xD6\x38\xEE\x8D\xDB\x5\xF2\xAF\xE8\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x23\xEF\xAA\xFE\xED\xC9\xB2\x7B\x91\x73\x73\x0\x71\x1B\xFB\x22\x50\x54\x46\xBA\xCA\xAD\xD3\xAA\xAE\xA5\xDB\x5\xBB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x25\xAC\xAA\x75\xD5\xC9\x30\xBB\x9F\x29\x73\x0\x61\x1B\xFA\xA2\x50\x50\x46\xBA\xAA\xAD\xD1\xAA\xAE\xAD\xDB\x5\xBB\x8F\xEB\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x20\xEB\xAA\xB5\xD5\xCD\xB3\xBB\x90\xE9\x73\x0\x61\x1B\xFA\xA2\x50\x58\x46\xBA\x8A\xAD\xD1\xAA\xAE\xB5\xDB\x5\xFB\x8F\xE9\x76\x1",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB6\xA8\xAA\x2C\xA4\xE9\x78\x5F\xE\xB3\x73\x0\x63\x53\xFB\x6B\x70\x4C\x46\xBA\x4E\x3D\xD7\x38\xEE\x9D\xDB\x5\xB2\xAF\xEC\x52\x0",
+ "\xFE\x2B\xFC\x15\x50\x6E\xAC\xBB\x74\x15\xDB\xAF\xAE\xC1\x71\x7\xFA\xAF\xE0\x10\x0\xD3\x3B\xB2\x80\xAA\xE2\xF4\xE9\x6B\x9F\xD\xE5\x73\x0\x53\x53\xFA\x6B\x70\x4C\x46\xBA\x4E\x3D\xD6\x38\xEE\x95\xDB\x5\xB2\xAF\xEA\x52\x0",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x24\xC3\xAA\x7B\x85\xCD\xA0\x7B\x93\xBF\x73\x0\x51\x1B\xFB\xA2\x50\x58\x46\xBA\x8A\xAD\xD0\xAA\xAE\xBD\xDB\x5\xFB\x8F\xEF\x76\x1",
+ "\xFE\x2B\xFC\x10\x50\x6E\xA8\xBB\x74\x15\xDB\xA5\xAE\xC1\x39\x7\xFA\xAF\xE0\x14\x0\xEF\xAE\x21\x25\xAA\x94\xB5\xCB\x30\x3B\xAA\x6B\x72\x80\x41\x13\xFA\x22\x50\x50\x46\xBA\xEA\xAD\xD2\xAA\xAE\xA5\xDB\x5\xBB\x8F\xE9\x76\x1",
+};
diff --git a/gfx/layers/d3d10/ThebesLayerD3D10.cpp b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
index 976aae3b842a..521c29729a0c 100644
--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
@@ -291,22 +291,7 @@ ThebesLayerD3D10::GetLayer()
void
ThebesLayerD3D10::VerifyContentType(SurfaceMode aMode)
{
- if (mD2DSurface) {
- gfxContentType type = aMode != SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA ?
- gfxContentType::COLOR : gfxContentType::COLOR_ALPHA;
-
- if (type != mD2DSurface->GetContentType()) {
- mD2DSurface = new gfxD2DSurface(mTexture, type);
-
- if (!mD2DSurface || mD2DSurface->CairoStatus()) {
- NS_WARNING("Failed to create surface for ThebesLayerD3D10.");
- mD2DSurface = nullptr;
- return;
- }
-
- mValidRegion.SetEmpty();
- }
- } else if (mDrawTarget) {
+ if (mDrawTarget) {
SurfaceFormat format = aMode != SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA ?
SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
@@ -324,7 +309,6 @@ ThebesLayerD3D10::VerifyContentType(SurfaceMode aMode)
if (aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA && mTextureOnWhite) {
// If we've transitioned away from component alpha, we can delete those resources.
- mD2DSurfaceOnWhite = nullptr;
mSRViewOnWhite = nullptr;
mTextureOnWhite = nullptr;
mValidRegion.SetEmpty();
@@ -400,21 +384,16 @@ ThebesLayerD3D10::DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode)
{
nsIntRect visibleRect = mVisibleRegion.GetBounds();
- if (!mD2DSurface && !mDrawTarget) {
+ if (!mDrawTarget) {
return;
}
aRegion.SimplifyOutwardByArea(100 * 100);
- nsRefPtr destinationSurface;
-
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
FillTexturesBlackWhite(aRegion, visibleRect.TopLeft());
- } else {
- destinationSurface = mD2DSurface;
}
- MOZ_ASSERT(mDrawTarget);
nsRefPtr context = new gfxContext(mDrawTarget);
context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
diff --git a/gfx/layers/d3d10/ThebesLayerD3D10.h b/gfx/layers/d3d10/ThebesLayerD3D10.h
index d0f7079837fe..d39429053688 100644
--- a/gfx/layers/d3d10/ThebesLayerD3D10.h
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.h
@@ -51,14 +51,8 @@ private:
/* Checks if our D2D surface has the right content type */
void VerifyContentType(SurfaceMode aMode);
- /* This contains the thebes surface */
- nsRefPtr mD2DSurface;
-
mozilla::RefPtr mDrawTarget;
- /* This contains the thebes surface for our render-on-white texture */
- nsRefPtr mD2DSurfaceOnWhite;
-
/* Have a region of our layer drawn */
void DrawRegion(nsIntRegion &aRegion, SurfaceMode aMode);
diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h
index 95c5e5a2556f..16db1eeacc02 100644
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -53,8 +53,7 @@ class MemoryTextureHost;
enum BufferCapabilities {
DEFAULT_BUFFER_CAPS = 0,
/**
- * The allocated buffer must be efficiently mappable as a
- * gfxImageSurface.
+ * The allocated buffer must be efficiently mappable as a DataSourceSurface.
*/
MAP_AS_IMAGE_SURFACE = 1 << 0,
/**
diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp
index f6e4b23b3946..a8abd112604e 100644
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -15,7 +15,6 @@
#include "gfx2DGlue.h" // for ThebesFilter
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
-#include "gfxImageSurface.h" // for gfxImageSurface
#include "gfxMatrix.h" // for gfxMatrix
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPlatform.h" // for gfxPlatform
diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h
index e4267cd2bb6f..42a3ddf2f346 100644
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -56,8 +56,8 @@ inline gfxRGBA ThebesColor(Color &aColor)
inline Matrix ToMatrix(const gfxMatrix &aMatrix)
{
- return Matrix(Float(aMatrix.xx), Float(aMatrix.yx), Float(aMatrix.xy),
- Float(aMatrix.yy), Float(aMatrix.x0), Float(aMatrix.y0));
+ return Matrix(Float(aMatrix._11), Float(aMatrix._12), Float(aMatrix._21),
+ Float(aMatrix._22), Float(aMatrix._31), Float(aMatrix._32));
}
inline gfxMatrix ThebesMatrix(const Matrix &aMatrix)
diff --git a/gfx/thebes/gfx3DMatrix.cpp b/gfx/thebes/gfx3DMatrix.cpp
index 27e5adef7ecd..06757305d574 100644
--- a/gfx/thebes/gfx3DMatrix.cpp
+++ b/gfx/thebes/gfx3DMatrix.cpp
@@ -162,12 +162,12 @@ gfx3DMatrix
gfx3DMatrix::From2D(const gfxMatrix &aMatrix)
{
gfx3DMatrix matrix;
- matrix._11 = (float)aMatrix.xx;
- matrix._12 = (float)aMatrix.yx;
- matrix._21 = (float)aMatrix.xy;
- matrix._22 = (float)aMatrix.yy;
- matrix._41 = (float)aMatrix.x0;
- matrix._42 = (float)aMatrix.y0;
+ matrix._11 = (float)aMatrix._11;
+ matrix._12 = (float)aMatrix._12;
+ matrix._21 = (float)aMatrix._21;
+ matrix._22 = (float)aMatrix._22;
+ matrix._41 = (float)aMatrix._31;
+ matrix._42 = (float)aMatrix._32;
return matrix;
}
@@ -369,22 +369,22 @@ void
gfx3DMatrix::PreMultiply(const gfxMatrix& aOther)
{
gfx3DMatrix temp;
- temp._11 = aOther.xx * _11 + aOther.yx * _21;
- temp._21 = aOther.xy * _11 + aOther.yy * _21;
+ temp._11 = aOther._11 * _11 + aOther._12 * _21;
+ temp._21 = aOther._21 * _11 + aOther._22 * _21;
temp._31 = _31;
- temp._41 = aOther.x0 * _11 + aOther.y0 * _21 + _41;
- temp._12 = aOther.xx * _12 + aOther.yx * _22;
- temp._22 = aOther.xy * _12 + aOther.yy * _22;
+ temp._41 = aOther._31 * _11 + aOther._32 * _21 + _41;
+ temp._12 = aOther._11 * _12 + aOther._12 * _22;
+ temp._22 = aOther._21 * _12 + aOther._22 * _22;
temp._32 = _32;
- temp._42 = aOther.x0 * _12 + aOther.y0 * _22 + _42;
- temp._13 = aOther.xx * _13 + aOther.yx * _23;
- temp._23 = aOther.xy * _13 + aOther.yy * _23;
+ temp._42 = aOther._31 * _12 + aOther._32 * _22 + _42;
+ temp._13 = aOther._11 * _13 + aOther._12 * _23;
+ temp._23 = aOther._21 * _13 + aOther._22 * _23;
temp._33 = _33;
- temp._43 = aOther.x0 * _13 + aOther.y0 * _23 + _43;
- temp._14 = aOther.xx * _14 + aOther.yx * _24;
- temp._24 = aOther.xy * _14 + aOther.yy * _24;
+ temp._43 = aOther._31 * _13 + aOther._32 * _23 + _43;
+ temp._14 = aOther._11 * _14 + aOther._12 * _24;
+ temp._24 = aOther._21 * _14 + aOther._22 * _24;
temp._34 = _34;
- temp._44 = aOther.x0 * _14 + aOther.y0 * _24 + _44;
+ temp._44 = aOther._31 * _14 + aOther._32 * _24 + _44;
*this = temp;
}
@@ -711,12 +711,12 @@ gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const
return false;
}
if (aMatrix) {
- aMatrix->xx = _11;
- aMatrix->yx = _12;
- aMatrix->xy = _21;
- aMatrix->yy = _22;
- aMatrix->x0 = _41;
- aMatrix->y0 = _42;
+ aMatrix->_11 = _11;
+ aMatrix->_12 = _12;
+ aMatrix->_21 = _21;
+ aMatrix->_22 = _22;
+ aMatrix->_31 = _41;
+ aMatrix->_32 = _42;
}
return true;
}
@@ -730,12 +730,12 @@ gfx3DMatrix::CanDraw2D(gfxMatrix* aMatrix) const
return false;
}
if (aMatrix) {
- aMatrix->xx = _11;
- aMatrix->yx = _12;
- aMatrix->xy = _21;
- aMatrix->yy = _22;
- aMatrix->x0 = _41;
- aMatrix->y0 = _42;
+ aMatrix->_11 = _11;
+ aMatrix->_12 = _12;
+ aMatrix->_21 = _21;
+ aMatrix->_22 = _22;
+ aMatrix->_31 = _41;
+ aMatrix->_32 = _42;
}
return true;
}
diff --git a/gfx/thebes/gfxDrawable.cpp b/gfx/thebes/gfxDrawable.cpp
index a2891d2c4534..046d669932ef 100644
--- a/gfx/thebes/gfxDrawable.cpp
+++ b/gfx/thebes/gfxDrawable.cpp
@@ -97,8 +97,8 @@ PreparePatternForUntiledDrawing(gfxPattern* aPattern,
// enough X server.
if (static_cast(currentTarget)->IsPadSlow()) {
bool isDownscale =
- aDeviceToImage.xx >= 1.0 && aDeviceToImage.yy >= 1.0 &&
- aDeviceToImage.xy == 0.0 && aDeviceToImage.yx == 0.0;
+ aDeviceToImage._11 >= 1.0 && aDeviceToImage._22 >= 1.0 &&
+ aDeviceToImage._21 == 0.0 && aDeviceToImage._12 == 0.0;
GraphicsFilter filter =
isDownscale ? aDefaultFilter : (const GraphicsFilter)GraphicsFilter::FILTER_FAST;
diff --git a/gfx/thebes/gfxMatrix.cpp b/gfx/thebes/gfxMatrix.cpp
index 22a47bd781e5..4cdc1d1f0271 100644
--- a/gfx/thebes/gfxMatrix.cpp
+++ b/gfx/thebes/gfxMatrix.cpp
@@ -135,10 +135,10 @@ static void NudgeToInteger(double *aVal)
void
gfxMatrix::NudgeToIntegers(void)
{
- NudgeToInteger(&xx);
- NudgeToInteger(&xy);
- NudgeToInteger(&yx);
- NudgeToInteger(&yy);
- NudgeToInteger(&x0);
- NudgeToInteger(&y0);
+ NudgeToInteger(&_11);
+ NudgeToInteger(&_21);
+ NudgeToInteger(&_12);
+ NudgeToInteger(&_22);
+ NudgeToInteger(&_31);
+ NudgeToInteger(&_32);
}
diff --git a/gfx/thebes/gfxMatrix.h b/gfx/thebes/gfxMatrix.h
index b0107c11f9e1..d6297d3423ac 100644
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -31,9 +31,9 @@
*
*/
struct gfxMatrix {
- double xx; double yx;
- double xy; double yy;
- double x0; double y0;
+ double _11; double _12;
+ double _21; double _22;
+ double _31; double _32;
public:
/**
@@ -46,9 +46,9 @@ public:
* description for the layout of the matrix.
*/
gfxMatrix(gfxFloat a, gfxFloat b, gfxFloat c, gfxFloat d, gfxFloat tx, gfxFloat ty) :
- xx(a), yx(b),
- xy(c), yy(d),
- x0(tx), y0(ty) { }
+ _11(a), _12(b),
+ _21(c), _22(d),
+ _31(tx), _32(ty) { }
/**
* Post-multiplies m onto the matrix.
@@ -69,9 +69,9 @@ public:
*/
bool operator==(const gfxMatrix& other) const
{
- return FuzzyEqual(xx, other.xx) && FuzzyEqual(yx, other.yx) &&
- FuzzyEqual(xy, other.xy) && FuzzyEqual(yy, other.yy) &&
- FuzzyEqual(x0, other.x0) && FuzzyEqual(y0, other.y0);
+ return FuzzyEqual(_11, other._11) && FuzzyEqual(_12, other._12) &&
+ FuzzyEqual(_21, other._21) && FuzzyEqual(_22, other._22) &&
+ FuzzyEqual(_31, other._31) && FuzzyEqual(_32, other._32);
}
bool operator!=(const gfxMatrix& other) const
@@ -86,9 +86,9 @@ public:
const gfxMatrix& Reset();
bool IsIdentity() const {
- return xx == 1.0 && yx == 0.0 &&
- xy == 0.0 && yy == 1.0 &&
- x0 == 0.0 && y0 == 0.0;
+ return _11 == 1.0 && _12 == 0.0 &&
+ _21 == 0.0 && _22 == 1.0 &&
+ _31 == 0.0 && _32 == 0.0;
}
/**
@@ -105,7 +105,7 @@ public:
*/
bool IsSingular() const {
// if the determinant (ad - bc) is zero it's singular
- return (xx * yy) == (yx * xy);
+ return (_11 * _22) == (_12 * _21);
}
/**
@@ -167,7 +167,7 @@ public:
* Returns the translation component of this matrix.
*/
gfxPoint GetTranslation() const {
- return gfxPoint(x0, y0);
+ return gfxPoint(_31, _32);
}
/**
@@ -176,8 +176,8 @@ public:
*/
bool HasNonIntegerTranslation() const {
return HasNonTranslation() ||
- !FuzzyEqual(x0, floor(x0 + 0.5)) ||
- !FuzzyEqual(y0, floor(y0 + 0.5));
+ !FuzzyEqual(_31, floor(_31 + 0.5)) ||
+ !FuzzyEqual(_32, floor(_32 + 0.5));
}
/**
@@ -185,8 +185,8 @@ public:
* than a straight translation
*/
bool HasNonTranslation() const {
- return !FuzzyEqual(xx, 1.0) || !FuzzyEqual(yy, 1.0) ||
- !FuzzyEqual(xy, 0.0) || !FuzzyEqual(yx, 0.0);
+ return !FuzzyEqual(_11, 1.0) || !FuzzyEqual(_22, 1.0) ||
+ !FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
}
/**
@@ -201,9 +201,9 @@ public:
* than a translation or a -1 y scale (y axis flip)
*/
bool HasNonTranslationOrFlip() const {
- return !FuzzyEqual(xx, 1.0) ||
- (!FuzzyEqual(yy, 1.0) && !FuzzyEqual(yy, -1.0)) ||
- !FuzzyEqual(xy, 0.0) || !FuzzyEqual(yx, 0.0);
+ return !FuzzyEqual(_11, 1.0) ||
+ (!FuzzyEqual(_22, 1.0) && !FuzzyEqual(_22, -1.0)) ||
+ !FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
}
/**
@@ -212,14 +212,14 @@ public:
* no rotation.
*/
bool HasNonAxisAlignedTransform() const {
- return !FuzzyEqual(xy, 0.0) || !FuzzyEqual(yx, 0.0);
+ return !FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
}
/**
* Computes the determinant of this matrix.
*/
double Determinant() const {
- return xx*yy - yx*xy;
+ return _11*_22 - _12*_21;
}
/* Computes the scale factors of this matrix; that is,
@@ -264,16 +264,16 @@ public:
* scaling and translation.
*/
bool PreservesAxisAlignedRectangles() const {
- return ((FuzzyEqual(xx, 0.0) && FuzzyEqual(yy, 0.0))
- || (FuzzyEqual(xy, 0.0) && FuzzyEqual(yx, 0.0)));
+ return ((FuzzyEqual(_11, 0.0) && FuzzyEqual(_22, 0.0))
+ || (FuzzyEqual(_21, 0.0) && FuzzyEqual(_12, 0.0)));
}
/**
* Returns true if the matrix has non-integer scale
*/
bool HasNonIntegerScale() const {
- return !FuzzyEqual(xx, floor(xx + 0.5)) ||
- !FuzzyEqual(yy, floor(yy + 0.5));
+ return !FuzzyEqual(_11, floor(_11 + 0.5)) ||
+ !FuzzyEqual(_22, floor(_22 + 0.5));
}
private:
diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp
index 60818d3f9ba8..9a1c51f9c293 100644
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -266,17 +266,17 @@ struct MOZ_STACK_CLASS AutoCairoPixmanBugWorkaround
if (!aSurface || aSurface->GetType() == gfxSurfaceType::Quartz)
return;
- if (!IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.xx) ||
- !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.xy) ||
- !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.yx) ||
- !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.yy)) {
+ if (!IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._11) ||
+ !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._21) ||
+ !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._12) ||
+ !IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._22)) {
NS_WARNING("Scaling up too much, bailing out");
mSucceeded = false;
return;
}
- if (IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.x0) &&
- IsSafeImageTransformComponent(aDeviceSpaceToImageSpace.y0))
+ if (IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._31) &&
+ IsSafeImageTransformComponent(aDeviceSpaceToImageSpace._32))
return;
// We'll push a group, which will hopefully reduce our transform's
@@ -438,9 +438,9 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
// we know we have the pixman limits. 16384.0 is a somewhat arbitrary
// large number to make sure we avoid the expensive fmod when we can, but
// still maintain a safe margin from the actual limit
- if (doTile && (userSpaceToImageSpace.y0 > 16384.0 || userSpaceToImageSpace.x0 > 16384.0)) {
- userSpaceToImageSpace.x0 = fmod(userSpaceToImageSpace.x0, aImageRect.width);
- userSpaceToImageSpace.y0 = fmod(userSpaceToImageSpace.y0, aImageRect.height);
+ if (doTile && (userSpaceToImageSpace._32 > 16384.0 || userSpaceToImageSpace._31 > 16384.0)) {
+ userSpaceToImageSpace._31 = fmod(userSpaceToImageSpace._31, aImageRect.width);
+ userSpaceToImageSpace._32 = fmod(userSpaceToImageSpace._32, aImageRect.height);
}
#else
// OK now, the hard part left is to account for the subimage sampling
@@ -641,19 +641,19 @@ gfxUtils::TransformRectToRect(const gfxRect& aFrom, const gfxPoint& aToTopLeft,
gfxMatrix m;
if (aToTopRight.y == aToTopLeft.y && aToTopRight.x == aToBottomRight.x) {
// Not a rotation, so xy and yx are zero
- m.xy = m.yx = 0.0;
- m.xx = (aToBottomRight.x - aToTopLeft.x)/aFrom.width;
- m.yy = (aToBottomRight.y - aToTopLeft.y)/aFrom.height;
- m.x0 = aToTopLeft.x - m.xx*aFrom.x;
- m.y0 = aToTopLeft.y - m.yy*aFrom.y;
+ m._21 = m._12 = 0.0;
+ m._11 = (aToBottomRight.x - aToTopLeft.x)/aFrom.width;
+ m._22 = (aToBottomRight.y - aToTopLeft.y)/aFrom.height;
+ m._31 = aToTopLeft.x - m._11*aFrom.x;
+ m._32 = aToTopLeft.y - m._22*aFrom.y;
} else {
NS_ASSERTION(aToTopRight.y == aToBottomRight.y && aToTopRight.x == aToTopLeft.x,
"Destination rectangle not axis-aligned");
- m.xx = m.yy = 0.0;
- m.xy = (aToBottomRight.x - aToTopLeft.x)/aFrom.height;
- m.yx = (aToBottomRight.y - aToTopLeft.y)/aFrom.width;
- m.x0 = aToTopLeft.x - m.xy*aFrom.y;
- m.y0 = aToTopLeft.y - m.yx*aFrom.x;
+ m._11 = m._22 = 0.0;
+ m._21 = (aToBottomRight.x - aToTopLeft.x)/aFrom.height;
+ m._12 = (aToBottomRight.y - aToTopLeft.y)/aFrom.width;
+ m._31 = aToTopLeft.x - m._21*aFrom.y;
+ m._32 = aToTopLeft.y - m._12*aFrom.x;
}
return m;
}
diff --git a/gfx/thebes/gfxWindowsNativeDrawing.cpp b/gfx/thebes/gfxWindowsNativeDrawing.cpp
index b9807de7984f..51f334fa12e6 100644
--- a/gfx/thebes/gfxWindowsNativeDrawing.cpp
+++ b/gfx/thebes/gfxWindowsNativeDrawing.cpp
@@ -79,12 +79,12 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
&& (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) ||
(mNativeDrawFlags & CAN_COMPLEX_TRANSFORM))
{
- mWorldTransform.eM11 = (FLOAT) m.xx;
- mWorldTransform.eM12 = (FLOAT) m.yx;
- mWorldTransform.eM21 = (FLOAT) m.xy;
- mWorldTransform.eM22 = (FLOAT) m.yy;
- mWorldTransform.eDx = (FLOAT) m.x0;
- mWorldTransform.eDy = (FLOAT) m.y0;
+ mWorldTransform.eM11 = (FLOAT) m._11;
+ mWorldTransform.eM12 = (FLOAT) m._12;
+ mWorldTransform.eM21 = (FLOAT) m._21;
+ mWorldTransform.eM22 = (FLOAT) m._22;
+ mWorldTransform.eDx = (FLOAT) m._31;
+ mWorldTransform.eDy = (FLOAT) m._32;
mRenderState = RENDER_STATE_NATIVE_DRAWING;
}
diff --git a/image/src/imgFrame.cpp b/image/src/imgFrame.cpp
index 72c786b358f3..9e0af24bb922 100644
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -343,12 +343,12 @@ imgFrame::SurfaceForDrawing(bool aDoPadding,
imageSpaceToUserSpace.Invert();
SurfacePattern pattern(aSurface,
ExtendMode::REPEAT,
- Matrix(imageSpaceToUserSpace.xx,
- imageSpaceToUserSpace.xy,
- imageSpaceToUserSpace.yx,
- imageSpaceToUserSpace.yy,
- imageSpaceToUserSpace.x0,
- imageSpaceToUserSpace.y0));
+ Matrix(imageSpaceToUserSpace._11,
+ imageSpaceToUserSpace._21,
+ imageSpaceToUserSpace._12,
+ imageSpaceToUserSpace._22,
+ imageSpaceToUserSpace._31,
+ imageSpaceToUserSpace._32));
target->FillRect(fillRect, pattern);
}
diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h
index c58d62d029b3..7ac14c83607c 100644
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -43,7 +43,7 @@ namespace JS {
D(TOO_MUCH_MALLOC) \
D(ALLOC_TRIGGER) \
D(DEBUG_GC) \
- D(TRANSPLANT) \
+ D(COMPARTMENT_REVIVED) \
D(RESET) \
D(OUT_OF_NURSERY) \
D(EVICT_NURSERY) \
diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp
index 7689e8d0c0d0..168138f356ce 100644
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -198,9 +198,6 @@ CheckMarkedThing(JSTracer *trc, T **thingp)
DebugOnly rt = trc->runtime();
- JS_ASSERT_IF(IS_GC_MARKING_TRACER(trc) && rt->gc.isManipulatingDeadZones(),
- !thing->zone()->scheduledForDestruction);
-
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
JS_ASSERT_IF(thing->zone()->requireGCTracer(),
@@ -231,6 +228,33 @@ CheckMarkedThing(JSTracer *trc, T **thingp)
}
+/*
+ * We only set the maybeAlive flag for objects and scripts. It's assumed that,
+ * if a compartment is alive, then it will have at least some live object or
+ * script it in. Even if we get this wrong, the worst that will happen is that
+ * scheduledForDestruction will be set on the compartment, which will cause some
+ * extra GC activity to try to free the compartment.
+ */
+template
+static inline void
+SetMaybeAliveFlag(T *thing)
+{
+}
+
+template<>
+void
+SetMaybeAliveFlag(JSObject *thing)
+{
+ thing->compartment()->maybeAlive = true;
+}
+
+template<>
+void
+SetMaybeAliveFlag(JSScript *thing)
+{
+ thing->compartment()->maybeAlive = true;
+}
+
template
static void
MarkInternal(JSTracer *trc, T **thingp)
@@ -274,7 +298,7 @@ MarkInternal(JSTracer *trc, T **thingp)
return;
PushMarkStack(AsGCMarker(trc), thing);
- thing->zone()->maybeAlive = true;
+ SetMaybeAliveFlag(thing);
} else {
trc->callback(trc, (void **)thingp, MapTypeToTraceKind::kind);
trc->unsetTracingLocation();
diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp
index 73503826acd9..edf45332115c 100644
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -638,7 +638,20 @@ GCMarker::appendGrayRoot(void *thing, JSGCTraceKind kind)
Zone *zone = static_cast(thing)->tenuredZone();
if (zone->isCollecting()) {
- zone->maybeAlive = true;
+ // See the comment on SetMaybeAliveFlag to see why we only do this for
+ // objects and scripts. We rely on gray root buffering for this to work,
+ // but we only need to worry about uncollected dead compartments during
+ // incremental GCs (when we do gray root buffering).
+ switch (kind) {
+ case JSTRACE_OBJECT:
+ static_cast(thing)->compartment()->maybeAlive = true;
+ break;
+ case JSTRACE_SCRIPT:
+ static_cast(thing)->compartment()->maybeAlive = true;
+ break;
+ default:
+ break;
+ }
if (!zone->gcGrayRoots.append(root)) {
resetBufferedGrayRoots();
grayBufferState = GRAY_BUFFER_FAILED;
diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp
index 9cc5e244bb2a..efa6e9cb699f 100644
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -35,8 +35,6 @@ JS::Zone::Zone(JSRuntime *rt)
data(nullptr),
isSystem(false),
usedByExclusiveThread(false),
- scheduledForDestruction(false),
- maybeAlive(true),
active(false),
jitZone_(nullptr),
gcState_(NoGC),
diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h
index 648f3194a09d..6cbf0f4ad9e3 100644
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -258,11 +258,6 @@ struct Zone : public JS::shadow::Zone,
bool usedByExclusiveThread;
- // These flags help us to discover if a compartment that shouldn't be alive
- // manages to outlive a GC.
- bool scheduledForDestruction;
- bool maybeAlive;
-
// True when there are active frames.
bool active;
diff --git a/js/src/jit-test/tests/parallel/bug1024756.js b/js/src/jit-test/tests/parallel/bug1024756.js
new file mode 100644
index 000000000000..16f6ed3ee744
--- /dev/null
+++ b/js/src/jit-test/tests/parallel/bug1024756.js
@@ -0,0 +1,12 @@
+// Failure to track frame size properly in code generation for NewDenseArray and rest arguments.
+
+if (!getBuildConfiguration().parallelJS)
+ quit(0);
+
+var x =
+(function() {
+ return Array.buildPar(15891, function() {
+ return [].map(function() {})
+ })
+})();
+assertEq(x.length, 15891);
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 32db56259696..514d39284651 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -3916,10 +3916,10 @@ CodeGenerator::visitNewDenseArrayPar(LNewDenseArrayPar *lir)
Register tempReg2 = ToRegister(lir->getTemp2());
JSObject *templateObj = lir->mir()->templateObject();
- masm.push(lengthReg);
+ masm.Push(lengthReg);
if (!emitAllocateGCThingPar(lir, tempReg2, cxReg, tempReg0, tempReg1, templateObj))
return false;
- masm.pop(lengthReg);
+ masm.Pop(lengthReg);
// Invoke a C helper to allocate the elements. The helper returns
// nullptr on allocation error or the array object.
@@ -6602,10 +6602,10 @@ CodeGenerator::visitRestPar(LRestPar *lir)
unsigned numFormals = lir->mir()->numFormals();
JSObject *templateObject = lir->mir()->templateObject();
- masm.push(numActuals);
+ masm.Push(numActuals);
if (!emitAllocateGCThingPar(lir, temp2, cx, temp0, temp1, templateObject))
return false;
- masm.pop(numActuals);
+ masm.Pop(numActuals);
return emitRest(lir, temp2, numActuals, temp0, temp1, numFormals, templateObject, true, ToRegister(lir->output()));
}
diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp
index 7e429e123d15..3e31e32021fd 100644
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -1534,28 +1534,6 @@ MDiv::fallible() const
return !isTruncated();
}
-bool
-MMod::canBeDivideByZero() const
-{
- JS_ASSERT(specialization_ == MIRType_Int32);
- return !rhs()->isConstant() || rhs()->toConstant()->value().toInt32() == 0;
-}
-
-bool
-MMod::canBePowerOfTwoDivisor() const
-{
- JS_ASSERT(specialization_ == MIRType_Int32);
-
- if (!rhs()->isConstant())
- return true;
-
- int32_t i = rhs()->toConstant()->value().toInt32();
- if (i <= 0 || !IsPowerOfTwo(i))
- return false;
-
- return true;
-}
-
MDefinition *
MMod::foldsTo(TempAllocator &alloc, bool useValueNumbers)
{
@@ -1568,6 +1546,23 @@ MMod::foldsTo(TempAllocator &alloc, bool useValueNumbers)
return this;
}
+void
+MMod::analyzeEdgeCasesForward()
+{
+ // These optimizations make sense only for integer division
+ if (specialization_ != MIRType_Int32)
+ return;
+
+ if (rhs()->isConstant() && !rhs()->toConstant()->value().isInt32(0))
+ canBeDivideByZero_ = false;
+
+ if (rhs()->isConstant()) {
+ int32_t n = rhs()->toConstant()->value().toInt32();
+ if (n > 0 && !IsPowerOfTwo(n))
+ canBePowerOfTwoDivisor_ = false;
+ }
+}
+
bool
MMod::fallible() const
{
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index 88e89b6132e2..43e11a83d957 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3398,6 +3398,7 @@ class MToInt32
return AliasSet::None();
}
void computeRange(TempAllocator &alloc);
+ void collectRangeInfoPreTrunc();
#ifdef DEBUG
bool isConsistentFloat32Use(MUse *use) const { return true; }
@@ -4449,6 +4450,7 @@ class MMul : public MBinaryArithInstruction
MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
void analyzeEdgeCasesForward();
void analyzeEdgeCasesBackward();
+ void collectRangeInfoPreTrunc();
double getIdentity() {
return 1;
@@ -4606,11 +4608,15 @@ class MMod : public MBinaryArithInstruction
{
bool unsigned_;
bool canBeNegativeDividend_;
+ bool canBePowerOfTwoDivisor_;
+ bool canBeDivideByZero_;
MMod(MDefinition *left, MDefinition *right, MIRType type)
: MBinaryArithInstruction(left, right),
unsigned_(false),
- canBeNegativeDividend_(true)
+ canBeNegativeDividend_(true),
+ canBePowerOfTwoDivisor_(true),
+ canBeDivideByZero_(true)
{
if (type != MIRType_Value)
specialization_ = type;
@@ -4642,8 +4648,18 @@ class MMod : public MBinaryArithInstruction
JS_ASSERT(specialization_ == MIRType_Int32);
return canBeNegativeDividend_;
}
- bool canBeDivideByZero() const;
- bool canBePowerOfTwoDivisor() const;
+
+ bool canBeDivideByZero() const {
+ JS_ASSERT(specialization_ == MIRType_Int32);
+ return canBeDivideByZero_;
+ }
+
+ bool canBePowerOfTwoDivisor() const {
+ JS_ASSERT(specialization_ == MIRType_Int32);
+ return canBePowerOfTwoDivisor_;
+ }
+
+ void analyzeEdgeCasesForward();
bool isUnsigned() const {
return unsigned_;
@@ -9895,6 +9911,7 @@ class MNewDenseArrayPar : public MBinaryInstruction
: MBinaryInstruction(cx, length),
templateObject_(templateObject)
{
+ JS_ASSERT(length->type() == MIRType_Int32);
setResultType(MIRType_Object);
}
diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp
index 2df93c75d137..3780a55815dc 100644
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -2694,16 +2694,77 @@ void
MDiv::collectRangeInfoPreTrunc()
{
Range lhsRange(lhs());
+ Range rhsRange(rhs());
+
+ // Test if Dividend is non-negative.
if (lhsRange.isFiniteNonNegative())
canBeNegativeDividend_ = false;
+
+ // Try removing divide by zero check.
+ if (!rhsRange.canBeZero())
+ canBeDivideByZero_ = false;
+
+ // If lhsRange does not contain INT32_MIN in its range,
+ // negative overflow check can be skipped.
+ if (!lhsRange.contains(INT32_MIN))
+ canBeNegativeOverflow_ = false;
+
+ // If rhsRange does not contain -1 likewise.
+ if (!rhsRange.contains(-1))
+ canBeNegativeOverflow_ = false;
+
+ // If lhsRange does not contain a zero,
+ // negative zero check can be skipped.
+ if (!lhsRange.canBeZero())
+ canBeNegativeZero_ = false;
+
+ // If rhsRange >= 0 negative zero check can be skipped.
+ if (rhsRange.isFiniteNonNegative())
+ canBeNegativeZero_ = false;
+}
+
+void
+MMul::collectRangeInfoPreTrunc()
+{
+ Range lhsRange(lhs());
+ Range rhsRange(rhs());
+
+ // If lhsRange contains only positive then we can skip negative zero check.
+ if (lhsRange.isFiniteNonNegative() && !lhsRange.canBeZero())
+ setCanBeNegativeZero(false);
+
+ // Likewise rhsRange.
+ if (rhsRange.isFiniteNonNegative() && !rhsRange.canBeZero())
+ setCanBeNegativeZero(false);
+
+ // If rhsRange and lhsRange contain Non-negative integers only,
+ // We skip negative zero check.
+ if (rhsRange.isFiniteNonNegative() && lhsRange.isFiniteNonNegative())
+ setCanBeNegativeZero(false);
+
+ //If rhsRange and lhsRange < 0. Then we skip negative zero check.
+ if (rhsRange.isFiniteNegative() && lhsRange.isFiniteNegative())
+ setCanBeNegativeZero(false);
}
void
MMod::collectRangeInfoPreTrunc()
{
Range lhsRange(lhs());
+ Range rhsRange(rhs());
if (lhsRange.isFiniteNonNegative())
canBeNegativeDividend_ = false;
+ if (!rhsRange.canBeZero())
+ canBeDivideByZero_ = false;
+
+}
+
+void
+MToInt32::collectRangeInfoPreTrunc()
+{
+ Range inputRange(input());
+ if (!inputRange.canBeZero())
+ canBeNegativeZero_ = false;
}
void
diff --git a/js/src/jit/RangeAnalysis.h b/js/src/jit/RangeAnalysis.h
index 7271fce27ed0..52990bcc0e2c 100644
--- a/js/src/jit/RangeAnalysis.h
+++ b/js/src/jit/RangeAnalysis.h
@@ -456,9 +456,14 @@ class Range : public TempObject {
return canHaveFractionalPart() || max_exponent_ >= MaxTruncatableExponent;
}
+ // Test if an integer x belongs to the range.
+ bool contains(int32_t x) const {
+ return x >= lower_ && x <= upper_;
+ }
+
// Test whether the range contains zero.
bool canBeZero() const {
- return lower_ <= 0 && upper_ >= 0;
+ return contains(0);
}
// Test whether the range contains NaN values.
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 070c28ed2db5..5d11979f549f 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1090,7 +1090,6 @@ JS_TransplantObject(JSContext *cx, HandleObject origobj, HandleObject target)
JS_ASSERT(!origobj->is());
JS_ASSERT(!target->is());
- AutoMaybeTouchDeadZones agc(cx);
AutoDisableProxyCheck adpc(cx->runtime());
JSCompartment *destination = target->compartment();
diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp
index 97515875dd2e..ea473ddbac03 100644
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -65,7 +65,9 @@ JSCompartment::JSCompartment(Zone *zone, const JS::CompartmentOptions &options =
debugScriptMap(nullptr),
debugScopes(nullptr),
enumerators(nullptr),
- compartmentStats(nullptr)
+ compartmentStats(nullptr),
+ scheduledForDestruction(false),
+ maybeAlive(true)
#ifdef JS_ION
, jitCompartment_(nullptr)
#endif
diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h
index 6a296540c9b6..a99325cd5395 100644
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -448,6 +448,11 @@ struct JSCompartment
/* Used by memory reporters and invalid otherwise. */
void *compartmentStats;
+ // These flags help us to discover if a compartment that shouldn't be alive
+ // manages to outlive a GC.
+ bool scheduledForDestruction;
+ bool maybeAlive;
+
#ifdef JS_ION
private:
js::jit::JitCompartment *jitCompartment_;
diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp
index 42289d156bbe..d562107357c8 100644
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -957,8 +957,6 @@ JS::IncrementalObjectBarrier(JSObject *obj)
JS_ASSERT(!obj->zone()->runtimeFromMainThread()->isHeapMajorCollecting());
- AutoMarkInDeadZone amn(obj->zone());
-
JSObject::writeBarrierPre(obj);
}
@@ -969,13 +967,13 @@ JS::IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind)
return;
gc::Cell *cell = static_cast(ptr);
+
+#ifdef DEBUG
Zone *zone = kind == JSTRACE_OBJECT
? static_cast(cell)->zone()
: cell->tenuredZone();
-
JS_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting());
-
- AutoMarkInDeadZone amn(zone);
+#endif
if (kind == JSTRACE_OBJECT)
JSObject::writeBarrierPre(static_cast(cell));
diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h
index c93e6fb19491..82b67ab929c6 100644
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -2064,9 +2064,6 @@ IdToValue(jsid id)
return JS::UndefinedValue();
}
-extern JS_FRIEND_API(bool)
-IsTypedArrayThisCheck(JS::IsAcceptableThis test);
-
/*
* If the embedder has registered a default JSContext callback, returns the
* result of the callback. Otherwise, asserts that |rt| has exactly one
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index 98add3a402a2..25243add4c63 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -3100,14 +3100,14 @@ GCRuntime::beginMarkPhase()
isFull = false;
}
- zone->scheduledForDestruction = false;
- zone->maybeAlive = false;
zone->setPreservingCode(false);
}
for (CompartmentsIter c(rt, WithAtoms); !c.done(); c.next()) {
JS_ASSERT(c->gcLiveArrayBuffers.empty());
c->marked = false;
+ c->scheduledForDestruction = false;
+ c->maybeAlive = false;
if (shouldPreserveJITCode(c, currentTime))
c->zone()->setPreservingCode(true);
}
@@ -3208,40 +3208,50 @@ GCRuntime::beginMarkPhase()
bufferGrayRoots();
/*
- * This code ensures that if a zone is "dead", then it will be
- * collected in this GC. A zone is considered dead if its maybeAlive
+ * This code ensures that if a compartment is "dead", then it will be
+ * collected in this GC. A compartment is considered dead if its maybeAlive
* flag is false. The maybeAlive flag is set if:
- * (1) the zone has incoming cross-compartment edges, or
- * (2) an object in the zone was marked during root marking, either
+ * (1) the compartment has incoming cross-compartment edges, or
+ * (2) an object in the compartment was marked during root marking, either
* as a black root or a gray root.
* If the maybeAlive is false, then we set the scheduledForDestruction flag.
- * At any time later in the GC, if we try to mark an object whose
- * zone is scheduled for destruction, we will assert.
- * NOTE: Due to bug 811587, we only assert if gcManipulatingDeadCompartments
- * is true (e.g., if we're doing a brain transplant).
+ * At the end of the GC, we look for compartments where
+ * scheduledForDestruction is true. These are compartments that were somehow
+ * "revived" during the incremental GC. If any are found, we do a special,
+ * non-incremental GC of those compartments to try to collect them.
*
- * The purpose of this check is to ensure that a zone that we would
- * normally destroy is not resurrected by a read barrier or an
- * allocation. This might happen during a function like JS_TransplantObject,
- * which iterates over all compartments, live or dead, and operates on their
- * objects. See bug 803376 for details on this problem. To avoid the
- * problem, we are very careful to avoid allocation and read barriers during
- * JS_TransplantObject and the like. The code here ensures that we don't
- * regress.
+ * Compartments can be revived for a variety of reasons. On reason is bug
+ * 811587, where a reflector that was dead can be revived by DOM code that
+ * still refers to the underlying DOM node.
*
- * Note that there are certain cases where allocations or read barriers in
- * dead zone are difficult to avoid. We detect such cases (via the
- * gcObjectsMarkedInDeadCompartment counter) and redo any ongoing GCs after
- * the JS_TransplantObject function has finished. This ensures that the dead
- * zones will be cleaned up. See AutoMarkInDeadZone and
- * AutoMaybeTouchDeadZones for details.
+ * Read barriers and allocations can also cause revival. This might happen
+ * during a function like JS_TransplantObject, which iterates over all
+ * compartments, live or dead, and operates on their objects. See bug 803376
+ * for details on this problem. To avoid the problem, we try to avoid
+ * allocation and read barriers during JS_TransplantObject and the like.
*/
/* Set the maybeAlive flag based on cross-compartment edges. */
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
- Cell *dst = e.front().key().wrapped;
- dst->tenuredZone()->maybeAlive = true;
+ const CrossCompartmentKey &key = e.front().key();
+ JSCompartment *dest;
+ switch (key.kind) {
+ case CrossCompartmentKey::ObjectWrapper:
+ case CrossCompartmentKey::DebuggerObject:
+ case CrossCompartmentKey::DebuggerSource:
+ case CrossCompartmentKey::DebuggerEnvironment:
+ dest = static_cast(key.wrapped)->compartment();
+ break;
+ case CrossCompartmentKey::DebuggerScript:
+ dest = static_cast(key.wrapped)->compartment();
+ break;
+ default:
+ dest = nullptr;
+ break;
+ }
+ if (dest)
+ dest->maybeAlive = true;
}
}
@@ -3250,9 +3260,9 @@ GCRuntime::beginMarkPhase()
* during MarkRuntime.
*/
- for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
- if (!zone->maybeAlive && !rt->isAtomsZone(zone))
- zone->scheduledForDestruction = true;
+ for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
+ if (!c->maybeAlive && !rt->isAtomsCompartment(c))
+ c->scheduledForDestruction = true;
}
foundBlackGrayEdges = false;
@@ -4567,8 +4577,8 @@ GCRuntime::resetIncrementalGC(const char *reason)
case SWEEP:
marker.reset();
- for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
- zone->scheduledForDestruction = false;
+ for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next())
+ c->scheduledForDestruction = false;
/* Finish sweeping the current zone group, then abort. */
abortSweepAfterCurrentGroup = true;
@@ -5076,13 +5086,30 @@ GCRuntime::collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
if (poked && shouldCleanUpEverything)
JS::PrepareForFullGC(rt);
+ /*
+ * This code makes an extra effort to collect compartments that we
+ * thought were dead at the start of the GC. See the large comment in
+ * beginMarkPhase.
+ */
+ bool repeatForDeadZone = false;
+ if (incremental && incrementalState == NO_INCREMENTAL) {
+ for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
+ if (c->scheduledForDestruction) {
+ incremental = false;
+ repeatForDeadZone = true;
+ reason = JS::gcreason::COMPARTMENT_REVIVED;
+ c->zone()->scheduleGC();
+ }
+ }
+ }
+
/*
* If we reset an existing GC, we need to start a new one. Also, we
* repeat GCs that happen during shutdown (the gcShouldCleanUpEverything
* case) until we can be sure that no additional garbage is created
* (which typically happens if roots are dropped during finalizers).
*/
- repeat = (poked && shouldCleanUpEverything) || wasReset;
+ repeat = (poked && shouldCleanUpEverything) || wasReset || repeatForDeadZone;
} while (repeat);
if (incrementalState == NO_INCREMENTAL) {
@@ -5654,34 +5681,6 @@ ArenaLists::containsArena(JSRuntime *rt, ArenaHeader *needle)
}
-AutoMaybeTouchDeadZones::AutoMaybeTouchDeadZones(JSContext *cx)
- : runtime(cx->runtime()),
- markCount(runtime->gc.objectsMarkedInDeadZonesCount()),
- inIncremental(JS::IsIncrementalGCInProgress(runtime)),
- manipulatingDeadZones(runtime->gc.isManipulatingDeadZones())
-{
- runtime->gc.setManipulatingDeadZones(true);
-}
-
-AutoMaybeTouchDeadZones::AutoMaybeTouchDeadZones(JSObject *obj)
- : runtime(obj->compartment()->runtimeFromMainThread()),
- markCount(runtime->gc.objectsMarkedInDeadZonesCount()),
- inIncremental(JS::IsIncrementalGCInProgress(runtime)),
- manipulatingDeadZones(runtime->gc.isManipulatingDeadZones())
-{
- runtime->gc.setManipulatingDeadZones(true);
-}
-
-AutoMaybeTouchDeadZones::~AutoMaybeTouchDeadZones()
-{
- runtime->gc.setManipulatingDeadZones(manipulatingDeadZones);
-
- if (inIncremental && runtime->gc.objectsMarkedInDeadZonesCount() != markCount) {
- JS::PrepareForFullGC(runtime);
- js::GC(runtime, GC_NORMAL, JS::gcreason::TRANSPLANT);
- }
-}
-
AutoSuppressGC::AutoSuppressGC(ExclusiveContext *cx)
: suppressGC_(cx->perThreadData->suppressGC)
{
diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h
index 118b1f77f91a..bbf6c4b2bac6 100644
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -16,33 +16,6 @@ namespace js {
class Shape;
-/*
- * This auto class should be used around any code that might cause a mark bit to
- * be set on an object in a dead zone. See AutoMaybeTouchDeadZones
- * for more details.
- */
-struct AutoMarkInDeadZone
-{
- explicit AutoMarkInDeadZone(JS::Zone *zone)
- : zone(zone),
- scheduled(zone->scheduledForDestruction)
- {
- gc::GCRuntime &gc = zone->runtimeFromMainThread()->gc;
- if (gc.isManipulatingDeadZones() && zone->scheduledForDestruction) {
- gc.incObjectsMarkedInDeadZone();
- zone->scheduledForDestruction = false;
- }
- }
-
- ~AutoMarkInDeadZone() {
- zone->scheduledForDestruction = scheduled;
- }
-
- private:
- JS::Zone *zone;
- bool scheduled;
-};
-
inline Allocator *
ThreadSafeContext::allocator() const
{
diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
index 1e1dd7b62896..1763e5f6f515 100644
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2505,9 +2505,6 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
bool
JSObject::swap(JSContext *cx, HandleObject a, HandleObject b)
{
- AutoMarkInDeadZone adc1(a->zone());
- AutoMarkInDeadZone adc2(b->zone());
-
// Ensure swap doesn't cause a finalizer to not be run.
JS_ASSERT(IsBackgroundFinalized(a->tenuredGetAllocKind()) ==
IsBackgroundFinalized(b->tenuredGetAllocKind()));
diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp
index f5f82401ce24..612342b05ff6 100644
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -369,9 +369,6 @@ static const JSFunctionSpec string_functions[] = {
JS_FS_END
};
-const jschar js_empty_ucstr[] = {0};
-const JSSubString js_EmptySubString = {0, js_empty_ucstr};
-
static const unsigned STRING_ELEMENT_ATTRS = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
static bool
@@ -2488,7 +2485,6 @@ struct ReplaceData
RootedLinearString repstr; /* replacement string */
uint32_t dollarIndex; /* index of first $ in repstr, or UINT32_MAX */
int leftIndex; /* left context index in str->chars */
- JSSubString dollarStr; /* for "$$" InterpretDollar result */
bool calledBack; /* record whether callback has been called */
FastInvokeGuard fig; /* used for lambda calls, also holds arguments */
StringBuffer sb; /* buffer built during DoMatch */
@@ -2592,9 +2588,7 @@ InterpretDollar(RegExpStatics *res, const jschar *dp, const jschar *ep,
*skip = 2;
switch (dc) {
case '$':
- rdata.dollarStr.chars = dp;
- rdata.dollarStr.length = 1;
- *out = rdata.dollarStr;
+ out->init(rdata.repstr, dp - rdata.repstr->chars(), 1);
return true;
case '&':
res->getLastMatch(out);
@@ -2758,7 +2752,7 @@ DoReplace(RegExpStatics *res, ReplaceData &rdata)
JSSubString sub;
size_t skip;
if (InterpretDollar(res, dp, ep, rdata, &sub, &skip)) {
- rdata.sb.infallibleAppend(sub.chars, sub.length);
+ rdata.sb.infallibleAppendSubstring(sub.base, sub.offset, sub.length);
cp += skip;
dp += skip;
} else {
@@ -3203,7 +3197,7 @@ StrReplaceRegExp(JSContext *cx, ReplaceData &rdata, MutableHandleValue rval)
JSSubString sub;
res->getRightContext(&sub);
- if (!rdata.sb.append(sub.chars, sub.length))
+ if (!rdata.sb.appendSubstring(sub.base, sub.offset, sub.length))
return false;
JSString *retstr = rdata.sb.finishString();
@@ -3592,7 +3586,8 @@ SplitHelper(JSContext *cx, HandleLinearString str, uint32_t limit, const Matcher
if (!matches[i + 1].isUndefined()) {
JSSubString parsub;
res->getParen(i + 1, &parsub);
- sub = js_NewStringCopyN(cx, parsub.chars, parsub.length);
+ sub = js_NewStringCopyN(cx, parsub.base->chars() + parsub.offset,
+ parsub.length);
if (!sub || !splits.append(StringValue(sub)))
return nullptr;
} else {
diff --git a/js/src/jsstr.h b/js/src/jsstr.h
index 268cb5d5a8b9..aa7ae0fbb015 100644
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -64,12 +64,22 @@ CompareChars(const Char1 *s1, size_t len1, const Char2 *s2, size_t len2)
} /* namespace js */
struct JSSubString {
+ JSLinearString *base;
+ size_t offset;
size_t length;
- const jschar *chars;
-};
-extern const jschar js_empty_ucstr[];
-extern const JSSubString js_EmptySubString;
+ JSSubString() { mozilla::PodZero(this); }
+
+ void initEmpty(JSLinearString *base) {
+ this->base = base;
+ offset = length = 0;
+ }
+ void init(JSLinearString *base, size_t offset, size_t length) {
+ this->base = base;
+ this->offset = offset;
+ this->length = length;
+ }
+};
/*
* Shorthands for ASCII (7-bit) decimal and hex conversion.
diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp
index 5db847b4548b..382a99ee8ad6 100644
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -44,8 +44,6 @@ Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, Wrapper *handler,
{
JS_ASSERT(parent);
- AutoMarkInDeadZone amd(cx->zone());
-
RootedValue priv(cx, ObjectValue(*obj));
mozilla::Maybe opts;
if (!options) {
@@ -1043,8 +1041,6 @@ JS_FRIEND_API(bool)
js::RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter,
const CompartmentFilter &targetFilter)
{
- AutoMaybeTouchDeadZones agc(cx);
-
AutoWrapperVector toRecompute(cx);
for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h
index a7561958bf42..762ad1c3e199 100644
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -303,34 +303,6 @@ JS_FRIEND_API(bool)
RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter,
const CompartmentFilter &targetFilter);
-/*
- * This auto class should be used around any code, such as brain transplants,
- * that may touch dead zones. Brain transplants can cause problems
- * because they operate on all compartments, whether live or dead. A brain
- * transplant can cause a formerly dead object to be "reanimated" by causing a
- * read or write barrier to be invoked on it during the transplant. In this way,
- * a zone becomes a zombie, kept alive by repeatedly consuming
- * (transplanted) brains.
- *
- * To work around this issue, we observe when mark bits are set on objects in
- * dead zones. If this happens during a brain transplant, we do a full,
- * non-incremental GC at the end of the brain transplant. This will clean up any
- * objects that were improperly marked.
- */
-struct JS_FRIEND_API(AutoMaybeTouchDeadZones)
-{
- // The version that takes an object just uses it for its runtime.
- explicit AutoMaybeTouchDeadZones(JSContext *cx);
- explicit AutoMaybeTouchDeadZones(JSObject *obj);
- ~AutoMaybeTouchDeadZones();
-
- private:
- JSRuntime *runtime;
- unsigned markCount;
- bool inIncremental;
- bool manipulatingDeadZones;
-};
-
} /* namespace js */
#endif /* jswrapper_h */
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
index 42b794dcbfcd..c7edc4d5eb16 100644
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2093,7 +2093,7 @@ Debugger::addAllGlobalsAsDebuggees(JSContext *cx, unsigned argc, Value *vp)
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
if (c == dbg->object->compartment() || c->options().invisibleToDebugger())
continue;
- c->zone()->scheduledForDestruction = false;
+ c->scheduledForDestruction = false;
GlobalObject *global = c->maybeGlobal();
if (global) {
Rooted rg(cx, global);
@@ -2890,7 +2890,7 @@ Debugger::findAllGlobals(JSContext *cx, unsigned argc, Value *vp)
if (c->options().invisibleToDebugger())
continue;
- c->zone()->scheduledForDestruction = false;
+ c->scheduledForDestruction = false;
GlobalObject *global = c->maybeGlobal();
diff --git a/js/src/vm/ProxyObject.cpp b/js/src/vm/ProxyObject.cpp
index e8521ee7647a..384852dc93d9 100644
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -77,14 +77,7 @@ ProxyObject::initHandler(BaseProxyHandler *handler)
static void
NukeSlot(ProxyObject *proxy, uint32_t slot)
{
- Value old = proxy->getSlot(slot);
- if (old.isMarkable()) {
- Zone *zone = ZoneOfValue(old);
- AutoMarkInDeadZone amd(zone);
- proxy->setReservedSlot(slot, NullValue());
- } else {
- proxy->setReservedSlot(slot, NullValue());
- }
+ proxy->setReservedSlot(slot, NullValue());
}
void
diff --git a/js/src/vm/RegExpStatics.h b/js/src/vm/RegExpStatics.h
index 8b8db38efac5..8e408ac397c4 100644
--- a/js/src/vm/RegExpStatics.h
+++ b/js/src/vm/RegExpStatics.h
@@ -343,11 +343,10 @@ RegExpStatics::getParen(size_t pairNum, JSSubString *out) const
JS_ASSERT(pairNum >= 1 && pairNum < matches.pairCount());
const MatchPair &pair = matches[pairNum];
if (pair.isUndefined()) {
- *out = js_EmptySubString;
+ out->initEmpty(matchesInput);
return;
}
- out->chars = matchesInput->chars() + pair.start;
- out->length = pair.length();
+ out->init(matchesInput, pair.start, pair.length());
}
inline void
@@ -356,13 +355,12 @@ RegExpStatics::getLastMatch(JSSubString *out) const
JS_ASSERT(!pendingLazyEvaluation);
if (matches.empty()) {
- *out = js_EmptySubString;
+ out->initEmpty(matchesInput);
return;
}
JS_ASSERT(matchesInput);
- out->chars = matchesInput->chars() + matches[0].start;
JS_ASSERT(matches[0].limit >= matches[0].start);
- out->length = matches[0].length();
+ out->init(matchesInput, matches[0].start, matches[0].length());
}
inline void
@@ -372,7 +370,7 @@ RegExpStatics::getLastParen(JSSubString *out) const
/* Note: the first pair is the whole match. */
if (matches.empty() || matches.pairCount() == 1) {
- *out = js_EmptySubString;
+ out->initEmpty(matchesInput);
return;
}
getParen(matches.parenCount(), out);
@@ -384,11 +382,10 @@ RegExpStatics::getLeftContext(JSSubString *out) const
JS_ASSERT(!pendingLazyEvaluation);
if (matches.empty()) {
- *out = js_EmptySubString;
+ out->initEmpty(matchesInput);
return;
}
- out->chars = matchesInput->chars();
- out->length = matches[0].start;
+ out->init(matchesInput, 0, matches[0].start);
}
inline void
@@ -397,12 +394,12 @@ RegExpStatics::getRightContext(JSSubString *out) const
JS_ASSERT(!pendingLazyEvaluation);
if (matches.empty()) {
- *out = js_EmptySubString;
+ out->initEmpty(matchesInput);
return;
}
- out->chars = matchesInput->chars() + matches[0].limit;
JS_ASSERT(matches[0].limit <= int(matchesInput->length()));
- out->length = matchesInput->length() - matches[0].limit;
+ size_t length = matchesInput->length() - matches[0].limit;
+ out->init(matchesInput, matches[0].limit, length);
}
inline void
diff --git a/js/src/vm/StringBuffer.h b/js/src/vm/StringBuffer.h
index 42fa2604dbd0..27fbfde09a1c 100644
--- a/js/src/vm/StringBuffer.h
+++ b/js/src/vm/StringBuffer.h
@@ -172,6 +172,8 @@ class StringBuffer
infallibleAppend(reinterpret_cast(chars), len);
}
+ void infallibleAppendSubstring(JSLinearString *base, size_t off, size_t len);
+
/*
* Because inflation is fallible, these methods should only be used after
* calling ensureTwoByteChars().
@@ -249,6 +251,19 @@ StringBuffer::append(JSLinearString *str)
: twoByteChars().append(str->twoByteChars(nogc), str->length());
}
+inline void
+StringBuffer::infallibleAppendSubstring(JSLinearString *base, size_t off, size_t len)
+{
+ MOZ_ASSERT(off + len <= base->length());
+ MOZ_ASSERT(base->hasLatin1Chars() == isLatin1());
+
+ JS::AutoCheckCannotGC nogc;
+ if (base->hasLatin1Chars())
+ infallibleAppend(base->latin1Chars(nogc) + off, len);
+ else
+ infallibleAppend(base->twoByteChars(nogc) + off, len);
+}
+
inline bool
StringBuffer::appendSubstring(JSLinearString *base, size_t off, size_t len)
{
diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp
index d8d3d63ae09c..db9da65ea3a4 100644
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -2153,6 +2153,17 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Uint32, uint32_t, uint32_t)
IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float32, float, float)
IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
+#define TYPED_ARRAY_CLASS_SPEC(_typedArray) \
+{ \
+ GenericCreateConstructor<_typedArray##Object::class_constructor, \
+ NAME_OFFSET(_typedArray), 3>, \
+ _typedArray##Object::CreatePrototype, \
+ nullptr, \
+ _typedArray##Object::jsfuncs, \
+ _typedArray##Object::jsprops, \
+ _typedArray##Object::FinishClassInit \
+}
+
#define IMPL_TYPED_ARRAY_PROTO_CLASS(_typedArray) \
{ \
#_typedArray "Prototype", \
@@ -2165,7 +2176,13 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
JS_StrictPropertyStub, /* setProperty */ \
JS_EnumerateStub, \
JS_ResolveStub, \
- JS_ConvertStub \
+ JS_ConvertStub, \
+ nullptr, /* finalize */ \
+ nullptr, /* call */ \
+ nullptr, /* hasInstance */ \
+ nullptr, /* construct */ \
+ nullptr, /* trace */ \
+ TYPED_ARRAY_CLASS_SPEC(_typedArray) \
}
#define IMPL_TYPED_ARRAY_FAST_CLASS(_typedArray) \
@@ -2186,15 +2203,7 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
nullptr, /* hasInstance */ \
nullptr, /* construct */ \
ArrayBufferViewObject::trace, /* trace */ \
- { \
- GenericCreateConstructor<_typedArray##Object::class_constructor, \
- NAME_OFFSET(_typedArray), 3>, \
- _typedArray##Object::CreatePrototype, \
- nullptr, \
- _typedArray##Object::jsfuncs, \
- _typedArray##Object::jsprops, \
- _typedArray##Object::FinishClassInit \
- } \
+ TYPED_ARRAY_CLASS_SPEC(_typedArray) \
}
template
@@ -2264,23 +2273,6 @@ const Class TypedArrayObject::protoClasses[ScalarTypeDescr::TYPE_MAX] = {
IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8ClampedArray)
};
-#define CHECK(t, a) { if (t == a::IsThisClass) return true; }
-JS_FRIEND_API(bool)
-js::IsTypedArrayThisCheck(JS::IsAcceptableThis test)
-{
- CHECK(test, Int8ArrayObject);
- CHECK(test, Uint8ArrayObject);
- CHECK(test, Int16ArrayObject);
- CHECK(test, Uint16ArrayObject);
- CHECK(test, Int32ArrayObject);
- CHECK(test, Uint32ArrayObject);
- CHECK(test, Float32ArrayObject);
- CHECK(test, Float64ArrayObject);
- CHECK(test, Uint8ClampedArrayObject);
- return false;
-}
-#undef CHECK
-
JSObject *
js_InitArrayBufferClass(JSContext *cx, HandleObject obj)
{
diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp
index f3e2238c9cf1..01a147d8c186 100644
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -356,9 +356,6 @@ XPCWrappedNative::GetNewOrUsed(xpcObjectHelper& helper,
mozilla::Maybe ac;
if (sciWrapper.GetFlags().WantPreCreate()) {
- // PreCreate may touch dead compartments.
- js::AutoMaybeTouchDeadZones agc(parent);
-
RootedObject plannedParent(cx, parent);
nsresult rv = sciWrapper.GetCallback()->PreCreate(identity, cx,
parent, parent.address());
@@ -1285,9 +1282,6 @@ RescueOrphans(HandleObject obj)
return NS_OK; // Global object. We're done.
parentObj = js::UncheckedUnwrap(parentObj, /* stopAtOuter = */ false);
- // PreCreate may touch dead compartments.
- js::AutoMaybeTouchDeadZones agc(parentObj);
-
// Recursively fix up orphans on the parent chain.
rv = RescueOrphans(parentObj);
NS_ENSURE_SUCCESS(rv, rv);
diff --git a/js/xpconnect/src/dom_quickstubs.qsconf b/js/xpconnect/src/dom_quickstubs.qsconf
index 6d9332076188..637d54346358 100644
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -61,8 +61,6 @@ members = [
'nsIBoxObject.width',
'nsIBoxObject.height',
- # dom/indexedDB
- 'nsIIndexedDatabaseManager.*',
]
# Most interfaces can be found by searching the includePath; to find
@@ -74,8 +72,6 @@ members = [
irregularFilenames = {
# stowaways
'nsIDOMBlob': 'nsIDOMFile',
- 'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
- 'nsITelephoneCallback': 'nsITelephone',
}
customIncludes = [
diff --git a/js/xpconnect/tests/chrome/test_bug760109.xul b/js/xpconnect/tests/chrome/test_bug760109.xul
index 27429c7baf72..d8045d464524 100644
--- a/js/xpconnect/tests/chrome/test_bug760109.xul
+++ b/js/xpconnect/tests/chrome/test_bug760109.xul
@@ -59,10 +59,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=760109
chromeArray.sort();
is(chromeArray.join(''), 'abz', "Able to call sort");
- // Make sure we can see the data on the typed array
- is(chromeTypedArray.length, 3, "Able to check typed array length");
- is(chromeTypedArray[0], 10, "Able to access typed array data");
-
// We should be able to .hasOwnProperty on the Object, and have
// it filter the objects we can see.
ok(chromeObject.hasOwnProperty('foo'), "Should see r property");
@@ -85,7 +81,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=760109
var sb = new Cu.Sandbox('http://www.example.org');
sb.chromeArray = ['a', 'b', 'z'];
sb.chromeArray.__exposedProps__ = {};
- sb.chromeTypedArray = new Uint8Array([10, 20, 30]);
sb.chromeObject = new SomeConstructor();
sb.ok = ok;
sb.is = is;
diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xul b/js/xpconnect/tests/chrome/test_xrayToJS.xul
index daf007236a19..65877e6ef6ba 100644
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
/** Test for ES constructors on Xrayed globals. **/
SimpleTest.waitForExplicitFinish();
+ const Cc = Components.classes;
+ const Ci = Components.interfaces;
const Cu = Components.utils;
let global = Cu.getGlobalForObject.bind(Cu);
@@ -33,13 +35,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
}
}
+ typedArrayClasses = ['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array',
+ 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array',
+ 'Uint8ClampedArray'];
simpleConstructors = ['Object', 'Function', 'Array', 'Boolean', 'Date', 'Number',
'String', 'RegExp', 'Error', 'InternalError', 'EvalError',
'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError',
- 'URIError', 'ArrayBuffer', 'Int8Array', 'Uint8Array',
- 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array',
- 'Float32Array', 'Float64Array', 'Uint8ClampedArray',
- 'WeakMap', 'Map', 'Set'];
+ 'URIError', 'ArrayBuffer', 'WeakMap', 'Map', 'Set'].concat(typedArrayClasses);
function go() {
window.iwin = document.getElementById('ifr').contentWindow;
@@ -117,6 +119,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
testArray();
+ testTypedArrays();
+
// We could also test DataView and Iterator here for completeness, but it's
// more trouble than it's worth.
@@ -129,6 +133,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
// Xray-safe.
//
// DO NOT CHANGE WTIHOUT REVIEW FROM AN XPCONNECT PEER.
+ var isReleaseBuild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).isReleaseBuild;
var gPrototypeProperties = {};
gPrototypeProperties['Date'] =
["getTime", "getTimezoneOffset", "getYear", "getFullYear", "getUTCFullYear",
@@ -153,6 +158,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
"forEach", "map", "reduce", "reduceRight", "filter", "some", "every", "mapPar",
"reducePar", "scanPar", "scatterPar", "filterPar", "find", "findIndex", "copyWithin",
"fill", "@@iterator", "entries", "keys", "constructor"];
+ for (var c of typedArrayClasses) {
+ gPrototypeProperties[c] = ["constructor", "BYTES_PER_ELEMENT", "length", "buffer",
+ "byteLength", "byteOffset", "@@iterator", "subarray", "set"];
+ if (!isReleaseBuild)
+ gPrototypeProperties[c].push("move");
+ }
function filterOut(array, props) {
return array.filter(p => props.indexOf(p) == -1);
@@ -168,29 +179,40 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
" prototype has been added! You need a security audit from an XPConnect peer");
let protoProps = filterOut(Object.getOwnPropertyNames(localProto), propsToSkip).sort();
- let protoMethods = protoProps.filter(name => typeof localProto[name] == 'function' &&
- name != 'constructor');
- ok(protoMethods.length > 0, "Need something to test");
+ let protoCallables = protoProps.filter(name => Object.getOwnPropertyDescriptor(localProto, name).get ||
+ typeof localProto[name] == 'function' &&
+ name != 'constructor');
+ let protoGetters = protoProps.filter(name => Object.getOwnPropertyDescriptor(localProto, name).get);
+ ok(protoCallables.length > 0, "Need something to test");
is(xrayProto, iwin[classname].prototype, "Xray proto is correct");
is(xrayProto, xray.__proto__, "Proto accessors agree");
var protoProto = classname == "Object" ? null : iwin.Object.prototype;
is(Object.getPrototypeOf(xrayProto), protoProto, "proto proto is correct");
- for (let name of protoMethods) {
+ for (let name of protoCallables) {
info("Running tests for property: " + name);
+ // Test both methods and getter properties.
+ function lookupCallable(obj) {
+ let desc = null;
+ do {
+ desc = Object.getOwnPropertyDescriptor(obj, name);
+ obj = Object.getPrototypeOf(obj);
+ } while (!desc);
+ return desc.get || desc.value;
+ };
ok(xrayProto.hasOwnProperty(name), "proto should have the property as own");
ok(!xray.hasOwnProperty(name), "instance should not have the property as own");
- let method = xrayProto[name];
+ let method = lookupCallable(xrayProto);
is(typeof method, 'function', "Methods from Xrays are functions");
is(global(method), window, "Methods from Xrays are local");
ok(method instanceof Function, "instanceof works on methods from Xrays");
- is(xrayProto[name], method, "Holder caching works properly");
- is(xray[name], method, "Proto props resolve on the instance");
- let local = localProto[name];
+ is(lookupCallable(xrayProto), method, "Holder caching works properly");
+ is(lookupCallable(xray), method, "Proto props resolve on the instance");
+ let local = lookupCallable(localProto);
is(method.length, local.length, "Function.length identical");
if (method.length == 0) {
- is(xray[name]() + "", local.call(xray) + "",
+ is(method.call(xray) + "", local.call(xray) + "",
"Xray and local method results stringify identically");
- is(xray[name]() + "", xray.wrappedJSObject[name]() + "",
+ is(method.call(xray) + "", lookupCallable(xray.wrappedJSObject).call(xray.wrappedJSObject) + "",
"Xray and waived method results stringify identically");
}
}
@@ -360,6 +382,28 @@ function testTrickyObject(trickyObject) {
/accessor property/, "Should reject accessor property definition");
}
+ function testTypedArrays() {
+ for (var c of typedArrayClasses) {
+ testXray(c, new iwin[c](4), new iwin[c](), ['BYTES_PER_ELEMENT']);
+
+ var t = new iwin[c](10);
+ checkThrows(function() { t[2]; }, /performant/, "direct property-wise reading of typed arrays forbidden over Xrays");
+ checkThrows(function() { t[2] = 3; }, /performant/, "direct property-wise writing of typed arrays forbidden over Xrays");
+ t.wrappedJSObject[2] = 3;
+ is(t.wrappedJSObject[2], 3, "accessing elements over waivers works");
+ t.wrappedJSObject.expando = 'hi';
+ is(t.wrappedJSObject.expando, 'hi', "access expandos over waivers works");
+ is(Cu.cloneInto(t, window)[2], 3, "cloneInto works");
+ is(Cu.cloneInto(t, window).expando, undefined, "cloneInto does not copy expandos");
+ is(Object.getOwnPropertyNames(t).sort().toSource(), Array.apply(null, Array(10)).map(function (_, i) {return i + "";}).toSource(),
+ "Only indexed properties visible over Xrays");
+ Object.defineProperty(t.wrappedJSObject, 'length', {value: 42});
+ is(t.wrappedJSObject.length, 42, "Set tricky expando")
+ is(t.length, 10, "Length accessor works over Xrays")
+ is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays")
+ }
+ }
+
]]>
diff --git a/js/xpconnect/tests/unit/test_bug809652.js b/js/xpconnect/tests/unit/test_bug809652.js
index 65bfdf7c19ad..3a2724303256 100644
--- a/js/xpconnect/tests/unit/test_bug809652.js
+++ b/js/xpconnect/tests/unit/test_bug809652.js
@@ -46,11 +46,12 @@ function run_test() {
/* Typed arrays. */
function testForTypedArray(t) {
sb.curr = t;
- do_check_eq(Cu.evalInSandbox("this[curr.constructor.name].prototype.subarray.call(curr, 0)[0]", sb), t[0]);
- do_check_eq(Cu.evalInSandbox("(new this[curr.constructor.name]).__lookupGetter__('length').call(curr)", sb), t.length);
- do_check_eq(Cu.evalInSandbox("(new this[curr.constructor.name]).__lookupGetter__('buffer').call(curr)", sb), sb.ab);
- do_check_eq(Cu.evalInSandbox("(new this[curr.constructor.name]).__lookupGetter__('byteOffset').call(curr)", sb), t.byteOffset);
- do_check_eq(Cu.evalInSandbox("(new this[curr.constructor.name]).__lookupGetter__('byteLength').call(curr)", sb), t.byteLength);
+ sb.currName = t.constructor.name;
+ checkThrows("this[currName].prototype.subarray.call(curr, 0)[0]", sb);
+ checkThrows("(new this[currName]).__lookupGetter__('length').call(curr)", sb);
+ checkThrows("(new this[currName]).__lookupGetter__('buffer').call(curr)", sb);
+ checkThrows("(new this[currName]).__lookupGetter__('byteOffset').call(curr)", sb);
+ checkThrows("(new this[currName]).__lookupGetter__('byteLength').call(curr)", sb);
}
sb.ta.forEach(testForTypedArray);
}
diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp
index 6e9fcc7c5990..9a7aa535b244 100644
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -333,11 +333,4 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapperArg, jsid idArg, Wr
return true;
}
-bool
-ExposedPropertiesOnly::allowNativeCall(JSContext *cx, JS::IsAcceptableThis test,
- JS::NativeImpl impl)
-{
- return js::IsTypedArrayThisCheck(test);
-}
-
}
diff --git a/js/xpconnect/wrappers/AccessCheck.h b/js/xpconnect/wrappers/AccessCheck.h
index 65958422414f..a40a6db459c6 100644
--- a/js/xpconnect/wrappers/AccessCheck.h
+++ b/js/xpconnect/wrappers/AccessCheck.h
@@ -101,7 +101,9 @@ struct ExposedPropertiesOnly : public Policy {
// Fail silently for GETs and ENUMERATEs.
return act == js::Wrapper::GET || act == js::Wrapper::ENUMERATE;
}
- static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl);
+ static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
+ return false;
+ }
};
}
diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp
index c4fed9fac84b..e5894b3e51e4 100644
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -39,10 +39,34 @@ namespace xpc {
using namespace XrayUtils;
+inline bool
+IsTypedArrayKey(JSProtoKey key)
+{
+#ifdef DEBUG
+ bool isTypedArraySlow = key == JSProto_Int8Array ||
+ key == JSProto_Uint8Array ||
+ key == JSProto_Int16Array ||
+ key == JSProto_Uint16Array ||
+ key == JSProto_Int32Array ||
+ key == JSProto_Uint32Array ||
+ key == JSProto_Float32Array ||
+ key == JSProto_Float64Array ||
+ key == JSProto_Uint8ClampedArray;
+#endif
+ bool isTypedArray = key >= JSProto_Int8Array &&
+ key <= JSProto_Uint8ClampedArray;
+ MOZ_ASSERT(isTypedArray == isTypedArraySlow, "Somebody reordered jsprototypes.h!");
+ static_assert(JSProto_Uint8ClampedArray - JSProto_Int8Array == 8,
+ "New prototype added in typed array range");
+ return isTypedArray;
+}
+
// Whitelist for the standard ES classes we can Xray to.
static bool
IsJSXraySupported(JSProtoKey key)
{
+ if (IsTypedArrayKey(key))
+ return true;
switch (key) {
case JSProto_Date:
case JSProto_Object:
@@ -464,24 +488,8 @@ bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext *cx,
return SilentFailure(cx, id, "Value not same-origin with target");
// Disallow non-Xrayable objects.
- if (GetXrayType(propObj) == NotXray) {
- // Note - We're going add Xrays for Arrays/TypedArrays soon in
- // bug 987163, so we don't want to cause unnecessary compat churn
- // by making xrayedObj.arrayProp stop working temporarily, and then
- // start working again. At the same time, this is an important check,
- // and this patch wouldn't be as useful without it. So we just
- // forcibly override the behavior here for Arrays until bug 987163
- // lands.
- JSProtoKey key = IdentifyStandardInstanceOrPrototype(propObj);
- if (key != JSProto_Uint8ClampedArray &&
- key != JSProto_Int8Array && key != JSProto_Uint8Array &&
- key != JSProto_Int16Array && key != JSProto_Uint16Array &&
- key != JSProto_Int32Array && key != JSProto_Uint32Array &&
- key != JSProto_Float32Array && key != JSProto_Float64Array)
- {
- return SilentFailure(cx, id, "Value not Xrayable");
- }
- }
+ if (GetXrayType(propObj) == NotXray)
+ return SilentFailure(cx, id, "Value not Xrayable");
// Disallow callables.
if (JS_ObjectIsCallable(cx, propObj))
@@ -520,6 +528,7 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper,
RootedObject target(cx, getTargetObject(wrapper));
if (!isPrototype(holder)) {
+ JSProtoKey key = getProtoKey(holder);
// For Object and Array instances, we expose some properties from the
// underlying object, but only after filtering them carefully.
//
@@ -529,19 +538,20 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper,
// it's tempting to try to impose some sort of structure on what Arrays
// "should" look like over Xrays, the underlying object is squishy enough
// that it makes sense to just treat them like Objects for Xray purposes.
- switch (getProtoKey(holder)) {
- case JSProto_Object:
- case JSProto_Array:
+ if (key == JSProto_Object || key == JSProto_Array) {
{
JSAutoCompartment ac(cx, target);
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, desc))
return false;
}
return JS_WrapPropertyDescriptor(cx, desc);
-
- default:
- // Most instance (non-prototypes) Xrays don't have anything on them.
- break;
+ } else if (IsTypedArrayKey(key)) {
+ if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
+ JS_ReportError(cx, "Accessing TypedArray data over Xrays is slow, and forbidden "
+ "in order to encourage performant code. To copy TypedArrays "
+ "across origin boundaries, consider using Components.utils.cloneInto().");
+ return false;
+ }
}
// The rest of this function applies only to prototypes.
@@ -763,11 +773,10 @@ JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags
return false;
if (!isPrototype(holder)) {
+ JSProtoKey key = getProtoKey(holder);
// For Object and Array instances, we expose some properties from the underlying
// object, but only after filtering them carefully.
- switch (getProtoKey(holder)) {
- case JSProto_Object:
- case JSProto_Array:
+ if (key == JSProto_Object || key == JSProto_Array) {
MOZ_ASSERT(props.empty());
{
JSAutoCompartment ac(cx, target);
@@ -776,19 +785,26 @@ JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags
return false;
// Loop over the properties, and only pass along the ones that
// we determine to be safe.
+ if (!props.reserve(targetProps.length()))
+ return false;
for (size_t i = 0; i < targetProps.length(); ++i) {
Rooted desc(cx);
RootedId id(cx, targetProps[i]);
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
return false;
if (desc.object())
- props.append(id);
+ props.infallibleAppend(id);
}
}
return JS_WrapAutoIdVector(cx, props);
- default:
- // Most instance (non-prototypes) Xrays don't have anything on them.
- break;
+ } else if (IsTypedArrayKey(key)) {
+ uint32_t length = JS_GetTypedArrayLength(target);
+ // TypedArrays enumerate every indexed property in range, but
+ // |length| is a getter that lives on the proto, like it should be.
+ if (!props.reserve(length))
+ return false;
+ for (int32_t i = 0; i <= int32_t(length - 1); ++i)
+ props.infallibleAppend(INT_TO_JSID(i));
}
// The rest of this function applies only to prototypes.
@@ -1654,13 +1670,15 @@ XPCWrappedNativeXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper,
return false;
// Go through the properties we got and enumerate all native ones.
+ if (!props.reserve(wnProps.length()))
+ return false;
for (size_t n = 0; n < wnProps.length(); ++n) {
RootedId id(cx, wnProps[n]);
bool hasProp;
if (!JS_HasPropertyById(cx, wrapper, id, &hasProp))
return false;
if (hasProp)
- props.append(id);
+ props.infallibleAppend(id);
}
return true;
}
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 1f0524beef2e..d2ef6ae7adb8 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -5164,11 +5164,11 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
// and will sometimes get incorrect results (e.g. rotated blurs)
gfxMatrix transform = aDestinationCtx->CurrentMatrix();
// XXX: we could probably handle negative scales but for now it's easier just to fallback
- if (transform.HasNonAxisAlignedTransform() || transform.xx <= 0.0 || transform.yy <= 0.0) {
+ if (transform.HasNonAxisAlignedTransform() || transform._11 <= 0.0 || transform._22 <= 0.0) {
transform = gfxMatrix();
} else {
- scaleX = transform.xx;
- scaleY = transform.yy;
+ scaleX = transform._11;
+ scaleY = transform._22;
}
// compute a large or smaller blur radius
@@ -5288,9 +5288,9 @@ nsContextBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
// and will sometimes get incorrect results (e.g. rotated blurs)
gfxMatrix transform = aDestinationCtx->CurrentMatrix();
// XXX: we could probably handle negative scales but for now it's easier just to fallback
- if (!transform.HasNonAxisAlignedTransform() && transform.xx > 0.0 && transform.yy > 0.0) {
- scaleX = transform.xx;
- scaleY = transform.yy;
+ if (!transform.HasNonAxisAlignedTransform() && transform._11 > 0.0 && transform._22 > 0.0) {
+ scaleX = transform._11;
+ scaleY = transform._22;
aDestinationCtx->IdentityMatrix();
} else {
transform = gfxMatrix();
diff --git a/layout/base/nsCSSRenderingBorders.cpp b/layout/base/nsCSSRenderingBorders.cpp
index 8677d36cb208..1466e02b4693 100644
--- a/layout/base/nsCSSRenderingBorders.cpp
+++ b/layout/base/nsCSSRenderingBorders.cpp
@@ -1598,8 +1598,8 @@ nsCSSBorderRenderer::DrawBorders()
mAvoidStroke = true;
}
} else {
- mat.x0 = floor(mat.x0 + 0.5);
- mat.y0 = floor(mat.y0 + 0.5);
+ mat._31 = floor(mat._31 + 0.5);
+ mat._32 = floor(mat._32 + 0.5);
mContext->SetMatrix(mat);
// round mOuterRect and mInnerRect; they're already an integer
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index d32bbe397959..b183f28271e6 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4938,7 +4938,7 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
// we have something that's not translation+scale, or if the scale flips in
// the X or Y direction, because snapped image drawing can't handle that yet.
if (!currentMatrix.HasNonAxisAlignedTransform() &&
- currentMatrix.xx > 0.0 && currentMatrix.yy > 0.0 &&
+ currentMatrix._11 > 0.0 && currentMatrix._22 > 0.0 &&
aCtx->UserToDevicePixelSnapped(fill, true)) {
didSnap = true;
if (fill.IsEmpty()) {
@@ -4987,8 +4987,8 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
if (didSnap) {
// We'll reset aCTX to the identity matrix before drawing, so we need to
// adjust our scales to match.
- scaleX /= currentMatrix.xx;
- scaleY /= currentMatrix.yy;
+ scaleX /= currentMatrix._11;
+ scaleY /= currentMatrix._22;
}
gfxFloat translateX = imageSpaceAnchorPoint.x - anchorPoint.x*scaleX;
gfxFloat translateY = imageSpaceAnchorPoint.y - anchorPoint.y*scaleY;
diff --git a/layout/build/nsLayoutCID.h b/layout/build/nsLayoutCID.h
index fe9d2bb295ab..5e7d639b86cc 100644
--- a/layout/build/nsLayoutCID.h
+++ b/layout/build/nsLayoutCID.h
@@ -70,10 +70,6 @@
#define NS_FOCUSMANAGER_CID \
{ 0xcf7fd51f, 0xaba2, 0x44c1, { 0x9f, 0xf0, 0x11, 0xf7, 0x50, 0x8e, 0xfc, 0xd4 } }
-// {1A26A7B7-D06E-4F45-8B45-D7AD60F7A9AB}
-#define INDEXEDDB_MANAGER_CID \
-{ 0x1a26a7b7, 0xd06e, 0x4f45, { 0x8b, 0x45, 0xd7, 0xad, 0x60, 0xf7, 0xa9, 0xab } }
-
// {3160e271-138d-4cc7-9d63-6429f16957c7}
#define DOMREQUEST_SERVICE_CID \
{ 0x3160e271, 0x138d, 0x4cc7, { 0x9d, 0x63, 0x64, 0x29, 0xf1, 0x69, 0x57, 0xc7 } }
diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp
index f63575a8320f..2a64999415a8 100644
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -87,7 +87,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMRequest.h"
-#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/network/TCPSocketChild.h"
#include "mozilla/dom/network/TCPSocketParent.h"
#include "mozilla/dom/network/TCPServerSocketChild.h"
@@ -251,7 +250,6 @@ using namespace mozilla::dom;
using namespace mozilla::dom::mobilemessage;
using namespace mozilla::dom::telephony;
using mozilla::dom::alarm::AlarmHalService;
-using mozilla::dom::indexedDB::IndexedDatabaseManager;
using mozilla::dom::power::PowerManagerService;
using mozilla::dom::quota::QuotaManager;
using mozilla::dom::workers::ServiceWorkerManager;
@@ -289,8 +287,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(Exception)
NS_GENERIC_FACTORY_CONSTRUCTOR(DOMSessionStorageManager)
NS_GENERIC_FACTORY_CONSTRUCTOR(DOMLocalStorageManager)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChannelPolicy)
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(IndexedDatabaseManager,
- IndexedDatabaseManager::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DOMRequestService,
DOMRequestService::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(QuotaManager,
@@ -722,7 +718,6 @@ NS_DEFINE_NAMED_CID(NS_DOMSESSIONSTORAGEMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_DOMLOCALSTORAGEMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_DOMJSON_CID);
NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
-NS_DEFINE_NAMED_CID(INDEXEDDB_MANAGER_CID);
NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID);
NS_DEFINE_NAMED_CID(QUOTA_MANAGER_CID);
NS_DEFINE_NAMED_CID(SERVICEWORKERMANAGER_CID);
@@ -1013,7 +1008,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_DOMLOCALSTORAGEMANAGER_CID, false, nullptr, DOMLocalStorageManagerConstructor },
{ &kNS_DOMJSON_CID, false, nullptr, NS_NewJSON },
{ &kNS_TEXTEDITOR_CID, false, nullptr, nsPlaintextEditorConstructor },
- { &kINDEXEDDB_MANAGER_CID, false, nullptr, IndexedDatabaseManagerConstructor },
{ &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor },
{ &kQUOTA_MANAGER_CID, false, nullptr, QuotaManagerConstructor },
{ &kSERVICEWORKERMANAGER_CID, false, nullptr, ServiceWorkerManagerConstructor },
@@ -1171,7 +1165,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ "@mozilla.org/dom/sessionStorage-manager;1", &kNS_DOMSESSIONSTORAGEMANAGER_CID },
{ "@mozilla.org/dom/json;1", &kNS_DOMJSON_CID },
{ "@mozilla.org/editor/texteditor;1", &kNS_TEXTEDITOR_CID },
- { INDEXEDDB_MANAGER_CONTRACTID, &kINDEXEDDB_MANAGER_CID },
{ DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID },
{ QUOTA_MANAGER_CONTRACTID, &kQUOTA_MANAGER_CID },
{ SERVICEWORKERMANAGER_CONTRACTID, &kSERVICEWORKERMANAGER_CID },
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index e2d22ecf737d..e09749cbc942 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4990,10 +4990,10 @@ nsIFrame::TryUpdateTransformOnly(Layer** aLayerResult)
static const gfx::Float kError = 0.0001f;
if (!transform3d.Is2D(&transform) ||
!layer->GetBaseTransform().Is2D(&previousTransform) ||
- !gfx::FuzzyEqual(transform.xx, previousTransform._11, kError) ||
- !gfx::FuzzyEqual(transform.yy, previousTransform._22, kError) ||
- !gfx::FuzzyEqual(transform.xy, previousTransform._21, kError) ||
- !gfx::FuzzyEqual(transform.yx, previousTransform._12, kError)) {
+ !gfx::FuzzyEqual(transform._11, previousTransform._11, kError) ||
+ !gfx::FuzzyEqual(transform._22, previousTransform._22, kError) ||
+ !gfx::FuzzyEqual(transform._21, previousTransform._21, kError) ||
+ !gfx::FuzzyEqual(transform._12, previousTransform._12, kError)) {
return false;
}
gfx::Matrix4x4 matrix;
diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp
index ace37b0132b2..a0511699dfab 100644
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -1339,10 +1339,10 @@ Decompose2DMatrix(const gfxMatrix &aMatrix, gfxPoint3D &aScale,
float aShear[3], gfxQuaternion &aRotate,
gfxPoint3D &aTranslate)
{
- float A = aMatrix.xx,
- B = aMatrix.yx,
- C = aMatrix.xy,
- D = aMatrix.yy;
+ float A = aMatrix._11,
+ B = aMatrix._12,
+ C = aMatrix._21,
+ D = aMatrix._22;
if (A * D == B * C) {
// singular matrix
return false;
@@ -1378,8 +1378,8 @@ Decompose2DMatrix(const gfxMatrix &aMatrix, gfxPoint3D &aScale,
aShear[XYSHEAR] = XYshear;
aScale.x = scaleX;
aScale.y = scaleY;
- aTranslate.x = aMatrix.x0;
- aTranslate.y = aMatrix.y0;
+ aTranslate.x = aMatrix._31;
+ aTranslate.y = aMatrix._32;
return true;
}
diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp
index 6513c2eee09e..7627bd8a0334 100644
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -97,18 +97,18 @@ ProcessMatrix(gfx3DMatrix& aMatrix,
/* Take the first four elements out of the array as floats and store
* them.
*/
- result.xx = aData->Item(1).GetFloatValue();
- result.yx = aData->Item(2).GetFloatValue();
- result.xy = aData->Item(3).GetFloatValue();
- result.yy = aData->Item(4).GetFloatValue();
+ result._11 = aData->Item(1).GetFloatValue();
+ result._12 = aData->Item(2).GetFloatValue();
+ result._21 = aData->Item(3).GetFloatValue();
+ result._22 = aData->Item(4).GetFloatValue();
/* The last two elements have their length parts stored in aDelta
* and their percent parts stored in aX[0] and aY[1].
*/
- result.x0 = ProcessTranslatePart(aData->Item(5),
+ result._31 = ProcessTranslatePart(aData->Item(5),
aContext, aPresContext, aCanStoreInRuleTree,
aBounds.Width());
- result.y0 = ProcessTranslatePart(aData->Item(6),
+ result._32 = ProcessTranslatePart(aData->Item(6),
aContext, aPresContext, aCanStoreInRuleTree,
aBounds.Height());
diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp
index a0280f057672..e2cd74592bac 100644
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1114,8 +1114,8 @@ PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
gfxMatrix matrix = aMatrix;
matrix.Multiply(nsSVGUtils::GetStrokeTransform(aFrame));
- double dx = style_expansion * (fabs(matrix.xx) + fabs(matrix.xy));
- double dy = style_expansion * (fabs(matrix.yy) + fabs(matrix.yx));
+ double dx = style_expansion * (fabs(matrix._11) + fabs(matrix._21));
+ double dy = style_expansion * (fabs(matrix._22) + fabs(matrix._12));
gfxRect strokeExtents = aPathExtents;
strokeExtents.Inflate(dx, dy);
diff --git a/media/webrtc/moz.build b/media/webrtc/moz.build
index 9dc10c482be8..d2ca2c92a636 100644
--- a/media/webrtc/moz.build
+++ b/media/webrtc/moz.build
@@ -64,6 +64,7 @@ if CONFIG['MOZ_WEBRTC_SIGNALING']:
'signaling/src/media-conduit/AudioConduit.cpp',
'signaling/src/media-conduit/CodecStatistics.cpp',
'signaling/src/media-conduit/VideoConduit.cpp',
+ 'signaling/src/media-conduit/WebrtcOMXH264VideoCodec.cpp',
'signaling/src/media/CSFAudioControlWrapper.cpp',
'signaling/src/media/CSFVideoControlWrapper.cpp',
'signaling/src/media/VcmSIPCCBinding.cpp',
diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in
index 4c1f94241ae6..520a0021d1be 100644
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -147,7 +147,6 @@
@BINPATH@/components/dom_network.xpt
@BINPATH@/components/dom_notification.xpt
@BINPATH@/components/dom_html.xpt
-@BINPATH@/components/dom_indexeddb.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_json.xpt
@BINPATH@/components/dom_payment.xpt
diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp
index 8a42c44c0df9..1f9ed60e148d 100644
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -224,6 +224,8 @@ NS_IMPL_ISUPPORTS_INHERITED(nsJARChannel,
nsIRequestObserver,
nsIDownloadObserver,
nsIRemoteOpenFileListener,
+ nsIThreadRetargetableRequest,
+ nsIThreadRetargetableStreamListener,
nsIJARChannel)
nsresult
@@ -434,6 +436,20 @@ nsJARChannel::NotifyError(nsresult aError)
OnStopRequest(nullptr, nullptr, aError);
}
+void
+nsJARChannel::FireOnProgress(uint64_t aProgress)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mProgressSink);
+
+ if (mLoadFlags & LOAD_BACKGROUND) {
+ return;
+ }
+
+ mProgressSink->OnProgress(this, nullptr, aProgress,
+ uint64_t(mContentLength));
+}
+
//-----------------------------------------------------------------------------
// nsIRequest
//-----------------------------------------------------------------------------
@@ -972,7 +988,11 @@ nsJARChannel::OnStartRequest(nsIRequest *req, nsISupports *ctx)
{
LOG(("nsJARChannel::OnStartRequest [this=%x %s]\n", this, mSpec.get()));
- return mListener->OnStartRequest(this, mListenerContext);
+ mRequest = req;
+ nsresult rv = mListener->OnStartRequest(this, mListenerContext);
+ mRequest = nullptr;
+
+ return rv;
}
NS_IMETHODIMP
@@ -1020,9 +1040,44 @@ nsJARChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
// simply report progress here instead of hooking ourselves up as a
// nsITransportEventSink implementation.
// XXX do the 64-bit stuff for real
- if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
- mProgressSink->OnProgress(this, nullptr, offset + count,
- uint64_t(mContentLength));
+ if (mProgressSink && NS_SUCCEEDED(rv)) {
+ if (NS_IsMainThread()) {
+ FireOnProgress(offset + count);
+ } else {
+ nsCOMPtr runnable =
+ NS_NewRunnableMethodWithArg(this,
+ &nsJARChannel::FireOnProgress,
+ offset + count);
+ NS_DispatchToMainThread(runnable);
+ }
+ }
return rv; // let the pump cancel on failure
}
+
+NS_IMETHODIMP
+nsJARChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr request = do_QueryInterface(mRequest);
+ if (!request) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+
+ return request->RetargetDeliveryTo(aEventTarget);
+}
+
+NS_IMETHODIMP
+nsJARChannel::CheckListenerChain()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsCOMPtr listener =
+ do_QueryInterface(mListener);
+ if (!listener) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+
+ return listener->CheckListenerChain();
+}
diff --git a/modules/libjar/nsJARChannel.h b/modules/libjar/nsJARChannel.h
index 4775188fb841..2b15060e8c0d 100644
--- a/modules/libjar/nsJARChannel.h
+++ b/modules/libjar/nsJARChannel.h
@@ -16,6 +16,8 @@
#include "nsIZipReader.h"
#include "nsIDownloader.h"
#include "nsILoadGroup.h"
+#include "nsIThreadRetargetableRequest.h"
+#include "nsIThreadRetargetableStreamListener.h"
#include "nsHashPropertyBag.h"
#include "nsIFile.h"
#include "nsIURI.h"
@@ -31,6 +33,8 @@ class nsJARChannel : public nsIJARChannel
, public nsIDownloadObserver
, public nsIStreamListener
, public nsIRemoteOpenFileListener
+ , public nsIThreadRetargetableRequest
+ , public nsIThreadRetargetableStreamListener
, public nsHashPropertyBag
{
public:
@@ -42,18 +46,23 @@ public:
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREMOTEOPENFILELISTENER
+ NS_DECL_NSITHREADRETARGETABLEREQUEST
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
nsJARChannel();
- virtual ~nsJARChannel();
nsresult Init(nsIURI *uri);
private:
+ virtual ~nsJARChannel();
+
nsresult CreateJarInput(nsIZipReaderCache *, nsJARInputThunk **);
nsresult LookupFile();
nsresult OpenLocalFile();
void NotifyError(nsresult aError);
+ void FireOnProgress(uint64_t aProgress);
+
#if defined(PR_LOGGING)
nsCString mSpec;
#endif
@@ -85,6 +94,9 @@ private:
nsCOMPtr mDownloader;
nsCOMPtr mPump;
+ // mRequest is only non-null during OnStartRequest, so we'll have a pointer
+ // to the request if we get called back via RetargetDeliveryTo.
+ nsCOMPtr mRequest;
nsCOMPtr mJarFile;
nsCOMPtr mJarBaseURI;
nsCString mJarEntry;
diff --git a/netwerk/base/public/nsIThreadRetargetableRequest.idl b/netwerk/base/public/nsIThreadRetargetableRequest.idl
index a93130fe5575..9a93b70c65a9 100644
--- a/netwerk/base/public/nsIThreadRetargetableRequest.idl
+++ b/netwerk/base/public/nsIThreadRetargetableRequest.idl
@@ -20,8 +20,8 @@ interface nsIThreadRetargetableRequest : nsISupports
/**
* Called to retarget delivery of OnDataAvailable to another thread. Should
* only be called before AsyncOpen for nsIWebsocketChannels, or during
- * OnStartRequest for nsIHttpChannels.
- * Note: For nsIHttpChannels, OnStartRequest and OnStopRequest will still be
+ * OnStartRequest for nsIChannels.
+ * Note: For nsIChannels, OnStartRequest and OnStopRequest will still be
* delivered on the main thread.
*
* @param aNewTarget New event target, e.g. thread or threadpool.
@@ -33,5 +33,3 @@ interface nsIThreadRetargetableRequest : nsISupports
*/
void retargetDeliveryTo(in nsIEventTarget aNewTarget);
};
-
-
diff --git a/netwerk/base/src/nsBaseChannel.cpp b/netwerk/base/src/nsBaseChannel.cpp
index 75a769c808e0..7f877647a8d1 100644
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -54,6 +54,7 @@ nsBaseChannel::nsBaseChannel()
: mLoadFlags(LOAD_NORMAL)
, mQueriedProgressSink(true)
, mSynthProgressEvents(false)
+ , mAllowThreadRetargeting(true)
, mWasOpened(false)
, mWaitingOnAsyncRedirect(false)
, mStatus(NS_OK)
@@ -289,10 +290,12 @@ NS_IMPL_ISUPPORTS_INHERITED(nsBaseChannel,
nsHashPropertyBag,
nsIRequest,
nsIChannel,
+ nsIThreadRetargetableRequest,
nsIInterfaceRequestor,
nsITransportEventSink,
nsIRequestObserver,
nsIStreamListener,
+ nsIThreadRetargetableStreamListener,
nsIAsyncVerifyRedirectCallback,
nsIPrivateBrowsingChannel)
@@ -693,6 +696,8 @@ CallUnknownTypeSniffer(void *aClosure, const uint8_t *aData, uint32_t aCount)
NS_IMETHODIMP
nsBaseChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
+ MOZ_ASSERT(request == mPump);
+
// If our content type is unknown or if the content type is
// application/octet-stream and the caller requested it, use the content type
// sniffer. If the sniffer is not available for some reason, then we just keep
@@ -759,7 +764,34 @@ nsBaseChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
offset, count);
if (mSynthProgressEvents && NS_SUCCEEDED(rv)) {
uint64_t prog = offset + count;
- OnTransportStatus(nullptr, NS_NET_STATUS_READING, prog, mContentLength);
+ if (NS_IsMainThread()) {
+ OnTransportStatus(nullptr, NS_NET_STATUS_READING, prog, mContentLength);
+ } else {
+ class OnTransportStatusAsyncEvent : public nsRunnable
+ {
+ nsRefPtr mChannel;
+ uint64_t mProgress;
+ uint64_t mContentLength;
+ public:
+ OnTransportStatusAsyncEvent(nsBaseChannel* aChannel,
+ uint64_t aProgress,
+ uint64_t aContentLength)
+ : mChannel(aChannel),
+ mProgress(aProgress),
+ mContentLength(aContentLength)
+ { }
+
+ NS_IMETHOD Run() MOZ_OVERRIDE
+ {
+ return mChannel->OnTransportStatus(nullptr, NS_NET_STATUS_READING,
+ mProgress, mContentLength);
+ }
+ };
+
+ nsCOMPtr runnable =
+ new OnTransportStatusAsyncEvent(this, prog, mContentLength);
+ NS_DispatchToMainThread(runnable);
+ }
}
return rv;
@@ -782,3 +814,35 @@ nsBaseChannel::OnRedirectVerifyCallback(nsresult result)
return NS_OK;
}
+
+NS_IMETHODIMP
+nsBaseChannel::RetargetDeliveryTo(nsIEventTarget* aEventTarget)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ENSURE_TRUE(mPump, NS_ERROR_NOT_INITIALIZED);
+
+ if (!mAllowThreadRetargeting) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ return mPump->RetargetDeliveryTo(aEventTarget);
+}
+
+NS_IMETHODIMP
+nsBaseChannel::CheckListenerChain()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!mAllowThreadRetargeting) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ nsCOMPtr listener =
+ do_QueryInterface(mListener);
+ if (!listener) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+
+ return listener->CheckListenerChain();
+}
diff --git a/netwerk/base/src/nsBaseChannel.h b/netwerk/base/src/nsBaseChannel.h
index 2a50e813d870..febcd19a393b 100644
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -20,6 +20,8 @@
#include "nsIProgressEventSink.h"
#include "nsITransport.h"
#include "nsIAsyncVerifyRedirectCallback.h"
+#include "nsIThreadRetargetableRequest.h"
+#include "nsIThreadRetargetableStreamListener.h"
#include "PrivateBrowsingChannel.h"
#include "nsThreadUtils.h"
#include "nsNetUtil.h"
@@ -40,11 +42,13 @@ class nsIInputStream;
class nsBaseChannel : public nsHashPropertyBag
, public nsIChannel
+ , public nsIThreadRetargetableRequest
, public nsIInterfaceRequestor
, public nsITransportEventSink
, public nsIAsyncVerifyRedirectCallback
, public mozilla::net::PrivateBrowsingChannel
, protected nsIStreamListener
+ , protected nsIThreadRetargetableStreamListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
@@ -53,6 +57,8 @@ public:
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSITRANSPORTEVENTSINK
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
+ NS_DECL_NSITHREADRETARGETABLEREQUEST
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
nsBaseChannel();
@@ -203,6 +209,11 @@ public:
bool invalidatesContentLength = true,
nsIStreamListener **converter = nullptr);
+protected:
+ void DisallowThreadRetargeting() {
+ mAllowThreadRetargeting = false;
+ }
+
private:
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
@@ -265,6 +276,7 @@ private:
uint32_t mLoadFlags;
bool mQueriedProgressSink;
bool mSynthProgressEvents;
+ bool mAllowThreadRetargeting;
bool mWasOpened;
bool mWaitingOnAsyncRedirect;
bool mOpenRedirectChannel;
diff --git a/netwerk/protocol/ftp/FTPChannelChild.cpp b/netwerk/protocol/ftp/FTPChannelChild.cpp
index e940f6fcf6f4..1e29c111b923 100644
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -43,6 +43,10 @@ FTPChannelChild::FTPChannelChild(nsIURI* uri)
NS_ADDREF(gFtpHandler);
SetURI(uri);
mEventQ = new ChannelEventQueue(static_cast(this));
+
+ // We could support thread retargeting, but as long as we're being driven by
+ // IPDL on the main thread it doesn't buy us anything.
+ DisallowThreadRetargeting();
}
FTPChannelChild::~FTPChannelChild()
diff --git a/netwerk/protocol/rtsp/RtspChannelChild.cpp b/netwerk/protocol/rtsp/RtspChannelChild.cpp
index d2b2690de308..e06e0b1ccb1f 100644
--- a/netwerk/protocol/rtsp/RtspChannelChild.cpp
+++ b/netwerk/protocol/rtsp/RtspChannelChild.cpp
@@ -20,6 +20,7 @@ RtspChannelChild::RtspChannelChild(nsIURI *aUri)
, mCanceled(false)
{
nsBaseChannel::SetURI(aUri);
+ DisallowThreadRetargeting();
}
RtspChannelChild::~RtspChannelChild()
diff --git a/netwerk/protocol/rtsp/RtspChannelParent.cpp b/netwerk/protocol/rtsp/RtspChannelParent.cpp
index 401dde50e976..f8dd5ae36eb5 100644
--- a/netwerk/protocol/rtsp/RtspChannelParent.cpp
+++ b/netwerk/protocol/rtsp/RtspChannelParent.cpp
@@ -18,6 +18,7 @@ RtspChannelParent::RtspChannelParent(nsIURI *aUri)
: mIPCClosed(false)
{
nsBaseChannel::SetURI(aUri);
+ DisallowThreadRetargeting();
}
RtspChannelParent::~RtspChannelParent()
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
index 0b6c7cce9735..fd036ad33824 100644
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -933,14 +933,18 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
mReparseForbidden = true;
mFeedChardet = false; // can't restart anyway
}
+ }
- // Attempt to retarget delivery of data (via OnDataAvailable) to the parser
- // thread, rather than through the main thread.
- nsCOMPtr threadRetargetableRequest =
- do_QueryInterface(mRequest);
- if (threadRetargetableRequest) {
- threadRetargetableRequest->RetargetDeliveryTo(mThread);
- }
+ // Attempt to retarget delivery of data (via OnDataAvailable) to the parser
+ // thread, rather than through the main thread.
+ nsCOMPtr threadRetargetableRequest =
+ do_QueryInterface(mRequest, &rv);
+ if (threadRetargetableRequest) {
+ rv = threadRetargetableRequest->RetargetDeliveryTo(mThread);
+ }
+
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to retarget HTML data delivery to the parser thread.");
}
if (mCharsetSource == kCharsetFromParentFrame) {
diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml
index c2c51330c000..02ab9bed5623 100644
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -226,7 +226,7 @@
case "Browser:Init":
let result = {};
result.useGlobalHistory = !this.hasAttribute("disableglobalhistory");
- result.initPopup = this.autoCompletePopup;
+ result.initPopup = this.autoCompletePopup != null;
return result;
break;
case "DOMTitleChanged":
diff --git a/toolkit/devtools/server/actors/storage.js b/toolkit/devtools/server/actors/storage.js
index bd0230f09bf5..362a2b33a274 100644
--- a/toolkit/devtools/server/actors/storage.js
+++ b/toolkit/devtools/server/actors/storage.js
@@ -7,6 +7,12 @@
const {Cu, Cc, Ci} = require("chrome");
const events = require("sdk/event/core");
const protocol = require("devtools/server/protocol");
+try {
+ const { indexedDB } = require("sdk/indexed-db");
+} catch (e) {
+ // In xpcshell tests, we can't actually have indexedDB, which is OK:
+ // we don't use it there anyway.
+}
const {async} = require("devtools/async-utils");
const {Arg, Option, method, RetVal, types} = protocol;
const {LongStringActor, ShortLongString} = require("devtools/server/actors/string");
@@ -930,11 +936,6 @@ StorageActors.createActor({
}, {
initialize: function(storageActor) {
protocol.Actor.prototype.initialize.call(this, null);
- if (!global.indexedDB) {
- let idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"]
- .getService(Ci.nsIIndexedDatabaseManager);
- idbManager.initWindowless(global);
- }
this.objectsSize = {};
this.storageActor = storageActor;
this.onWindowReady = this.onWindowReady.bind(this);
diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm
index 163d42c903ac..6c3e2d71eb84 100644
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2165,7 +2165,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
fprintf(stderr, "Native theme drawing widget %d [%p] dis:%d in rect [%d %d %d %d]\n",
aWidgetType, aFrame, IsDisabled(aFrame), aRect.x, aRect.y, aRect.width, aRect.height);
fprintf(stderr, "Cairo matrix: [%f %f %f %f %f %f]\n",
- mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0);
+ mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
fprintf(stderr, "Native theme xform[0]: [%f %f %f %f %f %f]\n",
mm0.a, mm0.b, mm0.c, mm0.d, mm0.tx, mm0.ty);
CGAffineTransform mm = CGContextGetCTM(cgContext);
diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp
index b958c29ac1a6..b984499499aa 100644
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -377,9 +377,9 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
// Reflection is applied before rotation
gfxMatrix rotation = transform * aGLWorldTransform;
// Compute fuzzy zero like PreservesAxisAlignedRectangles()
- if (fabs(rotation.xx) < 1e-6) {
- if (rotation.xy < 0) {
- if (rotation.yx > 0) {
+ if (fabs(rotation._11) < 1e-6) {
+ if (rotation._21 < 0) {
+ if (rotation._12 > 0) {
// 90 degree rotation
//
// | 0 -1 |
@@ -403,7 +403,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
LOGD("Layer vertically reflected then rotated 270 degrees");
}
} else {
- if (rotation.yx < 0) {
+ if (rotation._12 < 0) {
// 270 degree rotation
//
// | 0 1 |
@@ -427,8 +427,8 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
LOGD("Layer horizontally reflected then rotated 270 degrees");
}
}
- } else if (rotation.xx < 0) {
- if (rotation.yy > 0) {
+ } else if (rotation._11 < 0) {
+ if (rotation._22 > 0) {
// Horizontal reflection
//
// | -1 0 |
@@ -452,7 +452,7 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer,
LOGD("Layer rotated 180 degrees");
}
} else {
- if (rotation.yy < 0) {
+ if (rotation._22 < 0) {
// Vertical reflection
//
// | 1 0 |
diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp
index 57a00976a48b..a2b024e4f55a 100644
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -1623,8 +1623,8 @@ RENDER_AGAIN:
#if 0
{
PR_LOG(gWindowsLog, PR_LOG_ERROR,
- (stderr, "xform: %f %f %f %f [%f %f]\n", m.xx, m.yx, m.xy, m.yy,
- m.x0, m.y0));
+ (stderr, "xform: %f %f %f %f [%f %f]\n", m._11, m._21, m._12, m._22,
+ m._31, m._32));
PR_LOG(gWindowsLog, PR_LOG_ERROR,
(stderr, "tr: [%d %d %d %d]\ndr: [%d %d %d %d]\noff: [%f %f]\n",
tr.x, tr.y, tr.width, tr.height, dr.x, dr.y, dr.width, dr.height,
@@ -1789,11 +1789,11 @@ RENDER_AGAIN:
}
else if (aWidgetType == NS_THEME_MENUARROW)
{
- // We're dpi aware and as such on systems that have dpi > 96 set, the
- // theme library expects us to do proper positioning and scaling of glyphs.
- // For NS_THEME_MENUARROW, layout may hand us a widget rect larger than the
- // glyph rect we request in GetMinimumWidgetSize. To prevent distortion we
- // have to position and scale what we draw.
+ // We're dpi aware and as such on systems that have dpi > 96 set, the
+ // theme library expects us to do proper positioning and scaling of glyphs.
+ // For NS_THEME_MENUARROW, layout may hand us a widget rect larger than the
+ // glyph rect we request in GetMinimumWidgetSize. To prevent distortion we
+ // have to position and scale what we draw.
SIZE glyphSize;
GetThemePartSize(theme, hdc, part, state, nullptr, TS_TRUE, &glyphSize);
|