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") + } + } + ]]>