зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to central, a=merge
--HG-- extra : commitid : 7NebvxBmkpu
This commit is contained in:
Коммит
359fa021b5
3
CLOBBER
3
CLOBBER
|
@ -22,4 +22,5 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
bug 1168113's backout needs a CLOBBER to clear up some TC bustage
|
||||
Bug 1210165 - Update ICU to release 56.1.
|
||||
Bug 966038 - Updating ICU doesn't properly notify the Mozilla build system, necessitating a clobber.
|
||||
|
|
|
@ -372,6 +372,30 @@ DocAccessibleChild::RecvGetLevelInternal(const uint64_t& aID, int32_t* aLevel)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvScrollTo(const uint64_t& aID,
|
||||
const uint32_t& aScrollType)
|
||||
{
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (acc) {
|
||||
nsCoreUtils::ScrollTo(acc->Document()->PresShell(), acc->GetContent(),
|
||||
aScrollType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvScrollToPoint(const uint64_t& aID, const uint32_t& aScrollType, const int32_t& aX, const int32_t& aY)
|
||||
{
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (acc) {
|
||||
acc->ScrollToPoint(aScrollType, aX, aY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
|
||||
{
|
||||
|
|
|
@ -98,6 +98,11 @@ public:
|
|||
|
||||
virtual bool RecvAttributes(const uint64_t& aID,
|
||||
nsTArray<Attribute> *aAttributes) override;
|
||||
virtual bool RecvScrollTo(const uint64_t& aID, const uint32_t& aScrollType)
|
||||
override;
|
||||
virtual bool RecvScrollToPoint(const uint64_t& aID,
|
||||
const uint32_t& aScrollType,
|
||||
const int32_t& aX, const int32_t& aY) override;
|
||||
|
||||
virtual bool RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
|
||||
override;
|
||||
|
|
|
@ -86,6 +86,9 @@ child:
|
|||
prio(high) sync LandmarkRole(uint64_t aID) returns(nsString landmark);
|
||||
prio(high) sync ARIARoleAtom(uint64_t aID) returns(nsString role);
|
||||
prio(high) sync GetLevelInternal(uint64_t aID) returns(int32_t aLevel);
|
||||
async ScrollTo(uint64_t aID, uint32_t aScrollType);
|
||||
async ScrollToPoint(uint64_t aID, uint32_t aScrollType, int32_t aX,
|
||||
int32_t aY);
|
||||
|
||||
// AccessibleText
|
||||
|
||||
|
|
|
@ -200,6 +200,18 @@ ProxyAccessible::GetLevelInternal()
|
|||
return level;
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::ScrollTo(uint32_t aScrollType)
|
||||
{
|
||||
Unused << mDoc->SendScrollTo(mID, aScrollType);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY)
|
||||
{
|
||||
Unused << mDoc->SendScrollToPoint(mID, aScrollType, aX, aY);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ProxyAccessible::CaretLineNumber()
|
||||
{
|
||||
|
|
|
@ -144,6 +144,8 @@ public:
|
|||
nsIAtom* ARIARoleAtom() const;
|
||||
|
||||
int32_t GetLevelInternal();
|
||||
void ScrollTo(uint32_t aScrollType);
|
||||
void ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY);
|
||||
|
||||
int32_t CaretLineNumber();
|
||||
int32_t CaretOffset();
|
||||
|
|
|
@ -279,8 +279,13 @@ ia2Accessible::scrollTo(enum IA2ScrollType aScrollType)
|
|||
if (acc->IsDefunct())
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
nsCoreUtils::ScrollTo(acc->Document()->PresShell(),
|
||||
acc->GetContent(), aScrollType);
|
||||
if (acc->IsProxy()) {
|
||||
acc->Proxy()->ScrollTo(aScrollType);
|
||||
} else {
|
||||
nsCoreUtils::ScrollTo(acc->Document()->PresShell(), acc->GetContent(),
|
||||
aScrollType);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
A11Y_TRYBLOCK_END
|
||||
|
@ -300,7 +305,12 @@ ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType,
|
|||
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
|
||||
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
|
||||
|
||||
acc->ScrollToPoint(geckoCoordType, aX, aY);
|
||||
if (acc->IsProxy()) {
|
||||
acc->Proxy()->ScrollToPoint(geckoCoordType, aX, aY);
|
||||
} else {
|
||||
acc->ScrollToPoint(geckoCoordType, aX, aY);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
A11Y_TRYBLOCK_END
|
||||
|
|
|
@ -278,7 +278,7 @@ if test -n "$gonkdir" ; then
|
|||
AC_DEFINE(MOZ_OMX_ENCODER)
|
||||
AC_SUBST(MOZ_AUDIO_OFFLOAD)
|
||||
AC_DEFINE(MOZ_AUDIO_OFFLOAD)
|
||||
MOZ_FMP4=
|
||||
MOZ_FMP4=1
|
||||
MOZ_B2G_CAMERA=1
|
||||
if test -d "$gonkdir/system/bluetoothd"; then
|
||||
MOZ_B2G_BT=1
|
||||
|
|
|
@ -394,3 +394,4 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
|||
[browser_webconsole_bug_1050691_click_function_to_source.js]
|
||||
[browser_webconsole_context_menu_open_in_var_view.js]
|
||||
[browser_webconsole_context_menu_store_as_global.js]
|
||||
[browser_webconsole_strict_mode_errors.js]
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Check that "use strict" JS errors generate errors, not warnings.
|
||||
|
||||
"use strict";
|
||||
|
||||
var test = asyncTest(function* () {
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
yield loadTab("data:text/html;charset=utf8,<script>'use strict';var arguments;</script>");
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "SyntaxError: redefining arguments is deprecated",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
content.location = "data:text/html;charset=utf8,<script>'use strict';function f(a, a) {};</script>";
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "SyntaxError: duplicate formal argument a",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
content.location = "data:text/html;charset=utf8,<script>'use strict';var o = {get p() {}};o.p = 1;</script>";
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "TypeError: setting a property that has only a getter",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
content.location = "data:text/html;charset=utf8,<script>'use strict';v = 1;</script>";
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "ReferenceError: assignment to undeclared variable v",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
hud = null;
|
||||
});
|
|
@ -2538,7 +2538,10 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
|||
if (sameTypeParent) {
|
||||
mUpgradeInsecureRequests =
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecureRequests();
|
||||
// if the parent document makes use of upgrade-insecure-requests
|
||||
// then subdocument preloads should always be upgraded.
|
||||
mUpgradeInsecurePreloads =
|
||||
mUpgradeInsecureRequests ||
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecurePreloads();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4409,11 +4409,13 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
templateBody = "${declName} = &${val}.toObject();\n"
|
||||
|
||||
# For JS-implemented APIs, we refuse to allow passing objects that the
|
||||
# API consumer does not subsume.
|
||||
# API consumer does not subsume. The extra parens around
|
||||
# ($${passedToJSImpl}) suppress unreachable code warnings when
|
||||
# $${passedToJSImpl} is the literal `false`.
|
||||
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
|
||||
templateBody = fill(
|
||||
"""
|
||||
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
|
||||
if (($${passedToJSImpl}) && !CallerSubsumes($${val})) {
|
||||
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
|
||||
$*{exceptionCode}
|
||||
}
|
||||
|
@ -5456,11 +5458,13 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
templateBody = "${declName} = ${val};\n"
|
||||
|
||||
# For JS-implemented APIs, we refuse to allow passing objects that the
|
||||
# API consumer does not subsume.
|
||||
# API consumer does not subsume. The extra parens around
|
||||
# ($${passedToJSImpl}) suppress unreachable code warnings when
|
||||
# $${passedToJSImpl} is the literal `false`.
|
||||
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
|
||||
templateBody = fill(
|
||||
"""
|
||||
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
|
||||
if (($${passedToJSImpl}) && !CallerSubsumes($${val})) {
|
||||
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
|
||||
$*{exceptionCode}
|
||||
}
|
||||
|
@ -7319,7 +7323,7 @@ class CGCase(CGList):
|
|||
self.append(CGGeneric("case " + expression + ": {\n"))
|
||||
bodyList = CGList([body])
|
||||
if fallThrough:
|
||||
bodyList.append(CGGeneric("/* Fall through */\n"))
|
||||
bodyList.append(CGGeneric("MOZ_FALLTHROUGH;\n"))
|
||||
else:
|
||||
bodyList.append(CGGeneric("break;\n"))
|
||||
self.append(CGIndenter(bodyList))
|
||||
|
|
|
@ -3973,10 +3973,13 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle()
|
|||
if (presShell && !presShell->IsDestroying()) {
|
||||
tp = presShell->GetPresContext()->GetTextPerfMetrics();
|
||||
}
|
||||
int32_t perDevPixel, perCSSPixel;
|
||||
GetAppUnitsValues(&perDevPixel, &perCSSPixel);
|
||||
gfxFloat devToCssSize = gfxFloat(perDevPixel) / gfxFloat(perCSSPixel);
|
||||
CurrentState().fontGroup =
|
||||
gfxPlatform::GetPlatform()->CreateFontGroup(FontFamilyList(eFamily_sans_serif),
|
||||
&style, tp,
|
||||
nullptr);
|
||||
nullptr, devToCssSize);
|
||||
if (CurrentState().fontGroup) {
|
||||
CurrentState().font = kDefaultFontStyle;
|
||||
} else {
|
||||
|
|
|
@ -307,11 +307,10 @@ public:
|
|||
already_AddRefed<DOMRequest> CreateAndRejectDOMRequest(const char *aReason,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult CheckPermission(DeviceStorageRequest* aRequest);
|
||||
void StorePermission(DeviceStorageRequest* aRequest, bool aAllow);
|
||||
nsresult CheckPermission(already_AddRefed<DeviceStorageRequest>&& aRequest);
|
||||
|
||||
bool IsOwningThread();
|
||||
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
|
||||
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
private:
|
||||
~nsDOMDeviceStorage();
|
||||
|
|
|
@ -36,6 +36,7 @@ DeviceStorageRequestParent::DeviceStorageRequestParent(
|
|||
void
|
||||
DeviceStorageRequestParent::Dispatch()
|
||||
{
|
||||
RefPtr<CancelableRunnable> r;
|
||||
switch (mParams.type()) {
|
||||
case DeviceStorageParams::TDeviceStorageAddParams:
|
||||
{
|
||||
|
@ -52,13 +53,8 @@ DeviceStorageRequestParent::Dispatch()
|
|||
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_CREATE);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_CREATE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -77,13 +73,8 @@ DeviceStorageRequestParent::Dispatch()
|
|||
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_APPEND);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_APPEND);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -94,12 +85,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new CreateFdEvent(this, dsf.forget());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new CreateFdEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -109,12 +95,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(),
|
||||
p.rootDir(), p.relpath());
|
||||
RefPtr<CancelableRunnable> r = new ReadFileEvent(this, dsf.forget());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new ReadFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -124,12 +105,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
|
||||
RefPtr<CancelableRunnable> r = new DeleteFileEvent(this, dsf.forget());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new DeleteFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -139,12 +115,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<FreeSpaceFileEvent> r = new FreeSpaceFileEvent(this, dsf.forget());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new FreeSpaceFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -158,10 +129,9 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<UsedSpaceFileEvent> r = new UsedSpaceFileEvent(this, dsf.forget());
|
||||
|
||||
usedSpaceCache->Dispatch(r);
|
||||
break;
|
||||
usedSpaceCache->Dispatch(
|
||||
MakeAndAddRef<UsedSpaceFileEvent>(this, dsf.forget()));
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageFormatParams:
|
||||
|
@ -170,11 +140,10 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostFormatResultEvent> r
|
||||
= new PostFormatResultEvent(this, dsf.forget());
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostFormatResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageMountParams:
|
||||
|
@ -183,11 +152,10 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostMountResultEvent> r
|
||||
= new PostMountResultEvent(this, dsf.forget());
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostMountResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageUnmountParams:
|
||||
|
@ -196,11 +164,10 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostUnmountResultEvent> r
|
||||
= new PostUnmountResultEvent(this, dsf.forget());
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostUnmountResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageEnumerationParams:
|
||||
|
@ -209,21 +176,22 @@ DeviceStorageRequestParent::Dispatch()
|
|||
RefPtr<DeviceStorageFile> dsf
|
||||
= new DeviceStorageFile(p.type(), p.storageName(),
|
||||
p.rootdir(), NS_LITERAL_STRING(""));
|
||||
RefPtr<CancelableRunnable> r
|
||||
= new EnumerateFileEvent(this, dsf.forget(), p.since());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new EnumerateFileEvent(this, dsf.forget(), p.since());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -500,19 +468,18 @@ DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
|
|||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
FileDescriptor fileDescriptor;
|
||||
nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -524,7 +491,7 @@ DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
|
|||
r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -532,11 +499,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
|||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mInputStream || !mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
bool check = false;
|
||||
|
@ -545,21 +510,22 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
|||
|
||||
if (mRequestType == DEVICE_STORAGE_REQUEST_CREATE) {
|
||||
if (check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
|
||||
}
|
||||
rv = mFile->Write(mInputStream);
|
||||
} else if (mRequestType == DEVICE_STORAGE_REQUEST_APPEND) {
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
rv = mFile->Append(mInputStream);
|
||||
} else {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
|
@ -567,7 +533,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
|||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -577,12 +543,11 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
|||
|
||||
mFile->Remove();
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (check) {
|
||||
|
@ -592,7 +557,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
|||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -605,9 +570,8 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
|
|||
mFile->GetStorageFreeSpace(&freeSpace);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace));
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace)));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -631,7 +595,7 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
|
|||
} else {
|
||||
r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
|
||||
}
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::ReadFileEvent::
|
||||
|
@ -654,38 +618,36 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
|||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
|
||||
int64_t fileSize;
|
||||
nsresult rv = mFile->mFile->GetFileSize(&fileSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
PRTime modDate;
|
||||
rv = mFile->mFile->GetLastModifiedTime(&modDate);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
r = new PostBlobSuccessEvent(mParent, mFile.forget(),
|
||||
static_cast<uint64_t>(fileSize),
|
||||
mMimeType, modDate);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostBlobSuccessEvent(mParent, mFile.forget(),
|
||||
static_cast<uint64_t>(fileSize),
|
||||
mMimeType, modDate));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -693,13 +655,12 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
|||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
if (mFile->mFile) {
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,9 +675,9 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
|||
values.AppendElement(dsvf);
|
||||
}
|
||||
|
||||
r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
|
||||
mFile->mRootDir, values);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
|
||||
mFile->mRootDir, values));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -831,7 +831,7 @@ DeviceStorageStatics::ListenerWrapper::OnFileWatcherUpdate(const nsCString& aDat
|
|||
listener->OnFileWatcherUpdate(data, file);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -844,7 +844,7 @@ DeviceStorageStatics::ListenerWrapper::OnDiskSpaceWatcher(bool aLowDiskSpace)
|
|||
listener->OnDiskSpaceWatcher(aLowDiskSpace);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -857,7 +857,7 @@ DeviceStorageStatics::ListenerWrapper::OnWritableNameChanged()
|
|||
listener->OnWritableNameChanged();
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -872,7 +872,7 @@ DeviceStorageStatics::ListenerWrapper::OnVolumeStateChanged(nsIVolume* aVolume)
|
|||
listener->OnVolumeStateChanged(volume);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -836,8 +836,7 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -864,8 +863,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -881,8 +879,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
|
|||
outputStream->Write((char*) aBits.Elements(), aBits.Length(), &wrote);
|
||||
outputStream->Close();
|
||||
|
||||
iocomplete = new IOEventComplete(this, "modified");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -935,8 +932,7 @@ DeviceStorageFile::Append(nsIInputStream* aInputStream, nsIOutputStream* aOutput
|
|||
bufSize -= wrote;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "modified");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -973,8 +969,7 @@ DeviceStorageFile::Remove()
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "deleted");
|
||||
return NS_DispatchToMainThread(iocomplete);
|
||||
return NS_DispatchToMainThread(new IOEventComplete(this, "deleted"));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1534,7 +1529,7 @@ DeviceStorageRequest::~DeviceStorageRequest()
|
|||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aId)
|
||||
{
|
||||
DS_LOG_DEBUG("%p manages %p", aManager, this);
|
||||
|
@ -1548,11 +1543,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
|||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
BlobImpl* aBlob)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mBlob = aBlob;
|
||||
mCheckBlob = true;
|
||||
mCheckFile = true;
|
||||
|
@ -1561,11 +1556,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
|||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
DeviceStorageFileDescriptor* aDSFileDescriptor)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mDSFileDescriptor = aDSFileDescriptor;
|
||||
MOZ_ASSERT(mDSFileDescriptor);
|
||||
}
|
||||
|
@ -1597,7 +1592,7 @@ DeviceStorageRequest::Allow()
|
|||
{
|
||||
self->Allow();
|
||||
});
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult rv = AllowInternal();
|
||||
|
@ -1686,7 +1681,8 @@ DeviceStorageRequest::AllowInternal()
|
|||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
return target->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
nsCOMPtr<nsIRunnable> self = this;
|
||||
return target->Dispatch(self.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
DS_LOG_INFO("run %u", mId);
|
||||
|
@ -1706,7 +1702,7 @@ DeviceStorageRequest::SendToParentProcess()
|
|||
self->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
});
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -1736,11 +1732,11 @@ DeviceStorageCursorRequest::DeviceStorageCursorRequest()
|
|||
|
||||
void
|
||||
DeviceStorageCursorRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
PRTime aSince)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mStorageType = mFile->mStorageType;
|
||||
mSince = aSince;
|
||||
}
|
||||
|
@ -1766,7 +1762,7 @@ DeviceStorageCursorRequest::SendContinueToParentProcess()
|
|||
{
|
||||
self->SendContinueToParentProcess();
|
||||
});
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -1793,7 +1789,7 @@ DeviceStorageCursorRequest::Continue()
|
|||
{
|
||||
self->Continue();
|
||||
});
|
||||
nsresult rv = NS_DispatchToMainThread(r);
|
||||
nsresult rv = NS_DispatchToMainThread(r.forget());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
|
@ -1943,11 +1939,11 @@ public:
|
|||
}
|
||||
|
||||
void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest) override
|
||||
{
|
||||
DeviceStorageRequest::Initialize(aManager, aFile, aRequest);
|
||||
mUseMainThread = aFile->mPath.IsEmpty();
|
||||
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
|
||||
mUseMainThread = mFile->mPath.IsEmpty();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2087,10 +2083,10 @@ public:
|
|||
}
|
||||
|
||||
void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest) override
|
||||
{
|
||||
DeviceStorageRequest::Initialize(aManager, aFile, aRequest);
|
||||
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
|
||||
mAccess = mFile->mEditable ? DEVICE_STORAGE_ACCESS_WRITE
|
||||
: DEVICE_STORAGE_ACCESS_READ;
|
||||
}
|
||||
|
@ -2217,7 +2213,8 @@ public:
|
|||
DeviceStorageUsedSpaceCache* usedSpaceCache
|
||||
= DeviceStorageUsedSpaceCache::CreateOrGet();
|
||||
MOZ_ASSERT(usedSpaceCache);
|
||||
usedSpaceCache->Dispatch(this);
|
||||
nsCOMPtr<nsIRunnable> self = this;
|
||||
usedSpaceCache->Dispatch(self.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2402,10 +2399,10 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStoragePermissionCheck,
|
||||
nsIContentPermissionRequest)
|
||||
|
||||
DeviceStoragePermissionCheck(DeviceStorageRequest* aRequest,
|
||||
uint64_t aWindowID,
|
||||
const PrincipalInfo &aPrincipalInfo)
|
||||
: mRequest(aRequest)
|
||||
DeviceStoragePermissionCheck(
|
||||
already_AddRefed<DeviceStorageRequest>&& aRequest,
|
||||
uint64_t aWindowID, const PrincipalInfo &aPrincipalInfo)
|
||||
: mRequest(Move(aRequest))
|
||||
, mWindowID(aWindowID)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
{
|
||||
|
@ -2557,37 +2554,31 @@ nsDOMDeviceStorage::nsDOMDeviceStorage(nsPIDOMWindow* aWindow)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDeviceStorage::CheckPermission(DeviceStorageRequest* aRequest)
|
||||
nsDOMDeviceStorage::CheckPermission(
|
||||
already_AddRefed<DeviceStorageRequest>&& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
uint32_t cache = mManager->CheckPermission(aRequest->GetAccess());
|
||||
RefPtr<DeviceStorageRequest> request(aRequest);
|
||||
uint32_t cache = mManager->CheckPermission(request->GetAccess());
|
||||
switch (cache) {
|
||||
case nsIPermissionManager::ALLOW_ACTION:
|
||||
return aRequest->Allow();
|
||||
return request->Allow();
|
||||
case nsIPermissionManager::DENY_ACTION:
|
||||
return aRequest->Cancel();
|
||||
return request->Cancel();
|
||||
case nsIPermissionManager::PROMPT_ACTION:
|
||||
default:
|
||||
{
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
return request->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
|
||||
/* We need to do a bit of a song and dance here to release the object
|
||||
because while we can initially increment the ownership count (no one
|
||||
else is using it), we cannot safely decrement after dispatching because
|
||||
it uses cycle collection and requires the main thread to free it. */
|
||||
nsCOMPtr<nsIRunnable> r
|
||||
= new DeviceStoragePermissionCheck(aRequest, mInnerWindowID,
|
||||
*mPrincipalInfo);
|
||||
rv = mainThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
rv = aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
NS_ProxyRelease(mainThread, r.forget().take());
|
||||
return rv;
|
||||
return mainThread->Dispatch(
|
||||
MakeAndAddRef<DeviceStoragePermissionCheck>(request.forget(),
|
||||
mInnerWindowID,
|
||||
*mPrincipalInfo),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2601,9 +2592,10 @@ nsDOMDeviceStorage::IsOwningThread()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDeviceStorage::DispatchToOwningThread(nsIRunnable* aRunnable)
|
||||
nsDOMDeviceStorage::DispatchToOwningThread(
|
||||
already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
|
@ -3116,8 +3108,8 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
|
|||
} else {
|
||||
request = new DeviceStorageAppendRequest();
|
||||
}
|
||||
request->Initialize(mManager, dsf, id, aBlob->Impl());
|
||||
aRv = CheckPermission(request);
|
||||
request->Initialize(mManager, dsf.forget(), id, aBlob->Impl());
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3151,9 +3143,9 @@ nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageOpenRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3185,9 +3177,9 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageDeleteRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3206,9 +3198,9 @@ nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageFreeSpaceRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3231,9 +3223,9 @@ nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageUsedSpaceRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3252,9 +3244,9 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageAvailableRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3273,9 +3265,9 @@ nsDOMDeviceStorage::StorageStatus(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageStatusRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3294,9 +3286,9 @@ nsDOMDeviceStorage::Format(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageFormatRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3315,9 +3307,9 @@ nsDOMDeviceStorage::Mount(ErrorResult& aRv)
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageMountRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3337,9 +3329,9 @@ nsDOMDeviceStorage::Unmount(ErrorResult& aRv)
|
|||
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageUnmountRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3385,9 +3377,9 @@ nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath,
|
|||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageCreateFdRequest();
|
||||
request->Initialize(mManager, dsf, id, aDSFileDescriptor);
|
||||
request->Initialize(mManager, dsf.forget(), id, aDSFileDescriptor);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
|
@ -3492,8 +3484,8 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
|
|||
if (!dsf->IsSafePath()) {
|
||||
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
|
||||
} else {
|
||||
request->Initialize(mManager, dsf, id, since);
|
||||
aRv = CheckPermission(request);
|
||||
request->Initialize(mManager, dsf.forget(), id, since);
|
||||
aRv = CheckPermission(request.forget());
|
||||
}
|
||||
|
||||
return cursor.forget();
|
||||
|
@ -3695,8 +3687,8 @@ nsDOMDeviceStorage::EventListenerWasAdded(const nsAString& aType,
|
|||
RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
|
||||
mStorageName);
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageWatchRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
aRv = CheckPermission(request);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
aRv = CheckPermission(request.forget());
|
||||
}
|
||||
|
||||
Atomic<uint32_t> DeviceStorageRequestManager::sLastRequestId(0);
|
||||
|
@ -3760,14 +3752,15 @@ DeviceStorageRequestManager::IsOwningThread()
|
|||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestManager::DispatchToOwningThread(nsIRunnable* aRunnable)
|
||||
DeviceStorageRequestManager::DispatchToOwningThread(
|
||||
already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
|
||||
nsIRunnable* aRunnable)
|
||||
DeviceStorageRequestManager::DispatchOrAbandon(
|
||||
uint32_t aId, already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mShutdown) {
|
||||
|
@ -3776,10 +3769,11 @@ DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
|
|||
safe to be freed off the owner thread but the dispatch method
|
||||
does not know that. */
|
||||
DS_LOG_DEBUG("shutdown %u", aId);
|
||||
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
||||
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
|
||||
}
|
||||
|
||||
nsresult rv = DispatchToOwningThread(aRunnable);
|
||||
nsresult rv = DispatchToOwningThread(Move(aRunnable));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
DS_LOG_ERROR("abandon %u", aId);
|
||||
}
|
||||
|
@ -3846,7 +3840,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, bool aForceDispatch)
|
|||
{
|
||||
self->Resolve(aId, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u", aId);
|
||||
|
@ -3878,7 +3872,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, const nsString& aResult,
|
|||
{
|
||||
self->Resolve(aId, result, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %s", aId,
|
||||
|
@ -3923,7 +3917,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, uint64_t aValue,
|
|||
{
|
||||
self->Resolve(aId, aValue, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %" PRIu64, aId, aValue);
|
||||
|
@ -4003,7 +3997,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, BlobImpl* aBlobImpl,
|
|||
{
|
||||
self->Resolve(aId, blobImpl, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %p", aId, aBlobImpl);
|
||||
|
@ -4131,7 +4125,7 @@ DeviceStorageRequestManager::Reject(uint32_t aId, const nsString& aReason)
|
|||
|
||||
self->RejectInternal(i, reason);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -130,16 +130,16 @@ public:
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
RefPtr<InvalidateRunnable> r = new InvalidateRunnable(this, aStorageName);
|
||||
mIOThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mIOThread->Dispatch(new InvalidateRunnable(this, aStorageName),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void Dispatch(nsIRunnable* aRunnable)
|
||||
void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
mIOThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
mIOThread->Dispatch(mozilla::Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult AccumUsedSizes(const nsAString& aStorageName,
|
||||
|
@ -245,7 +245,7 @@ public:
|
|||
DeviceStorageRequestManager();
|
||||
|
||||
bool IsOwningThread();
|
||||
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
|
||||
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
void StorePermission(size_t aAccess, bool aAllow);
|
||||
uint32_t CheckPermission(size_t aAccess);
|
||||
|
@ -290,7 +290,8 @@ private:
|
|||
uint32_t CreateInternal(mozilla::dom::DOMRequest* aRequest, bool aCursor);
|
||||
nsresult ResolveInternal(ListIndex aIndex, JS::HandleValue aResult);
|
||||
nsresult RejectInternal(ListIndex aIndex, const nsString& aReason);
|
||||
nsresult DispatchOrAbandon(uint32_t aId, nsIRunnable* aRunnable);
|
||||
nsresult DispatchOrAbandon(uint32_t aId,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
ListType::index_type Find(uint32_t aId);
|
||||
|
||||
nsCOMPtr<nsIThread> mOwningThread;
|
||||
|
@ -311,16 +312,16 @@ protected:
|
|||
|
||||
public:
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest);
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
mozilla::dom::BlobImpl* aBlob);
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
DeviceStorageFileDescriptor* aDSFileDescriptor);
|
||||
|
||||
|
@ -411,7 +412,7 @@ public:
|
|||
using DeviceStorageRequest::Initialize;
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
PRTime aSince);
|
||||
|
||||
|
|
|
@ -3442,7 +3442,7 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
|
|||
NotifyOwnerDocumentActivityChangedInternal();
|
||||
}
|
||||
|
||||
if (mDefaultPlaybackStartPosition > 0) {
|
||||
if (mDefaultPlaybackStartPosition != 0.0) {
|
||||
SetCurrentTime(mDefaultPlaybackStartPosition);
|
||||
mDefaultPlaybackStartPosition = 0.0;
|
||||
}
|
||||
|
|
|
@ -2177,8 +2177,7 @@ ContentChild::ActorDestroy(ActorDestroyReason why)
|
|||
// going through the full XPCOM shutdown path, because it doesn't
|
||||
// keep persistent state.
|
||||
QuickExit();
|
||||
#endif
|
||||
|
||||
#else
|
||||
if (sFirstIdleTask) {
|
||||
sFirstIdleTask->Cancel();
|
||||
}
|
||||
|
@ -2203,6 +2202,7 @@ ContentChild::ActorDestroy(ActorDestroyReason why)
|
|||
#endif
|
||||
|
||||
XRE_ShutdownChildProcess();
|
||||
#endif // NS_FREE_PERMANENT_DATA
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,9 +47,9 @@ DetailedPromise::MaybeReject(nsresult aArg, const nsACString& aReason)
|
|||
|
||||
LogToBrowserConsole(NS_ConvertUTF8toUTF16(msg));
|
||||
|
||||
RefPtr<DOMException> exception =
|
||||
DOMException::Create(aArg, aReason);
|
||||
Promise::MaybeRejectBrokenly(exception);
|
||||
ErrorResult rv;
|
||||
rv.ThrowDOMException(aArg, aReason);
|
||||
Promise::MaybeReject(rv);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <gui/Surface.h>
|
||||
#include <ICrypto.h>
|
||||
#include "GonkVideoDecoderManager.h"
|
||||
#include "GrallocImages.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "VideoUtils.h"
|
||||
|
@ -45,7 +46,6 @@ GonkVideoDecoderManager::GonkVideoDecoderManager(
|
|||
const VideoInfo& aConfig)
|
||||
: mImageContainer(aImageContainer)
|
||||
, mColorConverterBufferSize(0)
|
||||
, mNativeWindow(nullptr)
|
||||
, mPendingReleaseItemsLock("GonkVideoDecoderManager::mPendingReleaseItemsLock")
|
||||
, mNeedsCopyBuffer(false)
|
||||
{
|
||||
|
@ -122,7 +122,13 @@ GonkVideoDecoderManager::Init()
|
|||
uint32_t capability = MediaCodecProxy::kEmptyCapability;
|
||||
if (mDecoder->getCapability(&capability) == OK && (capability &
|
||||
MediaCodecProxy::kCanExposeGraphicBuffer)) {
|
||||
#if ANDROID_VERSION >= 21
|
||||
sp<IGonkGraphicBufferConsumer> consumer;
|
||||
GonkBufferQueue::createBufferQueue(&mGraphicBufferProducer, &consumer);
|
||||
mNativeWindow = new GonkNativeWindow(consumer);
|
||||
#else
|
||||
mNativeWindow = new GonkNativeWindow();
|
||||
#endif
|
||||
}
|
||||
|
||||
mVideoCodecRequest.Begin(mDecoder->AsyncAllocateVideoMediaCodec()
|
||||
|
@ -604,7 +610,11 @@ GonkVideoDecoderManager::codecReserved()
|
|||
// the video decoding.
|
||||
format->setInt32("moz-use-undequeued-bufs", 1);
|
||||
if (mNativeWindow != nullptr) {
|
||||
#if ANDROID_VERSION >= 21
|
||||
surface = new Surface(mGraphicBufferProducer);
|
||||
#else
|
||||
surface = new Surface(mNativeWindow->getBufferQueue());
|
||||
#endif
|
||||
}
|
||||
mDecoder->configure(format, surface, nullptr, 0);
|
||||
mDecoder->Prepare();
|
||||
|
|
|
@ -116,6 +116,10 @@ private:
|
|||
size_t mColorConverterBufferSize;
|
||||
|
||||
android::sp<android::GonkNativeWindow> mNativeWindow;
|
||||
#if ANDROID_VERSION >= 21
|
||||
android::sp<android::IGraphicBufferProducer> mGraphicBufferProducer;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
kNotifyPostReleaseBuffer = 'nprb',
|
||||
};
|
||||
|
|
|
@ -771,6 +771,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
|||
tags=capturestream
|
||||
[test_resume.html]
|
||||
skip-if = true # bug 1021673
|
||||
[test_seek_negative.html]
|
||||
[test_seek_nosrc.html]
|
||||
[test_seek_out_of_range.html]
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: seeking to a negative time with readyState HAVE_NOTHING</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function startTest(test, token) {
|
||||
var type = getMajorMimeType(test.type);
|
||||
var v = document.createElement(type);
|
||||
v.token = token;
|
||||
manager.started(token);
|
||||
|
||||
// Seek to negative start time.
|
||||
v.currentTime = -123;
|
||||
is(v.readyState, v.HAVE_NOTHING, "readyState is HAVE_NOTHING");
|
||||
ok(!v.seeking, "can't be seeking prior src defined");
|
||||
is(v.currentTime, -123, "currentTime is original seek time");
|
||||
|
||||
v.src = test.name;
|
||||
|
||||
// Initialize running variables.
|
||||
v._name = test.name;
|
||||
v._seekStarted = false;
|
||||
v._seekCompleted = false;
|
||||
v._metadata = false;
|
||||
|
||||
var events = [ "suspend", "play", "canplay", "canplaythrough", "loadstart",
|
||||
"loadedmetadata", "loadeddata", "playing", "ended", "error",
|
||||
"stalled", "emptied", "abort", "waiting", "pause" ];
|
||||
function logEvent(e) {
|
||||
var v = e.target;
|
||||
Log(e.target.token, "got " + e.type + " with currentTime = " + v.currentTime);
|
||||
}
|
||||
events.forEach(function(e) {
|
||||
v.addEventListener(e, logEvent, false);
|
||||
});
|
||||
|
||||
once(v, "seeking", function() {
|
||||
v._seekStarted = true;
|
||||
ok(v.currentTime >= 0, "currentTime should be positive");
|
||||
});
|
||||
once(v, "seeked", function() {
|
||||
v._seekCompleted = true;
|
||||
ok(v.currentTime >= 0, "currentTime should be positive");
|
||||
});
|
||||
once(v, "loadedmetadata", function() {
|
||||
v._metadata = true;
|
||||
ok(v.seeking, "element is seeking once readyState is HAVE_METADATA");
|
||||
ok(v.currentTime >= 0, "currentTime should be positive");
|
||||
});
|
||||
once(v, "ended", function() {
|
||||
ok(v._seekStarted, "seek should have started");
|
||||
ok(v._seekCompleted, "seek should have completed");
|
||||
ok(v._metadata, "loadedmetadata fired");
|
||||
ok(v.currentTime >= 0, "currentTime should be positive");
|
||||
removeNodeAndSource(v);
|
||||
manager.finished(v.token);
|
||||
});
|
||||
|
||||
v.play();
|
||||
}
|
||||
|
||||
|
||||
manager.runTests(gSmallTests, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/MediaStreamError.h"
|
||||
#include "mozilla/dom/PromiseBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
@ -1766,10 +1765,6 @@ void Promise::MaybeRejectBrokenly(const RefPtr<DOMError>& aArg) {
|
|||
MaybeSomething(aArg, &Promise::MaybeReject);
|
||||
}
|
||||
template<>
|
||||
void Promise::MaybeRejectBrokenly(const RefPtr<DOMException>& aArg) {
|
||||
MaybeSomething(aArg, &Promise::MaybeReject);
|
||||
}
|
||||
template<>
|
||||
void Promise::MaybeRejectBrokenly(const nsAString& aArg) {
|
||||
MaybeSomething(aArg, &Promise::MaybeReject);
|
||||
}
|
||||
|
|
|
@ -421,7 +421,9 @@ nsContentSecurityManager::IsURIPotentiallyTrustworthy(nsIURI* aURI, bool* aIsTru
|
|||
*aIsTrustWorthy = false;
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = aURI->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (scheme.EqualsLiteral("https") ||
|
||||
scheme.EqualsLiteral("file") ||
|
||||
|
@ -433,7 +435,9 @@ nsContentSecurityManager::IsURIPotentiallyTrustworthy(nsIURI* aURI, bool* aIsTru
|
|||
|
||||
nsAutoCString host;
|
||||
rv = aURI->GetHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (host.Equals("127.0.0.1") ||
|
||||
host.Equals("localhost") ||
|
||||
|
@ -441,6 +445,5 @@ nsContentSecurityManager::IsURIPotentiallyTrustworthy(nsIURI* aURI, bool* aIsTru
|
|||
*aIsTrustWorthy = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1286,6 +1286,9 @@ AudioManager::SelectDeviceFromDevices(uint32_t aOutDevices)
|
|||
device &= AUDIO_DEVICE_OUT_ALL_A2DP;
|
||||
}
|
||||
}
|
||||
#if ANDROID_VERSION >= 17
|
||||
MOZ_ASSERT(audio_is_output_device(device));
|
||||
#endif
|
||||
return device;
|
||||
}
|
||||
AudioManager::VolumeStreamState::VolumeStreamState(AudioManager& aManager,
|
||||
|
|
|
@ -547,6 +547,17 @@ enum {
|
|||
typedef uint32_t audio_devices_t;
|
||||
#endif
|
||||
|
||||
#if ANDROID_VERSION >= 17
|
||||
static inline bool audio_is_output_device(audio_devices_t device)
|
||||
{
|
||||
if (((device & AUDIO_DEVICE_BIT_IN) == 0) &&
|
||||
(__builtin_popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* device connection states used for audio_policy->set_device_connection_state()
|
||||
* */
|
||||
typedef enum {
|
||||
|
|
|
@ -865,7 +865,7 @@ class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
|
|||
nsCString mScope;
|
||||
nsCString mScriptSpec;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
RefPtr<ServiceWorkerUpdateFinishCallback> mCallback;
|
||||
nsTArray<RefPtr<ServiceWorkerUpdateFinishCallback>> mCallbacks;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
RefPtr<ServiceWorkerInfo> mUpdateAndInstallInfo;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
@ -894,13 +894,16 @@ public:
|
|||
: ServiceWorkerJob(aQueue)
|
||||
, mScope(aScope)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mCallback(aCallback)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mLoadGroup(aLoadGroup)
|
||||
, mJobType(REGISTER_JOB)
|
||||
, mCanceled(false)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mLoadGroup);
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
mCallbacks.AppendElement(aCallback);
|
||||
}
|
||||
|
||||
// [[Update]]
|
||||
|
@ -909,10 +912,14 @@ public:
|
|||
ServiceWorkerUpdateFinishCallback* aCallback)
|
||||
: ServiceWorkerJob(aQueue)
|
||||
, mRegistration(aRegistration)
|
||||
, mCallback(aCallback)
|
||||
, mJobType(UPDATE_JOB)
|
||||
, mCanceled(false)
|
||||
{ }
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
mCallbacks.AppendElement(aCallback);
|
||||
}
|
||||
|
||||
bool
|
||||
IsRegisterJob() const override
|
||||
|
@ -920,6 +927,16 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AppendCallback(ServiceWorkerUpdateFinishCallback* aCallback)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT(!mCallbacks.Contains(aCallback));
|
||||
|
||||
mCallbacks.AppendElement(aCallback);
|
||||
}
|
||||
|
||||
void
|
||||
Cancel()
|
||||
{
|
||||
|
@ -971,6 +988,10 @@ public:
|
|||
swm->StoreRegistration(mPrincipal, mRegistration);
|
||||
} else {
|
||||
MOZ_ASSERT(mJobType == UPDATE_JOB);
|
||||
MOZ_ASSERT(mRegistration);
|
||||
MOZ_ASSERT(mRegistration->mUpdateJob == nullptr);
|
||||
|
||||
mRegistration->mUpdateJob = this;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
@ -1101,8 +1122,9 @@ public:
|
|||
void
|
||||
Fail(ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mCallback);
|
||||
RefPtr<ServiceWorkerUpdateFinishCallback> callback = mCallback.forget();
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mCallbacks.Length());
|
||||
|
||||
// With cancellation support, we may only be running with one reference
|
||||
// from another object like a stream loader or something.
|
||||
RefPtr<ServiceWorkerRegisterJob> kungFuDeathGrip = this;
|
||||
|
@ -1135,7 +1157,14 @@ public:
|
|||
aRv.ThrowTypeError<MSG_SW_INSTALL_ERROR>(&scriptSpec, &scope);
|
||||
}
|
||||
|
||||
callback->UpdateFailed(aRv);
|
||||
for (uint32_t i = 1; i < mCallbacks.Length(); ++i) {
|
||||
ErrorResult rv;
|
||||
aRv.CloneTo(rv);
|
||||
mCallbacks[i]->UpdateFailed(rv);
|
||||
rv.SuppressException();
|
||||
}
|
||||
|
||||
mCallbacks[0]->UpdateFailed(aRv);
|
||||
|
||||
// In case the callback does not consume the exception
|
||||
aRv.SuppressException();
|
||||
|
@ -1152,6 +1181,7 @@ public:
|
|||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
swm->MaybeRemoveRegistration(mRegistration);
|
||||
// Ensures that the job can't do anything useful from this point on.
|
||||
mRegistration->mUpdateJob = nullptr;
|
||||
mRegistration = nullptr;
|
||||
Done(origStatus);
|
||||
}
|
||||
|
@ -1294,9 +1324,13 @@ private:
|
|||
void
|
||||
Succeed()
|
||||
{
|
||||
MOZ_ASSERT(mCallback);
|
||||
mCallback->UpdateSucceeded(mRegistration);
|
||||
mCallback = nullptr;
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mCallbacks.Length());
|
||||
|
||||
for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
|
||||
mCallbacks[i]->UpdateSucceeded(mRegistration);
|
||||
}
|
||||
mCallbacks.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1350,6 +1384,18 @@ private:
|
|||
// Activate() is invoked out of band of atomic.
|
||||
mRegistration->TryToActivate();
|
||||
}
|
||||
|
||||
void
|
||||
Done(nsresult aStatus)
|
||||
{
|
||||
ServiceWorkerJob::Done(aStatus);
|
||||
|
||||
if (mJobType == UPDATE_JOB && mRegistration) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mRegistration->mUpdateJob);
|
||||
mRegistration->mUpdateJob = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(ServiceWorkerRegisterJob, ServiceWorkerJob);
|
||||
|
@ -2620,6 +2666,23 @@ ServiceWorkerRegistrationInfo::NotifyListenersOnChange()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerRegistrationInfo::IsUpdating() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mUpdateJob != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerRegistrationInfo::AppendUpdateCallback(ServiceWorkerUpdateFinishCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT(mUpdateJob);
|
||||
|
||||
mUpdateJob->AppendCallback(aCallback);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::LoadRegistration(
|
||||
const ServiceWorkerRegistrationData& aRegistration)
|
||||
|
@ -3551,9 +3614,17 @@ ServiceWorkerManager::SoftUpdate(const nsACString& aScopeKey,
|
|||
|
||||
// "Invoke Update algorithm, or its equivalent, with client, registration as
|
||||
// its argument."
|
||||
RefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, registration, cb);
|
||||
queue->Append(job);
|
||||
if (registration->IsUpdating()) {
|
||||
// This is used to reduce burst of update events. If there is an update
|
||||
// job in queue when we try to create a new one, drop current one and
|
||||
// merge the callback function to existing update job.
|
||||
// See. https://github.com/slightlyoff/ServiceWorker/issues/759
|
||||
registration->AppendUpdateCallback(cb);
|
||||
} else {
|
||||
RefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, registration, cb);
|
||||
queue->Append(job);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -47,9 +47,11 @@ class ServiceWorker;
|
|||
class ServiceWorkerClientInfo;
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerJob;
|
||||
class ServiceWorkerRegisterJob;
|
||||
class ServiceWorkerJobQueue;
|
||||
class ServiceWorkerManagerChild;
|
||||
class ServiceWorkerPrivate;
|
||||
class ServiceWorkerUpdateFinishCallback;
|
||||
|
||||
class ServiceWorkerRegistrationInfo final : public nsIServiceWorkerRegistrationInfo
|
||||
{
|
||||
|
@ -76,6 +78,8 @@ public:
|
|||
|
||||
uint64_t mLastUpdateCheckTime;
|
||||
|
||||
RefPtr<ServiceWorkerRegisterJob> mUpdateJob;
|
||||
|
||||
// When unregister() is called on a registration, it is not immediately
|
||||
// removed since documents may be controlled. It is marked as
|
||||
// pendingUninstall and when all controlling documents go away, removed.
|
||||
|
@ -143,6 +147,12 @@ public:
|
|||
|
||||
void
|
||||
NotifyListenersOnChange();
|
||||
|
||||
bool
|
||||
IsUpdating() const;
|
||||
|
||||
void
|
||||
AppendUpdateCallback(ServiceWorkerUpdateFinishCallback* aCallback);
|
||||
};
|
||||
|
||||
class ServiceWorkerUpdateFinishCallback
|
||||
|
|
|
@ -114,8 +114,10 @@ SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner,
|
|||
GrTexture *skiaTexture = aOwner->mGrContext->wrapBackendTexture(skiaTexGlue);
|
||||
SkImageInfo imgInfo = SkImageInfo::Make(aSize.width, aSize.height, GfxFormatToSkiaColorType(aFormat), kOpaque_SkAlphaType);
|
||||
SkGrPixelRef *texRef = new SkGrPixelRef(imgInfo, skiaTexture, false);
|
||||
mBitmap.setInfo(imgInfo, aSize.width*aSize.height*4);
|
||||
mBitmap.setInfo(imgInfo);
|
||||
mBitmap.setPixelRef(texRef);
|
||||
mFormat = aFormat;
|
||||
mStride = mBitmap.rowBytes();
|
||||
#endif
|
||||
|
||||
mDrawTarget = aOwner;
|
||||
|
|
|
@ -150,8 +150,11 @@ nsFontMetrics::Init(const nsFont& aFont,
|
|||
|
||||
aFont.AddFontFeaturesToStyle(&style);
|
||||
|
||||
gfxFloat devToCssSize = gfxFloat(mP2A) /
|
||||
gfxFloat(mDeviceContext->AppUnitsPerCSSPixel());
|
||||
mFontGroup = gfxPlatform::GetPlatform()->
|
||||
CreateFontGroup(aFont.fontlist, &style, aTextPerf, aUserFontSet);
|
||||
CreateFontGroup(aFont.fontlist, &style, aTextPerf,
|
||||
aUserFontSet, devToCssSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
<object>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛
|
||||
<i>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
|
||||
<script>
|
||||
var doc = document;
|
||||
if (document.getElementById('content')) {
|
||||
doc = document.getElementById('content').contentDocument;
|
||||
}
|
||||
|
||||
var docviewer;
|
||||
function do_onload() {
|
||||
var navigator1 = SpecialPowers.wrap(parent).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).getInterface(SpecialPowers.Ci.nsIWebNavigation);
|
||||
var docShell = navigator1.QueryInterface(SpecialPowers.Ci.nsIDocShell);
|
||||
docviewer = docShell.contentViewer.QueryInterface(SpecialPowers.Ci.nsIMarkupDocumentViewer);
|
||||
|
||||
setTimeout(doe,500, 0.2);
|
||||
}
|
||||
do_onload();
|
||||
|
||||
|
||||
|
||||
function doe(i) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
docviewer.textZoom += i;
|
||||
|
||||
if (docviewer.textZoom >=4)
|
||||
i = -0.2;
|
||||
|
||||
if (docviewer.textZoom <=0)
|
||||
i = 0.2;
|
||||
window.status = docviewer.textZoom;
|
||||
setTimeout(doe, 100, i);
|
||||
}
|
||||
</script>
|
||||
<object>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
᚛᚛᚛᚛
|
||||
<i>᚛᚛᚛᚛᚛᚛᚛᚛᚛᚛
|
||||
|
||||
<script>
|
||||
var doc = document;
|
||||
if (document.getElementById('content')) {
|
||||
doc = document.getElementById('content').contentDocument;
|
||||
}
|
||||
|
||||
var docviewer;
|
||||
function do_onload() {
|
||||
var navigator1 = SpecialPowers.wrap(parent).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).getInterface(SpecialPowers.Ci.nsIWebNavigation);
|
||||
var docShell = navigator1.QueryInterface(SpecialPowers.Ci.nsIDocShell);
|
||||
docviewer = docShell.contentViewer;
|
||||
|
||||
setTimeout(doe,500, 0.2);
|
||||
}
|
||||
do_onload();
|
||||
|
||||
|
||||
|
||||
function doe(i) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
docviewer.textZoom += i;
|
||||
|
||||
if (docviewer.textZoom >=4)
|
||||
i = -0.2;
|
||||
|
||||
if (docviewer.textZoom <=0)
|
||||
i = 0.2;
|
||||
window.status = docviewer.textZoom;
|
||||
setTimeout(doe, 100, i);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -249,7 +249,7 @@ static bool
|
|||
RunTest (TestEntry *test, gfxContext *ctx) {
|
||||
RefPtr<gfxFontGroup> fontGroup;
|
||||
|
||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle, nullptr, nullptr);
|
||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->utf8FamilyString), &test->fontStyle, nullptr, nullptr, 1.0);
|
||||
|
||||
nsAutoPtr<gfxTextRun> textRun;
|
||||
gfxTextRunFactory::Parameters params = {
|
||||
|
|
|
@ -63,7 +63,7 @@ RunTest (TestEntry *test, gfxContext *ctx) {
|
|||
false, false,
|
||||
NS_LITERAL_STRING(""));
|
||||
|
||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16, nullptr, nullptr);
|
||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16, nullptr, nullptr, 1.0);
|
||||
}
|
||||
|
||||
nsAutoPtr<gfxTextRun> textRun;
|
||||
|
|
|
@ -111,7 +111,7 @@ TEST(Gfx, WordCache) {
|
|||
RefPtr<gfxFontGroup> fontGroup =
|
||||
gfxPlatform::GetPlatform()->CreateFontGroup(
|
||||
NS_LITERAL_STRING("Geneva, MS Sans Serif, Helvetica,serif"), &style,
|
||||
nullptr, nullptr);
|
||||
nullptr, nullptr, 1.0);
|
||||
|
||||
gfxTextRunFactory::Parameters params = {
|
||||
ctx, nullptr, nullptr, nullptr, 0, 60
|
||||
|
|
|
@ -313,9 +313,11 @@ gfxFontGroup *
|
|||
gfxAndroidPlatform::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet* aUserFontSet)
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf, aUserFontSet);
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
FT_Library
|
||||
|
|
|
@ -73,7 +73,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) override;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
virtual bool FontHintingEnabled() override;
|
||||
virtual bool RequiresLinearZoom() override;
|
||||
|
|
|
@ -1257,7 +1257,8 @@ gfxDWriteFontList::GetStandardFamilyName(const nsAString& aFontName,
|
|||
}
|
||||
|
||||
gfxFontFamily*
|
||||
gfxDWriteFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle)
|
||||
gfxDWriteFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
nsAutoString keyName(aFamily);
|
||||
BuildKeyNameFromFontName(keyName);
|
||||
|
|
|
@ -368,7 +368,8 @@ public:
|
|||
bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
|
||||
|
||||
gfxFontFamily* FindFamily(const nsAString& aFamily,
|
||||
gfxFontStyle* aStyle = nullptr) override;
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
|
||||
|
||||
|
|
|
@ -1310,7 +1310,8 @@ gfxFcPlatformFontList::MakePlatformFont(const nsAString& aFontName,
|
|||
}
|
||||
|
||||
gfxFontFamily*
|
||||
gfxFcPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle)
|
||||
gfxFcPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
nsAutoString familyName(aFamily);
|
||||
ToLowerCase(familyName);
|
||||
|
|
|
@ -225,7 +225,8 @@ public:
|
|||
uint32_t aLength) override;
|
||||
|
||||
gfxFontFamily* FindFamily(const nsAString& aFamily,
|
||||
gfxFontStyle* aStyle = nullptr) override;
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
bool GetStandardFamilyName(const nsAString& aFontName,
|
||||
nsAString& aFamilyName) override;
|
||||
|
|
|
@ -871,8 +871,8 @@ gfxFontEntry::HasGraphiteSpaceContextuals()
|
|||
const gr_faceinfo* faceInfo = gr_face_info(face, 0);
|
||||
mHasGraphiteSpaceContextuals =
|
||||
faceInfo->space_contextuals != gr_faceinfo::gr_space_none;
|
||||
ReleaseGrFace(face);
|
||||
}
|
||||
ReleaseGrFace(face); // always balance GetGrFace, even if face is null
|
||||
mGraphiteSpaceContextualsInitialized = true;
|
||||
}
|
||||
return mHasGraphiteSpaceContextuals;
|
||||
|
@ -1051,7 +1051,7 @@ gfxFontEntry::SupportsGraphiteFeature(uint32_t aFeatureTag)
|
|||
}
|
||||
|
||||
gr_face* face = GetGrFace();
|
||||
result = gr_face_find_fref(face, aFeatureTag) != nullptr;
|
||||
result = face ? gr_face_find_fref(face, aFeatureTag) != nullptr : false;
|
||||
ReleaseGrFace(face);
|
||||
|
||||
mSupportedFeatures->Put(scriptFeature, result);
|
||||
|
|
|
@ -1258,8 +1258,9 @@ PrepareSortPattern(FcPattern *aPattern, double aFallbackSize,
|
|||
|
||||
gfxPangoFontGroup::gfxPangoFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet)
|
||||
: gfxFontGroup(aFontFamilyList, aStyle, nullptr, aUserFontSet),
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
: gfxFontGroup(aFontFamilyList, aStyle, nullptr, aUserFontSet, aDevToCssSize),
|
||||
mPangoLanguage(GuessPangoLanguage(aStyle->language))
|
||||
{
|
||||
// This language is passed to the font for shaping.
|
||||
|
@ -1280,7 +1281,7 @@ gfxPangoFontGroup::~gfxPangoFontGroup()
|
|||
gfxFontGroup *
|
||||
gfxPangoFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||
{
|
||||
return new gfxPangoFontGroup(mFamilyList, aStyle, mUserFontSet);
|
||||
return new gfxPangoFontGroup(mFamilyList, aStyle, mUserFontSet, mDevToCssSize);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1813,7 +1814,7 @@ gfxPangoFontGroup::GetFTLibrary()
|
|||
gfxFontStyle style;
|
||||
RefPtr<gfxPangoFontGroup> fontGroup =
|
||||
new gfxPangoFontGroup(FontFamilyList(eFamily_sans_serif),
|
||||
&style, nullptr);
|
||||
&style, nullptr, 1.0);
|
||||
|
||||
gfxFcFont *font = fontGroup->GetBaseFont();
|
||||
if (!font)
|
||||
|
|
|
@ -25,7 +25,8 @@ class gfxPangoFontGroup : public gfxFontGroup {
|
|||
public:
|
||||
gfxPangoFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet);
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize);
|
||||
virtual ~gfxPangoFontGroup();
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
|
|
@ -831,7 +831,8 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
|
|||
}
|
||||
|
||||
gfxFontFamily*
|
||||
gfxGDIFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle)
|
||||
gfxGDIFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
nsAutoString keyName(aFamily);
|
||||
BuildKeyNameFromFontName(keyName);
|
||||
|
|
|
@ -306,7 +306,8 @@ public:
|
|||
virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
|
||||
|
||||
gfxFontFamily* FindFamily(const nsAString& aFamily,
|
||||
gfxFontStyle* aStyle = nullptr) override;
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
|
|
|
@ -96,7 +96,8 @@ public:
|
|||
uint32_t aLength) override;
|
||||
|
||||
gfxFontFamily* FindFamily(const nsAString& aFamily,
|
||||
gfxFontStyle* aStyle = nullptr) override;
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
// lookup the system font for a particular system font type and set
|
||||
// the name and style characteristics
|
||||
|
|
|
@ -1092,18 +1092,19 @@ gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName,
|
|||
static const char kSystemFont_system[] = "-apple-system";
|
||||
|
||||
gfxFontFamily*
|
||||
gfxMacPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle)
|
||||
gfxMacPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
// search for special system font name, -apple-system
|
||||
if (aFamily.EqualsLiteral(kSystemFont_system)) {
|
||||
if (mUseSizeSensitiveSystemFont &&
|
||||
aStyle && aStyle->size >= kTextDisplayCrossover) {
|
||||
aStyle && (aStyle->size * aDevToCssSize) >= kTextDisplayCrossover) {
|
||||
return mSystemDisplayFontFamily;
|
||||
}
|
||||
return mSystemTextFontFamily;
|
||||
}
|
||||
|
||||
return gfxPlatformFontList::FindFamily(aFamily, aStyle);
|
||||
return gfxPlatformFontList::FindFamily(aFamily, aStyle, aDevToCssSize);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -337,7 +337,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) = 0;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) = 0;
|
||||
|
||||
/**
|
||||
* Look up a local platform font using the full font face name.
|
||||
|
|
|
@ -639,7 +639,8 @@ gfxPlatformFontList::CheckFamily(gfxFontFamily *aFamily)
|
|||
}
|
||||
|
||||
gfxFontFamily*
|
||||
gfxPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle)
|
||||
gfxPlatformFontList::FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
nsAutoString key;
|
||||
gfxFontFamily *familyEntry;
|
||||
|
|
|
@ -129,8 +129,9 @@ public:
|
|||
int32_t aRunScript,
|
||||
const gfxFontStyle* aStyle);
|
||||
|
||||
virtual gfxFontFamily* FindFamily(const nsAString& aFamily,
|
||||
gfxFontStyle* aStyle = nullptr);
|
||||
virtual gfxFontFamily*
|
||||
FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0);
|
||||
|
||||
gfxFontEntry* FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, bool& aNeedsBold);
|
||||
|
||||
|
|
|
@ -247,13 +247,16 @@ gfxFontGroup *
|
|||
gfxPlatformGtk::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet* aUserFontSet)
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf, aUserFontSet);
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
return new gfxPangoFontGroup(aFontFamilyList, aStyle, aUserFontSet);
|
||||
return new gfxPangoFontGroup(aFontFamilyList, aStyle,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
|
|
@ -54,7 +54,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) override;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
/**
|
||||
* Look up a local platform font using the full font face name (needed to
|
||||
|
|
|
@ -142,9 +142,11 @@ gfxFontGroup *
|
|||
gfxPlatformMac::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet)
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf, aUserFontSet);
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
// these will move to gfxPlatform once all platforms support the fontlist
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) override;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
|
|
|
@ -123,9 +123,11 @@ gfxFontGroup *
|
|||
gfxQtPlatform::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet* aUserFontSet)
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
return new gfxPangoFontGroup(aFontFamilyList, aStyle, aUserFontSet);
|
||||
return new gfxPangoFontGroup(aFontFamilyList, aStyle,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
|
|
@ -45,7 +45,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) override;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
/**
|
||||
* Look up a local platform font using the full font face name (needed to
|
||||
|
|
|
@ -1532,11 +1532,13 @@ gfxTextRun::Dump(FILE* aOutput) {
|
|||
gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet)
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
: mFamilyList(aFontFamilyList)
|
||||
, mStyle(*aStyle)
|
||||
, mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET)
|
||||
, mHyphenWidth(-1)
|
||||
, mDevToCssSize(aDevToCssSize)
|
||||
, mUserFontSet(aUserFontSet)
|
||||
, mTextPerf(aTextPerf)
|
||||
, mPageLang(gfxPlatformFontList::GetFontPrefLangFor(aStyle->language))
|
||||
|
@ -1619,7 +1621,7 @@ gfxFontGroup::AddPlatformFont(const nsAString& aName,
|
|||
// Not known in the user font set ==> check system fonts
|
||||
if (!family) {
|
||||
gfxPlatformFontList* fontList = gfxPlatformFontList::PlatformFontList();
|
||||
family = fontList->FindFamily(aName, &mStyle);
|
||||
family = fontList->FindFamily(aName, &mStyle, mDevToCssSize);
|
||||
}
|
||||
|
||||
if (family) {
|
||||
|
@ -1896,7 +1898,8 @@ gfxFontGroup *
|
|||
gfxFontGroup::Copy(const gfxFontStyle *aStyle)
|
||||
{
|
||||
gfxFontGroup *fg =
|
||||
new gfxFontGroup(mFamilyList, aStyle, mTextPerf, mUserFontSet);
|
||||
new gfxFontGroup(mFamilyList, aStyle, mTextPerf,
|
||||
mUserFontSet, mDevToCssSize);
|
||||
return fg;
|
||||
}
|
||||
|
||||
|
|
|
@ -727,7 +727,8 @@ public:
|
|||
gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle* aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet* aUserFontSet = nullptr);
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize);
|
||||
|
||||
virtual ~gfxFontGroup();
|
||||
|
||||
|
@ -1027,6 +1028,7 @@ protected:
|
|||
|
||||
gfxFloat mUnderlineOffset;
|
||||
gfxFloat mHyphenWidth;
|
||||
gfxFloat mDevToCssSize;
|
||||
|
||||
RefPtr<gfxUserFontSet> mUserFontSet;
|
||||
uint64_t mCurrGeneration; // track the current user font set generation, rebuild font list if needed
|
||||
|
|
|
@ -129,8 +129,7 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet,
|
|||
mFeatureSettings.AppendElements(aFeatureSettings);
|
||||
mLanguageOverride = aLanguageOverride;
|
||||
|
||||
if (aUnicodeRanges &&
|
||||
Preferences::GetBool("layout.css.unicode-range.enabled")) {
|
||||
if (aUnicodeRanges) {
|
||||
mCharacterMap = new gfxCharacterMap(*aUnicodeRanges);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1048,9 +1048,11 @@ gfxFontGroup *
|
|||
gfxWindowsPlatform::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet)
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf, aUserFontSet);
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
|
|
@ -185,7 +185,8 @@ public:
|
|||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet) override;
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
/**
|
||||
* Look up a local platform font using the full font face name (needed to support @font-face src local() )
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
diff --git a/intl/icu/source/tools/pkgdata/pkgdata.cpp b/intl/icu/source/tools/pkgdata/pkgdata.cpp
|
||||
--- a/intl/icu/source/tools/toolutil/flagparser.c
|
||||
+++ b/intl/icu/source/tools/toolutil/flagparser.c
|
||||
@@ -96,8 +96,8 @@
|
||||
uprv_free(buffer);
|
||||
|
||||
T_FileStream_close(f);
|
||||
-
|
||||
- if (U_FAILURE(*status)) {
|
||||
+
|
||||
+ if (U_FAILURE(*status) && *status != U_BUFFER_OVERFLOW_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
diff --git a/intl/icu/source/tools/pkgdata/pkgdata.cpp b/intl/icu/source/tools/pkgdata/pkgdata.cpp
|
||||
--- a/intl/icu/source/tools/pkgdata/pkgdata.cpp
|
||||
+++ b/intl/icu/source/tools/pkgdata/pkgdata.cpp
|
||||
@@ -2166,17 +2166,17 @@ static void pkg_createOptMatchArch(char
|
||||
const char* obj = "oma.obj";
|
||||
FileStream* stream = NULL;
|
||||
|
||||
stream = T_FileStream_open(source,"w");
|
||||
if (stream != NULL) {
|
||||
T_FileStream_writeLine(stream, code);
|
||||
T_FileStream_close(stream);
|
||||
|
||||
- char cmd[SMALL_BUFFER_MAX_SIZE];
|
||||
+ char cmd[LARGE_BUFFER_MAX_SIZE];
|
||||
sprintf(cmd, "%s %s -o %s",
|
||||
pkgDataFlags[COMPILER],
|
||||
source,
|
||||
obj);
|
||||
|
||||
if (runCommand(cmd) == 0){
|
||||
sprintf(optMatchArch, "%s", obj);
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
Path: release-55-1
|
||||
URL: http://source.icu-project.org/repos/icu/icu/tags/release-55-1
|
||||
Relative URL: ^/icu/tags/release-55-1
|
||||
Path: release-56-1
|
||||
URL: http://source.icu-project.org/repos/icu/icu/tags/release-56-1
|
||||
Repository Root: http://source.icu-project.org/repos/icu
|
||||
Repository UUID: 251d0590-4201-4cf1-90de-194747b24ca1
|
||||
Node Kind: directory
|
||||
Last Changed Author: mow
|
||||
Last Changed Rev: 37298
|
||||
Last Changed Date: 2015-03-27 21:06:39 +0000 (Fri, 27 Mar 2015)
|
||||
Last Changed Rev: 38044
|
||||
Last Changed Date: 2015-10-07 22:20:20 +0000 (Wed, 07 Oct 2015)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Doxyfile 1.3.7
|
||||
# ********************************************************************
|
||||
# * COPYRIGHT:
|
||||
# * Copyright (c) 2004-2014, International Business Machines Corporation
|
||||
# * Copyright (c) 2004-2015, International Business Machines Corporation
|
||||
# * and others. All Rights Reserved.
|
||||
# ********************************************************************
|
||||
|
||||
|
@ -192,7 +192,7 @@ EXPAND_ONLY_PREDEF = YES
|
|||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = U_EXPORT2= U_STABLE= U_DRAFT= U_INTERNAL= U_SYSTEM= U_DEPRECATED= U_OBSOLETE= U_CALLCONV= U_CDECL_BEGIN= U_CDECL_END= U_NO_THROW=\ "U_NAMESPACE_BEGIN=namespace icu{" "U_NAMESPACE_END=}" U_HAVE_STD_STRING=1 U_SHOW_CPLUSPLUS_API=1 U_DEFINE_LOCAL_OPEN_POINTER()= U_IN_DOXYGEN=1 U_OVERRIDE= U_FINAL=
|
||||
PREDEFINED = U_EXPORT2= U_STABLE= U_DRAFT= U_INTERNAL= U_SYSTEM= U_DEPRECATED= U_OBSOLETE= U_CALLCONV= U_CDECL_BEGIN= U_CDECL_END= U_NO_THROW=\ "U_NAMESPACE_BEGIN=namespace icu{" "U_NAMESPACE_END=}" U_HAVE_STD_STRING=1 U_SHOW_CPLUSPLUS_API=1 U_DEFINE_LOCAL_OPEN_POINTER()= U_IN_DOXYGEN=1 U_OVERRIDE= U_FINAL= UCONFIG_ENABLE_PLUGINS=1
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#******************************************************************************
|
||||
#
|
||||
# Copyright (C) 1998-2014, International Business Machines
|
||||
# Copyright (C) 1998-2015, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#
|
||||
#******************************************************************************
|
||||
|
@ -339,7 +339,6 @@ $(top_builddir)/config/icu-config: $(top_builddir)/Makefile $(top_srcdir)/config
|
|||
LC_ALL=C sed -f $(top_srcdir)/config/make2sh.sed < $(top_builddir)/config/Makefile.inc | grep -v '#M#' | uniq >> $@
|
||||
LC_ALL=C sed -f $(top_srcdir)/config/make2sh.sed < @platform_make_fragment@ | grep -v '#M#' | uniq >> $@
|
||||
cat $(top_srcdir)/config/icu-config-bottom >> $@
|
||||
echo "# Rebuilt on "`date` >> $@
|
||||
chmod u-w $@
|
||||
|
||||
config.status: $(srcdir)/configure $(srcdir)/common/unicode/uvernum.h
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 1999-2014, International Business Machines Corporation and
|
||||
# Copyright (c) 1999-2015, International Business Machines Corporation and
|
||||
# others. All Rights Reserved.
|
||||
# acinclude.m4 for ICU
|
||||
# Don't edit aclocal.m4, do edit acinclude.m4
|
||||
|
@ -88,15 +88,6 @@ esac
|
|||
)
|
||||
])
|
||||
|
||||
# ICU_CONDITIONAL - similar example taken from Automake 1.4
|
||||
AC_DEFUN([ICU_CONDITIONAL],
|
||||
[AC_SUBST($1_TRUE)
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
else
|
||||
$1_TRUE='#'
|
||||
fi])
|
||||
|
||||
# ICU_PROG_LINK - Make sure that the linker is usable
|
||||
AC_DEFUN([ICU_PROG_LINK],
|
||||
[
|
||||
|
|
|
@ -0,0 +1,500 @@
|
|||
# Copyright (c) 1999-2015, International Business Machines Corporation and
|
||||
# others. All Rights Reserved.
|
||||
# acinclude.m4 for ICU
|
||||
# Don't edit aclocal.m4, do edit acinclude.m4
|
||||
# Stephen F. Booth
|
||||
|
||||
# @TOP@
|
||||
|
||||
# ICU_CHECK_MH_FRAG
|
||||
AC_DEFUN([ICU_CHECK_MH_FRAG], [
|
||||
AC_CACHE_CHECK(
|
||||
[which Makefile fragment to use for ${host}],
|
||||
[icu_cv_host_frag],
|
||||
[
|
||||
case "${host}" in
|
||||
*-*-solaris*)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-solaris-gcc
|
||||
else
|
||||
icu_cv_host_frag=mh-solaris
|
||||
fi ;;
|
||||
alpha*-*-linux-gnu)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-alpha-linux-gcc
|
||||
else
|
||||
icu_cv_host_frag=mh-alpha-linux-cc
|
||||
fi ;;
|
||||
powerpc*-*-linux*)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-linux
|
||||
else
|
||||
icu_cv_host_frag=mh-linux-va
|
||||
fi ;;
|
||||
*-*-linux*|*-*-gnu|*-*-k*bsd*-gnu|*-*-kopensolaris*-gnu) icu_cv_host_frag=mh-linux ;;
|
||||
i[[34567]]86-*-cygwin)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-cygwin
|
||||
else
|
||||
icu_cv_host_frag=mh-cygwin-msvc
|
||||
fi ;;
|
||||
x86_64-*-cygwin)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-cygwin64
|
||||
else
|
||||
icu_cv_host_frag=mh-cygwin-msvc
|
||||
fi ;;
|
||||
*-*-mingw*)
|
||||
if test "$GCC" = yes; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#ifndef __MINGW64__
|
||||
#error This is not MinGW64
|
||||
#endif]])], [icu_cv_host_frag=mh-mingw64],
|
||||
[icu_cv_host_frag=mh-mingw])
|
||||
else
|
||||
case "${host}" in
|
||||
*-*-mingw*) icu_cv_host_frag=mh-msys-msvc ;;
|
||||
*-*-cygwin) icu_cv_host_frag=mh-cygwin-msvc ;;
|
||||
esac
|
||||
fi ;;
|
||||
*-*-*bsd*|*-*-dragonfly*) icu_cv_host_frag=mh-bsd-gcc ;;
|
||||
*-*-aix*)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-aix-gcc
|
||||
else
|
||||
icu_cv_host_frag=mh-aix-va
|
||||
fi ;;
|
||||
*-*-hpux*)
|
||||
if test "$GCC" = yes; then
|
||||
icu_cv_host_frag=mh-hpux-gcc
|
||||
else
|
||||
case "$CXX" in
|
||||
*aCC) icu_cv_host_frag=mh-hpux-acc ;;
|
||||
esac
|
||||
fi ;;
|
||||
*-*ibm-openedition*|*-*-os390*) icu_cv_host_frag=mh-os390 ;;
|
||||
*-*-os400*) icu_cv_host_frag=mh-os400 ;;
|
||||
*-apple-rhapsody*) icu_cv_host_frag=mh-darwin ;;
|
||||
*-apple-darwin*) icu_cv_host_frag=mh-darwin ;;
|
||||
*-*-beos) icu_cv_host_frag=mh-beos ;;
|
||||
*-*-haiku) icu_cv_host_frag=mh-haiku ;;
|
||||
*-*-irix*) icu_cv_host_frag=mh-irix ;;
|
||||
*-dec-osf*) icu_cv_host_frag=mh-alpha-osf ;;
|
||||
*-*-nto*) icu_cv_host_frag=mh-qnx ;;
|
||||
*-ncr-*) icu_cv_host_frag=mh-mpras ;;
|
||||
*) icu_cv_host_frag=mh-unknown ;;
|
||||
esac
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
# ICU_PROG_LINK - Make sure that the linker is usable
|
||||
AC_DEFUN([ICU_PROG_LINK],
|
||||
[
|
||||
case "${host}" in
|
||||
*-*-cygwin*|*-*-mingw*)
|
||||
if test "$GCC" != yes && test -n "`link --version 2>&1 | grep 'GNU coreutils'`"; then
|
||||
AC_MSG_ERROR([link.exe is not a valid linker. Your PATH is incorrect.
|
||||
Please follow the directions in ICU's readme.])
|
||||
fi;;
|
||||
*);;
|
||||
esac])
|
||||
|
||||
# AC_SEARCH_LIBS_FIRST(FUNCTION, SEARCH-LIBS [, ACTION-IF-FOUND
|
||||
# [, ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
|
||||
# Search for a library defining FUNC, then see if it's not already available.
|
||||
|
||||
AC_DEFUN([AC_SEARCH_LIBS_FIRST],
|
||||
[AC_PREREQ([2.13])
|
||||
AC_CACHE_CHECK([for library containing $1], [ac_cv_search_$1],
|
||||
[ac_func_search_save_LIBS="$LIBS"
|
||||
ac_cv_search_$1="no"
|
||||
for i in $2; do
|
||||
LIBS="-l$i $5 $ac_func_search_save_LIBS"
|
||||
AC_TRY_LINK_FUNC([$1],
|
||||
[ac_cv_search_$1="-l$i"
|
||||
break])
|
||||
done
|
||||
if test "$ac_cv_search_$1" = "no"; then
|
||||
AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="none required"])
|
||||
fi
|
||||
LIBS="$ac_func_search_save_LIBS"])
|
||||
if test "$ac_cv_search_$1" != "no"; then
|
||||
test "$ac_cv_search_$1" = "none required" || LIBS="$ac_cv_search_$1 $LIBS"
|
||||
$3
|
||||
else :
|
||||
$4
|
||||
fi])
|
||||
|
||||
|
||||
|
||||
# Check if we can build and use 64-bit libraries
|
||||
AC_DEFUN([AC_CHECK_64BIT_LIBS],
|
||||
[
|
||||
BITS_REQ=nochange
|
||||
ENABLE_64BIT_LIBS=unknown
|
||||
## revisit this for cross-compile.
|
||||
|
||||
AC_ARG_ENABLE(64bit-libs,
|
||||
[ --enable-64bit-libs (deprecated, use --with-library-bits) build 64-bit libraries [default= platform default]],
|
||||
[echo "note, use --with-library-bits instead of --*-64bit-libs"
|
||||
case "${enableval}" in
|
||||
no|false|32) with_library_bits=32; ;;
|
||||
yes|true|64) with_library_bits=64else32 ;;
|
||||
nochange) with_library_bits=nochange; ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for '--*-64bit-libs') ;;
|
||||
esac] )
|
||||
|
||||
|
||||
AC_ARG_WITH(library-bits,
|
||||
[ --with-library-bits=bits specify how many bits to use for the library (32, 64, 64else32, nochange) [default=nochange]],
|
||||
[case "${withval}" in
|
||||
""|nochange) BITS_REQ=$withval ;;
|
||||
32|64|64else32) BITS_REQ=$withval ;;
|
||||
*) AC_MSG_ERROR(bad value ${withval} for --with-library-bits) ;;
|
||||
esac])
|
||||
|
||||
# don't use these for cross compiling
|
||||
if test "$cross_compiling" = "yes" -a "${BITS_REQ}" != "nochange"; then
|
||||
AC_MSG_ERROR([Don't specify bitness when cross compiling. See readme.html for help with cross compilation., and set compiler options manually.])
|
||||
fi
|
||||
AC_CHECK_SIZEOF([void *])
|
||||
AC_MSG_CHECKING([whether runnable 64 bit binaries are built by default])
|
||||
case $ac_cv_sizeof_void_p in
|
||||
8) DEFAULT_64BIT=yes ;;
|
||||
4) DEFAULT_64BIT=no ;;
|
||||
*) DEFAULT_64BIT=unknown
|
||||
esac
|
||||
BITS_GOT=unknown
|
||||
|
||||
# 'OK' here means, we can exit any further checking, everything's copa
|
||||
BITS_OK=yes
|
||||
|
||||
# do we need to check for buildable/runnable 32 or 64 bit?
|
||||
BITS_CHECK_32=no
|
||||
BITS_CHECK_64=no
|
||||
|
||||
# later, can we run the 32/64 bit binaries so made?
|
||||
BITS_RUN_32=no
|
||||
BITS_RUN_64=no
|
||||
|
||||
if test "$DEFAULT_64BIT" = "yes"; then
|
||||
# we get 64 bits by default.
|
||||
BITS_GOT=64
|
||||
case "$BITS_REQ" in
|
||||
32)
|
||||
# need to look for 32 bit support.
|
||||
BITS_CHECK_32=yes
|
||||
# not copa.
|
||||
BITS_OK=no;;
|
||||
# everyone else is happy.
|
||||
nochange) ;;
|
||||
*) ;;
|
||||
esac
|
||||
elif test "$DEFAULT_64BIT" = "no"; then
|
||||
# not 64 bit by default.
|
||||
BITS_GOT=32
|
||||
case "$BITS_REQ" in
|
||||
64|64else32)
|
||||
BITS_CHECK_64=yes
|
||||
#BITS_CHECK_32=yes
|
||||
BITS_OK=no;;
|
||||
nochange) ;;
|
||||
*) ;;
|
||||
esac
|
||||
elif test "$DEFAULT_64BIT" = "unknown"; then
|
||||
# cross compiling.
|
||||
BITS_GOT=unknown
|
||||
case "$BITS_REQ" in
|
||||
64|64else32) BITS_OK=no
|
||||
BITS_CHECK_32=yes
|
||||
BITS_CHECK_64=yes ;;
|
||||
32) BITS_OK=no;;
|
||||
nochange) ;;
|
||||
*) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT($DEFAULT_64BIT);
|
||||
|
||||
if test "$BITS_OK" != "yes"; then
|
||||
# not copa. back these up.
|
||||
CFLAGS_OLD="${CFLAGS}"
|
||||
CXXFLAGS_OLD="${CXXFLAGS}"
|
||||
LDFLAGS_OLD="${LDFLAGS}"
|
||||
ARFLAGS_OLD="${ARFLAGS}"
|
||||
|
||||
CFLAGS_32="${CFLAGS}"
|
||||
CXXFLAGS_32="${CXXFLAGS}"
|
||||
LDFLAGS_32="${LDFLAGS}"
|
||||
ARFLAGS_32="${ARFLAGS}"
|
||||
|
||||
CFLAGS_64="${CFLAGS}"
|
||||
CXXFLAGS_64="${CXXFLAGS}"
|
||||
LDFLAGS_64="${LDFLAGS}"
|
||||
ARFLAGS_64="${ARFLAGS}"
|
||||
|
||||
CAN_BUILD_64=unknown
|
||||
CAN_BUILD_32=unknown
|
||||
# These results can't be cached because is sets compiler flags.
|
||||
if test "$BITS_CHECK_64" = "yes"; then
|
||||
AC_MSG_CHECKING([how to build 64-bit executables])
|
||||
CAN_BUILD_64=no
|
||||
####
|
||||
# Find out if we think we can *build* for 64 bit. Doesn't check whether we can run it.
|
||||
# Note, we don't have to actually check if the options work- we'll try them before using them.
|
||||
# So, only try actually testing the options, if you are trying to decide between multiple options.
|
||||
# On exit from the following clauses:
|
||||
# if CAN_BUILD_64=yes:
|
||||
# *FLAGS are assumed to contain the right settings for 64bit
|
||||
# else if CAN_BUILD_64=no: (default)
|
||||
# *FLAGS are assumed to be trashed, and will be reset from *FLAGS_OLD
|
||||
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="${CFLAGS} -m64"
|
||||
CXXFLAGS="${CXXFLAGS} -m64"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no)
|
||||
else
|
||||
case "${host}" in
|
||||
sparc*-*-solaris*)
|
||||
# 1. try -m64
|
||||
CFLAGS="${CFLAGS} -m64"
|
||||
CXXFLAGS="${CXXFLAGS} -m64"
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no, CAN_BUILD_64=unknown)
|
||||
if test "$CAN_BUILD_64" != yes; then
|
||||
# Nope. back out changes.
|
||||
CFLAGS="${CFLAGS_OLD}"
|
||||
CXXFLAGS="${CXXFLAGS_OLD}"
|
||||
# 2. try xarch=v9 [deprecated]
|
||||
## TODO: cross compile: the following won't work.
|
||||
SPARCV9=`isainfo -n 2>&1 | grep sparcv9`
|
||||
SOL64=`$CXX -xarch=v9 2>&1 && $CC -xarch=v9 2>&1 | grep -v usage:`
|
||||
# "Warning: -xarch=v9 is deprecated, use -m64 to create 64-bit programs"
|
||||
if test -z "$SOL64" && test -n "$SPARCV9"; then
|
||||
CFLAGS="${CFLAGS} -xtarget=ultra -xarch=v9"
|
||||
CXXFLAGS="${CXXFLAGS} -xtarget=ultra -xarch=v9"
|
||||
LDFLAGS="${LDFLAGS} -xtarget=ultra -xarch=v9"
|
||||
CAN_BUILD_64=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
i386-*-solaris*)
|
||||
# 1. try -m64
|
||||
CFLAGS="${CFLAGS} -m64"
|
||||
CXXFLAGS="${CXXFLAGS} -m64"
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no, CAN_BUILD_64=unknown)
|
||||
if test "$CAN_BUILD_64" != yes; then
|
||||
# Nope. back out changes.
|
||||
CFLAGS="${CFLAGS_OLD}"
|
||||
CXXFLAGS="${CXXFLAGS_OLD}"
|
||||
# 2. try the older compiler option
|
||||
## TODO: cross compile problem
|
||||
AMD64=`isainfo -n 2>&1 | grep amd64`
|
||||
SOL64=`$CXX -xtarget=generic64 2>&1 && $CC -xtarget=generic64 2>&1 | grep -v usage:`
|
||||
if test -z "$SOL64" && test -n "$AMD64"; then
|
||||
CFLAGS="${CFLAGS} -xtarget=generic64"
|
||||
CXXFLAGS="${CXXFLAGS} -xtarget=generic64"
|
||||
CAN_BUILD_64=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
ia64-*-linux*)
|
||||
# check for ecc/ecpc compiler support
|
||||
## TODO: cross compiler problem
|
||||
if test -n "`$CXX --help 2>&1 && $CC --help 2>&1 | grep -v Intel`"; then
|
||||
if test -n "`$CXX --help 2>&1 && $CC --help 2>&1 | grep -v Itanium`"; then
|
||||
CAN_BUILD_64=yes
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*-*-cygwin)
|
||||
# vcvarsamd64.bat should have been used to enable 64-bit builds.
|
||||
# We only do this check to display the correct answer.
|
||||
## TODO: cross compiler problem
|
||||
if test -n "`$CXX -help 2>&1 | grep 'for x64'`"; then
|
||||
CAN_BUILD_64=yes
|
||||
fi
|
||||
;;
|
||||
*-*-aix*|powerpc64-*-linux*)
|
||||
CFLAGS="${CFLAGS} -q64"
|
||||
CXXFLAGS="${CXXFLAGS} -q64"
|
||||
LDFLAGS="${LDFLAGS} -q64"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no)
|
||||
if test "$CAN_BUILD_64" = yes; then
|
||||
# worked- set other options.
|
||||
case "${host}" in
|
||||
*-*-aix*)
|
||||
# tell AIX what executable mode to use.
|
||||
ARFLAGS="${ARFLAGS} -X64"
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*-*-hpux*)
|
||||
# First we try the newer +DD64, if that doesn't work,
|
||||
# try other options.
|
||||
|
||||
CFLAGS="${CFLAGS} +DD64"
|
||||
CXXFLAGS="${CXXFLAGS} +DD64"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no)
|
||||
if test "$CAN_BUILD_64" != yes; then
|
||||
# reset
|
||||
CFLAGS="${CFLAGS_OLD}"
|
||||
CXXFLAGS="${CXXFLAGS_OLD}"
|
||||
# append
|
||||
CFLAGS="${CFLAGS} +DA2.0W"
|
||||
CXXFLAGS="${CXXFLAGS} +DA2.0W"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no)
|
||||
fi
|
||||
;;
|
||||
*-*ibm-openedition*|*-*-os390*)
|
||||
CFLAGS="${CFLAGS} -Wc,lp64"
|
||||
CXXFLAGS="${CXXFLAGS} -Wc,lp64"
|
||||
LDFLAGS="${LDFLAGS} -Wl,lp64"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
CAN_BUILD_64=yes, CAN_BUILD_64=no)
|
||||
;;
|
||||
*)
|
||||
# unknown platform.
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_MSG_RESULT($CAN_BUILD_64)
|
||||
if test "$CAN_BUILD_64" = yes; then
|
||||
AC_MSG_CHECKING([whether runnable 64-bit binaries are being built ])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==64)?0:1;}])],
|
||||
BITS_RUN_64=yes, BITS_RUN_64=no, BITS_RUN_64=unknown)
|
||||
AC_MSG_RESULT($BITS_RUN_64);
|
||||
|
||||
CFLAGS_64="${CFLAGS}"
|
||||
CXXFLAGS_64="${CXXFLAGS}"
|
||||
LDFLAGS_64="${LDFLAGS}"
|
||||
ARFLAGS_64="${ARFLAGS}"
|
||||
fi
|
||||
# put it back.
|
||||
CFLAGS="${CFLAGS_OLD}"
|
||||
CXXFLAGS="${CXXFLAGS_OLD}"
|
||||
LDFLAGS="${LDFLAGS_OLD}"
|
||||
ARFLAGS="${ARFLAGS_OLD}"
|
||||
fi
|
||||
if test "$BITS_CHECK_32" = "yes"; then
|
||||
# see comment under 'if BITS_CHECK_64', above.
|
||||
AC_MSG_CHECKING([how to build 32-bit executables])
|
||||
if test "$GCC" = yes; then
|
||||
CFLAGS="${CFLAGS} -m32"
|
||||
CXXFLAGS="${CXXFLAGS} -m32"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==32)?0:1;}])],
|
||||
CAN_BUILD_32=yes, CAN_BUILD_32=no)
|
||||
fi
|
||||
AC_MSG_RESULT($CAN_BUILD_32)
|
||||
if test "$CAN_BUILD_32" = yes; then
|
||||
AC_MSG_CHECKING([whether runnable 32-bit binaries are being built ])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([int main(void) {return (sizeof(void*)*8==32)?0:1;}])],
|
||||
BITS_RUN_32=yes, BITS_RUN_32=no, BITS_RUN_32=unknown)
|
||||
AC_MSG_RESULT($BITS_RUN_32);
|
||||
CFLAGS_32="${CFLAGS}"
|
||||
CXXFLAGS_32="${CXXFLAGS}"
|
||||
LDFLAGS_32="${LDFLAGS}"
|
||||
ARFLAGS_32="${ARFLAGS}"
|
||||
fi
|
||||
# put it back.
|
||||
CFLAGS="${CFLAGS_OLD}"
|
||||
CXXFLAGS="${CXXFLAGS_OLD}"
|
||||
LDFLAGS="${LDFLAGS_OLD}"
|
||||
ARFLAGS="${ARFLAGS_OLD}"
|
||||
fi
|
||||
|
||||
##
|
||||
# OK. Now, we've tested for 32 and 64 bitness. Let's see what we'll do.
|
||||
#
|
||||
|
||||
# First, implement 64else32
|
||||
if test "$BITS_REQ" = "64else32"; then
|
||||
if test "$BITS_RUN_64" = "yes"; then
|
||||
BITS_REQ=64
|
||||
else
|
||||
# no changes.
|
||||
BITS_OK=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
# implement.
|
||||
if test "$BITS_REQ" = "32" -a "$BITS_RUN_32" = "yes"; then
|
||||
CFLAGS="${CFLAGS_32}"
|
||||
CXXFLAGS="${CXXFLAGS_32}"
|
||||
LDFLAGS="${LDFLAGS_32}"
|
||||
ARFLAGS="${ARFLAGS_32}"
|
||||
BITS_OK=yes
|
||||
elif test "$BITS_REQ" = "64" -a "$BITS_RUN_64" = "yes"; then
|
||||
CFLAGS="${CFLAGS_64}"
|
||||
CXXFLAGS="${CXXFLAGS_64}"
|
||||
LDFLAGS="${LDFLAGS_64}"
|
||||
ARFLAGS="${ARFLAGS_64}"
|
||||
BITS_OK=yes
|
||||
elif test "$BITS_OK" != "yes"; then
|
||||
AC_MSG_ERROR([Requested $BITS_REQ bit binaries but could not compile and execute them. See readme.html for help with cross compilation., and set compiler options manually.])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Strict compilation options.
|
||||
AC_DEFUN([AC_CHECK_STRICT_COMPILE],
|
||||
[
|
||||
AC_MSG_CHECKING([whether strict compiling is on])
|
||||
AC_ARG_ENABLE(strict,[ --enable-strict compile with strict compiler options [default=yes]], [
|
||||
if test "$enableval" = no
|
||||
then
|
||||
ac_use_strict_options=no
|
||||
else
|
||||
ac_use_strict_options=yes
|
||||
fi
|
||||
], [ac_use_strict_options=yes])
|
||||
AC_MSG_RESULT($ac_use_strict_options)
|
||||
|
||||
if test "$ac_use_strict_options" = yes
|
||||
then
|
||||
if test "$GCC" = yes
|
||||
then
|
||||
case "${host}" in
|
||||
*)
|
||||
# Do not use -ansi. It limits us to C90, and it breaks some platforms.
|
||||
# We use -std=c99 to disable the gnu99 defaults and its associated warnings
|
||||
CFLAGS="$CFLAGS -std=c99"
|
||||
;;
|
||||
esac
|
||||
|
||||
CFLAGS="$CFLAGS -Wall -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings"
|
||||
else
|
||||
case "${host}" in
|
||||
*-*-cygwin)
|
||||
if test "`$CC /help 2>&1 | head -c9`" = "Microsoft"
|
||||
then
|
||||
CFLAGS="$CFLAGS /W4"
|
||||
fi ;;
|
||||
*-*-mingw*)
|
||||
CFLAGS="$CFLAGS -W4" ;;
|
||||
esac
|
||||
fi
|
||||
if test "$GXX" = yes
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long"
|
||||
else
|
||||
case "${host}" in
|
||||
*-*-cygwin)
|
||||
if test "`$CXX /help 2>&1 | head -c9`" = "Microsoft"
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS /W4"
|
||||
fi ;;
|
||||
*-*-mingw*)
|
||||
CFLAGS="$CFLAGS -W4" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
@ -11,7 +11,9 @@
|
|||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
|
@ -38,8 +40,12 @@
|
|||
# ----------------------------------
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
|
@ -52,7 +58,6 @@ if test -n "$PKG_CONFIG"; then
|
|||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
|
||||
fi[]dnl
|
||||
])# PKG_PROG_PKG_CONFIG
|
||||
|
||||
|
@ -61,21 +66,20 @@ fi[]dnl
|
|||
# Check to see whether a particular set of modules exists. Similar
|
||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
#
|
||||
#
|
||||
# Similar to PKG_CHECK_MODULES, make sure that the first instance of
|
||||
# this or PKG_CHECK_MODULES is called, or make sure to call
|
||||
# PKG_CHECK_EXISTS manually
|
||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
# only at the first occurence in configure.ac, so if the first place
|
||||
# it's called might be skipped (such as if it is within an "if", you
|
||||
# have to call PKG_CHECK_EXISTS manually
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_ifval([$2], [$2], [:])
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
|
||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
# ---------------------------------------------
|
||||
m4_define([_PKG_CONFIG],
|
||||
|
@ -83,7 +87,8 @@ m4_define([_PKG_CONFIG],
|
|||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
|
@ -128,16 +133,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
|
|||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
ifelse([$4], , [AC_MSG_ERROR(dnl
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
@ -145,26 +151,81 @@ $$1_PKG_ERRORS
|
|||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT
|
||||
])],
|
||||
[AC_MSG_RESULT([no])
|
||||
$4])
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
ifelse([$4], , [AC_MSG_FAILURE(dnl
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
|
||||
[$4])
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
ifelse([$3], , :, [$3])
|
||||
$3
|
||||
fi[]dnl
|
||||
])# PKG_CHECK_MODULES
|
||||
|
||||
|
||||
# PKG_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable pkgconfigdir as the location where a module
|
||||
# should install pkg-config .pc files. By default the directory is
|
||||
# $libdir/pkgconfig, but the default can be changed by passing
|
||||
# DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
# parameter.
|
||||
AC_DEFUN([PKG_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
|
||||
[with_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
# module should install arch-independent pkg-config .pc files. By
|
||||
# default the directory is $datadir/pkgconfig, but the default can be
|
||||
# changed by passing DIRECTORY. The user can override through the
|
||||
# --with-noarch-pkgconfigdir parameter.
|
||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([noarch-pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
|
||||
[with_noarch_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_NOARCH_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
# -------------------------------------------
|
||||
# Retrieves the value of the pkg-config variable for the given module.
|
||||
AC_DEFUN([PKG_CHECK_VAR],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
||||
|
||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
||||
AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])# PKG_CHECK_VAR
|
||||
|
||||
m4_include([config/m4/icu-conditional.m4])
|
||||
m4_include([acinclude.m4])
|
||||
|
|
|
@ -99,13 +99,14 @@ chariter.o schriter.o uchriter.o uiter.o \
|
|||
patternprops.o uchar.o uprops.o ucase.o propname.o ubidi_props.o ubidi.o ubidiwrt.o ubidiln.o ushape.o \
|
||||
uscript.o uscript_props.o usc_impl.o unames.o \
|
||||
utrie.o utrie2.o utrie2_builder.o bmpset.o unisetspan.o uset_props.o uniset_props.o uniset_closure.o uset.o uniset.o usetiter.o ruleiter.o caniter.o unifilt.o unifunct.o \
|
||||
uarrsort.o brkiter.o ubrk.o brkeng.o dictbe.o \
|
||||
uarrsort.o brkiter.o ubrk.o brkeng.o dictbe.o filteredbrk.o \
|
||||
rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.o \
|
||||
serv.o servnotf.o servls.o servlk.o servlkf.o servrbf.o servslkf.o \
|
||||
uidna.o usprep.o uts46.o punycode.o \
|
||||
util.o util_props.o parsepos.o locbased.o cwchar.o wintz.o dtintrv.o ucnvsel.o propsvec.o \
|
||||
ulist.o uloc_tag.o icudataver.o icuplug.o listformatter.o ulistformatter.o \
|
||||
sharedobject.o simplepatternformatter.o unifiedcache.o uloc_keytype.o
|
||||
sharedobject.o simplepatternformatter.o unifiedcache.o uloc_keytype.o \
|
||||
pluralmap.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS = $(srcdir)/unicode/*.h
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
************************************************************************************
|
||||
* Copyright (C) 2006-2014, International Business Machines Corporation
|
||||
* Copyright (C) 2006-2015, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
************************************************************************************
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "unicode/bytestrie.h"
|
||||
#include "charstr.h"
|
||||
#include "dictionarydata.h"
|
||||
#include "mutex.h"
|
||||
#include "uvector.h"
|
||||
#include "umutex.h"
|
||||
#include "uresimp.h"
|
||||
|
@ -138,82 +139,38 @@ static void U_CALLCONV _deleteEngine(void *obj) {
|
|||
U_CDECL_END
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
const LanguageBreakEngine *
|
||||
ICULanguageBreakFactory::getEngineFor(UChar32 c, int32_t breakType) {
|
||||
UBool needsInit;
|
||||
int32_t i;
|
||||
const LanguageBreakEngine *lbe = NULL;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
// TODO: The global mutex should not be used.
|
||||
// The global mutex should only be used for short periods.
|
||||
// A ICULanguageBreakFactory specific mutex should be used.
|
||||
umtx_lock(NULL);
|
||||
needsInit = (UBool)(fEngines == NULL);
|
||||
if (!needsInit) {
|
||||
i = fEngines->size();
|
||||
Mutex m(&gBreakEngineMutex);
|
||||
|
||||
if (fEngines == NULL) {
|
||||
UStack *engines = new UStack(_deleteEngine, NULL, status);
|
||||
if (U_FAILURE(status) || engines == NULL) {
|
||||
// Note: no way to return error code to caller.
|
||||
delete engines;
|
||||
return NULL;
|
||||
}
|
||||
fEngines = engines;
|
||||
} else {
|
||||
int32_t i = fEngines->size();
|
||||
while (--i >= 0) {
|
||||
lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
|
||||
if (lbe != NULL && lbe->handles(c, breakType)) {
|
||||
break;
|
||||
return lbe;
|
||||
}
|
||||
lbe = NULL;
|
||||
}
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
// We didn't find an engine. Create one.
|
||||
lbe = loadEngineFor(c, breakType);
|
||||
if (lbe != NULL) {
|
||||
return lbe;
|
||||
fEngines->push((void *)lbe, status);
|
||||
}
|
||||
|
||||
if (needsInit) {
|
||||
UStack *engines = new UStack(_deleteEngine, NULL, status);
|
||||
if (U_SUCCESS(status) && engines == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
else if (U_FAILURE(status)) {
|
||||
delete engines;
|
||||
engines = NULL;
|
||||
}
|
||||
else {
|
||||
umtx_lock(NULL);
|
||||
if (fEngines == NULL) {
|
||||
fEngines = engines;
|
||||
engines = NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete engines;
|
||||
}
|
||||
}
|
||||
|
||||
if (fEngines == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We didn't find an engine the first time through, or there was no
|
||||
// stack. Create an engine.
|
||||
const LanguageBreakEngine *newlbe = loadEngineFor(c, breakType);
|
||||
|
||||
// Now get the lock, and see if someone else has created it in the
|
||||
// meantime
|
||||
umtx_lock(NULL);
|
||||
i = fEngines->size();
|
||||
while (--i >= 0) {
|
||||
lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
|
||||
if (lbe != NULL && lbe->handles(c, breakType)) {
|
||||
break;
|
||||
}
|
||||
lbe = NULL;
|
||||
}
|
||||
if (lbe == NULL && newlbe != NULL) {
|
||||
fEngines->push((void *)newlbe, status);
|
||||
lbe = newlbe;
|
||||
newlbe = NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
delete newlbe;
|
||||
|
||||
return lbe;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "unicode/udata.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/filteredbrk.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "cstring.h"
|
||||
#include "umutex.h"
|
||||
|
@ -383,7 +384,7 @@ BreakIterator::createInstance(const Locale& loc, int32_t kind, UErrorCode& statu
|
|||
}
|
||||
|
||||
// -------------------------------------
|
||||
enum { kLBTypeLenMax = 32 };
|
||||
enum { kKeyValueLenMax = 32 };
|
||||
|
||||
BreakIterator*
|
||||
BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
||||
|
@ -392,7 +393,7 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
|||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
char lbType[kLBTypeLenMax];
|
||||
char lbType[kKeyValueLenMax];
|
||||
|
||||
BreakIterator *result = NULL;
|
||||
switch (kind) {
|
||||
|
@ -405,9 +406,9 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
|||
case UBRK_LINE:
|
||||
uprv_strcpy(lbType, "line");
|
||||
{
|
||||
char lbKeyValue[kLBTypeLenMax] = {0};
|
||||
char lbKeyValue[kKeyValueLenMax] = {0};
|
||||
UErrorCode kvStatus = U_ZERO_ERROR;
|
||||
int32_t kLen = loc.getKeywordValue("lb", lbKeyValue, kLBTypeLenMax, kvStatus);
|
||||
int32_t kLen = loc.getKeywordValue("lb", lbKeyValue, kKeyValueLenMax, kvStatus);
|
||||
if (U_SUCCESS(kvStatus) && kLen > 0 && (uprv_strcmp(lbKeyValue,"strict")==0 || uprv_strcmp(lbKeyValue,"normal")==0 || uprv_strcmp(lbKeyValue,"loose")==0)) {
|
||||
uprv_strcat(lbType, "_");
|
||||
uprv_strcat(lbType, lbKeyValue);
|
||||
|
@ -417,6 +418,18 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
|
|||
break;
|
||||
case UBRK_SENTENCE:
|
||||
result = BreakIterator::buildInstance(loc, "sentence", kind, status);
|
||||
{
|
||||
char ssKeyValue[kKeyValueLenMax] = {0};
|
||||
UErrorCode kvStatus = U_ZERO_ERROR;
|
||||
int32_t kLen = loc.getKeywordValue("ss", ssKeyValue, kKeyValueLenMax, kvStatus);
|
||||
if (U_SUCCESS(kvStatus) && kLen > 0 && uprv_strcmp(ssKeyValue,"standard")==0) {
|
||||
FilteredBreakIteratorBuilder* fbiBuilder = FilteredBreakIteratorBuilder::createInstance(loc, kvStatus);
|
||||
if (U_SUCCESS(kvStatus)) {
|
||||
result = fbiBuilder->build(result, status);
|
||||
delete fbiBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UBRK_TITLE:
|
||||
result = BreakIterator::buildInstance(loc, "title", kind, status);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1996-2014, International Business Machines Corporation and
|
||||
* Copyright (C) 1996-2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
@ -508,6 +508,13 @@ Hashtable *CanonicalIterator::extract(Hashtable *fillinResult, UChar32 comp, con
|
|||
int32_t inputLen=temp.length();
|
||||
UnicodeString decompString;
|
||||
nfd.normalize(temp, decompString, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (decompString.isBogus()) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
const UChar *decomp=decompString.getBuffer();
|
||||
int32_t decompLen=decompString.length();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2010-2011, International Business Machines
|
||||
* Copyright (C) 2010-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
* file name: charstr.cpp
|
||||
|
@ -16,6 +16,7 @@
|
|||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "uinvchar.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -27,6 +28,15 @@ CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
int32_t CharString::lastIndexOf(char c) const {
|
||||
for(int32_t i=len; i>0;) {
|
||||
if(buffer[--i]==c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
CharString &CharString::truncate(int32_t newLength) {
|
||||
if(newLength<0) {
|
||||
newLength=0;
|
||||
|
@ -101,6 +111,13 @@ char *CharString::getAppendBuffer(int32_t minCapacity,
|
|||
}
|
||||
|
||||
CharString &CharString::appendInvariantChars(const UnicodeString &s, UErrorCode &errorCode) {
|
||||
if(U_FAILURE(errorCode)) {
|
||||
return *this;
|
||||
}
|
||||
if (!uprv_isInvariantUnicodeString(s)) {
|
||||
errorCode = U_INVARIANT_CONVERSION_ERROR;
|
||||
return *this;
|
||||
}
|
||||
if(ensureCapacity(len+s.length()+1, 0, errorCode)) {
|
||||
len+=s.extract(0, 0x7fffffff, buffer.getAlias()+len, buffer.getCapacity()-len, US_INV);
|
||||
}
|
||||
|
@ -142,4 +159,13 @@ CharString &CharString::appendPathPart(const StringPiece &s, UErrorCode &errorCo
|
|||
return *this;
|
||||
}
|
||||
|
||||
CharString &CharString::ensureEndsWithFileSeparator(UErrorCode &errorCode) {
|
||||
char c;
|
||||
if(U_SUCCESS(errorCode) && len>0 &&
|
||||
(c=buffer[len-1])!=U_FILE_SEP_CHAR && c!=U_FILE_ALT_SEP_CHAR) {
|
||||
append(U_FILE_SEP_CHAR, errorCode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2001-2012, International Business Machines
|
||||
* Copyright (c) 2001-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Date Name Description
|
||||
|
@ -69,6 +69,9 @@ public:
|
|||
const char *data() const { return buffer.getAlias(); }
|
||||
char *data() { return buffer.getAlias(); }
|
||||
|
||||
/** @return last index of c, or -1 if c is not in this string */
|
||||
int32_t lastIndexOf(char c) const;
|
||||
|
||||
CharString &clear() { len=0; buffer[0]=0; return *this; }
|
||||
CharString &truncate(int32_t newLength);
|
||||
|
||||
|
@ -114,6 +117,12 @@ public:
|
|||
*/
|
||||
CharString &appendPathPart(const StringPiece &s, UErrorCode &errorCode);
|
||||
|
||||
/**
|
||||
* Appends a U_FILE_SEP_CHAR if this string is not empty
|
||||
* and does not already end with a U_FILE_SEP_CHAR or U_FILE_ALT_SEP_CHAR.
|
||||
*/
|
||||
CharString &ensureEndsWithFileSeparator(UErrorCode &errorCode);
|
||||
|
||||
private:
|
||||
MaybeStackArray<char, 40> buffer;
|
||||
int32_t len;
|
||||
|
|
|
@ -158,12 +158,63 @@ public:
|
|||
* @param p simple pointer to an array of T items that is adopted
|
||||
*/
|
||||
explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {}
|
||||
#if U_HAVE_RVALUE_REFERENCES
|
||||
/**
|
||||
* Move constructor, leaves src with isNull().
|
||||
* @param src source smart pointer
|
||||
*/
|
||||
LocalMemory(LocalMemory<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
|
||||
src.ptr=NULL;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* Destructor deletes the memory it owns.
|
||||
*/
|
||||
~LocalMemory() {
|
||||
uprv_free(LocalPointerBase<T>::ptr);
|
||||
}
|
||||
#if U_HAVE_RVALUE_REFERENCES
|
||||
/**
|
||||
* Move assignment operator, leaves src with isNull().
|
||||
* The behavior is undefined if *this and src are the same object.
|
||||
* @param src source smart pointer
|
||||
* @return *this
|
||||
*/
|
||||
LocalMemory<T> &operator=(LocalMemory<T> &&src) U_NOEXCEPT {
|
||||
return moveFrom(src);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* Move assignment, leaves src with isNull().
|
||||
* The behavior is undefined if *this and src are the same object.
|
||||
*
|
||||
* Can be called explicitly, does not need C++11 support.
|
||||
* @param src source smart pointer
|
||||
* @return *this
|
||||
*/
|
||||
LocalMemory<T> &moveFrom(LocalMemory<T> &src) U_NOEXCEPT {
|
||||
delete[] LocalPointerBase<T>::ptr;
|
||||
LocalPointerBase<T>::ptr=src.ptr;
|
||||
src.ptr=NULL;
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* Swap pointers.
|
||||
* @param other other smart pointer
|
||||
*/
|
||||
void swap(LocalMemory<T> &other) U_NOEXCEPT {
|
||||
T *temp=LocalPointerBase<T>::ptr;
|
||||
LocalPointerBase<T>::ptr=other.ptr;
|
||||
other.ptr=temp;
|
||||
}
|
||||
/**
|
||||
* Non-member LocalMemory swap function.
|
||||
* @param p1 will get p2's pointer
|
||||
* @param p2 will get p1's pointer
|
||||
*/
|
||||
friend inline void swap(LocalMemory<T> &p1, LocalMemory<T> &p2) U_NOEXCEPT {
|
||||
p1.swap(p2);
|
||||
}
|
||||
/**
|
||||
* Deletes the array it owns,
|
||||
* and adopts (takes ownership of) the one passed in.
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2014, International Business Machines Corporation
|
||||
* Copyright (C) 2006-2015, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -1138,12 +1138,12 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// UnicodeString version of input UText, NFKC normalized in necessary.
|
||||
UnicodeString *inString;
|
||||
// UnicodeString version of input UText, NFKC normalized if necessary.
|
||||
UnicodeString inString;
|
||||
|
||||
// inputMap[inStringIndex] = corresponding native index from UText inText.
|
||||
// If NULL then mapping is 1:1
|
||||
UVector32 *inputMap = NULL;
|
||||
LocalPointer<UVector32> inputMap;
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
|
@ -1153,12 +1153,12 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
inText->chunkNativeStart <= rangeStart &&
|
||||
inText->chunkNativeLimit >= rangeEnd &&
|
||||
inText->nativeIndexingLimit >= rangeEnd - inText->chunkNativeStart) {
|
||||
|
||||
// Input UTtxt is in one contiguous UTF-16 chunk.
|
||||
// Use Read-only aliasing UnicodeString constructor on it.
|
||||
inString = new UnicodeString(FALSE,
|
||||
inText->chunkContents + rangeStart - inText->chunkNativeStart,
|
||||
rangeEnd - rangeStart);
|
||||
|
||||
// Input UText is in one contiguous UTF-16 chunk.
|
||||
// Use Read-only aliasing UnicodeString.
|
||||
inString.setTo(FALSE,
|
||||
inText->chunkContents + rangeStart - inText->chunkNativeStart,
|
||||
rangeEnd - rangeStart);
|
||||
} else {
|
||||
// Copy the text from the original inText (UText) to inString (UnicodeString).
|
||||
// Create a map from UnicodeString indices -> UText offsets.
|
||||
|
@ -1168,14 +1168,16 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
if (limit > utext_nativeLength(inText)) {
|
||||
limit = utext_nativeLength(inText);
|
||||
}
|
||||
inString = new UnicodeString;
|
||||
inputMap = new UVector32(status);
|
||||
inputMap.adoptInsteadAndCheckErrorCode(new UVector32(status), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
while (utext_getNativeIndex(inText) < limit) {
|
||||
int32_t nativePosition = utext_getNativeIndex(inText);
|
||||
UChar32 c = utext_next32(inText);
|
||||
U_ASSERT(c != U_SENTINEL);
|
||||
inString->append(c);
|
||||
while (inputMap->size() < inString->length()) {
|
||||
inString.append(c);
|
||||
while (inputMap->size() < inString.length()) {
|
||||
inputMap->addElement(nativePosition, status);
|
||||
}
|
||||
}
|
||||
|
@ -1183,67 +1185,70 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
}
|
||||
|
||||
|
||||
if (!nfkcNorm2->isNormalized(*inString, status)) {
|
||||
UnicodeString *normalizedInput = new UnicodeString();
|
||||
if (!nfkcNorm2->isNormalized(inString, status)) {
|
||||
UnicodeString normalizedInput;
|
||||
// normalizedMap[normalizedInput position] == original UText position.
|
||||
UVector32 *normalizedMap = new UVector32(status);
|
||||
LocalPointer<UVector32> normalizedMap(new UVector32(status), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UnicodeString fragment;
|
||||
UnicodeString normalizedFragment;
|
||||
for (int32_t srcI = 0; srcI < inString->length();) { // Once per normalization chunk
|
||||
for (int32_t srcI = 0; srcI < inString.length();) { // Once per normalization chunk
|
||||
fragment.remove();
|
||||
int32_t fragmentStartI = srcI;
|
||||
UChar32 c = inString->char32At(srcI);
|
||||
UChar32 c = inString.char32At(srcI);
|
||||
for (;;) {
|
||||
fragment.append(c);
|
||||
srcI = inString->moveIndex32(srcI, 1);
|
||||
if (srcI == inString->length()) {
|
||||
srcI = inString.moveIndex32(srcI, 1);
|
||||
if (srcI == inString.length()) {
|
||||
break;
|
||||
}
|
||||
c = inString->char32At(srcI);
|
||||
c = inString.char32At(srcI);
|
||||
if (nfkcNorm2->hasBoundaryBefore(c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
nfkcNorm2->normalize(fragment, normalizedFragment, status);
|
||||
normalizedInput->append(normalizedFragment);
|
||||
normalizedInput.append(normalizedFragment);
|
||||
|
||||
// Map every position in the normalized chunk to the start of the chunk
|
||||
// in the original input.
|
||||
int32_t fragmentOriginalStart = inputMap? inputMap->elementAti(fragmentStartI) : fragmentStartI+rangeStart;
|
||||
while (normalizedMap->size() < normalizedInput->length()) {
|
||||
int32_t fragmentOriginalStart = inputMap.isValid() ?
|
||||
inputMap->elementAti(fragmentStartI) : fragmentStartI+rangeStart;
|
||||
while (normalizedMap->size() < normalizedInput.length()) {
|
||||
normalizedMap->addElement(fragmentOriginalStart, status);
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
U_ASSERT(normalizedMap->size() == normalizedInput->length());
|
||||
int32_t nativeEnd = inputMap? inputMap->elementAti(inString->length()) : inString->length()+rangeStart;
|
||||
U_ASSERT(normalizedMap->size() == normalizedInput.length());
|
||||
int32_t nativeEnd = inputMap.isValid() ?
|
||||
inputMap->elementAti(inString.length()) : inString.length()+rangeStart;
|
||||
normalizedMap->addElement(nativeEnd, status);
|
||||
|
||||
delete inputMap;
|
||||
inputMap = normalizedMap;
|
||||
delete inString;
|
||||
inString = normalizedInput;
|
||||
inputMap.moveFrom(normalizedMap);
|
||||
inString.moveFrom(normalizedInput);
|
||||
}
|
||||
|
||||
int32_t numCodePts = inString->countChar32();
|
||||
if (numCodePts != inString->length()) {
|
||||
int32_t numCodePts = inString.countChar32();
|
||||
if (numCodePts != inString.length()) {
|
||||
// There are supplementary characters in the input.
|
||||
// The dictionary will produce boundary positions in terms of code point indexes,
|
||||
// not in terms of code unit string indexes.
|
||||
// Use the inputMap mechanism to take care of this in addition to indexing differences
|
||||
// from normalization and/or UTF-8 input.
|
||||
UBool hadExistingMap = (inputMap != NULL);
|
||||
UBool hadExistingMap = inputMap.isValid();
|
||||
if (!hadExistingMap) {
|
||||
inputMap = new UVector32(status);
|
||||
inputMap.adoptInsteadAndCheckErrorCode(new UVector32(status), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int32_t cpIdx = 0;
|
||||
for (int32_t cuIdx = 0; ; cuIdx = inString->moveIndex32(cuIdx, 1)) {
|
||||
for (int32_t cuIdx = 0; ; cuIdx = inString.moveIndex32(cuIdx, 1)) {
|
||||
U_ASSERT(cuIdx >= cpIdx);
|
||||
if (hadExistingMap) {
|
||||
inputMap->setElementAt(inputMap->elementAti(cuIdx), cpIdx);
|
||||
|
@ -1251,7 +1256,7 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
inputMap->addElement(cuIdx+rangeStart, status);
|
||||
}
|
||||
cpIdx++;
|
||||
if (cuIdx == inString->length()) {
|
||||
if (cuIdx == inString.length()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1280,7 +1285,7 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
lengths.setSize(numCodePts);
|
||||
|
||||
UText fu = UTEXT_INITIALIZER;
|
||||
utext_openUnicodeString(&fu, inString, &status);
|
||||
utext_openUnicodeString(&fu, &inString, &status);
|
||||
|
||||
// Dynamic programming to find the best segmentation.
|
||||
|
||||
|
@ -1288,7 +1293,7 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
// ix is the corresponding string (code unit) index.
|
||||
// They differ when the string contains supplementary characters.
|
||||
int32_t ix = 0;
|
||||
for (int32_t i = 0; i < numCodePts; ++i, ix = inString->moveIndex32(ix, 1)) {
|
||||
for (int32_t i = 0; i < numCodePts; ++i, ix = inString.moveIndex32(ix, 1)) {
|
||||
if ((uint32_t)bestSnlp.elementAti(i) == kuint32max) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1306,7 +1311,7 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
// Exclude Korean characters from this treatment, as they should be left
|
||||
// together by default.
|
||||
if ((count == 0 || lengths.elementAti(0) != 1) &&
|
||||
!fHangulWordSet.contains(inString->char32At(ix))) {
|
||||
!fHangulWordSet.contains(inString.char32At(ix))) {
|
||||
values.setElementAt(maxSnlp, count); // 255
|
||||
lengths.setElementAt(1, count++);
|
||||
}
|
||||
|
@ -1327,14 +1332,14 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
// specified in the katakanaCost table according to its length.
|
||||
|
||||
bool is_prev_katakana = false;
|
||||
bool is_katakana = isKatakana(inString->char32At(ix));
|
||||
bool is_katakana = isKatakana(inString.char32At(ix));
|
||||
int32_t katakanaRunLength = 1;
|
||||
if (!is_prev_katakana && is_katakana) {
|
||||
int32_t j = inString->moveIndex32(ix, 1);
|
||||
int32_t j = inString.moveIndex32(ix, 1);
|
||||
// Find the end of the continuous run of Katakana characters
|
||||
while (j < inString->length() && katakanaRunLength < kMaxKatakanaGroupLength &&
|
||||
isKatakana(inString->char32At(j))) {
|
||||
j = inString->moveIndex32(j, 1);
|
||||
while (j < inString.length() && katakanaRunLength < kMaxKatakanaGroupLength &&
|
||||
isKatakana(inString.char32At(j))) {
|
||||
j = inString.moveIndex32(j, 1);
|
||||
katakanaRunLength++;
|
||||
}
|
||||
if (katakanaRunLength < kMaxKatakanaGroupLength) {
|
||||
|
@ -1380,14 +1385,14 @@ CjkBreakEngine::divideUpDictionaryRange( UText *inText,
|
|||
// while reversing t_boundary and pushing values to foundBreaks.
|
||||
for (int32_t i = numBreaks-1; i >= 0; i--) {
|
||||
int32_t cpPos = t_boundary.elementAti(i);
|
||||
int32_t utextPos = inputMap ? inputMap->elementAti(cpPos) : cpPos + rangeStart;
|
||||
int32_t utextPos = inputMap.isValid() ? inputMap->elementAti(cpPos) : cpPos + rangeStart;
|
||||
// Boundaries are added to foundBreaks output in ascending order.
|
||||
U_ASSERT(foundBreaks.size() == 0 ||foundBreaks.peeki() < utextPos);
|
||||
foundBreaks.push(utextPos, status);
|
||||
}
|
||||
|
||||
delete inString;
|
||||
delete inputMap;
|
||||
// inString goes out of scope
|
||||
// inputMap goes out of scope
|
||||
return numBreaks;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and
|
||||
* Copyright (C) 2014-2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -43,6 +43,9 @@ static void _fb_trace(const char *m, const UnicodeString *s, UBool b, int32_t d,
|
|||
#define FB_TRACE(m,s,b,d)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Used with sortedInsert()
|
||||
*/
|
||||
static int8_t U_CALLCONV compareUnicodeString(UElement t1, UElement t2) {
|
||||
const UnicodeString &a = *(const UnicodeString*)t1.pointer;
|
||||
const UnicodeString &b = *(const UnicodeString*)t2.pointer;
|
||||
|
@ -52,7 +55,7 @@ static int8_t U_CALLCONV compareUnicodeString(UElement t1, UElement t2) {
|
|||
/**
|
||||
* A UVector which implements a set of strings.
|
||||
*/
|
||||
class U_I18N_API UStringSet : public UVector {
|
||||
class U_COMMON_API UStringSet : public UVector {
|
||||
public:
|
||||
UStringSet(UErrorCode &status) : UVector(uprv_deleteUObject,
|
||||
uhash_compareUnicodeString,
|
||||
|
@ -117,23 +120,46 @@ class U_I18N_API UStringSet : public UVector {
|
|||
*/
|
||||
UStringSet::~UStringSet() {}
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Filtered Break constants */
|
||||
static const int32_t kPARTIAL = (1<<0); //< partial - need to run through forward trie
|
||||
static const int32_t kMATCH = (1<<1); //< exact match - skip this one.
|
||||
static const int32_t kSuppressInReverse = (1<<0);
|
||||
static const int32_t kAddToForward = (1<<1);
|
||||
static const UChar kFULLSTOP = 0x002E; // '.'
|
||||
static const UChar kFULLSTOP = 0x002E; // '.'
|
||||
|
||||
/**
|
||||
* Shared data for SimpleFilteredSentenceBreakIterator
|
||||
*/
|
||||
class SimpleFilteredSentenceBreakData : public UMemory {
|
||||
public:
|
||||
SimpleFilteredSentenceBreakData(UCharsTrie *forwards, UCharsTrie *backwards )
|
||||
: fForwardsPartialTrie(forwards), fBackwardsTrie(backwards), refcount(1) { }
|
||||
SimpleFilteredSentenceBreakData *incr() { refcount++; return this; }
|
||||
SimpleFilteredSentenceBreakData *decr() { if((--refcount) <= 0) delete this; return 0; }
|
||||
virtual ~SimpleFilteredSentenceBreakData();
|
||||
|
||||
LocalPointer<UCharsTrie> fForwardsPartialTrie; // Has ".a" for "a.M."
|
||||
LocalPointer<UCharsTrie> fBackwardsTrie; // i.e. ".srM" for Mrs.
|
||||
int32_t refcount;
|
||||
};
|
||||
|
||||
SimpleFilteredSentenceBreakData::~SimpleFilteredSentenceBreakData() {}
|
||||
|
||||
/**
|
||||
* Concrete implementation
|
||||
*/
|
||||
class SimpleFilteredSentenceBreakIterator : public BreakIterator {
|
||||
public:
|
||||
SimpleFilteredSentenceBreakIterator(BreakIterator *adopt, UCharsTrie *forwards, UCharsTrie *backwards, UErrorCode &status);
|
||||
SimpleFilteredSentenceBreakIterator(const SimpleFilteredSentenceBreakIterator& other);
|
||||
virtual ~SimpleFilteredSentenceBreakIterator();
|
||||
private:
|
||||
SimpleFilteredSentenceBreakData *fData;
|
||||
LocalPointer<BreakIterator> fDelegate;
|
||||
LocalUTextPointer fText;
|
||||
LocalPointer<UCharsTrie> fBackwardsTrie; // i.e. ".srM" for Mrs.
|
||||
LocalPointer<UCharsTrie> fForwardsPartialTrie; // Has ".a" for "a.M."
|
||||
|
||||
/* -- subclass interface -- */
|
||||
public:
|
||||
|
@ -160,62 +186,82 @@ public:
|
|||
virtual CharacterIterator& getText(void) const { return fDelegate->getText(); }
|
||||
|
||||
/* -- ITERATION -- */
|
||||
virtual int32_t first(void) { return fDelegate->first(); }
|
||||
virtual int32_t preceding(int32_t /*offset*/) { /* TODO: not implemented */ return UBRK_DONE; }
|
||||
virtual int32_t previous(void) { /* TODO: not implemented */ return UBRK_DONE; }
|
||||
virtual UBool isBoundary(int32_t offset) { return fDelegate->isBoundary(offset); }
|
||||
virtual int32_t current(void) const { return fDelegate->current(); }
|
||||
virtual int32_t first(void);
|
||||
virtual int32_t preceding(int32_t offset);
|
||||
virtual int32_t previous(void);
|
||||
virtual UBool isBoundary(int32_t offset);
|
||||
virtual int32_t current(void) const { return fDelegate->current(); } // we keep the delegate current, so this should be correct.
|
||||
|
||||
virtual int32_t next(void);
|
||||
|
||||
virtual int32_t next(int32_t /*n*/) { /* TODO: not implemented */ return UBRK_DONE; }
|
||||
virtual int32_t following(int32_t /*offset*/) { /* TODO: not implemented */ return UBRK_DONE; }
|
||||
virtual int32_t last(void) { return fDelegate->last(); }
|
||||
virtual int32_t next(int32_t n);
|
||||
virtual int32_t following(int32_t offset);
|
||||
virtual int32_t last(void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Given that the fDelegate has already given its "initial" answer,
|
||||
* find the NEXT actual (non-excepted) break.
|
||||
* @param n initial position from delegate
|
||||
* @return new break position or UBRK_DONE
|
||||
*/
|
||||
int32_t internalNext(int32_t n);
|
||||
/**
|
||||
* Given that the fDelegate has already given its "initial" answer,
|
||||
* find the PREV actual (non-excepted) break.
|
||||
* @param n initial position from delegate
|
||||
* @return new break position or UBRK_DONE
|
||||
*/
|
||||
int32_t internalPrev(int32_t n);
|
||||
/**
|
||||
* set up the UText with the value of the fDelegate.
|
||||
* Call this before calling breakExceptionAt.
|
||||
* May be able to avoid excess calls
|
||||
*/
|
||||
void resetState(UErrorCode &status);
|
||||
/**
|
||||
* Is there a match (exception) at this spot?
|
||||
*/
|
||||
enum EFBMatchResult { kNoExceptionHere, kExceptionHere };
|
||||
/**
|
||||
* Determine if there is an exception at this spot
|
||||
* @param n spot to check
|
||||
* @return kNoExceptionHere or kExceptionHere
|
||||
**/
|
||||
enum EFBMatchResult breakExceptionAt(int32_t n);
|
||||
};
|
||||
|
||||
SimpleFilteredSentenceBreakIterator::SimpleFilteredSentenceBreakIterator(const SimpleFilteredSentenceBreakIterator& other)
|
||||
: BreakIterator(other), fDelegate(other.fDelegate->clone())
|
||||
: BreakIterator(other), fData(other.fData->incr()), fDelegate(other.fDelegate->clone())
|
||||
{
|
||||
/*
|
||||
TODO: not able to clone Tries. Should be a refcounted hidden master instead.
|
||||
if(other.fBackwardsTrie.isValid()) {
|
||||
fBackwardsTrie.adoptInstead(other.fBackwardsTrie->clone());
|
||||
}
|
||||
if(other.fForwardsPartialTrie.isValid()) {
|
||||
fForwardsPartialTrie.adoptInstead(other.fForwardsPartialTrie->clone());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
SimpleFilteredSentenceBreakIterator::SimpleFilteredSentenceBreakIterator(BreakIterator *adopt, UCharsTrie *forwards, UCharsTrie *backwards, UErrorCode &status) :
|
||||
BreakIterator(adopt->getLocale(ULOC_VALID_LOCALE,status),adopt->getLocale(ULOC_ACTUAL_LOCALE,status)),
|
||||
fDelegate(adopt),
|
||||
fBackwardsTrie(backwards),
|
||||
fForwardsPartialTrie(forwards)
|
||||
fData(new SimpleFilteredSentenceBreakData(forwards, backwards)),
|
||||
fDelegate(adopt)
|
||||
{
|
||||
// all set..
|
||||
}
|
||||
|
||||
SimpleFilteredSentenceBreakIterator::~SimpleFilteredSentenceBreakIterator() {}
|
||||
SimpleFilteredSentenceBreakIterator::~SimpleFilteredSentenceBreakIterator() {
|
||||
fData = fData->decr();
|
||||
}
|
||||
|
||||
int32_t SimpleFilteredSentenceBreakIterator::next() {
|
||||
int32_t n = fDelegate->next();
|
||||
if(n == UBRK_DONE || // at end or
|
||||
fBackwardsTrie.isNull()) { // .. no backwards table loaded == no exceptions
|
||||
return n;
|
||||
}
|
||||
// OK, do we need to break here?
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// refresh text
|
||||
void SimpleFilteredSentenceBreakIterator::resetState(UErrorCode &status) {
|
||||
fText.adoptInstead(fDelegate->getUText(fText.orphan(), status));
|
||||
//if(debug2) u_printf("str, native len=%d\n", utext_nativeLength(fText.getAlias()));
|
||||
do { // outer loop runs once per underlying break (from fDelegate).
|
||||
}
|
||||
|
||||
SimpleFilteredSentenceBreakIterator::EFBMatchResult
|
||||
SimpleFilteredSentenceBreakIterator::breakExceptionAt(int32_t n) {
|
||||
int64_t bestPosn = -1;
|
||||
int32_t bestValue = -1;
|
||||
// loops while 'n' points to an exception.
|
||||
utext_setNativeIndex(fText.getAlias(), n); // from n..
|
||||
fBackwardsTrie->reset();
|
||||
fData->fBackwardsTrie->reset();
|
||||
UChar32 uch;
|
||||
|
||||
//if(debug2) u_printf(" n@ %d\n", n);
|
||||
// Assume a space is following the '.' (so we handle the case: "Mr. /Brown")
|
||||
if((uch=utext_previous32(fText.getAlias()))==(UChar32)0x0020) { // TODO: skip a class of chars here??
|
||||
|
@ -226,23 +272,21 @@ int32_t SimpleFilteredSentenceBreakIterator::next() {
|
|||
uch = utext_next32(fText.getAlias());
|
||||
//if(debug2) u_printf(" -> : |%C| \n", (UChar)uch);
|
||||
}
|
||||
|
||||
UStringTrieResult r = USTRINGTRIE_INTERMEDIATE_VALUE;
|
||||
|
||||
int32_t bestPosn = -1;
|
||||
int32_t bestValue = -1;
|
||||
|
||||
while((uch=utext_previous32(fText.getAlias()))!=U_SENTINEL && // more to consume backwards and..
|
||||
USTRINGTRIE_HAS_NEXT(r=fBackwardsTrie->nextForCodePoint(uch))) {// more in the trie
|
||||
USTRINGTRIE_HAS_NEXT(r=fData->fBackwardsTrie->nextForCodePoint(uch))) {// more in the trie
|
||||
if(USTRINGTRIE_HAS_VALUE(r)) { // remember the best match so far
|
||||
bestPosn = utext_getNativeIndex(fText.getAlias());
|
||||
bestValue = fBackwardsTrie->getValue();
|
||||
bestValue = fData->fBackwardsTrie->getValue();
|
||||
}
|
||||
//if(debug2) u_printf("rev< /%C/ cont?%d @%d\n", (UChar)uch, r, utext_getNativeIndex(fText.getAlias()));
|
||||
}
|
||||
|
||||
if(USTRINGTRIE_MATCHES(r)) { // exact match?
|
||||
//if(debug2) u_printf("rev<?/%C/?end of seq.. r=%d, bestPosn=%d, bestValue=%d\n", (UChar)uch, r, bestPosn, bestValue);
|
||||
bestValue = fBackwardsTrie->getValue();
|
||||
bestValue = fData->fBackwardsTrie->getValue();
|
||||
bestPosn = utext_getNativeIndex(fText.getAlias());
|
||||
//if(debug2) u_printf("rev<+/%C/+end of seq.. r=%d, bestPosn=%d, bestValue=%d\n", (UChar)uch, r, bestPosn, bestValue);
|
||||
}
|
||||
|
@ -256,49 +300,158 @@ int32_t SimpleFilteredSentenceBreakIterator::next() {
|
|||
|
||||
if(bestValue == kMATCH) { // exact match!
|
||||
//if(debug2) u_printf(" exact backward match\n");
|
||||
n = fDelegate->next(); // skip this one. Find the next lowerlevel break.
|
||||
if(n==UBRK_DONE) return n;
|
||||
continue; // See if the next is another exception.
|
||||
return kExceptionHere; // See if the next is another exception.
|
||||
} else if(bestValue == kPARTIAL
|
||||
&& fForwardsPartialTrie.isValid()) { // make sure there's a forward trie
|
||||
&& fData->fForwardsPartialTrie.isValid()) { // make sure there's a forward trie
|
||||
//if(debug2) u_printf(" partial backward match\n");
|
||||
// We matched the "Ph." in "Ph.D." - now we need to run everything through the forwards trie
|
||||
// to see if it matches something going forward.
|
||||
fForwardsPartialTrie->reset();
|
||||
fData->fForwardsPartialTrie->reset();
|
||||
UStringTrieResult rfwd = USTRINGTRIE_INTERMEDIATE_VALUE;
|
||||
utext_setNativeIndex(fText.getAlias(), bestPosn); // hope that's close ..
|
||||
//if(debug2) u_printf("Retrying at %d\n", bestPosn);
|
||||
while((uch=utext_next32(fText.getAlias()))!=U_SENTINEL &&
|
||||
USTRINGTRIE_HAS_NEXT(rfwd=fForwardsPartialTrie->nextForCodePoint(uch))) {
|
||||
USTRINGTRIE_HAS_NEXT(rfwd=fData->fForwardsPartialTrie->nextForCodePoint(uch))) {
|
||||
//if(debug2) u_printf("fwd> /%C/ cont?%d @%d\n", (UChar)uch, rfwd, utext_getNativeIndex(fText.getAlias()));
|
||||
}
|
||||
if(USTRINGTRIE_MATCHES(rfwd)) {
|
||||
//if(debug2) u_printf("fwd> /%C/ == forward match!\n", (UChar)uch);
|
||||
// only full matches here, nothing to check
|
||||
// skip the next:
|
||||
n = fDelegate->next();
|
||||
if(n==UBRK_DONE) return n;
|
||||
continue;
|
||||
return kExceptionHere;
|
||||
} else {
|
||||
//if(debug2) u_printf("fwd> /%C/ no match.\n", (UChar)uch);
|
||||
// no match (no exception) -return the 'underlying' break
|
||||
return n;
|
||||
return kNoExceptionHere;
|
||||
}
|
||||
} else {
|
||||
return n; // internal error and/or no forwards trie
|
||||
return kNoExceptionHere; // internal error and/or no forwards trie
|
||||
}
|
||||
} else {
|
||||
//if(debug2) u_printf("rev< /%C/ .. no match..%d\n", (UChar)uch, r); // no best match
|
||||
return n; // No match - so exit. Not an exception.
|
||||
return kNoExceptionHere; // No match - so exit. Not an exception.
|
||||
}
|
||||
} while(n != UBRK_DONE);
|
||||
}
|
||||
|
||||
// the workhorse single next.
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::internalNext(int32_t n) {
|
||||
if(n == UBRK_DONE || // at end or
|
||||
fData->fBackwardsTrie.isNull()) { // .. no backwards table loaded == no exceptions
|
||||
return n;
|
||||
}
|
||||
// OK, do we need to break here?
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// refresh text
|
||||
resetState(status);
|
||||
if(U_FAILURE(status)) return UBRK_DONE; // bail out
|
||||
int64_t utextLen = utext_nativeLength(fText.getAlias());
|
||||
|
||||
//if(debug2) u_printf("str, native len=%d\n", utext_nativeLength(fText.getAlias()));
|
||||
while (n != UBRK_DONE && n != utextLen) { // outer loop runs once per underlying break (from fDelegate).
|
||||
SimpleFilteredSentenceBreakIterator::EFBMatchResult m = breakExceptionAt(n);
|
||||
|
||||
switch(m) {
|
||||
case kExceptionHere:
|
||||
n = fDelegate->next(); // skip this one. Find the next lowerlevel break.
|
||||
continue;
|
||||
|
||||
default:
|
||||
case kNoExceptionHere:
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::internalPrev(int32_t n) {
|
||||
if(n == 0 || n == UBRK_DONE || // at end or
|
||||
fData->fBackwardsTrie.isNull()) { // .. no backwards table loaded == no exceptions
|
||||
return n;
|
||||
}
|
||||
// OK, do we need to break here?
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
// refresh text
|
||||
resetState(status);
|
||||
if(U_FAILURE(status)) return UBRK_DONE; // bail out
|
||||
|
||||
//if(debug2) u_printf("str, native len=%d\n", utext_nativeLength(fText.getAlias()));
|
||||
while (n != UBRK_DONE && n != 0) { // outer loop runs once per underlying break (from fDelegate).
|
||||
SimpleFilteredSentenceBreakIterator::EFBMatchResult m = breakExceptionAt(n);
|
||||
|
||||
switch(m) {
|
||||
case kExceptionHere:
|
||||
n = fDelegate->previous(); // skip this one. Find the next lowerlevel break.
|
||||
continue;
|
||||
|
||||
default:
|
||||
case kNoExceptionHere:
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::next() {
|
||||
return internalNext(fDelegate->next());
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::first(void) {
|
||||
return internalNext(fDelegate->first());
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::preceding(int32_t offset) {
|
||||
return internalPrev(fDelegate->preceding(offset));
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::previous(void) {
|
||||
return internalPrev(fDelegate->previous());
|
||||
}
|
||||
|
||||
UBool SimpleFilteredSentenceBreakIterator::isBoundary(int32_t offset) {
|
||||
if(!fDelegate->isBoundary(offset)) return false; // no break to suppress
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
resetState(status);
|
||||
|
||||
SimpleFilteredSentenceBreakIterator::EFBMatchResult m = breakExceptionAt(offset);
|
||||
|
||||
switch(m) {
|
||||
case kExceptionHere:
|
||||
return false;
|
||||
default:
|
||||
case kNoExceptionHere:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::next(int32_t offset) {
|
||||
return internalNext(fDelegate->next(offset));
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::following(int32_t offset) {
|
||||
return internalNext(fDelegate->following(offset));
|
||||
}
|
||||
|
||||
int32_t
|
||||
SimpleFilteredSentenceBreakIterator::last(void) {
|
||||
// Don't suppress a break opportunity at the end of text.
|
||||
return fDelegate->last();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Concrete implementation of builder class.
|
||||
*/
|
||||
class U_I18N_API SimpleFilteredBreakIteratorBuilder : public FilteredBreakIteratorBuilder {
|
||||
class U_COMMON_API SimpleFilteredBreakIteratorBuilder : public FilteredBreakIteratorBuilder {
|
||||
public:
|
||||
virtual ~SimpleFilteredBreakIteratorBuilder();
|
||||
SimpleFilteredBreakIteratorBuilder(const Locale &fromLocale, UErrorCode &status);
|
||||
|
@ -503,14 +656,14 @@ FilteredBreakIteratorBuilder *
|
|||
FilteredBreakIteratorBuilder::createInstance(const Locale& where, UErrorCode& status) {
|
||||
if(U_FAILURE(status)) return NULL;
|
||||
LocalPointer<FilteredBreakIteratorBuilder> ret(new SimpleFilteredBreakIteratorBuilder(where, status), status);
|
||||
return ret.orphan();
|
||||
return (U_SUCCESS(status))? ret.orphan(): NULL;
|
||||
}
|
||||
|
||||
FilteredBreakIteratorBuilder *
|
||||
FilteredBreakIteratorBuilder::createInstance(UErrorCode& status) {
|
||||
if(U_FAILURE(status)) return NULL;
|
||||
LocalPointer<FilteredBreakIteratorBuilder> ret(new SimpleFilteredBreakIteratorBuilder(status), status);
|
||||
return ret.orphan();
|
||||
return (U_SUCCESS(status))? ret.orphan(): NULL;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
|
@ -14,6 +14,11 @@
|
|||
*/
|
||||
|
||||
#include "unicode/icuplug.h"
|
||||
|
||||
|
||||
#if UCONFIG_ENABLE_PLUGINS
|
||||
|
||||
|
||||
#include "icuplugimp.h"
|
||||
#include "cstring.h"
|
||||
#include "cmemory.h"
|
||||
|
@ -307,6 +312,9 @@ static void uplug_queryPlug(UPlugData *plug, UErrorCode *status) {
|
|||
|
||||
|
||||
static void uplug_loadPlug(UPlugData *plug, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
if(!plug->awaitingLoad || (plug->level < UPLUG_LEVEL_LOW) ) { /* shouldn't happen. Plugin hasn'tbeen loaded yet.*/
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
return;
|
||||
|
@ -352,13 +360,11 @@ static UPlugData *uplug_allocateEmptyPlug(UErrorCode *status)
|
|||
|
||||
static UPlugData *uplug_allocatePlug(UPlugEntrypoint *entrypoint, const char *config, void *lib, const char *symName,
|
||||
UErrorCode *status) {
|
||||
UPlugData *plug;
|
||||
|
||||
UPlugData *plug = uplug_allocateEmptyPlug(status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plug = uplug_allocateEmptyPlug(status);
|
||||
if(config!=NULL) {
|
||||
uprv_strncpy(plug->config, config, UPLUG_NAME_MAX);
|
||||
} else {
|
||||
|
@ -870,3 +876,7 @@ uplug_init(UErrorCode *status) {
|
|||
gCurrentLevel = UPLUG_LEVEL_HIGH;
|
||||
ucln_registerCleanup(UCLN_UPLUG, uplug_cleanup);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2010, International Business Machines
|
||||
* Copyright (C) 2009-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "unicode/icuplug.h"
|
||||
|
||||
#if UCONFIG_ENABLE_PLUGINS
|
||||
|
||||
/*========================*/
|
||||
/** @{ Library Manipulation
|
||||
*/
|
||||
|
@ -85,3 +87,5 @@ uplug_getPluginFile(void);
|
|||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "unicode/unistr.h"
|
||||
#include "charstr.h"
|
||||
#include "cstring.h"
|
||||
#include "pluralmap.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static const char * const gPluralForms[] = {
|
||||
"other", "zero", "one", "two", "few", "many"};
|
||||
|
||||
PluralMapBase::Category
|
||||
PluralMapBase::toCategory(const char *pluralForm) {
|
||||
for (int32_t i = 0; i < UPRV_LENGTHOF(gPluralForms); ++i) {
|
||||
if (uprv_strcmp(pluralForm, gPluralForms[i]) == 0) {
|
||||
return static_cast<Category>(i);
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
PluralMapBase::Category
|
||||
PluralMapBase::toCategory(const UnicodeString &pluralForm) {
|
||||
CharString cCategory;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
cCategory.appendInvariantChars(pluralForm, status);
|
||||
return U_FAILURE(status) ? NONE : toCategory(cCategory.data());
|
||||
}
|
||||
|
||||
const char *PluralMapBase::getCategoryName(Category c) {
|
||||
int32_t index = c;
|
||||
return (index < 0 || index >= UPRV_LENGTHOF(gPluralForms)) ?
|
||||
NULL : gPluralForms[index];
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2015, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
*
|
||||
* File pluralmap.h - PluralMap class that maps plural categories to values.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __PLURAL_MAP_H__
|
||||
#define __PLURAL_MAP_H__
|
||||
|
||||
#include "unicode/uobject.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class UnicodeString;
|
||||
|
||||
class U_COMMON_API PluralMapBase : public UMemory {
|
||||
public:
|
||||
/**
|
||||
* The names of all the plural categories. NONE is not an actual plural
|
||||
* category, but rather represents the absense of a plural category.
|
||||
*/
|
||||
enum Category {
|
||||
NONE = -1,
|
||||
OTHER,
|
||||
ZERO,
|
||||
ONE,
|
||||
TWO,
|
||||
FEW,
|
||||
MANY,
|
||||
CATEGORY_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a category name such as "zero", "one", "two", "few", "many"
|
||||
* or "other" to a category enum. Returns NONE for an unrecognized
|
||||
* category name.
|
||||
*/
|
||||
static Category toCategory(const char *categoryName);
|
||||
|
||||
/**
|
||||
* Converts a category name such as "zero", "one", "two", "few", "many"
|
||||
* or "other" to a category enum. Returns NONE for urecongized
|
||||
* category name.
|
||||
*/
|
||||
static Category toCategory(const UnicodeString &categoryName);
|
||||
|
||||
/**
|
||||
* Converts a category to a name.
|
||||
* Passing NONE or CATEGORY_COUNT for category returns NULL.
|
||||
*/
|
||||
static const char *getCategoryName(Category category);
|
||||
};
|
||||
|
||||
/**
|
||||
* A Map of plural categories to values. It maintains ownership of the
|
||||
* values.
|
||||
*
|
||||
* Type T is the value type. T must provide the followng:
|
||||
* 1) Default constructor
|
||||
* 2) Copy constructor
|
||||
* 3) Assignment operator
|
||||
* 4) Must extend UMemory
|
||||
*/
|
||||
template<typename T>
|
||||
class PluralMap : public PluralMapBase {
|
||||
public:
|
||||
/**
|
||||
* Other category is maps to a copy of the default value.
|
||||
*/
|
||||
PluralMap() : fOtherVariant() {
|
||||
initializeNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* Other category is mapped to otherVariant.
|
||||
*/
|
||||
PluralMap(const T &otherVariant) : fOtherVariant(otherVariant) {
|
||||
initializeNew();
|
||||
}
|
||||
|
||||
PluralMap(const PluralMap<T> &other) : fOtherVariant(other.fOtherVariant) {
|
||||
fVariants[0] = &fOtherVariant;
|
||||
for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
fVariants[i] = other.fVariants[i] ?
|
||||
new T(*other.fVariants[i]) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PluralMap<T> &operator=(const PluralMap<T> &other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
for (int32_t i = 0; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
if (fVariants[i] != NULL && other.fVariants[i] != NULL) {
|
||||
*fVariants[i] = *other.fVariants[i];
|
||||
} else if (fVariants[i] != NULL) {
|
||||
delete fVariants[i];
|
||||
fVariants[i] = NULL;
|
||||
} else if (other.fVariants[i] != NULL) {
|
||||
fVariants[i] = new T(*other.fVariants[i]);
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~PluralMap() {
|
||||
for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
delete fVariants[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all mappings and makes 'other' point to the default value.
|
||||
*/
|
||||
void clear() {
|
||||
*fVariants[0] = T();
|
||||
for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
delete fVariants[i];
|
||||
fVariants[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the mappings in this instance, set index to NONE
|
||||
* prior to using. Call next repeatedly to get the values until it
|
||||
* returns NULL. Each time next returns, caller may pass index
|
||||
* to getCategoryName() to get the name of the plural category.
|
||||
* When this function returns NULL, index is CATEGORY_COUNT
|
||||
*/
|
||||
const T *next(Category &index) const {
|
||||
int32_t idx = index;
|
||||
++idx;
|
||||
for (; idx < UPRV_LENGTHOF(fVariants); ++idx) {
|
||||
if (fVariants[idx] != NULL) {
|
||||
index = static_cast<Category>(idx);
|
||||
return fVariants[idx];
|
||||
}
|
||||
}
|
||||
index = static_cast<Category>(idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* non const version of next.
|
||||
*/
|
||||
T *nextMutable(Category &index) {
|
||||
const T *result = next(index);
|
||||
return const_cast<T *>(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'other' variant.
|
||||
* Same as calling get(OTHER).
|
||||
*/
|
||||
const T &getOther() const {
|
||||
return get(OTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value associated with a category.
|
||||
* If no value found, or v is NONE or CATEGORY_COUNT, falls
|
||||
* back to returning the value for the 'other' category.
|
||||
*/
|
||||
const T &get(Category v) const {
|
||||
int32_t index = v;
|
||||
if (index < 0 || index >= UPRV_LENGTHOF(fVariants) || fVariants[index] == NULL) {
|
||||
return *fVariants[0];
|
||||
}
|
||||
return *fVariants[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience routine to get the value by category name. Otherwise
|
||||
* works just like get(Category).
|
||||
*/
|
||||
const T &get(const char *category) const {
|
||||
return get(toCategory(category));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience routine to get the value by category name as a
|
||||
* UnicodeString. Otherwise works just like get(category).
|
||||
*/
|
||||
const T &get(const UnicodeString &category) const {
|
||||
return get(toCategory(category));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the value associated with a category
|
||||
* that caller can safely modify. If the value was defaulting to the 'other'
|
||||
* variant because no explicit value was stored, this method creates a
|
||||
* new value using the default constructor at the returned pointer.
|
||||
*
|
||||
* @param category the category with the value to change.
|
||||
* @param status error returned here if index is NONE or CATEGORY_COUNT
|
||||
* or memory could not be allocated, or any other error happens.
|
||||
*/
|
||||
T *getMutable(
|
||||
Category category,
|
||||
UErrorCode &status) {
|
||||
return getMutable(category, NULL, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience routine to get a mutable pointer to a value by category name.
|
||||
* Otherwise works just like getMutable(Category, UErrorCode &).
|
||||
* reports an error if the category name is invalid.
|
||||
*/
|
||||
T *getMutable(
|
||||
const char *category,
|
||||
UErrorCode &status) {
|
||||
return getMutable(toCategory(category), NULL, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just like getMutable(Category, UErrorCode &) but copies defaultValue to
|
||||
* returned pointer if it was defaulting to the 'other' variant
|
||||
* because no explicit value was stored.
|
||||
*/
|
||||
T *getMutableWithDefault(
|
||||
Category category,
|
||||
const T &defaultValue,
|
||||
UErrorCode &status) {
|
||||
return getMutable(category, &defaultValue, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if this object equals rhs.
|
||||
*/
|
||||
UBool equals(
|
||||
const PluralMap<T> &rhs,
|
||||
UBool (*eqFunc)(const T &, const T &)) const {
|
||||
for (int32_t i = 0; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
if (fVariants[i] == rhs.fVariants[i]) {
|
||||
continue;
|
||||
}
|
||||
if (fVariants[i] == NULL || rhs.fVariants[i] == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!eqFunc(*fVariants[i], *rhs.fVariants[i])) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
T fOtherVariant;
|
||||
T* fVariants[6];
|
||||
|
||||
T *getMutable(
|
||||
Category category,
|
||||
const T *defaultValue,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
int32_t index = category;
|
||||
if (index < 0 || index >= UPRV_LENGTHOF(fVariants)) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
if (fVariants[index] == NULL) {
|
||||
fVariants[index] = defaultValue == NULL ?
|
||||
new T() : new T(*defaultValue);
|
||||
}
|
||||
if (!fVariants[index]) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return fVariants[index];
|
||||
}
|
||||
|
||||
void initializeNew() {
|
||||
fVariants[0] = &fOtherVariant;
|
||||
for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
|
||||
fVariants[i] = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -212,7 +212,7 @@ typedef size_t uintptr_t;
|
|||
*/
|
||||
#ifdef U_HAVE_STD_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif !defined(__cplusplus) || __cplusplus<201103L
|
||||
#elif U_CPLUSPLUS_VERSION < 11
|
||||
/* Not C++11, disable use of atomics */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
|
||||
|
@ -229,26 +229,22 @@ typedef size_t uintptr_t;
|
|||
#endif
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ Code alignment */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* \def U_ALIGN_CODE
|
||||
* This is used to align code fragments to a specific byte boundary.
|
||||
* This is useful for getting consistent performance test results.
|
||||
* @internal
|
||||
* \def U_HAVE_CLANG_ATOMICS
|
||||
* Defines whether Clang c11 style built-in atomics are avaialable.
|
||||
* These are used in preference to gcc atomics when both are available.
|
||||
*/
|
||||
#ifdef U_ALIGN_CODE
|
||||
#ifdef U_HAVE_CLANG_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86) && !defined(_MANAGED)
|
||||
# define U_ALIGN_CODE(boundarySize) __asm align boundarySize
|
||||
#elif __has_builtin(__c11_atomic_load) && \
|
||||
__has_builtin(__c11_atomic_store) && \
|
||||
__has_builtin(__c11_atomic_fetch_add) && \
|
||||
__has_builtin(__c11_atomic_fetch_sub)
|
||||
# define U_HAVE_CLANG_ATOMICS 1
|
||||
#else
|
||||
# define U_ALIGN_CODE(boundarySize)
|
||||
# define U_HAVE_CLANG_ATOMICS 0
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ Programs used by ICU code */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -0,0 +1,607 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* FILE NAME : putilimp.h
|
||||
*
|
||||
* Date Name Description
|
||||
* 10/17/04 grhoten Move internal functions from putil.h to this file.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef PUTILIMP_H
|
||||
#define PUTILIMP_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/putil.h"
|
||||
|
||||
/**
|
||||
* \def U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
|
||||
* Nearly all CPUs and compilers implement a right-shift of a signed integer
|
||||
* as an Arithmetic Shift Right which copies the sign bit (the Most Significant Bit (MSB))
|
||||
* into the vacated bits (sign extension).
|
||||
* For example, (int32_t)0xfff5fff3>>4 becomes 0xffff5fff and -1>>1=-1.
|
||||
*
|
||||
* This can be useful for storing a signed value in the upper bits
|
||||
* and another bit field in the lower bits.
|
||||
* The signed value can be retrieved by simple right-shifting.
|
||||
*
|
||||
* This is consistent with the Java language.
|
||||
*
|
||||
* However, the C standard allows compilers to implement a right-shift of a signed integer
|
||||
* as a Logical Shift Right which copies a 0 into the vacated bits.
|
||||
* For example, (int32_t)0xfff5fff3>>4 becomes 0x0fff5fff and -1>>1=0x7fffffff.
|
||||
*
|
||||
* Code that depends on the natural behavior should be guarded with this macro,
|
||||
* with an alternate path for unusual platforms.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
|
||||
/* Use the predefined value. */
|
||||
#else
|
||||
/*
|
||||
* Nearly all CPUs & compilers implement a right-shift of a signed integer
|
||||
* as an Arithmetic Shift Right (with sign extension).
|
||||
*/
|
||||
# define U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC 1
|
||||
#endif
|
||||
|
||||
/** Define this to 1 if your platform supports IEEE 754 floating point,
|
||||
to 0 if it does not. */
|
||||
#ifndef IEEE_754
|
||||
# define IEEE_754 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uintptr_t is an optional part of the standard definitions in stdint.h.
|
||||
* The opengroup.org documentation for stdint.h says
|
||||
* "On XSI-conformant systems, the intptr_t and uintptr_t types are required;
|
||||
* otherwise, they are optional."
|
||||
* We assume that when uintptr_t is defined, UINTPTR_MAX is defined as well.
|
||||
*
|
||||
* Do not use ptrdiff_t since it is signed. size_t is unsigned.
|
||||
*/
|
||||
/* TODO: This check fails on some z environments. Filed a ticket #9357 for this. */
|
||||
#if !defined(__intptr_t_defined) && !defined(UINTPTR_MAX) && (U_PLATFORM != U_PF_OS390)
|
||||
typedef size_t uintptr_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def U_HAVE_MSVC_2003_OR_EARLIER
|
||||
* Flag for workaround of MSVC 2003 optimization bugs
|
||||
* @internal
|
||||
*/
|
||||
#if !defined(U_HAVE_MSVC_2003_OR_EARLIER) && defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
#define U_HAVE_MSVC_2003_OR_EARLIER
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ Information about POSIX support */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef U_HAVE_NL_LANGINFO_CODESET
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_HAS_WIN32_API || U_PLATFORM == U_PF_ANDROID || U_PLATFORM == U_PF_QNX
|
||||
# define U_HAVE_NL_LANGINFO_CODESET 0
|
||||
#else
|
||||
# define U_HAVE_NL_LANGINFO_CODESET 1
|
||||
#endif
|
||||
|
||||
#ifdef U_NL_LANGINFO_CODESET
|
||||
/* Use the predefined value. */
|
||||
#elif !U_HAVE_NL_LANGINFO_CODESET
|
||||
# define U_NL_LANGINFO_CODESET -1
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#else
|
||||
# define U_NL_LANGINFO_CODESET CODESET
|
||||
#endif
|
||||
|
||||
#ifdef U_TZSET
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
# define U_TZSET _tzset
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#else
|
||||
# define U_TZSET tzset
|
||||
#endif
|
||||
|
||||
#if defined(U_TIMEZONE) || defined(U_HAVE_TIMEZONE)
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM == U_PF_ANDROID
|
||||
# define U_TIMEZONE timezone
|
||||
#elif U_PLATFORM_IS_LINUX_BASED
|
||||
# if defined(__UCLIBC__)
|
||||
/* uClibc does not have __timezone or _timezone. */
|
||||
# elif defined(_NEWLIB_VERSION)
|
||||
# define U_TIMEZONE _timezone
|
||||
# elif defined(__GLIBC__)
|
||||
/* glibc */
|
||||
# define U_TIMEZONE __timezone
|
||||
# endif
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
# define U_TIMEZONE _timezone
|
||||
#elif U_PLATFORM == U_PF_BSD && !defined(__NetBSD__)
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#elif U_PLATFORM == U_PF_IPHONE
|
||||
/* not defined */
|
||||
#else
|
||||
# define U_TIMEZONE timezone
|
||||
#endif
|
||||
|
||||
#ifdef U_TZNAME
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
# define U_TZNAME _tzname
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
/* not defined */
|
||||
#else
|
||||
# define U_TZNAME tzname
|
||||
#endif
|
||||
|
||||
#ifdef U_HAVE_MMAP
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_HAS_WIN32_API
|
||||
# define U_HAVE_MMAP 0
|
||||
#else
|
||||
# define U_HAVE_MMAP 1
|
||||
#endif
|
||||
|
||||
#ifdef U_HAVE_POPEN
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_USES_ONLY_WIN32_API
|
||||
# define U_HAVE_POPEN 0
|
||||
#elif U_PLATFORM == U_PF_OS400
|
||||
# define U_HAVE_POPEN 0
|
||||
#else
|
||||
# define U_HAVE_POPEN 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def U_HAVE_DIRENT_H
|
||||
* Defines whether dirent.h is available.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_HAVE_DIRENT_H
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM_HAS_WIN32_API
|
||||
# define U_HAVE_DIRENT_H 0
|
||||
#else
|
||||
# define U_HAVE_DIRENT_H 1
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ GCC built in functions for atomic memory operations */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* \def U_HAVE_GCC_ATOMICS
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_HAVE_GCC_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM == U_PF_MINGW
|
||||
#define U_HAVE_GCC_ATOMICS 0
|
||||
#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
|
||||
/* TODO: Intel icc and IBM xlc on AIX also support gcc atomics. (Intel originated them.)
|
||||
* Add them for these compilers.
|
||||
* Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
|
||||
*/
|
||||
# define U_HAVE_GCC_ATOMICS 1
|
||||
#else
|
||||
# define U_HAVE_GCC_ATOMICS 0
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \def U_HAVE_STD_ATOMICS
|
||||
* Defines whether the standard C++11 <atomic> is available.
|
||||
* ICU will use this when avialable,
|
||||
* otherwise will fall back to compiler or platform specific alternatives.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_HAVE_STD_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif U_CPLUSPLUS_VERSION < 11
|
||||
/* Not C++11, disable use of atomics */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
|
||||
/* Clang 3.1, has atomic variable initializer bug. */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#else
|
||||
/* U_HAVE_ATOMIC is typically set by an autoconf test of #include <atomic> */
|
||||
/* Can be set manually, or left undefined, on platforms without autoconf. */
|
||||
# if defined(U_HAVE_ATOMIC) && U_HAVE_ATOMIC
|
||||
# define U_HAVE_STD_ATOMICS 1
|
||||
# else
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \def U_HAVE_CLANG_ATOMICS
|
||||
* Defines whether Clang c11 style built-in atomics are avaialable.
|
||||
* These are used in preference to gcc atomics when both are available.
|
||||
*/
|
||||
#ifdef U_HAVE_CLANG_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif __has_builtin(__c11_atomic_load) && \
|
||||
__has_builtin(__c11_atomic_store) && \
|
||||
__has_builtin(__c11_atomic_fetch_add) && \
|
||||
__has_builtin(__c11_atomic_fetch_sub)
|
||||
# define U_HAVE_CLANG_ATOMICS 1
|
||||
#else
|
||||
# define U_HAVE_CLANG_ATOMICS 0
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ Programs used by ICU code */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* \def U_MAKE_IS_NMAKE
|
||||
* Defines whether the "make" program is Windows nmake.
|
||||
*/
|
||||
#ifdef U_MAKE_IS_NMAKE
|
||||
/* Use the predefined value. */
|
||||
#elif U_PLATFORM == U_PF_WINDOWS
|
||||
# define U_MAKE_IS_NMAKE 1
|
||||
#else
|
||||
# define U_MAKE_IS_NMAKE 0
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*==========================================================================*/
|
||||
/* Platform utilities */
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* Platform utilities isolates the platform dependencies of the
|
||||
* libarary. For each platform which this code is ported to, these
|
||||
* functions may have to be re-implemented.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Floating point utility to determine if a double is Not a Number (NaN).
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_isNaN(double d);
|
||||
/**
|
||||
* Floating point utility to determine if a double has an infinite value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_isInfinite(double d);
|
||||
/**
|
||||
* Floating point utility to determine if a double has a positive infinite value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_isPositiveInfinity(double d);
|
||||
/**
|
||||
* Floating point utility to determine if a double has a negative infinite value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_isNegativeInfinity(double d);
|
||||
/**
|
||||
* Floating point utility that returns a Not a Number (NaN) value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_getNaN(void);
|
||||
/**
|
||||
* Floating point utility that returns an infinite value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_getInfinity(void);
|
||||
|
||||
/**
|
||||
* Floating point utility to truncate a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_trunc(double d);
|
||||
/**
|
||||
* Floating point utility to calculate the floor of a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_floor(double d);
|
||||
/**
|
||||
* Floating point utility to calculate the ceiling of a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_ceil(double d);
|
||||
/**
|
||||
* Floating point utility to calculate the absolute value of a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_fabs(double d);
|
||||
/**
|
||||
* Floating point utility to calculate the fractional and integer parts of a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_modf(double d, double* pinteger);
|
||||
/**
|
||||
* Floating point utility to calculate the remainder of a double divided by another double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_fmod(double d, double y);
|
||||
/**
|
||||
* Floating point utility to calculate d to the power of exponent (d^exponent).
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_pow(double d, double exponent);
|
||||
/**
|
||||
* Floating point utility to calculate 10 to the power of exponent (10^exponent).
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_pow10(int32_t exponent);
|
||||
/**
|
||||
* Floating point utility to calculate the maximum value of two doubles.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_fmax(double d, double y);
|
||||
/**
|
||||
* Floating point utility to calculate the minimum value of two doubles.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_fmin(double d, double y);
|
||||
/**
|
||||
* Private utility to calculate the maximum value of two integers.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL int32_t U_EXPORT2 uprv_max(int32_t d, int32_t y);
|
||||
/**
|
||||
* Private utility to calculate the minimum value of two integers.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL int32_t U_EXPORT2 uprv_min(int32_t d, int32_t y);
|
||||
|
||||
#if U_IS_BIG_ENDIAN
|
||||
# define uprv_isNegative(number) (*((signed char *)&(number))<0)
|
||||
#else
|
||||
# define uprv_isNegative(number) (*((signed char *)&(number)+sizeof(number)-1)<0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return the largest positive number that can be represented by an integer
|
||||
* type of arbitrary bit length.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_maxMantissa(void);
|
||||
|
||||
/**
|
||||
* Floating point utility to calculate the logarithm of a double.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_log(double d);
|
||||
|
||||
/**
|
||||
* Does common notion of rounding e.g. uprv_floor(x + 0.5);
|
||||
* @param x the double number
|
||||
* @return the rounded double
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL double U_EXPORT2 uprv_round(double x);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Returns the number of digits after the decimal point in a double number x.
|
||||
*
|
||||
* @param x the double number
|
||||
* @return the number of digits after the decimal point in a double number x.
|
||||
* @internal
|
||||
*/
|
||||
/*U_INTERNAL int32_t U_EXPORT2 uprv_digitsAfterDecimal(double x);*/
|
||||
#endif
|
||||
|
||||
#if !U_CHARSET_IS_UTF8
|
||||
/**
|
||||
* Please use ucnv_getDefaultName() instead.
|
||||
* Return the default codepage for this platform and locale.
|
||||
* This function can call setlocale() on Unix platforms. Please read the
|
||||
* platform documentation on setlocale() before calling this function.
|
||||
* @return the default codepage for this platform
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL const char* U_EXPORT2 uprv_getDefaultCodepage(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Please use uloc_getDefault() instead.
|
||||
* Return the default locale ID string by querying ths system, or
|
||||
* zero if one cannot be found.
|
||||
* This function can call setlocale() on Unix platforms. Please read the
|
||||
* platform documentation on setlocale() before calling this function.
|
||||
* @return the default locale ID string
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL const char* U_EXPORT2 uprv_getDefaultLocaleID(void);
|
||||
|
||||
/**
|
||||
* Time zone utilities
|
||||
*
|
||||
* Wrappers for C runtime library functions relating to timezones.
|
||||
* The t_tzset() function (similar to tzset) uses the current setting
|
||||
* of the environment variable TZ to assign values to three global
|
||||
* variables: daylight, timezone, and tzname. These variables have the
|
||||
* following meanings, and are declared in <time.h>.
|
||||
*
|
||||
* daylight Nonzero if daylight-saving-time zone (DST) is specified
|
||||
* in TZ; otherwise, 0. Default value is 1.
|
||||
* timezone Difference in seconds between coordinated universal
|
||||
* time and local time. E.g., -28,800 for PST (GMT-8hrs)
|
||||
* tzname(0) Three-letter time-zone name derived from TZ environment
|
||||
* variable. E.g., "PST".
|
||||
* tzname(1) Three-letter DST zone name derived from TZ environment
|
||||
* variable. E.g., "PDT". If DST zone is omitted from TZ,
|
||||
* tzname(1) is an empty string.
|
||||
*
|
||||
* Notes: For example, to set the TZ environment variable to correspond
|
||||
* to the current time zone in Germany, you can use one of the
|
||||
* following statements:
|
||||
*
|
||||
* set TZ=GST1GDT
|
||||
* set TZ=GST+1GDT
|
||||
*
|
||||
* If the TZ value is not set, t_tzset() attempts to use the time zone
|
||||
* information specified by the operating system. Under Windows NT
|
||||
* and Windows 95, this information is specified in the Control Panel's
|
||||
* Date/Time application.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL void U_EXPORT2 uprv_tzset(void);
|
||||
|
||||
/**
|
||||
* Difference in seconds between coordinated universal
|
||||
* time and local time. E.g., -28,800 for PST (GMT-8hrs)
|
||||
* @return the difference in seconds between coordinated universal time and local time.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL int32_t U_EXPORT2 uprv_timezone(void);
|
||||
|
||||
/**
|
||||
* tzname(0) Three-letter time-zone name derived from TZ environment
|
||||
* variable. E.g., "PST".
|
||||
* tzname(1) Three-letter DST zone name derived from TZ environment
|
||||
* variable. E.g., "PDT". If DST zone is omitted from TZ,
|
||||
* tzname(1) is an empty string.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL const char* U_EXPORT2 uprv_tzname(int n);
|
||||
|
||||
/**
|
||||
* Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970.
|
||||
* This function is affected by 'faketime' and should be the bottleneck for all user-visible ICU time functions.
|
||||
* @return the UTC time measured in milliseconds
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UDate U_EXPORT2 uprv_getUTCtime(void);
|
||||
|
||||
/**
|
||||
* Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970.
|
||||
* This function is not affected by 'faketime', so it should only be used by low level test functions- not by anything that
|
||||
* exposes time to the end user.
|
||||
* @return the UTC time measured in milliseconds
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UDate U_EXPORT2 uprv_getRawUTCtime(void);
|
||||
|
||||
/**
|
||||
* Determine whether a pathname is absolute or not, as defined by the platform.
|
||||
* @param path Pathname to test
|
||||
* @return TRUE if the path is absolute
|
||||
* @internal (ICU 3.0)
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
|
||||
|
||||
/**
|
||||
* Use U_MAX_PTR instead of this function.
|
||||
* @param void pointer to test
|
||||
* @return the largest possible pointer greater than the base
|
||||
* @internal (ICU 3.8)
|
||||
*/
|
||||
U_INTERNAL void * U_EXPORT2 uprv_maximumPtr(void *base);
|
||||
|
||||
/**
|
||||
* Maximum value of a (void*) - use to indicate the limit of an 'infinite' buffer.
|
||||
* In fact, buffer sizes must not exceed 2GB so that the difference between
|
||||
* the buffer limit and the buffer start can be expressed in an int32_t.
|
||||
*
|
||||
* The definition of U_MAX_PTR must fulfill the following conditions:
|
||||
* - return the largest possible pointer greater than base
|
||||
* - return a valid pointer according to the machine architecture (AS/400, 64-bit, etc.)
|
||||
* - avoid wrapping around at high addresses
|
||||
* - make sure that the returned pointer is not farther from base than 0x7fffffff bytes
|
||||
*
|
||||
* @param base The beginning of a buffer to find the maximum offset from
|
||||
* @internal
|
||||
*/
|
||||
#ifndef U_MAX_PTR
|
||||
# if U_PLATFORM == U_PF_OS390 && !defined(_LP64)
|
||||
/* We have 31-bit pointers. */
|
||||
# define U_MAX_PTR(base) ((void *)0x7fffffff)
|
||||
# elif U_PLATFORM == U_PF_OS400
|
||||
# define U_MAX_PTR(base) uprv_maximumPtr((void *)base)
|
||||
# elif 0
|
||||
/*
|
||||
* For platforms where pointers are scalar values (which is normal, but unlike i5/OS)
|
||||
* but that do not define uintptr_t.
|
||||
*
|
||||
* However, this does not work on modern compilers:
|
||||
* The C++ standard does not define pointer overflow, and allows compilers to
|
||||
* assume that p+u>p for any pointer p and any integer u>0.
|
||||
* Thus, modern compilers optimize away the ">" comparison.
|
||||
* (See ICU tickets #7187 and #8096.)
|
||||
*/
|
||||
# define U_MAX_PTR(base) \
|
||||
((void *)(((char *)(base)+0x7fffffffu) > (char *)(base) \
|
||||
? ((char *)(base)+0x7fffffffu) \
|
||||
: (char *)-1))
|
||||
# else
|
||||
/* Default version. C++ standard compliant for scalar pointers. */
|
||||
# define U_MAX_PTR(base) \
|
||||
((void *)(((uintptr_t)(base)+0x7fffffffu) > (uintptr_t)(base) \
|
||||
? ((uintptr_t)(base)+0x7fffffffu) \
|
||||
: (uintptr_t)-1))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Dynamic Library Functions */
|
||||
|
||||
typedef void (UVoidFunction)(void);
|
||||
|
||||
#if U_ENABLE_DYLOAD
|
||||
/**
|
||||
* Load a library
|
||||
* @internal (ICU 4.4)
|
||||
*/
|
||||
U_INTERNAL void * U_EXPORT2 uprv_dl_open(const char *libName, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Close a library
|
||||
* @internal (ICU 4.4)
|
||||
*/
|
||||
U_INTERNAL void U_EXPORT2 uprv_dl_close( void *lib, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Extract a symbol from a library (function)
|
||||
* @internal (ICU 4.8)
|
||||
*/
|
||||
U_INTERNAL UVoidFunction* U_EXPORT2 uprv_dlsym_func( void *lib, const char *symbolName, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Extract a symbol from a library (function)
|
||||
* Not implemented, no clients.
|
||||
* @internal
|
||||
*/
|
||||
/* U_INTERNAL void * U_EXPORT2 uprv_dlsym_data( void *lib, const char *symbolName, UErrorCode *status); */
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Define malloc and related functions
|
||||
* @internal
|
||||
*/
|
||||
#if U_PLATFORM == U_PF_OS400
|
||||
# define uprv_default_malloc(x) _C_TS_malloc(x)
|
||||
# define uprv_default_realloc(x,y) _C_TS_realloc(x,y)
|
||||
# define uprv_default_free(x) _C_TS_free(x)
|
||||
/* also _C_TS_calloc(x) */
|
||||
#else
|
||||
/* C defaults */
|
||||
# define uprv_default_malloc(x) malloc(x)
|
||||
# define uprv_default_realloc(x,y) realloc(x,y)
|
||||
# define uprv_default_free(x) free(x)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
//
|
||||
// file: rbbiscan.cpp
|
||||
//
|
||||
// Copyright (C) 2002-2014, International Business Machines Corporation and others.
|
||||
// Copyright (C) 2002-2015, International Business Machines Corporation and others.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// This file contains the Rule Based Break Iterator Rule Builder functions for
|
||||
|
@ -211,6 +210,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
fixOpStack(RBBINode::precOpCat);
|
||||
RBBINode *operandNode = fNodeStack[fNodeStackPtr--];
|
||||
RBBINode *orNode = pushNewNode(RBBINode::opOr);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
orNode->fLeftChild = operandNode;
|
||||
operandNode->fParent = orNode;
|
||||
}
|
||||
|
@ -225,6 +227,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
fixOpStack(RBBINode::precOpCat);
|
||||
RBBINode *operandNode = fNodeStack[fNodeStackPtr--];
|
||||
RBBINode *catNode = pushNewNode(RBBINode::opCat);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
catNode->fLeftChild = operandNode;
|
||||
operandNode->fParent = catNode;
|
||||
}
|
||||
|
@ -320,6 +325,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
RBBINode *thisRule = fNodeStack[fNodeStackPtr];
|
||||
RBBINode *endNode = pushNewNode(RBBINode::endMark);
|
||||
RBBINode *catNode = pushNewNode(RBBINode::opCat);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
fNodeStackPtr -= 2;
|
||||
catNode->fLeftChild = thisRule;
|
||||
catNode->fRightChild = endNode;
|
||||
|
@ -347,6 +355,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
RBBINode *thisRule = fNodeStack[fNodeStackPtr];
|
||||
RBBINode *prevRules = *destRules;
|
||||
RBBINode *orNode = pushNewNode(RBBINode::opOr);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
orNode->fLeftChild = prevRules;
|
||||
prevRules->fParent = orNode;
|
||||
orNode->fRightChild = thisRule;
|
||||
|
@ -387,6 +398,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
{
|
||||
RBBINode *operandNode = fNodeStack[fNodeStackPtr--];
|
||||
RBBINode *plusNode = pushNewNode(RBBINode::opPlus);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
plusNode->fLeftChild = operandNode;
|
||||
operandNode->fParent = plusNode;
|
||||
}
|
||||
|
@ -396,6 +410,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
{
|
||||
RBBINode *operandNode = fNodeStack[fNodeStackPtr--];
|
||||
RBBINode *qNode = pushNewNode(RBBINode::opQuestion);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
qNode->fLeftChild = operandNode;
|
||||
operandNode->fParent = qNode;
|
||||
}
|
||||
|
@ -405,6 +422,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
{
|
||||
RBBINode *operandNode = fNodeStack[fNodeStackPtr--];
|
||||
RBBINode *starNode = pushNewNode(RBBINode::opStar);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
starNode->fLeftChild = operandNode;
|
||||
operandNode->fParent = starNode;
|
||||
}
|
||||
|
@ -418,6 +438,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
// sets that just happen to contain only one character.
|
||||
{
|
||||
n = pushNewNode(RBBINode::setRef);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
findSetFor(UnicodeString(fC.fChar), n);
|
||||
n->fFirstPos = fScanIndex;
|
||||
n->fLastPos = fNextIndex;
|
||||
|
@ -429,6 +452,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
// scanned a ".", meaning match any single character.
|
||||
{
|
||||
n = pushNewNode(RBBINode::setRef);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
findSetFor(UnicodeString(TRUE, kAny, 3), n);
|
||||
n->fFirstPos = fScanIndex;
|
||||
n->fLastPos = fNextIndex;
|
||||
|
@ -439,6 +465,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
case doSlash:
|
||||
// Scanned a '/', which identifies a look-ahead break position in a rule.
|
||||
n = pushNewNode(RBBINode::lookAhead);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
n->fVal = fRuleNum;
|
||||
n->fFirstPos = fScanIndex;
|
||||
n->fLastPos = fNextIndex;
|
||||
|
@ -450,6 +479,9 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
case doStartTagValue:
|
||||
// Scanned a '{', the opening delimiter for a tag value within a rule.
|
||||
n = pushNewNode(RBBINode::tag);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
break;
|
||||
}
|
||||
n->fVal = 0;
|
||||
n->fFirstPos = fScanIndex;
|
||||
n->fLastPos = fNextIndex;
|
||||
|
@ -560,7 +592,7 @@ UBool RBBIRuleScanner::doParseActions(int32_t action)
|
|||
returnVal = FALSE;
|
||||
break;
|
||||
}
|
||||
return returnVal;
|
||||
return returnVal && U_SUCCESS(*fRB->fStatus);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1051,6 +1083,9 @@ void RBBIRuleScanner::parse() {
|
|||
if (fRB->fReverseTree == NULL) {
|
||||
fRB->fReverseTree = pushNewNode(RBBINode::opStar);
|
||||
RBBINode *operand = pushNewNode(RBBINode::setRef);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
return;
|
||||
}
|
||||
findSetFor(UnicodeString(TRUE, kAny, 3), operand);
|
||||
fRB->fReverseTree->fLeftChild = operand;
|
||||
operand->fParent = fRB->fReverseTree;
|
||||
|
@ -1103,6 +1138,9 @@ void RBBIRuleScanner::printNodeStack(const char *title) {
|
|||
//
|
||||
//------------------------------------------------------------------------------
|
||||
RBBINode *RBBIRuleScanner::pushNewNode(RBBINode::NodeType t) {
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
return NULL;
|
||||
}
|
||||
fNodeStackPtr++;
|
||||
if (fNodeStackPtr >= kStackSize) {
|
||||
error(U_BRK_INTERNAL_ERROR);
|
||||
|
@ -1192,6 +1230,9 @@ void RBBIRuleScanner::scanSet() {
|
|||
RBBINode *n;
|
||||
|
||||
n = pushNewNode(RBBINode::setRef);
|
||||
if (U_FAILURE(*fRB->fStatus)) {
|
||||
return;
|
||||
}
|
||||
n->fFirstPos = startPos;
|
||||
n->fLastPos = fNextIndex;
|
||||
fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
|
||||
|
|
|
@ -1,42 +1,67 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Copyright (C) 2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* sharedobject.cpp
|
||||
*/
|
||||
#include "sharedobject.h"
|
||||
#include "uassert.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
SharedObject::~SharedObject() {}
|
||||
|
||||
UnifiedCacheBase::~UnifiedCacheBase() {}
|
||||
|
||||
void
|
||||
SharedObject::addRef() const {
|
||||
SharedObject::addRef(UBool fromWithinCache) const {
|
||||
umtx_atomic_inc(&totalRefCount);
|
||||
|
||||
// Although items in use may not be correct immediately, it
|
||||
// will be correct eventually.
|
||||
if (umtx_atomic_inc(&hardRefCount) == 1 && cachePtr != NULL) {
|
||||
// If this object is cached, and the hardRefCount goes from 0 to 1,
|
||||
// then the increment must happen from within the cache while the
|
||||
// cache global mutex is locked. In this way, we can be rest assured
|
||||
// that data races can't happen if the cache performs some task if
|
||||
// the hardRefCount is zero while the global cache mutex is locked.
|
||||
U_ASSERT(fromWithinCache);
|
||||
cachePtr->incrementItemsInUse();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedObject::removeRef() const {
|
||||
if(umtx_atomic_dec(&totalRefCount) == 0) {
|
||||
SharedObject::removeRef(UBool fromWithinCache) const {
|
||||
UBool decrementItemsInUse = (umtx_atomic_dec(&hardRefCount) == 0);
|
||||
UBool allReferencesGone = (umtx_atomic_dec(&totalRefCount) == 0);
|
||||
|
||||
// Although items in use may not be correct immediately, it
|
||||
// will be correct eventually.
|
||||
if (decrementItemsInUse && cachePtr != NULL) {
|
||||
if (fromWithinCache) {
|
||||
cachePtr->decrementItemsInUse();
|
||||
} else {
|
||||
cachePtr->decrementItemsInUseWithLockingAndEviction();
|
||||
}
|
||||
}
|
||||
if (allReferencesGone) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedObject::addSoftRef() const {
|
||||
addRef();
|
||||
umtx_atomic_inc(&softRefCount);
|
||||
umtx_atomic_inc(&totalRefCount);
|
||||
++softRefCount;
|
||||
}
|
||||
|
||||
void
|
||||
SharedObject::removeSoftRef() const {
|
||||
umtx_atomic_dec(&softRefCount);
|
||||
removeRef();
|
||||
}
|
||||
|
||||
UBool
|
||||
SharedObject::allSoftReferences() const {
|
||||
return umtx_loadAcquire(totalRefCount) == umtx_loadAcquire(softRefCount);
|
||||
--softRefCount;
|
||||
if (umtx_atomic_dec(&totalRefCount) == 0) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
|
@ -45,8 +70,8 @@ SharedObject::getRefCount() const {
|
|||
}
|
||||
|
||||
int32_t
|
||||
SharedObject::getSoftRefCount() const {
|
||||
return umtx_loadAcquire(softRefCount);
|
||||
SharedObject::getHardRefCount() const {
|
||||
return umtx_loadAcquire(hardRefCount);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines
|
||||
* Copyright (C) 2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* sharedobject.h
|
||||
|
@ -15,6 +15,39 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Base class for unified cache exposing enough methods to SharedObject
|
||||
* instances to allow their addRef() and removeRef() methods to
|
||||
* update cache metrics. No other part of ICU, except for SharedObject,
|
||||
* should directly call the methods of this base class.
|
||||
*/
|
||||
class UnifiedCacheBase : public UObject {
|
||||
public:
|
||||
UnifiedCacheBase() { }
|
||||
|
||||
/**
|
||||
* Called by addRefWhileHoldingCacheLock() when the hard reference count
|
||||
* of its instance goes from 0 to 1.
|
||||
*/
|
||||
virtual void incrementItemsInUse() const = 0;
|
||||
|
||||
/**
|
||||
* Called by removeRef() when the hard reference count of its instance
|
||||
* drops from 1 to 0.
|
||||
*/
|
||||
virtual void decrementItemsInUseWithLockingAndEviction() const = 0;
|
||||
|
||||
/**
|
||||
* Called by removeRefWhileHoldingCacheLock() when the hard reference
|
||||
* count of its instance drops from 1 to 0.
|
||||
*/
|
||||
virtual void decrementItemsInUse() const = 0;
|
||||
virtual ~UnifiedCacheBase();
|
||||
private:
|
||||
UnifiedCacheBase(const UnifiedCacheBase &);
|
||||
UnifiedCacheBase &operator=(const UnifiedCacheBase &);
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for shared, reference-counted, auto-deleted objects.
|
||||
* Subclasses can be immutable.
|
||||
|
@ -27,33 +60,57 @@ U_NAMESPACE_BEGIN
|
|||
class U_COMMON_API SharedObject : public UObject {
|
||||
public:
|
||||
/** Initializes totalRefCount, softRefCount to 0. */
|
||||
SharedObject() : totalRefCount(0), softRefCount(0) {}
|
||||
SharedObject() :
|
||||
totalRefCount(0),
|
||||
softRefCount(0),
|
||||
hardRefCount(0),
|
||||
cachePtr(NULL) {}
|
||||
|
||||
/** Initializes totalRefCount, softRefCount to 0. */
|
||||
SharedObject(const SharedObject &other)
|
||||
: UObject(other),
|
||||
totalRefCount(0),
|
||||
softRefCount(0) {}
|
||||
SharedObject(const SharedObject &other) :
|
||||
UObject(other),
|
||||
totalRefCount(0),
|
||||
softRefCount(0),
|
||||
hardRefCount(0),
|
||||
cachePtr(NULL) {}
|
||||
|
||||
virtual ~SharedObject();
|
||||
|
||||
/**
|
||||
* Increments the number of references to this object. Thread-safe.
|
||||
*/
|
||||
void addRef() const;
|
||||
void addRef() const { addRef(FALSE); }
|
||||
|
||||
/**
|
||||
* Increments the number of soft references to this object. Thread-safe.
|
||||
* Increments the number of references to this object.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
void addRefWhileHoldingCacheLock() const { addRef(TRUE); }
|
||||
|
||||
/**
|
||||
* Increments the number of soft references to this object.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
void addSoftRef() const;
|
||||
|
||||
/**
|
||||
* Decrements the number of references to this object. Thread-safe.
|
||||
*/
|
||||
void removeRef() const;
|
||||
void removeRef() const { removeRef(FALSE); }
|
||||
|
||||
/**
|
||||
* Decrements the number of soft references to this object. Thread-safe.
|
||||
* Decrements the number of references to this object.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
void removeRefWhileHoldingCacheLock() const { removeRef(TRUE); }
|
||||
|
||||
/**
|
||||
* Decrements the number of soft references to this object.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
void removeSoftRef() const;
|
||||
|
||||
|
@ -64,22 +121,50 @@ public:
|
|||
int32_t getRefCount() const;
|
||||
|
||||
/**
|
||||
* Returns the count of soft references only. Uses a memory barrier.
|
||||
* Used for testing the cache. Regular clients won't need this.
|
||||
* Returns the count of soft references only.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
int32_t getSoftRefCount() const;
|
||||
int32_t getSoftRefCount() const { return softRefCount; }
|
||||
|
||||
/**
|
||||
* If allSoftReferences() == TRUE then this object has only soft
|
||||
* references. The converse is not necessarily true.
|
||||
* Returns the count of hard references only. Uses a memory barrier.
|
||||
* Used for testing the cache. Regular clients won't need this.
|
||||
*/
|
||||
UBool allSoftReferences() const;
|
||||
int32_t getHardRefCount() const;
|
||||
|
||||
/**
|
||||
* If noHardReferences() == TRUE then this object has no hard references.
|
||||
* Must be called only from within the internals of UnifiedCache.
|
||||
*/
|
||||
inline UBool noHardReferences() const { return getHardRefCount() == 0; }
|
||||
|
||||
/**
|
||||
* If hasHardReferences() == TRUE then this object has hard references.
|
||||
* Must be called only from within the internals of UnifiedCache.
|
||||
*/
|
||||
inline UBool hasHardReferences() const { return getHardRefCount() != 0; }
|
||||
|
||||
/**
|
||||
* If noSoftReferences() == TRUE then this object has no soft references.
|
||||
* Must be called only from within the internals of UnifiedCache and
|
||||
* only while the cache global mutex is held.
|
||||
*/
|
||||
UBool noSoftReferences() const { return (softRefCount == 0); }
|
||||
|
||||
/**
|
||||
* Deletes this object if it has no references or soft references.
|
||||
*/
|
||||
void deleteIfZeroRefCount() const;
|
||||
|
||||
/**
|
||||
* @internal For UnifedCache use only to register this object with itself.
|
||||
* Must be called before this object is exposed to multiple threads.
|
||||
*/
|
||||
void registerWithCache(const UnifiedCacheBase *ptr) const {
|
||||
cachePtr = ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a writable version of ptr.
|
||||
* If there is exactly one owner, then ptr itself is returned as a
|
||||
|
@ -133,7 +218,15 @@ public:
|
|||
|
||||
private:
|
||||
mutable u_atomic_int32_t totalRefCount;
|
||||
mutable u_atomic_int32_t softRefCount;
|
||||
|
||||
// Any thread modifying softRefCount must hold the global cache mutex
|
||||
mutable int32_t softRefCount;
|
||||
|
||||
mutable u_atomic_int32_t hardRefCount;
|
||||
mutable const UnifiedCacheBase *cachePtr;
|
||||
void addRef(UBool withCacheLock) const;
|
||||
void removeRef(UBool withCacheLock) const;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -17,9 +17,6 @@
|
|||
#ifndef UBIDIIMP_H
|
||||
#define UBIDIIMP_H
|
||||
|
||||
/* set import/export definitions */
|
||||
#ifdef U_COMMON_IMPLEMENTATION
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/uchar.h"
|
||||
#include "ubidi_props.h"
|
||||
|
@ -468,5 +465,3 @@ ubidi_getMemory(BidiMemoryForAllocation *pMemory, int32_t *pSize, UBool mayAlloc
|
|||
TRUE, (length)*sizeof(Isolate))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2014, International Business Machines
|
||||
* Copyright (C) 1999-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -22,10 +22,6 @@
|
|||
#include "ubidiimp.h"
|
||||
#include "uassert.h"
|
||||
|
||||
#ifndef U_COMMON_IMPLEMENTATION
|
||||
#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General remarks about the functions in this file:
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2000-2011, International Business Machines
|
||||
* Copyright (C) 2000-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -17,11 +17,6 @@
|
|||
* the core algorithm and core API to write reordered text.
|
||||
*/
|
||||
|
||||
/* set import/export definitions */
|
||||
#ifndef U_COMMON_IMPLEMENTATION
|
||||
# define U_COMMON_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/uchar.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
********************************************************************************
|
||||
* Copyright (C) 1996-2013, International Business Machines
|
||||
* Copyright (C) 1996-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************************
|
||||
*/
|
||||
|
@ -164,10 +164,9 @@ ubrk_setText(UBreakIterator* bi,
|
|||
int32_t textLength,
|
||||
UErrorCode* status)
|
||||
{
|
||||
BreakIterator *brit = (BreakIterator *)bi;
|
||||
UText ut = UTEXT_INITIALIZER;
|
||||
utext_openUChars(&ut, text, textLength, status);
|
||||
brit->setText(&ut, *status);
|
||||
((BreakIterator*)bi)->setText(&ut, *status);
|
||||
// A stack allocated UText wrapping a UChar * string
|
||||
// can be dumped without explicitly closing it.
|
||||
}
|
||||
|
@ -179,8 +178,7 @@ ubrk_setUText(UBreakIterator *bi,
|
|||
UText *text,
|
||||
UErrorCode *status)
|
||||
{
|
||||
RuleBasedBreakIterator *brit = (RuleBasedBreakIterator *)bi;
|
||||
brit->RuleBasedBreakIterator::setText(text, *status);
|
||||
((BreakIterator*)bi)->setText(text, *status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,35 +189,35 @@ U_CAPI int32_t U_EXPORT2
|
|||
ubrk_current(const UBreakIterator *bi)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::current();
|
||||
return ((BreakIterator*)bi)->current();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_next(UBreakIterator *bi)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::next();
|
||||
return ((BreakIterator*)bi)->next();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_previous(UBreakIterator *bi)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::previous();
|
||||
return ((BreakIterator*)bi)->previous();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_first(UBreakIterator *bi)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::first();
|
||||
return ((BreakIterator*)bi)->first();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_last(UBreakIterator *bi)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::last();
|
||||
return ((BreakIterator*)bi)->last();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
@ -227,7 +225,7 @@ ubrk_preceding(UBreakIterator *bi,
|
|||
int32_t offset)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::preceding(offset);
|
||||
return ((BreakIterator*)bi)->preceding(offset);
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
@ -235,7 +233,7 @@ ubrk_following(UBreakIterator *bi,
|
|||
int32_t offset)
|
||||
{
|
||||
|
||||
return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::following(offset);
|
||||
return ((BreakIterator*)bi)->following(offset);
|
||||
}
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
|
@ -256,20 +254,20 @@ ubrk_countAvailable()
|
|||
U_CAPI UBool U_EXPORT2
|
||||
ubrk_isBoundary(UBreakIterator *bi, int32_t offset)
|
||||
{
|
||||
return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::isBoundary(offset);
|
||||
return ((BreakIterator*)bi)->isBoundary(offset);
|
||||
}
|
||||
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_getRuleStatus(UBreakIterator *bi)
|
||||
{
|
||||
return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatus();
|
||||
return ((BreakIterator*)bi)->getRuleStatus();
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status)
|
||||
{
|
||||
return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatusVec(fillInVec, capacity, *status);
|
||||
return ((BreakIterator*)bi)->getRuleStatusVec(fillInVec, capacity, *status);
|
||||
}
|
||||
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче