diff --git a/accessible/src/base/NotificationController.cpp b/accessible/src/base/NotificationController.cpp index 176761066ecb..651abef4527f 100644 --- a/accessible/src/base/NotificationController.cpp +++ b/accessible/src/base/NotificationController.cpp @@ -55,7 +55,7 @@ NotificationController::NotificationController(nsDocAccessible* aDocument, nsIPresShell* aPresShell) : mObservingState(eNotObservingRefresh), mDocument(aDocument), - mPresShell(aPresShell), mTreeConstructedState(eTreeConstructionPending) + mPresShell(aPresShell) { mTextHash.Init(); @@ -154,10 +154,6 @@ NotificationController::ScheduleContentInsertion(nsAccessible* aContainer, nsIContent* aStartChildNode, nsIContent* aEndChildNode) { - // Ignore content insertions until we constructed accessible tree. - if (mTreeConstructedState == eTreeConstructionPending) - return; - nsRefPtr insertion = new ContentInsertion(mDocument, aContainer); if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) && @@ -207,7 +203,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mObservingState = eRefreshProcessingForUpdate; // Initial accessible tree construction. - if (mTreeConstructedState == eTreeConstructionPending) { + if (!mDocument->HasLoadState(nsDocAccessible::eTreeConstructed)) { // If document is not bound to parent at this point then the document is not // ready yet (process notifications later). if (!mDocument->IsBoundToParent()) @@ -218,8 +214,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mDocument.get(), mDocument->GetDocumentNode()); #endif - mTreeConstructedState = eTreeConstructed; - mDocument->NotifyOfInitialUpdate(); + mDocument->DoInitialUpdate(); NS_ASSERTION(mContentInsertions.Length() == 0, "Pending content insertions while initial accessible tree isn't created!"); @@ -250,8 +245,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mTextHash.Clear(); // Bind hanging child documents. - PRUint32 childDocCount = mHangingChildDocuments.Length(); - for (PRUint32 idx = 0; idx < childDocCount; idx++) { + PRUint32 hangingDocCnt = mHangingChildDocuments.Length(); + for (PRUint32 idx = 0; idx < hangingDocCnt; idx++) { nsDocAccessible* childDoc = mHangingChildDocuments[idx]; nsIContent* ownerContent = mDocument->GetDocumentNode()-> @@ -271,6 +266,25 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) } mHangingChildDocuments.Clear(); + // If the document is ready and all its subdocuments are completely loaded + // then process the document load. + if (mDocument->HasLoadState(nsDocAccessible::eReady) && + !mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) && + hangingDocCnt == 0) { + PRUint32 childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0; + for (; childDocIdx < childDocCnt; childDocIdx++) { + nsDocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx); + if (!childDoc->HasLoadState(nsDocAccessible::eCompletelyLoaded)) + break; + } + + if (childDocIdx == childDocCnt) { + mDocument->ProcessLoad(); + if (!mDocument) + return; + } + } + // Process only currently queued generic notifications. nsTArray < nsRefPtr > notifications; notifications.SwapElements(mNotifications); @@ -310,10 +324,12 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) return; } - // Stop further processing if there are no newly queued insertions, - // notifications or events. + // Stop further processing if there are no new notifications of any kind or + // events and document load is processed. if (mContentInsertions.Length() == 0 && mNotifications.Length() == 0 && - mEvents.Length() == 0 && + mEvents.Length() == 0 && mTextHash.Count() == 0 && + mHangingChildDocuments.Length() == 0 && + mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) && mPresShell->RemoveRefreshObserver(this, Flush_Display)) { mObservingState = eNotObservingRefresh; } diff --git a/accessible/src/base/NotificationController.h b/accessible/src/base/NotificationController.h index 878ff56562d2..7a8e5a317726 100644 --- a/accessible/src/base/NotificationController.h +++ b/accessible/src/base/NotificationController.h @@ -127,14 +127,6 @@ public: NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController) - /** - * Return true when tree is constructed. - */ - inline bool IsTreeConstructed() - { - return mTreeConstructedState == eTreeConstructed; - } - /** * Shutdown the notification controller. */ @@ -155,11 +147,8 @@ public: */ inline void ScheduleTextUpdate(nsIContent* aTextNode) { - // Ignore the notification if initial tree construction hasn't been done yet. - if (mTreeConstructedState != eTreeConstructionPending && - mTextHash.PutEntry(aTextNode)) { + if (mTextHash.PutEntry(aTextNode)) ScheduleProcessing(); - } } /** @@ -299,17 +288,6 @@ private: */ nsIPresShell* mPresShell; - /** - * Indicate whether initial construction of the document's accessible tree - * performed or pending. When the document accessible is created then - * we construct its initial accessible tree. - */ - enum eTreeConstructedState { - eTreeConstructed, - eTreeConstructionPending - }; - eTreeConstructedState mTreeConstructedState; - /** * Child documents that needs to be bound to the tree. */ diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/nsAccDocManager.cpp index 776ac93d533b..63b90dd627fb 100644 --- a/accessible/src/base/nsAccDocManager.cpp +++ b/accessible/src/base/nsAccDocManager.cpp @@ -190,9 +190,6 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress, NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest, aStateFlags) - if (!IsEventTargetDocument(document)) - return NS_OK; - nsDocAccessible* docAcc = mDocAccessibleCache.GetWeak(document); if (!docAcc) return NS_OK; @@ -201,32 +198,17 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress, nsCOMPtr docShell(do_QueryInterface(webNav)); NS_ENSURE_STATE(docShell); - // Fire reload and state busy events on existing document accessible while - // event from user input flag can be calculated properly and accessible - // is alive. When new document gets loaded then this one is destroyed. + bool isReloading = false; PRUint32 loadType; docShell->GetLoadType(&loadType); if (loadType == LOAD_RELOAD_NORMAL || loadType == LOAD_RELOAD_BYPASS_CACHE || loadType == LOAD_RELOAD_BYPASS_PROXY || loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) { - - // Fire reload event. - nsRefPtr reloadEvent = - new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc); - nsEventShell::FireEvent(reloadEvent); + isReloading = true; } - // Mark the document accessible as loading, if it stays alive then we'll mark - // it as loaded when we receive proper notification. - docAcc->MarkAsLoading(); - - // Fire state busy change event. Use delayed event since we don't care - // actually if event isn't delivered when the document goes away like a shot. - nsRefPtr stateEvent = - new AccStateChangeEvent(document, states::BUSY, PR_TRUE); - docAcc->FireDelayedAccessibleEvent(stateEvent); - + docAcc->NotifyOfLoading(isReloading); return NS_OK; } @@ -338,54 +320,7 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument, return; } - // Mark the document as loaded to drop off the busy state flag on it. - docAcc->MarkAsLoaded(); - - // Do not fire document complete/stop events for root chrome document - // accessibles and for frame/iframe documents because - // a) screen readers start working on focus event in the case of root chrome - // documents - // b) document load event on sub documents causes screen readers to act is if - // entire page is reloaded. - if (!IsEventTargetDocument(aDocument)) - return; - - // Fire complete/load stopped if the load event type is given. - if (aLoadEventType) { - nsRefPtr loadEvent = new AccEvent(aLoadEventType, aDocument); - docAcc->FireDelayedAccessibleEvent(loadEvent); - } - - // Fire busy state change event. - nsRefPtr stateEvent = - new AccStateChangeEvent(aDocument, states::BUSY, PR_FALSE); - docAcc->FireDelayedAccessibleEvent(stateEvent); -} - -PRBool -nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const -{ - nsCOMPtr container = aDocument->GetContainer(); - nsCOMPtr docShellTreeItem = - do_QueryInterface(container); - NS_ASSERTION(docShellTreeItem, "No document shell for document!"); - - nsCOMPtr parentTreeItem; - docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem)); - - // It's not a root document. - if (parentTreeItem) { - nsCOMPtr sameTypeRoot; - docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot)); - - // It's not a sub document, i.e. a frame or iframe. - return (sameTypeRoot == docShellTreeItem); - } - - // It's not chrome root document. - PRInt32 contentType; - docShellTreeItem->GetItemType(&contentType); - return (contentType == nsIDocShellTreeItem::typeContent); + docAcc->NotifyOfLoad(aLoadEventType); } void diff --git a/accessible/src/base/nsAccDocManager.h b/accessible/src/base/nsAccDocManager.h index f17148f15d5c..5605500b721f 100644 --- a/accessible/src/base/nsAccDocManager.h +++ b/accessible/src/base/nsAccDocManager.h @@ -120,24 +120,6 @@ private: void HandleDOMDocumentLoad(nsIDocument *aDocument, PRUint32 aLoadEventType); - /** - * Return true if accessibility events accompanying document accessible - * loading should be fired. - * - * The rules are: do not fire events for root chrome document accessibles and - * for sub document accessibles (like HTML frame of iframe) of the loading - * document accessible. - * - * XXX: in general AT expect events for document accessible loading into - * tabbrowser, events from other document accessibles may break AT. We need to - * figure out what AT wants to know about loading page (for example, some of - * them have separate processing of iframe documents on the page and therefore - * they need a way to distinguish sub documents from page document). Ideally - * we should make events firing for any loaded document and provide additional - * info AT are needing. - */ - PRBool IsEventTargetDocument(nsIDocument *aDocument) const; - /** * Add 'pagehide' and 'DOMContentLoaded' event listeners. */ diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index 1e74d2684e2f..ae4ce4cc0712 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -105,7 +105,8 @@ nsDocAccessible:: nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent, nsIWeakReference *aShell) : nsHyperTextAccessibleWrap(aRootContent, aShell), - mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE) + mDocument(aDocument), mScrollPositionChangedTicks(0), + mLoadState(eTreeConstructionPending), mLoadEventType(0) { mFlags |= eDocAccessible; @@ -309,11 +310,16 @@ nsDocAccessible::NativeState() state |= states::FOCUSED; } - // Expose state busy until the document is loaded or tree is constructed. - if (!mIsLoaded || !mNotificationController->IsTreeConstructed()) { - state |= states::BUSY | states::STALE; - } - + // Expose stale state until the document is ready (DOM is loaded and tree is + // constructed). + if (!HasLoadState(eReady)) + state |= states::STALE; + + // Expose state busy until the document and all its subdocuments is completely + // loaded. + if (!HasLoadState(eCompletelyLoaded)) + state |= states::BUSY; + nsIFrame* frame = GetFrame(); if (!frame || !nsCoreUtils::CheckVisibilityInParentChain(frame)) { state |= states::INVISIBLE | states::OFFSCREEN; @@ -605,7 +611,7 @@ nsDocAccessible::Init() // this point (this can happen because a11y is started late or DOM document // having no container was loaded. if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) - mIsLoaded = PR_TRUE; + mLoadState |= eDOMLoaded; AddEventListeners(); return PR_TRUE; @@ -1376,8 +1382,9 @@ nsDocAccessible::ContentInserted(nsIContent* aContainerNode, nsIContent* aStartChildNode, nsIContent* aEndChildNode) { - /// Pend tree update on content insertion until layout. - if (mNotificationController) { + // Ignore content insertions until we constructed accessible tree. Otherwise + // schedule tree update on content insertion after layout. + if (mNotificationController && HasLoadState(eTreeConstructed)) { // Update the whole tree of this document accessible when the container is // null (document element is inserted or removed). nsAccessible* container = aContainerNode ? @@ -1467,8 +1474,36 @@ nsDocAccessible::CacheChildren() // Protected members void -nsDocAccessible::NotifyOfInitialUpdate() +nsDocAccessible::NotifyOfLoading(bool aIsReloading) { + // Mark the document accessible as loading, if it stays alive then we'll mark + // it as loaded when we receive proper notification. + mLoadState &= ~eDOMLoaded; + + if (!IsLoadEventTarget()) + return; + + if (aIsReloading) { + // Fire reload and state busy events on existing document accessible while + // event from user input flag can be calculated properly and accessible + // is alive. When new document gets loaded then this one is destroyed. + nsRefPtr reloadEvent = + new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, this); + nsEventShell::FireEvent(reloadEvent); + } + + // Fire state busy change event. Use delayed event since we don't care + // actually if event isn't delivered when the document goes away like a shot. + nsRefPtr stateEvent = + new AccStateChangeEvent(mDocument, states::BUSY, PR_TRUE); + FireDelayedAccessibleEvent(stateEvent); +} + +void +nsDocAccessible::DoInitialUpdate() +{ + mLoadState |= eTreeConstructed; + // The content element may be changed before the initial update and then we // miss the notification (since content tree change notifications are ignored // prior to initial update). Make sure the content element is valid. @@ -1491,6 +1526,34 @@ nsDocAccessible::NotifyOfInitialUpdate() } } +void +nsDocAccessible::ProcessLoad() +{ + mLoadState |= eCompletelyLoaded; + + // Do not fire document complete/stop events for root chrome document + // accessibles and for frame/iframe documents because + // a) screen readers start working on focus event in the case of root chrome + // documents + // b) document load event on sub documents causes screen readers to act is if + // entire page is reloaded. + if (!IsLoadEventTarget()) + return; + + // Fire complete/load stopped if the load event type is given. + if (mLoadEventType) { + nsRefPtr loadEvent = new AccEvent(mLoadEventType, this); + nsEventShell::FireEvent(loadEvent); + + mLoadEventType = 0; + } + + // Fire busy state change event. + nsRefPtr stateEvent = + new AccStateChangeEvent(this, states::BUSY, PR_FALSE); + nsEventShell::FireEvent(stateEvent); +} + void nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider, nsIAtom* aRelAttr) @@ -1964,3 +2027,30 @@ nsDocAccessible::ShutdownChildrenInSubtree(nsAccessible* aAccessible) UnbindFromDocument(aAccessible); } + +bool +nsDocAccessible::IsLoadEventTarget() const +{ + nsCOMPtr container = mDocument->GetContainer(); + nsCOMPtr docShellTreeItem = + do_QueryInterface(container); + NS_ASSERTION(docShellTreeItem, "No document shell for document!"); + + nsCOMPtr parentTreeItem; + docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem)); + + // It's not a root document. + if (parentTreeItem) { + nsCOMPtr sameTypeRoot; + docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot)); + + // It's not a sub document, i.e. a frame or iframe. + return (sameTypeRoot == docShellTreeItem); + } + + // It's not chrome root document. + PRInt32 contentType; + docShellTreeItem->GetItemType(&contentType); + return (contentType == nsIDocShellTreeItem::typeContent); +} + diff --git a/accessible/src/base/nsDocAccessible.h b/accessible/src/base/nsDocAccessible.h index 2a82c88a0b7b..7e12efe72e25 100644 --- a/accessible/src/base/nsDocAccessible.h +++ b/accessible/src/base/nsDocAccessible.h @@ -134,19 +134,34 @@ public: */ PRBool IsContentLoaded() const { + // eDOMLoaded flag check is used for error pages as workaround to make this + // method return correct result since error pages do not receive 'pageshow' + // event and as consequence nsIDocument::IsShowing() returns false. return mDocument && mDocument->IsVisible() && - (mDocument->IsShowing() || mIsLoaded); + (mDocument->IsShowing() || HasLoadState(eDOMLoaded)); } /** - * Marks this document as loaded or loading, used to expose busy state. - * The loaded flag has special meaning for error pages and used as workaround - * to make IsContentLoaded() return correct result since these pages do not - * receive pageshow event and as consequence nsIDocument::IsShowing() returns - * false. + * Document load states. */ - void MarkAsLoaded() { mIsLoaded = PR_TRUE; } - void MarkAsLoading() { mIsLoaded = PR_FALSE; } + enum LoadState { + // initial tree construction is pending + eTreeConstructionPending = 0, + // initial tree construction done + eTreeConstructed = 1, + // DOM document is loaded. + eDOMLoaded = 1 << 1, + // document is ready + eReady = eTreeConstructed | eDOMLoaded, + // document and all its subdocuments are ready + eCompletelyLoaded = eReady | 1 << 2 + }; + + /** + * Return true if the document has given document state. + */ + bool HasLoadState(LoadState aState) const + { return (mLoadState & aState) == aState; } /** * Return a native window handler or pointer depending on platform. @@ -326,7 +341,8 @@ public: { NS_ASSERTION(mNotificationController, "The document was shut down!"); - if (mNotificationController) + // Ignore the notification if initial tree construction hasn't been done yet. + if (mNotificationController && HasLoadState(eTreeConstructed)) mNotificationController->ScheduleTextUpdate(aTextNode); } @@ -346,10 +362,29 @@ protected: virtual nsresult RemoveEventListeners(); /** - * Notify this document that was bound to the accessible document tree. + * Marks this document as loaded or loading. + */ + inline void NotifyOfLoad(PRUint32 aLoadEventType) + { + mLoadState |= eDOMLoaded; + mLoadEventType = aLoadEventType; + } + + void NotifyOfLoading(bool aIsReloading); + + friend class nsAccDocManager; + + /** + * Perform initial update (create accessible tree). * Can be overridden by wrappers to prepare initialization work. */ - virtual void NotifyOfInitialUpdate(); + virtual void DoInitialUpdate(); + + /** + * Process document load notification, fire document load and state busy + * events if applicable. + */ + void ProcessLoad(); void AddScrollListener(); void RemoveScrollListener(); @@ -483,6 +518,24 @@ protected: */ void ShutdownChildrenInSubtree(nsAccessible *aAccessible); + /** + * Return true if accessibility events accompanying document accessible + * loading should be fired. + * + * The rules are: do not fire events for root chrome document accessibles and + * for sub document accessibles (like HTML frame of iframe) of the loading + * document accessible. + * + * XXX: in general AT expect events for document accessible loading into + * tabbrowser, events from other document accessibles may break AT. We need to + * figure out what AT wants to know about loading page (for example, some of + * them have separate processing of iframe documents on the page and therefore + * they need a way to distinguish sub documents from page document). Ideally + * we should make events firing for any loaded document and provide additional + * info AT are needing. + */ + bool IsLoadEventTarget() const; + /** * Used to fire scrolling end event after page scroll. * @@ -491,6 +544,8 @@ protected: */ static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure); +protected: + /** * Cache of accessibles within this document accessible. */ @@ -502,12 +557,15 @@ protected: nsCOMPtr mScrollWatchTimer; PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events -protected: + /** + * Bit mask of document load states (@see LoadState). + */ + PRUint32 mLoadState; /** - * Specifies if the document was loaded, used for error pages only. + * Type of document load event fired after the document is loaded completely. */ - PRPackedBool mIsLoaded; + PRUint32 mLoadEventType; static PRUint64 gLastFocusedAccessiblesState; diff --git a/accessible/src/base/nsRootAccessible.h b/accessible/src/base/nsRootAccessible.h index 56ee2453ac93..9555a6c7f816 100644 --- a/accessible/src/base/nsRootAccessible.h +++ b/accessible/src/base/nsRootAccessible.h @@ -49,8 +49,7 @@ #include "nsHashtable.h" #include "nsCaretAccessible.h" #include "nsIDocument.h" -#include "nsIDOMFocusListener.h" -#include "nsIDOMFormListener.h" +#include "nsIDOMEventListener.h" #define NS_ROOTACCESSIBLE_IMPL_CID \ { /* eaba2cf0-21b1-4e2b-b711-d3a89dcd5e1a */ \ diff --git a/accessible/src/msaa/nsDocAccessibleWrap.cpp b/accessible/src/msaa/nsDocAccessibleWrap.cpp index a2a92f925a24..b64cf2f6a48f 100644 --- a/accessible/src/msaa/nsDocAccessibleWrap.cpp +++ b/accessible/src/msaa/nsDocAccessibleWrap.cpp @@ -268,9 +268,9 @@ nsDocAccessibleWrap::GetNativeWindow() const // nsDocAccessible protected void -nsDocAccessibleWrap::NotifyOfInitialUpdate() +nsDocAccessibleWrap::DoInitialUpdate() { - nsDocAccessible::NotifyOfInitialUpdate(); + nsDocAccessible::DoInitialUpdate(); if (nsWinUtils::IsWindowEmulationStarted()) { // Create window for tab document. diff --git a/accessible/src/msaa/nsDocAccessibleWrap.h b/accessible/src/msaa/nsDocAccessibleWrap.h index 1c541ef9cc4f..a932e925665d 100644 --- a/accessible/src/msaa/nsDocAccessibleWrap.h +++ b/accessible/src/msaa/nsDocAccessibleWrap.h @@ -97,7 +97,7 @@ public: protected: // nsDocAccessible - virtual void NotifyOfInitialUpdate(); + virtual void DoInitialUpdate(); protected: void* mHWND; diff --git a/accessible/tests/mochitest/relations/test_tabbrowser.xul b/accessible/tests/mochitest/relations/test_tabbrowser.xul index 89f347fc6ad7..d9fb315a2a87 100644 --- a/accessible/tests/mochitest/relations/test_tabbrowser.xul +++ b/accessible/tests/mochitest/relations/test_tabbrowser.xul @@ -65,7 +65,7 @@ if (this.reorderCnt == docURIs.length) { unregisterA11yEventListener(EVENT_REORDER, this); - testAccTree(); + testRelations(); } }, diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc index 6bfe0e02ffba..c69d7bd0f0fd 100644 --- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -36,6 +36,7 @@ # # ***** END LICENSE BLOCK ***** + diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index 5e13fac7baf4..e4b785d1345e 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -220,6 +220,7 @@ # Mac: Cmd+K (cross platform binding) # Cmd+Opt+F (platform convention) # Win: Ctrl+K (cross platform binding) +# Ctrl+E (IE compat) # # We support Ctrl+K on all platforms now and advertise it in the menu since it is # our standard - it is a "safe" choice since it is near no harmful keys like "W" as @@ -232,6 +233,9 @@ #ifdef XP_MACOSX #endif +#ifdef XP_WIN + +#endif #ifdef XP_GNOME diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 3478c212edcb..81be94c47644 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -216,6 +216,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter", "nsICrashReporter"); #endif +XPCOMUtils.defineLazyGetter(this, "PageMenu", function() { + let tmp = {}; + Cu.import("resource://gre/modules/PageMenu.jsm", tmp); + return new tmp.PageMenu(); +}); + /** * We can avoid adding multiple load event listeners and save some time by adding * one listener that calls all real handlers. diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 5355ed502ff0..2251cdb944cc 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -273,10 +273,10 @@ oncommand="BrowserFullScreen();"/> - - + diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js index 2464be585d24..627d80154227 100644 --- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -61,14 +61,14 @@ # # ***** END LICENSE BLOCK ***** -function nsContextMenu(aXulMenu, aBrowser) { +function nsContextMenu(aXulMenu, aBrowser, aIsShift) { this.shouldDisplay = true; - this.initMenu(aBrowser); + this.initMenu(aBrowser, aXulMenu, aIsShift); } // Prototype for nsContextMenu "class." nsContextMenu.prototype = { - initMenu: function CM_initMenu(aBrowser) { + initMenu: function CM_initMenu(aBrowser, aXulMenu, aIsShift) { // Get contextual info. this.setTarget(document.popupNode, document.popupRangeParent, document.popupRangeOffset); @@ -76,6 +76,12 @@ nsContextMenu.prototype = { return; this.browser = aBrowser; + + this.hasPageMenu = false; + if (!aIsShift) { + this.hasPageMenu = PageMenu.init(this.target, aXulMenu); + } + this.isFrameImage = document.getElementById("isFrameImage"); this.ellipsis = "\u2026"; try { @@ -90,6 +96,7 @@ nsContextMenu.prototype = { }, initItems: function CM_initItems() { + this.initPageMenuSeparator(); this.initOpenItems(); this.initNavigationItems(); this.initViewItems(); @@ -100,6 +107,10 @@ nsContextMenu.prototype = { this.initMediaPlayerItems(); }, + initPageMenuSeparator: function CM_initPageMenuSeparator() { + this.showItem("page-menu-separator", this.hasPageMenu); + }, + initOpenItems: function CM_initOpenItems() { var isMailtoInternal = false; if (this.onMailtoLink) { diff --git a/browser/base/content/tabview/groupitems.js b/browser/base/content/tabview/groupitems.js index bd7a55d11743..69329a3e5b4c 100644 --- a/browser/base/content/tabview/groupitems.js +++ b/browser/base/content/tabview/groupitems.js @@ -2233,12 +2233,14 @@ let GroupItems = { // Function: groupItemStorageSanity // Given persistent storage data for a groupItem, returns true if it appears to not be damaged. groupItemStorageSanity: function GroupItems_groupItemStorageSanity(groupItemData) { - // TODO: check everything - // Bug 586555 - var sane = true; - if (!Utils.isRect(groupItemData.bounds)) { + let sane = true; + if (!groupItemData.bounds || !Utils.isRect(groupItemData.bounds)) { Utils.log('GroupItems.groupItemStorageSanity: bad bounds', groupItemData.bounds); sane = false; + } else if ((groupItemData.userSize && + !Utils.isPoint(groupItemData.userSize)) || + !groupItemData.id) { + sane = false; } return sane; diff --git a/browser/base/content/test/subtst_contextmenu.html b/browser/base/content/test/subtst_contextmenu.html index caaf143dff0f..18358a93b69b 100644 --- a/browser/base/content/test/subtst_contextmenu.html +++ b/browser/base/content/test/subtst_contextmenu.html @@ -21,6 +21,40 @@ Browser context menu subtest.
chssseefsbbbie
+
+

I've got a context menu!

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/browser/base/content/test/test_contextmenu.html b/browser/base/content/test/test_contextmenu.html index 0d842ea6e448..87917954d4c5 100644 --- a/browser/base/content/test/test_contextmenu.html +++ b/browser/base/content/test/test_contextmenu.html @@ -24,11 +24,11 @@ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); const Cc = Components.classes; const Ci = Components.interfaces; -function openContextMenuFor(element) { +function openContextMenuFor(element, shiftkey) { // Context menu should be closed before we open it again. is(contextMenu.state, "closed", "checking if popup is closed"); - var eventDetails = { type : "contextmenu", button : 2 }; + var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey }; synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView); } @@ -50,7 +50,15 @@ function executeCopyCommand(command, expectedValue) is(input.value, expectedValue, "paste for command " + command); } -function getVisibleMenuItems(aMenu) { +function invokeItemAction(ident) +{ + var item = contextMenu.getElementsByAttribute("ident", ident)[0]; + ok(item, "Got generated XUL menu item"); + item.doCommand(); + is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed"); +} + +function getVisibleMenuItems(aMenu, aData) { var items = []; var accessKeys = {}; for (var i = 0; i < aMenu.childNodes.length; i++) { @@ -62,10 +70,14 @@ function getVisibleMenuItems(aMenu) { if (key) key = key.toLowerCase(); + var isGenerated = item.hasAttribute("generated"); + if (item.nodeName == "menuitem") { var isSpellSuggestion = item.className == "spell-suggestion"; if (isSpellSuggestion) { is(item.id, "", "child menuitem #" + i + " is a spelling suggestion"); + } else if (isGenerated) { + is(item.id, "", "child menuitem #" + i + " is a generated item"); } else { ok(item.id, "child menuitem #" + i + " has an ID"); } @@ -74,6 +86,8 @@ function getVisibleMenuItems(aMenu) { if (isSpellSuggestion) { is(key, "", "Spell suggestions shouldn't have an access key"); items.push("*" + label); + } else if (isGenerated) { + items.push("+" + label); } else if (item.id.indexOf("spell-check-dictionary-") != 0 && item.id != "spell-no-suggestions") { ok(key, "menuitem " + item.id + " has an access key"); @@ -82,21 +96,35 @@ function getVisibleMenuItems(aMenu) { else accessKeys[key] = item.id; } - if (!isSpellSuggestion) { + if (!isSpellSuggestion && !isGenerated) { items.push(item.id); } - items.push(!item.disabled); + if (isGenerated) { + var p = {}; + p.type = item.getAttribute("type"); + p.icon = item.getAttribute("image"); + p.checked = item.hasAttribute("checked"); + p.disabled = item.hasAttribute("disabled"); + items.push(p); + } else { + items.push(!item.disabled); + } } else if (item.nodeName == "menuseparator") { ok(true, "--- seperator id is " + item.id); items.push("---"); items.push(null); } else if (item.nodeName == "menu") { + if (isGenerated) { + item.id = "generated-submenu-" + aData.generatedSubmenuId++; + } ok(item.id, "child menu #" + i + " has an ID"); - ok(key, "menu has an access key"); - if (accessKeys[key]) - ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]); - else - accessKeys[key] = item.id; + if (!isGenerated) { + ok(key, "menu has an access key"); + if (accessKeys[key]) + ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]); + else + accessKeys[key] = item.id; + } items.push(item.id); items.push(!item.disabled); // Add a dummy item to that the indexes in checkMenu are the same @@ -113,7 +141,8 @@ function getVisibleMenuItems(aMenu) { function checkContextMenu(expectedItems) { is(contextMenu.state, "open", "checking if popup is open"); - checkMenu(contextMenu, expectedItems); + var data = { generatedSubmenuId: 1 }; + checkMenu(contextMenu, expectedItems, data); } /* @@ -129,8 +158,8 @@ function checkContextMenu(expectedItems) { * "lol", false] // item disabled * */ -function checkMenu(menu, expectedItems) { - var actualItems = getVisibleMenuItems(menu); +function checkMenu(menu, expectedItems, data) { + var actualItems = getVisibleMenuItems(menu, data); //ok(false, "Items are: " + actualItems); for (var i = 0; i < expectedItems.length; i+=2) { var actualItem = actualItems[i]; @@ -142,11 +171,40 @@ function checkMenu(menu, expectedItems) { var menuID = expectedItems[i - 2]; // The last item was the menu ID. var submenu = menu.getElementsByAttribute("id", menuID)[0]; ok(submenu && submenu.nodeName == "menu", "got expected submenu element"); - checkMenu(submenu.menupopup, expectedItem); + checkMenu(submenu.menupopup, expectedItem, data); } else { is(actualItem, expectedItem, "checking item #" + i/2 + " (" + expectedItem + ") name"); - if (expectedEnabled != null) + + if (typeof expectedEnabled == "object" && expectedEnabled != null || + typeof actualEnabled == "object" && actualEnabled != null) { + + ok(!(actualEnabled == null), "actualEnabled is not null"); + ok(!(expectedEnabled == null), "expectedEnabled is not null"); + is(typeof actualEnabled, typeof expectedEnabled, "checking types"); + + if (typeof actualEnabled != typeof expectedEnabled || + actualEnabled == null || expectedEnabled == null) + continue; + + is(actualEnabled.type, expectedEnabled.type, + "checking item #" + i/2 + " (" + expectedItem + ") type attr value"); + var icon = actualEnabled.icon; + if (icon) { + var tmp = ""; + var j = icon.length - 1; + while (j && icon[j] != "/") { + tmp = icon[j--] + tmp; + } + icon = tmp; + } + is(icon, expectedEnabled.icon, + "checking item #" + i/2 + " (" + expectedItem + ") icon attr value"); + is(actualEnabled.checked, expectedEnabled.checked, + "checking item #" + i/2 + " (" + expectedItem + ") has checked attr"); + is(actualEnabled.disabled, expectedEnabled.disabled, + "checking item #" + i/2 + " (" + expectedItem + ") has disabled attr"); + } else if (expectedEnabled != null) is(actualEnabled, expectedEnabled, "checking item #" + i/2 + " (" + expectedItem + ") enabled state"); } @@ -408,9 +466,70 @@ function runTest(testNum) { openContextMenuFor(link); // Invoke context menu for next test. break; - case 15: + case 15: executeCopyCommand("cmd_copyLink", "http://mozilla.com/"); closeContextMenu(); + openContextMenuFor(pagemenu); // Invoke context menu for next test. + break; + + case 16: + // Context menu for element with assigned content context menu + checkContextMenu(["+Plain item", {type: "", icon: "", checked: false, disabled: false}, + "+Disabled item", {type: "", icon: "", checked: false, disabled: true}, + "---", null, + "+Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false}, + "---", null, + "+Radio1", {type: "checkbox", icon: "", checked: true, disabled: false}, + "+Radio2", {type: "checkbox", icon: "", checked: false, disabled: false}, + "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false}, + "---", null, + "+Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false}, + "+Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false}, + "---", null, + "generated-submenu-1", true, + ["+Radio1", {type: "checkbox", icon: "", checked: false, disabled: false}, + "+Radio2", {type: "checkbox", icon: "", checked: true, disabled: false}, + "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false}, + "---", null, + "+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null, + "---", null, + "context-back", false, + "context-forward", false, + "context-reload", true, + "context-stop", false, + "---", null, + "context-bookmarkpage", true, + "context-savepage", true, + "context-sendpage", true, + "---", null, + "context-viewbgimage", false, + "context-selectall", true, + "---", null, + "context-viewsource", true, + "context-viewinfo", true]); + + invokeItemAction("0"); + closeContextMenu(); + openContextMenuFor(pagemenu, true); // Invoke context menu for next test. + break; + + case 17: + // Context menu for element with assigned content context menu + // The shift key should bypass content context menu processing + checkContextMenu(["context-back", false, + "context-forward", false, + "context-reload", true, + "context-stop", false, + "---", null, + "context-bookmarkpage", true, + "context-savepage", true, + "context-sendpage", true, + "---", null, + "context-viewbgimage", false, + "context-selectall", true, + "---", null, + "context-viewsource", true, + "context-viewinfo", true]); subwindow.close(); SimpleTest.finish(); @@ -437,7 +556,7 @@ function runTest(testNum) { var testNum = 1; var subwindow, chromeWin, contextMenu; var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2, - iframe, textarea, contenteditable, inputspell; + iframe, textarea, contenteditable, inputspell, pagemenu; function startTest() { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); @@ -470,6 +589,7 @@ function startTest() { textarea = subwindow.document.getElementById("test-textarea"); contenteditable = subwindow.document.getElementById("test-contenteditable"); inputspell = subwindow.document.getElementById("test-input-spellcheck"); + pagemenu = subwindow.document.getElementById("test-pagemenu"); contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false); runTest(1); diff --git a/browser/base/content/web-panels.xul b/browser/base/content/web-panels.xul index 93630bf84769..f5515240a28d 100644 --- a/browser/base/content/web-panels.xul +++ b/browser/base/content/web-panels.xul @@ -80,10 +80,10 @@ - Mac: Cmd+K (cross platform binding) Cmd+Opt+F (platform convention) Win: Ctrl+K (cross platform binding) + Ctrl+E (IE compat) We support Ctrl+K on all platforms now and advertise it in the menu since it is our standard - it is a "safe" choice since it is near no harmful keys like "W" as @@ -320,6 +321,7 @@ can reach it easily. --> --> + diff --git a/browser/themes/pinstripe/browser/Toolbar-lion.png b/browser/themes/pinstripe/browser/Toolbar-lion.png new file mode 100644 index 000000000000..a65aa30ebae6 Binary files /dev/null and b/browser/themes/pinstripe/browser/Toolbar-lion.png differ diff --git a/browser/themes/pinstripe/browser/browser.css b/browser/themes/pinstripe/browser/browser.css index 62c5fd41ce04..69b707f03d94 100644 --- a/browser/themes/pinstripe/browser/browser.css +++ b/browser/themes/pinstripe/browser/browser.css @@ -88,8 +88,8 @@ #PersonalToolbar { -moz-appearance: none; - margin-top: -1px; /* overlay the bottom border of the toolbar above us */ - padding-top: 0 !important; + margin-top: -2px; /* overlay the bottom border of the toolbar above us */ + padding-top: 1px !important; background-color: -moz-mac-chrome-active; border-bottom: 1px solid rgba(0, 0, 0, 0.57); } @@ -293,21 +293,22 @@ toolbarbutton.bookmark-item > menupopup { .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker, #restore-button { -moz-box-orient: vertical; - padding: 0 3px; + -moz-appearance: toolbarbutton; height: 22px; - border: 1px solid @toolbarbuttonBorderColor@; - border-radius: @toolbarbuttonCornerRadius@; - box-shadow: 0 1px rgba(255, 255, 255, 0.2); - background: @toolbarbuttonBackground@; - background-origin: border-box; + padding: 0; + border: 0; } .toolbarbutton-1:not([type="menu-button"]):-moz-lwtheme, .toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-lwtheme, .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-lwtheme, #restore-button:-moz-lwtheme { - border-color: rgba(0, 0, 0, 0.4); - background-image: -moz-linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.2) 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.2)); + -moz-appearance: none; + padding: 0 3px; + border: 1px solid rgba(0, 0, 0, 0.4); + border-radius: @toolbarbuttonCornerRadius@; + background: -moz-linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.2) 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.2)) repeat-x; + background-origin: border-box; box-shadow: inset 0 1px rgba(255,255,255,0.3), 0 1px rgba(255,255,255,0.2); } @@ -337,6 +338,7 @@ toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]), toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-button, toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker, toolbar:not([mode="icons"]) #restore-button { + -moz-appearance: none; padding: 0; height: auto; border: none; @@ -408,16 +410,6 @@ toolbar:not([mode="icons"]) .toolbarbutton-1:not([open="true"]) > .toolbarbutton margin: 2px 0 0; } -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):active:hover:not(:-moz-lwtheme), -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"])[open="true"]:not(:-moz-lwtheme), -toolbar[mode="icons"] .toolbarbutton-1:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover:not(:-moz-lwtheme), -toolbar[mode="icons"] .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme), -toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover:not(:-moz-lwtheme) { - background: @toolbarbuttonPressedBackgroundColor@; - text-shadow: @loweredShadow@; - box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@; -} - toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):active:hover:-moz-lwtheme, toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"])[open="true"]:-moz-lwtheme, toolbar[mode="icons"] .toolbarbutton-1:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover:-moz-lwtheme, @@ -428,39 +420,16 @@ toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover:-moz-l box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2); } -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not(:-moz-lwtheme) { - background: #606060; - box-shadow: inset #2A2A2A 0 3px 3.5px, @loweredShadow@; -} - toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:-moz-lwtheme { background-color: rgba(0,0,0,0.4); box-shadow: inset 0 2px 5px rgba(0,0,0,0.7), 0 1px rgba(255,255,255,0.2); } -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not([disabled="true"]):active:hover:not(:-moz-lwtheme) { - background: #4E4E4E; - box-shadow: inset #1c1c1c 0 3px 3.5px; -} - toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not([disabled="true"]):active:hover:-moz-lwtheme { background-color: rgba(0, 0, 0, 0.6); box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.8), 0 1px rgba(255, 255, 255, 0.2); } -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):-moz-window-inactive:not(:-moz-lwtheme), -toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-window-inactive:not(:-moz-lwtheme), -toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-window-inactive:not(:-moz-lwtheme), -toolbar[mode="icons"] #restore-button:-moz-window-inactive:not(:-moz-lwtheme) { - border-color: @toolbarbuttonInactiveBorderColor@; - background-image: @toolbarbuttonInactiveBackgroundImage@; -} - -toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:-moz-window-inactive { - background: #8E8E8E; - box-shadow: inset rgba(0, 0, 0, 0.5) 0 3px 3.5px, @loweredShadow@; -} - toolbar[mode="icons"] .toolbarbutton-1 > menupopup { margin-top: 1px; } @@ -477,17 +446,28 @@ toolbar[mode="icons"] .toolbarbutton-1 > menupopup { } #back-button, -toolbar:not([mode="icons"]) #forward-button:-moz-locale-dir(rtl) { +#forward-button:-moz-locale-dir(rtl), +toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl):-moz-lwtheme { -moz-image-region: rect(0, 40px, 20px, 20px); } #forward-button, -toolbar:not([mode="icons"]) #back-button:-moz-locale-dir(rtl) { +#back-button:-moz-locale-dir(rtl), +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-locale-dir(rtl), +toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl):-moz-lwtheme { -moz-image-region: rect(0, 60px, 20px, 40px); } +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-locale-dir(rtl), +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-locale-dir(rtl), +toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl):-moz-lwtheme, +toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl):-moz-lwtheme { + -moz-transform: scaleX(-1); +} + #navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button { - -moz-margin-end: -5px; + -moz-appearance: none; + -moz-margin-end: -7px; position: relative; z-index: 1; -moz-image-region: rect(0, 20px, 20px, 0); @@ -497,31 +477,45 @@ toolbar:not([mode="icons"]) #back-button:-moz-locale-dir(rtl) { border-radius: 10000px; } -toolbar[mode="icons"] #back-button:-moz-locale-dir(rtl), -toolbar[mode="icons"] #forward-button:-moz-locale-dir(rtl) { - -moz-transform: scaleX(-1); +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not(:-moz-lwtheme) { + height: 31px; + padding: 4px 5px 5px 3px; + margin-bottom: -1px; + background: url(chrome://browser/skin/keyhole-circle.png) 0 0 no-repeat; +} + +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:-moz-window-inactive:not(:-moz-lwtheme) { + background-position: -60px 0; +} + +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):active:hover:not(:-moz-lwtheme), +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"]:not(:-moz-lwtheme) { + background-position: -30px 0; } toolbar[mode="icons"] #forward-button { -moz-margin-start: 0; } -#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button { - /* 1px to the right */ - padding-left: 4px; - padding-right: 2px; +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button > .toolbarbutton-icon { + /* shift the icon away from the back button */ + margin-left: 3px; + margin-right: -1px; } -#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-lwtheme { +#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button { mask: url(chrome://browser/content/browser.xul#pinstripe-keyhole-forward-mask); } #navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #forward-button { width: 27px; +} + +#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #forward-button:-moz-lwtheme { padding-left: 2px; } -toolbar[mode="icons"] #forward-button { +toolbar[mode="icons"] #forward-button:-moz-lwtheme { border-top-left-radius: 0; border-bottom-left-radius: 0; } @@ -529,6 +523,9 @@ toolbar[mode="icons"] #forward-button { #navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #back-button { -moz-margin-end: 0; width: 26px; +} + +#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #back-button:-moz-lwtheme { padding-right: 2px; border-right-width: 0; border-top-right-radius: 0; @@ -1776,34 +1773,35 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { background-repeat: repeat-x; } -#TabsToolbar:not(:-moz-lwtheme) { - background-color: -moz-mac-chrome-active; -} - -#TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive { - background-color: -moz-mac-chrome-inactive; -} - #TabsToolbar[tabsontop="false"] { - margin-top: -1px; + margin-top: -2px; padding-top: 2px; } +/* For tabs-on-top, only fill the bottom 2px with the chrome background + * color, so that the borders in tabbar-top-bg-*.png can mix with it. + * In the top 24px the unified toolbar (from the ::before above) will show. + */ #TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme) { padding-bottom: 2px; - background-image: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-active.png) ; + background: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-active.png), + -moz-linear-gradient(bottom, -moz-mac-chrome-active 2px, transparent 2px); } #TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme):-moz-window-inactive { - background-image: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-inactive.png); + background: url(chrome://browser/skin/tabbrowser/tabbar-top-bg-inactive.png), + -moz-linear-gradient(bottom, -moz-mac-chrome-inactive 2px, transparent 2px); } +/* In tabs-on-bottom mode, fill the whole toolbar with the chrome + * background color. + */ #TabsToolbar[tabsontop="false"]:not(:-moz-lwtheme) { - background-image: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-active.png); + background: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-active.png) -moz-mac-chrome-active; } #TabsToolbar[tabsontop="false"]:not(:-moz-lwtheme):-moz-window-inactive { - background-image: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-inactive.png); + background: url(chrome://browser/skin/tabbrowser/tabbar-bottom-bg-inactive.png) -moz-mac-chrome-inactive; } #tabbrowser-tabs { @@ -1955,11 +1953,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { :-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1, :-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-button, :-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker { - margin: 0; - padding: 0; - border: none; - border-radius: 0; + -moz-appearance: none; /* !important flags needed because of bug 561154: */ + margin: 0 !important; + padding: 0 !important; + border: none !important; + border-radius: 0 !important; background: none !important; box-shadow: none !important; } diff --git a/browser/themes/pinstripe/browser/jar.mn b/browser/themes/pinstripe/browser/jar.mn index d1952b88f933..6c982967e16d 100644 --- a/browser/themes/pinstripe/browser/jar.mn +++ b/browser/themes/pinstripe/browser/jar.mn @@ -42,6 +42,7 @@ browser.jar: skin/classic/browser/section_collapsed-rtl.png skin/classic/browser/section_expanded.png skin/classic/browser/Secure-Glyph-White.png + skin/classic/browser/keyhole-circle.png skin/classic/browser/Toolbar.png skin/classic/browser/toolbarbutton-dropmarker.png skin/classic/browser/urlbar-arrow.png @@ -134,3 +135,8 @@ browser.jar: skin/classic/browser/syncCommon.css skin/classic/browser/syncQuota.css #endif + skin/classic/browser/lion/keyhole-circle.png (keyhole-circle-lion.png) + skin/classic/browser/lion/Toolbar.png (Toolbar-lion.png) + +% override chrome://browser/skin/keyhole-circle.png chrome://browser/skin/lion/keyhole-circle.png os=Darwin osversion>=10.7 +% override chrome://browser/skin/Toolbar.png chrome://browser/skin/lion/Toolbar.png os=Darwin osversion>=10.7 diff --git a/browser/themes/pinstripe/browser/keyhole-circle-lion.png b/browser/themes/pinstripe/browser/keyhole-circle-lion.png new file mode 100644 index 000000000000..f164d498c351 Binary files /dev/null and b/browser/themes/pinstripe/browser/keyhole-circle-lion.png differ diff --git a/browser/themes/pinstripe/browser/keyhole-circle.png b/browser/themes/pinstripe/browser/keyhole-circle.png new file mode 100644 index 000000000000..c3ecea0315f6 Binary files /dev/null and b/browser/themes/pinstripe/browser/keyhole-circle.png differ diff --git a/browser/themes/pinstripe/browser/places/organizer.css b/browser/themes/pinstripe/browser/places/organizer.css index 99dfffcee35f..9b793398fd4c 100644 --- a/browser/themes/pinstripe/browser/places/organizer.css +++ b/browser/themes/pinstripe/browser/places/organizer.css @@ -80,33 +80,9 @@ #placesToolbar > toolbarbutton { list-style-image: url("chrome://browser/skin/places/toolbar.png"); margin: 4px 4px 5px; - padding: 1px 3px; - border: 1px solid @toolbarbuttonBorderColor@; - border-radius: @toolbarbuttonCornerRadius@; - box-shadow: @loweredShadow@; - background: @toolbarbuttonBackground@; - background-origin: border-box; -} - -#placesToolbar > toolbarbutton:not([disabled="true"]):active:hover, -#placesToolbar > toolbarbutton[open="true"] { - background: @toolbarbuttonPressedBackgroundColor@; - text-shadow: @loweredShadow@; - box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@; -} - -#placesToolbar > toolbarbutton:-moz-focusring { - border-color: @toolbarbuttonFocusedBorderColorAqua@; - box-shadow: @focusRingShadow@; -} - -#placesToolbar > toolbarbutton:-moz-system-metric(mac-graphite-theme):-moz-focusring { - border-color: @toolbarbuttonFocusedBorderColorGraphite@; -} - -#placesToolbar > toolbarbutton:-moz-window-inactive { - border-color: @toolbarbuttonInactiveBorderColor@; - background-image: @toolbarbuttonInactiveBackgroundImage@; + padding: 0; + height: 22px; + -moz-appearance: toolbarbutton; } #placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon { @@ -136,17 +112,12 @@ #back-button:-moz-locale-dir(ltr), #forward-button:-moz-locale-dir(rtl) { -moz-image-region: rect(0px, 16px, 16px, 0px); - border-top-right-radius: 0; - border-bottom-right-radius: 0; margin-right: 0; - border-right: 0; } #forward-button:-moz-locale-dir(ltr), #back-button:-moz-locale-dir(rtl) { -moz-image-region: rect(0px, 32px, 16px, 16px); - border-top-left-radius: 0; - border-bottom-left-radius: 0; margin-left: 0; } diff --git a/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-active.png b/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-active.png index 0e7f271a5d67..fc7b3497d55e 100644 Binary files a/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-active.png and b/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-active.png differ diff --git a/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-inactive.png b/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-inactive.png index 0c7a196de516..c47147cbddb4 100644 Binary files a/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-inactive.png and b/browser/themes/pinstripe/browser/tabbrowser/tabbar-top-bg-inactive.png differ diff --git a/browser/themes/winstripe/browser/browser-aero.css b/browser/themes/winstripe/browser/browser-aero.css index 58774e42f0e0..c0d02a4cfcd0 100644 --- a/browser/themes/winstripe/browser/browser-aero.css +++ b/browser/themes/winstripe/browser/browser-aero.css @@ -180,17 +180,18 @@ because of the border radius on the toolbar below the tab bar. */ #main-window[sizemode=normal][tabsontop=true] #nav-bar:not(:-moz-lwtheme), #main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme), - #main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme) { + #main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme), + #main-window[sizemode=normal][tabsontop=true][disablechrome] #navigator-toolbox:not(:-moz-lwtheme)::after { border-top: 1px solid @toolbarShadowColor@; border-top-left-radius: 3.5px; border-top-right-radius: 3.5px; background-clip: padding-box; } - #main-window[sizemode=normal]:not([disablechrome]) #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) { + #main-window[sizemode=normal] #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) { margin-bottom: -1px; background-image: none !important; } - #main-window[sizemode=normal]:not([disablechrome]) #tabbrowser-tabs[tabsontop=true] > .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox > .scrollbox-innerbox:not(:-moz-lwtheme) { + #main-window[sizemode=normal] #tabbrowser-tabs[tabsontop=true] > .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox > .scrollbox-innerbox:not(:-moz-lwtheme) { position: relative; } @@ -213,6 +214,14 @@ padding-right: 2px; } + /* Rounded corners for when chrome is disabled */ + #main-window[sizemode=normal][tabsontop=true][disablechrome] #navigator-toolbox:not(:-moz-lwtheme)::after { + visibility: visible; + background-color: @customToolbarColor@; + background-image: -moz-linear-gradient(@toolbarHighlight@, @toolbarHighlight@); + height: 4px; + } + /* Make the window draggable by glassed toolbars (bug 555081) */ #toolbar-menubar:not([autohide="true"]), #TabsToolbar[tabsontop="true"], diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index f0c2ca56de38..56019336ea1f 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -143,12 +143,9 @@ MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@ MOZ_FEEDS = @MOZ_FEEDS@ MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@ MOZ_PLACES = @MOZ_PLACES@ -MOZ_STORAGE = @MOZ_STORAGE@ MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@ MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@ MOZ_ZIPWRITER = @MOZ_ZIPWRITER@ -MOZ_MORK = @MOZ_MORK@ -MOZ_MORKREADER = @MOZ_MORKREADER@ MOZ_OGG = @MOZ_OGG@ MOZ_RAW = @MOZ_RAW@ MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@ diff --git a/configure.in b/configure.in index a3f404e9ee5e..111248d5d0bc 100644 --- a/configure.in +++ b/configure.in @@ -3892,63 +3892,6 @@ if test "x$ac_cv_va_val_copy" = "xno"; then fi AC_MSG_RESULT($ac_cv_va_val_copy) -dnl Check for dll-challenged libc's. -dnl This check is apparently only needed for Linux. -case "$target" in - *-linux*) - dnl =================================================================== - _curdir=`pwd` - export _curdir - rm -rf conftest* _conftest - mkdir _conftest - cat >> conftest.C <<\EOF -#include -#include -#include -#ifdef _dl_loaded -void __dump_link_map(void) { - struct link_map *map = _dl_loaded; - while (NULL != map) {printf("0x%08x %s\n", map->l_addr, map->l_name); map = map->l_next;} -} -int main() { - dlopen("./conftest1.so",RTLD_LAZY); - dlopen("./../_conftest/conftest1.so",RTLD_LAZY); - dlopen("CURDIR/_conftest/conftest1.so",RTLD_LAZY); - dlopen("CURDIR/_conftest/../_conftest/conftest1.so",RTLD_LAZY); - __dump_link_map(); -} -#else -/* _dl_loaded isn't defined, so this should be either a libc5 (glibc1) system, or a glibc2 system that doesn't have the multiple load bug (i.e., RH6.0).*/ -int main() { printf("./conftest1.so\n"); } -#endif -EOF - - $PERL -p -i -e "s/CURDIR/\$ENV{_curdir}/g;" conftest.C - - cat >> conftest1.C <<\EOF -#include -void foo(void) {printf("foo in dll called\n");} -EOF - ${CXX-g++} -fPIC -c -g conftest1.C - ${CXX-g++} -shared -Wl,-h -Wl,conftest1.so -o conftest1.so conftest1.o - ${CXX-g++} -g conftest.C -o conftest -ldl - cp -f conftest1.so conftest _conftest - cd _conftest - if test `./conftest | grep conftest1.so | wc -l` -gt 1 - then - echo - echo "*** Your libc has a bug that can result in loading the same dynamic" - echo "*** library multiple times. This bug is known to be fixed in glibc-2.0.7-32" - echo "*** or later. However, if you choose not to upgrade, the only effect" - echo "*** will be excessive memory usage at runtime." - echo - fi - cd ${_curdir} - rm -rf conftest* _conftest - dnl =================================================================== - ;; -esac - dnl =================================================================== dnl ======================================================== dnl Put your C++ language/feature checks below @@ -4631,11 +4574,6 @@ if test "$SYSTEM_JPEG" = 1; then SYSTEM_JPEG=1, [SYSTEM_JPEG= JPEG_CFLAGS= JPEG_LIBS=]) fi - -MOZ_LIBJPEG_TURBO= -if test -z "$SYSTEM_JPEG"; then - MOZ_LIBJPEG_TURBO=1 -fi CFLAGS=$_SAVE_CFLAGS LDFLAGS=$_SAVE_LDFLAGS LIBS=$_SAVE_LIBS @@ -4821,8 +4759,6 @@ MOZ_OFFICIAL_BRANDING= MOZ_FEEDS=1 MOZ_INSTALLER=1 MOZ_JSDEBUGGER=1 -MOZ_MORK= -MOZ_MORKREADER= MOZ_AUTH_EXTENSION=1 MOZ_OGG=1 MOZ_RAW= @@ -4854,7 +4790,6 @@ MOZ_REFLOW_PERF= MOZ_SAFE_BROWSING= MOZ_HELP_VIEWER= MOZ_SPELLCHECK=1 -MOZ_STORAGE=1 MOZ_SVG_DLISTS= MOZ_TOOLKIT_SEARCH=1 MOZ_UI_LOCALE=en-US @@ -6256,12 +6191,20 @@ AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_P dnl ======================================================== dnl = libjpeg-turbo configuration dnl ======================================================== +MOZ_LIBJPEG_TURBO= +if test -z "$SYSTEM_JPEG"; then + MOZ_LIBJPEG_TURBO=1 +fi MOZ_ARG_DISABLE_BOOL(libjpeg_turbo, [ --disable-libjpeg-turbo Disable optimized jpeg decoding routines], MOZ_LIBJPEG_TURBO=, MOZ_LIBJPEG_TURBO=1) +if test "$SYSTEM_JPEG" = 1 -a "$MOZ_LIBJPEG_TURBO" = 1; then + AC_MSG_ERROR([cannot use --with-system-jpeg with --enable-libjpeg-turbo.]) +fi + dnl Detect if we can use yasm to compile libjpeg-turbo's optimized assembly dnl files. @@ -6605,18 +6548,6 @@ else fi fi -dnl ======================================================== -dnl = Enable mozStorage -dnl ======================================================== -dnl Implicitly enabled by default if building calendar or places -MOZ_ARG_ENABLE_BOOL(storage, -[ --enable-storage Enable mozStorage module and related components], - MOZ_STORAGE=1, - MOZ_STORAGE= ) -if test -n "$MOZ_STORAGE"; then - AC_DEFINE(MOZ_STORAGE) -fi - dnl ======================================================== dnl Check for sqlite dnl ======================================================== @@ -8888,18 +8819,6 @@ fi dnl NECKO_ configuration options are not global _NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_" -dnl Only build Mork if it's required -AC_SUBST(MOZ_MORK) -if test "$MOZ_MORK"; then - AC_DEFINE(MOZ_MORK) -fi - -dnl Build the lightweight Mork reader if required -AC_SUBST(MOZ_MORKREADER) -if test "$MOZ_MORKREADER"; then - AC_DEFINE(MOZ_MORKREADER) -fi - dnl Build Places if required if test "$MOZ_PLACES"; then AC_DEFINE(MOZ_PLACES) @@ -8979,7 +8898,6 @@ AC_SUBST(MOZ_PROFILING) AC_SUBST(MOZ_QUANTIFY) AC_SUBST(LIBICONV) AC_SUBST(MOZ_PLACES) -AC_SUBST(MOZ_STORAGE) AC_SUBST(MOZ_TOOLKIT_SEARCH) AC_SUBST(MOZ_FEEDS) AC_SUBST(NS_PRINTING) diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 736af834966f..7653153054f8 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -69,6 +69,7 @@ #include "nsIAnimationFrameListener.h" #include "nsEventStates.h" #include "nsIStructuredCloneContainer.h" +#include "nsIBFCacheEntry.h" #include "nsDOMMemoryReporter.h" class nsIContent; @@ -125,9 +126,9 @@ class Element; } // namespace mozilla -#define NS_IDOCUMENT_IID \ -{ 0xfac563fb, 0x2b6a, 0x4ac8, \ - { 0x85, 0xf7, 0xd5, 0x14, 0x4b, 0x3e, 0xce, 0x78 } } +#define NS_IDOCUMENT_IID \ +{ 0x455e4d79, 0x756b, 0x4f73, \ + { 0x95, 0xea, 0x3f, 0xf6, 0x0c, 0x6a, 0x8c, 0xa6 } } // Flag for AddStyleSheet(). #define NS_STYLESHEET_FROM_CATALOG (1 << 0) @@ -480,11 +481,15 @@ public: return GetBFCacheEntry() ? nsnull : mPresShell; } - void SetBFCacheEntry(nsISHEntry* aSHEntry) { - mSHEntry = aSHEntry; + void SetBFCacheEntry(nsIBFCacheEntry* aEntry) + { + mBFCacheEntry = aEntry; } - nsISHEntry* GetBFCacheEntry() const { return mSHEntry; } + nsIBFCacheEntry* GetBFCacheEntry() const + { + return mBFCacheEntry; + } /** * Return the parent document of this document. Will return null @@ -1326,6 +1331,10 @@ public: PRUint32 EventHandlingSuppressed() const { return mEventsSuppressed; } + bool IsEventHandlingEnabled() { + return !EventHandlingSuppressed() && mScriptGlobalObject; + } + /** * Increment the number of external scripts being evaluated. */ @@ -1738,9 +1747,9 @@ protected: AnimationListenerList mAnimationFrameListeners; - // The session history entry in which we're currently bf-cached. Non-null - // if and only if we're currently in the bfcache. - nsISHEntry* mSHEntry; + // This object allows us to evict ourself from the back/forward cache. The + // pointer is non-null iff we're currently in the bfcache. + nsIBFCacheEntry *mBFCacheEntry; // Our base target. nsString mBaseTarget; diff --git a/content/base/public/nsIDroppedLinkHandler.idl b/content/base/public/nsIDroppedLinkHandler.idl index c7997f0b52fa..3dd2f8769e4a 100644 --- a/content/base/public/nsIDroppedLinkHandler.idl +++ b/content/base/public/nsIDroppedLinkHandler.idl @@ -51,7 +51,7 @@ interface nsIDroppedLinkHandler : nsISupports * includes any parent, sibling and child frames in the same content tree. * If true, the source is not checked. */ - boolean canDropLink(in nsIDOMDragEvent aEvent, in PRBool aAllowSameDocument); + boolean canDropLink(in nsIDOMDragEvent aEvent, in boolean aAllowSameDocument); /** * Given a drop event aEvent, determines the link being dragged and returns diff --git a/content/base/public/nsISelection2.idl b/content/base/public/nsISelection2.idl index c894c5cdc049..84345eceb66e 100644 --- a/content/base/public/nsISelection2.idl +++ b/content/base/public/nsISelection2.idl @@ -63,14 +63,14 @@ interface nsISelection2 : nsISelection void GetRangesForInterval( in nsIDOMNode beginNode, in PRInt32 beginOffset, in nsIDOMNode endNode, in PRInt32 endOffset, - in PRBool allowAdjacent, + in boolean allowAdjacent, out PRUint32 resultCount, [retval, array, size_is(resultCount)] out nsIDOMRange results); [noscript] void GetRangesForIntervalCOMArray( in nsIDOMNode beginNode, in PRInt32 beginOffset, in nsIDOMNode endNode, in PRInt32 endOffset, - in PRBool allowAdjacent, + in boolean allowAdjacent, in RangeArray results); /** diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 38add33f3067..7bb1e98c5107 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -492,172 +492,14 @@ nsContentUtils::InitializeEventTable() { NS_ASSERTION(!sStringEventTable, "EventTable already initialized!"); static const EventNameMapping eventArray[] = { - { nsGkAtoms::onmousedown, NS_MOUSE_BUTTON_DOWN, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::onmouseup, NS_MOUSE_BUTTON_UP, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::onclick, NS_MOUSE_CLICK, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::ondblclick, NS_MOUSE_DOUBLECLICK, EventNameType_HTMLXUL, NS_MOUSE_EVENT }, - { nsGkAtoms::onmouseover, NS_MOUSE_ENTER_SYNTH, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::onmouseout, NS_MOUSE_EXIT_SYNTH, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::onMozMouseHittest, NS_MOUSE_MOZHITTEST, EventNameType_None, NS_MOUSE_EVENT }, - { nsGkAtoms::onmousemove, NS_MOUSE_MOVE, EventNameType_All, NS_MOUSE_EVENT }, - { nsGkAtoms::oncontextmenu, NS_CONTEXTMENU, EventNameType_HTMLXUL, NS_MOUSE_EVENT }, - - { nsGkAtoms::onkeydown, NS_KEY_DOWN, EventNameType_HTMLXUL, NS_KEY_EVENT }, - { nsGkAtoms::onkeyup, NS_KEY_UP, EventNameType_HTMLXUL, NS_KEY_EVENT }, - { nsGkAtoms::onkeypress, NS_KEY_PRESS, EventNameType_HTMLXUL, NS_KEY_EVENT }, - - { nsGkAtoms::onfocus, NS_FOCUS_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT }, - { nsGkAtoms::onblur, NS_BLUR_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT }, - - { nsGkAtoms::onoffline, NS_OFFLINE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::ononline, NS_ONLINE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onsubmit, NS_FORM_SUBMIT, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onreset, NS_FORM_RESET, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onchange, NS_FORM_CHANGE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onselect, NS_FORM_SELECTED, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::oninvalid, NS_FORM_INVALID, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onload, NS_LOAD, EventNameType_All, NS_EVENT }, - { nsGkAtoms::onpopstate, NS_POPSTATE, EventNameType_HTMLXUL, NS_EVENT_NULL }, - { nsGkAtoms::onunload, NS_PAGE_UNLOAD, - (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT }, - { nsGkAtoms::onhashchange, NS_HASHCHANGE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onreadystatechange, NS_READYSTATECHANGE, EventNameType_HTMLXUL }, - { nsGkAtoms::onbeforeunload, NS_BEFORE_PAGE_UNLOAD, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onabort, NS_IMAGE_ABORT, - (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT }, - { nsGkAtoms::onerror, NS_LOAD_ERROR, - (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT }, - { nsGkAtoms::onbeforescriptexecute, NS_BEFORE_SCRIPT_EXECUTE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onafterscriptexecute, NS_AFTER_SCRIPT_EXECUTE, EventNameType_HTMLXUL, NS_EVENT }, - - { nsGkAtoms::onDOMAttrModified, NS_MUTATION_ATTRMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMCharacterDataModified, NS_MUTATION_CHARACTERDATAMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMNodeInserted, NS_MUTATION_NODEINSERTED, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMNodeRemoved, NS_MUTATION_NODEREMOVED, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMNodeInsertedIntoDocument, NS_MUTATION_NODEINSERTEDINTODOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMNodeRemovedFromDocument, NS_MUTATION_NODEREMOVEDFROMDOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - { nsGkAtoms::onDOMSubtreeModified, NS_MUTATION_SUBTREEMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT }, - - { nsGkAtoms::onDOMActivate, NS_UI_ACTIVATE, EventNameType_HTMLXUL, NS_UI_EVENT }, - { nsGkAtoms::onDOMFocusIn, NS_UI_FOCUSIN, EventNameType_HTMLXUL, NS_UI_EVENT }, - { nsGkAtoms::onDOMFocusOut, NS_UI_FOCUSOUT, EventNameType_HTMLXUL, NS_UI_EVENT }, - { nsGkAtoms::oninput, NS_FORM_INPUT, EventNameType_HTMLXUL, NS_UI_EVENT }, - - { nsGkAtoms::onDOMMouseScroll, NS_MOUSE_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT }, - { nsGkAtoms::onMozMousePixelScroll, NS_MOUSE_PIXEL_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT }, - - { nsGkAtoms::onpageshow, NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT }, - { nsGkAtoms::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT }, - { nsGkAtoms::onMozBeforeResize, NS_BEFORERESIZE_EVENT, EventNameType_None, NS_EVENT }, - { nsGkAtoms::onresize, NS_RESIZE_EVENT, - (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT }, - { nsGkAtoms::onscroll, NS_SCROLL_EVENT, - (EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT_NULL }, - { nsGkAtoms::oncopy, NS_COPY, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::oncut, NS_CUT, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onpaste, NS_PASTE, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onopen, NS_OPEN, EventNameType_None, NS_EVENT }, - { nsGkAtoms::onmessage, NS_MESSAGE, EventNameType_None, NS_EVENT }, - // XUL specific events - { nsGkAtoms::ontext, NS_TEXT_TEXT, EventNameType_XUL, NS_EVENT_NULL }, - - { nsGkAtoms::oncompositionstart, NS_COMPOSITION_START, EventNameType_XUL, NS_COMPOSITION_EVENT }, - { nsGkAtoms::oncompositionend, NS_COMPOSITION_END, EventNameType_XUL, NS_COMPOSITION_EVENT }, - - { nsGkAtoms::oncommand, NS_XUL_COMMAND, EventNameType_XUL, NS_INPUT_EVENT }, - - { nsGkAtoms::onclose, NS_XUL_CLOSE, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onpopupshowing, NS_XUL_POPUP_SHOWING, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onpopupshown, NS_XUL_POPUP_SHOWN, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onpopuphiding, NS_XUL_POPUP_HIDING, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onpopuphidden, NS_XUL_POPUP_HIDDEN, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onbroadcast, NS_XUL_BROADCAST, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::oncommandupdate, NS_XUL_COMMAND_UPDATE, EventNameType_XUL, NS_EVENT_NULL}, - - { nsGkAtoms::ondragenter, NS_DRAGDROP_ENTER, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragover, NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragexit, NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragdrop, NS_DRAGDROP_DRAGDROP, EventNameType_XUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondraggesture, NS_DRAGDROP_GESTURE, EventNameType_XUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondrag, NS_DRAGDROP_DRAG, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragend, NS_DRAGDROP_END, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragstart, NS_DRAGDROP_START, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondragleave, NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - { nsGkAtoms::ondrop, NS_DRAGDROP_DROP, EventNameType_HTMLXUL, NS_DRAG_EVENT }, - - { nsGkAtoms::onoverflow, NS_SCROLLPORT_OVERFLOW, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onunderflow, NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL, NS_EVENT_NULL}, - { nsGkAtoms::onSVGLoad, NS_SVG_LOAD, EventNameType_None, NS_SVG_EVENT }, - { nsGkAtoms::onSVGUnload, NS_SVG_UNLOAD, EventNameType_None, NS_SVG_EVENT }, - { nsGkAtoms::onSVGAbort, NS_SVG_ABORT, EventNameType_None, NS_SVG_EVENT }, - { nsGkAtoms::onSVGError, NS_SVG_ERROR, EventNameType_None, NS_SVG_EVENT }, - { nsGkAtoms::onSVGResize, NS_SVG_RESIZE, EventNameType_None, NS_SVG_EVENT }, - { nsGkAtoms::onSVGScroll, NS_SVG_SCROLL, EventNameType_None, NS_SVG_EVENT }, - - { nsGkAtoms::onSVGZoom, NS_SVG_ZOOM, EventNameType_None, NS_SVGZOOM_EVENT }, - - // This is a bit hackish, but SVG's event names are weird. - { nsGkAtoms::onzoom, NS_SVG_ZOOM, EventNameType_SVGSVG, NS_EVENT_NULL }, -#ifdef MOZ_SMIL - { nsGkAtoms::onbegin, NS_SMIL_BEGIN, EventNameType_SMIL, NS_EVENT_NULL }, - { nsGkAtoms::onbeginEvent, NS_SMIL_BEGIN, EventNameType_None, NS_SMIL_TIME_EVENT }, - { nsGkAtoms::onend, NS_SMIL_END, EventNameType_SMIL, NS_EVENT_NULL }, - { nsGkAtoms::onendEvent, NS_SMIL_END, EventNameType_None, NS_SMIL_TIME_EVENT }, - { nsGkAtoms::onrepeat, NS_SMIL_REPEAT, EventNameType_SMIL, NS_EVENT_NULL }, - { nsGkAtoms::onrepeatEvent, NS_SMIL_REPEAT, EventNameType_None, NS_SMIL_TIME_EVENT }, -#endif // MOZ_SMIL -#ifdef MOZ_MEDIA - { nsGkAtoms::onloadstart, NS_LOADSTART, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onprogress, NS_PROGRESS, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onsuspend, NS_SUSPEND, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onemptied, NS_EMPTIED, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onstalled, NS_STALLED, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onplay, NS_PLAY, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onpause, NS_PAUSE, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onloadedmetadata, NS_LOADEDMETADATA, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onloadeddata, NS_LOADEDDATA, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onwaiting, NS_WAITING, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onplaying, NS_PLAYING, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::oncanplay, NS_CANPLAY, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::oncanplaythrough, NS_CANPLAYTHROUGH, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onseeking, NS_SEEKING, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onseeked, NS_SEEKED, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::ontimeupdate, NS_TIMEUPDATE, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onended, NS_ENDED, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onratechange, NS_RATECHANGE, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::ondurationchange, NS_DURATIONCHANGE, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onvolumechange, NS_VOLUMECHANGE, EventNameType_HTML, NS_EVENT_NULL }, - { nsGkAtoms::onMozAudioAvailable, NS_MOZAUDIOAVAILABLE, EventNameType_None, NS_EVENT_NULL }, -#endif // MOZ_MEDIA - { nsGkAtoms::onMozAfterPaint, NS_AFTERPAINT, EventNameType_None, NS_EVENT }, - { nsGkAtoms::onMozBeforePaint, NS_BEFOREPAINT, EventNameType_None, NS_EVENT_NULL }, - - { nsGkAtoms::onMozScrolledAreaChanged, NS_SCROLLEDAREACHANGED, EventNameType_None, NS_SCROLLAREA_EVENT }, - - // Simple gesture events - { nsGkAtoms::onMozSwipeGesture, NS_SIMPLE_GESTURE_SWIPE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozMagnifyGestureStart, NS_SIMPLE_GESTURE_MAGNIFY_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozMagnifyGestureUpdate, NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozMagnifyGesture, NS_SIMPLE_GESTURE_MAGNIFY, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozRotateGestureStart, NS_SIMPLE_GESTURE_ROTATE_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozRotateGestureUpdate, NS_SIMPLE_GESTURE_ROTATE_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozRotateGesture, NS_SIMPLE_GESTURE_ROTATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozTapGesture, NS_SIMPLE_GESTURE_TAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - { nsGkAtoms::onMozPressTapGesture, NS_SIMPLE_GESTURE_PRESSTAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT }, - - { nsGkAtoms::onMozTouchDown, NS_MOZTOUCH_DOWN, EventNameType_None, NS_MOZTOUCH_EVENT }, - { nsGkAtoms::onMozTouchMove, NS_MOZTOUCH_MOVE, EventNameType_None, NS_MOZTOUCH_EVENT }, - { nsGkAtoms::onMozTouchUp, NS_MOZTOUCH_UP, EventNameType_None, NS_MOZTOUCH_EVENT }, - - { nsGkAtoms::ondevicemotion, NS_DEVICE_MOTION, EventNameType_None, NS_EVENT }, - { nsGkAtoms::ondeviceorientation, NS_DEVICE_ORIENTATION, EventNameType_None, NS_EVENT }, - - { nsGkAtoms::ontransitionend, NS_TRANSITION_END, EventNameType_None, NS_TRANSITION_EVENT }, - { nsGkAtoms::onanimationstart, NS_ANIMATION_START, EventNameType_None, NS_ANIMATION_EVENT }, - { nsGkAtoms::onanimationend, NS_ANIMATION_END, EventNameType_None, NS_ANIMATION_EVENT }, - { nsGkAtoms::onanimationiteration, NS_ANIMATION_ITERATION, EventNameType_None, NS_ANIMATION_EVENT }, - { nsGkAtoms::onbeforeprint, NS_BEFOREPRINT, EventNameType_HTMLXUL, NS_EVENT }, - { nsGkAtoms::onafterprint, NS_AFTERPRINT, EventNameType_HTMLXUL, NS_EVENT } +#define EVENT(name_, _id, _type, _struct) \ + { nsGkAtoms::on##name_, _id, _type, _struct }, +#define WINDOW_ONLY_EVENT EVENT +#define NON_IDL_EVENT EVENT +#include "nsEventNameList.h" +#undef WINDOW_ONLY_EVENT +#undef EVENT + nsnull }; sAtomEventTable = new nsDataHashtable; @@ -676,7 +518,8 @@ nsContentUtils::InitializeEventTable() { return PR_FALSE; } - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray); ++i) { + // Subtract one from the length because of the trailing null + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray) - 1; ++i) { if (!sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]) || !sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2), eventArray[i])) { @@ -698,14 +541,16 @@ nsContentUtils::InitializeTouchEventTable() if (!sEventTableInitialized && sAtomEventTable && sStringEventTable) { sEventTableInitialized = PR_TRUE; static const EventNameMapping touchEventArray[] = { - { nsGkAtoms::ontouchstart, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }, - { nsGkAtoms::ontouchend, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }, - { nsGkAtoms::ontouchmove, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }, - { nsGkAtoms::ontouchenter, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }, - { nsGkAtoms::ontouchleave, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT }, - { nsGkAtoms::ontouchcancel, NS_USER_DEFINED_EVENT, EventNameType_All, NS_INPUT_EVENT } +#define EVENT(name_, _id, _type, _struct) +#define TOUCH_EVENT(name_, _id, _type, _struct) \ + { nsGkAtoms::on##name_, _id, _type, _struct }, +#include "nsEventNameList.h" +#undef TOUCH_EVENT +#undef EVENT + nsnull }; - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(touchEventArray); ++i) { + // Subtract one from the length because of the trailing null + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(touchEventArray) - 1; ++i) { if (!sAtomEventTable->Put(touchEventArray[i].mAtom, touchEventArray[i]) || !sStringEventTable->Put(Substring(nsDependentAtomString(touchEventArray[i].mAtom), 2), touchEventArray[i])) { diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 29bba6e324c5..34fb9dc671ef 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -3196,9 +3196,7 @@ nsDocument::doCreateShell(nsPresContext* aContext, mExternalResourceMap.ShowViewers(); - if (mScriptGlobalObject) { - RescheduleAnimationFrameNotifications(); - } + MaybeRescheduleAnimationFrameNotifications(); shell.swap(*aInstancePtrResult); @@ -3206,8 +3204,13 @@ nsDocument::doCreateShell(nsPresContext* aContext, } void -nsDocument::RescheduleAnimationFrameNotifications() +nsDocument::MaybeRescheduleAnimationFrameNotifications() { + if (!mPresShell || !IsEventHandlingEnabled()) { + // bail out for now, until one of those conditions changes + return; + } + nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver(); if (mHavePendingPaint) { rd->ScheduleBeforePaintEvent(this); @@ -3228,7 +3231,7 @@ void nsDocument::DeleteShell() { mExternalResourceMap.HideViewers(); - if (mScriptGlobalObject) { + if (IsEventHandlingEnabled()) { RevokeAnimationFrameNotifications(); } mPresShell = nsnull; @@ -3776,7 +3779,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) // our layout history state now. mLayoutHistoryState = GetLayoutHistoryState(); - if (mPresShell) { + if (mPresShell && !EventHandlingSuppressed()) { RevokeAnimationFrameNotifications(); } @@ -3837,9 +3840,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) } } - if (mPresShell) { - RescheduleAnimationFrameNotifications(); - } + MaybeRescheduleAnimationFrameNotifications(); } // Remember the pointer to our window (or lack there of), to avoid @@ -7648,6 +7649,10 @@ SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData) void nsDocument::SuppressEventHandling(PRUint32 aIncrease) { + if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell && + mScriptGlobalObject) { + RevokeAnimationFrameNotifications(); + } mEventsSuppressed += aIncrease; EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease); } @@ -7807,13 +7812,8 @@ GetAndUnsuppressSubDocuments(nsIDocument* aDocument, void* aData) void nsDocument::UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents) { - if (mEventsSuppressed > 0) { - --mEventsSuppressed; - } - nsTArray > documents; - documents.AppendElement(this); - EnumerateSubDocuments(GetAndUnsuppressSubDocuments, &documents); + GetAndUnsuppressSubDocuments(this, &documents); if (aFireEvents) { NS_DispatchToCurrentThread(new nsDelayedEventDispatcher(documents)); @@ -8042,7 +8042,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener) if (aListener) { PRBool alreadyRegistered = !mAnimationFrameListeners.IsEmpty(); if (mAnimationFrameListeners.AppendElement(aListener) && - !alreadyRegistered && mPresShell) { + !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) { mPresShell->GetPresContext()->RefreshDriver()-> ScheduleAnimationFrameListeners(this); } @@ -8056,6 +8056,7 @@ nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener) // event will fire, or we'll quietly go away at some point. mHavePendingPaint = !mPresShell || + !IsEventHandlingEnabled() || mPresShell->GetPresContext()->RefreshDriver()-> ScheduleBeforePaintEvent(this); } diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 603d3961ed08..765e6090f675 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -865,7 +865,10 @@ public: virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents); - void DecreaseEventSuppression() { --mEventsSuppressed; } + void DecreaseEventSuppression() { + --mEventsSuppressed; + MaybeRescheduleAnimationFrameNotifications(); + } NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument, nsIDocument) @@ -1149,8 +1152,9 @@ private: // Revoke any pending notifications due to mozRequestAnimationFrame calls void RevokeAnimationFrameNotifications(); - // Reschedule any notifications we need to handle mozRequestAnimationFrame - void RescheduleAnimationFrameNotifications(); + // Reschedule any notifications we need to handle + // mozRequestAnimationFrame, if it's OK to do so. + void MaybeRescheduleAnimationFrameNotifications(); // These are not implemented and not supported. nsDocument(const nsDocument& aOther); diff --git a/content/base/src/nsFrameMessageManager.cpp b/content/base/src/nsFrameMessageManager.cpp index f906120b31a2..c3fdd79a8c7d 100644 --- a/content/base/src/nsFrameMessageManager.cpp +++ b/content/base/src/nsFrameMessageManager.cpp @@ -249,7 +249,7 @@ nsFrameMessageManager::SendSyncMessage() NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY); for (PRUint32 i = 0; i < len; ++i) { - if (!retval[i].Length()) + if (retval[i].IsEmpty()) continue; jsval ret = JSVAL_VOID; diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 460f14ce30e7..02175dfa9c48 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -1127,26 +1127,6 @@ nsINode::DispatchDOMEvent(nsEvent* aEvent, aPresContext, aEventStatus); } -nsresult -nsINode::AddEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID) -{ - nsEventListenerManager* elm = GetListenerManager(PR_TRUE); - NS_ENSURE_STATE(elm); - return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); -} - -nsresult -nsINode::RemoveEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID) -{ - nsEventListenerManager* elm = GetListenerManager(PR_FALSE); - if (elm) { - elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); - } - return NS_OK; -} - nsEventListenerManager* nsINode::GetListenerManager(PRBool aCreateIfNotFound) { diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 66a05b007bf8..771f7c433b1e 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -567,6 +567,7 @@ GK_ATOM(menuButton, "menu-button") GK_ATOM(menuitem, "menuitem") GK_ATOM(menulist, "menulist") GK_ATOM(menupopup, "menupopup") +GK_ATOM(menuseparator, "menuseparator") GK_ATOM(message, "message") GK_ATOM(meta, "meta") GK_ATOM(meter, "meter") @@ -723,6 +724,7 @@ GK_ATOM(onresize, "onresize") GK_ATOM(onscroll, "onscroll") GK_ATOM(onselect, "onselect") GK_ATOM(onset, "onset") +GK_ATOM(onshow, "onshow") GK_ATOM(onsubmit, "onsubmit") GK_ATOM(ontext, "ontext") GK_ATOM(ontouchstart, "ontouchstart") diff --git a/content/base/src/nsWebSocket.cpp b/content/base/src/nsWebSocket.cpp index a0bf1cf698be..e45fac54a253 100644 --- a/content/base/src/nsWebSocket.cpp +++ b/content/base/src/nsWebSocket.cpp @@ -382,6 +382,8 @@ nsWebSocketEstablishedConnection::Close() if (mOwner->mReadyState == nsIMozWebSocket::CONNECTING) { mOwner->SetReadyState(nsIMozWebSocket::CLOSED); + mWebSocketChannel->Close(mOwner->mClientReasonCode, + mOwner->mClientReason); Disconnect(); return NS_OK; } @@ -1494,7 +1496,7 @@ nsWebSocketEstablishedConnection::GetStatus(nsresult *aStatus) return NS_OK; } -// probably means window went away or stop button pressed +// Window closed, stop/reload button pressed, user navigated away from page, etc. NS_IMETHODIMP nsWebSocketEstablishedConnection::Cancel(nsresult aStatus) { diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 86c85b2cca8c..3f3fc099b6ee 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -501,6 +501,8 @@ _TEST_FILES2 = \ delayedServerEvents.sjs \ test_bug664916.html \ test_bug666604.html \ + test_bug675121.html \ + file_bug675121.sjs \ $(NULL) _CHROME_FILES = \ diff --git a/content/base/test/file_bug675121.sjs b/content/base/test/file_bug675121.sjs new file mode 100644 index 000000000000..45ad03d7f6a9 --- /dev/null +++ b/content/base/test/file_bug675121.sjs @@ -0,0 +1,15 @@ +var timer; + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + response.write("Responded"); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.finish(); + // 50ms certainly be enough for one refresh driver firing to happen! + }, 50, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/content/base/test/test_bug675121.html b/content/base/test/test_bug675121.html new file mode 100644 index 000000000000..1248218f4a7e --- /dev/null +++ b/content/base/test/test_bug675121.html @@ -0,0 +1,46 @@ + + + + + Test for Bug 675121 + + + + + +Mozilla Bug 675121 +

+ +
+
+
+ + diff --git a/content/canvas/src/CanvasUtils.h b/content/canvas/src/CanvasUtils.h index 3d57d9a32b56..c59d67e7e70a 100644 --- a/content/canvas/src/CanvasUtils.h +++ b/content/canvas/src/CanvasUtils.h @@ -162,7 +162,7 @@ JSValToDashArray(JSContext* cx, const jsval& patternArray, } bool haveNonzeroElement = false; - for (jsint i = 0; i < jsint(length); ++i) { + for (uint32 i = 0; i < length; ++i) { jsval elt; double d; if (!JS_GetElement(cx, obj, i, &elt)) { diff --git a/content/events/public/Makefile.in b/content/events/public/Makefile.in index 1329dbd728b2..c0759f958001 100644 --- a/content/events/public/Makefile.in +++ b/content/events/public/Makefile.in @@ -53,6 +53,7 @@ EXPORTS = \ nsPLDOMEvent.h \ nsEventDispatcher.h \ nsEventStates.h \ + nsEventNameList.h \ $(NULL) XPIDLSRCS = \ diff --git a/content/events/public/nsEventNameList.h b/content/events/public/nsEventNameList.h new file mode 100644 index 000000000000..3b98283d66ff --- /dev/null +++ b/content/events/public/nsEventNameList.h @@ -0,0 +1,751 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Boris Zbarsky + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * This file contains the list of event names that are exposed via IDL + * on various objects. It is designed to be used as inline input to + * various consumers through the magic of C preprocessing. + * + * Each entry consists of 4 pieces of information: + * 1) The name of the event + * 2) The event ID (see nsGUIEvent.h) + * 3) The event type (see the EventNameType enum in nsContentUtils.h) + * 4) The event struct type for this event. + * Items 2-4 might be empty strings for events for which they don't make sense. + * + * Event names that are exposed as content attributes on HTML elements + * and as IDL attributes on Elements, Documents and Windows and have + * no forwarding behavior should be enclosed in the EVENT macro. + * + * Event names that are exposed as content attributes on HTML elements + * and as IDL attributes on Elements, Documents and Windows and are + * forwarded from and to the Window should be + * enclosed in the FORWARDED_EVENT macro. If this macro is not + * defined, it will be defined to be equivalent to EVENT. + * + * Event names that are exposed as IDL attributes on Windows only + * should be enclosed in the WINDOW_ONLY_EVENT macro. If this macro + * is not defined, it will be defined to the empty string. + * + * Event names that are exposed as content and IDL attributes on + * and , which forward them to the Window, and are + * exposed as IDL attributes on the Window should be enclosed in the + * WINDOW_EVENT macro. If this macro is not defined, it will be + * defined to be equivalent to WINDOW_ONLY_EVENT. + * + * Touch-specific event names should be enclosed in TOUCH_EVENT. They + * are otherwise equivalent to those enclosed in EVENT. If + * TOUCH_EVENT is not defined, it will be defined to the empty string. + * + * Event names that are not exposed as IDL attributes at all should be + * enclosed in NON_IDL_EVENT. If NON_IDL_EVENT is not defined, it + * will be defined to the empty string. + */ + +#ifdef DEFINED_FORWARDED_EVENT +#error "Don't define DEFINED_FORWARDED_EVENT" +#endif /* DEFINED_FORWARDED_EVENT */ + +#ifndef FORWARDED_EVENT +#define FORWARDED_EVENT EVENT +#define DEFINED_FORWARDED_EVENT +#endif /* FORWARDED_EVENT */ + +#ifdef DEFINED_WINDOW_ONLY_EVENT +#error "Don't define DEFINED_WINDOW_ONLY_EVENT" +#endif /* DEFINED_WINDOW_ONLY_EVENT */ + +#ifndef WINDOW_ONLY_EVENT +#define WINDOW_ONLY_EVENT(_name, _id, _type, _struct) +#define DEFINED_WINDOW_ONLY_EVENT +#endif /* WINDOW_ONLY_EVENT */ + +#ifdef DEFINED_WINDOW_EVENT +#error "Don't define DEFINED_WINDOW_EVENT" +#endif /* DEFINED_WINDOW_EVENT */ + +#ifndef WINDOW_EVENT +#define WINDOW_EVENT WINDOW_ONLY_EVENT +#define DEFINED_WINDOW_EVENT +#endif /* WINDOW_EVENT */ + +#ifdef DEFINED_TOUCH_EVENT +#error "Don't define DEFINED_TOUCH_EVENT" +#endif /* DEFINED_TOUCH_EVENT */ + +#ifndef TOUCH_EVENT +#define TOUCH_EVENT(_name, _id, _type, _struct) +#define DEFINED_TOUCH_EVENT +#endif /* TOUCH_EVENT */ + +#ifdef DEFINED_NON_IDL_EVENT +#error "Don't define DEFINED_NON_IDL_EVENT" +#endif /* DEFINED_NON_IDL_EVENT */ + +#ifndef NON_IDL_EVENT +#define NON_IDL_EVENT(_name, _id, _type, _struct) +#define DEFINED_NON_IDL_EVENT +#endif /* NON_IDL_EVENT */ + +EVENT(abort, + NS_IMAGE_ABORT, + (EventNameType_HTMLXUL | EventNameType_SVGSVG), + NS_EVENT) +EVENT(canplay, + NS_CANPLAY, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(canplaythrough, + NS_CANPLAYTHROUGH, + EventNameType_HTML, + NS_EVENT_NULL ) +EVENT(change, + NS_FORM_CHANGE, + EventNameType_HTMLXUL, + NS_EVENT ) +EVENT(click, + NS_MOUSE_CLICK, + EventNameType_All, + NS_MOUSE_EVENT) +EVENT(contextmenu, + NS_CONTEXTMENU, + EventNameType_HTMLXUL, + NS_MOUSE_EVENT) +// Not supported yet +// EVENT(cuechange) +EVENT(dblclick, + NS_MOUSE_DOUBLECLICK, + EventNameType_HTMLXUL, + NS_MOUSE_EVENT) +EVENT(drag, + NS_DRAGDROP_DRAG, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(dragend, + NS_DRAGDROP_END, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(dragenter, + NS_DRAGDROP_ENTER, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(dragleave, + NS_DRAGDROP_LEAVE_SYNTH, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(dragover, + NS_DRAGDROP_OVER_SYNTH, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(dragstart, + NS_DRAGDROP_START, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(drop, + NS_DRAGDROP_DROP, + EventNameType_HTMLXUL, + NS_DRAG_EVENT) +EVENT(durationchange, + NS_DURATIONCHANGE, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(emptied, + NS_EMPTIED, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(ended, + NS_ENDED, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(input, + NS_FORM_INPUT, + EventNameType_HTMLXUL, + NS_UI_EVENT) +EVENT(invalid, + NS_FORM_INVALID, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(keydown, + NS_KEY_DOWN, + EventNameType_HTMLXUL, + NS_KEY_EVENT) +EVENT(keypress, + NS_KEY_PRESS, + EventNameType_HTMLXUL, + NS_KEY_EVENT) +EVENT(keyup, + NS_KEY_UP, + EventNameType_HTMLXUL, + NS_KEY_EVENT) +EVENT(loadeddata, + NS_LOADEDDATA, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(loadedmetadata, + NS_LOADEDMETADATA, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(loadstart, + NS_LOADSTART, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(mousedown, + NS_MOUSE_BUTTON_DOWN, + EventNameType_All, + NS_MOUSE_EVENT) +EVENT(mousemove, + NS_MOUSE_MOVE, + EventNameType_All, + NS_MOUSE_EVENT) +EVENT(mouseout, + NS_MOUSE_EXIT_SYNTH, + EventNameType_All, + NS_MOUSE_EVENT) +EVENT(mouseover, + NS_MOUSE_ENTER_SYNTH, + EventNameType_All, + NS_MOUSE_EVENT) +EVENT(mouseup, + NS_MOUSE_BUTTON_UP, + EventNameType_All, + NS_MOUSE_EVENT) +// Not supported yet; probably never because "wheel" is a better idea. +// EVENT(mousewheel) +EVENT(pause, + NS_PAUSE, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(play, + NS_PLAY, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(playing, + NS_PLAYING, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(progress, + NS_PROGRESS, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(ratechange, + NS_RATECHANGE, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(readystatechange, + NS_READYSTATECHANGE, + EventNameType_HTMLXUL, + NS_EVENT_NULL) +EVENT(reset, + NS_FORM_RESET, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(seeked, + NS_SEEKED, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(seeking, + NS_SEEKING, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(select, + NS_FORM_SELECTED, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(show, + NS_SHOW_EVENT, + EventNameType_HTML, + NS_EVENT) +EVENT(stalled, + NS_STALLED, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(submit, + NS_FORM_SUBMIT, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(suspend, + NS_SUSPEND, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(timeupdate, + NS_TIMEUPDATE, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(volumechange, + NS_VOLUMECHANGE, + EventNameType_HTML, + NS_EVENT_NULL) +EVENT(waiting, + NS_WAITING, + EventNameType_HTML, + NS_EVENT_NULL) +// Gecko-specific extensions that apply to elements +EVENT(copy, + NS_COPY, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(cut, + NS_CUT, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(paste, + NS_PASTE, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(beforescriptexecute, + NS_BEFORE_SCRIPT_EXECUTE, + EventNameType_HTMLXUL, + NS_EVENT) +EVENT(afterscriptexecute, + NS_AFTER_SCRIPT_EXECUTE, + EventNameType_HTMLXUL, + NS_EVENT) + +FORWARDED_EVENT(blur, + NS_BLUR_CONTENT, + EventNameType_HTMLXUL, + NS_FOCUS_EVENT) +FORWARDED_EVENT(error, + NS_LOAD_ERROR, + (EventNameType_HTMLXUL | EventNameType_SVGSVG), + NS_EVENT) +FORWARDED_EVENT(focus, + NS_FOCUS_CONTENT, + EventNameType_HTMLXUL, + NS_FOCUS_EVENT) +FORWARDED_EVENT(load, + NS_LOAD, + EventNameType_All, + NS_EVENT) +FORWARDED_EVENT(scroll, + NS_SCROLL_EVENT, + (EventNameType_HTMLXUL | EventNameType_SVGSVG), + NS_EVENT_NULL) + +WINDOW_EVENT(afterprint, + NS_AFTERPRINT, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(beforeprint, + NS_BEFOREPRINT, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(beforeunload, + NS_BEFORE_PAGE_UNLOAD, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(hashchange, + NS_HASHCHANGE, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(message, + NS_MESSAGE, + EventNameType_None, + NS_EVENT) +WINDOW_EVENT(offline, + NS_OFFLINE, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(online, + NS_ONLINE, + EventNameType_HTMLXUL, + NS_EVENT) +WINDOW_EVENT(pagehide, + NS_PAGE_HIDE, + EventNameType_HTML, + NS_EVENT) +WINDOW_EVENT(pageshow, + NS_PAGE_SHOW, + EventNameType_HTML, + NS_EVENT) +WINDOW_EVENT(popstate, + NS_POPSTATE, + EventNameType_HTMLXUL, + NS_EVENT_NULL) +// Not supported yet +// WINDOW_EVENT(redo) +WINDOW_EVENT(resize, + NS_RESIZE_EVENT, + (EventNameType_HTMLXUL | EventNameType_SVGSVG), + NS_EVENT) +// Not supported yet +// WINDOW_EVENT(storage) +// Not supported yet +// WINDOW_EVENT(undo) +WINDOW_EVENT(unload, + NS_PAGE_UNLOAD, + (EventNameType_HTMLXUL | EventNameType_SVGSVG), + NS_EVENT) + +WINDOW_ONLY_EVENT(devicemotion, + NS_DEVICE_MOTION, + EventNameType_None, + NS_EVENT) +WINDOW_ONLY_EVENT(deviceorientation, + NS_DEVICE_ORIENTATION, + EventNameType_None, + NS_EVENT) + +TOUCH_EVENT(touchstart, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT) +TOUCH_EVENT(touchend, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT) +TOUCH_EVENT(touchmove, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT ) +TOUCH_EVENT(touchenter, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT ) +TOUCH_EVENT(touchleave, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT) +TOUCH_EVENT(touchcancel, + NS_USER_DEFINED_EVENT, + EventNameType_All, + NS_INPUT_EVENT) + +NON_IDL_EVENT(MozMouseHittest, + NS_MOUSE_MOZHITTEST, + EventNameType_None, + NS_MOUSE_EVENT) + +NON_IDL_EVENT(DOMAttrModified, + NS_MUTATION_ATTRMODIFIED, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMCharacterDataModified, + NS_MUTATION_CHARACTERDATAMODIFIED, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMNodeInserted, + NS_MUTATION_NODEINSERTED, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMNodeRemoved, + NS_MUTATION_NODEREMOVED, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMNodeInsertedIntoDocument, + NS_MUTATION_NODEINSERTEDINTODOCUMENT, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMNodeRemovedFromDocument, + NS_MUTATION_NODEREMOVEDFROMDOCUMENT, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) +NON_IDL_EVENT(DOMSubtreeModified, + NS_MUTATION_SUBTREEMODIFIED, + EventNameType_HTMLXUL, + NS_MUTATION_EVENT) + +NON_IDL_EVENT(DOMActivate, + NS_UI_ACTIVATE, + EventNameType_HTMLXUL, + NS_UI_EVENT) +NON_IDL_EVENT(DOMFocusIn, + NS_UI_FOCUSIN, + EventNameType_HTMLXUL, + NS_UI_EVENT) +NON_IDL_EVENT(DOMFocusOut, + NS_UI_FOCUSOUT, + EventNameType_HTMLXUL, + NS_UI_EVENT) + +NON_IDL_EVENT(DOMMouseScroll, + NS_MOUSE_SCROLL, + EventNameType_HTMLXUL, + NS_MOUSE_SCROLL_EVENT) +NON_IDL_EVENT(MozMousePixelScroll, + NS_MOUSE_PIXEL_SCROLL, + EventNameType_HTMLXUL, + NS_MOUSE_SCROLL_EVENT) + +NON_IDL_EVENT(MozBeforeResize, + NS_BEFORERESIZE_EVENT, + EventNameType_None, + NS_EVENT) +NON_IDL_EVENT(open, + NS_OPEN, + EventNameType_None, + NS_EVENT) + +// Events that only have on* attributes on XUL elements +NON_IDL_EVENT(text, + NS_TEXT_TEXT, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(compositionstart, + NS_COMPOSITION_START, + EventNameType_XUL, + NS_COMPOSITION_EVENT) +NON_IDL_EVENT(compositionend, + NS_COMPOSITION_END, + EventNameType_XUL, + NS_COMPOSITION_EVENT) +NON_IDL_EVENT(command, + NS_XUL_COMMAND, + EventNameType_XUL, + NS_INPUT_EVENT) +NON_IDL_EVENT(close, + NS_XUL_CLOSE, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(popupshowing, + NS_XUL_POPUP_SHOWING, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(popupshown, + NS_XUL_POPUP_SHOWN, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(popuphiding, + NS_XUL_POPUP_HIDING, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(popuphidden, + NS_XUL_POPUP_HIDDEN, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(broadcast, + NS_XUL_BROADCAST, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(commandupdate, + NS_XUL_COMMAND_UPDATE, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(dragexit, + NS_DRAGDROP_EXIT_SYNTH, + EventNameType_XUL, + NS_DRAG_EVENT) +NON_IDL_EVENT(dragdrop, + NS_DRAGDROP_DRAGDROP, + EventNameType_XUL, + NS_DRAG_EVENT) +NON_IDL_EVENT(draggesture, + NS_DRAGDROP_GESTURE, + EventNameType_XUL, + NS_DRAG_EVENT) +NON_IDL_EVENT(overflow, + NS_SCROLLPORT_OVERFLOW, + EventNameType_XUL, + NS_EVENT_NULL) +NON_IDL_EVENT(underflow, + NS_SCROLLPORT_UNDERFLOW, + EventNameType_XUL, + NS_EVENT_NULL) + +// Various SVG events +NON_IDL_EVENT(SVGLoad, + NS_SVG_LOAD, + EventNameType_None, + NS_SVG_EVENT) +NON_IDL_EVENT(SVGUnload, + NS_SVG_UNLOAD, + EventNameType_None, + NS_SVG_EVENT) +NON_IDL_EVENT(SVGAbort, + NS_SVG_ABORT, + EventNameType_None, + NS_SVG_EVENT) +NON_IDL_EVENT(SVGError, + NS_SVG_ERROR, + EventNameType_None, + NS_SVG_EVENT) +NON_IDL_EVENT(SVGResize, + NS_SVG_RESIZE, + EventNameType_None, + NS_SVG_EVENT) +NON_IDL_EVENT(SVGScroll, + NS_SVG_SCROLL, + EventNameType_None, + NS_SVG_EVENT) + +NON_IDL_EVENT(SVGZoom, + NS_SVG_ZOOM, + EventNameType_None, + NS_SVGZOOM_EVENT) +// This is a bit hackish, but SVG's event names are weird. +NON_IDL_EVENT(zoom, + NS_SVG_ZOOM, + EventNameType_SVGSVG, + NS_EVENT_NULL) +#ifdef MOZ_SMIL +NON_IDL_EVENT(begin, + NS_SMIL_BEGIN, + EventNameType_SMIL, + NS_EVENT_NULL) +NON_IDL_EVENT(beginEvent, + NS_SMIL_BEGIN, + EventNameType_None, + NS_SMIL_TIME_EVENT) +NON_IDL_EVENT(end, + NS_SMIL_END, + EventNameType_SMIL, + NS_EVENT_NULL) +NON_IDL_EVENT(endEvent, + NS_SMIL_END, + EventNameType_None, + NS_SMIL_TIME_EVENT) +NON_IDL_EVENT(repeat, + NS_SMIL_REPEAT, + EventNameType_SMIL, + NS_EVENT_NULL) +NON_IDL_EVENT(repeatEvent, + NS_SMIL_REPEAT, + EventNameType_None, + NS_SMIL_TIME_EVENT) +#endif // MOZ_SMIL + +NON_IDL_EVENT(MozAudioAvailable, + NS_MOZAUDIOAVAILABLE, + EventNameType_None, + NS_EVENT_NULL) +NON_IDL_EVENT(MozAfterPaint, + NS_AFTERPAINT, + EventNameType_None, + NS_EVENT) +NON_IDL_EVENT(MozBeforePaint, + NS_BEFOREPAINT, + EventNameType_None, + NS_EVENT_NULL) + +NON_IDL_EVENT(MozScrolledAreaChanged, + NS_SCROLLEDAREACHANGED, + EventNameType_None, + NS_SCROLLAREA_EVENT) + +// Simple gesture events +NON_IDL_EVENT(MozSwipeGesture, + NS_SIMPLE_GESTURE_SWIPE, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozMagnifyGestureStart, + NS_SIMPLE_GESTURE_MAGNIFY_START, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozMagnifyGestureUpdate, + NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozMagnifyGesture, + NS_SIMPLE_GESTURE_MAGNIFY, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozRotateGestureStart, + NS_SIMPLE_GESTURE_ROTATE_START, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozRotateGestureUpdate, + NS_SIMPLE_GESTURE_ROTATE_UPDATE, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozRotateGesture, + NS_SIMPLE_GESTURE_ROTATE, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozTapGesture, + NS_SIMPLE_GESTURE_TAP, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) +NON_IDL_EVENT(MozPressTapGesture, + NS_SIMPLE_GESTURE_PRESSTAP, + EventNameType_None, + NS_SIMPLE_GESTURE_EVENT) + +NON_IDL_EVENT(MozTouchDown, + NS_MOZTOUCH_DOWN, + EventNameType_None, + NS_MOZTOUCH_EVENT) +NON_IDL_EVENT(MozTouchMove, + NS_MOZTOUCH_MOVE, + EventNameType_None, + NS_MOZTOUCH_EVENT) +NON_IDL_EVENT(MozTouchUp, + NS_MOZTOUCH_UP, + EventNameType_None, + NS_MOZTOUCH_EVENT) + +NON_IDL_EVENT(transitionend, + NS_TRANSITION_END, + EventNameType_None, + NS_TRANSITION_EVENT) +NON_IDL_EVENT(animationstart, + NS_ANIMATION_START, + EventNameType_None, + NS_ANIMATION_EVENT) +NON_IDL_EVENT(animationend, + NS_ANIMATION_END, + EventNameType_None, + NS_ANIMATION_EVENT) +NON_IDL_EVENT(animationiteration, + NS_ANIMATION_ITERATION, + EventNameType_None, + NS_ANIMATION_EVENT) + +#ifdef DEFINED_FORWARDED_EVENT +#undef DEFINED_FORWARDED_EVENT +#undef FORWARDED_EVENT +#endif /* DEFINED_FORWARDED_EVENT */ + +#ifdef DEFINED_WINDOW_EVENT +#undef DEFINED_WINDOW_EVENT +#undef WINDOW_EVENT +#endif /* DEFINED_WINDOW_EVENT */ + +#ifdef DEFINED_WINDOW_ONLY_EVENT +#undef DEFINED_WINDOW_ONLY_EVENT +#undef WINDOW_ONLY_EVENT +#endif /* DEFINED_WINDOW_ONLY_EVENT */ + +#ifdef DEFINED_TOUCH_EVENT +#undef DEFINED_TOUCH_EVENT +#undef TOUCH_EVENT +#endif /* DEFINED_TOUCH_EVENT */ + +#ifdef DEFINED_NON_IDL_EVENT +#undef DEFINED_NON_IDL_EVENT +#undef NON_IDL_EVENT +#endif /* DEFINED_NON_IDL_EVENT */ + diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index 035a498449ba..440aff12d994 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -77,7 +77,7 @@ static const char* const sEventNames[] = { "DOMAttrModified", "DOMCharacterDataModified", "DOMActivate", "DOMFocusIn", "DOMFocusOut", "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll", - "offline", "online", "copy", "cut", "paste", "open", "message", + "offline", "online", "copy", "cut", "paste", "open", "message", "show", "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll", "SVGZoom", #ifdef MOZ_SMIL @@ -1257,6 +1257,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType) return sEventNames[eDOMEvents_open]; case NS_MESSAGE: return sEventNames[eDOMEvents_message]; + case NS_SHOW_EVENT: + return sEventNames[eDOMEvents_show]; case NS_SVG_LOAD: return sEventNames[eDOMEvents_SVGLoad]; case NS_SVG_UNLOAD: diff --git a/content/events/src/nsDOMEvent.h b/content/events/src/nsDOMEvent.h index dc02891fab3a..c8a3f726ba1d 100644 --- a/content/events/src/nsDOMEvent.h +++ b/content/events/src/nsDOMEvent.h @@ -138,6 +138,7 @@ public: eDOMEvents_paste, eDOMEvents_open, eDOMEvents_message, + eDOMEvents_show, eDOMEvents_SVGLoad, eDOMEvents_SVGUnload, eDOMEvents_SVGAbort, diff --git a/content/events/src/nsDOMEventTargetHelper.cpp b/content/events/src/nsDOMEventTargetHelper.cpp index 588a5c6db244..fe9f7a47de4f 100644 --- a/content/events/src/nsDOMEventTargetHelper.cpp +++ b/content/events/src/nsDOMEventTargetHelper.cpp @@ -206,26 +206,6 @@ nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound) return mListenerManager; } -nsresult -nsDOMEventTargetHelper::AddEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID) -{ - nsEventListenerManager* elm = GetListenerManager(PR_TRUE); - NS_ENSURE_STATE(elm); - return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); -} - -nsresult -nsDOMEventTargetHelper::RemoveEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID) -{ - nsEventListenerManager* elm = GetListenerManager(PR_FALSE); - if (elm) { - elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); - } - return NS_OK; -} - nsIScriptContext* nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv) { diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 4b29939819d4..546d7bcf3065 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -42,16 +42,6 @@ #include "nsCaret.h" #include "nsIDOMNSEvent.h" #include "nsIDOMEventListener.h" -#include "nsIDOMMouseListener.h" -#include "nsIDOMMouseMotionListener.h" -#include "nsIDOMContextMenuListener.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMFocusListener.h" -#include "nsIDOMFormListener.h" -#include "nsIDOMLoadListener.h" -#include "nsIDOMTextListener.h" -#include "nsIDOMCompositionListener.h" -#include "nsIDOMUIListener.h" #include "nsITextControlFrame.h" #include "nsGkAtoms.h" #include "nsPIDOMWindow.h" @@ -95,13 +85,9 @@ using namespace mozilla::dom; #define EVENT_TYPE_EQUALS( ls, type, userType ) \ - (ls->mEventType && ls->mEventType == type && \ + (ls->mEventType == type && \ (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType)) -#define EVENT_TYPE_DATA_EQUALS( type1, type2 ) \ - (type1 && type2 && type1->iid && type2->iid && \ - type1->iid->Equals(*(type2->iid))) - static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); @@ -138,137 +124,6 @@ MutationBitForEventType(PRUint32 aEventType) return 0; } -typedef -NS_STDCALL_FUNCPROTO(nsresult, - GenericHandler, - nsIDOMEventListener, HandleEvent, - (nsIDOMEvent*)); - -/* - * Things here are not as they appear. Namely, |ifaceListener| below is - * not really a pointer to the nsIDOMEventListener interface, and aMethod is - * not really a pointer-to-member for nsIDOMEventListener. They both - * actually refer to the event-type-specific listener interface. The casting - * magic allows us to use a single dispatch method. This relies on the - * assumption that nsIDOMEventListener and the event type listener interfaces - * have the same object layout and will therefore have compatible - * pointer-to-member implementations. - */ - -static nsresult DispatchToInterface(nsIDOMEvent* aEvent, - nsIDOMEventListener* aListener, - GenericHandler aMethod, - const nsIID& aIID) -{ - nsIDOMEventListener* ifaceListener = nsnull; - nsresult rv = NS_OK; - aListener->QueryInterface(aIID, (void**) &ifaceListener); - NS_WARN_IF_FALSE(ifaceListener, - "DispatchToInterface couldn't QI to the right interface"); - if (ifaceListener) { - rv = (ifaceListener->*aMethod)(aEvent); - NS_RELEASE(ifaceListener); - } - return rv; -} - -struct EventDispatchData -{ - PRUint32 message; - GenericHandler method; -}; - -struct EventTypeData -{ - const EventDispatchData* events; - int numEvents; - const nsIID* iid; -}; - -#define HANDLER(x) reinterpret_cast(x) - -static const EventDispatchData sMouseEvents[] = { - { NS_MOUSE_BUTTON_DOWN, HANDLER(&nsIDOMMouseListener::MouseDown) }, - { NS_MOUSE_BUTTON_UP, HANDLER(&nsIDOMMouseListener::MouseUp) }, - { NS_MOUSE_CLICK, HANDLER(&nsIDOMMouseListener::MouseClick) }, - { NS_MOUSE_DOUBLECLICK, HANDLER(&nsIDOMMouseListener::MouseDblClick) }, - { NS_MOUSE_ENTER_SYNTH, HANDLER(&nsIDOMMouseListener::MouseOver) }, - { NS_MOUSE_EXIT_SYNTH, HANDLER(&nsIDOMMouseListener::MouseOut) } -}; - -static const EventDispatchData sMouseMotionEvents[] = { - { NS_MOUSE_MOVE, HANDLER(&nsIDOMMouseMotionListener::MouseMove) } -}; - -static const EventDispatchData sContextMenuEvents[] = { - { NS_CONTEXTMENU, HANDLER(&nsIDOMContextMenuListener::ContextMenu) } -}; - -static const EventDispatchData sCompositionEvents[] = { - { NS_COMPOSITION_START, - HANDLER(&nsIDOMCompositionListener::HandleStartComposition) }, - { NS_COMPOSITION_END, - HANDLER(&nsIDOMCompositionListener::HandleEndComposition) } -}; - -static const EventDispatchData sTextEvents[] = { - { NS_TEXT_TEXT, HANDLER(&nsIDOMTextListener::HandleText) } -}; - -static const EventDispatchData sKeyEvents[] = { - { NS_KEY_UP, HANDLER(&nsIDOMKeyListener::KeyUp) }, - { NS_KEY_DOWN, HANDLER(&nsIDOMKeyListener::KeyDown) }, - { NS_KEY_PRESS, HANDLER(&nsIDOMKeyListener::KeyPress) } -}; - -static const EventDispatchData sFocusEvents[] = { - { NS_FOCUS_CONTENT, HANDLER(&nsIDOMFocusListener::Focus) }, - { NS_BLUR_CONTENT, HANDLER(&nsIDOMFocusListener::Blur) } -}; - -static const EventDispatchData sFormEvents[] = { - { NS_FORM_SUBMIT, HANDLER(&nsIDOMFormListener::Submit) }, - { NS_FORM_RESET, HANDLER(&nsIDOMFormListener::Reset) }, - { NS_FORM_CHANGE, HANDLER(&nsIDOMFormListener::Change) }, - { NS_FORM_SELECTED, HANDLER(&nsIDOMFormListener::Select) }, - { NS_FORM_INPUT, HANDLER(&nsIDOMFormListener::Input) } -}; - -static const EventDispatchData sLoadEvents[] = { - { NS_LOAD, HANDLER(&nsIDOMLoadListener::Load) }, - { NS_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::Unload) }, - { NS_LOAD_ERROR, HANDLER(&nsIDOMLoadListener::Error) }, - { NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) } -}; - -static const EventDispatchData sUIEvents[] = { - { NS_UI_ACTIVATE, HANDLER(&nsIDOMUIListener::Activate) }, - { NS_UI_FOCUSIN, HANDLER(&nsIDOMUIListener::FocusIn) }, - { NS_UI_FOCUSOUT, HANDLER(&nsIDOMUIListener::FocusOut) } -}; - -#define IMPL_EVENTTYPEDATA(type) \ -{ \ - s##type##Events, \ - NS_ARRAY_LENGTH(s##type##Events), \ - &NS_GET_IID(nsIDOM##type##Listener) \ -} - -// IMPORTANT: indices match up with eEventArrayType_ enum values - -static const EventTypeData sEventTypes[] = { - IMPL_EVENTTYPEDATA(Mouse), - IMPL_EVENTTYPEDATA(MouseMotion), - IMPL_EVENTTYPEDATA(ContextMenu), - IMPL_EVENTTYPEDATA(Key), - IMPL_EVENTTYPEDATA(Load), - IMPL_EVENTTYPEDATA(Focus), - IMPL_EVENTTYPEDATA(Form), - IMPL_EVENTTYPEDATA(Text), - IMPL_EVENTTYPEDATA(Composition), - IMPL_EVENTTYPEDATA(UI) -}; - PRUint32 nsEventListenerManager::sCreatedCount = 0; nsEventListenerManager::nsEventListenerManager(nsISupports* aTarget) : @@ -333,33 +188,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsEventListenerManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_END -const EventTypeData* -nsEventListenerManager::GetTypeDataForIID(const nsIID& aIID) -{ - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) { - if (aIID.Equals(*(sEventTypes[i].iid))) { - return &sEventTypes[i]; - } - } - return nsnull; -} - -const EventTypeData* -nsEventListenerManager::GetTypeDataForEventName(nsIAtom* aName) -{ - PRUint32 event = nsContentUtils::GetEventId(aName); - if (event != NS_USER_DEFINED_EVENT) { - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) { - for (PRInt32 j = 0; j < sEventTypes[i].numEvents; ++j) { - if (event == sEventTypes[i].events[j].message) { - return &sEventTypes[i]; - } - } - } - } - return nsnull; -} - nsPIDOMWindow* nsEventListenerManager::GetInnerWindowForTarget() { @@ -385,38 +213,19 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aTypeAtom, - const EventTypeData* aTypeData, PRInt32 aFlags) { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); - NS_ENSURE_TRUE(aType || aTypeData, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(aType, NS_ERROR_FAILURE); nsRefPtr kungFuDeathGrip = aListener; - if (!aTypeData) { - // If we don't have type data, we can try to QI listener to the right - // interface and set mTypeData only if QI succeeds. This way we can save - // calls to DispatchToInterface (in HandleEvent) in those cases when QI - // would fail. - // @see also DispatchToInterface() - const EventTypeData* td = GetTypeDataForEventName(aTypeAtom); - if (td && td->iid) { - nsIDOMEventListener* ifaceListener = nsnull; - aListener->QueryInterface(*(td->iid), (void**) &ifaceListener); - if (ifaceListener) { - aTypeData = td; - NS_RELEASE(ifaceListener); - } - } - } - nsListenerStruct* ls; PRUint32 count = mListeners.Length(); for (PRUint32 i = 0; i < count; i++) { ls = &mListeners.ElementAt(i); if (ls->mListener == aListener && ls->mFlags == aFlags && - (EVENT_TYPE_EQUALS(ls, aType, aTypeAtom) || - EVENT_TYPE_DATA_EQUALS(aTypeData, ls->mTypeData))) { + EVENT_TYPE_EQUALS(ls, aType, aTypeAtom)) { return NS_OK; } } @@ -430,7 +239,6 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, ls->mTypeAtom = aTypeAtom; ls->mFlags = aFlags; ls->mHandlerIsString = PR_FALSE; - ls->mTypeData = aTypeData; if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) { mMayHaveSystemGroupListeners = PR_TRUE; @@ -491,10 +299,9 @@ void nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aUserType, - const EventTypeData* aTypeData, PRInt32 aFlags) { - if (!aListener || !(aType || aTypeData)) { + if (!aListener || !aType) { return; } @@ -506,9 +313,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, ls = &mListeners.ElementAt(i); if (ls->mListener == aListener && ((ls->mFlags & ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED) == aFlags) && - (EVENT_TYPE_EQUALS(ls, aType, aUserType) || - (!(ls->mEventType) && - EVENT_TYPE_DATA_EQUALS(ls->mTypeData, aTypeData)))) { + EVENT_TYPE_EQUALS(ls, aType, aUserType)) { nsRefPtr kungFuDeathGrip = this; mListeners.RemoveElementAt(i); mNoListenerForEvent = NS_EVENT_TYPE_NULL; @@ -518,33 +323,15 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, } } -nsresult -nsEventListenerManager::AddEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID, - PRInt32 aFlags) +static inline PRBool +ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent) { - return AddEventListener(aListener, NS_EVENT_TYPE_NULL, nsnull, - GetTypeDataForIID(aIID), aFlags); -} - -void -nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID, - PRInt32 aFlags) -{ - RemoveEventListener(aListener, NS_EVENT_TYPE_NULL, nsnull, - GetTypeDataForIID(aIID), aFlags); -} - -PRBool -nsEventListenerManager::ListenerCanHandle(nsListenerStruct* aLs, - nsEvent* aEvent) -{ - if (aEvent->message == NS_USER_DEFINED_EVENT) { - // We don't want to check aLs->mEventType here, bug 276846. - return (aEvent->userType && aLs->mTypeAtom == aEvent->userType); - } - return (aLs->mEventType == aEvent->message); + // This is slightly different from EVENT_TYPE_EQUALS in that it returns + // true even when aEvent->message == NS_USER_DEFINED_EVENT and + // aLs=>mEventType != NS_USER_DEFINED_EVENT as long as the atoms are the same + return aEvent->message == NS_USER_DEFINED_EVENT ? + (aLs->mTypeAtom == aEvent->userType) : + (aLs->mEventType == aEvent->message); } nsresult @@ -554,7 +341,7 @@ nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener, { nsCOMPtr atom = do_GetAtom(NS_LITERAL_STRING("on") + aType); PRUint32 type = nsContentUtils::GetEventId(atom); - return AddEventListener(aListener, type, atom, nsnull, aFlags); + return AddEventListener(aListener, type, atom, aFlags); } void @@ -564,7 +351,7 @@ nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener { nsCOMPtr atom = do_GetAtom(NS_LITERAL_STRING("on") + aType); PRUint32 type = nsContentUtils::GetEventId(atom); - RemoveEventListener(aListener, type, atom, nsnull, aFlags); + RemoveEventListener(aListener, type, atom, aFlags); } nsListenerStruct* @@ -603,7 +390,7 @@ nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName, getter_AddRefs(scriptListener)); if (NS_SUCCEEDED(rv)) { - AddEventListener(scriptListener, eventType, aName, nsnull, + AddEventListener(scriptListener, eventType, aName, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT); ls = FindJSEventListener(eventType, aName); @@ -1078,10 +865,6 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct, return result; } -static PRUint32 sLatestEventType = 0; -static const EventTypeData* sLatestEventTypeData = nsnull; -static const EventDispatchData* sLatestEventDispData = nsnull; - /** * Causes a check for event listeners and processing by them if they exist. * @param an event listener @@ -1101,79 +884,39 @@ nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext, aEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT; } - const EventTypeData* typeData = nsnull; - const EventDispatchData* dispData = nsnull; - if (aEvent->message != NS_USER_DEFINED_EVENT) { - // Check if this is the same type of event as what a listener manager - // handled last time. - if (aEvent->message == sLatestEventType) { - typeData = sLatestEventTypeData; - dispData = sLatestEventDispData; - goto found; - } - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) { - typeData = &sEventTypes[i]; - for (PRInt32 j = 0; j < typeData->numEvents; ++j) { - dispData = &(typeData->events[j]); - if (aEvent->message == dispData->message) { - sLatestEventType = aEvent->message; - sLatestEventTypeData = typeData; - sLatestEventDispData = dispData; - goto found; - } - } - typeData = nsnull; - dispData = nsnull; - } - } - -found: - nsAutoTObserverArray::EndLimitedIterator iter(mListeners); nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent)); PRBool hasListener = PR_FALSE; while (iter.HasMore()) { nsListenerStruct* ls = &iter.GetNext(); - PRBool useTypeInterface = - EVENT_TYPE_DATA_EQUALS(ls->mTypeData, typeData); - PRBool useGenericInterface = - (!useTypeInterface && ListenerCanHandle(ls, aEvent)); - // Don't fire the listener if it's been removed. // Check that the phase is same in event and event listener. // Handle only trusted events, except when listener permits untrusted events. - if (useTypeInterface || useGenericInterface) { - if (ls->mListener) { - hasListener = PR_TRUE; - // XXX The (mFlags & aFlags) test here seems fragile. Shouldn't we - // specifically only test the capture/bubble flags. - if ((ls->mFlags & aFlags & ~NS_EVENT_FLAG_SYSTEM_EVENT) && - (ls->mFlags & NS_EVENT_FLAG_SYSTEM_EVENT) == - (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) && - (NS_IS_TRUSTED_EVENT(aEvent) || - ls->mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED)) { - if (!*aDOMEvent) { - nsEventDispatcher::CreateEvent(aPresContext, aEvent, - EmptyString(), aDOMEvent); - } - if (*aDOMEvent) { + if (ListenerCanHandle(ls, aEvent)) { + hasListener = PR_TRUE; + // XXX The (mFlags & aFlags) test here seems fragile. Shouldn't we + // specifically only test the capture/bubble flags. + if ((ls->mFlags & aFlags & ~NS_EVENT_FLAG_SYSTEM_EVENT) && + (ls->mFlags & NS_EVENT_FLAG_SYSTEM_EVENT) == + (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) && + (NS_IS_TRUSTED_EVENT(aEvent) || + ls->mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED)) { + if (!*aDOMEvent) { + nsEventDispatcher::CreateEvent(aPresContext, aEvent, + EmptyString(), aDOMEvent); + } + if (*aDOMEvent) { + if (!aEvent->currentTarget) { + aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent(); if (!aEvent->currentTarget) { - aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent(); - if (!aEvent->currentTarget) { - break; - } + break; } - nsRefPtr kungFuDeathGrip = ls->mListener; - if (useTypeInterface) { - aPusher->Pop(); - DispatchToInterface(*aDOMEvent, ls->mListener, - dispData->method, *typeData->iid); - } else if (useGenericInterface && - aPusher->RePush(aCurrentTarget)) { - if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent, - aCurrentTarget, aFlags, - aPusher))) { - aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN; - } + } + nsRefPtr kungFuDeathGrip = ls->mListener; + if (aPusher->RePush(aCurrentTarget)) { + if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent, + aCurrentTarget, aFlags, + aPusher))) { + aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN; } } } @@ -1267,30 +1010,11 @@ PRBool nsEventListenerManager::HasListenersFor(const nsAString& aEventName) { nsCOMPtr atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventName); - PRUint32 type = nsContentUtils::GetEventId(atom); - - const EventTypeData* typeData = nsnull; - const EventDispatchData* dispData = nsnull; - if (type != NS_USER_DEFINED_EVENT) { - for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(sEventTypes); ++i) { - typeData = &sEventTypes[i]; - for (PRInt32 j = 0; j < typeData->numEvents; ++j) { - dispData = &(typeData->events[j]); - if (type == dispData->message) { - goto found; - } - } - typeData = nsnull; - dispData = nsnull; - } - } -found: PRUint32 count = mListeners.Length(); for (PRUint32 i = 0; i < count; ++i) { nsListenerStruct* ls = &mListeners.ElementAt(i); - if (ls->mTypeAtom == atom || - EVENT_TYPE_DATA_EQUALS(ls->mTypeData, typeData)) { + if (ls->mTypeAtom == atom) { return PR_TRUE; } } @@ -1329,43 +1053,13 @@ nsEventListenerManager::GetListenerInfo(nsCOMArray* aList) PR_TRUE); } } - if (ls.mTypeData) { - // Handle special event listener interfaces, like nsIDOMFocusListener. - for (PRInt32 j = 0; j < ls.mTypeData->numEvents; ++j) { - const EventDispatchData* dispData = &(ls.mTypeData->events[j]); - const char* eventName = nsDOMEvent::GetEventName(dispData->message); - if (eventName) { - NS_ConvertASCIItoUTF16 eventType(eventName); - nsRefPtr info = - new nsEventListenerInfo(eventType, ls.mListener, capturing, - allowsUntrusted, systemGroup); - NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY); - aList->AppendObject(info); - } - } - } else if (ls.mEventType == NS_USER_DEFINED_EVENT) { - // Handle user defined event types. - if (ls.mTypeAtom) { - const nsDependentSubstring& eventType = - Substring(nsDependentAtomString(ls.mTypeAtom), 2); - nsRefPtr info = - new nsEventListenerInfo(eventType, ls.mListener, capturing, - allowsUntrusted, systemGroup); - NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY); - aList->AppendObject(info); - } - } else { - // Handle normal events. - const char* eventName = nsDOMEvent::GetEventName(ls.mEventType); - if (eventName) { - NS_ConvertASCIItoUTF16 eventType(eventName); - nsRefPtr info = - new nsEventListenerInfo(eventType, ls.mListener, capturing, - allowsUntrusted, systemGroup); - NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY); - aList->AppendObject(info); - } - } + const nsDependentSubstring& eventType = + Substring(nsDependentAtomString(ls.mTypeAtom), 2); + nsRefPtr info = + new nsEventListenerInfo(eventType, ls.mListener, capturing, + allowsUntrusted, systemGroup); + NS_ENSURE_TRUE(info, NS_ERROR_OUT_OF_MEMORY); + aList->AppendObject(info); } return NS_OK; } @@ -1377,9 +1071,7 @@ nsEventListenerManager::HasUnloadListeners() for (PRUint32 i = 0; i < count; ++i) { nsListenerStruct* ls = &mListeners.ElementAt(i); if (ls->mEventType == NS_PAGE_UNLOAD || - ls->mEventType == NS_BEFORE_PAGE_UNLOAD || - (ls->mTypeData && ls->mTypeData->iid && - ls->mTypeData->iid->Equals(NS_GET_IID(nsIDOMLoadListener)))) { + ls->mEventType == NS_BEFORE_PAGE_UNLOAD) { return PR_TRUE; } } diff --git a/content/events/src/nsEventListenerManager.h b/content/events/src/nsEventListenerManager.h index d0570064f7c1..506fea2a80dd 100644 --- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -67,7 +67,6 @@ typedef struct { nsCOMPtr mTypeAtom; PRUint16 mFlags; PRBool mHandlerIsString; - const EventTypeData* mTypeData; } nsListenerStruct; /* @@ -97,10 +96,6 @@ public: * Sets events listeners of all types. * @param an event listener */ - nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID, PRInt32 aFlags); - void RemoveEventListenerByIID(nsIDOMEventListener *aListener, - const nsIID& aIID, PRInt32 aFlags); nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsAString& type, PRInt32 aFlags); @@ -218,17 +213,14 @@ protected: nsresult AddEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aTypeAtom, - const EventTypeData* aTypeData, PRInt32 aFlags); void RemoveEventListener(nsIDOMEventListener *aListener, PRUint32 aType, nsIAtom* aUserType, - const EventTypeData* aTypeData, PRInt32 aFlags); void RemoveAllListeners(); const EventTypeData* GetTypeDataForIID(const nsIID& aIID); const EventTypeData* GetTypeDataForEventName(nsIAtom* aName); - PRBool ListenerCanHandle(nsListenerStruct* aLs, nsEvent* aEvent); nsPIDOMWindow* GetInnerWindowForTarget(); PRUint32 mMayHavePaintEventListener : 1; diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 30e239af5f27..6cda116b39d5 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -141,6 +141,10 @@ #ifdef XP_MACOSX #import + +#ifdef MOZ_WIDGET_COCOA +#include "nsCocoaFeatures.h" +#endif #endif using namespace mozilla; @@ -373,6 +377,7 @@ public: static void OnEvent(nsEvent* aEvent); static void Shutdown(); static PRUint32 GetTimeoutTime(); + static PRUint32 GetGestureTimeoutTime(); static PRInt32 AccelerateWheelDelta(PRInt32 aScrollLines, PRBool aIsHorizontal, PRBool aAllowScrollSpeedOverride, nsIScrollableFrame::ScrollUnit *aScrollQuantity, @@ -382,6 +387,10 @@ public: enum { kScrollSeriesTimeout = 80 }; +#ifdef MOZ_WIDGET_COCOA + static PRBool GetGestureTriggered(); + static void SetGestureTriggered(); +#endif protected: static nsIntPoint GetScreenPoint(nsGUIEvent* aEvent); static void OnFailToScrollTarget(); @@ -402,6 +411,9 @@ protected: static PRUint32 sMouseMoved; // in milliseconds static nsITimer* sTimer; static PRInt32 sScrollSeriesCounter; +#ifdef MOZ_WIDGET_COCOA + static PRUint32 sGestureTriggered; // in milliseconds +#endif }; nsWeakFrame nsMouseWheelTransaction::sTargetFrame(nsnull); @@ -409,6 +421,9 @@ PRUint32 nsMouseWheelTransaction::sTime = 0; PRUint32 nsMouseWheelTransaction::sMouseMoved = 0; nsITimer* nsMouseWheelTransaction::sTimer = nsnull; PRInt32 nsMouseWheelTransaction::sScrollSeriesCounter = 0; +#ifdef MOZ_WIDGET_COCOA +PRUint32 nsMouseWheelTransaction::sGestureTriggered = 0; +#endif static PRBool OutOfTime(PRUint32 aBaseTime, PRUint32 aThreshold) @@ -487,8 +502,29 @@ nsMouseWheelTransaction::EndTransaction() sTimer->Cancel(); sTargetFrame = nsnull; sScrollSeriesCounter = 0; +#ifdef MOZ_WIDGET_COCOA + sGestureTriggered = 0; +#endif } +#ifdef MOZ_WIDGET_COCOA +void +nsMouseWheelTransaction::SetGestureTriggered() { + sGestureTriggered = PR_IntervalToMilliseconds(PR_IntervalNow()); +} + +PRBool +nsMouseWheelTransaction::GetGestureTriggered() { + if (sGestureTriggered != 0 && + OutOfTime(sGestureTriggered, GetGestureTimeoutTime())) { + // Start accepting new gestures + sGestureTriggered = 0; + } + + return sGestureTriggered != 0; +} +#endif + void nsMouseWheelTransaction::OnEvent(nsEvent* aEvent) { @@ -634,6 +670,12 @@ nsMouseWheelTransaction::GetScreenPoint(nsGUIEvent* aEvent) return aEvent->refPoint + aEvent->widget->WidgetToScreenOffset(); } +PRUint32 +nsMouseWheelTransaction::GetGestureTimeoutTime() +{ + return Preferences::GetUint("mousewheel.transaction.gesturetimeout", 300); +} + PRUint32 nsMouseWheelTransaction::GetTimeoutTime() { @@ -2797,6 +2839,22 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame, } } +#ifdef MOZ_WIDGET_COCOA + // On lion scroll will trigger back/forward at the edge of the page + if (isHorizontal && passToParent && nsCocoaFeatures::OnLionOrLater()) { + if (!nsMouseWheelTransaction::GetGestureTriggered()) { + if (numLines > 4 || numLines < -4) { + DoScrollHistory(-numLines); + nsMouseWheelTransaction::SetGestureTriggered(); + return NS_OK; + } + } else { + // Extend the gesture in progress + nsMouseWheelTransaction::SetGestureTriggered(); + } + } +#endif + if (!passToParent && frameToScroll) { if (aScrollQuantity == nsIScrollableFrame::LINES) { // When this is called for querying the scroll target information, diff --git a/content/html/content/public/Makefile.in b/content/html/content/public/Makefile.in index c6fe08c1b2e6..c38fa5a4a93f 100644 --- a/content/html/content/public/Makefile.in +++ b/content/html/content/public/Makefile.in @@ -48,6 +48,8 @@ XPIDL_MODULE = content_html XPIDLSRCS = \ nsIFormSubmitObserver.idl \ nsIPhonetic.idl \ + nsIHTMLMenu.idl \ + nsIMenuBuilder.idl \ $(NULL) EXPORTS = \ diff --git a/dom/public/coreEvents/nsIDOMMouseMotionListener.h b/content/html/content/public/nsIHTMLMenu.idl similarity index 51% rename from dom/public/coreEvents/nsIDOMMouseMotionListener.h rename to content/html/content/public/nsIHTMLMenu.idl index 44ba7b0c77e9..8496d2da768e 100644 --- a/dom/public/coreEvents/nsIDOMMouseMotionListener.h +++ b/content/html/content/public/nsIHTMLMenu.idl @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,11 +12,10 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -35,43 +34,40 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsISupports.idl" -#ifndef nsIDOMMouseMotionListener_h__ -#define nsIDOMMouseMotionListener_h__ +interface nsIMenuBuilder; -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Mouse motion event listener - * +/** + * A private interface. + * All methods throw NS_ERROR_DOM_SECURITY_ERR if the caller is not chrome. */ -#define NS_IDOMMOUSEMOTIONLISTENER_IID \ -{ /* 162b3480-ded6-11d1-bd85-00805f8ae3f4 */ \ -0x162b3480, 0xded6, 0x11d1, \ -{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } -class nsIDOMMouseMotionListener : public nsIDOMEventListener { - -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMMOUSEMOTIONLISTENER_IID) +[scriptable, uuid(d3d068d8-e223-4228-ba39-4d6df21ba616)] +interface nsIHTMLMenu : nsISupports +{ /** - * Processes a mouse move event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a drag move event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult + * Creates and dispatches a trusted event named "show". + * The event is not cancelable and does not bubble. + * See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#context-menus */ - NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent) = 0; + void sendShowEvent(); + + /** + * Creates a native menu builder. The builder type is dependent on menu type. + * Currently, it returns nsXULContextMenuBuilder for context menus. + * Toolbar menus are not yet supported (the method returns null). + */ + nsIMenuBuilder createBuilder(); + + /* + * Builds a menu by iterating over menu children. + * See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#building-menus-and-toolbars + * The caller can use a native builder by calling createBuilder() or provide + * a custom builder that implements the nsIMenuBuilder interface. + * A custom builder can be used for example to build native context menus + * that are not defined using . + */ + void build(in nsIMenuBuilder aBuilder); }; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMMouseMotionListener, - NS_IDOMMOUSEMOTIONLISTENER_IID) - -#endif // nsIDOMMouseMotionListener_h__ diff --git a/content/html/content/public/nsIMenuBuilder.idl b/content/html/content/public/nsIMenuBuilder.idl new file mode 100644 index 000000000000..09bae6db1d57 --- /dev/null +++ b/content/html/content/public/nsIMenuBuilder.idl @@ -0,0 +1,83 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIDOMHTMLMenuItemElement; + +/** + * An interface used to construct native toolbar or context menus from + */ + +[scriptable, uuid(12724737-f7db-43b4-94ab-708a7b86e115)] +interface nsIMenuBuilder : nsISupports +{ + + /** + * Create the top level menu or a submenu. The implementation should create + * a new context for this menu, so all subsequent methods will add new items + * to this newly created menu. + */ + void openContainer(in DOMString aLabel); + + /** + * Add a new menu item. All menu item details can be obtained from + * the element. This method is not called for hidden elements or elements + * with no or empty label. The icon should be loaded only if aCanLoadIcon + * is true. + */ + void addItemFor(in nsIDOMHTMLMenuItemElement aElement, + in boolean aCanLoadIcon); + + /** + * Create a new separator. + */ + void addSeparator(); + + /** + * Remove last added separator. + * Sometimes it's needed to remove last added separator, otherwise it's not + * possible to implement the postprocessing in one pass. + * See http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#building-menus-and-toolbars + */ + void undoAddSeparator(); + + /** + * Set the context to the parent menu. + */ + void closeContainer(); + +}; diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in index 3ab42a0b52ce..71f54bf4e1b4 100644 --- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -82,6 +82,8 @@ CPPSRCS = \ nsHTMLLegendElement.cpp \ nsHTMLLinkElement.cpp \ nsHTMLMapElement.cpp \ + nsHTMLMenuElement.cpp \ + nsHTMLMenuItemElement.cpp \ nsHTMLMetaElement.cpp \ nsHTMLModElement.cpp \ nsHTMLObjectElement.cpp \ @@ -134,6 +136,7 @@ INCLUDES += \ -I$(srcdir)/../../../base/src \ -I$(srcdir)/../../../events/src \ -I$(srcdir)/../../../xbl/src \ + -I$(srcdir)/../../../xul/content/src \ -I$(srcdir)/../../../../layout/forms \ -I$(srcdir)/../../../../layout/style \ -I$(srcdir)/../../../../layout/tables \ diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index b26e36e26934..9d529f350a0b 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -50,6 +50,7 @@ #include "nsIDOMAttr.h" #include "nsIDOMDocumentFragment.h" #include "nsIDOMNSHTMLElement.h" +#include "nsIDOMHTMLMenuElement.h" #include "nsIDOMElementCSSInlineStyle.h" #include "nsIDOMWindow.h" #include "nsIDOMDocument.h" @@ -115,6 +116,7 @@ #include "nsITextControlElement.h" #include "mozilla/dom/Element.h" #include "nsHTMLFieldSetElement.h" +#include "nsHTMLMenuElement.h" #include "mozilla/Preferences.h" @@ -2451,6 +2453,28 @@ nsGenericHTMLElement::GetIsContentEditable(PRBool* aContentEditable) return NS_OK; } +nsresult +nsGenericHTMLElement::GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu) +{ + *aContextMenu = nsnull; + + nsAutoString value; + GetAttr(kNameSpaceID_None, nsGkAtoms::contextmenu, value); + + if (value.IsEmpty()) { + return NS_OK; + } + + nsIDocument* doc = GetCurrentDoc(); + if (doc) { + nsRefPtr element = + nsHTMLMenuElement::FromContent(doc->GetElementById(value)); + element.forget(aContextMenu); + } + + return NS_OK; +} + //---------------------------------------------------------------------- NS_IMPL_INT_ATTR(nsGenericHTMLFrameElement, TabIndex, tabindex) diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index af428736e755..daaca7356dd5 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -66,6 +66,7 @@ struct nsRect; struct nsSize; class nsHTMLFormElement; class nsIDOMDOMStringMap; +class nsIDOMHTMLMenuElement; typedef nsMappedAttributeElement nsGenericHTMLElementBase; @@ -161,6 +162,7 @@ public: nsresult GetDataset(nsIDOMDOMStringMap** aDataset); // Callback for destructor of of dataset to ensure to null out weak pointer. nsresult ClearDataset(); + nsresult GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu); // Implementation for nsIContent virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, @@ -533,6 +535,11 @@ public: return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); } + PRBool IsHidden() const + { + return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden); + } + protected: /** * Add/remove this element to the documents name cache @@ -1471,22 +1478,22 @@ protected: NS_INTERFACE_TABLE_ENTRY(_class, _i10) \ NS_OFFSET_AND_INTERFACE_TABLE_END -/* Use this macro to declare functions that forward the behavior of this interface to another object. - This macro doesn't forward Focus or Click because sometimes elements will want to override them. */ -#define NS_FORWARD_NSIDOMHTMLELEMENT_NOFOCUSCLICK(_to) \ - NS_SCRIPTABLE NS_IMETHOD GetId(nsAString & aId) { return _to GetId(aId); } \ - NS_SCRIPTABLE NS_IMETHOD SetId(const nsAString & aId) { return _to SetId(aId); } \ - NS_SCRIPTABLE NS_IMETHOD GetTitle(nsAString & aTitle) { return _to GetTitle(aTitle); } \ - NS_SCRIPTABLE NS_IMETHOD SetTitle(const nsAString & aTitle) { return _to SetTitle(aTitle); } \ - NS_SCRIPTABLE NS_IMETHOD GetLang(nsAString & aLang) { return _to GetLang(aLang); } \ - NS_SCRIPTABLE NS_IMETHOD SetLang(const nsAString & aLang) { return _to SetLang(aLang); } \ - NS_SCRIPTABLE NS_IMETHOD GetDir(nsAString & aDir) { return _to GetDir(aDir); } \ - NS_SCRIPTABLE NS_IMETHOD SetDir(const nsAString & aDir) { return _to SetDir(aDir); } \ - NS_SCRIPTABLE NS_IMETHOD GetClassName(nsAString & aClassName) { return _to GetClassName(aClassName); } \ - NS_SCRIPTABLE NS_IMETHOD SetClassName(const nsAString & aClassName) { return _to SetClassName(aClassName); } \ - NS_SCRIPTABLE NS_IMETHOD GetAccessKey(nsAString & aAccessKey) { return _to GetAccessKey(aAccessKey); } \ - NS_SCRIPTABLE NS_IMETHOD SetAccessKey(const nsAString & aAccessKey) { return _to SetAccessKey(aAccessKey); } \ - NS_SCRIPTABLE NS_IMETHOD GetAccessKeyLabel(nsAString & aLabel) { return _to GetAccessKeyLabel(aLabel); } \ +/* Use this macro to declare functions that forward the behavior of this interface to another object. + This macro doesn't forward Focus or Click because sometimes elements will want to override them. */ +#define NS_FORWARD_NSIDOMHTMLELEMENT_NOFOCUSCLICK(_to) \ + NS_SCRIPTABLE NS_IMETHOD GetId(nsAString & aId) { return _to GetId(aId); } \ + NS_SCRIPTABLE NS_IMETHOD SetId(const nsAString & aId) { return _to SetId(aId); } \ + NS_SCRIPTABLE NS_IMETHOD GetTitle(nsAString & aTitle) { return _to GetTitle(aTitle); } \ + NS_SCRIPTABLE NS_IMETHOD SetTitle(const nsAString & aTitle) { return _to SetTitle(aTitle); } \ + NS_SCRIPTABLE NS_IMETHOD GetLang(nsAString & aLang) { return _to GetLang(aLang); } \ + NS_SCRIPTABLE NS_IMETHOD SetLang(const nsAString & aLang) { return _to SetLang(aLang); } \ + NS_SCRIPTABLE NS_IMETHOD GetDir(nsAString & aDir) { return _to GetDir(aDir); } \ + NS_SCRIPTABLE NS_IMETHOD SetDir(const nsAString & aDir) { return _to SetDir(aDir); } \ + NS_SCRIPTABLE NS_IMETHOD GetClassName(nsAString & aClassName) { return _to GetClassName(aClassName); } \ + NS_SCRIPTABLE NS_IMETHOD SetClassName(const nsAString & aClassName) { return _to SetClassName(aClassName); } \ + NS_SCRIPTABLE NS_IMETHOD GetAccessKey(nsAString & aAccessKey) { return _to GetAccessKey(aAccessKey); } \ + NS_SCRIPTABLE NS_IMETHOD SetAccessKey(const nsAString & aAccessKey) { return _to SetAccessKey(aAccessKey); } \ + NS_SCRIPTABLE NS_IMETHOD GetAccessKeyLabel(nsAString & aLabel) { return _to GetAccessKeyLabel(aLabel); } \ NS_SCRIPTABLE NS_IMETHOD Blur(void) { return _to Blur(); } /** @@ -1563,6 +1570,8 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Label) NS_DECLARE_NS_NEW_HTML_ELEMENT(Legend) NS_DECLARE_NS_NEW_HTML_ELEMENT(Link) NS_DECLARE_NS_NEW_HTML_ELEMENT(Map) +NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu) +NS_DECLARE_NS_NEW_HTML_ELEMENT(MenuItem) NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta) NS_DECLARE_NS_NEW_HTML_ELEMENT(Object) NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup) diff --git a/content/html/content/src/nsHTMLMenuElement.cpp b/content/html/content/src/nsHTMLMenuElement.cpp new file mode 100644 index 000000000000..1921ac4dd06a --- /dev/null +++ b/content/html/content/src/nsHTMLMenuElement.cpp @@ -0,0 +1,289 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIDOMNSHTMLElement.h" +#include "nsIDOMHTMLMenuItemElement.h" +#include "nsXULContextMenuBuilder.h" +#include "nsGUIEvent.h" +#include "nsEventDispatcher.h" +#include "nsHTMLMenuItemElement.h" +#include "nsHTMLMenuElement.h" + +enum MenuType +{ + MENU_TYPE_CONTEXT = 1, + MENU_TYPE_TOOLBAR, + MENU_TYPE_LIST +}; + +static const nsAttrValue::EnumTable kMenuTypeTable[] = { + { "context", MENU_TYPE_CONTEXT }, + { "toolbar", MENU_TYPE_TOOLBAR }, + { "list", MENU_TYPE_LIST }, + { 0 } +}; + +static const nsAttrValue::EnumTable* kMenuDefaultType = + &kMenuTypeTable[2]; + +enum SeparatorType +{ + ST_TRUE_INIT = -1, + ST_FALSE = 0, + ST_TRUE = 1 +}; + +NS_IMPL_NS_NEW_HTML_ELEMENT(Menu) + + +nsHTMLMenuElement::nsHTMLMenuElement(already_AddRefed aNodeInfo) + : nsGenericHTMLElement(aNodeInfo), mType(MENU_TYPE_LIST) +{ +} + +nsHTMLMenuElement::~nsHTMLMenuElement() +{ +} + + +NS_IMPL_ADDREF_INHERITED(nsHTMLMenuElement, nsGenericElement) +NS_IMPL_RELEASE_INHERITED(nsHTMLMenuElement, nsGenericElement) + + +DOMCI_NODE_DATA(HTMLMenuElement, nsHTMLMenuElement) + +// QueryInterface implementation for nsHTMLMenuElement +NS_INTERFACE_TABLE_HEAD(nsHTMLMenuElement) + NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLMenuElement, + nsIDOMHTMLMenuElement, + nsIHTMLMenu) + NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMenuElement, + nsGenericHTMLElement) +NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMenuElement) + +NS_IMPL_ELEMENT_CLONE(nsHTMLMenuElement) + +NS_IMPL_BOOL_ATTR(nsHTMLMenuElement, Compact, compact) +NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMenuElement, Type, type, + kMenuDefaultType->tag) +NS_IMPL_STRING_ATTR(nsHTMLMenuElement, Label, label) + + +NS_IMETHODIMP +nsHTMLMenuElement::SendShowEvent() +{ + NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR); + + nsCOMPtr document = GetCurrentDoc(); + if (!document) { + return NS_ERROR_FAILURE; + } + + nsEvent event(PR_TRUE, NS_SHOW_EVENT); + event.flags |= NS_EVENT_FLAG_CANT_CANCEL | NS_EVENT_FLAG_CANT_BUBBLE; + + nsCOMPtr shell = document->GetShell(); + if (!shell) { + return NS_ERROR_FAILURE; + } + + nsRefPtr presContext = shell->GetPresContext(); + nsEventStatus status = nsEventStatus_eIgnore; + nsEventDispatcher::Dispatch(static_cast(this), presContext, + &event, nsnull, &status); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLMenuElement::CreateBuilder(nsIMenuBuilder** _retval) +{ + NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR); + + *_retval = nsnull; + + if (mType == MENU_TYPE_CONTEXT) { + NS_ADDREF(*_retval = new nsXULContextMenuBuilder()); + } + + return NS_OK; +} + + +NS_IMETHODIMP +nsHTMLMenuElement::Build(nsIMenuBuilder* aBuilder) +{ + NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR); + + if (!aBuilder) { + return NS_OK; + } + + BuildSubmenu(EmptyString(), this, aBuilder); + + return NS_OK; +} + + +PRBool +nsHTMLMenuElement::ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult) +{ + if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::type) { + PRBool success = aResult.ParseEnumValue(aValue, kMenuTypeTable, + PR_FALSE); + if (success) { + mType = aResult.GetEnumValue(); + } else { + mType = kMenuDefaultType->value; + } + + return success; + } + + return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, + aResult); +} + +void +nsHTMLMenuElement::BuildSubmenu(const nsAString& aLabel, + nsIContent* aContent, + nsIMenuBuilder* aBuilder) +{ + aBuilder->OpenContainer(aLabel); + + PRInt8 separator = ST_TRUE_INIT; + TraverseContent(aContent, aBuilder, separator); + + if (separator == ST_TRUE) { + aBuilder->UndoAddSeparator(); + } + + aBuilder->CloseContainer(); +} + +// static +PRBool +nsHTMLMenuElement::CanLoadIcon(nsIContent* aContent, const nsAString& aIcon) +{ + if (aIcon.IsEmpty()) { + return PR_FALSE; + } + + nsIDocument* doc = aContent->GetOwnerDoc(); + if (!doc) { + return PR_FALSE; + } + + nsCOMPtr baseURI = aContent->GetBaseURI(); + nsCOMPtr uri; + nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri), aIcon, doc, + baseURI); + + if (!uri) { + return PR_FALSE; + } + + return nsContentUtils::CanLoadImage(uri, aContent, doc, + aContent->NodePrincipal()); +} + +void +nsHTMLMenuElement::TraverseContent(nsIContent* aContent, + nsIMenuBuilder* aBuilder, + PRInt8& aSeparator) +{ + nsCOMPtr child; + for (child = aContent->GetFirstChild(); child; + child = child->GetNextSibling()) { + nsGenericHTMLElement* element = nsGenericHTMLElement::FromContent(child); + if (!element) { + continue; + } + + nsIAtom* tag = child->Tag(); + + if (tag == nsGkAtoms::menuitem) { + nsHTMLMenuItemElement* menuitem = + nsHTMLMenuItemElement::FromContent(child); + + if (menuitem->IsHidden()) { + continue; + } + + nsAutoString label; + menuitem->GetLabel(label); + if (label.IsEmpty()) { + continue; + } + + nsAutoString icon; + menuitem->GetIcon(icon); + + aBuilder->AddItemFor(menuitem, CanLoadIcon(child, icon)); + + aSeparator = ST_FALSE; + } else if (tag == nsGkAtoms::menu && !element->IsHidden()) { + if (child->HasAttr(kNameSpaceID_None, nsGkAtoms::label)) { + nsAutoString label; + child->GetAttr(kNameSpaceID_None, nsGkAtoms::label, label); + + BuildSubmenu(label, child, aBuilder); + + aSeparator = ST_FALSE; + } else { + AddSeparator(aBuilder, aSeparator); + + TraverseContent(child, aBuilder, aSeparator); + + AddSeparator(aBuilder, aSeparator); + } + } + } +} + +inline void +nsHTMLMenuElement::AddSeparator(nsIMenuBuilder* aBuilder, PRInt8& aSeparator) +{ + if (aSeparator) { + return; + } + + aBuilder->AddSeparator(); + aSeparator = ST_TRUE; +} diff --git a/content/html/content/src/nsHTMLMenuElement.h b/content/html/content/src/nsHTMLMenuElement.h new file mode 100644 index 000000000000..a44ef7dea865 --- /dev/null +++ b/content/html/content/src/nsHTMLMenuElement.h @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIDOMHTMLMenuElement.h" +#include "nsIHTMLMenu.h" +#include "nsGenericHTMLElement.h" +#include "nsIDOMNSHTMLElement.h" + +class nsHTMLMenuElement : public nsGenericHTMLElement, + public nsIDOMHTMLMenuElement, + public nsIHTMLMenu +{ +public: + nsHTMLMenuElement(already_AddRefed aNodeInfo); + virtual ~nsHTMLMenuElement(); + + /** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/ + static nsHTMLMenuElement* FromContent(nsIContent* aContent) + { + if (aContent && aContent->IsHTML(nsGkAtoms::menu)) + return static_cast(aContent); + return nsnull; + } + + // nsISupports + NS_DECL_ISUPPORTS_INHERITED + + // nsIDOMNode + NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::) + + // nsIDOMElement + NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::) + + // nsIDOMHTMLElement + NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::) + + // nsIDOMHTMLMenuElement + NS_DECL_NSIDOMHTMLMENUELEMENT + + // nsIHTMLMenu + NS_DECL_NSIHTMLMENU + + virtual PRBool ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); + + virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + + virtual nsXPCClassInfo* GetClassInfo(); + + PRUint8 GetType() const { return mType; } + +protected: + static PRBool CanLoadIcon(nsIContent* aContent, const nsAString& aIcon); + + void BuildSubmenu(const nsAString& aLabel, + nsIContent* aContent, + nsIMenuBuilder* aBuilder); + + void TraverseContent(nsIContent* aContent, + nsIMenuBuilder* aBuilder, + PRInt8& aSeparator); + + void AddSeparator(nsIMenuBuilder* aBuilder, PRInt8& aSeparator); + + PRUint8 mType; +}; diff --git a/content/html/content/src/nsHTMLMenuItemElement.cpp b/content/html/content/src/nsHTMLMenuItemElement.cpp new file mode 100644 index 000000000000..e456bb8b4c2c --- /dev/null +++ b/content/html/content/src/nsHTMLMenuItemElement.cpp @@ -0,0 +1,514 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsGUIEvent.h" +#include "nsEventDispatcher.h" +#include "nsHTMLMenuItemElement.h" + +using namespace mozilla::dom; + +// First bits are needed for the menuitem type. +#define NS_CHECKED_IS_TOGGLED (1 << 2) +#define NS_ORIGINAL_CHECKED_VALUE (1 << 3) +#define NS_MENUITEM_TYPE(bits) ((bits) & ~( \ + NS_CHECKED_IS_TOGGLED | NS_ORIGINAL_CHECKED_VALUE)) + +enum CmdType +{ + CMD_TYPE_MENUITEM = 1, + CMD_TYPE_CHECKBOX, + CMD_TYPE_RADIO +}; + +static const nsAttrValue::EnumTable kMenuItemTypeTable[] = { + { "menuitem", CMD_TYPE_MENUITEM }, + { "checkbox", CMD_TYPE_CHECKBOX }, + { "radio", CMD_TYPE_RADIO }, + { 0 } +}; + +static const nsAttrValue::EnumTable* kMenuItemDefaultType = + &kMenuItemTypeTable[0]; + +// A base class inherited by all radio visitors. +class Visitor +{ +public: + Visitor() { } + virtual ~Visitor() { } + + /** + * Visit a node in the tree. This is meant to be called on all radios in a + * group, sequentially. If the method returns false then the iteration is + * stopped. + */ + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) = 0; +}; + +// Find the selected radio, see GetSelectedRadio(). +class GetCheckedVisitor : public Visitor +{ +public: + GetCheckedVisitor(nsHTMLMenuItemElement** aResult) + : mResult(aResult) + { } + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) + { + if (aMenuItem->IsChecked()) { + *mResult = aMenuItem; + return PR_FALSE; + } + return PR_TRUE; + } +protected: + nsHTMLMenuItemElement** mResult; +}; + +// Deselect all radios except the one passed to the constructor. +class ClearCheckedVisitor : public Visitor +{ +public: + ClearCheckedVisitor(nsHTMLMenuItemElement* aExcludeMenuItem) + : mExcludeMenuItem(aExcludeMenuItem) + { } + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) + { + if (aMenuItem != mExcludeMenuItem && aMenuItem->IsChecked()) { + aMenuItem->ClearChecked(); + } + return PR_TRUE; + } +protected: + nsHTMLMenuItemElement* mExcludeMenuItem; +}; + +// Get current value of the checked dirty flag. The same value is stored on all +// radios in the group, so we need to check only the first one. +class GetCheckedDirtyVisitor : public Visitor +{ +public: + GetCheckedDirtyVisitor(PRBool* aCheckedDirty, + nsHTMLMenuItemElement* aExcludeMenuItem) + : mCheckedDirty(aCheckedDirty), + mExcludeMenuItem(aExcludeMenuItem) + { } + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) + { + if (aMenuItem == mExcludeMenuItem) { + return PR_TRUE; + } + *mCheckedDirty = aMenuItem->IsCheckedDirty(); + return PR_FALSE; + } +protected: + PRBool* mCheckedDirty; + nsHTMLMenuItemElement* mExcludeMenuItem; +}; + +// Set checked dirty to true on all radios in the group. +class SetCheckedDirtyVisitor : public Visitor +{ +public: + SetCheckedDirtyVisitor() + { } + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) + { + aMenuItem->SetCheckedDirty(); + return PR_TRUE; + } +}; + +// A helper visitor that is used to combine two operations (visitors) to avoid +// iterating over radios twice. +class CombinedVisitor : public Visitor +{ +public: + CombinedVisitor(Visitor* aVisitor1, Visitor* aVisitor2) + : mVisitor1(aVisitor1), mVisitor2(aVisitor2), + mContinue1(PR_TRUE), mContinue2(PR_TRUE) + { } + virtual PRBool Visit(nsHTMLMenuItemElement* aMenuItem) + { + if (mContinue1) { + mContinue1 = mVisitor1->Visit(aMenuItem); + } + if (mContinue2) { + mContinue2 = mVisitor2->Visit(aMenuItem); + } + return mContinue1 || mContinue2; + } +protected: + Visitor* mVisitor1; + Visitor* mVisitor2; + PRPackedBool mContinue1; + PRPackedBool mContinue2; +}; + + +NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(MenuItem) + +nsHTMLMenuItemElement::nsHTMLMenuItemElement( + already_AddRefed aNodeInfo, FromParser aFromParser) + : nsGenericHTMLElement(aNodeInfo), + mType(kMenuItemDefaultType->value), + mParserCreating(false), + mShouldInitChecked(false), + mCheckedDirty(false), + mChecked(false) +{ + mParserCreating = aFromParser; +} + +nsHTMLMenuItemElement::~nsHTMLMenuItemElement() +{ +} + + +NS_IMPL_ADDREF_INHERITED(nsHTMLMenuItemElement, nsGenericElement) +NS_IMPL_RELEASE_INHERITED(nsHTMLMenuItemElement, nsGenericElement) + + +DOMCI_NODE_DATA(HTMLMenuItemElement, nsHTMLMenuItemElement) + +// QueryInterface implementation for nsHTMLMenuItemElement +NS_INTERFACE_TABLE_HEAD(nsHTMLMenuItemElement) + NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLMenuItemElement, + nsIDOMHTMLCommandElement, + nsIDOMHTMLMenuItemElement) + NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMenuItemElement, + nsGenericHTMLElement) +NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMenuItemElement) + +//NS_IMPL_ELEMENT_CLONE(nsHTMLMenuItemElement) +nsresult +nsHTMLMenuItemElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const +{ + *aResult = nsnull; + nsCOMPtr ni = aNodeInfo; + nsHTMLMenuItemElement *it = new nsHTMLMenuItemElement(ni.forget(), + NOT_FROM_PARSER); + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCOMPtr kungFuDeathGrip = it; + nsresult rv = CopyInnerTo(it); + if (NS_SUCCEEDED(rv)) { + switch (mType) { + case CMD_TYPE_CHECKBOX: + case CMD_TYPE_RADIO: + if (mCheckedDirty) { + // We no longer have our original checked state. Set our + // checked state on the clone. + it->mCheckedDirty = true; + it->mChecked = mChecked; + } + break; + } + + kungFuDeathGrip.swap(*aResult); + } + + return rv; +} + + +NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMenuItemElement, Type, type, + kMenuItemDefaultType->tag) +NS_IMPL_STRING_ATTR(nsHTMLMenuItemElement, Label, label) +NS_IMPL_URI_ATTR(nsHTMLMenuItemElement, Icon, icon) +NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, Disabled, disabled) +NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, DefaultChecked, checked) +//NS_IMPL_BOOL_ATTR(nsHTMLMenuItemElement, Checked, checked) +NS_IMPL_STRING_ATTR(nsHTMLMenuItemElement, Radiogroup, radiogroup) + +NS_IMETHODIMP +nsHTMLMenuItemElement::GetChecked(PRBool* aChecked) +{ + *aChecked = mChecked; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLMenuItemElement::SetChecked(PRBool aChecked) +{ + PRBool checkedChanged = mChecked != aChecked; + + mChecked = aChecked; + + if (mType == CMD_TYPE_RADIO) { + if (checkedChanged) { + if (mCheckedDirty) { + ClearCheckedVisitor visitor(this); + WalkRadioGroup(&visitor); + } else { + ClearCheckedVisitor visitor1(this); + SetCheckedDirtyVisitor visitor2; + CombinedVisitor visitor(&visitor1, &visitor2); + WalkRadioGroup(&visitor); + } + } else if (!mCheckedDirty) { + SetCheckedDirtyVisitor visitor; + WalkRadioGroup(&visitor); + } + } else { + mCheckedDirty = true; + } + + return NS_OK; +} + +nsresult +nsHTMLMenuItemElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) +{ + if (aVisitor.mEvent->message == NS_MOUSE_CLICK) { + + PRBool originalCheckedValue = PR_FALSE; + switch (mType) { + case CMD_TYPE_CHECKBOX: + originalCheckedValue = mChecked; + SetChecked(!originalCheckedValue); + aVisitor.mItemFlags |= NS_CHECKED_IS_TOGGLED; + break; + case CMD_TYPE_RADIO: + nsCOMPtr selectedRadio = GetSelectedRadio(); + aVisitor.mItemData = selectedRadio; + + originalCheckedValue = mChecked; + if (!originalCheckedValue) { + SetChecked(PR_TRUE); + aVisitor.mItemFlags |= NS_CHECKED_IS_TOGGLED; + } + break; + } + + if (originalCheckedValue) { + aVisitor.mItemFlags |= NS_ORIGINAL_CHECKED_VALUE; + } + + // We must cache type because mType may change during JS event. + aVisitor.mItemFlags |= mType; + } + + return nsGenericHTMLElement::PreHandleEvent(aVisitor); +} + +nsresult +nsHTMLMenuItemElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) +{ + // Check to see if the event was cancelled. + if (aVisitor.mEvent->message == NS_MOUSE_CLICK && + aVisitor.mItemFlags & NS_CHECKED_IS_TOGGLED && + aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) { + PRBool originalCheckedValue = + !!(aVisitor.mItemFlags & NS_ORIGINAL_CHECKED_VALUE); + PRUint8 oldType = NS_MENUITEM_TYPE(aVisitor.mItemFlags); + + nsCOMPtr selectedRadio = + do_QueryInterface(aVisitor.mItemData); + if (selectedRadio) { + selectedRadio->SetChecked(PR_TRUE); + if (mType != CMD_TYPE_RADIO) { + SetChecked(PR_FALSE); + } + } else if (oldType == CMD_TYPE_CHECKBOX) { + SetChecked(originalCheckedValue); + } + } + + return NS_OK; +} + +nsresult +nsHTMLMenuItemElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers) +{ + nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + + if (NS_SUCCEEDED(rv) && aDocument && mType == CMD_TYPE_RADIO) { + AddedToRadioGroup(); + } + + return rv; +} + +PRBool +nsHTMLMenuItemElement::ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult) +{ + if (aNamespaceID == kNameSpaceID_None) { + if (aAttribute == nsGkAtoms::type) { + PRBool success = aResult.ParseEnumValue(aValue, kMenuItemTypeTable, + PR_FALSE); + if (success) { + mType = aResult.GetEnumValue(); + } else { + mType = kMenuItemDefaultType->value; + } + + return success; + } + + if (aAttribute == nsGkAtoms::radiogroup) { + aResult.ParseAtom(aValue); + return PR_TRUE; + } + } + + return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, + aResult); +} + +void +nsHTMLMenuItemElement::DoneCreatingElement() +{ + mParserCreating = false; + + if (mShouldInitChecked) { + InitChecked(); + mShouldInitChecked = false; + } +} + +nsresult +nsHTMLMenuItemElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, + const nsAString* aValue, PRBool aNotify) +{ + if (aNameSpaceID == kNameSpaceID_None) { + if ((aName == nsGkAtoms::radiogroup || aName == nsGkAtoms::type) && + mType == CMD_TYPE_RADIO && + !mParserCreating) { + if (IsInDoc() && GetParent()) { + AddedToRadioGroup(); + } + } + + // Checked must be set no matter what type of menuitem it is, since + // GetChecked() must reflect the new value + if (aName == nsGkAtoms::checked && + !mCheckedDirty) { + if (mParserCreating) { + mShouldInitChecked = true; + } else { + InitChecked(); + } + } + } + + return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue, + aNotify); +} + +void +nsHTMLMenuItemElement::WalkRadioGroup(Visitor* aVisitor) +{ + nsIContent* parent = GetParent(); + if (!parent) { + aVisitor->Visit(this); + return; + } + + nsAttrInfo info1(GetAttrInfo(kNameSpaceID_None, + nsGkAtoms::radiogroup)); + PRBool info1Empty = !info1.mValue || info1.mValue->IsEmptyString(); + + for (nsIContent* cur = parent->GetFirstChild(); + cur; + cur = cur->GetNextSibling()) { + nsHTMLMenuItemElement* menuitem = nsHTMLMenuItemElement::FromContent(cur); + + if (!menuitem || menuitem->GetType() != CMD_TYPE_RADIO) { + continue; + } + + nsAttrInfo info2(menuitem->GetAttrInfo(kNameSpaceID_None, + nsGkAtoms::radiogroup)); + PRBool info2Empty = !info2.mValue || info2.mValue->IsEmptyString(); + + if (info1Empty != info2Empty || + info1.mValue && info2.mValue && !info1.mValue->Equals(*info2.mValue)) { + continue; + } + + if (!aVisitor->Visit(menuitem)) { + break; + } + } +} + +nsHTMLMenuItemElement* +nsHTMLMenuItemElement::GetSelectedRadio() +{ + nsHTMLMenuItemElement* result = nsnull; + + GetCheckedVisitor visitor(&result); + WalkRadioGroup(&visitor); + + return result; +} + +void +nsHTMLMenuItemElement::AddedToRadioGroup() +{ + PRBool checkedDirty = mCheckedDirty; + if (mChecked) { + ClearCheckedVisitor visitor1(this); + GetCheckedDirtyVisitor visitor2(&checkedDirty, this); + CombinedVisitor visitor(&visitor1, &visitor2); + WalkRadioGroup(&visitor); + } else { + GetCheckedDirtyVisitor visitor(&checkedDirty, this); + WalkRadioGroup(&visitor); + } + mCheckedDirty = checkedDirty; +} + +void +nsHTMLMenuItemElement::InitChecked() +{ + PRBool defaultChecked; + GetDefaultChecked(&defaultChecked); + mChecked = defaultChecked; + if (mType == CMD_TYPE_RADIO) { + ClearCheckedVisitor visitor(this); + WalkRadioGroup(&visitor); + } +} diff --git a/content/html/content/src/nsHTMLMenuItemElement.h b/content/html/content/src/nsHTMLMenuItemElement.h new file mode 100644 index 000000000000..f7e781dd37c4 --- /dev/null +++ b/content/html/content/src/nsHTMLMenuItemElement.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIDOMHTMLMenuItemElement.h" +#include "nsGenericHTMLElement.h" + +class Visitor; + +class nsHTMLMenuItemElement : public nsGenericHTMLElement, + public nsIDOMHTMLMenuItemElement +{ +public: + nsHTMLMenuItemElement(already_AddRefed aNodeInfo, + mozilla::dom::FromParser aFromParser); + virtual ~nsHTMLMenuItemElement(); + + /** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/ + static nsHTMLMenuItemElement* FromContent(nsIContent* aContent) + { + if (aContent && aContent->IsHTML(nsGkAtoms::menuitem)) { + return static_cast(aContent); + } + return nsnull; + } + + // nsISupports + NS_DECL_ISUPPORTS_INHERITED + + // nsIDOMNode + NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::) + + // nsIDOMElement + NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::) + + // nsIDOMHTMLElement + NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::) + + // nsIDOMHTMLCommandElement + NS_DECL_NSIDOMHTMLCOMMANDELEMENT + + // nsIDOMHTMLMenuItemElement + NS_DECL_NSIDOMHTMLMENUITEMELEMENT + + virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); + virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor); + + virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, + nsIContent* aBindingParent, + PRBool aCompileEventHandlers); + + virtual PRBool ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult); + + virtual void DoneCreatingElement(); + + virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + + virtual nsXPCClassInfo* GetClassInfo(); + + PRUint8 GetType() const { return mType; } + + /** + * Syntax sugar to make it easier to check for checked and checked dirty + */ + PRBool IsChecked() const { return mChecked; } + PRBool IsCheckedDirty() const { return mCheckedDirty; } + +protected: + virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName, + const nsAString* aValue, PRBool aNotify); + + void WalkRadioGroup(Visitor* aVisitor); + + nsHTMLMenuItemElement* GetSelectedRadio(); + + void AddedToRadioGroup(); + + void InitChecked(); + + friend class ClearCheckedVisitor; + friend class SetCheckedDirtyVisitor; + + void ClearChecked() { mChecked = false; } + void SetCheckedDirty() { mCheckedDirty = true; } + +private: + PRUint8 mType : 2; + bool mParserCreating : 1; + bool mShouldInitChecked : 1; + bool mCheckedDirty : 1; + bool mChecked : 1; +}; diff --git a/content/html/content/src/nsHTMLSelectElement.cpp b/content/html/content/src/nsHTMLSelectElement.cpp index f560b6a59fb4..f422b9f5aab4 100644 --- a/content/html/content/src/nsHTMLSelectElement.cpp +++ b/content/html/content/src/nsHTMLSelectElement.cpp @@ -360,12 +360,6 @@ nsHTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions, return NS_OK; } -static PRBool IsOptGroup(nsIContent *aContent) -{ - return (aContent->NodeInfo()->Equals(nsGkAtoms::optgroup) && - aContent->IsHTML()); -} - // If the document is such that recursing over these options gets us // deeper than four levels, there is something terribly wrong with the // world. @@ -394,7 +388,7 @@ nsHTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions, } // Recurse down into optgroups - if (IsOptGroup(aOptions)) { + if (aOptions->IsHTML(nsGkAtoms::optgroup)) { mOptGroupCount++; PRUint32 numChildren = aOptions->GetChildCount(); @@ -438,7 +432,7 @@ nsHTMLSelectElement::RemoveOptionsFromListRecurse(nsIContent* aOptions, } // Recurse down deeper for options - if (mOptGroupCount && IsOptGroup(aOptions)) { + if (mOptGroupCount && aOptions->IsHTML(nsGkAtoms::optgroup)) { mOptGroupCount--; PRUint32 numChildren = aOptions->GetChildCount(); @@ -1873,15 +1867,15 @@ void nsHTMLSelectElement::DispatchContentReset() { static void AddOptionsRecurse(nsIContent* aRoot, nsHTMLOptionCollection* aArray) { - nsIContent* child; - for(PRUint32 i = 0; (child = aRoot->GetChildAt(i)); ++i) { - nsHTMLOptionElement *opt = nsHTMLOptionElement::FromContent(child); + for (nsIContent* cur = aRoot->GetFirstChild(); + cur; + cur = cur->GetNextSibling()) { + nsHTMLOptionElement* opt = nsHTMLOptionElement::FromContent(cur); if (opt) { // If we fail here, then at least we've tried our best aArray->AppendOption(opt); - } - else if (IsOptGroup(child)) { - AddOptionsRecurse(child, aArray); + } else if (cur->IsHTML(nsGkAtoms::optgroup)) { + AddOptionsRecurse(cur, aArray); } } } @@ -1969,15 +1963,15 @@ static void VerifyOptionsRecurse(nsIContent* aRoot, PRInt32& aIndex, nsHTMLOptionCollection* aArray) { - nsIContent* child; - for(PRUint32 i = 0; (child = aRoot->GetChildAt(i)); ++i) { - nsCOMPtr opt = do_QueryInterface(child); + for (nsIContent* cur = aRoot->GetFirstChild(); + cur; + cur = cur->GetNextSibling()) { + nsCOMPtr opt = do_QueryInterface(cur); if (opt) { NS_ASSERTION(opt == aArray->ItemAsOption(aIndex++), "Options collection broken"); - } - else if (IsOptGroup(child)) { - VerifyOptionsRecurse(child, aIndex, aArray); + } else if (cur->IsHTML(nsGkAtoms::optgroup)) { + VerifyOptionsRecurse(cur, aIndex, aArray); } } } diff --git a/content/html/content/src/nsHTMLSharedElement.cpp b/content/html/content/src/nsHTMLSharedElement.cpp index a8304e28eada..23ef1a797e75 100644 --- a/content/html/content/src/nsHTMLSharedElement.cpp +++ b/content/html/content/src/nsHTMLSharedElement.cpp @@ -38,7 +38,6 @@ #include "nsIDOMHTMLParamElement.h" #include "nsIDOMHTMLBaseElement.h" #include "nsIDOMHTMLDirectoryElement.h" -#include "nsIDOMHTMLMenuElement.h" #include "nsIDOMHTMLQuoteElement.h" #include "nsIDOMHTMLHeadElement.h" #include "nsIDOMHTMLHtmlElement.h" @@ -59,7 +58,6 @@ class nsHTMLSharedElement : public nsGenericHTMLElement, public nsIDOMHTMLParamElement, public nsIDOMHTMLBaseElement, public nsIDOMHTMLDirectoryElement, - public nsIDOMHTMLMenuElement, public nsIDOMHTMLQuoteElement, public nsIDOMHTMLHeadElement, public nsIDOMHTMLHtmlElement @@ -89,9 +87,6 @@ public: // nsIDOMHTMLDirectoryElement NS_DECL_NSIDOMHTMLDIRECTORYELEMENT - // nsIDOMHTMLMenuElement - // Same as directoryelement - // nsIDOMHTMLQuoteElement NS_DECL_NSIDOMHTMLQUOTEELEMENT @@ -157,7 +152,6 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLSharedElement, nsGenericElement) DOMCI_DATA(HTMLParamElement, nsHTMLSharedElement) DOMCI_DATA(HTMLBaseElement, nsHTMLSharedElement) DOMCI_DATA(HTMLDirectoryElement, nsHTMLSharedElement) -DOMCI_DATA(HTMLMenuElement, nsHTMLSharedElement) DOMCI_DATA(HTMLQuoteElement, nsHTMLSharedElement) DOMCI_DATA(HTMLHeadElement, nsHTMLSharedElement) DOMCI_DATA(HTMLHtmlElement, nsHTMLSharedElement) @@ -174,9 +168,6 @@ nsHTMLSharedElement::GetClassInfoInternal() if (mNodeInfo->Equals(nsGkAtoms::dir)) { return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLDirectoryElement_id); } - if (mNodeInfo->Equals(nsGkAtoms::menu)) { - return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLMenuElement_id); - } if (mNodeInfo->Equals(nsGkAtoms::q)) { return NS_GetDOMClassInfoInstance(eDOMClassInfo_HTMLQuoteElement_id); } @@ -203,7 +194,6 @@ NS_INTERFACE_TABLE_HEAD(nsHTMLSharedElement) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLParamElement, param) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLDirectoryElement, dir) - NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLMenuElement, menu) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, q) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, blockquote) NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLHeadElement, head) @@ -224,9 +214,6 @@ NS_IMPL_STRING_ATTR(nsHTMLSharedElement, ValueType, valuetype) // nsIDOMHTMLDirectoryElement NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact) -// nsIDOMHTMLMenuElement -//NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact) - // nsIDOMHTMLQuoteElement NS_IMPL_URI_ATTR(nsHTMLSharedElement, Cite, cite) @@ -275,8 +262,7 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID, nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None && - (mNodeInfo->Equals(nsGkAtoms::dir) || - mNodeInfo->Equals(nsGkAtoms::menu))) { + mNodeInfo->Equals(nsGkAtoms::dir)) { if (aAttribute == nsGkAtoms::type) { return aResult.ParseEnumValue(aValue, kListTypeTable, PR_FALSE); } @@ -290,7 +276,7 @@ nsHTMLSharedElement::ParseAttribute(PRInt32 aNamespaceID, } static void -DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes, +DirectoryMapAttributesIntoRule(const nsMappedAttributes* aAttributes, nsRuleData* aData) { if (aData->mSIDs & NS_STYLE_INHERIT_BIT(List)) { @@ -486,8 +472,8 @@ nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) nsMapRuleToAttributesFunc nsHTMLSharedElement::GetAttributeMappingFunction() const { - if (mNodeInfo->Equals(nsGkAtoms::dir) || mNodeInfo->Equals(nsGkAtoms::menu)) { - return &DirectoryMenuMapAttributesIntoRule; + if (mNodeInfo->Equals(nsGkAtoms::dir)) { + return &DirectoryMapAttributesIntoRule; } return nsGenericHTMLElement::GetAttributeMappingFunction(); diff --git a/content/html/content/src/nsTextEditorState.cpp b/content/html/content/src/nsTextEditorState.cpp index 3adcab595bb1..3456959339d4 100644 --- a/content/html/content/src/nsTextEditorState.cpp +++ b/content/html/content/src/nsTextEditorState.cpp @@ -36,6 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsTextEditorState.h" + #include "nsCOMPtr.h" #include "nsIPresShell.h" #include "nsIView.h" @@ -65,8 +67,6 @@ #include "nsTextEditRules.h" #include "nsEventListenerManager.h" -#include "nsTextEditorState.h" - using namespace mozilla::dom; static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID); diff --git a/content/html/content/src/nsTextEditorState.h b/content/html/content/src/nsTextEditorState.h index 4a692904bd9b..2e6a6b3a408f 100644 --- a/content/html/content/src/nsTextEditorState.h +++ b/content/html/content/src/nsTextEditorState.h @@ -40,6 +40,7 @@ #define nsTextEditorState_h__ #include "nsAutoPtr.h" +#include "nsString.h" #include "nsITextControlElement.h" #include "nsITextControlFrame.h" #include "nsCycleCollectionParticipant.h" diff --git a/content/html/content/test/Makefile.in b/content/html/content/test/Makefile.in index 2ab4592a9ee1..0722b7f6398c 100644 --- a/content/html/content/test/Makefile.in +++ b/content/html/content/test/Makefile.in @@ -146,7 +146,6 @@ _TEST_FILES = \ test_formSubmission2.html \ file_formSubmission_text.txt \ file_formSubmission_img.jpg \ - test_bug418756.html \ test_bug421640.html \ test_bug424698.html \ test_bug428135.xhtml \ @@ -280,6 +279,8 @@ _TEST_FILES = \ test_bug674558.html \ test_bug583533.html \ test_restore_from_parser_fragment.html \ + test_bug617528.html \ + test_checked.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/html/content/test/test_bug617528.html b/content/html/content/test/test_bug617528.html new file mode 100644 index 000000000000..1d0005cba63b --- /dev/null +++ b/content/html/content/test/test_bug617528.html @@ -0,0 +1,74 @@ + + + + + Test for Bug 617528 + + + + + +Mozilla Bug 617528 +

+
+ + + + + +
+
+
+
+ + diff --git a/content/html/content/test/test_bug418756.html b/content/html/content/test/test_checked.html similarity index 90% rename from content/html/content/test/test_bug418756.html rename to content/html/content/test/test_checked.html index e8fc0ff20200..d024ef0c077d 100644 --- a/content/html/content/test/test_bug418756.html +++ b/content/html/content/test/test_checked.html @@ -2,26 +2,41 @@ - Test for Bug 418756 + Test for Bug 418756 and 617528 -Mozilla Bug 418756 +Mozilla bug +418756 +and +617528

+ + + +
 
 
diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index d3786da46d67..9b074263c683 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -1021,7 +1021,10 @@ SinkContext::AddLeaf(const nsIParserNode& aNode) case eHTMLTag_input: content->DoneCreatingElement(); + break; + case eHTMLTag_menuitem: + content->DoneCreatingElement(); break; default: diff --git a/content/xbl/src/nsXBLBinding.cpp b/content/xbl/src/nsXBLBinding.cpp index d0607e8fdc55..f8c6bec1a12d 100644 --- a/content/xbl/src/nsXBLBinding.cpp +++ b/content/xbl/src/nsXBLBinding.cpp @@ -73,13 +73,7 @@ // Event listeners #include "nsEventListenerManager.h" -#include "nsIDOMMouseListener.h" -#include "nsIDOMMouseMotionListener.h" -#include "nsIDOMLoadListener.h" -#include "nsIDOMFocusListener.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMFormListener.h" -#include "nsIDOMContextMenuListener.h" +#include "nsIDOMEventListener.h" #include "nsAttrName.h" #include "nsGkAtoms.h" diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 0c00c811ae8e..7ade5adfcc40 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -1070,7 +1070,8 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName, // properly (eg form state restoration). if (nodeInfo->NamespaceID() == kNameSpaceID_XHTML) { if (nodeInfo->NameAtom() == nsGkAtoms::input || - nodeInfo->NameAtom() == nsGkAtoms::button) { + nodeInfo->NameAtom() == nsGkAtoms::button || + nodeInfo->NameAtom() == nsGkAtoms::menuitem) { content->DoneCreatingElement(); } else if (nodeInfo->NameAtom() == nsGkAtoms::head && !mCurrentHead) { mCurrentHead = content; diff --git a/content/xslt/src/xslt/txMozillaXMLOutput.cpp b/content/xslt/src/xslt/txMozillaXMLOutput.cpp index 202edf48c8e7..35140ab8dc5a 100644 --- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp +++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp @@ -343,7 +343,8 @@ txMozillaXMLOutput::endElement() } } else if (ns == kNameSpaceID_XHTML && (localName == nsGkAtoms::input || - localName == nsGkAtoms::button)) { + localName == nsGkAtoms::button || + localName == nsGkAtoms::menuitem)) { element->DoneCreatingElement(); } } diff --git a/content/xul/content/Makefile.in b/content/xul/content/Makefile.in index 9f33894a6465..e5e3a3fc283a 100644 --- a/content/xul/content/Makefile.in +++ b/content/xul/content/Makefile.in @@ -43,7 +43,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = xul -PARALLEL_DIRS = src +PARALLEL_DIRS = public src ifdef ENABLE_TESTS PARALLEL_DIRS += test diff --git a/db/mork/Makefile.in b/content/xul/content/public/Makefile.in similarity index 85% rename from db/mork/Makefile.in rename to content/xul/content/public/Makefile.in index e19c8204fedf..1c9bda3b5e42 100644 --- a/db/mork/Makefile.in +++ b/content/xul/content/public/Makefile.in @@ -1,4 +1,3 @@ -# # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # @@ -12,11 +11,10 @@ # for the specific language governing rights and limitations under the # License. # -# The Original Code is mozilla.org code. +# The Original Code is Mozilla code. # -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 +# The Initial Developer of the Original Code is Mozilla Foundation +# Portions created by the Initial Developer are Copyright (C) 2011 # the Initial Developer. All Rights Reserved. # # Contributor(s): @@ -35,14 +33,19 @@ # # ***** END LICENSE BLOCK ***** -DEPTH = ../.. +DEPTH = ../../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -DIRS = src build +MODULE = xul + +ifdef MOZ_XUL +XPIDLSRCS = \ + nsIXULContextMenuBuilder.idl \ + $(NULL) +endif include $(topsrcdir)/config/rules.mk - diff --git a/dom/public/coreEvents/nsIDOMContextMenuListener.h b/content/xul/content/public/nsIXULContextMenuBuilder.idl similarity index 55% rename from dom/public/coreEvents/nsIDOMContextMenuListener.h rename to content/xul/content/public/nsIXULContextMenuBuilder.idl index e8639a87b7e6..b14ba38fabb4 100644 --- a/dom/public/coreEvents/nsIDOMContextMenuListener.h +++ b/content/xul/content/public/nsIXULContextMenuBuilder.idl @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,11 +12,10 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -35,36 +34,40 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsISupports.idl" -#ifndef nsIDOMContextMenuListener_h__ -#define nsIDOMContextMenuListener_h__ +interface nsIDOMDocumentFragment; -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Context menu event listener - * +/** + * An interface for initialization of XUL context menu builder + * and for triggering of menuitem actions with assigned identifiers. */ -#define NS_IDOMCONTEXTMENULISTENER_IID \ -{ /* 162b3480-ded6-11d1-bd85-00805f8ae3f7 */ \ -0x162b3480, 0xded6, 0x11d1, \ -{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf7} } -class nsIDOMContextMenuListener : public nsIDOMEventListener { +[scriptable, uuid(f0c35053-14cc-4e23-a9db-f9a68fae8375)] +interface nsIXULContextMenuBuilder : nsISupports +{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMCONTEXTMENULISTENER_IID) /** - * Processes a context menu event - * @param aContextMenuEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD ContextMenu(nsIDOMEvent* aContextMenuEvent) = 0; + * Initialize builder before building. + * + * @param aDocumentFragment the fragment that will be used to append top + * level elements + * + * @param aGeneratedAttrName the name of the attribute that will be used + * to mark elements as generated. + * + * @param aIdentAttrName the name of the attribute that will be used for + * menuitem identification. + */ + void init(in nsIDOMDocumentFragment aDocumentFragment, + in AString aGeneratedAttrName, + in AString aIdentAttrName); + + /** + * Invoke the action of the menuitem with assigned identifier aIdent. + * + * @param aIdent the menuitem identifier + */ + void click(in DOMString aIdent); }; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMContextMenuListener, - NS_IDOMCONTEXTMENULISTENER_IID) - -#endif // nsIDOMContextMenuListener_h__ diff --git a/content/xul/content/src/Makefile.in b/content/xul/content/src/Makefile.in index f5df02234078..99c87adbfaf6 100644 --- a/content/xul/content/src/Makefile.in +++ b/content/xul/content/src/Makefile.in @@ -54,6 +54,7 @@ ifdef MOZ_XUL CPPSRCS += \ nsXULElement.cpp \ nsXULPopupListener.cpp \ + nsXULContextMenuBuilder.cpp \ $(NULL) endif diff --git a/content/xul/content/src/nsXULContextMenuBuilder.cpp b/content/xul/content/src/nsXULContextMenuBuilder.cpp new file mode 100644 index 000000000000..3c660ad355ce --- /dev/null +++ b/content/xul/content/src/nsXULContextMenuBuilder.cpp @@ -0,0 +1,268 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsContentCreatorFunctions.h" +#include "nsIDOMHTMLElement.h" +#include "nsIDOMHTMLMenuItemElement.h" +#include "nsXULContextMenuBuilder.h" + + +nsXULContextMenuBuilder::nsXULContextMenuBuilder() + : mCurrentIdent(0) +{ +} + +nsXULContextMenuBuilder::~nsXULContextMenuBuilder() +{ +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULContextMenuBuilder) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULContextMenuBuilder) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFragment) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentNode) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mElements) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULContextMenuBuilder) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFragment) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCurrentNode) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULContextMenuBuilder) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULContextMenuBuilder) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULContextMenuBuilder) + NS_INTERFACE_MAP_ENTRY(nsIMenuBuilder) + NS_INTERFACE_MAP_ENTRY(nsIXULContextMenuBuilder) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMenuBuilder) +NS_INTERFACE_MAP_END + + +NS_IMETHODIMP +nsXULContextMenuBuilder::OpenContainer(const nsAString& aLabel) +{ + if (!mFragment) { + return NS_ERROR_NOT_INITIALIZED; + } + + if (!mCurrentNode) { + mCurrentNode = mFragment; + } else { + nsCOMPtr menu; + nsresult rv = CreateElement(nsGkAtoms::menu, getter_AddRefs(menu)); + NS_ENSURE_SUCCESS(rv, rv); + + menu->SetAttr(kNameSpaceID_None, nsGkAtoms::label, aLabel, PR_FALSE); + + nsCOMPtr menuPopup; + rv = CreateElement(nsGkAtoms::menupopup, getter_AddRefs(menuPopup)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = menu->AppendChildTo(menuPopup, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + rv = mCurrentNode->AppendChildTo(menu, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + mCurrentNode = menuPopup; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXULContextMenuBuilder::AddItemFor(nsIDOMHTMLMenuItemElement* aElement, + PRBool aCanLoadIcon) +{ + if (!mFragment) { + return NS_ERROR_NOT_INITIALIZED; + } + + nsCOMPtr menuitem; + nsresult rv = CreateElement(nsGkAtoms::menuitem, getter_AddRefs(menuitem)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString type; + aElement->GetType(type); + if (type.EqualsLiteral("checkbox") || type.EqualsLiteral("radio")) { + // The menu is only temporary, so we don't need to handle + // the radio type precisely. + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::type, + NS_LITERAL_STRING("checkbox"), PR_FALSE); + PRBool checked; + aElement->GetChecked(&checked); + if (checked) { + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::checked, + NS_LITERAL_STRING("true"), PR_FALSE); + } + } + + nsAutoString label; + aElement->GetLabel(label); + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::label, label, PR_FALSE); + + nsAutoString icon; + aElement->GetIcon(icon); + if (!icon.IsEmpty()) { + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, + NS_LITERAL_STRING("menuitem-iconic"), PR_FALSE); + if (aCanLoadIcon) { + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::image, icon, PR_FALSE); + } + } + + PRBool disabled; + aElement->GetDisabled(&disabled); + if (disabled) { + menuitem->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, + NS_LITERAL_STRING("true"), PR_FALSE); + } + + nsAutoString ident; + ident.AppendInt(mCurrentIdent++); + + menuitem->SetAttr(kNameSpaceID_None, mIdentAttr, ident, PR_FALSE); + + rv = mCurrentNode->AppendChildTo(menuitem, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + mElements.AppendObject(aElement); + + return NS_OK; +} + +NS_IMETHODIMP +nsXULContextMenuBuilder::AddSeparator() +{ + if (!mFragment) { + return NS_ERROR_NOT_INITIALIZED; + } + + nsCOMPtr menuseparator; + nsresult rv = CreateElement(nsGkAtoms::menuseparator, + getter_AddRefs(menuseparator)); + NS_ENSURE_SUCCESS(rv, rv); + + return mCurrentNode->AppendChildTo(menuseparator, PR_FALSE); +} + +NS_IMETHODIMP +nsXULContextMenuBuilder::UndoAddSeparator() +{ + if (!mFragment) { + return NS_ERROR_NOT_INITIALIZED; + } + + PRUint32 count = mCurrentNode->GetChildCount(); + if (!count || + mCurrentNode->GetChildAt(count - 1)->Tag() != nsGkAtoms::menuseparator) { + return NS_OK; + } + + return mCurrentNode->RemoveChildAt(count - 1, PR_FALSE); +} + +NS_IMETHODIMP +nsXULContextMenuBuilder::CloseContainer() +{ + if (!mFragment) { + return NS_ERROR_NOT_INITIALIZED; + } + + if (mCurrentNode == mFragment) { + mCurrentNode = nsnull; + } else { + nsIContent* parent = mCurrentNode->GetParent(); + mCurrentNode = parent->GetParent(); + } + + return NS_OK; +} + + +NS_IMETHODIMP +nsXULContextMenuBuilder::Init(nsIDOMDocumentFragment* aDocumentFragment, + const nsAString& aGeneratedAttrName, + const nsAString& aIdentAttrName) +{ + NS_ENSURE_ARG_POINTER(aDocumentFragment); + + mFragment = do_QueryInterface(aDocumentFragment); + mDocument = mFragment->GetOwnerDocument(); + mGeneratedAttr = do_GetAtom(aGeneratedAttrName); + mIdentAttr = do_GetAtom(aIdentAttrName); + + return NS_OK; +} + +NS_IMETHODIMP +nsXULContextMenuBuilder::Click(const nsAString& aIdent) +{ + PRInt32 rv; + PRInt32 idx = nsString(aIdent).ToInteger(&rv); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr element = mElements.SafeObjectAt(idx); + if (element) { + element->Click(); + } + } + + return NS_OK; +} + +nsresult +nsXULContextMenuBuilder::CreateElement(nsIAtom* aTag, nsIContent** aResult) +{ + *aResult = nsnull; + + nsCOMPtr nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo( + aTag, nsnull, kNameSpaceID_XUL, nsIDOMNode::ELEMENT_NODE); + NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); + + nsresult rv = NS_NewElement(aResult, kNameSpaceID_XUL, nodeInfo.forget(), + mozilla::dom::NOT_FROM_PARSER); + if (NS_FAILED(rv)) { + return rv; + } + + (*aResult)->SetAttr(kNameSpaceID_None, mGeneratedAttr, EmptyString(), + PR_FALSE); + + return NS_OK; +} diff --git a/dom/public/coreEvents/nsIDOMFocusListener.h b/content/xul/content/src/nsXULContextMenuBuilder.h similarity index 57% rename from dom/public/coreEvents/nsIDOMFocusListener.h rename to content/xul/content/src/nsXULContextMenuBuilder.h index ffeb9b23f4da..2b8c2bdc9224 100644 --- a/dom/public/coreEvents/nsIDOMFocusListener.h +++ b/content/xul/content/src/nsXULContextMenuBuilder.h @@ -12,11 +12,10 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -35,43 +34,38 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsCOMPtr.h" +#include "nsCOMArray.h" +#include "nsIContent.h" +#include "nsIMenuBuilder.h" +#include "nsIXULContextMenuBuilder.h" +#include "nsIDOMDocumentFragment.h" +#include "nsCycleCollectionParticipant.h" -#ifndef nsIDOMFocusListener_h__ -#define nsIDOMFocusListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Mouse up/down/move event listener - * - */ -#define NS_IDOMFOCUSLISTENER_IID \ -{ /* 80974670-ded6-11d1-bd85-00805f8ae3f4 */ \ -0x80974670, 0xded6, 0x11d1, \ -{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } - -class nsIDOMFocusListener : public nsIDOMEventListener +class nsXULContextMenuBuilder : public nsIMenuBuilder, + public nsIXULContextMenuBuilder { public: + nsXULContextMenuBuilder(); + virtual ~nsXULContextMenuBuilder(); - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMFOCUSLISTENER_IID) + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULContextMenuBuilder, + nsIMenuBuilder) + NS_DECL_NSIMENUBUILDER - /** - * Processes a focus event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Focus(nsIDOMEvent* aEvent) = 0; + NS_DECL_NSIXULCONTEXTMENUBUILDER - /** - * Processes a blur event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Blur(nsIDOMEvent* aEvent) = 0; +protected: + nsresult CreateElement(nsIAtom* aTag, nsIContent** aResult); + + nsCOMPtr mFragment; + nsCOMPtr mDocument; + nsCOMPtr mGeneratedAttr; + nsCOMPtr mIdentAttr; + + nsCOMPtr mCurrentNode; + PRInt32 mCurrentIdent; + + nsCOMArray mElements; }; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMFocusListener, NS_IDOMFOCUSLISTENER_IID) - -#endif // nsIDOMFocusListener_h__ diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index b4f0f4d9d947..a062ce2581db 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -66,13 +66,6 @@ #include "nsIDOMAttr.h" #include "nsIDOMDocument.h" #include "nsIDOMElement.h" -#include "nsIDOMMouseListener.h" -#include "nsIDOMMouseMotionListener.h" -#include "nsIDOMLoadListener.h" -#include "nsIDOMFocusListener.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMFormListener.h" -#include "nsIDOMContextMenuListener.h" #include "nsIDOMEventListener.h" #include "nsIDOMNodeList.h" #include "nsIDOMXULCommandDispatcher.h" diff --git a/content/xul/document/src/nsXULCommandDispatcher.h b/content/xul/document/src/nsXULCommandDispatcher.h index a11161164efd..5753c680b33c 100644 --- a/content/xul/document/src/nsXULCommandDispatcher.h +++ b/content/xul/document/src/nsXULCommandDispatcher.h @@ -48,7 +48,6 @@ #include "nsCOMPtr.h" #include "nsIDOMXULCommandDispatcher.h" -#include "nsIDOMFocusListener.h" #include "nsWeakReference.h" #include "nsIDOMNode.h" #include "nsString.h" diff --git a/db/Makefile.in b/db/Makefile.in index 5eb6bc869f18..ee87e474d6c2 100644 --- a/db/Makefile.in +++ b/db/Makefile.in @@ -42,14 +42,4 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -ifndef NSS_DISABLE_DBM -ifdef MOZ_MORK -PARALLEL_DIRS = mdb mork -endif -endif - -ifdef MOZ_MORKREADER -PARALLEL_DIRS += morkreader -endif - include $(topsrcdir)/config/rules.mk diff --git a/db/README.html b/db/README.html deleted file mode 100644 index af663588011a..000000000000 --- a/db/README.html +++ /dev/null @@ -1,50 +0,0 @@ - - - -

- -mdb/Mork general-purpose database

- -

- -db contains C++ code for the mdb/Mork database which is a low-level, -general-purpose and cross-platform file library. It is used to store -mail box data, news data and global history data. - - - diff --git a/db/mdb/Makefile.in b/db/mdb/Makefile.in deleted file mode 100644 index 6cff7d00941f..000000000000 --- a/db/mdb/Makefile.in +++ /dev/null @@ -1,48 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -DIRS = public - -include $(topsrcdir)/config/rules.mk - diff --git a/db/mdb/public/Makefile.in b/db/mdb/public/Makefile.in deleted file mode 100644 index fbbb690adc2f..000000000000 --- a/db/mdb/public/Makefile.in +++ /dev/null @@ -1,51 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1999 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = mork -XPIDL_MODULE = msgmdb - -EXPORTS = mdb.h - -include $(topsrcdir)/config/rules.mk - diff --git a/db/mdb/public/mdb.h b/db/mdb/public/mdb.h deleted file mode 100644 index 33a84e5f1d8b..000000000000 --- a/db/mdb/public/mdb.h +++ /dev/null @@ -1,2569 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Blake Ross (blake@blakeross.com) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#define _MDB_ 1 - -#include "nscore.h" -#include "nsISupports.h" -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// { %%%%% begin scalar typedefs %%%%% -typedef unsigned char mdb_u1; // make sure this is one byte -typedef unsigned short mdb_u2; // make sure this is two bytes -typedef short mdb_i2; // make sure this is two bytes -typedef PRUint32 mdb_u4; // make sure this is four bytes -typedef PRInt32 mdb_i4; // make sure this is four bytes -typedef PRWord mdb_ip; // make sure sizeof(mdb_ip) == sizeof(void*) - -typedef mdb_u1 mdb_bool; // unsigned byte with zero=false, nonzero=true - -/* canonical boolean constants provided only for code clarity: */ -#define mdbBool_kTrue ((mdb_bool) 1) /* actually any nonzero means true */ -#define mdbBool_kFalse ((mdb_bool) 0) /* only zero means false */ - -typedef mdb_u4 mdb_id; // unsigned object identity in a scope -typedef mdb_id mdb_rid; // unsigned row identity inside scope -typedef mdb_id mdb_tid; // unsigned table identity inside scope -typedef mdb_u4 mdb_token; // unsigned token for atomized string -typedef mdb_token mdb_scope; // token used to id scope for rows -typedef mdb_token mdb_kind; // token used to id kind for tables -typedef mdb_token mdb_column; // token used to id columns for rows -typedef mdb_token mdb_cscode; // token used to id charset names -typedef mdb_u4 mdb_seed; // unsigned collection change counter -typedef mdb_u4 mdb_count; // unsigned collection member count -typedef mdb_u4 mdb_size; // unsigned physical media size -typedef mdb_u4 mdb_fill; // unsigned logical content size -typedef mdb_u4 mdb_more; // more available bytes for larger buffer - -#define mdbId_kNone ((mdb_id) -1) /* never a valid Mork object ID */ - -typedef mdb_u4 mdb_percent; // 0..100, with values >100 same as 100 - -typedef mdb_u1 mdb_priority; // 0..9, for a total of ten different values - -// temporary substitute for NS_RESULT, for mdb.h standalone compilation: -typedef nsresult mdb_err; // equivalent to NS_RESULT - -// sequence position is signed; negative is useful to mean "before first": -typedef mdb_i4 mdb_pos; // signed zero-based ordinal collection position - -#define mdbPos_kBeforeFirst ((mdb_pos) -1) /* any negative is before zero */ - -// order is also signed, so we can use three states for comparison order: -typedef mdb_i4 mdb_order; // neg:lessthan, zero:equalto, pos:greaterthan - -typedef mdb_order (* mdbAny_Order)(const void* inA, const void* inB, - const void* inClosure); - -// } %%%%% end scalar typedefs %%%%% - -// { %%%%% begin C structs %%%%% - -#ifndef mdbScopeStringSet_typedef -typedef struct mdbScopeStringSet mdbScopeStringSet; -#define mdbScopeStringSet_typedef 1 -#endif - -/*| mdbScopeStringSet: a set of null-terminated C strings that enumerate some -**| names of row scopes, so that row scopes intended for use by an application -**| can be declared by an app when trying to open or create a database file. -**| (We use strings and not tokens because we cannot know the tokens for any -**| particular db without having first opened the db.) The goal is to inform -**| a db runtime that scopes not appearing in this list can be given relatively -**| short shrift in runtime representation, with the expectation that other -**| scopes will not actually be used. However, a db should still be prepared -**| to handle accessing row scopes not in this list, rather than raising errors. -**| But it could be quite expensive to access a row scope not on the list. -**| Note a zero count for the string set means no such string set is being -**| specified, and that a db should handle all row scopes efficiently. -**| (It does NOT mean an app plans to use no content whatsoever.) -|*/ -#ifndef mdbScopeStringSet_struct -#define mdbScopeStringSet_struct 1 -struct mdbScopeStringSet { // vector of scopes for use in db opening policy - // when mScopeStringSet_Count is zero, this means no scope constraints - mdb_count mScopeStringSet_Count; // number of strings in vector below - const char** mScopeStringSet_Strings; // null-ended ascii scope strings -}; -#endif /*mdbScopeStringSet_struct*/ - -#ifndef mdbOpenPolicy_typedef -typedef struct mdbOpenPolicy mdbOpenPolicy; -#define mdbOpenPolicy_typedef 1 -#endif - -#ifndef mdbOpenPolicy_struct -#define mdbOpenPolicy_struct 1 -struct mdbOpenPolicy { // policies affecting db usage for ports and stores - mdbScopeStringSet mOpenPolicy_ScopePlan; // predeclare scope usage plan - mdb_bool mOpenPolicy_MaxLazy; // nonzero: do least work - mdb_bool mOpenPolicy_MinMemory; // nonzero: use least memory -}; -#endif /*mdbOpenPolicy_struct*/ - -#ifndef mdbTokenSet_typedef -typedef struct mdbTokenSet mdbTokenSet; -#define mdbTokenSet_typedef 1 -#endif - -#ifndef mdbTokenSet_struct -#define mdbTokenSet_struct 1 -struct mdbTokenSet { // array for a set of tokens, and actual slots used - mdb_count mTokenSet_Count; // number of token slots in the array - mdb_fill mTokenSet_Fill; // the subset of count slots actually used - mdb_more mTokenSet_More; // more tokens available for bigger array - mdb_token* mTokenSet_Tokens; // array of count mdb_token instances -}; -#endif /*mdbTokenSet_struct*/ - -#ifndef mdbUsagePolicy_typedef -typedef struct mdbUsagePolicy mdbUsagePolicy; -#define mdbUsagePolicy_typedef 1 -#endif - -/*| mdbUsagePolicy: another version of mdbOpenPolicy which uses tokens instead -**| of scope strings, because usage policies can be constructed for use with a -**| db that is already open, while an open policy must be constructed before a -**| db has yet been opened. -|*/ -#ifndef mdbUsagePolicy_struct -#define mdbUsagePolicy_struct 1 -struct mdbUsagePolicy { // policies affecting db usage for ports and stores - mdbTokenSet mUsagePolicy_ScopePlan; // current scope usage plan - mdb_bool mUsagePolicy_MaxLazy; // nonzero: do least work - mdb_bool mUsagePolicy_MinMemory; // nonzero: use least memory -}; -#endif /*mdbUsagePolicy_struct*/ - -#ifndef mdbOid_typedef -typedef struct mdbOid mdbOid; -#define mdbOid_typedef 1 -#endif - -#ifndef mdbOid_struct -#define mdbOid_struct 1 -struct mdbOid { // identity of some row or table inside a database - mdb_scope mOid_Scope; // scope token for an id's namespace - mdb_id mOid_Id; // identity of object inside scope namespace -}; -#endif /*mdbOid_struct*/ - -#ifndef mdbRange_typedef -typedef struct mdbRange mdbRange; -#define mdbRange_typedef 1 -#endif - -#ifndef mdbRange_struct -#define mdbRange_struct 1 -struct mdbRange { // range of row positions in a table - mdb_pos mRange_FirstPos; // position of first row - mdb_pos mRange_LastPos; // position of last row -}; -#endif /*mdbRange_struct*/ - -#ifndef mdbColumnSet_typedef -typedef struct mdbColumnSet mdbColumnSet; -#define mdbColumnSet_typedef 1 -#endif - -#ifndef mdbColumnSet_struct -#define mdbColumnSet_struct 1 -struct mdbColumnSet { // array of column tokens (just the same as mdbTokenSet) - mdb_count mColumnSet_Count; // number of columns - mdb_column* mColumnSet_Columns; // count mdb_column instances -}; -#endif /*mdbColumnSet_struct*/ - -#ifndef mdbYarn_typedef -typedef struct mdbYarn mdbYarn; -#define mdbYarn_typedef 1 -#endif - -#ifdef MDB_BEGIN_C_LINKAGE_define -#define MDB_BEGIN_C_LINKAGE_define 1 -#define MDB_BEGIN_C_LINKAGE extern "C" { -#define MDB_END_C_LINKAGE } -#endif /*MDB_BEGIN_C_LINKAGE_define*/ - -/*| mdbYarn_mGrow: an abstract API for growing the size of a mdbYarn -**| instance. With respect to a specific API that requires a caller -**| to supply a string (mdbYarn) that a callee fills with content -**| that might exceed the specified size, mdbYarn_mGrow is a caller- -**| supplied means of letting a callee attempt to increase the string -**| size to become large enough to receive all content available. -**| -**|| Grow(): a method for requesting that a yarn instance be made -**| larger in size. Note that such requests need not be honored, and -**| need not be honored in full if only partial size growth is desired. -**| (Note that no nsIMdbEnv instance is passed as argument, although one -**| might be needed in some circumstances. So if an nsIMdbEnv is needed, -**| a reference to one might be held inside a mdbYarn member slot.) -**| -**|| self: a yarn instance to be grown. Presumably this yarn is -**| the instance which holds the mYarn_Grow method pointer. Yarn -**| instancesshould only be passed to grow methods which they were -**| specifically designed to fit, as indicated by the mYarn_Grow slot. -**| -**|| inNewSize: the new desired value for slot mYarn_Size in self. -**| If mYarn_Size is already this big, then nothing should be done. -**| If inNewSize is larger than seems feasible or desirable to honor, -**| then any size restriction policy can be used to grow to some size -**| greater than mYarn_Size. (Grow() might even grow to a size -**| greater than inNewSize in order to make the increase in size seem -**| worthwhile, rather than growing in many smaller steps over time.) -|*/ -typedef void (* mdbYarn_mGrow)(mdbYarn* self, mdb_size inNewSize); -// mdbYarn_mGrow methods must be declared with C linkage in C++ - -/*| mdbYarn: a variable length "string" of arbitrary binary bytes, -**| whose length is mYarn_Fill, inside a buffer mYarn_Buf that has -**| at most mYarn_Size byte of physical space. -**| -**|| mYarn_Buf: a pointer to space containing content. This slot -**| might never be nil when mYarn_Size is nonzero, but checks for nil -**| are recommended anyway. -**| (Implementations of mdbYarn_mGrow methods should take care to -**| ensure the existence of a replacement before dropping old Bufs.) -**| Content in Buf can be anything in any format, but the mYarn_Form -**| implies the actual format by some caller-to-callee convention. -**| mYarn_Form==0 implies US-ASCII iso-8859-1 Latin1 string content. -**| -**|| mYarn_Size: the physical size of Buf in bytes. Note that if one -**| intends to terminate a string with a null byte, that it must not -**| be written at or after mYarn_Buf[mYarn_Size] because this is after -**| the last byte in the physical buffer space. Size can be zero, -**| which means the string has no content whatsoever; note that when -**| Size is zero, this is a suitable reason for Buf==nil as well. -**| -**|| mYarn_Fill: the logical content in Buf in bytes, where Fill must -**| never exceed mYarn_Size. Note that yarn strings might not have a -**| terminating null byte (since they might not even be C strings), but -**| when they do, such terminating nulls are considered part of content -**| and therefore Fill will count such null bytes. So an "empty" C -**| string will have Fill==1, because content includes one null byte. -**| Fill does not mean "length" when applied to C strings for this -**| reason. However, clients using yarns to hold C strings can infer -**| that length is equal to Fill-1 (but should take care to handle the -**| case where Fill==0). To be paranoid, one can always copy to a -**| destination with size exceeding Fill, and place a redundant null -**| byte in the Fill position when this simplifies matters. -**| -**|| mYarn_Form: a designation of content format within mYarn_Buf. -**| The semantics of this slot are the least well defined, since the -**| actual meaning is context dependent, to the extent that callers -**| and callees must agree on format encoding conventions when such -**| are not standardized in many computing contexts. However, in the -**| context of a specific mdb database, mYarn_Form is a token for an -**| atomized string in that database that typically names a preferred -**| mime type charset designation. If and when mdbYarn is used for -**| other purposes away from the mdb interface, folks can use another -**| convention system for encoding content formats. However, in all -**| contexts is it useful to maintain the convention that Form==0 -**| implies Buf contains US-ASCII iso-8859-1 Latin1 string content. -**| -**|| mYarn_Grow: either a mdbYarn_mGrow method, or else nil. When -**| a mdbYarn_mGrow method is provided, this method can be used to -**| request a yarn buf size increase. A caller who constructs the -**| original mdbYarn instance decides whether a grow method is necessary -**| or desirable, and uses only grow methods suitable for the buffering -**| nature of a specific mdbYarn instance. (For example, Buf might be a -**| staticly allocated string space which switches to something heap-based -**| when grown, and subsequent calls to grow the yarn must distinguish the -**| original static string from heap allocated space, etc.) Note that the -**| method stored in mYarn_Grow can change, and this might be a common way -**| to track memory managent changes in policy for mYarn_Buf. -|*/ -#ifndef mdbYarn_struct -#define mdbYarn_struct 1 -struct mdbYarn { // buffer with caller space allocation semantics - void* mYarn_Buf; // space for holding any binary content - mdb_fill mYarn_Fill; // logical content in Buf in bytes - mdb_size mYarn_Size; // physical size of Buf in bytes - mdb_more mYarn_More; // more available bytes if Buf is bigger - mdb_cscode mYarn_Form; // charset format encoding - mdbYarn_mGrow mYarn_Grow; // optional method to grow mYarn_Buf - - // Subclasses might add further slots after mYarn_Grow in order to - // maintain bookkeeping needs, such as state info about mYarn_Buf. -}; -#endif /*mdbYarn_struct*/ - -// } %%%%% end C structs %%%%% - -// { %%%%% begin class forward defines %%%%% -class nsIMdbEnv; -class nsIMdbObject; -class nsIMdbErrorHook; -class nsIMdbCompare; -class nsIMdbThumb; -class nsIMdbFactory; -class nsIMdbFile; -class nsIMdbPort; -class nsIMdbStore; -class nsIMdbCursor; -class nsIMdbPortTableCursor; -class nsIMdbCollection; -class nsIMdbTable; -class nsIMdbTableRowCursor; -class nsIMdbRow; -class nsIMdbRowCellCursor; -class nsIMdbBlob; -class nsIMdbCell; -class nsIMdbSorting; -// } %%%%% end class forward defines %%%%% - - -// { %%%%% begin C++ abstract class interfaces %%%%% - -/*| nsIMdbObject: base class for all message db class interfaces -**| -**|| factory: all nsIMdbObjects from the same code suite have the same factory -**| -**|| refcounting: both strong and weak references, to ensure strong refs are -**| acyclic, while weak refs can cause cycles. CloseMdbObject() is -**| called when (strong) use counts hit zero, but clients can call this close -**| method early for some reason, if absolutely necessary even though it will -**| thwart the other uses of the same object. Note that implementations must -**| cope with close methods being called arbitrary numbers of times. The COM -**| calls to AddRef() and release ref map directly to strong use ref calls, -**| but the total ref count for COM objects is the sum of weak & strong refs. -|*/ - -#define NS_IMDBOBJECT_IID_STR "5533ea4b-14c3-4bef-ac60-22f9e9a49084" - -#define NS_IMDBOBJECT_IID \ -{0x5533ea4b, 0x14c3, 0x4bef, \ -{ 0xac, 0x60, 0x22, 0xf9, 0xe9, 0xa4, 0x90, 0x84}} - -class nsIMdbObject : public nsISupports { // msg db base class -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBOBJECT_IID) -// { ===== begin nsIMdbObject methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly) = 0; - // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port. - // } ----- end attribute methods ----- - - // { ----- begin factory methods ----- - NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory) = 0; - // } ----- end factory methods ----- - - // { ----- begin ref counting for well-behaved cyclic graphs ----- - NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs - mdb_count* outCount) = 0; - NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs - mdb_count* outCount) = 0; - - NS_IMETHOD AddWeakRef(nsIMdbEnv* ev) = 0; - NS_IMETHOD AddStrongRef(nsIMdbEnv* ev) = 0; - - NS_IMETHOD CutWeakRef(nsIMdbEnv* ev) = 0; - NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) = 0; - - NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev) = 0; // called at strong refs zero - NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen) = 0; - // } ----- end ref counting ----- - -// } ===== end nsIMdbObject methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbObject, NS_IMDBOBJECT_IID) - -/*| nsIMdbErrorHook: a base class for clients of this API to subclass, in order -**| to provide a callback installable in nsIMdbEnv for error notifications. If -**| apps that subclass nsIMdbErrorHook wish to maintain a reference to the env -**| that contains the hook, then this should be a weak ref to avoid cycles. -**| -**|| OnError: when nsIMdbEnv has an error condition that causes the total count -**| of errors to increase, then nsIMdbEnv should call OnError() to report the -**| error in some fashion when an instance of nsIMdbErrorHook is installed. The -**| variety of string flavors is currently due to the uncertainty here in the -**| nsIMdbBlob and nsIMdbCell interfaces. (Note that overloading by using the -**| same method name is not necessary here, and potentially less clear.) -|*/ -class nsIMdbErrorHook : public nsISupports{ // env callback handler to report errors -public: - -// { ===== begin error methods ===== - NS_IMETHOD OnErrorString(nsIMdbEnv* ev, const char* inAscii) = 0; - NS_IMETHOD OnErrorYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0; -// } ===== end error methods ===== - -// { ===== begin warning methods ===== - NS_IMETHOD OnWarningString(nsIMdbEnv* ev, const char* inAscii) = 0; - NS_IMETHOD OnWarningYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0; -// } ===== end warning methods ===== - -// { ===== begin abort hint methods ===== - NS_IMETHOD OnAbortHintString(nsIMdbEnv* ev, const char* inAscii) = 0; - NS_IMETHOD OnAbortHintYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0; -// } ===== end abort hint methods ===== -}; - -/*| nsIMdbCompare: a caller-supplied yarn comparison interface. When two yarns -**| are compared to each other with Order(), this method should return a signed -**| long integer denoting relation R between the 1st and 2nd yarn instances -**| such that (First R Second), where negative is less than, zero is equal to, -**| and positive is greater than. Note that both yarns are readonly, and the -**| Order() method should make no attempt to modify the yarn content. -|*/ -class nsIMdbCompare { // caller-supplied yarn comparison -public: - -// { ===== begin nsIMdbCompare methods ===== - NS_IMETHOD Order(nsIMdbEnv* ev, // compare first to second yarn - const mdbYarn* inFirst, // first yarn in comparison - const mdbYarn* inSecond, // second yarn in comparison - mdb_order* outOrder) = 0; // negative="<", zero="=", positive=">" - - NS_IMETHOD AddStrongRef(nsIMdbEnv* ev) = 0; // does nothing - NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) = 0; // does nothing -// } ===== end nsIMdbCompare methods ===== - -}; - -/*| nsIMdbHeap: abstract memory allocation interface. -**| -**|| Alloc: return a block at least inSize bytes in size with alignment -**| suitable for any native type (such as long integers). When no such -**| block can be allocated, failure is indicated by a null address in -**| addition to reporting an error in the environment. -**| -**|| Free: deallocate a block allocated or resized earlier by the same -**| heap instance. If the inBlock parameter is nil, the heap should do -**| nothing (and crashing is strongly discouraged). -|*/ -class nsIMdbHeap { // caller-supplied memory management interface -public: -// { ===== begin nsIMdbHeap methods ===== - NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory - mdb_size inSize, // requested byte size of new memory block - void** outBlock) = 0; // memory block of inSize bytes, or nil - - NS_IMETHOD Free(nsIMdbEnv* ev, // free block from Alloc or Resize() - void* ioBlock) = 0; // block to be destroyed/deallocated - - NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev) = 0; - NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev) = 0; - -// } ===== end nsIMdbHeap methods ===== -}; - -/*| nsIMdbCPlusHeap: Alloc() with global ::new(), Free() with global ::delete(). -**| Resize() is done by ::new() followed by ::delete(). -|*/ -class nsIMdbCPlusHeap { // caller-supplied memory management interface -public: -// { ===== begin nsIMdbHeap methods ===== - NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory - mdb_size inSize, // requested size of new memory block - void** outBlock); // memory block of inSize bytes, or nil - - NS_IMETHOD Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc() - void* inBlock); - - NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev); - NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev); -// } ===== end nsIMdbHeap methods ===== -}; - -/*| nsIMdbThumb: -|*/ - - -#define NS_IMDBTHUMB_IID_STR "6d3ad7c1-a809-4e74-8577-49fa9a4562fa" - -#define NS_IMDBTHUMB_IID \ -{0x6d3ad7c1, 0xa809, 0x4e74, \ -{ 0x85, 0x77, 0x49, 0xfa, 0x9a, 0x45, 0x62, 0xfa}} - - -class nsIMdbThumb : public nsISupports { // closure for repeating incremental method -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTHUMB_IID) - -// { ===== begin nsIMdbThumb methods ===== - NS_IMETHOD GetProgress(nsIMdbEnv* ev, - mdb_count* outTotal, // total somethings to do in operation - mdb_count* outCurrent, // subportion of total completed so far - mdb_bool* outDone, // is operation finished? - mdb_bool* outBroken // is operation irreparably dead and broken? - ) = 0; - - NS_IMETHOD DoMore(nsIMdbEnv* ev, - mdb_count* outTotal, // total somethings to do in operation - mdb_count* outCurrent, // subportion of total completed so far - mdb_bool* outDone, // is operation finished? - mdb_bool* outBroken // is operation irreparably dead and broken? - ) = 0; - - NS_IMETHOD CancelAndBreakThumb( // cancel pending operation - nsIMdbEnv* ev) = 0; -// } ===== end nsIMdbThumb methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbThumb, NS_IMDBTHUMB_IID) - -/*| nsIMdbEnv: a context parameter used when calling most abstract db methods. -**| The main purpose of such an object is to permit a database implementation -**| to avoid the use of globals to share information between various parts of -**| the implementation behind the abstract db interface. An environment acts -**| like a session object for a given calling thread, and callers should use -**| at least one different nsIMdbEnv instance for each thread calling the API. -**| While the database implementation might not be threaded, it is highly -**| desirable that the db be thread-safe if calling threads use distinct -**| instances of nsIMdbEnv. Callers can stop at one nsIMdbEnv per thread, or they -**| might decide to make on nsIMdbEnv instance for every nsIMdbPort opened, so that -**| error information is segregated by database instance. Callers create -**| instances of nsIMdbEnv by calling the MakeEnv() method in nsIMdbFactory. -**| -**|| tracing: an environment might support some kind of tracing, and this -**| boolean attribute permits such activity to be enabled or disabled. -**| -**|| errors: when a call to the abstract db interface returns, a caller might -**| check the number of outstanding errors to see whether the operation did -**| actually succeed. Each nsIMdbEnv should have all its errors cleared by a -**| call to ClearErrors() before making each call to the abstract db API, -**| because outstanding errors might disable further database actions. (This -**| is not done inside the db interface, because the db cannot in general know -**| when a call originates from inside or outside -- only the app knows this.) -**| -**|| error hook: callers can install an instance of nsIMdbErrorHook to receive -**| error notifications whenever the error count increases. The hook can -**| be uninstalled by passing a null pointer. -**| -|*/ - -#define NS_IMDBENV_IID_STR "a765e46b-efb6-41e6-b75b-c5d6bd710594" - -#define NS_IMDBENV_IID \ -{0xa765e46b, 0xefb6, 0x41e6, \ -{ 0xb7, 0x5b, 0xc5, 0xd6, 0xbd, 0x71, 0x05, 0x94}} - -class nsIMdbEnv : public nsISupports { // db specific context parameter -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBENV_IID) -// { ===== begin nsIMdbEnv methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetErrorCount(mdb_count* outCount, - mdb_bool* outShouldAbort) = 0; - NS_IMETHOD GetWarningCount(mdb_count* outCount, - mdb_bool* outShouldAbort) = 0; - - NS_IMETHOD GetEnvBeVerbose(mdb_bool* outBeVerbose) = 0; - NS_IMETHOD SetEnvBeVerbose(mdb_bool inBeVerbose) = 0; - - NS_IMETHOD GetDoTrace(mdb_bool* outDoTrace) = 0; - NS_IMETHOD SetDoTrace(mdb_bool inDoTrace) = 0; - - NS_IMETHOD GetAutoClear(mdb_bool* outAutoClear) = 0; - NS_IMETHOD SetAutoClear(mdb_bool inAutoClear) = 0; - - NS_IMETHOD GetErrorHook(nsIMdbErrorHook** acqErrorHook) = 0; - NS_IMETHOD SetErrorHook( - nsIMdbErrorHook* ioErrorHook) = 0; // becomes referenced - - NS_IMETHOD GetHeap(nsIMdbHeap** acqHeap) = 0; - NS_IMETHOD SetHeap( - nsIMdbHeap* ioHeap) = 0; // becomes referenced - // } ----- end attribute methods ----- - - NS_IMETHOD ClearErrors() = 0; // clear errors beore re-entering db API - NS_IMETHOD ClearWarnings() = 0; // clear warnings - NS_IMETHOD ClearErrorsAndWarnings() = 0; // clear both errors & warnings -// } ===== end nsIMdbEnv methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbEnv, NS_IMDBENV_IID) - -/*| nsIMdbFactory: the main entry points to the abstract db interface. A DLL -**| that supports this mdb interface need only have a single exported method -**| that will return an instance of nsIMdbFactory, so that further methods in -**| the suite can be accessed from objects returned by nsIMdbFactory methods. -**| -**|| mdbYarn: note all nsIMdbFactory subclasses must guarantee null -**| termination of all strings written into mdbYarn instances, as long as -**| mYarn_Size and mYarn_Buf are nonzero. Even truncated string values must -**| be null terminated. This is more strict behavior than mdbYarn requires, -**| but it is part of the nsIMdbFactory interface. -**| -**|| envs: an environment instance is required as per-thread context for -**| most of the db method calls, so nsIMdbFactory creates such instances. -**| -**|| rows: callers must be able to create row instances that are independent -**| of storage space that is part of the db content graph. Many interfaces -**| for data exchange have strictly copy semantics, so that a row instance -**| has no specific identity inside the db content model, and the text in -**| cells are an independenty copy of unexposed content inside the db model. -**| Callers are expected to maintain one or more row instances as a buffer -**| for staging cell content copied into or out of a table inside the db. -**| Callers are urged to use an instance of nsIMdbRow created by the nsIMdbFactory -**| code suite, because reading and writing might be much more efficient than -**| when using a hand-rolled nsIMdbRow subclass with no relation to the suite. -**| -**|| ports: a port is a readonly interface to a specific database file. Most -**| of the methods to access a db file are suitable for a readonly interface, -**| so a port is the basic minimum for accessing content. This makes it -**| possible to read other external formats for import purposes, without -**| needing the code or competence necessary to write every such format. So -**| we can write generic import code just once, as long as every format can -**| show a face based on nsIMdbPort. (However, same suite import can be faster.) -**| Given a file name and the first 512 bytes of a file, a factory can say if -**| a port can be opened by this factory. Presumably an app maintains chains -**| of factories for different suites, and asks each in turn about opening a -**| a prospective file for reading (as a port) or writing (as a store). I'm -**| not ready to tackle issues of format fidelity and factory chain ordering. -**| -**|| stores: a store is a mutable interface to a specific database file, and -**| includes the port interface plus any methods particular to writing, which -**| are few in number. Presumably the set of files that can be opened as -**| stores is a subset of the set of files that can be opened as ports. A -**| new store can be created with CreateNewFileStore() by supplying a new -**| file name which does not yet exist (callers are always responsible for -**| destroying any existing files before calling this method). -|*/ - -#define NS_IMDBFACTORY_IID_STR "2b80395c-b91e-4990-b1a7-023e99ab14e9" - -#define NS_IMDBFACTORY_IID \ -{0xf04aa4ab, 0x1fe, 0x4115, \ -{ 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d}} - - -class nsIMdbFactory : public nsISupports { // suite entry points -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFACTORY_IID) -// { ===== begin nsIMdbFactory methods ===== - - // { ----- begin file methods ----- - NS_IMETHOD OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, - mdb_bool inFrozen, nsIMdbFile** acqFile) = 0; - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be open and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - - NS_IMETHOD CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, - nsIMdbFile** acqFile) = 0; - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be created and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - // } ----- end file methods ----- - - // { ----- begin env methods ----- - NS_IMETHOD MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv) = 0; // acquire new env - // ioHeap can be nil, causing a MakeHeap() style heap instance to be used - // } ----- end env methods ----- - - // { ----- begin heap methods ----- - NS_IMETHOD MakeHeap(nsIMdbEnv* ev, nsIMdbHeap** acqHeap) = 0; // acquire new heap - // } ----- end heap methods ----- - - // { ----- begin compare methods ----- - NS_IMETHOD MakeCompare(nsIMdbEnv* ev, nsIMdbCompare** acqCompare) = 0; // ASCII - // } ----- end compare methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbRow** acqRow) = 0; // new row - // ioHeap can be nil, causing the heap associated with ev to be used - // } ----- end row methods ----- - - // { ----- begin port methods ----- - NS_IMETHOD CanOpenFilePort( - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpen, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion) = 0; // informal file format description - - NS_IMETHOD OpenFilePort( - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for readonly import - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental port open - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then call nsIMdbFactory::ThumbToOpenPort() to get the port instance. - - NS_IMETHOD ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort() - nsIMdbEnv* ev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status - nsIMdbPort** acqPort) = 0; // acquire new port object - // } ----- end port methods ----- - - // { ----- begin store methods ----- - NS_IMETHOD CanOpenFileStore( - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed - mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion) = 0; // informal file format description - - NS_IMETHOD OpenFileStore( // open an existing database - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for general db usage - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental store open - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then call nsIMdbFactory::ThumbToOpenStore() to get the store instance. - - NS_IMETHOD - ThumbToOpenStore( // redeem completed thumb from OpenFileStore() - nsIMdbEnv* ev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status - nsIMdbStore** acqStore) = 0; // acquire new db store object - - NS_IMETHOD CreateNewFileStore( // create a new db with minimal content - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // name of file which should not yet exist - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbStore** acqStore) = 0; // acquire new db store object - // } ----- end store methods ----- - -// } ===== end nsIMdbFactory methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFactory, NS_IMDBFACTORY_IID) - -extern "C" nsIMdbFactory* MakeMdbFactory(); - -/*| nsIMdbFile: abstract file interface resembling the original morkFile -**| abstract interface (which was in turn modeled on the file interface -**| from public domain IronDoc). The design of this file interface is -**| complicated by the fact that some DB's will not find this interface -**| adequate for all runtime requirements (even though this file API is -**| enough to implement text-based DB's like Mork). For this reason, -**| more methods have been added to let a DB library force the file to -**| become closed so the DB can reopen the file in some other manner. -**| Folks are encouraged to suggest ways to tune this interface to suit -**| DB's that cannot manage to pull their maneuvers even given this API. -**| -**|| Tell: get the current i/o position in file -**| -**|| Seek: change the current i/o position in file -**| -**|| Eof: return file's total length in bytes -**| -**|| Read: input inSize bytes into outBuf, returning actual transfer size -**| -**|| Get: read starting at specific file offset (e.g. Seek(); Read();) -**| -**|| Write: output inSize bytes from inBuf, returning actual transfer size -**| -**|| Put: write starting at specific file offset (e.g. Seek(); Write();) -**| -**|| Flush: if written bytes are buffered, push them to final destination -**| -**|| Path: get file path in some string representation. This is intended -**| either to support the display of file name in a user presentation, or -**| to support the closing and reopening of the file when the DB needs more -**| exotic file access than is presented by the nsIMdbFile interface. -**| -**|| Steal: tell this file to close any associated i/o stream in the file -**| system, because the file ioThief intends to reopen the file in order -**| to provide the MDB implementation with more exotic file access than is -**| offered by the nsIMdbFile alone. Presumably the thief knows enough -**| from Path() in order to know which file to reopen. If Steal() is -**| successful, this file should probably delegate all future calls to -**| the nsIMdbFile interface down to the thief files, so that even after -**| the file has been stolen, it can still be read, written, or forcibly -**| closed (by a call to CloseMdbObject()). -**| -**|| Thief: acquire and return thief passed to an earlier call to Steal(). -|*/ - -#define NS_IMDBFILE_IID_STR "f04aa4ab-1fe7-4115-a4a5-6819dff1103d" - -#define NS_IMDBFILE_IID \ -{0xf04aa4ab, 0x1fe, 0x4115, \ -{ 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d}} - -class nsIMdbFile : public nsISupports { // minimal file interface -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFILE_IID) -// { ===== begin nsIMdbFile methods ===== - - // { ----- begin pos methods ----- - NS_IMETHOD Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0; - NS_IMETHOD Seek(nsIMdbEnv* ev, mdb_pos inPos, mdb_pos *outPos) = 0; - NS_IMETHOD Eof(nsIMdbEnv* ev, mdb_pos* outPos) = 0; - // } ----- end pos methods ----- - - // { ----- begin read methods ----- - NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, - mdb_size* outActualSize) = 0; - NS_IMETHOD Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize) = 0; - // } ----- end read methods ----- - - // { ----- begin write methods ----- - NS_IMETHOD Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, - mdb_size* outActualSize) = 0; - NS_IMETHOD Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize) = 0; - NS_IMETHOD Flush(nsIMdbEnv* ev) = 0; - // } ----- end attribute methods ----- - - // { ----- begin path methods ----- - NS_IMETHOD Path(nsIMdbEnv* ev, mdbYarn* outFilePath) = 0; - // } ----- end path methods ----- - - // { ----- begin replacement methods ----- - NS_IMETHOD Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0; - NS_IMETHOD Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief) = 0; - // } ----- end replacement methods ----- - - // { ----- begin versioning methods ----- - NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev) = 0; - // If this file is a file version branch created by calling AcquireBud(), - // BecomeTrunk() causes this file's content to replace the original - // file's content, typically by assuming the original file's identity. - // This default implementation of BecomeTrunk() does nothing, and this - // is appropriate behavior for files which are not branches, and is - // also the right behavior for files returned from AcquireBud() which are - // in fact the original file that has been truncated down to zero length. - - NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - nsIMdbFile** acqBud) = 0; // acquired file for new version of content - // AcquireBud() starts a new "branch" version of the file, empty of content, - // so that a new version of the file can be written. This new file - // can later be told to BecomeTrunk() the original file, so the branch - // created by budding the file will replace the original file. Some - // file subclasses might initially take the unsafe but expedient - // approach of simply truncating this file down to zero length, and - // then returning the same morkFile pointer as this, with an extra - // reference count increment. Note that the caller of AcquireBud() is - // expected to eventually call CutStrongRef() on the returned file - // in order to release the strong reference. High quality versions - // of morkFile subclasses will create entirely new files which later - // are renamed to become the old file, so that better transactional - // behavior is exhibited by the file, so crashes protect old files. - // Note that AcquireBud() is an illegal operation on readonly files. - // } ----- end versioning methods ----- - -// } ===== end nsIMdbFile methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFile, NS_IMDBFILE_IID) - -/*| nsIMdbPort: a readonly interface to a specific database file. The mutable -**| nsIMdbStore interface is a subclass that includes writing behavior, but -**| most of the needed db methods appear in the readonly nsIMdbPort interface. -**| -**|| mdbYarn: note all nsIMdbPort and nsIMdbStore subclasses must guarantee null -**| termination of all strings written into mdbYarn instances, as long as -**| mYarn_Size and mYarn_Buf are nonzero. Even truncated string values must -**| be null terminated. This is more strict behavior than mdbYarn requires, -**| but it is part of the nsIMdbPort and nsIMdbStore interface. -**| -**|| attributes: methods are provided to distinguish a readonly port from a -**| mutable store, and whether a mutable store actually has any dirty content. -**| -**|| filepath: the file path used to open the port from the nsIMdbFactory can be -**| queried and discovered by GetPortFilePath(), which includes format info. -**| -**|| export: a port can write itself in other formats, with perhaps a typical -**| emphasis on text interchange formats used by other systems. A port can be -**| queried to determine its preferred export interchange format, and a port -**| can be queried to see whether a specific export format is supported. And -**| actually exporting a port requires a new destination file name and format. -**| -**|| tokens: a port supports queries about atomized strings to map tokens to -**| strings or strings to token integers. (All atomized strings must be in -**| US-ASCII iso-8859-1 Latin1 charset encoding.) When a port is actually a -**| mutable store and a string has not yet been atomized, then StringToToken() -**| will actually do so and modify the store. The QueryToken() method will not -**| atomize a string if it has not already been atomized yet, even in stores. -**| -**|| tables: other than string tokens, all port content is presented through -**| tables, which are ordered collections of rows. Tables are identified by -**| row scope and table kind, which might or might not be unique in a port, -**| depending on app convention. When tables are effectively unique, then -**| queries for specific scope and kind pairs will find those tables. To see -**| all tables that match specific row scope and table kind patterns, even in -**| the presence of duplicates, every port supports a GetPortTableCursor() -**| method that returns an iterator over all matching tables. Table kind is -**| considered scoped inside row scope, so passing a zero for table kind will -**| find all table kinds for some nonzero row scope. Passing a zero for row -**| scope will iterate over all tables in the port, in some undefined order. -**| (A new table can be added to a port using nsIMdbStore::NewTable(), even when -**| the requested scope and kind combination is already used by other tables.) -**| -**|| memory: callers can request that a database use less memory footprint in -**| several flavors, from an inconsequential idle flavor to a rather drastic -**| panic flavor. Callers might perform an idle purge very frequently if desired -**| with very little cost, since only normally scheduled memory management will -**| be conducted, such as freeing resources for objects scheduled to be dropped. -**| Callers should perform session memory purges infrequently because they might -**| involve costly scanning of data structures to removed cached content, and -**| session purges are recommended only when a caller experiences memory crunch. -**| Callers should only rarely perform a panic purge, in response to dire memory -**| straits, since this is likely to make db operations much more expensive -**| than they would be otherwise. A panic purge asks a database to free as much -**| memory as possible while staying effective and operational, because a caller -**| thinks application failure might otherwise occur. (Apps might better close -**| an open db, so panic purges only make sense when a db is urgently needed.) -|*/ -class nsIMdbPort : public nsISupports { -public: - -// { ===== begin nsIMdbPort methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetIsPortReadonly(nsIMdbEnv* ev, mdb_bool* outBool) = 0; - NS_IMETHOD GetIsStore(nsIMdbEnv* ev, mdb_bool* outBool) = 0; - NS_IMETHOD GetIsStoreAndDirty(nsIMdbEnv* ev, mdb_bool* outBool) = 0; - - NS_IMETHOD GetUsagePolicy(nsIMdbEnv* ev, - mdbUsagePolicy* ioUsagePolicy) = 0; - - NS_IMETHOD SetUsagePolicy(nsIMdbEnv* ev, - const mdbUsagePolicy* inUsagePolicy) = 0; - // } ----- end attribute methods ----- - - // { ----- begin memory policy methods ----- - NS_IMETHOD IdleMemoryPurge( // do memory management already scheduled - nsIMdbEnv* ev, // context - mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed - - NS_IMETHOD SessionMemoryPurge( // request specific footprint decrease - nsIMdbEnv* ev, // context - mdb_size inDesiredBytesFreed, // approximate number of bytes wanted - mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed - - NS_IMETHOD PanicMemoryPurge( // desperately free all possible memory - nsIMdbEnv* ev, // context - mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed - // } ----- end memory policy methods ----- - - // { ----- begin filepath methods ----- - NS_IMETHOD GetPortFilePath( - nsIMdbEnv* ev, // context - mdbYarn* outFilePath, // name of file holding port content - mdbYarn* outFormatVersion) = 0; // file format description - - NS_IMETHOD GetPortFile( - nsIMdbEnv* ev, // context - nsIMdbFile** acqFile) = 0; // acquire file used by port or store - // } ----- end filepath methods ----- - - // { ----- begin export methods ----- - NS_IMETHOD BestExportFormat( // determine preferred export format - nsIMdbEnv* ev, // context - mdbYarn* outFormatVersion) = 0; // file format description - - // some tentative suggested import/export formats - // "ns:msg:db:port:format:ldif:ns4.0:passthrough" // necessary - // "ns:msg:db:port:format:ldif:ns4.5:utf8" // necessary - // "ns:msg:db:port:format:ldif:ns4.5:tabbed" - // "ns:msg:db:port:format:ldif:ns4.5:binary" // necessary - // "ns:msg:db:port:format:html:ns3.0:addressbook" // necessary - // "ns:msg:db:port:format:html:display:verbose" - // "ns:msg:db:port:format:html:display:concise" - // "ns:msg:db:port:format:mork:zany:verbose" // necessary - // "ns:msg:db:port:format:mork:zany:atomized" // necessary - // "ns:msg:db:port:format:rdf:xml" - // "ns:msg:db:port:format:xml:mork" - // "ns:msg:db:port:format:xml:display:verbose" - // "ns:msg:db:port:format:xml:display:concise" - // "ns:msg:db:port:format:xml:print:verbose" // recommended - // "ns:msg:db:port:format:xml:print:concise" - - NS_IMETHOD - CanExportToFormat( // can export content in given specific format? - nsIMdbEnv* ev, // context - const char* inFormatVersion, // file format description - mdb_bool* outCanExport) = 0; // whether ExportSource() might succeed - - NS_IMETHOD ExportToFormat( // export content in given specific format - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to receive exported content - nsIMdbFile* ioFile, // destination abstract file interface - const char* inFormatVersion, // file format description - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental export - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the export will be finished. - - // } ----- end export methods ----- - - // { ----- begin token methods ----- - NS_IMETHOD TokenToString( // return a string name for an integer token - nsIMdbEnv* ev, // context - mdb_token inToken, // token for inTokenName inside this port - mdbYarn* outTokenName) = 0; // the type of table to access - - NS_IMETHOD StringToToken( // return an integer token for scope name - nsIMdbEnv* ev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken) = 0; // token for inTokenName inside this port - - // String token zero is never used and never supported. If the port - // is a mutable store, then StringToToken() to create a new - // association of inTokenName with a new integer token if possible. - // But a readonly port will return zero for an unknown scope name. - - NS_IMETHOD QueryToken( // like StringToToken(), but without adding - nsIMdbEnv* ev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken) = 0; // token for inTokenName inside this port - - // QueryToken() will return a string token if one already exists, - // but unlike StringToToken(), will not assign a new token if not - // already in use. - - // } ----- end token methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD HasRow( // contains a row with the specified oid? - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_bool* outHasRow) = 0; // whether GetRow() might succeed - - NS_IMETHOD GetRowRefCount( // get number of tables that contain a row - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_count* outRefCount) = 0; // number of tables containing inRowKey - - NS_IMETHOD GetRow( // access one row with specific oid - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - nsIMdbRow** acqRow) = 0; // acquire specific row (or null) - - // NS_IMETHOD - // GetPortRowCursor( // get cursor for all rows in specific scope - // nsIMdbEnv* ev, // context - // mdb_scope inRowScope, // row scope for row ids - // nsIMdbPortRowCursor** acqCursor) = 0; // all such rows in the port - - NS_IMETHOD FindRow(nsIMdbEnv* ev, // search for row with matching cell - mdb_scope inRowScope, // row scope for row ids - mdb_column inColumn, // the column to search (and maintain an index) - const mdbYarn* inTargetCellValue, // cell value for which to search - mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match) - nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match) - // can be null if you only want the oid - // FindRow() searches for one row that has a cell in column inColumn with - // a contained value with the same form (i.e. charset) and is byte-wise - // identical to the blob described by yarn inTargetCellValue. Both content - // and form of the yarn must be an exact match to find a matching row. - // - // (In other words, both a yarn's blob bytes and form are significant. The - // form is not expected to vary in columns used for identity anyway. This - // is intended to make the cost of FindRow() cheaper for MDB implementors, - // since any cell value atomization performed internally must necessarily - // make yarn form significant in order to avoid data loss in atomization.) - // - // FindRow() can lazily create an index on attribute inColumn for all rows - // with that attribute in row space scope inRowScope, so that subsequent - // calls to FindRow() will perform faster. Such an index might or might - // not be persistent (but this seems desirable if it is cheap to do so). - // Note that lazy index creation in readonly DBs is not very feasible. - // - // This FindRow() interface assumes that attribute inColumn is effectively - // an alternative means of unique identification for a row in a rowspace, - // so correct behavior is only guaranteed when no duplicates for this col - // appear in the given set of rows. (If more than one row has the same cell - // value in this column, no more than one will be found; and cutting one of - // two duplicate rows can cause the index to assume no other such row lives - // in the row space, so future calls return nil for negative search results - // even though some duplicate row might still live within the rowspace.) - // - // In other words, the FindRow() implementation is allowed to assume simple - // hash tables mapping unqiue column keys to associated row values will be - // sufficient, where any duplication is not recorded because only one copy - // of a given key need be remembered. Implementors are not required to sort - // all rows by the specified column. - // } ----- end row methods ----- - - // { ----- begin table methods ----- - NS_IMETHOD HasTable( // supports a table with the specified oid? - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical table oid - mdb_bool* outHasTable) = 0; // whether GetTable() might succeed - - NS_IMETHOD GetTable( // access one table with specific oid - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical table oid - nsIMdbTable** acqTable) = 0; // acquire specific table (or null) - - NS_IMETHOD HasTableKind( // supports a table of the specified type? - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // rid scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outSupportsTable) = 0; // whether GetTableKind() might succeed - - // row scopes to be supported include the following suggestions: - // "ns:msg:db:row:scope:address:cards:all" - // "ns:msg:db:row:scope:mail:messages:all" - // "ns:msg:db:row:scope:news:articles:all" - - // table kinds to be supported include the following suggestions: - // "ns:msg:db:table:kind:address:cards:main" - // "ns:msg:db:table:kind:address:lists:all" - // "ns:msg:db:table:kind:address:list" - // "ns:msg:db:table:kind:news:threads:all" - // "ns:msg:db:table:kind:news:thread" - // "ns:msg:db:table:kind:mail:threads:all" - // "ns:msg:db:table:kind:mail:thread" - - NS_IMETHOD GetTableKind( // access one (random) table of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outMustBeUnique, // whether port can hold only one of these - nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows - - NS_IMETHOD - GetPortTableCursor( // get cursor for all tables of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - nsIMdbPortTableCursor** acqCursor) = 0; // all such tables in the port - // } ----- end table methods ----- - - - // { ----- begin commit methods ----- - - NS_IMETHOD ShouldCompress( // store wastes at least inPercentWaste? - nsIMdbEnv* ev, // context - mdb_percent inPercentWaste, // 0..100 percent file size waste threshold - mdb_percent* outActualWaste, // 0..100 percent of file actually wasted - mdb_bool* outShould) = 0; // true when about inPercentWaste% is wasted - // ShouldCompress() returns true if the store can determine that the file - // will shrink by an estimated percentage of inPercentWaste% (or more) if - // CompressCommit() is called, because that percentage of the file seems - // to be recoverable free space. The granularity is only in terms of - // percentage points, and any value over 100 is considered equal to 100. - // - // If a store only has an approximate idea how much space might be saved - // during a compress, then a best guess should be made. For example, the - // Mork implementation might keep track of how much file space began with - // text content before the first updating transaction, and then consider - // all content following the start of the first transaction as potentially - // wasted space if it is all updates and not just new content. (This is - // a safe assumption in the sense that behavior will stabilize on a low - // estimate of wastage after a commit removes all transaction updates.) - // - // Some db formats might attempt to keep a very accurate reckoning of free - // space size, so a very accurate determination can be made. But other db - // formats might have difficulty determining size of free space, and might - // require some lengthy calculation to answer. This is the reason for - // passing in the percentage threshold of interest, so that such lengthy - // computations can terminate early as soon as at least inPercentWaste is - // found, so that the entire file need not be groveled when unnecessary. - // However, we hope implementations will always favor fast but imprecise - // heuristic answers instead of extremely slow but very precise answers. - // - // If the outActualWaste parameter is non-nil, it will be used to return - // the actual estimated space wasted as a percentage of file size. (This - // parameter is provided so callers need not call repeatedly with altered - // inPercentWaste values to isolate the actual wastage figure.) Note the - // actual wastage figure returned can exactly equal inPercentWaste even - // when this grossly underestimates the real figure involved, if the db - // finds it very expensive to determine the extent of wastage after it is - // known to at least exceed inPercentWaste. Note we expect that whenever - // outShould returns true, that outActualWaste returns >= inPercentWaste. - // - // The effect of different inPercentWaste values is not very uniform over - // the permitted range. For example, 50 represents 50% wastage, or a file - // that is about double what it should be ideally. But 99 represents 99% - // wastage, or a file that is about ninety-nine times as big as it should - // be ideally. In the smaller direction, 25 represents 25% wastage, or - // a file that is only 33% larger than it should be ideally. - // - // Callers can determine what policy they want to use for considering when - // a file holds too much wasted space, and express this as a percentage - // of total file size to pass as in the inPercentWaste parameter. A zero - // likely returns always trivially true, and 100 always trivially false. - // The great majority of callers are expected to use values from 25 to 75, - // since most plausible thresholds for compressing might fall between the - // extremes of 133% of ideal size and 400% of ideal size. (Presumably the - // larger a file gets, the more important the percentage waste involved, so - // a sliding scale for compress thresholds might use smaller numbers for - // much bigger file sizes.) - - // } ----- end commit methods ----- - -// } ===== end nsIMdbPort methods ===== -}; - -/*| nsIMdbStore: a mutable interface to a specific database file. -**| -**|| tables: one can force a new table to exist in a store with NewTable() -**| and nonzero values for both row scope and table kind. (If one wishes only -**| one table of a certain kind, then one might look for it first using the -**| GetTableKind() method). One can pass inMustBeUnique to force future -**| users of this store to be unable to create other tables with the same pair -**| of scope and kind attributes. When inMustBeUnique is true, and the table -**| with the given scope and kind pair already exists, then the existing one -**| is returned instead of making a new table. Similarly, if one passes false -**| for inMustBeUnique, but the table kind has already been marked unique by a -**| previous user of the store, then the existing unique table is returned. -**| -**|| import: all or some of another port's content can be imported by calling -**| AddPortContent() with a row scope identifying the extent of content to -**| be imported. A zero row scope will import everything. A nonzero row -**| scope will only import tables with a matching row scope. Note that one -**| must somehow find a way to negotiate possible conflicts between existing -**| row content and imported row content, and this involves a specific kind of -**| definition for row identity involving either row IDs or unique attributes, -**| or some combination of these two. At the moment I am just going to wave -**| my hands, and say the default behavior is to assign all new row identities -**| to all imported content, which will result in no merging of content; this -**| must change later because it is unacceptable in some contexts. -**| -**|| commits: to manage modifications in a mutable store, very few methods are -**| really needed to indicate global policy choices that are independent of -**| the actual modifications that happen in objects at the level of tables, -**| rows, and cells, etc. The most important policy to specify is which sets -**| of changes are considered associated in a manner such that they should be -**| applied together atomically to a given store. We call each such group of -**| changes a transaction. We handle three different grades of transaction, -**| but they differ only in semantic significance to the application, and are -**| not intended to nest. (If small transactions were nested inside large -**| transactions, that would imply that a single large transaction must be -**| atomic over all the contained small transactions; but actually we intend -**| smalls transaction never be undone once commited due to, say, aborting a -**| transaction of greater significance.) The small, large, and session level -**| commits have equal granularity, and differ only in risk of loss from the -**| perspective of an application. Small commits characterize changes that -**| can be lost with relatively small risk, so small transactions can delay -**| until later if they are expensive or impractical to commit. Large commits -**| involve changes that would probably inconvenience users if lost, so the -**| need to pay costs of writing is rather greater than with small commits. -**| Session commits are last ditch attempts to save outstanding changes before -**| stopping the use of a particular database, so there will be no later point -**| in time to save changes that have been delayed due to possible high cost. -**| If large commits are never delayed, then a session commit has about the -**| same performance effect as another large commit; but if small and large -**| commits are always delayed, then a session commit is likely to be rather -**| expensive as a runtime cost compared to any earlier database usage. -**| -**|| aborts: the only way to abort changes to a store is by closing the store. -**| So there is no specific method for causing any abort. Stores must discard -**| all changes made that are uncommited when a store is closed. This design -**| choice makes the implementations of tables, rows, and cells much less -**| complex because they need not maintain a record of undobable changes. When -**| a store is closed, presumably this precipitates the closure of all tables, -**| rows, and cells in the store as well. So an application can revert the -**| state of a store in the user interface by quietly closing and reopening a -**| store, because this will discard uncommited changes and show old content. -**| This implies an app that closes a store will need to send a "scramble" -**| event notification to any views that depend on old discarded content. -|*/ - -#define NS_IMDBSTORE_IID_STR "726618d3-f15b-49b9-9f4a-efcc9db53d0d" - -#define NS_IMDBSTORE_IID \ -{0x726618d3, 0xf15b, 0x49b9, \ -{0x9f, 0x4a, 0xef, 0xcc, 0x9d, 0xb5, 0x3d, 0x0d}} - -class nsIMdbStore : public nsIMdbPort { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBSTORE_IID) - -// { ===== begin nsIMdbStore methods ===== - - // { ----- begin table methods ----- - NS_IMETHOD NewTable( // make one new table of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows - - NS_IMETHOD NewTableWithOid( // make one new table of specific type - nsIMdbEnv* ev, // context - const mdbOid* inOid, // caller assigned oid - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows - // } ----- end table methods ----- - - // { ----- begin row scope methods ----- - NS_IMETHOD RowScopeHasAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified - - NS_IMETHOD SetCallerAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified - - NS_IMETHOD SetStoreAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified - // } ----- end row scope methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD NewRowWithOid(nsIMdbEnv* ev, // new row w/ caller assigned oid - const mdbOid* inOid, // caller assigned oid - nsIMdbRow** acqRow) = 0; // create new row - - NS_IMETHOD NewRow(nsIMdbEnv* ev, // new row with db assigned oid - mdb_scope inRowScope, // row scope for row ids - nsIMdbRow** acqRow) = 0; // create new row - // Note this row must be added to some table or cell child before the - // store is closed in order to make this row persist across sesssions. - - // } ----- end row methods ----- - - // { ----- begin inport/export methods ----- - NS_IMETHOD ImportContent( // import content from port - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // scope for rows (or zero for all?) - nsIMdbPort* ioPort, // the port with content to add to store - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the import will be finished. - - NS_IMETHOD ImportFile( // import content from port - nsIMdbEnv* ev, // context - nsIMdbFile* ioFile, // the file with content to add to store - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the import will be finished. - // } ----- end inport/export methods ----- - - // { ----- begin hinting methods ----- - NS_IMETHOD - ShareAtomColumnsHint( // advise re shared column content atomizing - nsIMdbEnv* ev, // context - mdb_scope inScopeHint, // zero, or suggested shared namespace - const mdbColumnSet* inColumnSet) = 0; // cols desired tokenized together - - NS_IMETHOD - AvoidAtomColumnsHint( // advise column with poor atomizing prospects - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet) = 0; // cols with poor atomizing prospects - // } ----- end hinting methods ----- - - // { ----- begin commit methods ----- - NS_IMETHOD SmallCommit( // save minor changes if convenient and uncostly - nsIMdbEnv* ev) = 0; // context - - NS_IMETHOD LargeCommit( // save important changes if at all possible - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - NS_IMETHOD SessionCommit( // save all changes if large commits delayed - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - NS_IMETHOD - CompressCommit( // commit and make db physically smaller if possible - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - // } ----- end commit methods ----- - -// } ===== end nsIMdbStore methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbStore, NS_IMDBSTORE_IID) - -/*| nsIMdbCursor: base cursor class for iterating row cells and table rows -**| -**|| count: the number of elements in the collection (table or row) -**| -**|| seed: the change count in the underlying collection, which is synced -**| with the collection when the iteration position is set, and henceforth -**| acts to show whether the iter has lost collection synchronization, in -**| case it matters to clients whether any change happens during iteration. -**| -**|| pos: the position of the current element in the collection. Negative -**| means a position logically before the first element. A positive value -**| equal to count (or larger) implies a position after the last element. -**| To iterate over all elements, set the position to negative, so subsequent -**| calls to any 'next' method will access the first collection element. -**| -**|| doFailOnSeedOutOfSync: whether a cursor should return an error if the -**| cursor's snapshot of a table's seed becomes stale with respect the table's -**| current seed value (which implies the iteration is less than total) in -**| between to cursor calls that actually access collection content. By -**| default, a cursor should assume this attribute is false until specified, -**| so that iterations quietly try to re-sync when they lose coherence. -|*/ - -#define NS_IMDBCURSOR_IID_STR "a0c37337-6ebc-474c-90db-e65ea0b850aa" - -#define NS_IMDBCURSOR_IID \ -{0xa0c37337, 0x6ebc, 0x474c, \ -{0x90, 0xdb, 0xe6, 0x5e, 0xa0, 0xb8, 0x50, 0xaa}} - -class nsIMdbCursor : public nsISupports { // collection iterator -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBCURSOR_IID) -// { ===== begin nsIMdbCursor methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetCount(nsIMdbEnv* ev, mdb_count* outCount) = 0; // readonly - NS_IMETHOD GetSeed(nsIMdbEnv* ev, mdb_seed* outSeed) = 0; // readonly - - NS_IMETHOD SetPos(nsIMdbEnv* ev, mdb_pos inPos) = 0; // mutable - NS_IMETHOD GetPos(nsIMdbEnv* ev, mdb_pos* outPos) = 0; - - NS_IMETHOD SetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool inFail) = 0; - NS_IMETHOD GetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool* outFail) = 0; - // } ----- end attribute methods ----- - -// } ===== end nsIMdbCursor methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbCursor, NS_IMDBCURSOR_IID) - -#define NS_IMDBPORTTABLECURSOR_IID_STR = "f181a41e-933d-49b3-af93-20d3634b8b78" - -#define NS_IMDBPORTTABLECURSOR_IID \ -{0xf181a41e, 0x933d, 0x49b3, \ -{0xaf, 0x93, 0x20, 0xd3, 0x63, 0x4b, 0x8b, 0x78}} - -/*| nsIMdbPortTableCursor: cursor class for iterating port tables -**| -**|| port: the cursor is associated with a specific port, which can be -**| set to a different port (which resets the position to -1 so the -**| next table acquired is the first in the port. -**| -|*/ -class nsIMdbPortTableCursor : public nsISupports { // table collection iterator -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBPORTTABLECURSOR_IID) -// { ===== begin nsIMdbPortTableCursor methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD SetPort(nsIMdbEnv* ev, nsIMdbPort* ioPort) = 0; // sets pos to -1 - NS_IMETHOD GetPort(nsIMdbEnv* ev, nsIMdbPort** acqPort) = 0; - - NS_IMETHOD SetRowScope(nsIMdbEnv* ev, // sets pos to -1 - mdb_scope inRowScope) = 0; - NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0; - // setting row scope to zero iterates over all row scopes in port - - NS_IMETHOD SetTableKind(nsIMdbEnv* ev, // sets pos to -1 - mdb_kind inTableKind) = 0; - NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0; - // setting table kind to zero iterates over all table kinds in row scope - // } ----- end attribute methods ----- - - // { ----- begin table iteration methods ----- - NS_IMETHOD NextTable( // get table at next position in the db - nsIMdbEnv* ev, // context - nsIMdbTable** acqTable) = 0; // the next table in the iteration - // } ----- end table iteration methods ----- - -// } ===== end nsIMdbPortTableCursor methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbPortTableCursor, - NS_IMDBPORTTABLECURSOR_IID) - -/*| nsIMdbCollection: an object that collects a set of other objects as members. -**| The main purpose of this base class is to unify the perceived semantics -**| of tables and rows where their collection behavior is similar. This helps -**| isolate the mechanics of collection behavior from the other semantics that -**| are more characteristic of rows and tables. -**| -**|| count: the number of objects in a collection is the member count. (Some -**| collection interfaces call this attribute the 'size', but that can be a -**| little ambiguous, and counting actual members is harder to confuse.) -**| -**|| seed: the seed of a collection is a counter for changes in membership in -**| a specific collection. This seed should change when members are added to -**| or removed from a collection, but not when a member changes internal state. -**| The seed should also change whenever the internal collection of members has -**| a complex state change that reorders member positions (say by sorting) that -**| would affect the nature of an iteration over that collection of members. -**| The purpose of a seed is to inform any outstanding collection cursors that -**| they might be stale, without incurring the cost of broadcasting an event -**| notification to such cursors, which would need more data structure support. -**| Presumably a cursor in a particular mdb code suite has much more direct -**| access to a collection seed member slot that this abstract COM interface, -**| so this information is intended more for clients outside mdb that want to -**| make inferences similar to those made by the collection cursors. The seed -**| value as an integer magnitude is not very important, and callers should not -**| assume meaningful information can be derived from an integer value beyond -**| whether it is equal or different from a previous inspection. A seed uses -**| integers of many bits in order to make the odds of wrapping and becoming -**| equal to an earlier seed value have probability that is vanishingly small. -**| -**|| port: every collection is associated with a specific database instance. -**| -**|| cursor: a subclass of nsIMdbCursor suitable for this specific collection -**| subclass. The ability to GetCursor() from the base nsIMdbCollection class -**| is not really as useful as getting a more specifically typed cursor more -**| directly from the base class without any casting involved. So including -**| this method here is more for conceptual illustration. -**| -**|| oid: every collection has an identity that persists from session to -**| session. Implementations are probably able to distinguish row IDs from -**| table IDs, but we don't specify anything official in this regard. A -**| collection has the same identity for the lifetime of the collection, -**| unless identity is swapped with another collection by means of a call to -**| BecomeContent(), which is considered a way to swap a new representation -**| for an old well-known object. (Even so, only content appears to change, -**| while the identity seems to stay the same.) -**| -**|| become: developers can effectively cause two objects to swap identities, -**| in order to effect a complete swap between what persistent content is -**| represented by two oids. The caller should consider this a content swap, -**| and not identity wap, because identities will seem to stay the same while -**| only content changes. However, implementations will likely do this -**| internally by swapping identities. Callers must swap content only -**| between objects of similar type, such as a row with another row, and a -**| table with another table, because implementations need not support -**| cross-object swapping because it might break object name spaces. -**| -**|| dropping: when a caller expects a row or table will no longer be used, the -**| caller can tell the collection to 'drop activity', which means the runtime -**| object can have its internal representation purged to save memory or any -**| other resource that is being consumed by the collection's representation. -**| This has no effect on the collection's persistent content or semantics, -**| and is only considered a runtime effect. After a collection drops -**| activity, the object should still be as usable as before (because it has -**| NOT been closed), but further usage can be expensive to re-instate because -**| it might involve reallocating space and/or re-reading disk space. But -**| since this future usage is not expected, the caller does not expect to -**| pay the extra expense. An implementation can choose to implement -**| 'dropping activity' in different ways, or even not at all if this -**| operation is not really feasible. Callers cannot ask objects whether they -**| are 'dropped' or not, so this should be transparent. (Note that -**| implementors might fear callers do not really know whether future -**| usage will occur, and therefore might delay the act of dropping until -**| the near future, until seeing whether the object is used again -**| immediately elsewhere. Such use soon after the drop request might cause -**| the drop to be cancelled.) -|*/ -class nsIMdbCollection : public nsISupports { // sequence of objects -public: - -// { ===== begin nsIMdbCollection methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetSeed(nsIMdbEnv* ev, - mdb_seed* outSeed) = 0; // member change count - NS_IMETHOD GetCount(nsIMdbEnv* ev, - mdb_count* outCount) = 0; // member count - - NS_IMETHOD GetPort(nsIMdbEnv* ev, - nsIMdbPort** acqPort) = 0; // collection container - // } ----- end attribute methods ----- - - // { ----- begin cursor methods ----- - NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos - nsIMdbEnv* ev, // context - mdb_pos inMemberPos, // zero-based ordinal pos of member in collection - nsIMdbCursor** acqCursor) = 0; // acquire new cursor instance - // } ----- end cursor methods ----- - - // { ----- begin ID methods ----- - NS_IMETHOD GetOid(nsIMdbEnv* ev, - mdbOid* outOid) = 0; // read object identity - NS_IMETHOD BecomeContent(nsIMdbEnv* ev, - const mdbOid* inOid) = 0; // exchange content - // } ----- end ID methods ----- - - // { ----- begin activity dropping methods ----- - NS_IMETHOD DropActivity( // tell collection usage no longer expected - nsIMdbEnv* ev) = 0; - // } ----- end activity dropping methods ----- - -// } ===== end nsIMdbCollection methods ===== -}; - -/*| nsIMdbTable: an ordered collection of rows -**| -**|| row scope: an integer token for an atomized string in this database -**| that names a space for row IDs. This attribute of a table is intended -**| as guidance metainformation that helps with searching a database for -**| tables that operate on collections of rows of the specific type. By -**| convention, a table with a specific row scope is expected to focus on -**| containing rows that belong to that scope, however exceptions are easily -**| allowed because all rows in a table are known by both row ID and scope. -**| (A table with zero row scope is never allowed because this would make it -**| ambiguous to use a zero row scope when iterating over tables in a port to -**| indicate that all row scopes should be seen by a cursor.) -**| -**|| table kind: an integer token for an atomized string in this database -**| that names a kind of table as a subset of the associated row scope. This -**| attribute is intended as guidance metainformation to clarify the role of -**| this table with respect to other tables in the same row scope, and this -**| also helps search for such tables in a database. By convention, a table -**| with a specific table kind has a consistent role for containing rows with -**| respect to other collections of such rows in the same row scope. Also by -**| convention, at least one table in a row scope has a table kind purporting -**| to contain ALL the rows that belong in that row scope, so that at least -**| one table exists that allows all rows in a scope to be interated over. -**| (A table with zero table kind is never allowed because this would make it -**| ambiguous to use a zero table kind when iterating over tables in a port to -**| indicate that all table kinds in a row scope should be seen by a cursor.) -**| -**|| port: every table is considered part of some port that contains the -**| table, so that closing the containing port will cause the table to be -**| indirectly closed as well. We make it easy to get the containing port for -**| a table, because the port supports important semantic interfaces that will -**| affect how content in table is presented; the most important port context -**| that affects a table is specified by the set of token to string mappings -**| that affect all tokens used throughout the database, and which drive the -**| meanings of row scope, table kind, cell columns, etc. -**| -**|| cursor: a cursor that iterates over the rows in this table, where rows -**| have zero-based index positions from zero to count-1. Making a cursor -**| with negative position will next iterate over the first row in the table. -**| -**|| position: given any position from zero to count-1, a table will return -**| the row ID and row scope for the row at that position. (One can use the -**| GetRowAllCells() method to read that row, or else use a row cursor to both -**| get the row at some position and read its content at the same time.) The -**| position depends on whether a table is sorted, and upon the actual sort. -**| Note that moving a row's position is only possible in unsorted tables. -**| -**|| row set: every table contains a collection of rows, where a member row is -**| referenced by the table using the row ID and row scope for the row. No -**| single table owns a given row instance, because rows are effectively ref- -**| counted and destroyed only when the last table removes a reference to that -**| particular row. (But a row can be emptied of all content no matter how -**| many refs exist, and this might be the next best thing to destruction.) -**| Once a row exists in a least one table (after NewRow() is called), then it -**| can be added to any other table by calling AddRow(), or removed from any -**| table by calling CutRow(), or queried as a member by calling HasRow(). A -**| row can only be added to a table once, and further additions do nothing and -**| complain not at all. Cutting a row from a table only does something when -**| the row was actually a member, and otherwise does nothing silently. -**| -**|| row ref count: one can query the number of tables (and/or cells) -**| containing a row as a member or a child. -**| -**|| row content: one can access or modify the cell content in a table's row -**| by moving content to or from an instance of nsIMdbRow. Note that nsIMdbRow -**| never represents the actual row inside a table, and this is the reason -**| why nsIMdbRow instances do not have row IDs or row scopes. So an instance -**| of nsIMdbRow always and only contains a snapshot of some or all content in -**| past, present, or future persistent row inside a table. This means that -**| reading and writing rows in tables has strictly copy semantics, and we -**| currently do not plan any exceptions for specific performance reasons. -**| -**|| sorting: note all rows are assumed sorted by row ID as a secondary -**| sort following the primary column sort, when table rows are sorted. -**| -**|| indexes: -|*/ - - -#define NS_IMDBTABLE_IID_STR = "fe11bc98-d02b-4128-9fac-87042fdf9639" - -#define NS_IMDBTABLE_IID \ -{0xfe11bc98, 0xd02b, 0x4128, \ -{0x9f, 0xac, 0x87, 0x04, 0x2f, 0xdf, 0x96, 0x39}} - -class nsIMdbTable : public nsIMdbCollection { // a collection of rows -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLE_IID) -// { ===== begin nsIMdbTable methods ===== - - // { ----- begin meta attribute methods ----- - NS_IMETHOD SetTablePriority(nsIMdbEnv* ev, mdb_priority inPrio) = 0; - NS_IMETHOD GetTablePriority(nsIMdbEnv* ev, mdb_priority* outPrio) = 0; - - NS_IMETHOD GetTableBeVerbose(nsIMdbEnv* ev, mdb_bool* outBeVerbose) = 0; - NS_IMETHOD SetTableBeVerbose(nsIMdbEnv* ev, mdb_bool inBeVerbose) = 0; - - NS_IMETHOD GetTableIsUnique(nsIMdbEnv* ev, mdb_bool* outIsUnique) = 0; - - NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0; - NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0; - - NS_IMETHOD GetMetaRow( - nsIMdbEnv* ev, // context - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - mdbOid* outOid, // output meta row oid, can be nil to suppress output - nsIMdbRow** acqRow) = 0; // acquire table's unique singleton meta row - // The purpose of a meta row is to support the persistent recording of - // meta info about a table as cells put into the distinguished meta row. - // Each table has exactly one meta row, which is not considered a member - // of the collection of rows inside the table. The only way to tell - // whether a row is a meta row is by the fact that it is returned by this - // GetMetaRow() method from some table. Otherwise nothing distinguishes - // a meta row from any other row. A meta row can be used anyplace that - // any other row can be used, and can even be put into other tables (or - // the same table) as a table member, if this is useful for some reason. - // The first attempt to access a table's meta row using GetMetaRow() will - // cause the meta row to be created if it did not already exist. When the - // meta row is created, it will have the row oid that was previously - // requested for this table's meta row; or if no oid was ever explicitly - // specified for this meta row, then a unique oid will be generated in - // the row scope named "m" (so obviously MDB clients should not - // manually allocate any row IDs from that special meta scope namespace). - // The meta row oid can be specified either when the table is created, or - // else the first time that GetMetaRow() is called, by passing a non-nil - // pointer to an oid for parameter inOptionalMetaRowOid. The meta row's - // actual oid is returned in outOid (if this is a non-nil pointer), and - // it will be different from inOptionalMetaRowOid when the meta row was - // already given a different oid earlier. - // } ----- end meta attribute methods ----- - - - // { ----- begin cursor methods ----- - NS_IMETHOD GetTableRowCursor( // make a cursor, starting iteration at inRowPos - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance - // } ----- end row position methods ----- - - // { ----- begin row position methods ----- - NS_IMETHOD PosToOid( // get row member for a table position - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - mdbOid* outOid) = 0; // row oid at the specified position - - NS_IMETHOD OidToPos( // test for the table position of a row member - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row to find in table - mdb_pos* outPos) = 0; // zero-based ordinal position of row in table - - NS_IMETHOD PosToRow( // test for the table position of a row member - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos - - NS_IMETHOD RowToPos( // test for the table position of a row member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_pos* outPos) = 0; // zero-based ordinal position of row in table - // } ----- end row position methods ----- - - // { ----- begin oid set methods ----- - NS_IMETHOD AddOid( // make sure the row with inOid is a table member - nsIMdbEnv* ev, // context - const mdbOid* inOid) = 0; // row to ensure membership in table - - NS_IMETHOD HasOid( // test for the table position of a row member - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row to find in table - mdb_bool* outHasOid) = 0; // whether inOid is a member row - - NS_IMETHOD CutOid( // make sure the row with inOid is not a member - nsIMdbEnv* ev, // context - const mdbOid* inOid) = 0; // row to remove from table - // } ----- end oid set methods ----- - - // { ----- begin row set methods ----- - NS_IMETHOD NewRow( // create a new row instance in table - nsIMdbEnv* ev, // context - mdbOid* ioOid, // please use minus one (unbound) rowId for db-assigned IDs - nsIMdbRow** acqRow) = 0; // create new row - - NS_IMETHOD AddRow( // make sure the row with inOid is a table member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow) = 0; // row to ensure membership in table - - NS_IMETHOD HasRow( // test for the table position of a row member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_bool* outHasRow) = 0; // whether row is a table member - - NS_IMETHOD CutRow( // make sure the row with inOid is not a member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow) = 0; // row to remove from table - - NS_IMETHOD CutAllRows( // remove all rows from the table - nsIMdbEnv* ev) = 0; // context - // } ----- end row set methods ----- - - // { ----- begin hinting methods ----- - NS_IMETHOD SearchColumnsHint( // advise re future expected search cols - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet) = 0; // columns likely to be searched - - NS_IMETHOD SortColumnsHint( // advise re future expected sort columns - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet) = 0; // columns for likely sort requests - - NS_IMETHOD StartBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* ev, // context - const void* inLabel) = 0; // intend unique address to match end call - // If batch starts nest by virtue of nesting calls in the stack, then - // the address of a local variable makes a good batch start label that - // can be used at batch end time, and such addresses remain unique. - - NS_IMETHOD EndBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* ev, // context - const void* inLabel) = 0; // label matching start label - // Suppose a table is maintaining one or many sort orders for a table, - // so that every row added to the table must be inserted in each sort, - // and every row cut must be removed from each sort. If a db client - // intends to make many such changes before needing any information - // about the order or positions of rows inside a table, then a client - // might tell the table to start batch changes in order to disable - // sorting of rows for the interim. Presumably a table will then do - // a full sort of all rows at need when the batch changes end, or when - // a surprise request occurs for row position during batch changes. - // } ----- end hinting methods ----- - - // { ----- begin searching methods ----- - NS_IMETHOD FindRowMatches( // search variable number of sorted cols - nsIMdbEnv* ev, // context - const mdbYarn* inPrefix, // content to find as prefix in row's column cell - nsIMdbTableRowCursor** acqCursor) = 0; // set of matching rows - - NS_IMETHOD GetSearchColumns( // query columns used by FindRowMatches() - nsIMdbEnv* ev, // context - mdb_count* outCount, // context - mdbColumnSet* outColSet) = 0; // caller supplied space to put columns - // GetSearchColumns() returns the columns actually searched when the - // FindRowMatches() method is called. No more than mColumnSet_Count - // slots of mColumnSet_Columns will be written, since mColumnSet_Count - // indicates how many slots are present in the column array. The - // actual number of search column used by the table is returned in - // the outCount parameter; if this number exceeds mColumnSet_Count, - // then a caller needs a bigger array to read the entire column set. - // The minimum of mColumnSet_Count and outCount is the number slots - // in mColumnSet_Columns that were actually written by this method. - // - // Callers are expected to change this set of columns by calls to - // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both. - // } ----- end searching methods ----- - - // { ----- begin sorting methods ----- - // sorting: note all rows are assumed sorted by row ID as a secondary - // sort following the primary column sort, when table rows are sorted. - - NS_IMETHOD - CanSortColumn( // query which column is currently used for sorting - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to query sorting potential - mdb_bool* outCanSort) = 0; // whether the column can be sorted - - NS_IMETHOD GetSorting( // view same table in particular sorting - nsIMdbEnv* ev, // context - mdb_column inColumn, // requested new column for sorting table - nsIMdbSorting** acqSorting) = 0; // acquire sorting for column - - NS_IMETHOD SetSearchSorting( // use this sorting in FindRowMatches() - nsIMdbEnv* ev, // context - mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn() - nsIMdbSorting* ioSorting) = 0; // requested sorting for some column - // SetSearchSorting() attempts to inform the table that ioSorting - // should be used during calls to FindRowMatches() for searching - // the column which is actually sorted by ioSorting. This method - // is most useful in conjunction with nsIMdbSorting::SetCompare(), - // because otherwise a caller would not be able to override the - // comparison ordering method used during searchs. Note that some - // database implementations might be unable to use an arbitrarily - // specified sort order, either due to schema or runtime interface - // constraints, in which case ioSorting might not actually be used. - // Presumably ioSorting is an instance that was returned from some - // earlier call to nsIMdbTable::GetSorting(). A caller can also - // use nsIMdbTable::SearchColumnsHint() to specify desired change - // in which columns are sorted and searched by FindRowMatches(). - // - // A caller can pass a nil pointer for ioSorting to request that - // column inColumn no longer be used at all by FindRowMatches(). - // But when ioSorting is non-nil, then inColumn should match the - // column actually sorted by ioSorting; when these do not agree, - // implementations are instructed to give precedence to the column - // specified by ioSorting (so this means callers might just pass - // zero for inColumn when ioSorting is also provided, since then - // inColumn is both redundant and ignored). - // } ----- end sorting methods ----- - - // { ----- begin moving methods ----- - // moving a row does nothing unless a table is currently unsorted - - NS_IMETHOD MoveOid( // change position of row in unsorted table - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row inRowId - mdb_pos* outActualPos) = 0; // actual new position of row in table - - NS_IMETHOD MoveRow( // change position of row in unsorted table - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row inRowId - mdb_pos* outActualPos) = 0; // actual new position of row in table - // } ----- end moving methods ----- - - // { ----- begin index methods ----- - NS_IMETHOD AddIndex( // create a sorting index for column if possible - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to sort by index - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental index building - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the index addition will be finished. - - NS_IMETHOD CutIndex( // stop supporting a specific column index - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column with index to be removed - nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental index destroy - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the index removal will be finished. - - NS_IMETHOD HasIndex( // query for current presence of a column index - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outHasIndex) = 0; // whether column has index for this column - - - NS_IMETHOD EnableIndexOnSort( // create an index for col on first sort - nsIMdbEnv* ev, // context - mdb_column inColumn) = 0; // the column to index if ever sorted - - NS_IMETHOD QueryIndexOnSort( // check whether index on sort is enabled - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outIndexOnSort) = 0; // whether column has index-on-sort enabled - - NS_IMETHOD DisableIndexOnSort( // prevent future index creation on sort - nsIMdbEnv* ev, // context - mdb_column inColumn) = 0; // the column to index if ever sorted - // } ----- end index methods ----- - -// } ===== end nsIMdbTable methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTable, NS_IMDBTABLE_IID) - -/*| nsIMdbSorting: a view of a table in some particular sort order. This -**| row order closely resembles a readonly array of rows with the same row -**| membership as the underlying table, but in a different order than the -**| table's explicit row order. But the sorting's row membership changes -**| whenever the table's membership changes (without any notification, so -**| keep this in mind when modifying the table). -**| -**|| table: every sorting is associated with a particular table. You -**| cannot change which table is used by a sorting (just ask some new -**| table for a suitable sorting instance instead). -**| -**|| compare: the ordering method used by a sorting, wrapped up in a -**| abstract plug-in interface. When this was never installed by an -**| explicit call to SetNewCompare(), a compare object is still returned, -**| and it might match the compare instance returned by the factory method -**| nsIMdbFactory::MakeCompare(), which represents a default sort order -**| (which we fervently hope is consistently ASCII byte ordering). -**| -**|| cursor: in case callers are more comfortable with a cursor style -**| of accessing row members, each sorting will happily return a cursor -**| instance with behavior very similar to a cursor returned from a call -**| to nsIMdbTable::GetTableRowCursor(), but with different row order. -**| A cursor should show exactly the same information as the pos methods. -**| -**|| pos: the PosToOid() and PosToRow() methods are just like the table -**| methods of the same name, except they show rows in the sort order of -**| the sorting, rather than that of the table. These methods are like -**| readonly array position accessor's, or like a C++ operator[]. -|*/ -class nsIMdbSorting : public nsIMdbObject { // sorting of some table -public: -// { ===== begin nsIMdbSorting methods ===== - - // { ----- begin attribute methods ----- - // sorting: note all rows are assumed sorted by row ID as a secondary - // sort following the primary column sort, when table rows are sorted. - - NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0; - NS_IMETHOD GetSortColumn( // query which col is currently sorted - nsIMdbEnv* ev, // context - mdb_column* outColumn) = 0; // col the table uses for sorting (or zero) - - NS_IMETHOD SetNewCompare(nsIMdbEnv* ev, - nsIMdbCompare* ioNewCompare) = 0; - // Setting the sorting's compare object will typically cause the rows - // to be resorted, presumably in a lazy fashion when the sorting is - // next required to be in a valid row ordering state, such as when a - // call to PosToOid() happens. ioNewCompare can be nil, in which case - // implementations should revert to the default sort order, which must - // be equivalent to whatever is used by nsIMdbFactory::MakeCompare(). - - NS_IMETHOD GetOldCompare(nsIMdbEnv* ev, - nsIMdbCompare** acqOldCompare) = 0; - // Get this sorting instance's compare object, which handles the - // ordering of rows in the sorting, by comparing yarns from the cells - // in the column being sorted. Since nsIMdbCompare has no interface - // to query the state of the compare object, it is not clear what you - // would do with this object when returned, except maybe compare it - // as a pointer address to some other instance, to check identities. - - // } ----- end attribute methods ----- - - // { ----- begin cursor methods ----- - NS_IMETHOD GetSortingRowCursor( // make a cursor, starting at inRowPos - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance - // A cursor interface turning same info as PosToOid() or PosToRow(). - // } ----- end row position methods ----- - - // { ----- begin row position methods ----- - NS_IMETHOD PosToOid( // get row member for a table position - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - mdbOid* outOid) = 0; // row oid at the specified position - - NS_IMETHOD PosToRow( // test for the table position of a row member - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos - // } ----- end row position methods ----- - -// } ===== end nsIMdbSorting methods ===== -}; - -/*| nsIMdbTableRowCursor: cursor class for iterating table rows -**| -**|| table: the cursor is associated with a specific table, which can be -**| set to a different table (which resets the position to -1 so the -**| next row acquired is the first in the table. -**| -**|| NextRowId: the rows in the table can be iterated by identity alone, -**| without actually reading the cells of any row with this method. -**| -**|| NextRowCells: read the next row in the table, but only read cells -**| from the table which are already present in the row (so no new cells -**| are added to the row, even if they are present in the table). All the -**| cells will have content specified, even it is the empty string. No -**| columns will be removed, even if missing from the row (because missing -**| and empty are semantically equivalent). -**| -**|| NextRowAllCells: read the next row in the table, and access all the -**| cells for this row in the table, adding any missing columns to the row -**| as needed until all cells are represented. All the -**| cells will have content specified, even it is the empty string. No -**| columns will be removed, even if missing from the row (because missing -**| and empty are semantically equivalent). -**| -|*/ - -#define NS_IMDBTABLEROWCURSOR_IID_STR = "4f325dad-0385-4b62-a992-c914ab93587e" - -#define NS_IMDBTABLEROWCURSOR_IID \ -{0x4f325dad, 0x0385, 0x4b62, \ -{0xa9, 0x92, 0xc9, 0x14, 0xab, 0x93, 0x58, 0x7e}} - - - -class nsIMdbTableRowCursor : public nsISupports { // table row iterator -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID) - -// { ===== begin nsIMdbTableRowCursor methods ===== - - // { ----- begin attribute methods ----- - // NS_IMETHOD SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable) = 0; // sets pos to -1 - // Method SetTable() cut and made obsolete in keeping with new sorting methods. - - NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0; - // } ----- end attribute methods ----- - - // { ----- begin duplicate row removal methods ----- - NS_IMETHOD CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups? - mdb_bool* outCanHaveDups) = 0; - - NS_IMETHOD MakeUniqueCursor( // clone cursor, removing duplicate rows - nsIMdbEnv* ev, // context - nsIMdbTableRowCursor** acqCursor) = 0; // acquire clone with no dups - // Note that MakeUniqueCursor() is never necessary for a cursor which was - // created by table method nsIMdbTable::GetTableRowCursor(), because a table - // never contains the same row as a member more than once. However, a cursor - // created by table method nsIMdbTable::FindRowMatches() might contain the - // same row more than once, because the same row can generate a hit by more - // than one column with a matching string prefix. Note this method can - // return the very same cursor instance with just an incremented refcount, - // when the original cursor could not contain any duplicate rows (calling - // CanHaveDupRowMembers() shows this case on a false return). Otherwise - // this method returns a different cursor instance. Callers should not use - // this MakeUniqueCursor() method lightly, because it tends to defeat the - // purpose of lazy programming techniques, since it can force creation of - // an explicit row collection in a new cursor's representation, in order to - // inspect the row membership and remove any duplicates; this can have big - // impact if a collection holds tens of thousands of rows or more, when - // the original cursor with dups simply referenced rows indirectly by row - // position ranges, without using an explicit row set representation. - // Callers are encouraged to use nsIMdbCursor::GetCount() to determine - // whether the row collection is very large (tens of thousands), and to - // delay calling MakeUniqueCursor() when possible, until a user interface - // element actually demands the creation of an explicit set representation. - // } ----- end duplicate row removal methods ----- - - // { ----- begin oid iteration methods ----- - NS_IMETHOD NextRowOid( // get row id of next row in the table - nsIMdbEnv* ev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos) = 0; // zero-based position of the row in table - // } ----- end oid iteration methods ----- - - // { ----- begin row iteration methods ----- - NS_IMETHOD NextRow( // get row cells from table for cells already in row - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // acquire next row in table - mdb_pos* outRowPos) = 0; // zero-based position of the row in table - - NS_IMETHOD PrevRowOid( // get row id of previous row in the table - nsIMdbEnv* ev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos) = 0; // zero-based position of the row in table - // } ----- end oid iteration methods ----- - - // { ----- begin row iteration methods ----- - NS_IMETHOD PrevRow( // get row cells from table for cells already in row - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // acquire previous row in table - mdb_pos* outRowPos) = 0; // zero-based position of the row in table - - // } ----- end row iteration methods ----- - - // { ----- begin copy iteration methods ----- - // NS_IMETHOD NextRowCopy( // put row cells into sink only when already in sink - // nsIMdbEnv* ev, // context - // nsIMdbRow* ioSinkRow, // sink for row cells read from next row - // mdbOid* outOid, // out row oid - // mdb_pos* outRowPos) = 0; // zero-based position of the row in table - // - // NS_IMETHOD NextRowCopyAll( // put all row cells into sink, adding to sink - // nsIMdbEnv* ev, // context - // nsIMdbRow* ioSinkRow, // sink for row cells read from next row - // mdbOid* outOid, // out row oid - // mdb_pos* outRowPos) = 0; // zero-based position of the row in table - // } ----- end copy iteration methods ----- - -// } ===== end nsIMdbTableRowCursor methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTableRowCursor, NS_IMDBTABLEROWCURSOR_IID) - -/*| nsIMdbRow: a collection of cells -**| -|*/ - -#define NS_IMDBROW_IID_STR "271e8d6e-183a-40e3-9f18-36913b4c7853" - - -#define NS_IMDBROW_IID \ -{0x271e8d6e, 0x183a, 0x40e3, \ -{0x9f, 0x18, 0x36, 0x91, 0x3b, 0x4c, 0x78, 0x53}} - - -class nsIMdbRow : public nsIMdbCollection { // cell tuple -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBROW_IID) -// { ===== begin nsIMdbRow methods ===== - - // { ----- begin cursor methods ----- - NS_IMETHOD GetRowCellCursor( // make a cursor starting iteration at inCellPos - nsIMdbEnv* ev, // context - mdb_pos inCellPos, // zero-based ordinal position of cell in row - nsIMdbRowCellCursor** acqCursor) = 0; // acquire new cursor instance - // } ----- end cursor methods ----- - - // { ----- begin column methods ----- - NS_IMETHOD AddColumn( // make sure a particular column is inside row - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to add - const mdbYarn* inYarn) = 0; // cell value to install - - NS_IMETHOD CutColumn( // make sure a column is absent from the row - nsIMdbEnv* ev, // context - mdb_column inColumn) = 0; // column to ensure absent from row - - NS_IMETHOD CutAllColumns( // remove all columns from the row - nsIMdbEnv* ev) = 0; // context - // } ----- end column methods ----- - - // { ----- begin cell methods ----- - NS_IMETHOD NewCell( // get cell for specified column, or add new one - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to add - nsIMdbCell** acqCell) = 0; // cell column and value - - NS_IMETHOD AddCell( // copy a cell from another row to this row - nsIMdbEnv* ev, // context - const nsIMdbCell* inCell) = 0; // cell column and value - - NS_IMETHOD GetCell( // find a cell in this row - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to find - nsIMdbCell** acqCell) = 0; // cell for specified column, or null - - NS_IMETHOD EmptyAllCells( // make all cells in row empty of content - nsIMdbEnv* ev) = 0; // context - // } ----- end cell methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD AddRow( // add all cells in another row to this one - nsIMdbEnv* ev, // context - nsIMdbRow* ioSourceRow) = 0; // row to union with - - NS_IMETHOD SetRow( // make exact duplicate of another row - nsIMdbEnv* ev, // context - nsIMdbRow* ioSourceRow) = 0; // row to duplicate - // } ----- end row methods ----- - - // { ----- begin blob methods ----- - NS_IMETHOD SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn() - mdb_column inColumn, // column to write - const mdbYarn* inYarn) = 0; // reads from yarn slots - // make this text object contain content from the yarn's buffer - - NS_IMETHOD GetCellYarn(nsIMdbEnv* ev, - mdb_column inColumn, // column to read - mdbYarn* outYarn) = 0; // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - - NS_IMETHOD AliasCellYarn(nsIMdbEnv* ev, - mdb_column inColumn, // column to alias - mdbYarn* outYarn) = 0; // writes ALL yarn slots - - NS_IMETHOD NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn() - mdb_column* ioColumn, // next column to read - mdbYarn* outYarn) = 0; // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - // - // The ioColumn argument is an inout parameter which initially contains the - // last column accessed and returns the next column corresponding to the - // content read into the yarn. Callers should start with a zero column - // value to say 'no previous column', which causes the first column to be - // read. Then the value returned in ioColumn is perfect for the next call - // to NextCellYarn(), since it will then be the previous column accessed. - // Callers need only examine the column token returned to see which cell - // in the row is being read into the yarn. When no more columns remain, - // and the iteration has ended, ioColumn will return a zero token again. - // So iterating over cells starts and ends with a zero column token. - - NS_IMETHOD SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell() - nsIMdbEnv* ev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - mdbYarn* outYarn) = 0; // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - // Callers can pass nil for outYarn to indicate no interest in content, so - // only the outColumn value is returned. NOTE to subclasses: you must be - // able to ignore outYarn when the pointer is nil; please do not crash. - - // } ----- end blob methods ----- - -// } ===== end nsIMdbRow methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRow, NS_IMDBROW_IID) - -/*| nsIMdbRowCellCursor: cursor class for iterating row cells -**| -**|| row: the cursor is associated with a specific row, which can be -**| set to a different row (which resets the position to -1 so the -**| next cell acquired is the first in the row. -**| -**|| NextCell: get the next cell in the row and return its position and -**| a new instance of a nsIMdbCell to represent this next cell. -|*/ - -#define NS_IMDBROWCELLCURSOR_IID_STR "b33371a7-5d63-4d10-85a8-e44dffe75c28" - - -#define NS_IMDBROWCELLCURSOR_IID \ -{0x271e8d6e, 0x5d63, 0x4d10 , \ -{0x85, 0xa8, 0xe4, 0x4d, 0xff, 0xe7, 0x5c, 0x28}} - - -class nsIMdbRowCellCursor : public nsISupports{ // cell collection iterator -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBROWCELLCURSOR_IID) -// { ===== begin nsIMdbRowCellCursor methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD SetRow(nsIMdbEnv* ev, nsIMdbRow* ioRow) = 0; // sets pos to -1 - NS_IMETHOD GetRow(nsIMdbEnv* ev, nsIMdbRow** acqRow) = 0; - // } ----- end attribute methods ----- - - // { ----- begin cell creation methods ----- - NS_IMETHOD MakeCell( // get cell at current pos in the row - nsIMdbEnv* ev, // context - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos, // position of cell in row sequence - nsIMdbCell** acqCell) = 0; // the cell at inPos - // } ----- end cell creation methods ----- - - // { ----- begin cell seeking methods ----- - NS_IMETHOD SeekCell( // same as SetRow() followed by MakeCell() - nsIMdbEnv* ev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - nsIMdbCell** acqCell) = 0; // the cell at inPos - // } ----- end cell seeking methods ----- - - // { ----- begin cell iteration methods ----- - NS_IMETHOD NextCell( // get next cell in the row - nsIMdbEnv* ev, // context - nsIMdbCell** acqCell, // changes to the next cell in the iteration - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos) = 0; // position of cell in row sequence - - NS_IMETHOD PickNextCell( // get next cell in row within filter set - nsIMdbEnv* ev, // context - nsIMdbCell* ioCell, // changes to the next cell in the iteration - const mdbColumnSet* inFilterSet, // col set of actual caller interest - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos) = 0; // position of cell in row sequence - - // Note that inFilterSet should not have too many (many more than 10?) - // cols, since this might imply a potential excessive consumption of time - // over many cursor calls when looking for column and filter intersection. - // } ----- end cell iteration methods ----- - -// } ===== end nsIMdbRowCellCursor methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRowCellCursor, NS_IMDBROWCELLCURSOR_IID) - -/*| nsIMdbBlob: a base class for objects composed mainly of byte sequence state. -**| (This provides a base class for nsIMdbCell, so that cells themselves can -**| be used to set state in another cell, without extracting a buffer.) -|*/ -class nsIMdbBlob : public nsISupports { // a string with associated charset -public: - -// { ===== begin nsIMdbBlob methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD SetBlob(nsIMdbEnv* ev, - nsIMdbBlob* ioBlob) = 0; // reads inBlob slots - // when inBlob is in the same suite, this might be fastest cell-to-cell - - NS_IMETHOD ClearBlob( // make empty (so content has zero length) - nsIMdbEnv* ev) = 0; - // clearing a yarn is like SetYarn() with empty yarn instance content - - NS_IMETHOD GetBlobFill(nsIMdbEnv* ev, - mdb_fill* outFill) = 0; // size of blob - // Same value that would be put into mYarn_Fill, if one called GetYarn() - // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0. - - NS_IMETHOD SetYarn(nsIMdbEnv* ev, - const mdbYarn* inYarn) = 0; // reads from yarn slots - // make this text object contain content from the yarn's buffer - - NS_IMETHOD GetYarn(nsIMdbEnv* ev, - mdbYarn* outYarn) = 0; // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - - NS_IMETHOD AliasYarn(nsIMdbEnv* ev, - mdbYarn* outYarn) = 0; // writes ALL yarn slots - // AliasYarn() reveals sensitive internal text buffer state to the caller - // by setting mYarn_Buf to point into the guts of this text implementation. - // - // The caller must take great care to avoid writing on this space, and to - // avoid calling any method that would cause the state of this text object - // to change (say by directly or indirectly setting the text to hold more - // content that might grow the size of the buffer and free the old buffer). - // In particular, callers should scrupulously avoid making calls into the - // mdb interface to write any content while using the buffer pointer found - // in the returned yarn instance. Best safe usage involves copying content - // into some other kind of external content representation beyond mdb. - // - // (The original design of this method a week earlier included the concept - // of very fast and efficient cooperative locking via a pointer to some lock - // member slot. But let's ignore that complexity in the current design.) - // - // AliasYarn() is specifically intended as the first step in transferring - // content from nsIMdbBlob to a nsString representation, without forcing extra - // allocations and/or memory copies. (A standard nsIMdbBlob_AsString() utility - // will use AliasYarn() as the first step in setting a nsString instance.) - // - // This is an alternative to the GetYarn() method, which has copy semantics - // only; AliasYarn() relaxes a robust safety principle only for performance - // reasons, to accomodate the need for callers to transform text content to - // some other canonical representation that would necessitate an additional - // copy and transformation when such is incompatible with the mdbYarn format. - // - // The implementation of AliasYarn() should have extremely little overhead - // besides the virtual dispatch to the method implementation, and the code - // necessary to populate all the mdbYarn member slots with internal buffer - // address and metainformation that describes the buffer content. Note that - // mYarn_Grow must always be set to nil to indicate no resizing is allowed. - - // } ----- end attribute methods ----- - -// } ===== end nsIMdbBlob methods ===== -}; - -/*| nsIMdbCell: the text in a single column of a row. The base nsIMdbBlob -**| class provides all the interface related to accessing cell text. -**| -**|| column: each cell in a row appears in a specific column, where this -**| column is identified by the an integer mdb_scope value (generated by -**| the StringToScopeToken() method in the containing nsIMdbPort instance). -**| Because a row cannot have more than one cell with the same column, -**| something must give if one calls SetColumn() with an existing column -**| in the same row. When this happens, the other cell is replaced with -**| this cell (and the old cell is closed if it has outstanding refs). -**| -**|| row: every cell instance is a part of some row, and every cell knows -**| which row is the parent row. (Note this should be represented by a -**| weak backpointer, so that outstanding cell references cannot keep a -**| row open that should be closed. Otherwise we'd have ref graph cycles.) -**| -**|| text: a cell can either be text, or it can have a child row or table, -**| but not both at once. If text is read from a cell with a child, the text -**| content should be empty (for AliasYarn()) or a description of the type -**| of child (perhaps "mdb:cell:child:row" or "mdb:cell:child:table"). -**| -**|| child: a cell might reference another row or a table, rather than text. -**| The interface for putting and getting children rows and tables was first -**| defined in the nsIMdbTable interface, but then this was moved to this cell -**| interface as more natural. -|*/ - - - -#define NS_IMDBCELL_IID \ -{0xa3b62f71, 0xa181, 0x4a91, \ -{0xb6, 0x6b, 0x27, 0x10, 0x9b, 0x88, 0x98, 0x35}} - -#define NS_IMDBCELL_IID_STR = "a3b62f71-a181-4a91-b66b-27109b889835" - -class nsIMdbCell : public nsIMdbBlob { // text attribute in row with column scope -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID) -// { ===== begin nsIMdbCell methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD SetColumn(nsIMdbEnv* ev, mdb_column inColumn) = 0; - NS_IMETHOD GetColumn(nsIMdbEnv* ev, mdb_column* outColumn) = 0; - - NS_IMETHOD GetCellInfo( // all cell metainfo except actual content - nsIMdbEnv* ev, - mdb_column* outColumn, // the column in the containing row - mdb_fill* outBlobFill, // the size of text content in bytes - mdbOid* outChildOid, // oid of possible row or table child - mdb_bool* outIsRowChild) = 0; // nonzero if child, and a row child - - // Checking all cell metainfo is a good way to avoid forcing a large cell - // in to memory when you don't actually want to use the content. - - NS_IMETHOD GetRow(nsIMdbEnv* ev, // parent row for this cell - nsIMdbRow** acqRow) = 0; - NS_IMETHOD GetPort(nsIMdbEnv* ev, // port containing cell - nsIMdbPort** acqPort) = 0; - // } ----- end attribute methods ----- - - // { ----- begin children methods ----- - NS_IMETHOD HasAnyChild( // does cell have a child instead of text? - nsIMdbEnv* ev, - mdbOid* outOid, // out id of row or table (or unbound if no child) - mdb_bool* outIsRow) = 0; // nonzero if child is a row (rather than a table) - - NS_IMETHOD GetAnyChild( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // child row (or null) - nsIMdbTable** acqTable) = 0; // child table (or null) - - - NS_IMETHOD SetChildRow( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow) = 0; // inRow must be bound inside this same db port - - NS_IMETHOD GetChildRow( // access row of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow) = 0; // acquire child row (or nil if no child) - - - NS_IMETHOD SetChildTable( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbTable* inTable) = 0; // table must be bound inside this same db port - - NS_IMETHOD GetChildTable( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbTable** acqTable) = 0; // acquire child table (or nil if no child) - // } ----- end children methods ----- - -// } ===== end nsIMdbCell methods ===== -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbCell, NS_IMDBTABLEROWCURSOR_IID) - -// } %%%%% end C++ abstract class interfaces %%%%% - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MDB_ */ - diff --git a/db/mork/build/Makefile.in b/db/mork/build/Makefile.in deleted file mode 100644 index 34e101ca550d..000000000000 --- a/db/mork/build/Makefile.in +++ /dev/null @@ -1,63 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -VPATH = @srcdir@ -srcdir = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = mork -LIBRARY_NAME = mork -EXPORT_LIBRARY = 1 -IS_COMPONENT = 1 -MODULE_NAME = nsMorkModule -LIBXUL_LIBRARY = 1 - - -CPPSRCS = nsMorkFactory.cpp - -EXPORTS = \ - nsMorkCID.h \ - nsIMdbFactoryFactory.h \ - $(NULL) - -SHARED_LIBRARY_LIBS = ../src/$(LIB_PREFIX)msgmork_s.$(LIB_SUFFIX) - -include $(topsrcdir)/config/rules.mk - diff --git a/db/mork/build/nsIMdbFactoryFactory.h b/db/mork/build/nsIMdbFactoryFactory.h deleted file mode 100644 index 39e1447fd8b3..000000000000 --- a/db/mork/build/nsIMdbFactoryFactory.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsIMdbFactoryFactory_h__ -#define nsIMdbFactoryFactory_h__ - -#include "nsISupports.h" -#include "nsIFactory.h" -#include "nsIComponentManager.h" - -class nsIMdbFactory; - -// 2794D0B7-E740-47a4-91C0-3E4FCB95B806 -#define NS_IMDBFACTORYFACTORY_IID \ -{ 0x2794d0b7, 0xe740, 0x47a4, { 0x91, 0xc0, 0x3e, 0x4f, 0xcb, 0x95, 0xb8, 0x6 } } - -// because Mork doesn't support XPCOM, we have to wrap the mdb factory interface -// with an interface that gives you an mdb factory. -class nsIMdbFactoryService : public nsISupports -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFACTORYFACTORY_IID) - NS_IMETHOD GetMdbFactory(nsIMdbFactory **aFactory) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFactoryService, NS_IMDBFACTORYFACTORY_IID) - -#endif diff --git a/db/mork/build/nsMorkFactory.cpp b/db/mork/build/nsMorkFactory.cpp deleted file mode 100644 index 9f636a9584e7..000000000000 --- a/db/mork/build/nsMorkFactory.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "mozilla/ModuleUtils.h" -#include "nsCOMPtr.h" -#include "nsMorkCID.h" -#include "nsIMdbFactoryFactory.h" -#include "mdb.h" - -class nsMorkFactoryService : public nsIMdbFactoryService -{ -public: - nsMorkFactoryService() {}; - // nsISupports methods - NS_DECL_ISUPPORTS - - NS_IMETHOD GetMdbFactory(nsIMdbFactory **aFactory); - -protected: - nsCOMPtr mMdbFactory; -}; - -NS_GENERIC_FACTORY_CONSTRUCTOR(nsMorkFactoryService) - -NS_DEFINE_NAMED_CID(NS_MORK_CID); - -const mozilla::Module::CIDEntry kMorkCIDs[] = { - { &kNS_MORK_CID, false, NULL, nsMorkFactoryServiceConstructor }, - { NULL } -}; - -const mozilla::Module::ContractIDEntry kMorkContracts[] = { - { NS_MORK_CONTRACTID, &kNS_MORK_CID }, - { NULL } -}; - -static const mozilla::Module kMorkModule = { - mozilla::Module::kVersion, - kMorkCIDs, - kMorkContracts -}; - -NSMODULE_DEFN(nsMorkModule) = &kMorkModule; - -NS_IMPL_ISUPPORTS1(nsMorkFactoryService, nsIMdbFactoryService) - -NS_IMETHODIMP nsMorkFactoryService::GetMdbFactory(nsIMdbFactory **aFactory) -{ - if (!mMdbFactory) - mMdbFactory = MakeMdbFactory(); - NS_IF_ADDREF(*aFactory = mMdbFactory); - return *aFactory ? NS_OK : NS_ERROR_OUT_OF_MEMORY; -} diff --git a/db/mork/src/Makefile.in b/db/mork/src/Makefile.in deleted file mode 100644 index 035a071de2a6..000000000000 --- a/db/mork/src/Makefile.in +++ /dev/null @@ -1,100 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = mork -LIBRARY_NAME = msgmork_s -FORCE_STATIC_LIB=1 -LIBXUL_LIBRARY = 1 - -CPPSRCS = \ - orkinHeap.cpp \ - morkArray.cpp \ - morkAtom.cpp \ - morkAtomMap.cpp \ - morkAtomSpace.cpp \ - morkBlob.cpp \ - morkBuilder.cpp \ - morkCell.cpp \ - morkCellObject.cpp \ - morkCh.cpp \ - morkConfig.cpp \ - morkCursor.cpp \ - morkDeque.cpp \ - morkEnv.cpp \ - morkFactory.cpp \ - morkFile.cpp \ - morkHandle.cpp \ - morkIntMap.cpp \ - morkMap.cpp \ - morkNode.cpp \ - morkNodeMap.cpp \ - morkObject.cpp \ - morkParser.cpp \ - morkPool.cpp \ - morkRow.cpp \ - morkRowCellCursor.cpp \ - morkRowMap.cpp \ - morkRowObject.cpp \ - morkRowSpace.cpp \ - morkSink.cpp \ - morkSpace.cpp \ - morkStore.cpp \ - morkStream.cpp \ - morkTable.cpp \ - morkPortTableCursor.cpp \ - morkTableRowCursor.cpp \ - morkThumb.cpp \ - morkWriter.cpp \ - morkYarn.cpp \ - morkBead.cpp \ - morkProbeMap.cpp \ - morkZone.cpp \ - $(NULL) - -ifeq ($(OS_ARCH),WINNT) -CPPSRCS += morkSearchRowCursor.cpp -endif - -include $(topsrcdir)/config/rules.mk - diff --git a/db/mork/src/mork.h b/db/mork/src/mork.h deleted file mode 100644 index 0a1f812b3c2e..000000000000 --- a/db/mork/src/mork.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORK_ -#define _MORK_ 1 - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#include "nscore.h" -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -// { %%%%% begin disable unused param warnings %%%%% -#define MORK_USED_1(x) (void)(&x) -#define MORK_USED_2(x,y) (void)(&x);(void)(&y); -#define MORK_USED_3(x,y,z) (void)(&x);(void)(&y);(void)(&z); -#define MORK_USED_4(w,x,y,z) (void)(&w);(void)(&x);(void)(&y);(void)(&z); - -// } %%%%% end disable unused param warnings %%%%% - -// { %%%%% begin macro for finding class member offset %%%%% - -/*| OffsetOf: the unsigned integer offset of a class or struct -**| field from the beginning of that class or struct. This is -**| the same as the similarly named public domain IronDoc macro, -**| and is also the same as another macro appearing in stdlib.h. -**| We want these offsets so we can correctly convert pointers -**| to member slots back into pointers to enclosing objects, and -**| have this exactly match what the compiler thinks is true. -**| -**|| Bascially we are asking the compiler to determine the offset at -**| compile time, and we use the definition of address artithmetic -**| to do this. By casting integer zero to a pointer of type obj*, -**| we can reference the address of a slot in such an object that -**| is hypothetically physically placed at address zero, but without -**| actually dereferencing a memory location. The absolute address -**| of slot is the same as offset of that slot, when the object is -**| placed at address zero. -|*/ -#define mork_OffsetOf(obj,slot) ((unsigned int)&((obj*) 0)->slot) - -// } %%%%% end macro for finding class member offset %%%%% - -// { %%%%% begin specific-size integer scalar typedefs %%%%% -typedef unsigned char mork_u1; // make sure this is one byte -typedef unsigned short mork_u2; // make sure this is two bytes -typedef short mork_i2; // make sure this is two bytes -typedef PRUint32 mork_u4; // make sure this is four bytes -typedef PRInt32 mork_i4; // make sure this is four bytes -typedef PRWord mork_ip; // make sure sizeof(mork_ip) == sizeof(void*) - -typedef mork_u1 mork_ch; // small byte-sized character (never wide) -typedef mork_u1 mork_flags; // one byte's worth of predicate bit flags - -typedef mork_u2 mork_base; // 2-byte magic class signature slot in object -typedef mork_u2 mork_derived; // 2-byte magic class signature slot in object -typedef mork_u2 mork_uses; // 2-byte strong uses count -typedef mork_u2 mork_refs; // 2-byte actual reference count - -typedef mork_u4 mork_token; // unsigned token for atomized string -typedef mork_token mork_scope; // token used to id scope for rows -typedef mork_token mork_kind; // token used to id kind for tables -typedef mork_token mork_cscode; // token used to id charset names -typedef mork_token mork_aid; // token used to id atomize cell values - -typedef mork_token mork_column; // token used to id columns for rows -typedef mork_column mork_delta; // mork_column plus mork_change - -typedef mork_token mork_color; // bead ID -#define morkColor_kNone ((mork_color) 0) - -typedef mork_u4 mork_magic; // unsigned magic signature - -typedef mork_u4 mork_seed; // unsigned collection change counter -typedef mork_u4 mork_count; // unsigned collection member count -typedef mork_count mork_num; // synonym for count -typedef mork_u4 mork_size; // unsigned physical media size -typedef mork_u4 mork_fill; // unsigned logical content size -typedef mork_u4 mork_more; // more available bytes for larger buffer - -typedef mdb_u4 mork_percent; // 0..100, with values >100 same as 100 - -typedef mork_i4 mork_pos; // negative means "before first" (at zero pos) -typedef mork_i4 mork_line; // negative means "before first line in file" - -typedef mork_u1 mork_usage; // 1-byte magic usage signature slot in object -typedef mork_u1 mork_access; // 1-byte magic access signature slot in object - -typedef mork_u1 mork_change; // add, cut, put, set, nil -typedef mork_u1 mork_priority; // 0..9, for a total of ten different values - -typedef mork_u1 mork_able; // on, off, asleep (clone IronDoc's fe_able) -typedef mork_u1 mork_load; // dirty or clean (clone IronDoc's fe_load) -// } %%%%% end specific-size integer scalar typedefs %%%%% - -// 'test' is a public domain Mithril for key equality tests in probe maps -typedef mork_i2 mork_test; /* neg=>kVoid, zero=>kHit, pos=>kMiss */ - -#define morkTest_kVoid ((mork_test) -1) /* -1: nil key slot, no key order */ -#define morkTest_kHit ((mork_test) 0) /* 0: keys are equal, a map hit */ -#define morkTest_kMiss ((mork_test) 1) /* 1: keys not equal, a map miss */ - -// { %%%%% begin constants for Mork scalar types %%%%% -#define morkPriority_kHi ((mork_priority) 0) /* best priority */ -#define morkPriority_kMin ((mork_priority) 0) /* best priority is smallest */ - -#define morkPriority_kLo ((mork_priority) 9) /* worst priority */ -#define morkPriority_kMax ((mork_priority) 9) /* worst priority is biggest */ - -#define morkPriority_kCount 10 /* number of distinct priority values */ - -#define morkAble_kEnabled ((mork_able) 0x55) /* same as IronDoc constant */ -#define morkAble_kDisabled ((mork_able) 0xAA) /* same as IronDoc constant */ -#define morkAble_kAsleep ((mork_able) 0x5A) /* same as IronDoc constant */ - -#define morkChange_kAdd 'a' /* add member */ -#define morkChange_kCut 'c' /* cut member */ -#define morkChange_kPut 'p' /* put member */ -#define morkChange_kSet 's' /* set all members */ -#define morkChange_kNil 0 /* no change in this member */ -#define morkChange_kDup 'd' /* duplicate changes have no effect */ -// kDup is intended to replace another change constant in an object as a -// conclusion about change feasibility while staging intended alterations. - -#define morkLoad_kDirty ((mork_load) 0xDD) /* same as IronDoc constant */ -#define morkLoad_kClean ((mork_load) 0x22) /* same as IronDoc constant */ - -#define morkAccess_kOpen 'o' -#define morkAccess_kClosing 'c' -#define morkAccess_kShut 's' -#define morkAccess_kDead 'd' -// } %%%%% end constants for Mork scalar types %%%%% - -// { %%%%% begin non-specific-size integer scalar typedefs %%%%% -typedef int mork_char; // nominal type for ints used to hold input byte -#define morkChar_IsWhite(c) \ - ((c) == 0xA || (c) == 0x9 || (c) == 0xD || (c) == ' ') -// } %%%%% end non-specific-size integer scalar typedefs %%%%% - -// { %%%%% begin mdb-driven scalar typedefs %%%%% -// easier to define bool exactly the same as mdb: -typedef mdb_bool mork_bool; // unsigned byte with zero=false, nonzero=true - -/* canonical boolean constants provided only for code clarity: */ -#define morkBool_kTrue ((mork_bool) 1) /* actually any nonzero means true */ -#define morkBool_kFalse ((mork_bool) 0) /* only zero means false */ - -// mdb clients can assign these, so we cannot pick maximum size: -typedef mdb_id mork_id; // unsigned object identity in a scope -typedef mork_id mork_rid; // unsigned row identity inside scope -typedef mork_id mork_tid; // unsigned table identity inside scope -typedef mork_id mork_gid; // unsigned group identity without any scope - -// we only care about neg, zero, pos -- so we don't care about size: -typedef mdb_order mork_order; // neg:lessthan, zero:equalto, pos:greaterthan -// } %%%%% end mdb-driven scalar typedefs %%%%% - -#define morkId_kMinusOne ((mdb_id) -1) - -// { %%%%% begin class forward defines %%%%% -// try to put these in alphabetical order for easier examination: -class morkMid; -class morkAtom; -class morkAtomSpace; -class morkBookAtom; -class morkBuf; -class morkBuilder; -class morkCell; -class morkCellObject; -class morkCursor; -class morkEnv; -class morkFactory; -class morkFile; -class morkHandle; -class morkHandleFace; // just an opaque cookie type -class morkHandleFrame; -class morkHashArrays; -class morkMap; -class morkNode; -class morkObject; -class morkOidAtom; -class morkParser; -class morkPool; -class morkPlace; -class morkPort; -class morkPortTableCursor; -class morkProbeMap; -class morkRow; -class morkRowCellCursor; -class morkRowObject; -class morkRowSpace; -class morkSorting; -class morkSortingRowCursor; -class morkSpace; -class morkSpan; -class morkStore; -class morkStream; -class morkTable; -class morkTableChange; -class morkTableRowCursor; -class morkThumb; -class morkWriter; -class morkZone; -// } %%%%% end class forward defines %%%%% - -// include this config file last for platform & environment specific stuff: -#ifndef _MORKCONFIG_ -#include "morkConfig.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORK_ */ diff --git a/db/mork/src/morkArray.cpp b/db/mork/src/morkArray.cpp deleted file mode 100644 index 91ad51e89d02..000000000000 --- a/db/mork/src/morkArray.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nscore.h" - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKARRAY_ -#include "morkArray.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkArray::CloseMorkNode(morkEnv* ev) // CloseTable() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseArray(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkArray::~morkArray() // assert CloseTable() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); - MORK_ASSERT(mArray_Slots==0); -} - -/*public non-poly*/ -morkArray::morkArray(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap) -: morkNode(ev, inUsage, ioHeap) -, mArray_Slots( 0 ) -, mArray_Heap( 0 ) -, mArray_Fill( 0 ) -, mArray_Size( 0 ) -, mArray_Seed( (mork_u4)NS_PTR_TO_INT32(this) ) // "random" integer assignment -{ - if ( ev->Good() ) - { - if ( ioSlotHeap ) - { - nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mArray_Heap); - if ( ev->Good() ) - { - if ( inSize < 3 ) - inSize = 3; - mdb_size byteSize = inSize * sizeof(void*); - void** block = 0; - ioSlotHeap->Alloc(ev->AsMdbEnv(), byteSize, (void**) &block); - if ( block && ev->Good() ) - { - mArray_Slots = block; - mArray_Size = inSize; - MORK_MEMSET(mArray_Slots, 0, byteSize); - if ( ev->Good() ) - mNode_Derived = morkDerived_kArray; - } - } - } - else - ev->NilPointerError(); - } -} - -/*public non-poly*/ void -morkArray::CloseArray(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - if ( mArray_Heap && mArray_Slots ) - mArray_Heap->Free(ev->AsMdbEnv(), mArray_Slots); - - mArray_Slots = 0; - mArray_Size = 0; - mArray_Fill = 0; - ++mArray_Seed; - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mArray_Heap); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkArray::NonArrayTypeError(morkEnv* ev) -{ - ev->NewError("non morkArray"); -} - -/*static*/ void -morkArray::IndexBeyondEndError(morkEnv* ev) -{ - ev->NewError("array index beyond end"); -} - -/*static*/ void -morkArray::NilSlotsAddressError(morkEnv* ev) -{ - ev->NewError("nil mArray_Slots"); -} - -/*static*/ void -morkArray::FillBeyondSizeError(morkEnv* ev) -{ - ev->NewError("mArray_Fill > mArray_Size"); -} - -mork_bool -morkArray::Grow(morkEnv* ev, mork_size inNewSize) -// Grow() returns true if capacity becomes >= inNewSize and ev->Good() -{ - if ( ev->Good() && inNewSize > mArray_Size ) // make array larger? - { - if ( mArray_Fill <= mArray_Size ) // fill and size fit the invariant? - { - if (mArray_Size <= 3) - inNewSize = mArray_Size + 3; - else - inNewSize = mArray_Size * 2;// + 3; // try doubling size here - used to grow by 3 - - mdb_size newByteSize = inNewSize * sizeof(void*); - void** newBlock = 0; - mArray_Heap->Alloc(ev->AsMdbEnv(), newByteSize, (void**) &newBlock); - if ( newBlock && ev->Good() ) // okay new block? - { - void** oldSlots = mArray_Slots; - void** oldEnd = oldSlots + mArray_Fill; - - void** newSlots = newBlock; - void** newEnd = newBlock + inNewSize; - - while ( oldSlots < oldEnd ) - *newSlots++ = *oldSlots++; - - while ( newSlots < newEnd ) - *newSlots++ = (void*) 0; - - oldSlots = mArray_Slots; - mArray_Size = inNewSize; - mArray_Slots = newBlock; - mArray_Heap->Free(ev->AsMdbEnv(), oldSlots); - } - } - else - this->FillBeyondSizeError(ev); - } - ++mArray_Seed; // always modify seed, since caller intends to add slots - return ( ev->Good() && mArray_Size >= inNewSize ); -} - -void* -morkArray::SafeAt(morkEnv* ev, mork_pos inPos) -{ - if ( mArray_Slots ) - { - if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill ) - return mArray_Slots[ inPos ]; - else - this->IndexBeyondEndError(ev); - } - else - this->NilSlotsAddressError(ev); - - return (void*) 0; -} - -void -morkArray::SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot) -{ - if ( mArray_Slots ) - { - if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill ) - { - mArray_Slots[ inPos ] = ioSlot; - ++mArray_Seed; - } - else - this->IndexBeyondEndError(ev); - } - else - this->NilSlotsAddressError(ev); -} - -mork_pos -morkArray::AppendSlot(morkEnv* ev, void* ioSlot) -{ - mork_pos outPos = -1; - if ( mArray_Slots ) - { - mork_fill fill = mArray_Fill; - if ( this->Grow(ev, fill+1) ) - { - outPos = (mork_pos) fill; - mArray_Slots[ fill ] = ioSlot; - mArray_Fill = fill + 1; - // note Grow() increments mArray_Seed - } - } - else - this->NilSlotsAddressError(ev); - - return outPos; -} - -void -morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot) -{ - if ( mArray_Slots ) - { - mork_fill fill = mArray_Fill; - if ( this->Grow(ev, fill+1) ) - { - void** slot = mArray_Slots; // the slot vector - void** end = slot + fill; // one past the last used array slot - slot += inPos; // the slot to be added - - while ( --end >= slot ) // another slot to move upward? - end[ 1 ] = *end; - - *slot = ioSlot; - mArray_Fill = fill + 1; - // note Grow() increments mArray_Seed - } - } - else - this->NilSlotsAddressError(ev); -} - -void -morkArray::CutSlot(morkEnv* ev, mork_pos inPos) -{ - MORK_USED_1(ev); - mork_fill fill = mArray_Fill; - if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion? - { - void** slot = mArray_Slots; // the slot vector - void** end = slot + fill; // one past the last used array slot - slot += inPos; // the slot to be cut - - while ( ++slot < end ) // another slot to move downward? - slot[ -1 ] = *slot; - - slot[ -1 ] = 0; // clear the last used slot which is now unused - - // note inPos0, so fill-1 must be nonnegative: - mArray_Fill = fill - 1; - ++mArray_Seed; - } -} - -void -morkArray::CutAllSlots(morkEnv* ev) -{ - if ( mArray_Slots ) - { - if ( mArray_Fill <= mArray_Size ) - { - mdb_size oldByteSize = mArray_Fill * sizeof(void*); - MORK_MEMSET(mArray_Slots, 0, oldByteSize); - } - else - this->FillBeyondSizeError(ev); - } - else - this->NilSlotsAddressError(ev); - - ++mArray_Seed; - mArray_Fill = 0; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkArray.h b/db/mork/src/morkArray.h deleted file mode 100644 index 881e0a5c829e..000000000000 --- a/db/mork/src/morkArray.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKARRAY_ -#define _MORKARRAY_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kArray /*i*/ 0x4179 /* ascii 'Ay' */ - -class morkArray : public morkNode { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - void** mArray_Slots; // array of pointers - nsIMdbHeap* mArray_Heap; // required heap for allocating mArray_Slots - mork_fill mArray_Fill; // logical count of used slots in mArray_Slots - mork_size mArray_Size; // physical count of mArray_Slots ( >= Fill) - mork_seed mArray_Seed; // change counter for syncing with iterators - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseArray() - virtual ~morkArray(); // assert that close executed earlier - -public: // morkArray construction & destruction - morkArray(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap); - void CloseArray(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkArray(const morkArray& other); - morkArray& operator=(const morkArray& other); - -public: // dynamic type identification - mork_bool IsArray() const - { return IsNode() && mNode_Derived == morkDerived_kArray; } -// } ===== end morkNode methods ===== - -public: // typing & errors - static void NonArrayTypeError(morkEnv* ev); - static void IndexBeyondEndError(morkEnv* ev); - static void NilSlotsAddressError(morkEnv* ev); - static void FillBeyondSizeError(morkEnv* ev); - -public: // other table row cursor methods - - mork_fill Length() const { return mArray_Fill; } - mork_size Capacity() const { return mArray_Size; } - - mork_bool Grow(morkEnv* ev, mork_size inNewSize); - // Grow() returns true if capacity becomes >= inNewSize and ev->Good() - - void* At(mork_pos inPos) const { return mArray_Slots[ inPos ]; } - void AtPut(mork_pos inPos, void* ioSlot) - { mArray_Slots[ inPos ] = ioSlot; } - - void* SafeAt(morkEnv* ev, mork_pos inPos); - void SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot); - - mork_pos AppendSlot(morkEnv* ev, void* ioSlot); - void AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot); - void CutSlot(morkEnv* ev, mork_pos inPos); - void CutAllSlots(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakArray(morkArray* me, - morkEnv* ev, morkArray** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongArray(morkArray* me, - morkEnv* ev, morkArray** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKTABLEROWCURSOR_ */ diff --git a/db/mork/src/morkAtom.cpp b/db/mork/src/morkAtom.cpp deleted file mode 100644 index fea20965486f..000000000000 --- a/db/mork/src/morkAtom.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -mork_bool -morkAtom::GetYarn(mdbYarn* outYarn) const -{ - const void* source = 0; - mdb_fill fill = 0; - mdb_cscode form = 0; - outYarn->mYarn_More = 0; - - if ( this ) - { - if ( this->IsWeeBook() ) - { - morkWeeBookAtom* weeBook = (morkWeeBookAtom*) this; - source = weeBook->mWeeBookAtom_Body; - fill = weeBook->mAtom_Size; - } - else if ( this->IsBigBook() ) - { - morkBigBookAtom* bigBook = (morkBigBookAtom*) this; - source = bigBook->mBigBookAtom_Body; - fill = bigBook->mBigBookAtom_Size; - form = bigBook->mBigBookAtom_Form; - } - else if ( this->IsWeeAnon() ) - { - morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) this; - source = weeAnon->mWeeAnonAtom_Body; - fill = weeAnon->mAtom_Size; - } - else if ( this->IsBigAnon() ) - { - morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) this; - source = bigAnon->mBigAnonAtom_Body; - fill = bigAnon->mBigAnonAtom_Size; - form = bigAnon->mBigAnonAtom_Form; - } - } - if ( source && fill ) // have an atom with nonempty content? - { - // if we have too many bytes, and yarn seems growable: - if ( fill > outYarn->mYarn_Size && outYarn->mYarn_Grow ) // try grow? - (*outYarn->mYarn_Grow)(outYarn, (mdb_size) fill); // request bigger - - mdb_size size = outYarn->mYarn_Size; // max dest size - if ( fill > size ) // too much atom content? - { - outYarn->mYarn_More = fill - size; // extra atom bytes omitted - fill = size; // copy no more bytes than size of yarn buffer - } - void* dest = outYarn->mYarn_Buf; // where bytes are going - if ( !dest ) // nil destination address buffer? - fill = 0; // we can't write any content at all - - if ( fill ) // anything to copy? - MORK_MEMCPY(dest, source, fill); // copy fill bytes to yarn - - outYarn->mYarn_Fill = fill; // tell yarn size of copied content - } - else // no content to put into the yarn - { - outYarn->mYarn_Fill = 0; // tell yarn that atom has no bytes - } - outYarn->mYarn_Form = form; // always update the form slot - - return ( source != 0 ); -} - -mork_bool -morkAtom::AsBuf(morkBuf& outBuf) const -{ - const morkAtom* atom = this; - if ( atom ) - { - if ( atom->IsWeeBook() ) - { - morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom; - outBuf.mBuf_Body = weeBook->mWeeBookAtom_Body; - outBuf.mBuf_Fill = weeBook->mAtom_Size; - } - else if ( atom->IsBigBook() ) - { - morkBigBookAtom* bigBook = (morkBigBookAtom*) atom; - outBuf.mBuf_Body = bigBook->mBigBookAtom_Body; - outBuf.mBuf_Fill = bigBook->mBigBookAtom_Size; - } - else if ( atom->IsWeeAnon() ) - { - morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom; - outBuf.mBuf_Body = weeAnon->mWeeAnonAtom_Body; - outBuf.mBuf_Fill = weeAnon->mAtom_Size; - } - else if ( atom->IsBigAnon() ) - { - morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom; - outBuf.mBuf_Body = bigAnon->mBigAnonAtom_Body; - outBuf.mBuf_Fill = bigAnon->mBigAnonAtom_Size; - } - else - atom = 0; // show desire to put empty content in yarn - } - - if ( !atom ) // empty content for yarn? - { - outBuf.mBuf_Body = 0; - outBuf.mBuf_Fill = 0; - } - return ( atom != 0 ); -} - -mork_bool -morkAtom::AliasYarn(mdbYarn* outYarn) const -{ - outYarn->mYarn_More = 0; - outYarn->mYarn_Form = 0; - const morkAtom* atom = this; - - if ( atom ) - { - if ( atom->IsWeeBook() ) - { - morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom; - outYarn->mYarn_Buf = weeBook->mWeeBookAtom_Body; - outYarn->mYarn_Fill = weeBook->mAtom_Size; - outYarn->mYarn_Size = weeBook->mAtom_Size; - } - else if ( atom->IsBigBook() ) - { - morkBigBookAtom* bigBook = (morkBigBookAtom*) atom; - outYarn->mYarn_Buf = bigBook->mBigBookAtom_Body; - outYarn->mYarn_Fill = bigBook->mBigBookAtom_Size; - outYarn->mYarn_Size = bigBook->mBigBookAtom_Size; - outYarn->mYarn_Form = bigBook->mBigBookAtom_Form; - } - else if ( atom->IsWeeAnon() ) - { - morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom; - outYarn->mYarn_Buf = weeAnon->mWeeAnonAtom_Body; - outYarn->mYarn_Fill = weeAnon->mAtom_Size; - outYarn->mYarn_Size = weeAnon->mAtom_Size; - } - else if ( atom->IsBigAnon() ) - { - morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom; - outYarn->mYarn_Buf = bigAnon->mBigAnonAtom_Body; - outYarn->mYarn_Fill = bigAnon->mBigAnonAtom_Size; - outYarn->mYarn_Size = bigAnon->mBigAnonAtom_Size; - outYarn->mYarn_Form = bigAnon->mBigAnonAtom_Form; - } - else - atom = 0; // show desire to put empty content in yarn - } - - if ( !atom ) // empty content for yarn? - { - outYarn->mYarn_Buf = 0; - outYarn->mYarn_Fill = 0; - outYarn->mYarn_Size = 0; - // outYarn->mYarn_Grow = 0; // please don't modify the Grow slot - } - return ( atom != 0 ); -} - -mork_aid -morkAtom::GetBookAtomAid() const // zero or book atom's ID -{ - return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0; -} - -mork_scope -morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope -{ - mork_scope outScope = 0; - if ( this->IsBook() ) - { - const morkBookAtom* bookAtom = (const morkBookAtom*) this; - morkAtomSpace* space = bookAtom->mBookAtom_Space; - if ( space->IsAtomSpace() ) - outScope = space->SpaceScope(); - else - space->NonAtomSpaceTypeError(ev); - } - - return outScope; -} - -void -morkAtom::MakeCellUseForever(morkEnv* ev) -{ - MORK_USED_1(ev); - mAtom_CellUses = morkAtom_kForeverCellUses; -} - -mork_u1 -morkAtom::AddCellUse(morkEnv* ev) -{ - MORK_USED_1(ev); - if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out? - ++mAtom_CellUses; - - return mAtom_CellUses; -} - -mork_u1 -morkAtom::CutCellUse(morkEnv* ev) -{ - if ( mAtom_CellUses ) // any outstanding uses to cut? - { - if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not frozen at max? - --mAtom_CellUses; - } - else - this->CellUsesUnderflowWarning(ev); - - return mAtom_CellUses; -} - -/*static*/ void -morkAtom::CellUsesUnderflowWarning(morkEnv* ev) -{ - ev->NewWarning("mAtom_CellUses underflow"); -} - -/*static*/ void -morkAtom::BadAtomKindError(morkEnv* ev) -{ - ev->NewError("bad mAtom_Kind"); -} - -/*static*/ void -morkAtom::ZeroAidError(morkEnv* ev) -{ - ev->NewError("zero atom ID"); -} - -/*static*/ void -morkAtom::AtomSizeOverflowError(morkEnv* ev) -{ - ev->NewError("atom mAtom_Size overflow"); -} - -void -morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid) -{ - MORK_USED_1(ev); - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindRowOid; - mAtom_Change = morkChange_kNil; - mAtom_Size = 0; - mOidAtom_Oid = inOid; // bitwise copy -} - -void -morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid) -{ - MORK_USED_1(ev); - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindTableOid; - mAtom_Change = morkChange_kNil; - mAtom_Size = 0; - mOidAtom_Oid = inOid; // bitwise copy -} - -void -morkWeeAnonAtom::InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf) -{ - mAtom_Kind = 0; - mAtom_Change = morkChange_kNil; - if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize ) - { - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindWeeAnon; - mork_size size = inBuf.mBuf_Fill; - mAtom_Size = (mork_u1) size; - if ( size && inBuf.mBuf_Body ) - MORK_MEMCPY(mWeeAnonAtom_Body, inBuf.mBuf_Body, size); - - mWeeAnonAtom_Body[ size ] = 0; - } - else - this->AtomSizeOverflowError(ev); -} - -void -morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm) -{ - MORK_USED_1(ev); - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindBigAnon; - mAtom_Change = morkChange_kNil; - mAtom_Size = 0; - mBigAnonAtom_Form = inForm; - mork_size size = inBuf.mBuf_Fill; - mBigAnonAtom_Size = size; - if ( size && inBuf.mBuf_Body ) - MORK_MEMCPY(mBigAnonAtom_Body, inBuf.mBuf_Body, size); - - mBigAnonAtom_Body[ size ] = 0; -} - -/*static*/ void -morkBookAtom::NonBookAtomTypeError(morkEnv* ev) -{ - ev->NewError("non morkBookAtom"); -} - -mork_u4 -morkBookAtom::HashFormAndBody(morkEnv* ev) const -{ - // This hash is obviously a variation of the dragon book string hash. - // (I won't bother to explain or rationalize this usage for you.) - - register mork_u4 outHash = 0; // hash value returned - register unsigned char c; // next character - register const mork_u1* body; // body of bytes to hash - mork_size size = 0; // the number of bytes to hash - - if ( this->IsWeeBook() ) - { - size = mAtom_Size; - body = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body; - } - else if ( this->IsBigBook() ) - { - size = ((const morkBigBookAtom*) this)->mBigBookAtom_Size; - body = ((const morkBigBookAtom*) this)->mBigBookAtom_Body; - } - else if ( this->IsFarBook() ) - { - size = ((const morkFarBookAtom*) this)->mFarBookAtom_Size; - body = ((const morkFarBookAtom*) this)->mFarBookAtom_Body; - } - else - { - this->NonBookAtomTypeError(ev); - return 0; - } - - const mork_u1* end = body + size; - while ( body < end ) - { - c = *body++; - outHash <<= 4; - outHash += c; - mork_u4 top = outHash & 0xF0000000L; // top four bits - if ( top ) // any of high four bits equal to one? - { - outHash ^= (top >> 24); // fold down high bits - outHash ^= top; // zero top four bits - } - } - - return outHash; -} - -mork_bool -morkBookAtom::EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const -{ - mork_bool outEqual = morkBool_kFalse; - - const mork_u1* body = 0; // body of inAtom bytes to compare - mork_size size; // the number of inAtom bytes to compare - mork_cscode form; // nominal charset for ioAtom - - if ( inAtom->IsWeeBook() ) - { - size = inAtom->mAtom_Size; - body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body; - form = 0; - } - else if ( inAtom->IsBigBook() ) - { - size = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Size; - body = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Body; - form = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Form; - } - else if ( inAtom->IsFarBook() ) - { - size = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Size; - body = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Body; - form = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Form; - } - else - { - inAtom->NonBookAtomTypeError(ev); - return morkBool_kFalse; - } - - const mork_u1* thisBody = 0; // body of bytes in this to compare - mork_size thisSize; // the number of bytes in this to compare - mork_cscode thisForm; // nominal charset for this atom - - if ( this->IsWeeBook() ) - { - thisSize = mAtom_Size; - thisBody = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body; - thisForm = 0; - } - else if ( this->IsBigBook() ) - { - thisSize = ((const morkBigBookAtom*) this)->mBigBookAtom_Size; - thisBody = ((const morkBigBookAtom*) this)->mBigBookAtom_Body; - thisForm = ((const morkBigBookAtom*) this)->mBigBookAtom_Form; - } - else if ( this->IsFarBook() ) - { - thisSize = ((const morkFarBookAtom*) this)->mFarBookAtom_Size; - thisBody = ((const morkFarBookAtom*) this)->mFarBookAtom_Body; - thisForm = ((const morkFarBookAtom*) this)->mFarBookAtom_Form; - } - else - { - this->NonBookAtomTypeError(ev); - return morkBool_kFalse; - } - - // if atoms are empty, form is irrelevant - if ( body && thisBody && size == thisSize && (!size || form == thisForm )) - outEqual = (MORK_MEMCMP(body, thisBody, size) == 0); - - return outEqual; -} - - -void -morkBookAtom::CutBookAtomFromSpace(morkEnv* ev) -{ - morkAtomSpace* space = mBookAtom_Space; - if ( space ) - { - mBookAtom_Space = 0; - space->mAtomSpace_AtomBodies.CutAtom(ev, this); - space->mAtomSpace_AtomAids.CutAtom(ev, this); - } - else - ev->NilPointerError(); -} - -morkWeeBookAtom::morkWeeBookAtom(mork_aid inAid) -{ - mAtom_Kind = morkAtom_kKindWeeBook; - mAtom_CellUses = 0; - mAtom_Change = morkChange_kNil; - mAtom_Size = 0; - - mBookAtom_Space = 0; - mBookAtom_Id = inAid; - - mWeeBookAtom_Body[ 0 ] = 0; -} - -void -morkWeeBookAtom::InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf, - morkAtomSpace* ioSpace, mork_aid inAid) -{ - mAtom_Kind = 0; - mAtom_Change = morkChange_kNil; - if ( ioSpace ) - { - if ( inAid ) - { - if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize ) - { - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindWeeBook; - mBookAtom_Space = ioSpace; - mBookAtom_Id = inAid; - mork_size size = inBuf.mBuf_Fill; - mAtom_Size = (mork_u1) size; - if ( size && inBuf.mBuf_Body ) - MORK_MEMCPY(mWeeBookAtom_Body, inBuf.mBuf_Body, size); - - mWeeBookAtom_Body[ size ] = 0; - } - else - this->AtomSizeOverflowError(ev); - } - else - this->ZeroAidError(ev); - } - else - ev->NilPointerError(); -} - -void -morkBigBookAtom::InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid) -{ - mAtom_Kind = 0; - mAtom_Change = morkChange_kNil; - if ( ioSpace ) - { - if ( inAid ) - { - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindBigBook; - mAtom_Size = 0; - mBookAtom_Space = ioSpace; - mBookAtom_Id = inAid; - mBigBookAtom_Form = inForm; - mork_size size = inBuf.mBuf_Fill; - mBigBookAtom_Size = size; - if ( size && inBuf.mBuf_Body ) - MORK_MEMCPY(mBigBookAtom_Body, inBuf.mBuf_Body, size); - - mBigBookAtom_Body[ size ] = 0; - } - else - this->ZeroAidError(ev); - } - else - ev->NilPointerError(); -} - -void morkFarBookAtom::InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid) -{ - mAtom_Kind = 0; - mAtom_Change = morkChange_kNil; - if ( ioSpace ) - { - if ( inAid ) - { - mAtom_CellUses = 0; - mAtom_Kind = morkAtom_kKindFarBook; - mAtom_Size = 0; - mBookAtom_Space = ioSpace; - mBookAtom_Id = inAid; - mFarBookAtom_Form = inForm; - mFarBookAtom_Size = inBuf.mBuf_Fill; - mFarBookAtom_Body = (mork_u1*) inBuf.mBuf_Body; - } - else - this->ZeroAidError(ev); - } - else - ev->NilPointerError(); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkAtom.h b/db/mork/src/morkAtom.h deleted file mode 100644 index ba6e851d47ed..000000000000 --- a/db/mork/src/morkAtom.h +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKATOM_ -#define _MORKATOM_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -#define morkAtom_kMaxByteSize 255 /* max for 8-bit integer */ -#define morkAtom_kForeverCellUses 0x0FF /* max for 8-bit integer */ -#define morkAtom_kMaxCellUses 0x07F /* max for 7-bit integer */ - -#define morkAtom_kKindWeeAnon 'a' /* means morkWeeAnonAtom subclass */ -#define morkAtom_kKindBigAnon 'A' /* means morkBigAnonAtom subclass */ -#define morkAtom_kKindWeeBook 'b' /* means morkWeeBookAtom subclass */ -#define morkAtom_kKindBigBook 'B' /* means morkBigBookAtom subclass */ -#define morkAtom_kKindFarBook 'f' /* means morkFarBookAtom subclass */ -#define morkAtom_kKindRowOid 'r' /* means morkOidAtom subclass */ -#define morkAtom_kKindTableOid 't' /* means morkOidAtom subclass */ - -/*| Atom: . -|*/ -class morkAtom { // - -public: - - mork_u1 mAtom_Kind; // identifies a specific atom subclass - mork_u1 mAtom_CellUses; // number of persistent uses in a cell - mork_change mAtom_Change; // how has this atom been changed? - mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes - -public: - morkAtom(mork_aid inAid, mork_u1 inKind); - - mork_bool IsWeeAnon() const { return mAtom_Kind == morkAtom_kKindWeeAnon; } - mork_bool IsBigAnon() const { return mAtom_Kind == morkAtom_kKindBigAnon; } - mork_bool IsWeeBook() const { return mAtom_Kind == morkAtom_kKindWeeBook; } - mork_bool IsBigBook() const { return mAtom_Kind == morkAtom_kKindBigBook; } - mork_bool IsFarBook() const { return mAtom_Kind == morkAtom_kKindFarBook; } - mork_bool IsRowOid() const { return mAtom_Kind == morkAtom_kKindRowOid; } - mork_bool IsTableOid() const { return mAtom_Kind == morkAtom_kKindTableOid; } - - mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); } - -public: // clean vs dirty - - void SetAtomClean() { mAtom_Change = morkChange_kNil; } - void SetAtomDirty() { mAtom_Change = morkChange_kAdd; } - - mork_bool IsAtomClean() const { return mAtom_Change == morkChange_kNil; } - mork_bool IsAtomDirty() const { return mAtom_Change == morkChange_kAdd; } - -public: // atom space scope if IsBook() is true, or else zero: - - mork_scope GetBookAtomSpaceScope(morkEnv* ev) const; - // zero or book's space's scope - - mork_aid GetBookAtomAid() const; - // zero or book atom's ID - -public: // empty construction does nothing - morkAtom() { } - -public: // one-byte refcounting, freezing at maximum - void MakeCellUseForever(morkEnv* ev); - mork_u1 AddCellUse(morkEnv* ev); - mork_u1 CutCellUse(morkEnv* ev); - - mork_bool IsCellUseForever() const - { return mAtom_CellUses == morkAtom_kForeverCellUses; } - -private: // warnings - - static void CellUsesUnderflowWarning(morkEnv* ev); - -public: // errors - - static void BadAtomKindError(morkEnv* ev); - static void ZeroAidError(morkEnv* ev); - static void AtomSizeOverflowError(morkEnv* ev); - -public: // yarns - - mork_bool AsBuf(morkBuf& outBuf) const; - mork_bool AliasYarn(mdbYarn* outYarn) const; - mork_bool GetYarn(mdbYarn* outYarn) const; - -private: // copying is not allowed - morkAtom(const morkAtom& other); - morkAtom& operator=(const morkAtom& other); -}; - -/*| OidAtom: an atom that references a row or table by identity. -|*/ -class morkOidAtom : public morkAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms - -public: - mdbOid mOidAtom_Oid; // identity of referenced object - -public: // empty construction does nothing - morkOidAtom() { } - void InitRowOidAtom(morkEnv* ev, const mdbOid& inOid); - void InitTableOidAtom(morkEnv* ev, const mdbOid& inOid); - -private: // copying is not allowed - morkOidAtom(const morkOidAtom& other); - morkOidAtom& operator=(const morkOidAtom& other); -}; - -/*| WeeAnonAtom: an atom whose content immediately follows morkAtom slots -**| in an inline fashion, so that morkWeeAnonAtom contains both leading -**| atom slots and then the content bytes without further overhead. Note -**| that charset encoding is not indicated, so zero is implied for Latin1. -**| (Non-Latin1 content must be stored in a morkBigAnonAtom with a charset.) -**| -**|| An anon (anonymous) atom has no identity, with no associated bookkeeping -**| for lookup needed for sharing like a book atom. -**| -**|| A wee anon atom is immediate but not shared with any other users of this -**| atom, so no bookkeeping for sharing is needed. This means the atom has -**| no ID, because the atom has no identity other than this immediate content, -**| and no hash table is needed to look up this particular atom. This also -**| applies to the larger format morkBigAnonAtom, which has more slots. -|*/ -class morkWeeAnonAtom : public morkAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes - -public: - mork_u1 mWeeAnonAtom_Body[ 1 ]; // 1st byte of immediate content vector - -public: // empty construction does nothing - morkWeeAnonAtom() { } - void InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf); - - // allow extra trailing byte for a null byte: - static mork_size SizeForFill(mork_fill inFill) - { return sizeof(morkWeeAnonAtom) + inFill; } - -private: // copying is not allowed - morkWeeAnonAtom(const morkWeeAnonAtom& other); - morkWeeAnonAtom& operator=(const morkWeeAnonAtom& other); -}; - -/*| BigAnonAtom: another immediate atom that cannot be encoded as the smaller -**| morkWeeAnonAtom format because either the size is too great, and/or the -**| charset is not the default zero for Latin1 and must be explicitly noted. -**| -**|| An anon (anonymous) atom has no identity, with no associated bookkeeping -**| for lookup needed for sharing like a book atom. -|*/ -class morkBigAnonAtom : public morkAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms - -public: - mork_cscode mBigAnonAtom_Form; // charset format encoding - mork_size mBigAnonAtom_Size; // size of content vector - mork_u1 mBigAnonAtom_Body[ 1 ]; // 1st byte of immed content vector - -public: // empty construction does nothing - morkBigAnonAtom() { } - void InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf, mork_cscode inForm); - - // allow extra trailing byte for a null byte: - static mork_size SizeForFill(mork_fill inFill) - { return sizeof(morkBigAnonAtom) + inFill; } - -private: // copying is not allowed - morkBigAnonAtom(const morkBigAnonAtom& other); - morkBigAnonAtom& operator=(const morkBigAnonAtom& other); -}; - -#define morkBookAtom_kMaxBodySize 1024 /* if larger, cannot be shared */ - -/*| BookAtom: the common subportion of wee book atoms and big book atoms that -**| includes the atom ID and the pointer to the space referencing this atom -**| through a hash table. -|*/ -class morkBookAtom : public morkAtom { // - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes - -public: - morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is atom scope - mork_aid mBookAtom_Id; // identity token for this shared atom - -public: // empty construction does nothing - morkBookAtom() { } - - static void NonBookAtomTypeError(morkEnv* ev); - -public: // Hash() and Equal() for atom ID maps are same for all subclasses: - - mork_u4 HashAid() const { return mBookAtom_Id; } - mork_bool EqualAid(const morkBookAtom* inAtom) const - { return ( mBookAtom_Id == inAtom->mBookAtom_Id); } - -public: // Hash() and Equal() for atom body maps know about subclasses: - - // YOU CANNOT SUBCLASS morkBookAtom WITHOUT FIXING Hash and Equal METHODS: - - mork_u4 HashFormAndBody(morkEnv* ev) const; - mork_bool EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const; - -public: // separation from containing space - - void CutBookAtomFromSpace(morkEnv* ev); - -private: // copying is not allowed - morkBookAtom(const morkBookAtom& other); - morkBookAtom& operator=(const morkBookAtom& other); -}; - -/*| FarBookAtom: this alternative format for book atoms was introduced -**| in May 2000 in order to support finding atoms in hash tables without -**| first copying the strings from original parsing buffers into a new -**| atom format. This was consuming too much time. However, we can -**| use morkFarBookAtom to stage a hash table query, as long as we then -**| fix HashFormAndBody() and EqualFormAndBody() to use morkFarBookAtom -**| correctly. -**| -**|| Note we do NOT intend that instances of morkFarBookAtom will ever -**| be installed in hash tables, because this is not space efficient. -**| We only expect to create temp instances for table lookups. -|*/ -class morkFarBookAtom : public morkBookAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms - - // morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope - // mork_aid mBookAtom_Id; // identity token for this shared atom - -public: - mork_cscode mFarBookAtom_Form; // charset format encoding - mork_size mFarBookAtom_Size; // size of content vector - mork_u1* mFarBookAtom_Body; // bytes are elsewere, out of line - -public: // empty construction does nothing - morkFarBookAtom() { } - void InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid); - -private: // copying is not allowed - morkFarBookAtom(const morkFarBookAtom& other); - morkFarBookAtom& operator=(const morkFarBookAtom& other); -}; - -/*| WeeBookAtom: . -|*/ -class morkWeeBookAtom : public morkBookAtom { // - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes - - // morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope - // mork_aid mBookAtom_Id; // identity token for this shared atom - -public: - mork_u1 mWeeBookAtom_Body[ 1 ]; // 1st byte of immed content vector - -public: // empty construction does nothing - morkWeeBookAtom() { } - morkWeeBookAtom(mork_aid inAid); - - void InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf, - morkAtomSpace* ioSpace, mork_aid inAid); - - // allow extra trailing byte for a null byte: - static mork_size SizeForFill(mork_fill inFill) - { return sizeof(morkWeeBookAtom) + inFill; } - -private: // copying is not allowed - morkWeeBookAtom(const morkWeeBookAtom& other); - morkWeeBookAtom& operator=(const morkWeeBookAtom& other); -}; - -/*| BigBookAtom: . -|*/ -class morkBigBookAtom : public morkBookAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms - - // morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope - // mork_aid mBookAtom_Id; // identity token for this shared atom - -public: - mork_cscode mBigBookAtom_Form; // charset format encoding - mork_size mBigBookAtom_Size; // size of content vector - mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector - -public: // empty construction does nothing - morkBigBookAtom() { } - void InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid); - - // allow extra trailing byte for a null byte: - static mork_size SizeForFill(mork_fill inFill) - { return sizeof(morkBigBookAtom) + inFill; } - -private: // copying is not allowed - morkBigBookAtom(const morkBigBookAtom& other); - morkBigBookAtom& operator=(const morkBigBookAtom& other); -}; - -/*| MaxBookAtom: . -|*/ -class morkMaxBookAtom : public morkBigBookAtom { // - - // mork_u1 mAtom_Kind; // identifies a specific atom subclass - // mork_u1 mAtom_CellUses; // number of persistent uses in a cell - // mork_change mAtom_Change; // how has this atom been changed? - // mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms - - // morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope - // mork_aid mBookAtom_Id; // identity token for this shared atom - - // mork_cscode mBigBookAtom_Form; // charset format encoding - // mork_size mBigBookAtom_Size; // size of content vector - // mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector - -public: - mork_u1 mMaxBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes - -public: // empty construction does nothing - morkMaxBookAtom() { } - void InitMaxBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid) - { this->InitBigBookAtom(ev, inBuf, inForm, ioSpace, inAid); } - -private: // copying is not allowed - morkMaxBookAtom(const morkMaxBookAtom& other); - morkMaxBookAtom& operator=(const morkMaxBookAtom& other); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKATOM_ */ - diff --git a/db/mork/src/morkAtomMap.cpp b/db/mork/src/morkAtomMap.cpp deleted file mode 100644 index 3bac7fdbdcd8..000000000000 --- a/db/mork/src/morkAtomMap.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKATOMMAP_ -#include "morkAtomMap.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKINTMAP_ -#include "morkIntMap.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkAtomAidMap::CloseMorkNode(morkEnv* ev) // CloseAtomAidMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseAtomAidMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - - -/*public non-poly*/ -morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -#ifdef MORK_ENABLE_PROBE_MAPS -: morkProbeMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0, - ioSlotHeap, morkAtomAidMap_kStartSlotCount, - /*inZeroIsClearKey*/ morkBool_kTrue) -#else /*MORK_ENABLE_PROBE_MAPS*/ -: morkMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0, - morkAtomAidMap_kStartSlotCount, ioSlotHeap, - /*inHoldChanges*/ morkBool_kFalse) -#endif /*MORK_ENABLE_PROBE_MAPS*/ -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kAtomAidMap; -} - -/*public non-poly*/ void -morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { -#ifdef MORK_ENABLE_PROBE_MAPS - this->CloseProbeMap(ev); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->CloseMap(ev); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -#ifdef MORK_ENABLE_PROBE_MAPS - - /*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b) - morkAtomAidMap::MapTest(morkEnv* ev, const void* inMapKey, - const void* inAppKey) const - { - MORK_USED_1(ev); - const morkBookAtom* key = *(const morkBookAtom**) inMapKey; - if ( key ) - { - mork_bool hit = key->EqualAid(*(const morkBookAtom**) inAppKey); - return ( hit ) ? morkTest_kHit : morkTest_kMiss; - } - else - return morkTest_kVoid; - } - - /*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b) - morkAtomAidMap::MapHash(morkEnv* ev, const void* inAppKey) const - { - const morkBookAtom* key = *(const morkBookAtom**) inAppKey; - if ( key ) - return key->HashAid(); - else - { - ev->NilPointerWarning(); - return 0; - } - } - - /*virtual*/ mork_u4 - morkAtomAidMap::ProbeMapHashMapKey(morkEnv* ev, - const void* inMapKey) const - { - const morkBookAtom* key = *(const morkBookAtom**) inMapKey; - if ( key ) - return key->HashAid(); - else - { - ev->NilPointerWarning(); - return 0; - } - } -#else /*MORK_ENABLE_PROBE_MAPS*/ - // { ===== begin morkMap poly interface ===== - /*virtual*/ mork_bool // - morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA, - const void* inKeyB) const - { - MORK_USED_1(ev); - return (*(const morkBookAtom**) inKeyA)->EqualAid( - *(const morkBookAtom**) inKeyB); - } - - /*virtual*/ mork_u4 // - morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const - { - MORK_USED_1(ev); - return (*(const morkBookAtom**) inKey)->HashAid(); - } - // } ===== end morkMap poly interface ===== -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - -mork_bool -morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom) -{ - if ( ev->Good() ) - { -#ifdef MORK_ENABLE_PROBE_MAPS - this->MapAtPut(ev, &ioAtom, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Put(ev, &ioAtom, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - } - return ev->Good(); -} - -morkBookAtom* -morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom) -{ - morkBookAtom* oldKey = 0; - -#ifdef MORK_ENABLE_PROBE_MAPS - MORK_USED_1(inAtom); - morkProbeMap::ProbeMapCutError(ev); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0, - (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - return oldKey; -} - -morkBookAtom* -morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom) -{ - morkBookAtom* key = 0; // old val in the map - -#ifdef MORK_ENABLE_PROBE_MAPS - this->MapAt(ev, &inAtom, &key, /*val*/ (void*) 0); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - return key; -} - -morkBookAtom* -morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid) -{ - morkWeeBookAtom weeAtom(inAid); - morkBookAtom* key = &weeAtom; // we need a pointer - morkBookAtom* oldKey = 0; // old key in the map - -#ifdef MORK_ENABLE_PROBE_MAPS - this->MapAt(ev, &key, &oldKey, /*val*/ (void*) 0); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - return oldKey; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkAtomBodyMap::CloseMorkNode(morkEnv* ev) // CloseAtomBodyMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseAtomBodyMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - - -/*public non-poly*/ -morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -#ifdef MORK_ENABLE_PROBE_MAPS -: morkProbeMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0, - ioSlotHeap, morkAtomBodyMap_kStartSlotCount, - /*inZeroIsClearKey*/ morkBool_kTrue) -#else /*MORK_ENABLE_PROBE_MAPS*/ -: morkMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0, - morkAtomBodyMap_kStartSlotCount, ioSlotHeap, - /*inHoldChanges*/ morkBool_kFalse) -#endif /*MORK_ENABLE_PROBE_MAPS*/ -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kAtomBodyMap; -} - -/*public non-poly*/ void -morkAtomBodyMap::CloseAtomBodyMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { -#ifdef MORK_ENABLE_PROBE_MAPS - this->CloseProbeMap(ev); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->CloseMap(ev); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` -#ifdef MORK_ENABLE_PROBE_MAPS - - /*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b) - morkAtomBodyMap::MapTest(morkEnv* ev, const void* inMapKey, - const void* inAppKey) const - { - const morkBookAtom* key = *(const morkBookAtom**) inMapKey; - if ( key ) - { - return ( key->EqualFormAndBody(ev, *(const morkBookAtom**) inAppKey) ) ? - morkTest_kHit : morkTest_kMiss; - } - else - return morkTest_kVoid; - } - - /*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b) - morkAtomBodyMap::MapHash(morkEnv* ev, const void* inAppKey) const - { - const morkBookAtom* key = *(const morkBookAtom**) inAppKey; - if ( key ) - return key->HashFormAndBody(ev); - else - return 0; - } - - /*virtual*/ mork_u4 - morkAtomBodyMap::ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const - { - const morkBookAtom* key = *(const morkBookAtom**) inMapKey; - if ( key ) - return key->HashFormAndBody(ev); - else - return 0; - } -#else /*MORK_ENABLE_PROBE_MAPS*/ - // { ===== begin morkMap poly interface ===== - /*virtual*/ mork_bool // - morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA, - const void* inKeyB) const - { - return (*(const morkBookAtom**) inKeyA)->EqualFormAndBody(ev, - *(const morkBookAtom**) inKeyB); - } - - /*virtual*/ mork_u4 // - morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const - { - return (*(const morkBookAtom**) inKey)->HashFormAndBody(ev); - } - // } ===== end morkMap poly interface ===== -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - -mork_bool -morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom) -{ - if ( ev->Good() ) - { -#ifdef MORK_ENABLE_PROBE_MAPS - this->MapAtPut(ev, &ioAtom, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Put(ev, &ioAtom, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - } - return ev->Good(); -} - -morkBookAtom* -morkAtomBodyMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom) -{ - morkBookAtom* oldKey = 0; - -#ifdef MORK_ENABLE_PROBE_MAPS - MORK_USED_1(inAtom); - morkProbeMap::ProbeMapCutError(ev); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0, - (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - return oldKey; -} - -morkBookAtom* -morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom) -{ - morkBookAtom* key = 0; // old val in the map -#ifdef MORK_ENABLE_PROBE_MAPS - this->MapAt(ev, &inAtom, &key, /*val*/ (void*) 0); -#else /*MORK_ENABLE_PROBE_MAPS*/ - this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - return key; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -morkAtomRowMap::~morkAtomRowMap() -{ -} - -// I changed to sizeof(mork_ip) from sizeof(mork_aid) to fix a crash on -// 64 bit machines. I am not sure it was the right way to fix the problem, -// but it does stop the crash. Perhaps we should be using the -// morkPointerMap instead? -morkAtomRowMap::morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn) - : morkIntMap(ev, inUsage, sizeof(mork_ip), ioHeap, ioSlotHeap, - /*inHoldChanges*/ morkBool_kFalse) -, mAtomRowMap_IndexColumn( inIndexColumn ) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kAtomRowMap; -} - -void morkAtomRowMap::AddRow(morkEnv* ev, morkRow* ioRow) -// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn. -{ - mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn); - if ( aid ) - this->AddAid(ev, aid, ioRow); -} - -void morkAtomRowMap::CutRow(morkEnv* ev, morkRow* ioRow) -// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn. -{ - mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn); - if ( aid ) - this->CutAid(ev, aid); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkAtomMap.h b/db/mork/src/morkAtomMap.h deleted file mode 100644 index 131119987da3..000000000000 --- a/db/mork/src/morkAtomMap.h +++ /dev/null @@ -1,397 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKATOMMAP_ -#define _MORKATOMMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKPROBEMAP_ -#include "morkProbeMap.h" -#endif - -#ifndef _MORKINTMAP_ -#include "morkIntMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */ - -#define morkAtomAidMap_kStartSlotCount 23 - -/*| morkAtomAidMap: keys of morkBookAtom organized by atom ID -|*/ -#ifdef MORK_ENABLE_PROBE_MAPS -class morkAtomAidMap : public morkProbeMap { // for mapping tokens to maps -#else /*MORK_ENABLE_PROBE_MAPS*/ -class morkAtomAidMap : public morkMap { // for mapping tokens to maps -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseAtomAidMap() only if open - virtual ~morkAtomAidMap(); // assert that CloseAtomAidMap() executed earlier - -public: // morkMap construction & destruction - morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseAtomAidMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsAtomAidMap() const - { return IsNode() && mNode_Derived == morkDerived_kAtomAidMap; } -// } ===== end morkNode methods ===== - -public: -#ifdef MORK_ENABLE_PROBE_MAPS - // { ===== begin morkProbeMap methods ===== - virtual mork_test // hit(a,b) implies hash(a) == hash(b) - MapTest(morkEnv* ev, const void* inMapKey, const void* inAppKey) const; - - virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) - MapHash(morkEnv* ev, const void* inAppKey) const; - - virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const; - - // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); - - // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - // void* ioMapKey, mork_count inKeyCount); // array of keys inside map - - // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - // const void* inAppKey, const void* inAppVal, // (key,val) outside map - // void* outMapKey, void* outMapVal); // (key,val) inside map - - // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - // const void* inMapKey, const void* inMapVal, // (key,val) inside map - // void* outAppKey, void* outAppVal) const; // (key,val) outside map - // } ===== end morkProbeMap methods ===== -#else /*MORK_ENABLE_PROBE_MAPS*/ -// { ===== begin morkMap poly interface ===== - virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - // implemented using morkBookAtom::HashAid() - - virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) - Hash(morkEnv* ev, const void* inKey) const; - // implemented using morkBookAtom::EqualAid() -// } ===== end morkMap poly interface ===== -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -public: // other map methods - - mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom); - // AddAtom() returns ev->Good() - - morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom); - // CutAtom() returns the atom removed equal to inAtom, if there was one - - morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom); - // GetAtom() returns the atom equal to inAtom, or else nil - - morkBookAtom* GetAid(morkEnv* ev, mork_aid inAid); - // GetAid() returns the atom equal to inAid, or else nil - - // note the atoms are owned elsewhere, usuall by morkAtomSpace - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakAtomAidMap(morkAtomAidMap* me, - morkEnv* ev, morkAtomAidMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongAtomAidMap(morkAtomAidMap* me, - morkEnv* ev, morkAtomAidMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -#ifdef MORK_ENABLE_PROBE_MAPS -class morkAtomAidMapIter: public morkProbeMapIter { // typesafe wrapper class -#else /*MORK_ENABLE_PROBE_MAPS*/ -class morkAtomAidMapIter: public morkMapIter { // typesafe wrapper class -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -public: -#ifdef MORK_ENABLE_PROBE_MAPS - morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) - : morkProbeMapIter(ev, ioMap) { } - - morkAtomAidMapIter( ) : morkProbeMapIter() { } -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkAtomAidMapIter( ) : morkMapIter() { } -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - void InitAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->First(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kAtomBodyMap /*i*/ 0x6142 /* ascii 'aB' */ - -#define morkAtomBodyMap_kStartSlotCount 23 - -/*| morkAtomBodyMap: keys of morkBookAtom organized by body bytes -|*/ -#ifdef MORK_ENABLE_PROBE_MAPS -class morkAtomBodyMap : public morkProbeMap { // for mapping tokens to maps -#else /*MORK_ENABLE_PROBE_MAPS*/ -class morkAtomBodyMap : public morkMap { // for mapping tokens to maps -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseAtomBodyMap() only if open - virtual ~morkAtomBodyMap(); // assert CloseAtomBodyMap() executed earlier - -public: // morkMap construction & destruction - morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseAtomBodyMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsAtomBodyMap() const - { return IsNode() && mNode_Derived == morkDerived_kAtomBodyMap; } -// } ===== end morkNode methods ===== - -public: -#ifdef MORK_ENABLE_PROBE_MAPS - // { ===== begin morkProbeMap methods ===== - virtual mork_test // hit(a,b) implies hash(a) == hash(b) - MapTest(morkEnv* ev, const void* inMapKey, const void* inAppKey) const; - - virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) - MapHash(morkEnv* ev, const void* inAppKey) const; - - virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const; - - // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); - - // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - // void* ioMapKey, mork_count inKeyCount); // array of keys inside map - - // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - // const void* inAppKey, const void* inAppVal, // (key,val) outside map - // void* outMapKey, void* outMapVal); // (key,val) inside map - - // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - // const void* inMapKey, const void* inMapVal, // (key,val) inside map - // void* outAppKey, void* outAppVal) const; // (key,val) outside map - // } ===== end morkProbeMap methods ===== -#else /*MORK_ENABLE_PROBE_MAPS*/ -// { ===== begin morkMap poly interface ===== - virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - // implemented using morkBookAtom::EqualFormAndBody() - - virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) - Hash(morkEnv* ev, const void* inKey) const; - // implemented using morkBookAtom::HashFormAndBody() -// } ===== end morkMap poly interface ===== -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -public: // other map methods - - mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom); - // AddAtom() returns ev->Good() - - morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom); - // CutAtom() returns the atom removed equal to inAtom, if there was one - - morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom); - // GetAtom() returns the atom equal to inAtom, or else nil - - // note the atoms are owned elsewhere, usuall by morkAtomSpace - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakAtomBodyMap(morkAtomBodyMap* me, - morkEnv* ev, morkAtomBodyMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongAtomBodyMap(morkAtomBodyMap* me, - morkEnv* ev, morkAtomBodyMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -#ifdef MORK_ENABLE_PROBE_MAPS -class morkAtomBodyMapIter: public morkProbeMapIter{ // typesafe wrapper class -#else /*MORK_ENABLE_PROBE_MAPS*/ -class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -public: -#ifdef MORK_ENABLE_PROBE_MAPS - morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) - : morkProbeMapIter(ev, ioMap) { } - - morkAtomBodyMapIter( ) : morkProbeMapIter() { } -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkAtomBodyMapIter( ) : morkMapIter() { } -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - void InitAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->First(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); } - - mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) - { return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kAtomRowMap /*i*/ 0x6152 /* ascii 'aR' */ - -/*| morkAtomRowMap: maps morkAtom* -> morkRow* -|*/ -class morkAtomRowMap : public morkIntMap { // for mapping atoms to rows - -public: - mork_column mAtomRowMap_IndexColumn; // row column being indexed - -public: - - virtual ~morkAtomRowMap(); - morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn); - -public: // adding and cutting from morkRow instance candidate - - void AddRow(morkEnv* ev, morkRow* ioRow); - // add ioRow only if it contains a cell in mAtomRowMap_IndexColumn. - - void CutRow(morkEnv* ev, morkRow* ioRow); - // cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn. - -public: // other map methods - - mork_bool AddAid(morkEnv* ev, mork_aid inAid, morkRow* ioRow) - { return this->AddInt(ev, inAid, ioRow); } - // the AddAid() boolean return equals ev->Good(). - - mork_bool CutAid(morkEnv* ev, mork_aid inAid) - { return this->CutInt(ev, inAid); } - // The CutAid() boolean return indicates whether removal happened. - - morkRow* GetAid(morkEnv* ev, mork_aid inAid) - { return (morkRow*) this->GetInt(ev, inAid); } - // Note the returned space does NOT have an increase in refcount for this. - -public: // dynamic type identification - mork_bool IsAtomRowMap() const - { return IsNode() && mNode_Derived == morkDerived_kAtomRowMap; } - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakAtomRowMap(morkAtomRowMap* me, - morkEnv* ev, morkAtomRowMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongAtomRowMap(morkAtomRowMap* me, - morkEnv* ev, morkAtomRowMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } - -}; - -class morkAtomRowMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkAtomRowMapIter( ) : morkMapIter() { } - void InitAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* - FirstAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow) - { return this->First(ev, outAtom, outRow); } - - mork_change* - NextAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow) - { return this->Next(ev, outAtom, outRow); } - - mork_change* - HereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow) - { return this->Here(ev, outAtom, outRow); } - - mork_change* - CutHereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow) - { return this->CutHere(ev, outAtom, outRow); } -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKATOMMAP_ */ diff --git a/db/mork/src/morkAtomSpace.cpp b/db/mork/src/morkAtomSpace.cpp deleted file mode 100644 index a3d72c99978c..000000000000 --- a/db/mork/src/morkAtomSpace.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkAtomSpace::CloseMorkNode(morkEnv* ev) // CloseAtomSpace() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseAtomSpace(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkAtomSpace::~morkAtomSpace() // assert CloseAtomSpace() executed earlier -{ - MORK_ASSERT(mAtomSpace_HighUnderId==0); - MORK_ASSERT(mAtomSpace_HighOverId==0); - MORK_ASSERT(this->IsShutNode()); - MORK_ASSERT(mAtomSpace_AtomAids.IsShutNode()); - MORK_ASSERT(mAtomSpace_AtomBodies.IsShutNode()); -} - -/*public non-poly*/ -morkAtomSpace::morkAtomSpace(morkEnv* ev, const morkUsage& inUsage, - mork_scope inScope, morkStore* ioStore, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap) -, mAtomSpace_HighUnderId( morkAtomSpace_kMinUnderId ) -, mAtomSpace_HighOverId( morkAtomSpace_kMinOverId ) -, mAtomSpace_AtomAids(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap) -, mAtomSpace_AtomBodies(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap) -{ - // the morkSpace base constructor handles any dirty propagation - if ( ev->Good() ) - mNode_Derived = morkDerived_kAtomSpace; -} - -/*public non-poly*/ void -morkAtomSpace::CloseAtomSpace(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mAtomSpace_AtomBodies.CloseMorkNode(ev); - morkStore* store = mSpace_Store; - if ( store ) - this->CutAllAtoms(ev, &store->mStore_Pool); - - mAtomSpace_AtomAids.CloseMorkNode(ev); - this->CloseSpace(ev); - mAtomSpace_HighUnderId = 0; - mAtomSpace_HighOverId = 0; - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkAtomSpace::NonAtomSpaceTypeError(morkEnv* ev) -{ - ev->NewError("non morkAtomSpace"); -} - -mork_num -morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool) -{ -#ifdef MORK_ENABLE_ZONE_ARENAS - MORK_USED_2(ev, ioPool); - return 0; -#else /*MORK_ENABLE_ZONE_ARENAS*/ - if ( this->IsAtomSpaceClean() ) - this->MaybeDirtyStoreAndSpace(); - - mork_num outSlots = mAtomSpace_AtomAids.MapFill(); - morkBookAtom* a = 0; // old key atom in the map - - morkStore* store = mSpace_Store; - mork_change* c = 0; - morkAtomAidMapIter i(ev, &mAtomSpace_AtomAids); - for ( c = i.FirstAtom(ev, &a); c ; c = i.NextAtom(ev, &a) ) - { - if ( a ) - ioPool->ZapAtom(ev, a, &store->mStore_Zone); - -#ifdef MORK_ENABLE_PROBE_MAPS - // do not cut anything from the map -#else /*MORK_ENABLE_PROBE_MAPS*/ - i.CutHereAtom(ev, /*key*/ (morkBookAtom**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - } - - return outSlots; -#endif /*MORK_ENABLE_ZONE_ARENAS*/ -} - - -morkBookAtom* -morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev, - const morkFarBookAtom& inAtom, mork_aid inAid) -// Make copy of inAtom and put it in both maps, using specified ID. -{ - morkBookAtom* outAtom = 0; - morkStore* store = mSpace_Store; - if ( ev->Good() && store ) - { - morkPool* pool = this->GetSpaceStorePool(); - outAtom = pool->NewFarBookAtomCopy(ev, inAtom, &store->mStore_Zone); - if ( outAtom ) - { - if ( store->mStore_CanDirty ) - { - outAtom->SetAtomDirty(); - if ( this->IsAtomSpaceClean() ) - this->MaybeDirtyStoreAndSpace(); - } - - outAtom->mBookAtom_Id = inAid; - outAtom->mBookAtom_Space = this; - mAtomSpace_AtomAids.AddAtom(ev, outAtom); - mAtomSpace_AtomBodies.AddAtom(ev, outAtom); - if ( this->SpaceScope() == morkAtomSpace_kColumnScope ) - outAtom->MakeCellUseForever(ev); - - if ( mAtomSpace_HighUnderId <= inAid ) - mAtomSpace_HighUnderId = inAid + 1; - } - } - return outAtom; -} - -morkBookAtom* -morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom) -// make copy of inAtom and put it in both maps, using a new ID as needed. -{ - morkBookAtom* outAtom = 0; - morkStore* store = mSpace_Store; - if ( ev->Good() && store ) - { - if ( store->mStore_CanAutoAssignAtomIdentity ) - { - morkPool* pool = this->GetSpaceStorePool(); - morkBookAtom* atom = pool->NewFarBookAtomCopy(ev, inAtom, &mSpace_Store->mStore_Zone); - if ( atom ) - { - mork_aid id = this->MakeNewAtomId(ev, atom); - if ( id ) - { - if ( store->mStore_CanDirty ) - { - atom->SetAtomDirty(); - if ( this->IsAtomSpaceClean() ) - this->MaybeDirtyStoreAndSpace(); - } - - outAtom = atom; - atom->mBookAtom_Space = this; - mAtomSpace_AtomAids.AddAtom(ev, atom); - mAtomSpace_AtomBodies.AddAtom(ev, atom); - if ( this->SpaceScope() == morkAtomSpace_kColumnScope ) - outAtom->MakeCellUseForever(ev); - } - else - pool->ZapAtom(ev, atom, &mSpace_Store->mStore_Zone); - } - } - else - mSpace_Store->CannotAutoAssignAtomIdentityError(ev); - } - return outAtom; -} - - -mork_aid -morkAtomSpace::MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom) -{ - mork_aid outAid = 0; - mork_tid id = mAtomSpace_HighUnderId; - mork_num count = 8; // try up to eight times - - while ( !outAid && count ) // still trying to find an unused table ID? - { - --count; - ioAtom->mBookAtom_Id = id; - if ( !mAtomSpace_AtomAids.GetAtom(ev, ioAtom) ) - outAid = id; - else - { - MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems - ++id; - } - } - - mAtomSpace_HighUnderId = id + 1; - return outAid; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -morkAtomSpaceMap::~morkAtomSpaceMap() -{ -} - -morkAtomSpaceMap::morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) - : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kAtomSpaceMap; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkAtomSpace.h b/db/mork/src/morkAtomSpace.h deleted file mode 100644 index fc0757d9e549..000000000000 --- a/db/mork/src/morkAtomSpace.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKATOMSPACE_ -#define _MORKATOMSPACE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKATOMMAP_ -#include "morkAtomMap.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| kMinUnderId: the smallest ID we auto-assign to the 'under' namespace -**| reserved for tokens expected to occur very frequently, such as the names -**| of columns. We reserve single byte ids in the ASCII range to correspond -**| one-to-one to those tokens consisting single ASCII characters (so that -**| this assignment is always known and constant). So we start at 0x80, and -**| then reserve the upper half of two hex digit ids and all the three hex -**| digit IDs for the 'under' namespace for common tokens. -|*/ -#define morkAtomSpace_kMinUnderId 0x80 /* low 7 bits mean byte tokens */ - -#define morkAtomSpace_kMaxSevenBitAid 0x7F /* low seven bit integer ID */ - -/*| kMinOverId: the smallest ID we auto-assign to the 'over' namespace that -**| might include very large numbers of tokens that are used infrequently, -**| so that we care less whether the shortest hex representation is used. -**| So we start all IDs for 'over' category tokens at a value range that -**| needs at least four hex digits, so we can reserve three hex digits and -**| shorter for more commonly occuring tokens in the 'under' category. -|*/ -#define morkAtomSpace_kMinOverId 0x1000 /* using at least four hex bytes */ - -#define morkDerived_kAtomSpace /*i*/ 0x6153 /* ascii 'aS' */ - -#define morkAtomSpace_kColumnScope ((mork_scope) 'c') /* column scope is forever */ - -/*| morkAtomSpace: -|*/ -class morkAtomSpace : public morkSpace { // - -// public: // slots inherited from morkSpace (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkStore* mSpace_Store; // weak ref to containing store - - // mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs - // mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs - // mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment - -public: // state is public because the entire Mork system is private - - mork_aid mAtomSpace_HighUnderId; // high ID in 'under' range - mork_aid mAtomSpace_HighOverId; // high ID in 'over' range - - morkAtomAidMap mAtomSpace_AtomAids; // all atoms in space by ID - morkAtomBodyMap mAtomSpace_AtomBodies; // all atoms in space by body - -public: // more specific dirty methods for atom space: - void SetAtomSpaceDirty() { this->SetNodeDirty(); } - void SetAtomSpaceClean() { this->SetNodeClean(); } - - mork_bool IsAtomSpaceClean() const { return this->IsNodeClean(); } - mork_bool IsAtomSpaceDirty() const { return this->IsNodeDirty(); } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseAtomSpace() only if open - virtual ~morkAtomSpace(); // assert that CloseAtomSpace() executed earlier - -public: // morkMap construction & destruction - morkAtomSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope, - morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap); - void CloseAtomSpace(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsAtomSpace() const - { return IsNode() && mNode_Derived == morkDerived_kAtomSpace; } -// } ===== end morkNode methods ===== - -public: // typing - void NonAtomSpaceTypeError(morkEnv* ev); - -public: // setup - - mork_bool MarkAllAtomSpaceContentDirty(morkEnv* ev); - // MarkAllAtomSpaceContentDirty() visits every space object and marks - // them dirty, including every table, row, cell, and atom. The return - // equals ev->Good(), to show whether any error happened. This method is - // intended for use in the beginning of a "compress commit" which writes - // all store content, whether dirty or not. We dirty everything first so - // that later iterations over content can mark things clean as they are - // written, and organize the process of serialization so that objects are - // written only at need (because of being dirty). - -public: // other space methods - - // void ReserveColumnAidCount(mork_count inCount) - // { - // mAtomSpace_HighUnderId = morkAtomSpace_kMinUnderId + inCount; - // mAtomSpace_HighOverId = morkAtomSpace_kMinOverId + inCount; - // } - - mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool); - // CutAllAtoms() puts all the atoms back in the pool. - - morkBookAtom* MakeBookAtomCopyWithAid(morkEnv* ev, - const morkFarBookAtom& inAtom, mork_aid inAid); - // Make copy of inAtom and put it in both maps, using specified ID. - - morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom); - // Make copy of inAtom and put it in both maps, using a new ID as needed. - - mork_aid MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom); - // generate an unused atom id. - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakAtomSpace(morkAtomSpace* me, - morkEnv* ev, morkAtomSpace** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongAtomSpace(morkAtomSpace* me, - morkEnv* ev, morkAtomSpace** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kAtomSpaceMap /*i*/ 0x615A /* ascii 'aZ' */ - -/*| morkAtomSpaceMap: maps mork_scope -> morkAtomSpace -|*/ -class morkAtomSpaceMap : public morkNodeMap { // for mapping tokens to tables - -public: - - virtual ~morkAtomSpaceMap(); - morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - -public: // other map methods - - mork_bool AddAtomSpace(morkEnv* ev, morkAtomSpace* ioAtomSpace) - { return this->AddNode(ev, ioAtomSpace->SpaceScope(), ioAtomSpace); } - // the AddAtomSpace() boolean return equals ev->Good(). - - mork_bool CutAtomSpace(morkEnv* ev, mork_scope inScope) - { return this->CutNode(ev, inScope); } - // The CutAtomSpace() boolean return indicates whether removal happened. - - morkAtomSpace* GetAtomSpace(morkEnv* ev, mork_scope inScope) - { return (morkAtomSpace*) this->GetNode(ev, inScope); } - // Note the returned space does NOT have an increase in refcount for this. - - mork_num CutAllAtomSpaces(morkEnv* ev) - { return this->CutAllNodes(ev); } - // CutAllAtomSpaces() releases all the referenced table values. -}; - -class morkAtomSpaceMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkAtomSpaceMapIter( ) : morkMapIter() { } - void InitAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* - FirstAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace) - { return this->First(ev, outScope, outAtomSpace); } - - mork_change* - NextAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace) - { return this->Next(ev, outScope, outAtomSpace); } - - mork_change* - HereAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace) - { return this->Here(ev, outScope, outAtomSpace); } - - mork_change* - CutHereAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace) - { return this->CutHere(ev, outScope, outAtomSpace); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKATOMSPACE_ */ - diff --git a/db/mork/src/morkBead.cpp b/db/mork/src/morkBead.cpp deleted file mode 100644 index f55155d544fb..000000000000 --- a/db/mork/src/morkBead.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKBEAD_ -#include "morkBead.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkBead::CloseMorkNode(morkEnv* ev) // CloseBead() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseBead(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkBead::~morkBead() // assert CloseBead() executed earlier -{ - MORK_ASSERT(mBead_Color==0 || mNode_Usage == morkUsage_kStack ); -} - -/*public non-poly*/ -morkBead::morkBead(mork_color inBeadColor) -: morkNode( morkUsage_kStack ) -, mBead_Color( inBeadColor ) -{ -} - -/*public non-poly*/ -morkBead::morkBead(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor) -: morkNode( inUsage, ioHeap ) -, mBead_Color( inBeadColor ) -{ -} - -/*public non-poly*/ -morkBead::morkBead(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, mork_color inBeadColor) -: morkNode(ev, inUsage, ioHeap) -, mBead_Color( inBeadColor ) -{ - if ( ev->Good() ) - { - if ( ev->Good() ) - mNode_Derived = morkDerived_kBead; - } -} - -/*public non-poly*/ void -morkBead::CloseBead(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - if ( !this->IsShutNode() ) - { - mBead_Color = 0; - this->MarkShut(); - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkBeadMap::CloseMorkNode(morkEnv* ev) // CloseBeadMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseBeadMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkBeadMap::~morkBeadMap() // assert CloseBeadMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkBeadMap::morkBeadMap(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkMap(ev, inUsage, ioHeap, sizeof(morkBead*), /*inValSize*/ 0, - /*slotCount*/ 11, ioSlotHeap, /*holdChanges*/ morkBool_kFalse) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kBeadMap; -} - -/*public non-poly*/ void -morkBeadMap::CloseBeadMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CutAllBeads(ev); - this->CloseMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -mork_bool -morkBeadMap::AddBead(morkEnv* ev, morkBead* ioBead) - // the AddBead() boolean return equals ev->Good(). -{ - if ( ioBead && ev->Good() ) - { - morkBead* oldBead = 0; // old key in the map - - mork_bool put = this->Put(ev, &ioBead, /*val*/ (void*) 0, - /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0); - - if ( put ) // replaced an existing key? - { - if ( oldBead != ioBead ) // new bead was not already in table? - ioBead->AddStrongRef(ev); // now there's another ref - - if ( oldBead && oldBead != ioBead ) // need to release old node? - oldBead->CutStrongRef(ev); - } - else - ioBead->AddStrongRef(ev); // another ref if not already in table - } - else if ( !ioBead ) - ev->NilPointerError(); - - return ev->Good(); -} - -mork_bool -morkBeadMap::CutBead(morkEnv* ev, mork_color inColor) -{ - morkBead* oldBead = 0; // old key in the map - morkBead bead(inColor); - morkBead* key = &bead; - - mork_bool outCutNode = this->Cut(ev, &key, - /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0); - - if ( oldBead ) - oldBead->CutStrongRef(ev); - - bead.CloseBead(ev); - return outCutNode; -} - -morkBead* -morkBeadMap::GetBead(morkEnv* ev, mork_color inColor) - // Note the returned bead does NOT have an increase in refcount for this. -{ - morkBead* oldBead = 0; // old key in the map - morkBead bead(inColor); - morkBead* key = &bead; - - this->Get(ev, &key, /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0); - - bead.CloseBead(ev); - return oldBead; -} - -mork_num -morkBeadMap::CutAllBeads(morkEnv* ev) - // CutAllBeads() releases all the referenced beads. -{ - mork_num outSlots = mMap_Slots; - - morkBeadMapIter i(ev, this); - morkBead* b = i.FirstBead(ev); - - while ( b ) - { - b->CutStrongRef(ev); - i.CutHereBead(ev); - b = i.NextBead(ev); - } - - return outSlots; -} - - -// { ===== begin morkMap poly interface ===== -/*virtual*/ mork_bool -morkBeadMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const -{ - MORK_USED_1(ev); - return (*(const morkBead**) inKeyA)->BeadEqual( - *(const morkBead**) inKeyB); -} - -/*virtual*/ mork_u4 -morkBeadMap::Hash(morkEnv* ev, const void* inKey) const -{ - MORK_USED_1(ev); - return (*(const morkBead**) inKey)->BeadHash(); -} -// } ===== end morkMap poly interface ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -morkBead* morkBeadMapIter::FirstBead(morkEnv* ev) -{ - morkBead* bead = 0; - this->First(ev, &bead, /*val*/ (void*) 0); - return bead; -} - -morkBead* morkBeadMapIter::NextBead(morkEnv* ev) -{ - morkBead* bead = 0; - this->Next(ev, &bead, /*val*/ (void*) 0); - return bead; -} - -morkBead* morkBeadMapIter::HereBead(morkEnv* ev) -{ - morkBead* bead = 0; - this->Here(ev, &bead, /*val*/ (void*) 0); - return bead; -} - -void morkBeadMapIter::CutHereBead(morkEnv* ev) -{ - this->CutHere(ev, /*key*/ (void*) 0, /*val*/ (void*) 0); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkBeadProbeMap::CloseMorkNode(morkEnv* ev) // CloseBeadProbeMap() if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseBeadProbeMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkBeadProbeMap::~morkBeadProbeMap() // assert CloseBeadProbeMap() earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - - -/*public non-poly*/ -morkBeadProbeMap::morkBeadProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkProbeMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkBead*), /*inValSize*/ 0, - ioSlotHeap, /*startSlotCount*/ 11, - /*inZeroIsClearKey*/ morkBool_kTrue) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kBeadProbeMap; -} - -/*public non-poly*/ void -morkBeadProbeMap::CloseBeadProbeMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CutAllBeads(ev); - this->CloseProbeMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b) -morkBeadProbeMap::MapTest(morkEnv* ev, const void* inMapKey, - const void* inAppKey) const -{ - MORK_USED_1(ev); - const morkBead* key = *(const morkBead**) inMapKey; - if ( key ) - { - mork_bool hit = key->BeadEqual(*(const morkBead**) inAppKey); - return ( hit ) ? morkTest_kHit : morkTest_kMiss; - } - else - return morkTest_kVoid; -} - -/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b) -morkBeadProbeMap::MapHash(morkEnv* ev, const void* inAppKey) const -{ - const morkBead* key = *(const morkBead**) inAppKey; - if ( key ) - return key->BeadHash(); - else - { - ev->NilPointerWarning(); - return 0; - } -} - -/*virtual*/ mork_u4 -morkBeadProbeMap::ProbeMapHashMapKey(morkEnv* ev, - const void* inMapKey) const -{ - const morkBead* key = *(const morkBead**) inMapKey; - if ( key ) - return key->BeadHash(); - else - { - ev->NilPointerWarning(); - return 0; - } -} - -mork_bool -morkBeadProbeMap::AddBead(morkEnv* ev, morkBead* ioBead) -{ - if ( ioBead && ev->Good() ) - { - morkBead* bead = 0; // old key in the map - - mork_bool put = this->MapAtPut(ev, &ioBead, /*val*/ (void*) 0, - /*key*/ &bead, /*val*/ (void*) 0); - - if ( put ) // replaced an existing key? - { - if ( bead != ioBead ) // new bead was not already in table? - ioBead->AddStrongRef(ev); // now there's another ref - - if ( bead && bead != ioBead ) // need to release old node? - bead->CutStrongRef(ev); - } - else - ioBead->AddStrongRef(ev); // now there's another ref - } - else if ( !ioBead ) - ev->NilPointerError(); - - return ev->Good(); -} - -morkBead* -morkBeadProbeMap::GetBead(morkEnv* ev, mork_color inColor) -{ - morkBead* oldBead = 0; // old key in the map - morkBead bead(inColor); - morkBead* key = &bead; - - this->MapAt(ev, &key, &oldBead, /*val*/ (void*) 0); - - bead.CloseBead(ev); - return oldBead; -} - -mork_num -morkBeadProbeMap::CutAllBeads(morkEnv* ev) - // CutAllBeads() releases all the referenced bead values. -{ - mork_num outSlots = sMap_Slots; - - morkBeadProbeMapIter i(ev, this); - morkBead* b = i.FirstBead(ev); - - while ( b ) - { - b->CutStrongRef(ev); - b = i.NextBead(ev); - } - this->MapCutAll(ev); - - return outSlots; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - diff --git a/db/mork/src/morkBead.h b/db/mork/src/morkBead.h deleted file mode 100644 index 02799405ddae..000000000000 --- a/db/mork/src/morkBead.h +++ /dev/null @@ -1,277 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKBEAD_ -#define _MORKBEAD_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKPROBEMAP_ -#include "morkProbeMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kBead /*i*/ 0x426F /* ascii 'Bo' */ - -/*| morkBead: subclass of morkNode that adds knowledge of db suite factory -**| and containing port to those objects that are exposed as instances of -**| nsIMdbBead in the public interface. -|*/ -class morkBead : public morkNode { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - - mork_color mBead_Color; // ID for this bead - -public: // Hash() and Equal() for bead maps are same for all subclasses: - - mork_u4 BeadHash() const { return (mork_u4) mBead_Color; } - mork_bool BeadEqual(const morkBead* inBead) const - { return ( mBead_Color == inBead->mBead_Color); } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseBead() only if open - virtual ~morkBead(); // assert that CloseBead() executed earlier - -public: // special case for stack construction for map usage: - morkBead(mork_color inBeadColor); // stack-based bead instance - -protected: // special case for morkObject: - morkBead(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor); - -public: // morkEnv construction & destruction - morkBead(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor); - void CloseBead(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkBead(const morkBead& other); - morkBead& operator=(const morkBead& other); - -public: // dynamic type identification - mork_bool IsBead() const - { return IsNode() && mNode_Derived == morkDerived_kBead; } -// } ===== end morkNode methods ===== - - // void NewNilHandleError(morkEnv* ev); // mBead_Handle is nil - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakBead(morkBead* me, - morkEnv* ev, morkBead** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongBead(morkBead* me, - morkEnv* ev, morkBead** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kBeadMap /*i*/ 0x744D /* ascii 'bM' */ - -/*| morkBeadMap: maps bead -> bead (key only using mBead_Color) -|*/ -class morkBeadMap : public morkMap { - - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseBeadMap() only if open - virtual ~morkBeadMap(); // assert that CloseBeadMap() executed earlier - -public: // morkMap construction & destruction - morkBeadMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseBeadMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsBeadMap() const - { return IsNode() && mNode_Derived == morkDerived_kBeadMap; } -// } ===== end morkNode methods ===== - -// { ===== begin morkMap poly interface ===== -public: - virtual mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - - virtual mork_u4 // some integer function of *((mork_u4*) inKey) - Hash(morkEnv* ev, const void* inKey) const; -// } ===== end morkMap poly interface ===== - -public: // other map methods - - mork_bool AddBead(morkEnv* ev, morkBead* ioBead); - // the AddBead() boolean return equals ev->Good(). - - mork_bool CutBead(morkEnv* ev, mork_color inColor); - // The CutBead() boolean return indicates whether removal happened. - - morkBead* GetBead(morkEnv* ev, mork_color inColor); - // Note the returned bead does NOT have an increase in refcount for this. - - mork_num CutAllBeads(morkEnv* ev); - // CutAllBeads() releases all the referenced beads. -}; - -class morkBeadMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkBeadMapIter(morkEnv* ev, morkBeadMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkBeadMapIter( ) : morkMapIter() { } - void InitBeadMapIter(morkEnv* ev, morkBeadMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - morkBead* FirstBead(morkEnv* ev); - morkBead* NextBead(morkEnv* ev); - morkBead* HereBead(morkEnv* ev); - void CutHereBead(morkEnv* ev); - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kBeadProbeMap /*i*/ 0x6D74 /* ascii 'mb' */ - -/*| morkBeadProbeMap: maps bead -> bead (key only using mBead_Color) -|*/ -class morkBeadProbeMap : public morkProbeMap { - - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseBeadProbeMap() only if open - virtual ~morkBeadProbeMap(); // assert that CloseBeadProbeMap() executed earlier - -public: // morkMap construction & destruction - morkBeadProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseBeadProbeMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsBeadProbeMap() const - { return IsNode() && mNode_Derived == morkDerived_kBeadProbeMap; } -// } ===== end morkNode methods ===== - - // { ===== begin morkProbeMap methods ===== -public: - virtual mork_test // hit(a,b) implies hash(a) == hash(b) - MapTest(morkEnv* ev, const void* inMapKey, const void* inAppKey) const; - - virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) - MapHash(morkEnv* ev, const void* inAppKey) const; - - virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const; - - // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); - - // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - // void* ioMapKey, mork_count inKeyCount); // array of keys inside map - - // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - // const void* inAppKey, const void* inAppVal, // (key,val) outside map - // void* outMapKey, void* outMapVal); // (key,val) inside map - - // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - // const void* inMapKey, const void* inMapVal, // (key,val) inside map - // void* outAppKey, void* outAppVal) const; // (key,val) outside map - // } ===== end morkProbeMap methods ===== - -public: // other map methods - - mork_bool AddBead(morkEnv* ev, morkBead* ioBead); - // the AddBead() boolean return equals ev->Good(). - - morkBead* GetBead(morkEnv* ev, mork_color inColor); - // Note the returned bead does NOT have an increase in refcount for this. - - mork_num CutAllBeads(morkEnv* ev); - // CutAllBeads() releases all the referenced bead values. -}; - -class morkBeadProbeMapIter: public morkProbeMapIter { // typesafe wrapper class - -public: - morkBeadProbeMapIter(morkEnv* ev, morkBeadProbeMap* ioMap) - : morkProbeMapIter(ev, ioMap) { } - - morkBeadProbeMapIter( ) : morkProbeMapIter() { } - void InitBeadProbeMapIter(morkEnv* ev, morkBeadProbeMap* ioMap) - { this->InitProbeMapIter(ev, ioMap); } - - morkBead* FirstBead(morkEnv* ev) - { return (morkBead*) this->IterFirstKey(ev); } - - morkBead* NextBead(morkEnv* ev) - { return (morkBead*) this->IterNextKey(ev); } - - morkBead* HereBead(morkEnv* ev) - { return (morkBead*) this->IterHereKey(ev); } - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKBEAD_ */ diff --git a/db/mork/src/morkBlob.cpp b/db/mork/src/morkBlob.cpp deleted file mode 100644 index 0e458eeabefa..000000000000 --- a/db/mork/src/morkBlob.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*static*/ void -morkBuf::NilBufBodyError(morkEnv* ev) -{ - ev->NewError("nil mBuf_Body"); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*static*/ void -morkBlob::BlobFillOverSizeError(morkEnv* ev) -{ - ev->NewError("mBuf_Fill > mBlob_Size"); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -mork_bool -morkBlob::GrowBlob(morkEnv* ev, nsIMdbHeap* ioHeap, mork_size inNewSize) -{ - if ( ioHeap ) - { - if ( !mBuf_Body ) // no body? implies zero sized? - mBlob_Size = 0; - - if ( mBuf_Fill > mBlob_Size ) // fill more than size? - { - ev->NewWarning("mBuf_Fill > mBlob_Size"); - mBuf_Fill = mBlob_Size; - } - - if ( inNewSize > mBlob_Size ) // need to allocate larger blob? - { - mork_u1* body = 0; - ioHeap->Alloc(ev->AsMdbEnv(), inNewSize, (void**) &body); - if ( body && ev->Good() ) - { - void* oldBody = mBuf_Body; - if ( mBlob_Size ) // any old content to transfer? - MORK_MEMCPY(body, oldBody, mBlob_Size); - - mBlob_Size = inNewSize; // install new size - mBuf_Body = body; // install new body - - if ( oldBody ) // need to free old buffer body? - ioHeap->Free(ev->AsMdbEnv(), oldBody); - } - } - } - else - ev->NilPointerError(); - - if ( ev->Good() && mBlob_Size < inNewSize ) - ev->NewError("mBlob_Size < inNewSize"); - - return ev->Good(); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -morkCoil::morkCoil(morkEnv* ev, nsIMdbHeap* ioHeap) -{ - mBuf_Body = 0; - mBuf_Fill = 0; - mBlob_Size = 0; - mText_Form = 0; - mCoil_Heap = ioHeap; - if ( !ioHeap ) - ev->NilPointerError(); -} - -void -morkCoil::CloseCoil(morkEnv* ev) -{ - void* body = mBuf_Body; - nsIMdbHeap* heap = mCoil_Heap; - - mBuf_Body = 0; - mCoil_Heap = 0; - - if ( body && heap ) - { - heap->Free(ev->AsMdbEnv(), body); - } -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkBlob.h b/db/mork/src/morkBlob.h deleted file mode 100644 index cd4e4b9cc24b..000000000000 --- a/db/mork/src/morkBlob.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKBLOB_ -#define _MORKBLOB_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| Buf: the minimum needed to describe location and content length. -**| This is typically only enough to read from this buffer, since -**| one cannot write effectively without knowing the size of a buf. -|*/ -class morkBuf { // subset of nsIMdbYarn slots -public: - void* mBuf_Body; // space for holding any binary content - mork_fill mBuf_Fill; // logical content in Buf in bytes - -public: - morkBuf() { } - morkBuf(const void* ioBuf, mork_fill inFill) - : mBuf_Body((void*) ioBuf), mBuf_Fill(inFill) { } - - void ClearBufFill() { mBuf_Fill = 0; } - - static void NilBufBodyError(morkEnv* ev); - -private: // copying is not allowed - morkBuf(const morkBuf& other); - morkBuf& operator=(const morkBuf& other); -}; - -/*| Blob: a buffer with an associated size, to increase known buf info -**| to include max capacity in addition to buf location and content. -**| This form factor allows us to allocate a vector of such blobs, -**| which can share the same managing heap stored elsewhere, and that -**| is why we don't include a pointer to a heap in this blob class. -|*/ -class morkBlob : public morkBuf { // greater subset of nsIMdbYarn slots - - // void* mBuf_Body; // space for holding any binary content - // mdb_fill mBuf_Fill; // logical content in Buf in bytes -public: - mork_size mBlob_Size; // physical size of Buf in bytes - -public: - morkBlob() { } - morkBlob(const void* ioBuf, mork_fill inFill, mork_size inSize) - : morkBuf(ioBuf, inFill), mBlob_Size(inSize) { } - - static void BlobFillOverSizeError(morkEnv* ev); - -public: - mork_bool GrowBlob(morkEnv* ev, nsIMdbHeap* ioHeap, - mork_size inNewSize); - -private: // copying is not allowed - morkBlob(const morkBlob& other); - morkBlob& operator=(const morkBlob& other); - -}; - -/*| Text: a blob with an associated charset annotation, where the -**| charset actually includes the general notion of typing, and not -**| just a specification of character set alone; we want to permit -**| arbitrary charset annotations for ad hoc binary types as well. -**| (We avoid including a nsIMdbHeap pointer in morkText for the same -**| reason morkBlob does: we want minimal size vectors of morkText.) -|*/ -class morkText : public morkBlob { // greater subset of nsIMdbYarn slots - - // void* mBuf_Body; // space for holding any binary content - // mdb_fill mBuf_Fill; // logical content in Buf in bytes - // mdb_size mBlob_Size; // physical size of Buf in bytes - -public: - mork_cscode mText_Form; // charset format encoding - - morkText() { } - -private: // copying is not allowed - morkText(const morkText& other); - morkText& operator=(const morkText& other); -}; - -/*| Coil: a text with an associated nsIMdbHeap instance that provides -**| all memory management for the space pointed to by mBuf_Body. (This -**| was the hardest type to give a name in this small class hierarchy, -**| because it's hard to characterize self-management of one's space.) -**| A coil is a self-contained blob that knows how to grow itself as -**| necessary to hold more content when necessary. Coil descends from -**| morkText to include the mText_Form slot, even though this won't be -**| needed always, because we are not as concerned about the overall -**| size of this particular Coil object (if we were concerned about -**| the size of an array of Coil instances, we would not bother with -**| a separate heap pointer for each of them). -**| -**|| A coil makes a good medium in which to stream content as a sink, -**| so we will have a subclass of morkSink called morkCoil that -**| will stream bytes into this self-contained coil object. The name -**| of this morkCoil class derives more from this intended usage than -**| from anything else. The Mork code to parse db content will use -**| coils with associated sinks to accumulate parsed strings. -**| -**|| Heap: this is the heap used for memory allocation. This instance -**| is NOT refcounted, since this coil always assumes the heap is held -**| through a reference elsewhere (for example, through the same object -**| that contains or holds the coil itself. This lack of refcounting -**| is consistent with the fact that morkCoil itself is not refcounted, -**| and is not intended for use as a standalone object. -|*/ -class morkCoil : public morkText { // self-managing text blob object - - // void* mBuf_Body; // space for holding any binary content - // mdb_fill mBuf_Fill; // logical content in Buf in bytes - // mdb_size mBlob_Size; // physical size of Buf in bytes - // mdb_cscode mText_Form; // charset format encoding -public: - nsIMdbHeap* mCoil_Heap; // storage manager for mBuf_Body pointer - -public: - morkCoil(morkEnv* ev, nsIMdbHeap* ioHeap); - - void CloseCoil(morkEnv* ev); - - mork_bool GrowCoil(morkEnv* ev, mork_size inNewSize) - { return this->GrowBlob(ev, mCoil_Heap, inNewSize); } - -private: // copying is not allowed - morkCoil(const morkCoil& other); - morkCoil& operator=(const morkCoil& other); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKBLOB_ */ diff --git a/db/mork/src/morkBuilder.cpp b/db/mork/src/morkBuilder.cpp deleted file mode 100644 index 7dc50393cdee..000000000000 --- a/db/mork/src/morkBuilder.cpp +++ /dev/null @@ -1,1068 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKPARSER_ -#include "morkParser.h" -#endif - -#ifndef _MORKBUILDER_ -#include "morkBuilder.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkBuilder::CloseMorkNode(morkEnv* ev) // CloseBuilder() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseBuilder(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkBuilder::~morkBuilder() // assert CloseBuilder() executed earlier -{ - MORK_ASSERT(mBuilder_Store==0); - MORK_ASSERT(mBuilder_Row==0); - MORK_ASSERT(mBuilder_Table==0); - MORK_ASSERT(mBuilder_Cell==0); - MORK_ASSERT(mBuilder_RowSpace==0); - MORK_ASSERT(mBuilder_AtomSpace==0); -} - -/*public non-poly*/ -morkBuilder::morkBuilder(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkStream* ioStream, mdb_count inBytesPerParseSegment, - nsIMdbHeap* ioSlotHeap, morkStore* ioStore) - -: morkParser(ev, inUsage, ioHeap, ioStream, - inBytesPerParseSegment, ioSlotHeap) - -, mBuilder_Store( 0 ) - -, mBuilder_Table( 0 ) -, mBuilder_Row( 0 ) -, mBuilder_Cell( 0 ) - -, mBuilder_RowSpace( 0 ) -, mBuilder_AtomSpace( 0 ) - -, mBuilder_OidAtomSpace( 0 ) -, mBuilder_ScopeAtomSpace( 0 ) - -, mBuilder_PortForm( 0 ) -, mBuilder_PortRowScope( (mork_scope) 'r' ) -, mBuilder_PortAtomScope( (mork_scope) 'v' ) - -, mBuilder_TableForm( 0 ) -, mBuilder_TableRowScope( (mork_scope) 'r' ) -, mBuilder_TableAtomScope( (mork_scope) 'v' ) -, mBuilder_TableKind( 0 ) - -, mBuilder_TablePriority( morkPriority_kLo ) -, mBuilder_TableIsUnique( morkBool_kFalse ) -, mBuilder_TableIsVerbose( morkBool_kFalse ) -, mBuilder_TablePadByte( 0 ) - -, mBuilder_RowForm( 0 ) -, mBuilder_RowRowScope( (mork_scope) 'r' ) -, mBuilder_RowAtomScope( (mork_scope) 'v' ) - -, mBuilder_CellForm( 0 ) -, mBuilder_CellAtomScope( (mork_scope) 'v' ) - -, mBuilder_DictForm( 0 ) -, mBuilder_DictAtomScope( (mork_scope) 'v' ) - -, mBuilder_MetaTokenSlot( 0 ) - -, mBuilder_DoCutRow( morkBool_kFalse ) -, mBuilder_DoCutCell( morkBool_kFalse ) -, mBuilder_CellsVecFill( 0 ) -{ - if ( ev->Good() ) - { - if ( ioStore ) - { - morkStore::SlotWeakStore(ioStore, ev, &mBuilder_Store); - if ( ev->Good() ) - mNode_Derived = morkDerived_kBuilder; - } - else - ev->NilPointerError(); - } - -} - -/*public non-poly*/ void -morkBuilder::CloseBuilder(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mBuilder_Row = 0; - mBuilder_Cell = 0; - mBuilder_MetaTokenSlot = 0; - - morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table); - morkStore::SlotWeakStore((morkStore*) 0, ev, &mBuilder_Store); - - morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev, - &mBuilder_RowSpace); - - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mBuilder_AtomSpace); - - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mBuilder_OidAtomSpace); - - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mBuilder_ScopeAtomSpace); - this->CloseParser(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkBuilder::NonBuilderTypeError(morkEnv* ev) -{ - ev->NewError("non morkBuilder"); -} - -/*static*/ void -morkBuilder::NilBuilderCellError(morkEnv* ev) -{ - ev->NewError("nil mBuilder_Cell"); -} - -/*static*/ void -morkBuilder::NilBuilderRowError(morkEnv* ev) -{ - ev->NewError("nil mBuilder_Row"); -} - -/*static*/ void -morkBuilder::NilBuilderTableError(morkEnv* ev) -{ - ev->NewError("nil mBuilder_Table"); -} - -/*static*/ void -morkBuilder::NonColumnSpaceScopeError(morkEnv* ev) -{ - ev->NewError("column space != 'c'"); -} - -void -morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch, - const char* inKind) -{ - MORK_USED_2(inGlitch,inKind); - ev->NewWarning("parsing glitch"); -} - -/*virtual*/ void -morkBuilder::MidToYarn(morkEnv* ev, - const morkMid& inMid, // typically an alias to concat with strings - mdbYarn* outYarn) -// The parser might ask that some aliases be turned into yarns, so they -// can be concatenated into longer blobs under some circumstances. This -// is an alternative to using a long and complex callback for many parts -// for a single cell value. -{ - mBuilder_Store->MidToYarn(ev, inMid, outYarn); -} - -/*virtual*/ void -morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace) -// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd -// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch -// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row -{ - MORK_USED_2(ev,inPlace); - // mParser_InPort = morkBool_kTrue; - mBuilder_PortForm = 0; - mBuilder_PortRowScope = (mork_scope) 'r'; - mBuilder_PortAtomScope = (mork_scope) 'v'; -} - -/*virtual*/ void -morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "port"); -} - -/*virtual*/ void -morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd -{ - MORK_USED_2(ev,inSpan); - // ev->StubMethodOnlyError(); - // nothing to do? - // mParser_InPort = morkBool_kFalse; -} - -/*virtual*/ void -morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) -{ - MORK_USED_1(inPlace); - mParser_InGroup = morkBool_kTrue; - mork_pos startPos = inPlace.mPlace_Pos; - - morkStore* store = mBuilder_Store; - if ( store ) - { - if ( inGid >= store->mStore_CommitGroupIdentity ) - store->mStore_CommitGroupIdentity = inGid + 1; - - if ( !store->mStore_FirstCommitGroupPos ) - store->mStore_FirstCommitGroupPos = startPos; - else if ( !store->mStore_SecondCommitGroupPos ) - store->mStore_SecondCommitGroupPos = startPos; - } -} - -/*virtual*/ void -morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "group"); -} - -/*virtual*/ void -morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) -{ - MORK_USED_2(ev,inSpan); - // mParser_InGroup = morkBool_kFalse; - // ev->StubMethodOnlyError(); -} - -/*virtual*/ void -morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) -{ - MORK_USED_1(inSpan); - // mParser_InGroup = morkBool_kFalse; - ev->StubMethodOnlyError(); -} - -/*virtual*/ void -morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_change inChange) -{ - MORK_USED_3(inMid,inPlace,inChange); - // mParser_InPortRow = morkBool_kTrue; - ev->StubMethodOnlyError(); -} - -/*virtual*/ void -morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "port row"); -} - -/*virtual*/ void -morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) -{ - MORK_USED_1(inSpan); - // mParser_InPortRow = morkBool_kFalse; - ev->StubMethodOnlyError(); -} - -/*virtual*/ void -morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllRows) -// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd -// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch -// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd -// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd -// mp:MetaItem ::= mp:Cell | OnMetaGlitch -{ - MORK_USED_1(inPlace); - // mParser_InTable = morkBool_kTrue; - mBuilder_TableForm = mBuilder_PortForm; - mBuilder_TableRowScope = mBuilder_PortRowScope; - mBuilder_TableAtomScope = mBuilder_PortAtomScope; - mBuilder_TableKind = morkStore_kNoneToken; - - mBuilder_TablePriority = morkPriority_kLo; - mBuilder_TableIsUnique = morkBool_kFalse; - mBuilder_TableIsVerbose = morkBool_kFalse; - - morkTable* table = mBuilder_Store->MidToTable(ev, inMid); - morkTable::SlotStrongTable(table, ev, &mBuilder_Table); - if ( table ) - { - if ( table->mTable_RowSpace ) - mBuilder_TableRowScope = table->mTable_RowSpace->SpaceScope(); - - if ( inCutAllRows ) - table->CutAllRows(ev); - } -} - -/*virtual*/ void -morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "table"); -} - -/*virtual*/ void -morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd -{ - MORK_USED_1(inSpan); - // mParser_InTable = morkBool_kFalse; - if ( mBuilder_Table ) - { - mBuilder_Table->mTable_Priority = mBuilder_TablePriority; - - if ( mBuilder_TableIsUnique ) - mBuilder_Table->SetTableUnique(); - - if ( mBuilder_TableIsVerbose ) - mBuilder_Table->SetTableVerbose(); - - morkTable::SlotStrongTable((morkTable*) 0, ev, &mBuilder_Table); - } - else - this->NilBuilderTableError(ev); - - mBuilder_Row = 0; - mBuilder_Cell = 0; - - - mBuilder_TablePriority = morkPriority_kLo; - mBuilder_TableIsUnique = morkBool_kFalse; - mBuilder_TableIsVerbose = morkBool_kFalse; - - if ( mBuilder_TableKind == morkStore_kNoneToken ) - ev->NewError("missing table kind"); - - mBuilder_CellAtomScope = mBuilder_RowAtomScope = - mBuilder_TableAtomScope = mBuilder_PortAtomScope; - - mBuilder_DoCutCell = morkBool_kFalse; - mBuilder_DoCutRow = morkBool_kFalse; -} - -/*virtual*/ void -morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace) -// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd -// mp:MetaItem ::= mp:Cell | OnMetaGlitch -// mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_2(ev,inPlace); - // mParser_InMeta = morkBool_kTrue; - -} - -/*virtual*/ void -morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "meta"); -} - -/*virtual*/ void -morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd -{ - MORK_USED_2(ev,inSpan); - // mParser_InMeta = morkBool_kFalse; -} - -/*virtual*/ void -morkBuilder::OnMinusRow(morkEnv* ev) -{ - MORK_USED_1(ev); - mBuilder_DoCutRow = morkBool_kTrue; -} - -/*virtual*/ void -morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllCols) -// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd -// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch -// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd -// mp:Row ::= OnMinusRow? OnNewRow mp:RowItem* OnRowEnd -// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch -// mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inPlace); - // mParser_InRow = morkBool_kTrue; - - mBuilder_CellForm = mBuilder_RowForm = mBuilder_TableForm; - mBuilder_CellAtomScope = mBuilder_RowAtomScope = mBuilder_TableAtomScope; - mBuilder_RowRowScope = mBuilder_TableRowScope; - morkStore* store = mBuilder_Store; - - if ( !inMid.mMid_Buf && !inMid.mMid_Oid.mOid_Scope ) - { - morkMid mid(inMid); - mid.mMid_Oid.mOid_Scope = mBuilder_RowRowScope; - mBuilder_Row = store->MidToRow(ev, mid); - } - else - { - mBuilder_Row = store->MidToRow(ev, inMid); - } - morkRow* row = mBuilder_Row; - if ( row && inCutAllCols ) - { - row->CutAllColumns(ev); - } - - morkTable* table = mBuilder_Table; - if ( table ) - { - if ( row ) - { - if ( mParser_InMeta ) - { - morkRow* metaRow = table->mTable_MetaRow; - if ( !metaRow ) - { - table->mTable_MetaRow = row; - table->mTable_MetaRowOid = row->mRow_Oid; - row->AddRowGcUse(ev); - } - else if ( metaRow != row ) // not identical? - ev->NewError("duplicate table meta row"); - } - else - { - if ( mBuilder_DoCutRow ) - table->CutRow(ev, row); - else - table->AddRow(ev, row); - } - } - } - // else // it is now okay to have rows outside a table: - // this->NilBuilderTableError(ev); - - mBuilder_DoCutRow = morkBool_kFalse; -} - -/*virtual*/ void -morkBuilder::OnRowPos(morkEnv* ev, mork_pos inRowPos) -{ - if ( mBuilder_Row && mBuilder_Table && !mParser_InMeta ) - { - mork_pos hintFromPos = 0; // best hint when we don't know position - mBuilder_Table->MoveRow(ev, mBuilder_Row, hintFromPos, inRowPos); - } -} - -/*virtual*/ void -morkBuilder::OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "row"); -} - -void -morkBuilder::FlushBuilderCells(morkEnv* ev) -{ - if ( mBuilder_Row ) - { - morkPool* pool = mBuilder_Store->StorePool(); - morkCell* cells = mBuilder_CellsVec; - mork_fill fill = mBuilder_CellsVecFill; - mBuilder_Row->TakeCells(ev, cells, fill, mBuilder_Store); - - morkCell* end = cells + fill; - --cells; // prepare for preincrement - while ( ++cells < end ) - { - if ( cells->mCell_Atom ) - cells->SetAtom(ev, (morkAtom*) 0, pool); - } - mBuilder_CellsVecFill = 0; - } - else - this->NilBuilderRowError(ev); -} - -/*virtual*/ void -morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Row ::= OnMinusRow? OnNewRow mp:RowItem* OnRowEnd -{ - MORK_USED_1(inSpan); - // mParser_InRow = morkBool_kFalse; - if ( mBuilder_Row ) - { - this->FlushBuilderCells(ev); - } - else - this->NilBuilderRowError(ev); - - mBuilder_Row = 0; - mBuilder_Cell = 0; - - mBuilder_DoCutCell = morkBool_kFalse; - mBuilder_DoCutRow = morkBool_kFalse; -} - -/*virtual*/ void -morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace) -// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd -// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch -{ - MORK_USED_2(ev,inPlace); - // mParser_InDict = morkBool_kTrue; - - mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm; - mBuilder_CellAtomScope = mBuilder_DictAtomScope = mBuilder_PortAtomScope; -} - -/*virtual*/ void -morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "dict"); -} - -/*virtual*/ void -morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd -{ - MORK_USED_2(ev,inSpan); - // mParser_InDict = morkBool_kFalse; - - mBuilder_DictForm = 0; - mBuilder_DictAtomScope = 0; -} - -/*virtual*/ void -morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) -{ - MORK_USED_1(inSpan); - if ( mParser_InDict ) - { - morkMid mid = inMid; // local copy for modification - mid.mMid_Oid.mOid_Scope = mBuilder_DictAtomScope; - mBuilder_Store->AddAlias(ev, mid, mBuilder_DictForm); - } - else - ev->NewError("alias not in dict"); -} - -/*virtual*/ void -morkBuilder::OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "alias"); -} - - -morkCell* -morkBuilder::AddBuilderCell(morkEnv* ev, - const morkMid& inMid, mork_change inChange) -{ - morkCell* outCell = 0; - mork_column column = inMid.mMid_Oid.mOid_Id; - - if ( ev->Good() ) - { - if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize ) - this->FlushBuilderCells(ev); - if ( ev->Good() ) - { - if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize ) - { - mork_fill indx = mBuilder_CellsVecFill++; - outCell = mBuilder_CellsVec + indx; - outCell->SetColumnAndChange(column, inChange); - outCell->mCell_Atom = 0; - } - else - ev->NewError("out of builder cells"); - } - } - return outCell; -} - -/*virtual*/ void -morkBuilder::OnMinusCell(morkEnv* ev) -{ - MORK_USED_1(ev); - mBuilder_DoCutCell = morkBool_kTrue; -} - -/*virtual*/ void -morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace, - const morkMid* inMid, const morkBuf* inBuf) -// Exactly one of inMid and inBuf is nil, and the other is non-nil. -// When hex ID syntax is used for a column, then inMid is not nil, and -// when a naked string names a column, then inBuf is not nil. - - // mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd - // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch - // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inPlace); - // mParser_InCell = morkBool_kTrue; - - mork_change cellChange = ( mBuilder_DoCutCell )? - morkChange_kCut : morkChange_kAdd; - - mBuilder_DoCutCell = morkBool_kFalse; - - mBuilder_CellAtomScope = mBuilder_RowAtomScope; - - mBuilder_Cell = 0; // nil until determined for a row - morkStore* store = mBuilder_Store; - mork_scope scope = morkStore_kColumnSpaceScope; - morkMid tempMid; // space for local and modifiable cell mid - morkMid* cellMid = &tempMid; // default to local if inMid==0 - - if ( inMid ) // mid parameter is actually provided? - { - *cellMid = *inMid; // bitwise copy for modifiable local mid - - if ( !cellMid->mMid_Oid.mOid_Scope ) - { - if ( cellMid->mMid_Buf ) - { - scope = store->BufToToken(ev, cellMid->mMid_Buf); - cellMid->mMid_Buf = 0; // don't do scope lookup again - ev->NewWarning("column mids need column scope"); - } - cellMid->mMid_Oid.mOid_Scope = scope; - } - } - else if ( inBuf ) // buf points to naked column string name? - { - cellMid->ClearMid(); - cellMid->mMid_Oid.mOid_Id = store->BufToToken(ev, inBuf); - cellMid->mMid_Oid.mOid_Scope = scope; // kColumnSpaceScope - } - else - ev->NilPointerError(); // either inMid or inBuf must be non-nil - - mork_column column = cellMid->mMid_Oid.mOid_Id; - - if ( mBuilder_Row && ev->Good() ) // this cell must be inside a row - { - // mBuilder_Cell = this->AddBuilderCell(ev, *cellMid, cellChange); - - if ( mBuilder_CellsVecFill >= morkBuilder_kCellsVecSize ) - this->FlushBuilderCells(ev); - if ( ev->Good() ) - { - if ( mBuilder_CellsVecFill < morkBuilder_kCellsVecSize ) - { - mork_fill ix = mBuilder_CellsVecFill++; - morkCell* cell = mBuilder_CellsVec + ix; - cell->SetColumnAndChange(column, cellChange); - - cell->mCell_Atom = 0; - mBuilder_Cell = cell; - } - else - ev->NewError("out of builder cells"); - } - } - - else if ( mParser_InMeta && ev->Good() ) // cell is in metainfo structure? - { - if ( scope == morkStore_kColumnSpaceScope ) - { - if ( mParser_InTable ) // metainfo for table? - { - if ( column == morkStore_kKindColumn ) - mBuilder_MetaTokenSlot = &mBuilder_TableKind; - else if ( column == morkStore_kStatusColumn ) - mBuilder_MetaTokenSlot = &mBuilder_TableStatus; - else if ( column == morkStore_kRowScopeColumn ) - mBuilder_MetaTokenSlot = &mBuilder_TableRowScope; - else if ( column == morkStore_kAtomScopeColumn ) - mBuilder_MetaTokenSlot = &mBuilder_TableAtomScope; - else if ( column == morkStore_kFormColumn ) - mBuilder_MetaTokenSlot = &mBuilder_TableForm; - } - else if ( mParser_InDict ) // metainfo for dict? - { - if ( column == morkStore_kAtomScopeColumn ) - mBuilder_MetaTokenSlot = &mBuilder_DictAtomScope; - else if ( column == morkStore_kFormColumn ) - mBuilder_MetaTokenSlot = &mBuilder_DictForm; - } - else if ( mParser_InRow ) // metainfo for row? - { - if ( column == morkStore_kAtomScopeColumn ) - mBuilder_MetaTokenSlot = &mBuilder_RowAtomScope; - else if ( column == morkStore_kRowScopeColumn ) - mBuilder_MetaTokenSlot = &mBuilder_RowRowScope; - else if ( column == morkStore_kFormColumn ) - mBuilder_MetaTokenSlot = &mBuilder_RowForm; - } - } - else - ev->NewWarning("expected column scope"); - } -} - -/*virtual*/ void -morkBuilder::OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch) -{ - this->LogGlitch(ev, inGlitch, "cell"); -} - -/*virtual*/ void -morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) -{ - morkCell* cell = mBuilder_Cell; - if ( cell ) - { - mBuilder_CellForm = inCharsetFormat; - } - else - this->NilBuilderCellError(ev); -} - -/*virtual*/ void -morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan) -// mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd -{ - MORK_USED_2(ev,inSpan); - // mParser_InCell = morkBool_kFalse; - - mBuilder_MetaTokenSlot = 0; - mBuilder_CellAtomScope = mBuilder_RowAtomScope; -} - -/*virtual*/ void -morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan, - const morkBuf& inBuf) -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inSpan); - morkStore* store = mBuilder_Store; - morkCell* cell = mBuilder_Cell; - if ( cell ) - { - mdbYarn yarn; - yarn.mYarn_Buf = inBuf.mBuf_Body; - yarn.mYarn_Fill = yarn.mYarn_Size = inBuf.mBuf_Fill; - yarn.mYarn_More = 0; - yarn.mYarn_Form = mBuilder_CellForm; - yarn.mYarn_Grow = 0; - morkAtom* atom = store->YarnToAtom(ev, &yarn, PR_TRUE /* create */); - cell->SetAtom(ev, atom, store->StorePool()); - } - else if ( mParser_InMeta ) - { - mork_token* metaSlot = mBuilder_MetaTokenSlot; - if ( metaSlot ) - { - if ( metaSlot == &mBuilder_TableStatus ) // table status? - { - if ( mParser_InTable && mBuilder_Table ) - { - const char* body = (const char*) inBuf.mBuf_Body; - mork_fill bufFill = inBuf.mBuf_Fill; - if ( body && bufFill ) - { - const char* bodyEnd = body + bufFill; - while ( body < bodyEnd ) - { - int c = *body++; - switch ( c ) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - mBuilder_TablePriority = (mork_priority) ( c - '0' ); - break; - - case 'u': - case 'U': - mBuilder_TableIsUnique = morkBool_kTrue; - break; - - case 'v': - case 'V': - mBuilder_TableIsVerbose = morkBool_kTrue; - break; - } - } - } - } - } - else - { - mork_token token = store->BufToToken(ev, &inBuf); - if ( token ) - { - *metaSlot = token; - if ( metaSlot == &mBuilder_TableKind ) // table kind? - { - if ( mParser_InTable && mBuilder_Table ) - mBuilder_Table->mTable_Kind = token; - } - } - } - } - } - else - this->NilBuilderCellError(ev); -} - -/*virtual*/ void -morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inSpan); - morkStore* store = mBuilder_Store; - morkCell* cell = mBuilder_Cell; - - morkMid valMid; // local mid for modifications - mdbOid* valOid = &valMid.mMid_Oid; // ref to oid inside mid - *valOid = inMid.mMid_Oid; // bitwise copy inMid's oid - - if ( inMid.mMid_Buf ) - { - if ( !valOid->mOid_Scope ) - store->MidToOid(ev, inMid, valOid); - } - else if ( !valOid->mOid_Scope ) - valOid->mOid_Scope = mBuilder_CellAtomScope; - - if ( cell ) - { - morkBookAtom* atom = store->MidToAtom(ev, valMid); - if ( atom ) - cell->SetAtom(ev, atom, store->StorePool()); - else - ev->NewError("undefined cell value alias"); - } - else if ( mParser_InMeta ) - { - mork_token* metaSlot = mBuilder_MetaTokenSlot; - if ( metaSlot ) - { - mork_scope valScope = valOid->mOid_Scope; - if ( !valScope || valScope == morkStore_kColumnSpaceScope ) - { - if ( ev->Good() && valMid.HasSomeId() ) - { - *metaSlot = valOid->mOid_Id; - if ( metaSlot == &mBuilder_TableKind ) // table kind? - { - if ( mParser_InTable && mBuilder_Table ) - { - mBuilder_Table->mTable_Kind = valOid->mOid_Id; - } - else - ev->NewWarning("mBuilder_TableKind not in table"); - } - else if ( metaSlot == &mBuilder_TableStatus ) // table status? - { - if ( mParser_InTable && mBuilder_Table ) - { - // $$ what here?? - } - else - ev->NewWarning("mBuilder_TableStatus not in table"); - } - } - } - else - this->NonColumnSpaceScopeError(ev); - } - } - else - this->NilBuilderCellError(ev); -} - -/*virtual*/ void -morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inSpan); - morkStore* store = mBuilder_Store; - morkCell* cell = mBuilder_Cell; - if ( cell ) - { - mdbOid rowOid = inMid.mMid_Oid; - if ( inMid.mMid_Buf ) - { - if ( !rowOid.mOid_Scope ) - store->MidToOid(ev, inMid, &rowOid); - } - else if ( !rowOid.mOid_Scope ) - rowOid.mOid_Scope = mBuilder_RowRowScope; - - if ( ev->Good() ) - { - morkPool* pool = store->StorePool(); - morkAtom* atom = pool->NewRowOidAtom(ev, rowOid, &store->mStore_Zone); - if ( atom ) - { - cell->SetAtom(ev, atom, pool); - morkRow* row = store->OidToRow(ev, &rowOid); - if ( row ) // found or created such a row? - row->AddRowGcUse(ev); - } - } - } - else - this->NilBuilderCellError(ev); -} - -/*virtual*/ void -morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid -{ - MORK_USED_1(inSpan); - morkStore* store = mBuilder_Store; - morkCell* cell = mBuilder_Cell; - if ( cell ) - { - mdbOid tableOid = inMid.mMid_Oid; - if ( inMid.mMid_Buf ) - { - if ( !tableOid.mOid_Scope ) - store->MidToOid(ev, inMid, &tableOid); - } - else if ( !tableOid.mOid_Scope ) - tableOid.mOid_Scope = mBuilder_RowRowScope; - - if ( ev->Good() ) - { - morkPool* pool = store->StorePool(); - morkAtom* atom = pool->NewTableOidAtom(ev, tableOid, &store->mStore_Zone); - if ( atom ) - { - cell->SetAtom(ev, atom, pool); - morkTable* table = store->OidToTable(ev, &tableOid, - /*optionalMetaRowOid*/ (mdbOid*) 0); - if ( table ) // found or created such a table? - table->AddTableGcUse(ev); - } - } - } - else - this->NilBuilderCellError(ev); -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkBuilder.h b/db/mork/src/morkBuilder.h deleted file mode 100644 index d423bd824282..000000000000 --- a/db/mork/src/morkBuilder.h +++ /dev/null @@ -1,335 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKBUILDER_ -#define _MORKBUILDER_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKPARSER_ -#include "morkParser.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| kCellsVecSize: length of cell vector buffer inside morkBuilder -|*/ -#define morkBuilder_kCellsVecSize 64 - -#define morkBuilder_kDefaultBytesPerParseSegment 512 /* plausible to big */ - -#define morkDerived_kBuilder /*i*/ 0x4275 /* ascii 'Bu' */ - -class morkBuilder /*d*/ : public morkParser { - -// public: // slots inherited from morkParser (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - - // nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation - // morkStream* mParser_Stream; // refcounted input stream - - // mork_u4 mParser_Tag; // must equal morkParser_kTag - // mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment - - // mork_u4 mParser_State; // state where parser should resume - - // after finding ends of group transactions, we can re-seek the start: - // mork_pos mParser_GroupContentStartPos; // start of this group - - // mdbOid mParser_TableOid; // table oid if inside a table - // mdbOid mParser_RowOid; // row oid if inside a row - // mork_gid mParser_GroupId; // group ID if inside a group - - // mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd? - // mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd? - // mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd? - // mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd? - - // morkMid mParser_Mid; // current alias being parsed - // note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below: - - // blob coils allocated in mParser_Heap - // morkCoil mParser_ScopeCoil; // place to accumulate ID scope blobs - // morkCoil mParser_ValueCoil; // place to accumulate value blobs - // morkCoil mParser_ColumnCoil; // place to accumulate column blobs - // morkCoil mParser_StringCoil; // place to accumulate string blobs - - // morkSpool mParser_ScopeSpool; // writes to mParser_ScopeCoil - // morkSpool mParser_ValueSpool; // writes to mParser_ValueCoil - // morkSpool mParser_ColumnSpool; // writes to mParser_ColumnCoil - // morkSpool mParser_StringSpool; // writes to mParser_StringCoil - - // yarns allocated in mParser_Heap - // morkYarn mParser_MidYarn; // place to receive from MidToYarn() - - // span showing current ongoing file position status: - // morkSpan mParser_PortSpan; // span of current db port file - - // various spans denoting nested subspaces inside the file's port span: - // morkSpan mParser_GroupSpan; // span of current transaction group - // morkSpan mParser_DictSpan; - // morkSpan mParser_AliasSpan; - // morkSpan mParser_MetaDictSpan; - // morkSpan mParser_TableSpan; - // morkSpan mParser_MetaTableSpan; - // morkSpan mParser_RowSpan; - // morkSpan mParser_MetaRowSpan; - // morkSpan mParser_CellSpan; - // morkSpan mParser_ColumnSpan; - // morkSpan mParser_SlotSpan; - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected morkBuilder members - - // weak refs that do not prevent closure of referenced nodes: - morkStore* mBuilder_Store; // weak ref to builder's store - - // strong refs that do indeed prevent closure of referenced nodes: - morkTable* mBuilder_Table; // current table being built (or nil) - morkRow* mBuilder_Row; // current row being built (or nil) - morkCell* mBuilder_Cell; // current cell within CellsVec (or nil) - - morkRowSpace* mBuilder_RowSpace; // space for mBuilder_CellRowScope - morkAtomSpace* mBuilder_AtomSpace; // space for mBuilder_CellAtomScope - - morkAtomSpace* mBuilder_OidAtomSpace; // ground atom space for oids - morkAtomSpace* mBuilder_ScopeAtomSpace; // ground atom space for scopes - - // scoped object ids for current objects under construction: - mdbOid mBuilder_TableOid; // full oid for current table - mdbOid mBuilder_RowOid; // full oid for current row - - // tokens that become set as the result of meta cells in port rows: - mork_cscode mBuilder_PortForm; // default port charset format - mork_scope mBuilder_PortRowScope; // port row scope - mork_scope mBuilder_PortAtomScope; // port atom scope - - // tokens that become set as the result of meta cells in meta tables: - mork_cscode mBuilder_TableForm; // default table charset format - mork_scope mBuilder_TableRowScope; // table row scope - mork_scope mBuilder_TableAtomScope; // table atom scope - mork_kind mBuilder_TableKind; // table kind - - mork_token mBuilder_TableStatus; // dummy: priority/unique/verbose - - mork_priority mBuilder_TablePriority; // table priority - mork_bool mBuilder_TableIsUnique; // table uniqueness - mork_bool mBuilder_TableIsVerbose; // table verboseness - mork_u1 mBuilder_TablePadByte; // for u4 alignment - - // tokens that become set as the result of meta cells in meta rows: - mork_cscode mBuilder_RowForm; // default row charset format - mork_scope mBuilder_RowRowScope; // row scope per row metainfo - mork_scope mBuilder_RowAtomScope; // row atom scope - - // meta tokens currently in force, driven by meta info slots above: - mork_cscode mBuilder_CellForm; // cell charset format - mork_scope mBuilder_CellAtomScope; // cell atom scope - - mork_cscode mBuilder_DictForm; // dict charset format - mork_scope mBuilder_DictAtomScope; // dict atom scope - - mork_token* mBuilder_MetaTokenSlot; // pointer to some slot above - - // If any of these 'cut' bools are true, it means a minus was seen in the - // Mork source text to indicate removal of content from some container. - // (Note there is no corresponding 'add' bool, since add is the default.) - // CutRow implies the current row should be cut from the table. - // CutCell implies the current column should be cut from the row. - mork_bool mBuilder_DoCutRow; // row with kCut change - mork_bool mBuilder_DoCutCell; // cell with kCut change - mork_u1 mBuilder_row_pad; // pad to u4 alignment - mork_u1 mBuilder_cell_pad; // pad to u4 alignment - - morkCell mBuilder_CellsVec[ morkBuilder_kCellsVecSize + 1 ]; - mork_fill mBuilder_CellsVecFill; // count used in CellsVec - // Note when mBuilder_CellsVecFill equals morkBuilder_kCellsVecSize, and - // another cell is added, this means all the cells in the vector above - // must be flushed to the current row being built to create more room. - -protected: // protected inlines - - mork_bool CellVectorIsFull() const - { return ( mBuilder_CellsVecFill == morkBuilder_kCellsVecSize ); } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseBuilder() only if open - virtual ~morkBuilder(); // assert that CloseBuilder() executed earlier - -public: // morkYarn construction & destruction - morkBuilder(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkStream* ioStream, // the readonly stream for input bytes - mdb_count inBytesPerParseSegment, // target for ParseMore() - nsIMdbHeap* ioSlotHeap, morkStore* ioStore - ); - - void CloseBuilder(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkBuilder(const morkBuilder& other); - morkBuilder& operator=(const morkBuilder& other); - -public: // dynamic type identification - mork_bool IsBuilder() const - { return IsNode() && mNode_Derived == morkDerived_kBuilder; } -// } ===== end morkNode methods ===== - -public: // errors - static void NonBuilderTypeError(morkEnv* ev); - static void NilBuilderCellError(morkEnv* ev); - static void NilBuilderRowError(morkEnv* ev); - static void NilBuilderTableError(morkEnv* ev); - static void NonColumnSpaceScopeError(morkEnv* ev); - - void LogGlitch(morkEnv* ev, const morkGlitch& inGlitch, - const char* inKind); - -public: // other builder methods - - morkCell* AddBuilderCell(morkEnv* ev, - const morkMid& inMid, mork_change inChange); - - void FlushBuilderCells(morkEnv* ev); - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // in virtual morkParser methods, data flow subclass to parser - - virtual void MidToYarn(morkEnv* ev, - const morkMid& inMid, // typically an alias to concat with strings - mdbYarn* outYarn); - // The parser might ask that some aliases be turned into yarns, so they - // can be concatenated into longer blobs under some circumstances. This - // is an alternative to using a long and complex callback for many parts - // for a single cell value. - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // out virtual morkParser methods, data flow parser to subclass - - virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace); - virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid); - virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan); - virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_change inChange); - virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllRows); - virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace); - virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnMinusRow(morkEnv* ev); - virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllCols); - virtual void OnRowPos(morkEnv* ev, mork_pos inRowPos); - virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace); - virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid); - - virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch); - - virtual void OnMinusCell(morkEnv* ev); - virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace, - const morkMid* inMid, const morkBuf* inBuf); - // Exactly one of inMid and inBuf is nil, and the other is non-nil. - // When hex ID syntax is used for a column, then inMid is not nil, and - // when a naked string names a column, then inBuf is not nil. - - virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch); - virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat); - virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan); - - virtual void OnValue(morkEnv* ev, const morkSpan& inSpan, - const morkBuf& inBuf); - - virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid); - - virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid); - - virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid); - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkBuilder methods - - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakBuilder(morkBuilder* me, - morkEnv* ev, morkBuilder** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongBuilder(morkBuilder* me, - morkEnv* ev, morkBuilder** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKBUILDER_ */ diff --git a/db/mork/src/morkCell.cpp b/db/mork/src/morkCell.cpp deleted file mode 100644 index 4002541aecee..000000000000 --- a/db/mork/src/morkCell.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -void -morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore) -{ - morkAtom* atom = ioStore->YarnToAtom(ev, inYarn, PR_TRUE /* create */); - if ( atom ) - this->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom -} - -void -morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const -{ - MORK_USED_1(ev); - mCell_Atom->GetYarn(outYarn); -} - -void -morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const -{ - MORK_USED_1(ev); - mCell_Atom->AliasYarn(outYarn); -} - - -void -morkCell::SetCellClean() -{ - mork_column col = this->GetColumn(); - this->SetColumnAndChange(col, morkChange_kNil); -} - -void -morkCell::SetCellDirty() -{ - mork_column col = this->GetColumn(); - this->SetColumnAndChange(col, morkChange_kAdd); -} - -void -morkCell::SetAtom(morkEnv* ev, morkAtom* ioAtom, morkPool* ioPool) - // SetAtom() "acquires" the new ioAtom if non-nil, by calling AddCellUse() - // to increase the refcount, and puts ioAtom into mCell_Atom. If the old - // atom in mCell_Atom is non-nil, then it is "released" first by a call to - // CutCellUse(), and if the use count then becomes zero, then the old atom - // is deallocated by returning it to the pool ioPool. (And this is - // why ioPool is a parameter to this method.) Note that ioAtom can be nil - // to cause the cell to refer to nothing, and the old atom in mCell_Atom - // can also be nil, and all the atom refcounting is handled correctly. - // - // Note that if ioAtom was just created, it typically has a zero use count - // before calling SetAtom(). But use count is one higher after SetAtom(). -{ - morkAtom* oldAtom = mCell_Atom; - if ( oldAtom != ioAtom ) // ioAtom is not already installed in this cell? - { - if ( oldAtom ) - { - mCell_Atom = 0; - if ( oldAtom->CutCellUse(ev) == 0 ) - { - // this was zapping atoms still in use - comment out until davidmc - // can figure out a better fix. -// if ( ioPool ) -// { -// if ( oldAtom->IsBook() ) -// ((morkBookAtom*) oldAtom)->CutBookAtomFromSpace(ev); - -// ioPool->ZapAtom(ev, oldAtom); -// } -// else -// ev->NilPointerError(); - } - } - if ( ioAtom ) - ioAtom->AddCellUse(ev); - - mCell_Atom = ioAtom; - } -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkCell.h b/db/mork/src/morkCell.h deleted file mode 100644 index a57c976ad229..000000000000 --- a/db/mork/src/morkCell.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKCELL_ -#define _MORKCELL_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDelta_kShift 8 /* 8 bit shift */ -#define morkDelta_kChangeMask 0x0FF /* low 8 bit mask */ -#define morkDelta_kColumnMask (~ (mork_column) morkDelta_kChangeMask) -#define morkDelta_Init(self,cl,ch) ((self) = ((cl)<> morkDelta_kShift) - -class morkCell { // minimal cell format - -public: - mork_delta mCell_Delta; // encoding of both column and change - morkAtom* mCell_Atom; // content in this cell - -public: - morkCell() : mCell_Delta( 0 ), mCell_Atom( 0 ) { } - - morkCell(const morkCell& c) - : mCell_Delta( c.mCell_Delta ), mCell_Atom( c.mCell_Atom ) { } - - // note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse(): - morkCell(mork_column inCol, mork_change inChange, morkAtom* ioAtom) - { - morkDelta_Init(mCell_Delta, inCol,inChange); - mCell_Atom = ioAtom; - } - - // note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse(): - void Init(mork_column inCol, mork_change inChange, morkAtom* ioAtom) - { - morkDelta_Init(mCell_Delta,inCol,inChange); - mCell_Atom = ioAtom; - } - - mork_column GetColumn() const { return morkDelta_Column(mCell_Delta); } - mork_change GetChange() const { return morkDelta_Change(mCell_Delta); } - - mork_bool IsCellClean() const { return GetChange() == morkChange_kNil; } - mork_bool IsCellDirty() const { return GetChange() != morkChange_kNil; } - - void SetCellClean(); // set change to kNil - void SetCellDirty(); // set change to kAdd - - void SetCellColumnDirty(mork_column inCol) - { this->SetColumnAndChange(inCol, morkChange_kAdd); } - - void SetCellColumnClean(mork_column inCol) - { this->SetColumnAndChange(inCol, morkChange_kNil); } - - void SetColumnAndChange(mork_column inCol, mork_change inChange) - { morkDelta_Init(mCell_Delta, inCol, inChange); } - - morkAtom* GetAtom() { return mCell_Atom; } - - void SetAtom(morkEnv* ev, morkAtom* ioAtom, morkPool* ioPool); - // SetAtom() "acquires" the new ioAtom if non-nil, by calling AddCellUse() - // to increase the refcount, and puts ioAtom into mCell_Atom. If the old - // atom in mCell_Atom is non-nil, then it is "released" first by a call to - // CutCellUse(), and if the use count then becomes zero, then the old atom - // is deallocated by returning it to the pool ioPool. (And this is - // why ioPool is a parameter to this method.) Note that ioAtom can be nil - // to cause the cell to refer to nothing, and the old atom in mCell_Atom - // can also be nil, and all the atom refcounting is handled correctly. - // - // Note that if ioAtom was just created, it typically has a zero use count - // before calling SetAtom(). But use count is one higher after SetAtom(). - - void SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore); - - void AliasYarn(morkEnv* ev, mdbYarn* outYarn) const; - void GetYarn(morkEnv* ev, mdbYarn* outYarn) const; -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKCELL_ */ diff --git a/db/mork/src/morkCellObject.cpp b/db/mork/src/morkCellObject.cpp deleted file mode 100644 index 151ef04d477d..000000000000 --- a/db/mork/src/morkCellObject.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCELLOBJECT_ -#include "morkCellObject.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkCellObject::CloseMorkNode(morkEnv* ev) // CloseCellObject() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseCellObject(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(mCellObject_Row==0); -} - -/*public non-poly*/ -morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell, - mork_column inCol, mork_pos inPos) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mCellObject_RowObject( 0 ) -, mCellObject_Row( 0 ) -, mCellObject_Cell( 0 ) -, mCellObject_Col( inCol ) -, mCellObject_RowSeed( 0 ) -, mCellObject_Pos( (mork_u2) inPos ) -{ - if ( ev->Good() ) - { - if ( ioRow && ioCell ) - { - if ( ioRow->IsRow() ) - { - morkStore* store = ioRow->GetRowSpaceStore(ev); - if ( store ) - { - morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store); - if ( rowObj ) - { - mCellObject_Row = ioRow; - mCellObject_Cell = ioCell; - mCellObject_RowSeed = ioRow->mRow_Seed; - - // morkRowObject::SlotStrongRowObject(rowObj, ev, - // &mCellObject_RowObject); - - mCellObject_RowObject = rowObj; // assume control of strong ref - } - if ( ev->Good() ) - mNode_Derived = morkDerived_kCellObject; - } - } - else - ioRow->NonRowTypeError(ev); - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkCellObject, morkObject, nsIMdbCell) - -/*public non-poly*/ void -morkCellObject::CloseCellObject(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - NS_RELEASE(mCellObject_RowObject); - mCellObject_Row = 0; - mCellObject_Cell = 0; - mCellObject_RowSeed = 0; - this->CloseObject(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -mork_bool -morkCellObject::ResyncWithRow(morkEnv* ev) -{ - morkRow* row = mCellObject_Row; - mork_pos pos = 0; - morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos); - if ( cell ) - { - mCellObject_Pos = (mork_u2) pos; - mCellObject_Cell = cell; - mCellObject_RowSeed = row->mRow_Seed; - } - else - { - mCellObject_Cell = 0; - this->MissingRowColumnError(ev); - } - return ev->Good(); -} - -morkAtom* -morkCellObject::GetCellAtom(morkEnv* ev) const -{ - morkCell* cell = mCellObject_Cell; - if ( cell ) - return cell->GetAtom(); - else - this->NilCellError(ev); - - return (morkAtom*) 0; -} - -/*static*/ void -morkCellObject::WrongRowObjectRowError(morkEnv* ev) -{ - ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row"); -} - -/*static*/ void -morkCellObject::NilRowError(morkEnv* ev) -{ - ev->NewError("nil mCellObject_Row"); -} - -/*static*/ void -morkCellObject::NilRowObjectError(morkEnv* ev) -{ - ev->NewError("nil mCellObject_RowObject"); -} - -/*static*/ void -morkCellObject::NilCellError(morkEnv* ev) -{ - ev->NewError("nil mCellObject_Cell"); -} - -/*static*/ void -morkCellObject::NonCellObjectTypeError(morkEnv* ev) -{ - ev->NewError("non morkCellObject"); -} - -/*static*/ void -morkCellObject::MissingRowColumnError(morkEnv* ev) -{ - ev->NewError("mCellObject_Col not in mCellObject_Row"); -} - -nsIMdbCell* -morkCellObject::AcquireCellHandle(morkEnv* ev) -{ - nsIMdbCell* outCell = this; - NS_ADDREF(outCell); - return outCell; -} - - -morkEnv* -morkCellObject::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable, - mdb_err* outErr, morkCell** outCell) -{ - morkEnv* outEnv = 0; - morkCell* cell = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( IsCellObject() ) - { - if ( IsMutable() || !inMutable ) - { - morkRowObject* rowObj = mCellObject_RowObject; - if ( rowObj ) - { - morkRow* row = mCellObject_Row; - if ( row ) - { - if ( rowObj->mRowObject_Row == row ) - { - mork_u2 oldSeed = mCellObject_RowSeed; - if ( row->mRow_Seed == oldSeed || ResyncWithRow(ev) ) - { - cell = mCellObject_Cell; - if ( cell ) - { - outEnv = ev; - } - else - NilCellError(ev); - } - } - else - WrongRowObjectRowError(ev); - } - else - NilRowError(ev); - } - else - NilRowObjectError(ev); - } - else - NonMutableNodeError(ev); - } - else - NonCellObjectTypeError(ev); - } - *outErr = ev->AsErr(); - MORK_ASSERT(outEnv); - *outCell = cell; - - return outEnv; -} - -// { ----- begin attribute methods ----- -NS_IMETHODIMP morkCellObject::SetBlob(nsIMdbEnv* /* mev */, - nsIMdbBlob* /* ioBlob */) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} // reads inBlob slots - -// when inBlob is in the same suite, this might be fastest cell-to-cell - -NS_IMETHODIMP morkCellObject::ClearBlob( // make empty (so content has zero length) - nsIMdbEnv* /* mev */) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; - // remember row->MaybeDirtySpaceStoreAndRow(); -} -// clearing a yarn is like SetYarn() with empty yarn instance content - -NS_IMETHODIMP morkCellObject::GetBlobFill(nsIMdbEnv* mev, - mdb_fill* outFill) -// Same value that would be put into mYarn_Fill, if one called GetYarn() -// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} // size of blob - -NS_IMETHODIMP morkCellObject::SetYarn(nsIMdbEnv* mev, - const mdbYarn* inYarn) -{ - mdb_err outErr = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - morkRow* row = mCellObject_Row; - if ( row ) - { - morkStore* store = row->GetRowSpaceStore(ev); - if ( store ) - { - cell->SetYarn(ev, inYarn, store); - if ( row->IsRowClean() && store->mStore_CanDirty ) - row->MaybeDirtySpaceStoreAndRow(); - } - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - - return outErr; -} // reads from yarn slots -// make this text object contain content from the yarn's buffer - -NS_IMETHODIMP morkCellObject::GetYarn(nsIMdbEnv* mev, - mdbYarn* outYarn) -{ - mdb_err outErr = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - morkAtom* atom = cell->GetAtom(); - atom->GetYarn(outYarn); - outErr = ev->AsErr(); - } - - return outErr; -} // writes some yarn slots -// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - -NS_IMETHODIMP morkCellObject::AliasYarn(nsIMdbEnv* mev, - mdbYarn* outYarn) -{ - mdb_err outErr = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - morkAtom* atom = cell->GetAtom(); - atom->AliasYarn(outYarn); - outErr = ev->AsErr(); - } - - return outErr; -} // writes ALL yarn slots - -// } ----- end attribute methods ----- - -// } ===== end nsIMdbBlob methods ===== - -// { ===== begin nsIMdbCell methods ===== - -// { ----- begin attribute methods ----- -NS_IMETHODIMP morkCellObject::SetColumn(nsIMdbEnv* mev, mdb_column inColumn) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; - // remember row->MaybeDirtySpaceStoreAndRow(); -} - -NS_IMETHODIMP morkCellObject::GetColumn(nsIMdbEnv* mev, mdb_column* outColumn) -{ - mdb_err outErr = 0; - mdb_column col = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - col = mCellObject_Col; - outErr = ev->AsErr(); - } - if ( outColumn ) - *outColumn = col; - return outErr; -} - -NS_IMETHODIMP morkCellObject::GetCellInfo( // all cell metainfo except actual content - nsIMdbEnv* mev, - mdb_column* outColumn, // the column in the containing row - mdb_fill* outBlobFill, // the size of text content in bytes - mdbOid* outChildOid, // oid of possible row or table child - mdb_bool* outIsRowChild) // nonzero if child, and a row child -// Checking all cell metainfo is a good way to avoid forcing a large cell -// in to memory when you don't actually want to use the content. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -NS_IMETHODIMP morkCellObject::GetRow(nsIMdbEnv* mev, // parent row for this cell - nsIMdbRow** acqRow) -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - outRow = mCellObject_RowObject->AcquireRowHandle(ev); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP morkCellObject::GetPort(nsIMdbEnv* mev, // port containing cell - nsIMdbPort** acqPort) -{ - mdb_err outErr = 0; - nsIMdbPort* outPort = 0; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - if ( mCellObject_Row ) - { - morkStore* store = mCellObject_Row->GetRowSpaceStore(ev); - if ( store ) - outPort = store->AcquireStoreHandle(ev); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqPort ) - *acqPort = outPort; - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin children methods ----- -NS_IMETHODIMP morkCellObject::HasAnyChild( // does cell have a child instead of text? - nsIMdbEnv* mev, - mdbOid* outOid, // out id of row or table (or unbound if no child) - mdb_bool* outIsRow) // nonzero if child is a row (rather than a table) -{ - mdb_err outErr = 0; - mdb_bool isRow = morkBool_kFalse; - outOid->mOid_Scope = 0; - outOid->mOid_Id = morkId_kMinusOne; - morkCell* cell = 0; - morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue, - &outErr, &cell); - if ( ev ) - { - morkAtom* atom = GetCellAtom(ev); - if ( atom ) - { - isRow = atom->IsRowOid(); - if ( isRow || atom->IsTableOid() ) - *outOid = ((morkOidAtom*) atom)->mOidAtom_Oid; - } - - outErr = ev->AsErr(); - } - if ( outIsRow ) - *outIsRow = isRow; - - return outErr; -} - -NS_IMETHODIMP morkCellObject::GetAnyChild( // access table of specific attribute - nsIMdbEnv* mev, // context - nsIMdbRow** acqRow, // child row (or null) - nsIMdbTable** acqTable) // child table (or null) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -NS_IMETHODIMP morkCellObject::SetChildRow( // access table of specific attribute - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} // inRow must be bound inside this same db port - -NS_IMETHODIMP morkCellObject::GetChildRow( // access row of specific attribute - nsIMdbEnv* mev, // context - nsIMdbRow** acqRow) // acquire child row (or nil if no child) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -NS_IMETHODIMP morkCellObject::SetChildTable( // access table of specific attribute - nsIMdbEnv* mev, // context - nsIMdbTable* inTable) // table must be bound inside this same db port -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; - // remember row->MaybeDirtySpaceStoreAndRow(); -} - -NS_IMETHODIMP morkCellObject::GetChildTable( // access table of specific attribute - nsIMdbEnv* mev, // context - nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end children methods ----- - -// } ===== end nsIMdbCell methods ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkCellObject.h b/db/mork/src/morkCellObject.h deleted file mode 100644 index d3b4c11a3728..000000000000 --- a/db/mork/src/morkCellObject.h +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKCELLOBJECT_ -#define _MORKCELLOBJECT_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kCellObject /*i*/ 0x634F /* ascii 'cO' */ - -class morkCellObject : public morkObject, public nsIMdbCell { // blob attribute in column scope - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // state is public because the entire Mork system is private - NS_DECL_ISUPPORTS_INHERITED - - morkRowObject* mCellObject_RowObject; // strong ref to row's object - morkRow* mCellObject_Row; // cell's row if still in row object - morkCell* mCellObject_Cell; // cell in row if rowseed matches - mork_column mCellObject_Col; // col of cell last living in pos - mork_u2 mCellObject_RowSeed; // copy of row's seed - mork_u2 mCellObject_Pos; // position of cell in row - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseCellObject() only if open - virtual ~morkCellObject(); // assert that CloseCellObject() executed earlier - -public: // morkCellObject construction & destruction - morkCellObject(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell, - mork_column inCol, mork_pos inPos); - void CloseCellObject(morkEnv* ev); // called by CloseMorkNode(); - - NS_IMETHOD SetBlob(nsIMdbEnv* ev, - nsIMdbBlob* ioBlob); // reads inBlob slots - // when inBlob is in the same suite, this might be fastest cell-to-cell - - NS_IMETHOD ClearBlob( // make empty (so content has zero length) - nsIMdbEnv* ev); - // clearing a yarn is like SetYarn() with empty yarn instance content - - NS_IMETHOD GetBlobFill(nsIMdbEnv* ev, - mdb_fill* outFill); // size of blob - // Same value that would be put into mYarn_Fill, if one called GetYarn() - // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0. - - NS_IMETHOD SetYarn(nsIMdbEnv* ev, - const mdbYarn* inYarn); // reads from yarn slots - // make this text object contain content from the yarn's buffer - - NS_IMETHOD GetYarn(nsIMdbEnv* ev, - mdbYarn* outYarn); // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - - NS_IMETHOD AliasYarn(nsIMdbEnv* ev, - mdbYarn* outYarn); // writes ALL yarn slots - NS_IMETHOD SetColumn(nsIMdbEnv* ev, mdb_column inColumn); - NS_IMETHOD GetColumn(nsIMdbEnv* ev, mdb_column* outColumn); - - NS_IMETHOD GetCellInfo( // all cell metainfo except actual content - nsIMdbEnv* ev, - mdb_column* outColumn, // the column in the containing row - mdb_fill* outBlobFill, // the size of text content in bytes - mdbOid* outChildOid, // oid of possible row or table child - mdb_bool* outIsRowChild); // nonzero if child, and a row child - - // Checking all cell metainfo is a good way to avoid forcing a large cell - // in to memory when you don't actually want to use the content. - - NS_IMETHOD GetRow(nsIMdbEnv* ev, // parent row for this cell - nsIMdbRow** acqRow); - NS_IMETHOD GetPort(nsIMdbEnv* ev, // port containing cell - nsIMdbPort** acqPort); - // } ----- end attribute methods ----- - - // { ----- begin children methods ----- - NS_IMETHOD HasAnyChild( // does cell have a child instead of text? - nsIMdbEnv* ev, - mdbOid* outOid, // out id of row or table (or unbound if no child) - mdb_bool* outIsRow); // nonzero if child is a row (rather than a table) - - NS_IMETHOD GetAnyChild( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // child row (or null) - nsIMdbTable** acqTable); // child table (or null) - - - NS_IMETHOD SetChildRow( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow); // inRow must be bound inside this same db port - - NS_IMETHOD GetChildRow( // access row of specific attribute - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow); // acquire child row (or nil if no child) - - - NS_IMETHOD SetChildTable( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbTable* inTable); // table must be bound inside this same db port - - NS_IMETHOD GetChildTable( // access table of specific attribute - nsIMdbEnv* ev, // context - nsIMdbTable** acqTable); // acquire child table (or nil if no child) - // } ----- end children methods ----- - -// } ===== end nsIMdbCell methods ===== -private: // copying is not allowed - morkCellObject(const morkCellObject& other); - morkCellObject& operator=(const morkCellObject& other); - -public: // dynamic type identification - mork_bool IsCellObject() const - { return IsNode() && mNode_Derived == morkDerived_kCellObject; } -// } ===== end morkNode methods ===== - -public: // other cell node methods - - morkEnv* CanUseCell(nsIMdbEnv* mev, mork_bool inMutable, - mdb_err* outErr, morkCell** outCell) ; - - mork_bool ResyncWithRow(morkEnv* ev); // return ev->Good() - morkAtom* GetCellAtom(morkEnv* ev) const; - - static void MissingRowColumnError(morkEnv* ev); - static void NilRowError(morkEnv* ev); - static void NilCellError(morkEnv* ev); - static void NilRowObjectError(morkEnv* ev); - static void WrongRowObjectRowError(morkEnv* ev); - static void NonCellObjectTypeError(morkEnv* ev); - - nsIMdbCell* AcquireCellHandle(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakCellObject(morkCellObject* me, - morkEnv* ev, morkCellObject** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongCellObject(morkCellObject* me, - morkEnv* ev, morkCellObject** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKCELLOBJECT_ */ diff --git a/db/mork/src/morkCh.cpp b/db/mork/src/morkCh.cpp deleted file mode 100644 index 07162a31517c..000000000000 --- a/db/mork/src/morkCh.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCH_ -#include "morkCh.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/* this byte char predicate source file derives from public domain Mithril */ -/* (that means much of this has a copyright dedicated to the public domain) */ - -/*============================================================================*/ -/* morkCh_Type */ - -const mork_flags morkCh_Type[] = /* derives from public domain Mithril table */ -{ - 0, /* 0x0 */ - 0, /* 0x1 */ - 0, /* 0x2 */ - 0, /* 0x3 */ - 0, /* 0x4 */ - 0, /* 0x5 */ - 0, /* 0x6 */ - 0, /* 0x7 */ - morkCh_kW, /* 0x8 backspace */ - morkCh_kW, /* 0x9 tab */ - morkCh_kW, /* 0xA linefeed */ - 0, /* 0xB */ - morkCh_kW, /* 0xC page */ - morkCh_kW, /* 0xD return */ - 0, /* 0xE */ - 0, /* 0xF */ - 0, /* 0x10 */ - 0, /* 0x11 */ - 0, /* 0x12 */ - 0, /* 0x13 */ - 0, /* 0x14 */ - 0, /* 0x15 */ - 0, /* 0x16 */ - 0, /* 0x17 */ - 0, /* 0x18 */ - 0, /* 0x19 */ - 0, /* 0x1A */ - 0, /* 0x1B */ - 0, /* 0x1C */ - 0, /* 0x1D */ - 0, /* 0x1E */ - 0, /* 0x1F */ - - morkCh_kV|morkCh_kW, /* 0x20 space */ - morkCh_kV|morkCh_kM, /* 0x21 ! */ - morkCh_kV, /* 0x22 " */ - morkCh_kV, /* 0x23 # */ - 0, /* 0x24 $ cannot be kV because needs escape */ - morkCh_kV, /* 0x25 % */ - morkCh_kV, /* 0x26 & */ - morkCh_kV, /* 0x27 ' */ - morkCh_kV, /* 0x28 ( */ - 0, /* 0x29 ) cannot be kV because needs escape */ - morkCh_kV, /* 0x2A * */ - morkCh_kV|morkCh_kM, /* 0x2B + */ - morkCh_kV, /* 0x2C , */ - morkCh_kV|morkCh_kM, /* 0x2D - */ - morkCh_kV, /* 0x2E . */ - morkCh_kV, /* 0x2F / */ - - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x30 0 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x31 1 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x32 2 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x33 3 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x34 4 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x35 5 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x36 6 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x37 7 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x38 8 */ - morkCh_kV|morkCh_kD|morkCh_kX, /* 0x39 9 */ - morkCh_kV|morkCh_kN|morkCh_kM, /* 0x3A : */ - morkCh_kV, /* 0x3B ; */ - morkCh_kV, /* 0x3C < */ - morkCh_kV, /* 0x3D = */ - morkCh_kV, /* 0x3E > */ - morkCh_kV|morkCh_kM, /* 0x3F ? */ - - morkCh_kV, /* 0x40 @ */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x41 A */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x42 B */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x43 C */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x44 D */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x45 E */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU|morkCh_kX, /* 0x46 F */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x47 G */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x48 H */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x49 I */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4A J */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4B K */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4C L */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4D M */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4E N */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x4F O */ - - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x50 P */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x51 Q */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x52 R */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x53 S */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x54 T */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x55 U */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x56 V */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x57 W */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x58 X */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x59 Y */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kU, /* 0x5A Z */ - morkCh_kV, /* 0x5B [ */ - 0, /* 0x5C \ cannot be kV because needs escape */ - morkCh_kV, /* 0x5D ] */ - morkCh_kV, /* 0x5E ^ */ - morkCh_kV|morkCh_kN|morkCh_kM, /* 0x5F _ */ - - morkCh_kV, /* 0x60 ` */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x61 a */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x62 b */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x63 c */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x64 d */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x65 e */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL|morkCh_kX, /* 0x66 f */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x67 g */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x68 h */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x69 i */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6A j */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6B k */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6C l */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6D m */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6E n */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x6F o */ - - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x70 p */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x71 q */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x72 r */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x73 s */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x74 t */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x75 u */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x76 v */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x77 w */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x78 x */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x79 y */ - morkCh_kV|morkCh_kN|morkCh_kM|morkCh_kL, /* 0x7A z */ - morkCh_kV, /* 0x7B { */ - morkCh_kV, /* 0x7C | */ - morkCh_kV, /* 0x7D } */ - morkCh_kV, /* 0x7E ~ */ - morkCh_kW, /* 0x7F rubout */ - -/* $"80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -/* $"F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF" */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkCh.h b/db/mork/src/morkCh.h deleted file mode 100644 index 1d77ec64e120..000000000000 --- a/db/mork/src/morkCh.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKCH_ -#define _MORKCH_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -/* this byte char predicate header file derives from public domain Mithril */ -/* (that means much of this has a copyright dedicated to the public domain) */ - -/* Use all 8 pred bits; lose some pred bits only if we need to reuse them. */ - -/* ch pred bits: W:white D:digit V:value U:upper L:lower N:name M:more */ -#define morkCh_kW (1 << 0) -#define morkCh_kD (1 << 1) -#define morkCh_kV (1 << 2) -#define morkCh_kU (1 << 3) -#define morkCh_kL (1 << 4) -#define morkCh_kX (1 << 5) -#define morkCh_kN (1 << 6) -#define morkCh_kM (1 << 7) - -extern const mork_flags morkCh_Type[]; /* 256 byte predicate bits ch map */ - -/* is a numeric decimal digit: (note memory access might be slower) */ -/* define morkCh_IsDigit(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kD ) */ -#define morkCh_IsDigit(c) ( ((mork_ch) c) >= '0' && ((mork_ch) c) <= '9' ) - -/* is a numeric octal digit: */ -#define morkCh_IsOctal(c) ( ((mork_ch) c) >= '0' && ((mork_ch) c) <= '7' ) - -/* is a numeric hexadecimal digit: */ -#define morkCh_IsHex(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kX ) - -/* is value (can be printed in Mork value without needing hex or escape): */ -#define morkCh_IsValue(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kV ) - -/* is white space : */ -#define morkCh_IsWhite(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kW ) - -/* is name (can start a Mork name): */ -#define morkCh_IsName(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kN ) - -/* is name (can continue a Mork name): */ -#define morkCh_IsMore(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kM ) - -/* is alphabetic upper or lower case */ -#define morkCh_IsAlpha(c) \ - ( morkCh_Type[ (mork_ch)(c) ] & (morkCh_kL|morkCh_kU) ) - -/* is alphanumeric, including lower case, upper case, and digits */ -#define morkCh_IsAlphaNum(c) \ - (morkCh_Type[ (mork_ch)(c) ]&(morkCh_kL|morkCh_kU|morkCh_kD)) - -/* ````` repeated testing of predicate bits in single flag byte ````` */ - -#define morkCh_GetFlags(c) ( morkCh_Type[ (mork_ch)(c) ] ) - -#define morkFlags_IsDigit(f) ( (f) & morkCh_kD ) -#define morkFlags_IsHex(f) ( (f) & morkCh_kX ) -#define morkFlags_IsValue(f) ( (f) & morkCh_kV ) -#define morkFlags_IsWhite(f) ( (f) & morkCh_kW ) -#define morkFlags_IsName(f) ( (f) & morkCh_kN ) -#define morkFlags_IsMore(f) ( (f) & morkCh_kM ) -#define morkFlags_IsAlpha(f) ( (f) & (morkCh_kL|morkCh_kU) ) -#define morkFlags_IsAlphaNum(f) ( (f) & (morkCh_kL|morkCh_kU|morkCh_kD) ) - -#define morkFlags_IsUpper(f) ( (f) & morkCh_kU ) -#define morkFlags_IsLower(f) ( (f) & morkCh_kL ) - -/* ````` character case (e.g. for case insensitive operations) ````` */ - - -#define morkCh_IsAscii(c) ( ((mork_u1) c) <= 0x7F ) -#define morkCh_IsSevenBitChar(c) ( ((mork_u1) c) <= 0x7F ) - -/* ````` character case (e.g. for case insensitive operations) ````` */ - -#define morkCh_ToLower(c) ((c)-'A'+'a') -#define morkCh_ToUpper(c) ((c)-'a'+'A') - -/* extern int morkCh_IsUpper (int c); */ -#define morkCh_IsUpper(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kU ) - -/* extern int morkCh_IsLower (int c); */ -#define morkCh_IsLower(c) ( morkCh_Type[ (mork_ch)(c) ] & morkCh_kL ) - -#endif -/* _MORKCH_ */ diff --git a/db/mork/src/morkConfig.cpp b/db/mork/src/morkConfig.cpp deleted file mode 100644 index b4f00ebdfd5c..000000000000 --- a/db/mork/src/morkConfig.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCONFIG_ -#include "morkConfig.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -void mork_assertion_signal(const char* inMessage) -{ -#if defined(MORK_WIN) || defined(MORK_MAC) - // asm { int 3 } - NS_ERROR(inMessage); -#endif /*MORK_WIN*/ -} - -#if defined(MORK_OS2) -#include -#include -#include -#include - -FILE* mork_fileopen(const char* name, const char* mode) -{ - int access = O_RDWR; - int descriptor; - int pmode = 0; - - /* Only possible options are wb+ and rb+ */ - MORK_ASSERT((mode[0] == 'w' || mode[0] == 'r') && (mode[1] == 'b') && (mode[2] == '+')); - if (mode[0] == 'w') { - access |= (O_TRUNC | O_CREAT); - pmode = S_IREAD | S_IWRITE; - } - - descriptor = sopen(name, access, SH_DENYNO, pmode); - if (descriptor != -1) { - return fdopen(descriptor, mode); - } - return NULL; -} -#endif - -#ifdef MORK_PROVIDE_STDLIB - -MORK_LIB_IMPL(mork_i4) -mork_memcmp(const void* inOne, const void* inTwo, mork_size inSize) -{ - register const mork_u1* t = (const mork_u1*) inTwo; - register const mork_u1* s = (const mork_u1*) inOne; - const mork_u1* end = s + inSize; - register mork_i4 delta; - - while ( s < end ) - { - delta = ((mork_i4) *s) - ((mork_i4) *t); - if ( delta ) - return delta; - else - { - ++t; - ++s; - } - } - return 0; -} - -MORK_LIB_IMPL(void) -mork_memcpy(void* outDst, const void* inSrc, mork_size inSize) -{ - register mork_u1* d = (mork_u1*) outDst; - mork_u1* end = d + inSize; - register const mork_u1* s = ((const mork_u1*) inSrc); - - while ( inSize >= 8 ) - { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - - inSize -= 8; - } - - while ( d < end ) - *d++ = *s++; -} - -MORK_LIB_IMPL(void) -mork_memmove(void* outDst, const void* inSrc, mork_size inSize) -{ - register mork_u1* d = (mork_u1*) outDst; - register const mork_u1* s = (const mork_u1*) inSrc; - if ( d != s && inSize ) // copy is necessary? - { - const mork_u1* srcEnd = s + inSize; // one past last source byte - - if ( d > s && d < srcEnd ) // overlap? need to copy backwards? - { - s = srcEnd; // start one past last source byte - d += inSize; // start one past last dest byte - mork_u1* dstBegin = d; // last byte to write is first in dest range - while ( d - dstBegin >= 8 ) - { - *--d = *--s; - *--d = *--s; - *--d = *--s; - *--d = *--s; - - *--d = *--s; - *--d = *--s; - *--d = *--s; - *--d = *--s; - } - while ( d > dstBegin ) - *--d = *--s; - } - else // can copy forwards without any overlap - { - mork_u1* dstEnd = d + inSize; - while ( dstEnd - d >= 8 ) - { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - while ( d < dstEnd ) - *d++ = *s++; - } - } -} - -MORK_LIB_IMPL(void) -mork_memset(void* outDst, int inByte, mork_size inSize) -{ - register mork_u1* d = (mork_u1*) outDst; - mork_u1* end = d + inSize; - while ( d < end ) - *d++ = (mork_u1) inByte; -} - -MORK_LIB_IMPL(void) -mork_strcpy(void* outDst, const void* inSrc) -{ - // back up one first to support preincrement - register mork_u1* d = ((mork_u1*) outDst) - 1; - register const mork_u1* s = ((const mork_u1*) inSrc) - 1; - while ( ( *++d = *++s ) != 0 ) - /* empty */; -} - -MORK_LIB_IMPL(mork_i4) -mork_strcmp(const void* inOne, const void* inTwo) -{ - register const mork_u1* t = (const mork_u1*) inTwo; - register const mork_u1* s = ((const mork_u1*) inOne); - register mork_i4 a; - register mork_i4 b; - register mork_i4 delta; - - do - { - a = (mork_i4) *s++; - b = (mork_i4) *t++; - delta = a - b; - } - while ( !delta && a && b ); - - return delta; -} - -MORK_LIB_IMPL(mork_i4) -mork_strncmp(const void* inOne, const void* inTwo, mork_size inSize) -{ - register const mork_u1* t = (const mork_u1*) inTwo; - register const mork_u1* s = (const mork_u1*) inOne; - const mork_u1* end = s + inSize; - register mork_i4 delta; - register mork_i4 a; - register mork_i4 b; - - while ( s < end ) - { - a = (mork_i4) *s++; - b = (mork_i4) *t++; - delta = a - b; - if ( delta || !a || !b ) - return delta; - } - return 0; -} - -MORK_LIB_IMPL(mork_size) -mork_strlen(const void* inString) -{ - // back up one first to support preincrement - register const mork_u1* s = ((const mork_u1*) inString) - 1; - while ( *++s ) // preincrement is cheapest - /* empty */; - - return s - ((const mork_u1*) inString); // distance from original address -} - -#endif /*MORK_PROVIDE_STDLIB*/ - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkConfig.h b/db/mork/src/morkConfig.h deleted file mode 100644 index 0b0954a615cf..000000000000 --- a/db/mork/src/morkConfig.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKCONFIG_ -#define _MORKCONFIG_ 1 - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// { %%%%% begin debug mode options in Mork %%%%% -#define MORK_DEBUG 1 -// } %%%%% end debug mode options in Mork %%%%% - -#ifdef MORK_DEBUG -#define MORK_MAX_CODE_COMPILE 1 -#endif - -// { %%%%% begin platform defs peculiar to Mork %%%%% - -#ifdef XP_MACOSX -#define MORK_MAC 1 -#endif - -#ifdef XP_OS2 -#define MORK_OS2 1 -#endif - -#ifdef XP_WIN -#define MORK_WIN 1 -#endif - -#ifdef XP_UNIX -#define MORK_UNIX 1 -#endif - -// } %%%%% end platform defs peculiar to Mork %%%%% - -#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC) || defined(MORK_OS2) -#include -#include -#include -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include /* for SEEK_SET, SEEK_END */ -#endif - -#include "nsDebug.h" - -#define MORK_ISPRINT(c) isprint(c) - -#define MORK_FILETELL(file) ftell(file) -#define MORK_FILESEEK(file, where, how) fseek(file, where, how) -#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, 1, insize, file) -#if defined(MORK_WIN) -void mork_fileflush(FILE * file); -#define MORK_FILEFLUSH(file) mork_fileflush(file) -#else -#define MORK_FILEFLUSH(file) fflush(file) -#endif /*MORK_WIN*/ - -#if defined(MORK_OS2) -FILE* mork_fileopen(const char* name, const char* mode); -#define MORK_FILEOPEN(file, how) mork_fileopen(file, how) -#else -#define MORK_FILEOPEN(file, how) fopen(file, how) -#endif -#define MORK_FILECLOSE(file) fclose(file) -#endif /*MORK_WIN*/ - -/* ===== separating switchable features ===== */ - -#define MORK_ENABLE_ZONE_ARENAS 1 /* using morkZone for pooling */ - -//#define MORK_ENABLE_PROBE_MAPS 1 /* use smaller hash tables */ - -#define MORK_BEAD_OVER_NODE_MAPS 1 /* use bead not node maps */ - -/* ===== pooling ===== */ - -#if defined(HAVE_64BIT_OS) -#define MORK_CONFIG_ALIGN_8 1 /* must have 8 byte alignment */ -#else -#define MORK_CONFIG_PTR_SIZE_4 1 /* sizeof(void*) == 4 */ -#endif - -// #define MORK_DEBUG_HEAP_STATS 1 /* analyze per-block heap usage */ - -/* ===== ===== ===== ===== line characters ===== ===== ===== ===== */ -#define mork_kCR 0x0D -#define mork_kLF 0x0A -#define mork_kVTAB '\013' -#define mork_kFF '\014' -#define mork_kTAB '\011' -#define mork_kCRLF "\015\012" /* A CR LF equivalent string */ - -#if defined(MORK_MAC) -# define mork_kNewline "\015" -# define mork_kNewlineSize 1 -#else -# if defined(MORK_WIN) || defined(MORK_OS2) -# define mork_kNewline "\015\012" -# define mork_kNewlineSize 2 -# else -# if defined(MORK_UNIX) -# define mork_kNewline "\012" -# define mork_kNewlineSize 1 -# endif /* MORK_UNIX */ -# endif /* MORK_WIN */ -#endif /* MORK_MAC */ - -// { %%%%% begin assertion macro %%%%% -extern void mork_assertion_signal(const char* inMessage); -#define MORK_ASSERTION_SIGNAL(Y) mork_assertion_signal(Y) -#define MORK_ASSERT(X) if (!(X)) MORK_ASSERTION_SIGNAL(#X) -// } %%%%% end assertion macro %%%%% - -#define MORK_LIB(return) return /*API return declaration*/ -#define MORK_LIB_IMPL(return) return /*implementation return declaration*/ - -// { %%%%% begin standard c utility methods %%%%% - -#if defined(MORK_WIN) || defined(MORK_UNIX) || defined(MORK_MAC) || defined(MORK_OS2) -#define MORK_USE_C_STDLIB 1 -#endif /*MORK_WIN*/ - -#ifdef MORK_USE_C_STDLIB -#define MORK_MEMCMP(src1,src2,size) memcmp(src1,src2,size) -#define MORK_MEMCPY(dest,src,size) memcpy(dest,src,size) -#define MORK_MEMMOVE(dest,src,size) memmove(dest,src,size) -#define MORK_MEMSET(dest,byte,size) memset(dest,byte,size) -#define MORK_STRCPY(dest,src) strcpy(dest,src) -#define MORK_STRCMP(one,two) strcmp(one,two) -#define MORK_STRNCMP(one,two,length) strncmp(one,two,length) -#define MORK_STRLEN(string) strlen(string) -#endif /*MORK_USE_C_STDLIB*/ - -#ifdef MORK_PROVIDE_STDLIB -MORK_LIB(mork_i4) mork_memcmp(const void* a, const void* b, mork_size inSize); -MORK_LIB(void) mork_memcpy(void* dst, const void* src, mork_size inSize); -MORK_LIB(void) mork_memmove(void* dst, const void* src, mork_size inSize); -MORK_LIB(void) mork_memset(void* dst, int inByte, mork_size inSize); -MORK_LIB(void) mork_strcpy(void* dst, const void* src); -MORK_LIB(mork_i4) mork_strcmp(const void* a, const void* b); -MORK_LIB(mork_i4) mork_strncmp(const void* a, const void* b, mork_size inSize); -MORK_LIB(mork_size) mork_strlen(const void* inString); - -#define MORK_MEMCMP(src1,src2,size) mork_memcmp(src1,src2,size) -#define MORK_MEMCPY(dest,src,size) mork_memcpy(dest,src,size) -#define MORK_MEMMOVE(dest,src,size) mork_memmove(dest,src,size) -#define MORK_MEMSET(dest,byte,size) mork_memset(dest,byte,size) -#define MORK_STRCPY(dest,src) mork_strcpy(dest,src) -#define MORK_STRCMP(one,two) mork_strcmp(one,two) -#define MORK_STRNCMP(one,two,length) mork_strncmp(one,two,length) -#define MORK_STRLEN(string) mork_strlen(string) -#endif /*MORK_PROVIDE_STDLIB*/ - -// } %%%%% end standard c utility methods %%%%% - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKCONFIG_ */ - diff --git a/db/mork/src/morkCursor.cpp b/db/mork/src/morkCursor.cpp deleted file mode 100644 index 98b40a11c0f5..000000000000 --- a/db/mork/src/morkCursor.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkCursor::CloseMorkNode(morkEnv* ev) // CloseCursor() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseCursor(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkCursor::~morkCursor() // assert CloseCursor() executed earlier -{ -} - -/*public non-poly*/ -morkCursor::morkCursor(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mCursor_Seed( 0 ) -, mCursor_Pos( -1 ) -, mCursor_DoFailOnSeedOutOfSync( morkBool_kFalse ) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kCursor; -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkCursor, morkObject, nsIMdbCursor) - -/*public non-poly*/ void -morkCursor::CloseCursor(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mCursor_Seed = 0; - mCursor_Pos = -1; - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// { ----- begin ref counting for well-behaved cyclic graphs ----- -NS_IMETHODIMP -morkCursor::GetWeakRefCount(nsIMdbEnv* mev, // weak refs - mdb_count* outCount) -{ - *outCount = WeakRefsOnly(); - return NS_OK; -} -NS_IMETHODIMP -morkCursor::GetStrongRefCount(nsIMdbEnv* mev, // strong refs - mdb_count* outCount) -{ - *outCount = StrongRefsOnly(); - return NS_OK; -} -// ### TODO - clean up this cast, if required -NS_IMETHODIMP -morkCursor::AddWeakRef(nsIMdbEnv* mev) -{ - return morkNode::AddWeakRef((morkEnv *) mev); -} -NS_IMETHODIMP -morkCursor::AddStrongRef(nsIMdbEnv* mev) -{ - return morkNode::AddStrongRef((morkEnv *) mev); -} - -NS_IMETHODIMP -morkCursor::CutWeakRef(nsIMdbEnv* mev) -{ - return morkNode::CutWeakRef((morkEnv *) mev); -} -NS_IMETHODIMP -morkCursor::CutStrongRef(nsIMdbEnv* mev) -{ - return morkNode::CutStrongRef((morkEnv *) mev); -} - - -NS_IMETHODIMP -morkCursor::CloseMdbObject(nsIMdbEnv* mev) -{ - return morkNode::CloseMdbObject((morkEnv *) mev); -} - -NS_IMETHODIMP -morkCursor::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen) -{ - *outOpen = IsOpenNode(); - return NS_OK; -} -NS_IMETHODIMP -morkCursor::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly) -{ - *outIsReadonly = IsFrozen(); - return NS_OK; -} -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -NS_IMETHODIMP -morkCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkCursor.h b/db/mork/src/morkCursor.h deleted file mode 100644 index 47e070cbcde8..000000000000 --- a/db/mork/src/morkCursor.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKCURSOR_ -#define _MORKCURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kCursor /*i*/ 0x4375 /* ascii 'Cu' */ - -class morkCursor : public morkObject, public nsIMdbCursor{ // collection iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // state is public because the entire Mork system is private - NS_DECL_ISUPPORTS_INHERITED - - // { ----- begin attribute methods ----- - NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly); - // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port. - // } ----- end attribute methods ----- - - // { ----- begin ref counting for well-behaved cyclic graphs ----- - NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs - mdb_count* outCount); - NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs - mdb_count* outCount); - - NS_IMETHOD AddWeakRef(nsIMdbEnv* ev); - NS_IMETHOD AddStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CutWeakRef(nsIMdbEnv* ev); - NS_IMETHOD CutStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero - NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen); - // } ----- end ref counting ----- - -// } ===== end nsIMdbObject methods ===== - -// { ===== begin nsIMdbCursor methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetCount(nsIMdbEnv* ev, mdb_count* outCount); // readonly - NS_IMETHOD GetSeed(nsIMdbEnv* ev, mdb_seed* outSeed); // readonly - - NS_IMETHOD SetPos(nsIMdbEnv* ev, mdb_pos inPos); // mutable - NS_IMETHOD GetPos(nsIMdbEnv* ev, mdb_pos* outPos); - - NS_IMETHOD SetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool inFail); - NS_IMETHOD GetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool* outFail); - // } ----- end attribute methods ----- - -// } ===== end nsIMdbCursor methods ===== - - // } ----- end attribute methods ----- - - mork_seed mCursor_Seed; - mork_pos mCursor_Pos; - mork_bool mCursor_DoFailOnSeedOutOfSync; - mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseCursor() only if open - virtual ~morkCursor(); // assert that CloseCursor() executed earlier - -public: // morkCursor construction & destruction - morkCursor(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap); - void CloseCursor(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkCursor(const morkCursor& other); - morkCursor& operator=(const morkCursor& other); - -public: // dynamic type identification - mork_bool IsCursor() const - { return IsNode() && mNode_Derived == morkDerived_kCursor; } -// } ===== end morkNode methods ===== - -public: // other cursor methods - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakCursor(morkCursor* me, - morkEnv* ev, morkCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongCursor(morkCursor* me, - morkEnv* ev, morkCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKCURSOR_ */ diff --git a/db/mork/src/morkDeque.cpp b/db/mork/src/morkDeque.cpp deleted file mode 100644 index 3f9d891696fc..000000000000 --- a/db/mork/src/morkDeque.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/************************************************************************* -This software is part of a public domain IronDoc source code distribution, -and is provided on an "AS IS" basis, with all risks borne by the consumers -or users of the IronDoc software. There are no warranties, guarantees, or -promises about quality of any kind; and no remedies for failure exist. - -Permission is hereby granted to use this IronDoc software for any purpose -at all, without need for written agreements, without royalty or license -fees, and without fees or obligations of any other kind. Anyone can use, -copy, change and distribute this software for any purpose, and nothing is -required, implicitly or otherwise, in exchange for this usage. - -You cannot apply your own copyright to this software, but otherwise you -are encouraged to enjoy the use of this software in any way you see fit. -However, it would be rude to remove names of developers from the code. -(IronDoc is also known by the short name "Fe" and a longer name "Ferrum", -which are used interchangeably with the name IronDoc in the sources.) -*************************************************************************/ -/* - * File: morkDeque.cpp - * Contains: Ferrum deque (double ended queue (linked list)) - * - * Copied directly from public domain IronDoc, with minor naming tweaks: - * Designed and written by David McCusker, but all this code is public domain. - * There are no warranties, no guarantees, no promises, and no remedies. - */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -/*============================================================================= - * morkNext: linked list node for very simple, singly-linked list - */ - -morkNext::morkNext() : mNext_Link( 0 ) -{ -} - -/*static*/ void* -morkNext::MakeNewNext(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) -{ - void* next = 0; - if ( &ioHeap ) - { - ioHeap.Alloc(ev->AsMdbEnv(), inSize, (void**) &next); - if ( !next ) - ev->OutOfMemoryError(); - } - else - ev->NilPointerError(); - - return next; -} - -/*static*/ -void morkNext::ZapOldNext(morkEnv* ev, nsIMdbHeap* ioHeap) -{ - if ( ioHeap ) - { - if ( this ) - ioHeap->Free(ev->AsMdbEnv(), this); - } - else - ev->NilPointerError(); -} - -/*============================================================================= - * morkList: simple, singly-linked list - */ - -morkList::morkList() : mList_Head( 0 ), mList_Tail( 0 ) -{ -} - -void morkList::CutAndZapAllListMembers(morkEnv* ev, nsIMdbHeap* ioHeap) -// make empty list, zapping every member by calling ZapOldNext() -{ - if ( ioHeap ) - { - morkNext* next = 0; - while ( (next = this->PopHead()) != 0 ) - next->ZapOldNext(ev, ioHeap); - - mList_Head = 0; - mList_Tail = 0; - } - else - ev->NilPointerError(); -} - -void morkList::CutAllListMembers() -// just make list empty, dropping members without zapping -{ - while ( this->PopHead() ) - /* empty */; - - mList_Head = 0; - mList_Tail = 0; -} - -morkNext* morkList::PopHead() // cut head of list -{ - morkNext* outHead = mList_Head; - if ( outHead ) // anything to cut from list? - { - morkNext* next = outHead->mNext_Link; - mList_Head = next; - if ( !next ) // cut the last member, so tail no longer exists? - mList_Tail = 0; - - outHead->mNext_Link = 0; // nil outgoing node link; unnecessary, but tidy - } - return outHead; -} - - -void morkList::PushHead(morkNext* ioLink) // add to head of list -{ - morkNext* head = mList_Head; // old head of list - morkNext* tail = mList_Tail; // old tail of list - - MORK_ASSERT( (head && tail) || (!head && !tail)); - - ioLink->mNext_Link = head; // make old head follow the new link - if ( !head ) // list was previously empty? - mList_Tail = ioLink; // head is also tail for first member added - - mList_Head = ioLink; // head of list is the new link -} - -void morkList::PushTail(morkNext* ioLink) // add to tail of list -{ - morkNext* head = mList_Head; // old head of list - morkNext* tail = mList_Tail; // old tail of list - - MORK_ASSERT( (head && tail) || (!head && !tail)); - - ioLink->mNext_Link = 0; - if ( tail ) - { - tail->mNext_Link = ioLink; - mList_Tail = ioLink; - } - else // list was previously empty? - mList_Head = mList_Tail = ioLink; // tail is also head for first member added -} - -/*============================================================================= - * morkLink: linked list node embedded in objs to allow insertion in morkDeques - */ - -morkLink::morkLink() : mLink_Next( 0 ), mLink_Prev( 0 ) -{ -} - -/*static*/ void* -morkLink::MakeNewLink(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) -{ - void* alink = 0; - if ( &ioHeap ) - { - ioHeap.Alloc(ev->AsMdbEnv(), inSize, (void**) &alink); - if ( !alink ) - ev->OutOfMemoryError(); - } - else - ev->NilPointerError(); - - return alink; -} - -/*static*/ -void morkLink::ZapOldLink(morkEnv* ev, nsIMdbHeap* ioHeap) -{ - if ( ioHeap ) - { - if ( this ) - ioHeap->Free(ev->AsMdbEnv(), this); - } - else - ev->NilPointerError(); -} - -/*============================================================================= - * morkDeque: doubly linked list modeled after VAX queue instructions - */ - -morkDeque::morkDeque() -{ - mDeque_Head.SelfRefer(); -} - - -/*| RemoveFirst: -|*/ -morkLink* -morkDeque::RemoveFirst() /*i*/ -{ - morkLink* alink = mDeque_Head.mLink_Next; - if ( alink != &mDeque_Head ) - { - (mDeque_Head.mLink_Next = alink->mLink_Next)->mLink_Prev = - &mDeque_Head; - return alink; - } - return (morkLink*) 0; -} - -/*| RemoveLast: -|*/ -morkLink* -morkDeque::RemoveLast() /*i*/ -{ - morkLink* alink = mDeque_Head.mLink_Prev; - if ( alink != &mDeque_Head ) - { - (mDeque_Head.mLink_Prev = alink->mLink_Prev)->mLink_Next = - &mDeque_Head; - return alink; - } - return (morkLink*) 0; -} - -/*| At: -|*/ -morkLink* -morkDeque::At(mork_pos index) const /*i*/ - /* indexes are one based (and not zero based) */ -{ - register mork_num count = 0; - register morkLink* alink; - for ( alink = this->First(); alink; alink = this->After(alink) ) - { - if ( ++count == (mork_num) index ) - break; - } - return alink; -} - -/*| IndexOf: -|*/ -mork_pos -morkDeque::IndexOf(const morkLink* member) const /*i*/ - /* indexes are one based (and not zero based) */ - /* zero means member is not in deque */ -{ - register mork_num count = 0; - register const morkLink* alink; - for ( alink = this->First(); alink; alink = this->After(alink) ) - { - ++count; - if ( member == alink ) - return (mork_pos) count; - } - return 0; -} - -/*| Length: -|*/ -mork_num -morkDeque::Length() const /*i*/ -{ - register mork_num count = 0; - register morkLink* alink; - for ( alink = this->First(); alink; alink = this->After(alink) ) - ++count; - return count; -} - -/*| LengthCompare: -|*/ -int -morkDeque::LengthCompare(mork_num c) const /*i*/ -{ - register mork_num count = 0; - register const morkLink* alink; - for ( alink = this->First(); alink; alink = this->After(alink) ) - { - if ( ++count > c ) - return 1; - } - return ( count == c )? 0 : -1; -} diff --git a/db/mork/src/morkDeque.h b/db/mork/src/morkDeque.h deleted file mode 100644 index 4375ecf029af..000000000000 --- a/db/mork/src/morkDeque.h +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************* -This software is part of a public domain IronDoc source code distribution, -and is provided on an "AS IS" basis, with all risks borne by the consumers -or users of the IronDoc software. There are no warranties, guarantees, or -promises about quality of any kind; and no remedies for failure exist. - -Permission is hereby granted to use this IronDoc software for any purpose -at all, without need for written agreements, without royalty or license -fees, and without fees or obligations of any other kind. Anyone can use, -copy, change and distribute this software for any purpose, and nothing is -required, implicitly or otherwise, in exchange for this usage. - -You cannot apply your own copyright to this software, but otherwise you -are encouraged to enjoy the use of this software in any way you see fit. -However, it would be rude to remove names of developers from the code. -(IronDoc is also known by the short name "Fe" and a longer name "Ferrum", -which are used interchangeably with the name IronDoc in the sources.) -*************************************************************************/ -/* - * File: morkDeque.h - * Contains: Ferrum deque (double ended queue (linked list)) - * - * Copied directly from public domain IronDoc, with minor naming tweaks: - * Designed and written by David McCusker, but all this code is public domain. - * There are no warranties, no guarantees, no promises, and no remedies. - */ - -#ifndef _MORKDEQUE_ -#define _MORKDEQUE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -/*============================================================================= - * morkNext: linked list node for very simple, singly-linked list - */ - -class morkNext /*d*/ { -public: - morkNext* mNext_Link; - -public: - morkNext(int inZero) : mNext_Link( 0 ) { } - - morkNext(morkNext* ioLink) : mNext_Link( ioLink ) { } - - morkNext(); // mNext_Link( 0 ), { } - -public: - morkNext* GetNextLink() const { return mNext_Link; } - -public: // link memory management methods - static void* MakeNewNext(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev); - void ZapOldNext(morkEnv* ev, nsIMdbHeap* ioHeap); - -public: // link memory management operators - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkNext::MakeNewNext(inSize, ioHeap, ev); } - - void operator delete(void* ioAddress) // DO NOT CALL THIS, hope to crash: - { ((morkNext*) 0)->ZapOldNext((morkEnv*) 0, (nsIMdbHeap*) 0); } // boom -}; - -/*============================================================================= - * morkList: simple, singly-linked list - */ - -/*| morkList: a list of singly-linked members (instances of morkNext), where -**| the number of list members might be so numerous that we must about cost -**| for two pointer link slots per member (as happens with morkLink). -**| -**|| morkList is intended to support lists of changes in morkTable, where we -**| are worried about the space cost of representing such changes. (Later we -**| can use an array instead, when we get even more worried, to avoid cost -**| of link slots at all, per member). -**| -**|| Do NOT create cycles in links using this list class, since we do not -**| deal with them very nicely. -|*/ -class morkList /*d*/ { -public: - morkNext* mList_Head; // first link in the list - morkNext* mList_Tail; // last link in the list - -public: - morkNext* GetListHead() const { return mList_Head; } - morkNext* GetListTail() const { return mList_Tail; } - - mork_bool IsListEmpty() const { return ( mList_Head == 0 ); } - mork_bool HasListMembers() const { return ( mList_Head != 0 ); } - -public: - morkList(); // : mList_Head( 0 ), mList_Tail( 0 ) { } - - void CutAndZapAllListMembers(morkEnv* ev, nsIMdbHeap* ioHeap); - // make empty list, zapping every member by calling ZapOldNext() - - void CutAllListMembers(); - // just make list empty, dropping members without zapping - -public: - morkNext* PopHead(); // cut head of list - - // Note we don't support PopTail(), so use morkDeque if you need that. - - void PushHead(morkNext* ioLink); // add to head of list - void PushTail(morkNext* ioLink); // add to tail of list -}; - -/*============================================================================= - * morkLink: linked list node embedded in objs to allow insertion in morkDeques - */ - -class morkLink /*d*/ { -public: - morkLink* mLink_Next; - morkLink* mLink_Prev; - -public: - morkLink(int inZero) : mLink_Next( 0 ), mLink_Prev( 0 ) { } - - morkLink(); // mLink_Next( 0 ), mLink_Prev( 0 ) { } - -public: - morkLink* Next() const { return mLink_Next; } - morkLink* Prev() const { return mLink_Prev; } - - void SelfRefer() { mLink_Next = mLink_Prev = this; } - void Clear() { mLink_Next = mLink_Prev = 0; } - - void AddBefore(morkLink* old) - { - ((old)->mLink_Prev->mLink_Next = (this))->mLink_Prev = (old)->mLink_Prev; - ((this)->mLink_Next = (old))->mLink_Prev = this; - } - - void AddAfter(morkLink* old) - { - ((old)->mLink_Next->mLink_Prev = (this))->mLink_Next = (old)->mLink_Next; - ((this)->mLink_Prev = (old))->mLink_Next = this; - } - - void Remove() - { - (mLink_Prev->mLink_Next = mLink_Next)->mLink_Prev = mLink_Prev; - } - -public: // link memory management methods - static void* MakeNewLink(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev); - void ZapOldLink(morkEnv* ev, nsIMdbHeap* ioHeap); - -public: // link memory management operators - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkLink::MakeNewLink(inSize, ioHeap, ev); } - -}; - -/*============================================================================= - * morkDeque: doubly linked list modeled after VAX queue instructions - */ - -class morkDeque /*d*/ { -public: - morkLink mDeque_Head; - -public: // construction - morkDeque(); // { mDeque_Head.SelfRefer(); } - -public:// methods - morkLink* RemoveFirst(); - - morkLink* RemoveLast(); - - morkLink* At(mork_pos index) const ; /* one-based, not zero-based */ - - mork_pos IndexOf(const morkLink* inMember) const; - /* one-based index ; zero means member is not in deque */ - - mork_num Length() const; - - /* the following method is more efficient for long lists: */ - int LengthCompare(mork_num inCount) const; - /* -1: length < count, 0: length == count, 1: length > count */ - -public: // inlines - - mork_bool IsEmpty()const - { return (mDeque_Head.mLink_Next == (morkLink*) &mDeque_Head); } - - morkLink* After(const morkLink* old) const - { return (((old)->mLink_Next != &mDeque_Head)? - (old)->mLink_Next : (morkLink*) 0); } - - morkLink* Before(const morkLink* old) const - { return (((old)->mLink_Prev != &mDeque_Head)? - (old)->mLink_Prev : (morkLink*) 0); } - - morkLink* First() const - { return ((mDeque_Head.mLink_Next != &mDeque_Head)? - mDeque_Head.mLink_Next : (morkLink*) 0); } - - morkLink* Last() const - { return ((mDeque_Head.mLink_Prev != &mDeque_Head)? - mDeque_Head.mLink_Prev : (morkLink*) 0); } - -/* -From IronDoc documentation for AddFirst: -+--------+ +--------+ +--------+ +--------+ +--------+ -| h.next |-->| b.next | | h.next |-->| a.next |-->| b.next | -+--------+ +--------+ ==> +--------+ +--------+ +--------+ -| h.prev |<--| b.prev | | h.prev |<--| a.prev |<--| b.prev | -+--------+ +--------+ +--------+ +--------+ +--------+ -*/ - - void AddFirst(morkLink* in) /*i*/ - { - ( (mDeque_Head.mLink_Next->mLink_Prev = - (in))->mLink_Next = mDeque_Head.mLink_Next, - ((in)->mLink_Prev = &mDeque_Head)->mLink_Next = (in) ); - } -/* -From IronDoc documentation for AddLast: -+--------+ +--------+ +--------+ +--------+ +--------+ -| y.next |-->| h.next | | y.next |-->| z.next |-->| h.next | -+--------+ +--------+ ==> +--------+ +--------+ +--------+ -| y.prev |<--| h.prev | | y.prev |<--| z.prev |<--| h.prev | -+--------+ +--------+ +--------+ +--------+ +--------+ -*/ - - void AddLast(morkLink* in) - { - ( (mDeque_Head.mLink_Prev->mLink_Next = - (in))->mLink_Prev = mDeque_Head.mLink_Prev, - ((in)->mLink_Next = &mDeque_Head)->mLink_Prev = (in) ); - } -}; - -#endif /* _MORKDEQUE_ */ diff --git a/db/mork/src/morkEnv.cpp b/db/mork/src/morkEnv.cpp deleted file mode 100644 index 1815cd3fb705..000000000000 --- a/db/mork/src/morkEnv.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKCH_ -#include "morkCh.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKFACTORY_ -#include "morkFactory.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkEnv::CloseMorkNode(morkEnv* ev) /*i*/ // CloseEnv() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseEnv(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkEnv::~morkEnv() /*i*/ // assert CloseEnv() executed earlier -{ - CloseMorkNode(mMorkEnv); - if (mEnv_Heap) - { - mork_bool ownsHeap = mEnv_OwnsHeap; - nsIMdbHeap*saveHeap = mEnv_Heap; - - if (ownsHeap) - { -#ifdef MORK_DEBUG_HEAP_STATS - printf("%d blocks remaining \n", ((orkinHeap *) saveHeap)->HeapBlockCount()); - mork_u4* array = (mork_u4*) this; - array -= 3; - // null out heap ptr in mem block so we won't crash trying to use it to - // delete the env. - *array = nsnull; -#endif // MORK_DEBUG_HEAP_STATS - // whoops, this is our heap - hmm. Can't delete it, or not allocate env's from - // an orkinHeap. - delete saveHeap; - } - - } -// MORK_ASSERT(mEnv_SelfAsMdbEnv==0); - MORK_ASSERT(mEnv_ErrorHook==0); -} - -/* choose morkBool_kTrue or morkBool_kFalse for kBeVerbose: */ -#define morkEnv_kBeVerbose morkBool_kFalse - -/*public non-poly*/ -morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap) -: morkObject(inUsage, ioHeap, morkColor_kNone) -, mEnv_Factory( ioFactory ) -, mEnv_Heap( ioSlotHeap ) - -, mEnv_SelfAsMdbEnv( 0 ) -, mEnv_ErrorHook( 0 ) -, mEnv_HandlePool( 0 ) - -, mEnv_ErrorCount( 0 ) -, mEnv_WarningCount( 0 ) - -, mEnv_ErrorCode( 0 ) - -, mEnv_DoTrace( morkBool_kFalse ) -, mEnv_AutoClear( morkAble_kDisabled ) -, mEnv_ShouldAbort( morkBool_kFalse ) -, mEnv_BeVerbose( morkEnv_kBeVerbose ) -, mEnv_OwnsHeap ( morkBool_kFalse ) -{ - MORK_ASSERT(ioSlotHeap && ioFactory ); - if ( ioSlotHeap ) - { - // mEnv_Heap is NOT refcounted: - // nsIMdbHeap_SlotStrongHeap(ioSlotHeap, this, &mEnv_Heap); - - mEnv_HandlePool = new morkPool(morkUsage::kGlobal, - (nsIMdbHeap*) 0, ioSlotHeap); - - MORK_ASSERT(mEnv_HandlePool); - if ( mEnv_HandlePool && this->Good() ) - { - mNode_Derived = morkDerived_kEnv; - mNode_Refs += morkEnv_kWeakRefCountEnvBonus; - } - } -} - -/*public non-poly*/ -morkEnv::morkEnv(morkEnv* ev, /*i*/ - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbEnv* inSelfAsMdbEnv, - morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mEnv_Factory( ioFactory ) -, mEnv_Heap( ioSlotHeap ) - -, mEnv_SelfAsMdbEnv( inSelfAsMdbEnv ) -, mEnv_ErrorHook( 0 ) -, mEnv_HandlePool( 0 ) - -, mEnv_ErrorCount( 0 ) -, mEnv_WarningCount( 0 ) - -, mEnv_ErrorCode( 0 ) - -, mEnv_DoTrace( morkBool_kFalse ) -, mEnv_AutoClear( morkAble_kDisabled ) -, mEnv_ShouldAbort( morkBool_kFalse ) -, mEnv_BeVerbose( morkEnv_kBeVerbose ) -, mEnv_OwnsHeap ( morkBool_kFalse ) -{ - // $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv?? - - if ( ioFactory && inSelfAsMdbEnv && ioSlotHeap) - { - // mEnv_Heap is NOT refcounted: - // nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mEnv_Heap); - - mEnv_HandlePool = new(*ioSlotHeap, ev) morkPool(ev, - morkUsage::kHeap, ioSlotHeap, ioSlotHeap); - - MORK_ASSERT(mEnv_HandlePool); - if ( mEnv_HandlePool && ev->Good() ) - { - mNode_Derived = morkDerived_kEnv; - mNode_Refs += morkEnv_kWeakRefCountEnvBonus; - } - } - else - ev->NilPointerError(); -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkEnv, morkObject, nsIMdbEnv) -/*public non-poly*/ void -morkEnv::CloseEnv(morkEnv* ev) /*i*/ // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - // $$$ release mEnv_SelfAsMdbEnv?? - // $$$ release mEnv_ErrorHook?? - - mEnv_SelfAsMdbEnv = 0; - mEnv_ErrorHook = 0; - - morkPool* savePool = mEnv_HandlePool; - morkPool::SlotStrongPool((morkPool*) 0, ev, &mEnv_HandlePool); - // free the pool - if (mEnv_SelfAsMdbEnv) - { - if (savePool && mEnv_Heap) - mEnv_Heap->Free(this->AsMdbEnv(), savePool); - } - else - { - if (savePool) - { - if (savePool->IsOpenNode()) - savePool->CloseMorkNode(ev); - delete savePool; - } - // how do we free this? might need to get rid of asserts. - } - // mEnv_Factory is NOT refcounted - - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -mork_size -morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid) -// sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope); -{ - mork_u1* p = (mork_u1*) outBuf; - mork_size outSize = this->TokenAsHex(p, inOid.mOid_Id); - p += outSize; - *p++ = ':'; - - mork_scope scope = inOid.mOid_Scope; - if ( scope < 0x80 && morkCh_IsName((mork_ch) scope) ) - { - *p++ = (mork_u1) scope; - *p = 0; // null termination - outSize += 2; - } - else - { - *p++ = '^'; - mork_size scopeSize = this->TokenAsHex(p, scope); - outSize += scopeSize + 2; - } - return outSize; -} - - -mork_u1 -morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex) -{ - mork_u1 hi = 0; // high four hex bits - mork_flags f = morkCh_GetFlags(inFirstHex); - if ( morkFlags_IsDigit(f) ) - hi = (mork_u1) (inFirstHex - (mork_ch) '0'); - else if ( morkFlags_IsUpper(f) ) - hi = (mork_u1) ((inFirstHex - (mork_ch) 'A') + 10); - else if ( morkFlags_IsLower(f) ) - hi = (mork_u1) ((inFirstHex - (mork_ch) 'a') + 10); - - mork_u1 lo = 0; // low four hex bits - f = morkCh_GetFlags(inSecondHex); - if ( morkFlags_IsDigit(f) ) - lo = (mork_u1) (inSecondHex - (mork_ch) '0'); - else if ( morkFlags_IsUpper(f) ) - lo = (mork_u1) ((inSecondHex - (mork_ch) 'A') + 10); - else if ( morkFlags_IsLower(f) ) - lo = (mork_u1) ((inSecondHex - (mork_ch) 'a') + 10); - - return (mork_u1) ((hi << 4) | lo); -} - -mork_size -morkEnv::TokenAsHex(void* outBuf, mork_token inToken) - // TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken); -{ - static const char morkEnv_kHexDigits[] = "0123456789ABCDEF"; - char* p = (char*) outBuf; - char* end = p + 32; // write no more than 32 digits for safety - if ( inToken ) - { - // first write all the hex digits in backwards order: - while ( p < end && inToken ) // more digits to write? - { - *p++ = morkEnv_kHexDigits[ inToken & 0x0F ]; // low four bits - inToken >>= 4; // we fervently hope this does not sign extend - } - *p = 0; // end the string with a null byte - char* s = (char*) outBuf; // first byte in string - mork_size size = (mork_size) (p - s); // distance from start - - // now reverse the string in place: - // note that p starts on the null byte, so we need predecrement: - while ( --p > s ) // need to swap another byte in the string? - { - char c = *p; // temp for swap - *p = *s; - *s++ = c; // move s forward here, and p backward in the test - } - return size; - } - else // special case for zero integer - { - *p++ = '0'; // write a zero digit - *p = 0; // end with a null byte - return 1; // one digit in hex representation - } -} - -void -morkEnv::StringToYarn(const char* inString, mdbYarn* outYarn) -{ - if ( outYarn ) - { - mdb_fill fill = ( inString )? (mdb_fill) MORK_STRLEN(inString) : 0; - - if ( fill ) // have nonempty content? - { - mdb_size size = outYarn->mYarn_Size; // max dest size - if ( fill > size ) // too much string content? - { - outYarn->mYarn_More = fill - size; // extra string bytes omitted - fill = size; // copy no more bytes than size of yarn buffer - } - void* dest = outYarn->mYarn_Buf; // where bytes are going - if ( !dest ) // nil destination address buffer? - fill = 0; // we can't write any content at all - - if ( fill ) // anything to copy? - MORK_MEMCPY(dest, inString, fill); // copy fill bytes to yarn - - outYarn->mYarn_Fill = fill; // tell yarn size of copied content - } - else // no content to put into the yarn - { - outYarn->mYarn_Fill = 0; // tell yarn that string has no bytes - } - outYarn->mYarn_Form = 0; // always update the form slot - } - else - this->NilPointerError(); -} - -char* -morkEnv::CopyString(nsIMdbHeap* ioHeap, const char* inString) -{ - char* outString = 0; - if ( ioHeap && inString ) - { - mork_size size = MORK_STRLEN(inString) + 1; - ioHeap->Alloc(this->AsMdbEnv(), size, (void**) &outString); - if ( outString ) - MORK_STRCPY(outString, inString); - } - else - this->NilPointerError(); - return outString; -} - -void -morkEnv::FreeString(nsIMdbHeap* ioHeap, char* ioString) -{ - if ( ioHeap ) - { - if ( ioString ) - ioHeap->Free(this->AsMdbEnv(), ioString); - } - else - this->NilPointerError(); -} - -void -morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode) -{ - MORK_ASSERT(morkBool_kFalse); // get developer's attention - - ++mEnv_ErrorCount; - mEnv_ErrorCode = (mork_u4) ((inCode)? inCode: morkEnv_kGenericError); - - if ( mEnv_ErrorHook ) - mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString); -} - -void -morkEnv::NewError(const char* inString) -{ - MORK_ASSERT(morkBool_kFalse); // get developer's attention - - ++mEnv_ErrorCount; - mEnv_ErrorCode = morkEnv_kGenericError; - - if ( mEnv_ErrorHook ) - mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString); -} - -void -morkEnv::NewWarning(const char* inString) -{ - MORK_ASSERT(morkBool_kFalse); // get developer's attention - - ++mEnv_WarningCount; - if ( mEnv_ErrorHook ) - mEnv_ErrorHook->OnWarningString(this->AsMdbEnv(), inString); -} - -void -morkEnv::StubMethodOnlyError() -{ - this->NewError("method is stub only"); -} - -void -morkEnv::OutOfMemoryError() -{ - this->NewError("out of memory"); -} - -void -morkEnv::CantMakeWhenBadError() -{ - this->NewError("can't make an object when ev->Bad()"); -} - -static const char morkEnv_kNilPointer[] = "nil pointer"; - -void -morkEnv::NilPointerError() -{ - this->NewError(morkEnv_kNilPointer); -} - -void -morkEnv::NilPointerWarning() -{ - this->NewWarning(morkEnv_kNilPointer); -} - -void -morkEnv::NewNonEnvError() -{ - this->NewError("non-env instance"); -} - -void -morkEnv::NilEnvSlotError() -{ - if ( !mEnv_HandlePool || !mEnv_Factory ) - { - if ( !mEnv_HandlePool ) - this->NewError("nil mEnv_HandlePool"); - if ( !mEnv_Factory ) - this->NewError("nil mEnv_Factory"); - } - else - this->NewError("unknown nil env slot"); -} - - -void morkEnv::NonEnvTypeError(morkEnv* ev) -{ - ev->NewError("non morkEnv"); -} - -void -morkEnv::ClearMorkErrorsAndWarnings() -{ - mEnv_ErrorCount = 0; - mEnv_WarningCount = 0; - mEnv_ErrorCode = 0; - mEnv_ShouldAbort = morkBool_kFalse; -} - -void -morkEnv::AutoClearMorkErrorsAndWarnings() -{ - if ( this->DoAutoClear() ) - { - mEnv_ErrorCount = 0; - mEnv_WarningCount = 0; - mEnv_ErrorCode = 0; - mEnv_ShouldAbort = morkBool_kFalse; - } -} - -/*static*/ morkEnv* -morkEnv::FromMdbEnv(nsIMdbEnv* ioEnv) // dynamic type checking -{ - morkEnv* outEnv = 0; - if ( ioEnv ) - { - // Note this cast is expected to perform some address adjustment of the - // pointer, so oenv likely does not equal ioEnv. Do not cast to void* - // first to force an exactly equal pointer (we tried it and it's wrong). - morkEnv* ev = (morkEnv*) ioEnv; - if ( ev && ev->IsEnv() ) - { - if ( ev->DoAutoClear() ) - { - ev->mEnv_ErrorCount = 0; - ev->mEnv_WarningCount = 0; - ev->mEnv_ErrorCode = 0; - } - outEnv = ev; - } - else - MORK_ASSERT(outEnv); - } - else - MORK_ASSERT(outEnv); - return outEnv; -} - - -NS_IMETHODIMP -morkEnv::GetErrorCount(mdb_count* outCount, - mdb_bool* outShouldAbort) -{ - if ( outCount ) - *outCount = mEnv_ErrorCount; - if ( outShouldAbort ) - *outShouldAbort = mEnv_ShouldAbort; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetWarningCount(mdb_count* outCount, - mdb_bool* outShouldAbort) -{ - if ( outCount ) - *outCount = mEnv_WarningCount; - if ( outShouldAbort ) - *outShouldAbort = mEnv_ShouldAbort; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetEnvBeVerbose(mdb_bool* outBeVerbose) -{ - NS_ENSURE_ARG_POINTER(outBeVerbose); - *outBeVerbose = mEnv_BeVerbose; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::SetEnvBeVerbose(mdb_bool inBeVerbose) -{ - mEnv_BeVerbose = inBeVerbose; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetDoTrace(mdb_bool* outDoTrace) -{ - NS_ENSURE_ARG_POINTER(outDoTrace); - *outDoTrace = mEnv_DoTrace; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::SetDoTrace(mdb_bool inDoTrace) -{ - mEnv_DoTrace = inDoTrace; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetAutoClear(mdb_bool* outAutoClear) -{ - NS_ENSURE_ARG_POINTER(outAutoClear); - *outAutoClear = DoAutoClear(); - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::SetAutoClear(mdb_bool inAutoClear) -{ - if ( inAutoClear ) - EnableAutoClear(); - else - DisableAutoClear(); - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetErrorHook(nsIMdbErrorHook** acqErrorHook) -{ - NS_ENSURE_ARG_POINTER(acqErrorHook); - *acqErrorHook = mEnv_ErrorHook; - NS_IF_ADDREF(mEnv_ErrorHook); - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::SetErrorHook( - nsIMdbErrorHook* ioErrorHook) // becomes referenced -{ - mEnv_ErrorHook = ioErrorHook; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::GetHeap(nsIMdbHeap** acqHeap) -{ - NS_ENSURE_ARG_POINTER(acqHeap); - nsIMdbHeap* outHeap = 0; - nsIMdbHeap* heap = mEnv_Heap; - if ( heap && heap->HeapAddStrongRef(this) == 0 ) - outHeap = heap; - - if ( acqHeap ) - *acqHeap = outHeap; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::SetHeap( - nsIMdbHeap* ioHeap) // becomes referenced -{ - nsIMdbHeap_SlotStrongHeap(ioHeap, this, &mEnv_Heap); - return NS_OK; -} -// } ----- end attribute methods ----- - -NS_IMETHODIMP -morkEnv::ClearErrors() // clear errors beore re-entering db API -{ - mEnv_ErrorCount = 0; - mEnv_ErrorCode = 0; - mEnv_ShouldAbort = morkBool_kFalse; - - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::ClearWarnings() // clear warning -{ - mEnv_WarningCount = 0; - return NS_OK; -} - -NS_IMETHODIMP -morkEnv::ClearErrorsAndWarnings() // clear both errors & warnings -{ - ClearMorkErrorsAndWarnings(); - return NS_OK; -} -// } ===== end nsIMdbEnv methods ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkEnv.h b/db/mork/src/morkEnv.h deleted file mode 100644 index 11c80b941a6f..000000000000 --- a/db/mork/src/morkEnv.h +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKENV_ -#define _MORKENV_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -// sean was here -#include "nsError.h" - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kEnv /*i*/ 0x4576 /* ascii 'Ev' */ - -// use NS error codes to make Mork easier to use with the rest of mozilla -#define morkEnv_kNoError NS_SUCCEEDED /* no error has happened */ -#define morkEnv_kGenericError NS_ERROR_FAILURE /* non-specific error code */ -#define morkEnv_kNonEnvTypeError NS_ERROR_FAILURE /* morkEnv::IsEnv() is false */ - -#define morkEnv_kStubMethodOnlyError NS_ERROR_NO_INTERFACE -#define morkEnv_kOutOfMemoryError NS_ERROR_OUT_OF_MEMORY -#define morkEnv_kNilPointerError NS_ERROR_NULL_POINTER -#define morkEnv_kNewNonEnvError NS_ERROR_FAILURE -#define morkEnv_kNilEnvSlotError NS_ERROR_FAILURE - -#define morkEnv_kBadFactoryError NS_ERROR_FACTORY_NOT_LOADED -#define morkEnv_kBadFactoryEnvError NS_ERROR_FACTORY_NOT_LOADED -#define morkEnv_kBadEnvError NS_ERROR_FAILURE - -#define morkEnv_kNonHandleTypeError NS_ERROR_FAILURE -#define morkEnv_kNonOpenNodeError NS_ERROR_FAILURE - - -#define morkEnv_kWeakRefCountEnvBonus 0 /* try NOT to leak all env instances */ - -/*| morkEnv: -|*/ -class morkEnv : public morkObject, public nsIMdbEnv { - NS_DECL_ISUPPORTS_INHERITED - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // state is public because the entire Mork system is private - - morkFactory* mEnv_Factory; // NON-refcounted factory - nsIMdbHeap* mEnv_Heap; // NON-refcounted heap - - nsIMdbEnv* mEnv_SelfAsMdbEnv; - nsIMdbErrorHook* mEnv_ErrorHook; - - morkPool* mEnv_HandlePool; // pool for re-using handles - - mork_u2 mEnv_ErrorCount; - mork_u2 mEnv_WarningCount; - - mork_u4 mEnv_ErrorCode; // simple basis for mdb_err style errors - - mork_bool mEnv_DoTrace; - mork_able mEnv_AutoClear; - mork_bool mEnv_ShouldAbort; - mork_bool mEnv_BeVerbose; - mork_bool mEnv_OwnsHeap; - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseEnv() only if open - virtual ~morkEnv(); // assert that CloseEnv() executed earlier - - // { ----- begin attribute methods ----- - NS_IMETHOD GetErrorCount(mdb_count* outCount, - mdb_bool* outShouldAbort); - NS_IMETHOD GetWarningCount(mdb_count* outCount, - mdb_bool* outShouldAbort); - - NS_IMETHOD GetEnvBeVerbose(mdb_bool* outBeVerbose); - NS_IMETHOD SetEnvBeVerbose(mdb_bool inBeVerbose); - - NS_IMETHOD GetDoTrace(mdb_bool* outDoTrace); - NS_IMETHOD SetDoTrace(mdb_bool inDoTrace); - - NS_IMETHOD GetAutoClear(mdb_bool* outAutoClear); - NS_IMETHOD SetAutoClear(mdb_bool inAutoClear); - - NS_IMETHOD GetErrorHook(nsIMdbErrorHook** acqErrorHook); - NS_IMETHOD SetErrorHook( - nsIMdbErrorHook* ioErrorHook); // becomes referenced - - NS_IMETHOD GetHeap(nsIMdbHeap** acqHeap); - NS_IMETHOD SetHeap( - nsIMdbHeap* ioHeap); // becomes referenced - // } ----- end attribute methods ----- - - NS_IMETHOD ClearErrors(); // clear errors beore re-entering db API - NS_IMETHOD ClearWarnings(); // clear warnings - NS_IMETHOD ClearErrorsAndWarnings(); // clear both errors & warnings -// } ===== end nsIMdbEnv methods ===== -public: // morkEnv construction & destruction - morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap); - morkEnv(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbEnv* inSelfAsMdbEnv, morkFactory* ioFactory, - nsIMdbHeap* ioSlotHeap); - void CloseEnv(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkEnv(const morkEnv& other); - morkEnv& operator=(const morkEnv& other); - -public: // dynamic type identification - mork_bool IsEnv() const - { return IsNode() && mNode_Derived == morkDerived_kEnv; } -// } ===== end morkNode methods ===== - -public: // utility env methods - - mork_u1 HexToByte(mork_ch inFirstHex, mork_ch inSecondHex); - - mork_size TokenAsHex(void* outBuf, mork_token inToken); - // TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken); - - mork_size OidAsHex(void* outBuf, const mdbOid& inOid); - // sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope); - - char* CopyString(nsIMdbHeap* ioHeap, const char* inString); - void FreeString(nsIMdbHeap* ioHeap, char* ioString); - void StringToYarn(const char* inString, mdbYarn* outYarn); - -public: // other env methods - - morkHandleFace* NewHandle(mork_size inSize) - { return mEnv_HandlePool->NewHandle(this, inSize, (morkZone*) 0); } - - void ZapHandle(morkHandleFace* ioHandle) - { mEnv_HandlePool->ZapHandle(this, ioHandle); } - - void EnableAutoClear() { mEnv_AutoClear = morkAble_kEnabled; } - void DisableAutoClear() { mEnv_AutoClear = morkAble_kDisabled; } - - mork_bool DoAutoClear() const - { return mEnv_AutoClear == morkAble_kEnabled; } - - void NewErrorAndCode(const char* inString, mork_u2 inCode); - void NewError(const char* inString); - void NewWarning(const char* inString); - - void ClearMorkErrorsAndWarnings(); // clear both errors & warnings - void AutoClearMorkErrorsAndWarnings(); // clear if auto is enabled - - void StubMethodOnlyError(); - void OutOfMemoryError(); - void NilPointerError(); - void NilPointerWarning(); - void CantMakeWhenBadError(); - void NewNonEnvError(); - void NilEnvSlotError(); - - void NonEnvTypeError(morkEnv* ev); - - // canonical env convenience methods to check for presence of errors: - mork_bool Good() const { return ( mEnv_ErrorCount == 0 ); } - mork_bool Bad() const { return ( mEnv_ErrorCount != 0 ); } - - nsIMdbEnv* AsMdbEnv() { return (nsIMdbEnv *) this; } - static morkEnv* FromMdbEnv(nsIMdbEnv* ioEnv); // dynamic type checking - - mork_u4 ErrorCode() const { return mEnv_ErrorCode; } - - mdb_err AsErr() const { return (mdb_err) mEnv_ErrorCode; } - //mdb_err AsErr() const { return (mdb_err) ( mEnv_ErrorCount != 0 ); } - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakEnv(morkEnv* me, - morkEnv* ev, morkEnv** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongEnv(morkEnv* me, - morkEnv* ev, morkEnv** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKENV_ */ diff --git a/db/mork/src/morkFactory.cpp b/db/mork/src/morkFactory.cpp deleted file mode 100644 index 0d6388bb0379..000000000000 --- a/db/mork/src/morkFactory.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKFACTORY_ -#include "morkFactory.h" -#endif - -#ifndef _ORKINHEAP_ -#include "orkinHeap.h" -#endif - -#ifndef _MORKFILE_ -#include "morkFile.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKTHUMB_ -#include "morkThumb.h" -#endif - -#ifndef _MORKWRITER_ -#include "morkWriter.h" -#endif -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkFactory::CloseMorkNode(morkEnv* ev) /*i*/ // CloseFactory() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseFactory(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkFactory::~morkFactory() /*i*/ // assert CloseFactory() executed earlier -{ - CloseFactory(&mFactory_Env); - MORK_ASSERT(mFactory_Env.IsShutNode()); - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkFactory::morkFactory() // uses orkinHeap -: morkObject(morkUsage::kGlobal, (nsIMdbHeap*) 0, morkColor_kNone) -, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this, - new orkinHeap()) -, mFactory_Heap() -{ - if ( mFactory_Env.Good() ) - { - mNode_Derived = morkDerived_kFactory; - mNode_Refs += morkFactory_kWeakRefCountBonus; - } -} - -/*public non-poly*/ -morkFactory::morkFactory(nsIMdbHeap* ioHeap) -: morkObject(morkUsage::kHeap, ioHeap, morkColor_kNone) -, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this, ioHeap) -, mFactory_Heap() -{ - if ( mFactory_Env.Good() ) - { - mNode_Derived = morkDerived_kFactory; - mNode_Refs += morkFactory_kWeakRefCountBonus; - } -} - -/*public non-poly*/ -morkFactory::morkFactory(morkEnv* ev, /*i*/ - const morkUsage& inUsage, nsIMdbHeap* ioHeap) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this, ioHeap) -, mFactory_Heap() -{ - if ( ev->Good() ) - { - mNode_Derived = morkDerived_kFactory; - mNode_Refs += morkFactory_kWeakRefCountBonus; - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkFactory, morkObject, nsIMdbFactory) - -extern "C" nsIMdbFactory* MakeMdbFactory() -{ - return new morkFactory(new orkinHeap()); -} - - -/*public non-poly*/ void -morkFactory::CloseFactory(morkEnv* ev) /*i*/ // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mFactory_Env.CloseMorkNode(ev); - this->CloseObject(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -morkEnv* morkFactory::GetInternalFactoryEnv(mdb_err* outErr) -{ - morkEnv* outEnv = 0; - if (IsNode() && IsOpenNode() && IsFactory() ) - { - morkEnv* fenv = &mFactory_Env; - if ( fenv && fenv->IsNode() && fenv->IsOpenNode() && fenv->IsEnv() ) - { - fenv->ClearMorkErrorsAndWarnings(); // drop any earlier errors - outEnv = fenv; - } - else - *outErr = morkEnv_kBadFactoryEnvError; - } - else - *outErr = morkEnv_kBadFactoryError; - - return outEnv; -} - - -void -morkFactory::NonFactoryTypeError(morkEnv* ev) -{ - ev->NewError("non morkFactory"); -} - - -NS_IMETHODIMP -morkFactory::OpenOldFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap, - const char* inFilePath, - mork_bool inFrozen, nsIMdbFile** acqFile) - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be open and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - morkFile* file = nsnull; - if ( ev ) - { - if ( !ioHeap ) - ioHeap = &mFactory_Heap; - - file = morkFile::OpenOldFile(ev, ioHeap, inFilePath, inFrozen); - NS_IF_ADDREF( file ); - - outErr = ev->AsErr(); - } - if ( acqFile ) - *acqFile = file; - - return outErr; -} - -NS_IMETHODIMP -morkFactory::CreateNewFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap, - const char* inFilePath, nsIMdbFile** acqFile) - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be created and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - morkFile* file = nsnull; - if ( ev ) - { - if ( !ioHeap ) - ioHeap = &mFactory_Heap; - - file = morkFile::CreateNewFile(ev, ioHeap, inFilePath); - if ( file ) - NS_ADDREF(file); - - outErr = ev->AsErr(); - } - if ( acqFile ) - *acqFile = file; - - return outErr; -} -// } ----- end file methods ----- - -// { ----- begin env methods ----- -NS_IMETHODIMP -morkFactory::MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv) -// ioHeap can be nil, causing a MakeHeap() style heap instance to be used -{ - mdb_err outErr = 0; - nsIMdbEnv* outEnv = 0; - mork_bool ownsHeap = (ioHeap == 0); - if ( !ioHeap ) - ioHeap = new orkinHeap(); - - if ( acqEnv && ioHeap ) - { - morkEnv* fenv = this->GetInternalFactoryEnv(&outErr); - if ( fenv ) - { - morkEnv* newEnv = new(*ioHeap, fenv) - morkEnv(morkUsage::kHeap, ioHeap, this, ioHeap); - - if ( newEnv ) - { - newEnv->mEnv_OwnsHeap = ownsHeap; - newEnv->mNode_Refs += morkEnv_kWeakRefCountEnvBonus; - NS_ADDREF(newEnv); - newEnv->mEnv_SelfAsMdbEnv = newEnv; - outEnv = newEnv; - } - else - outErr = morkEnv_kOutOfMemoryError; - } - - *acqEnv = outEnv; - } - else - outErr = morkEnv_kNilPointerError; - - return outErr; -} -// } ----- end env methods ----- - -// { ----- begin heap methods ----- -NS_IMETHODIMP -morkFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap) -{ - mdb_err outErr = 0; - nsIMdbHeap* outHeap = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - outHeap = new orkinHeap(); - if ( !outHeap ) - ev->OutOfMemoryError(); - } - MORK_ASSERT(acqHeap); - if ( acqHeap ) - *acqHeap = outHeap; - return outErr; -} -// } ----- end heap methods ----- - -// { ----- begin compare methods ----- -NS_IMETHODIMP -morkFactory::MakeCompare(nsIMdbEnv* mev, nsIMdbCompare** acqCompare) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end compare methods ----- - -// { ----- begin row methods ----- -NS_IMETHODIMP -morkFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap, - nsIMdbRow** acqRow) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// ioHeap can be nil, causing the heap associated with ev to be used -// } ----- end row methods ----- - -// { ----- begin port methods ----- -NS_IMETHODIMP -morkFactory::CanOpenFilePort( - nsIMdbEnv* mev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpen, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion) -{ - mdb_err outErr = 0; - if ( outFormatVersion ) - { - outFormatVersion->mYarn_Fill = 0; - } - mdb_bool canOpenAsPort = morkBool_kFalse; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioFile && outCanOpen ) - { - canOpenAsPort = this->CanOpenMorkTextFile(ev, ioFile); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - - if ( outCanOpen ) - *outCanOpen = canOpenAsPort; - - return outErr; -} - -NS_IMETHODIMP -morkFactory::OpenFilePort( - nsIMdbEnv* mev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for readonly import - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb) -{ - NS_ASSERTION(PR_FALSE, "this doesn't look implemented"); - MORK_USED_1(ioHeap); - mdb_err outErr = 0; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioFile && inOpenPolicy && acqThumb ) - { - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then call nsIMdbFactory::ThumbToOpenPort() to get the port instance. - -NS_IMETHODIMP -morkFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort() - nsIMdbEnv* mev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status - nsIMdbPort** acqPort) -{ - mdb_err outErr = 0; - nsIMdbPort* outPort = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioThumb && acqPort ) - { - morkThumb* thumb = (morkThumb*) ioThumb; - morkStore* store = thumb->ThumbToOpenStore(ev); - if ( store ) - { - store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue; - store->mStore_CanDirty = morkBool_kTrue; - store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue); - - NS_ADDREF(store); - outPort = store; - } - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqPort ) - *acqPort = outPort; - return outErr; -} -// } ----- end port methods ----- - -mork_bool -morkFactory::CanOpenMorkTextFile(morkEnv* ev, - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile) -{ - MORK_USED_1(ev); - mork_bool outBool = morkBool_kFalse; - mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader); - - char localBuf[ 256 + 4 ]; // for extra for sloppy safety - mdbYarn localYarn; - mdbYarn* y = &localYarn; - y->mYarn_Buf = localBuf; // space to hold content - y->mYarn_Fill = 0; // no logical content yet - y->mYarn_Size = 256; // physical capacity is 256 bytes - y->mYarn_More = 0; - y->mYarn_Form = 0; - y->mYarn_Grow = 0; - - if ( ioFile ) - { - nsIMdbEnv* menv = ev->AsMdbEnv(); - mdb_size actualSize = 0; - ioFile->Get(menv, y->mYarn_Buf, y->mYarn_Size, /*pos*/ 0, &actualSize); - y->mYarn_Fill = actualSize; - - if ( y->mYarn_Buf && actualSize >= headSize && ev->Good() ) - { - mork_u1* buf = (mork_u1*) y->mYarn_Buf; - outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 ); - } - } - else - ev->NilPointerError(); - - return outBool; -} - -// { ----- begin store methods ----- -NS_IMETHODIMP -morkFactory::CanOpenFileStore( - nsIMdbEnv* mev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed - mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion) -{ - mdb_bool canOpenAsStore = morkBool_kFalse; - mdb_bool canOpenAsPort = morkBool_kFalse; - if ( outFormatVersion ) - { - outFormatVersion->mYarn_Fill = 0; - } - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioFile && outCanOpenAsStore ) - { - // right now always say true; later we should look for magic patterns - canOpenAsStore = this->CanOpenMorkTextFile(ev, ioFile); - canOpenAsPort = canOpenAsStore; - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( outCanOpenAsStore ) - *outCanOpenAsStore = canOpenAsStore; - - if ( outCanOpenAsPort ) - *outCanOpenAsPort = canOpenAsPort; - - return outErr; -} - -NS_IMETHODIMP -morkFactory::OpenFileStore( // open an existing database - nsIMdbEnv* mev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for general db usage - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb) -{ - mdb_err outErr = 0; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( !ioHeap ) // need to use heap from env? - ioHeap = ev->mEnv_Heap; - - if ( ioFile && inOpenPolicy && acqThumb ) - { - morkStore* store = new(*ioHeap, ev) - morkStore(ev, morkUsage::kHeap, ioHeap, this, ioHeap); - - if ( store ) - { - mork_bool frozen = morkBool_kFalse; // open store mutable access - if ( store->OpenStoreFile(ev, frozen, ioFile, inOpenPolicy) ) - { - morkThumb* thumb = morkThumb::Make_OpenFileStore(ev, ioHeap, store); - if ( thumb ) - { - outThumb = thumb; - thumb->AddRef(); - } - } -// store->CutStrongRef(mev); // always cut ref (handle has its own ref) - } - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then call nsIMdbFactory::ThumbToOpenStore() to get the store instance. - -NS_IMETHODIMP -morkFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore() - nsIMdbEnv* mev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status - nsIMdbStore** acqStore) -{ - mdb_err outErr = 0; - nsIMdbStore* outStore = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioThumb && acqStore ) - { - morkThumb* thumb = (morkThumb*) ioThumb; - morkStore* store = thumb->ThumbToOpenStore(ev); - if ( store ) - { - store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue; - store->mStore_CanDirty = morkBool_kTrue; - store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue); - - outStore = store; - NS_ADDREF(store); - } - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqStore ) - *acqStore = outStore; - return outErr; -} - -NS_IMETHODIMP -morkFactory::CreateNewFileStore( // create a new db with minimal content - nsIMdbEnv* mev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // name of file which should not yet exist - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbStore** acqStore) -{ - mdb_err outErr = 0; - nsIMdbStore* outStore = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( !ioHeap ) // need to use heap from env? - ioHeap = ev->mEnv_Heap; - - if ( ioFile && inOpenPolicy && acqStore && ioHeap ) - { - morkStore* store = new(*ioHeap, ev) - morkStore(ev, morkUsage::kHeap, ioHeap, this, ioHeap); - - if ( store ) - { - store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue; - store->mStore_CanDirty = morkBool_kTrue; - store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue); - - if ( store->CreateStoreFile(ev, ioFile, inOpenPolicy) ) - outStore = store; - NS_ADDREF(store); - } - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqStore ) - *acqStore = outStore; - return outErr; -} -// } ----- end store methods ----- - -// } ===== end nsIMdbFactory methods ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkFactory.h b/db/mork/src/morkFactory.h deleted file mode 100644 index 927b4c79f05b..000000000000 --- a/db/mork/src/morkFactory.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKFACTORY_ -#define _MORKFACTORY_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _ORKINHEAP_ -#include "orkinHeap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class nsIMdbFactory; - -#define morkDerived_kFactory /*i*/ 0x4663 /* ascii 'Fc' */ -#define morkFactory_kWeakRefCountBonus 0 /* try NOT to leak all factories */ - -/*| morkFactory: -|*/ -class morkFactory : public morkObject, public nsIMdbFactory { // nsIMdbObject - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // state is public because the entire Mork system is private - - morkEnv mFactory_Env; // private env instance used internally - orkinHeap mFactory_Heap; - - NS_DECL_ISUPPORTS_INHERITED -// { ===== begin morkNode interface ===== -public: // morkFactory virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseFactory() only if open - virtual ~morkFactory(); // assert that CloseFactory() executed earlier - - -// { ===== begin nsIMdbFactory methods ===== - - // { ----- begin file methods ----- - NS_IMETHOD OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, - mdb_bool inFrozen, nsIMdbFile** acqFile); - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be open and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - - NS_IMETHOD CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, - nsIMdbFile** acqFile); - // Choose some subclass of nsIMdbFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be created and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - // } ----- end file methods ----- - - // { ----- begin env methods ----- - NS_IMETHOD MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv); // new env - // ioHeap can be nil, causing a MakeHeap() style heap instance to be used - // } ----- end env methods ----- - - // { ----- begin heap methods ----- - NS_IMETHOD MakeHeap(nsIMdbEnv* ev, nsIMdbHeap** acqHeap); // new heap - // } ----- end heap methods ----- - - // { ----- begin compare methods ----- - NS_IMETHOD MakeCompare(nsIMdbEnv* ev, nsIMdbCompare** acqCompare); // ASCII - // } ----- end compare methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbRow** acqRow); // new row - // ioHeap can be nil, causing the heap associated with ev to be used - // } ----- end row methods ----- - - // { ----- begin port methods ----- - NS_IMETHOD CanOpenFilePort( - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpen, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion); // informal file format description - - NS_IMETHOD OpenFilePort( - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for readonly import - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb); // acquire thumb for incremental port open - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then call nsIMdbFactory::ThumbToOpenPort() to get the port instance. - - NS_IMETHOD ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort() - nsIMdbEnv* ev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status - nsIMdbPort** acqPort); // acquire new port object - // } ----- end port methods ----- - - // { ----- begin store methods ----- - NS_IMETHOD CanOpenFileStore( - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to investigate - // const mdbYarn* inFirst512Bytes, - nsIMdbFile* ioFile, // db abstract file interface - mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed - mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed - mdbYarn* outFormatVersion); // informal file format description - - NS_IMETHOD OpenFileStore( // open an existing database - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // the file to open for general db usage - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbThumb** acqThumb); // acquire thumb for incremental store open - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then call nsIMdbFactory::ThumbToOpenStore() to get the store instance. - - NS_IMETHOD - ThumbToOpenStore( // redeem completed thumb from OpenFileStore() - nsIMdbEnv* ev, // context - nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status - nsIMdbStore** acqStore); // acquire new db store object - - NS_IMETHOD CreateNewFileStore( // create a new db with minimal content - nsIMdbEnv* ev, // context - nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used - // const char* inFilePath, // name of file which should not yet exist - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db - nsIMdbStore** acqStore); // acquire new db store object - // } ----- end store methods ----- - -// } ===== end nsIMdbFactory methods ===== - -public: // morkYarn construction & destruction - morkFactory(); // uses orkinHeap - morkFactory(nsIMdbHeap* ioHeap); // caller supplied heap - morkFactory(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap); - void CloseFactory(morkEnv* ev); // called by CloseMorkNode(); - - -public: // morkNode memory management operators - void* operator new(size_t inSize) CPP_THROW_NEW - { return ::operator new(inSize); } - - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkNode::MakeNew(inSize, ioHeap, ev); } - -private: // copying is not allowed - morkFactory(const morkFactory& other); - morkFactory& operator=(const morkFactory& other); - -public: // dynamic type identification - mork_bool IsFactory() const - { return IsNode() && mNode_Derived == morkDerived_kFactory; } -// } ===== end morkNode methods ===== - -public: // other factory methods - - void NonFactoryTypeError(morkEnv* ev); - morkEnv* GetInternalFactoryEnv(mdb_err* outErr); - mork_bool CanOpenMorkTextFile(morkEnv* ev, nsIMdbFile* ioFile); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakFactory(morkFactory* me, - morkEnv* ev, morkFactory** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongFactory(morkFactory* me, - morkEnv* ev, morkFactory** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKFACTORY_ */ diff --git a/db/mork/src/morkFile.cpp b/db/mork/src/morkFile.cpp deleted file mode 100644 index 74a2bf0edaa1..000000000000 --- a/db/mork/src/morkFile.cpp +++ /dev/null @@ -1,926 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKFILE_ -#include "morkFile.h" -#endif - -#ifdef MORK_WIN -#include "io.h" -#include -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkFile::CloseMorkNode(morkEnv* ev) // CloseFile() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseFile(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkFile::~morkFile() // assert CloseFile() executed earlier -{ - MORK_ASSERT(mFile_Frozen==0); - MORK_ASSERT(mFile_DoTrace==0); - MORK_ASSERT(mFile_IoOpen==0); - MORK_ASSERT(mFile_Active==0); -} - -/*public non-poly*/ -morkFile::morkFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mFile_Frozen( 0 ) -, mFile_DoTrace( 0 ) -, mFile_IoOpen( 0 ) -, mFile_Active( 0 ) - -, mFile_SlotHeap( 0 ) -, mFile_Name( 0 ) -, mFile_Thief( 0 ) -{ - if ( ev->Good() ) - { - if ( ioSlotHeap ) - { - nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mFile_SlotHeap); - if ( ev->Good() ) - mNode_Derived = morkDerived_kFile; - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkFile, morkObject, nsIMdbFile) -/*public non-poly*/ void -morkFile::CloseFile(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mFile_Frozen = 0; - mFile_DoTrace = 0; - mFile_IoOpen = 0; - mFile_Active = 0; - - if ( mFile_Name ) - this->SetFileName(ev, (const char*) 0); - - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mFile_SlotHeap); - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mFile_Thief); - - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ morkFile* -morkFile::OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, mork_bool inFrozen) - // Choose some subclass of morkFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be open and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. -{ - return morkStdioFile::OpenOldStdioFile(ev, ioHeap, inFilePath, inFrozen); -} - -/*static*/ morkFile* -morkFile::CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath) - // Choose some subclass of morkFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be created and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. -{ - return morkStdioFile::CreateNewStdioFile(ev, ioHeap, inFilePath); -} - -void -morkFile::NewMissingIoError(morkEnv* ev) const -{ - ev->NewError("file missing io"); -} - -/*static*/ void -morkFile::NonFileTypeError(morkEnv* ev) -{ - ev->NewError("non morkFile"); -} - -/*static*/ void -morkFile::NilSlotHeapError(morkEnv* ev) -{ - ev->NewError("nil mFile_SlotHeap"); -} - -/*static*/ void -morkFile::NilFileNameError(morkEnv* ev) -{ - ev->NewError("nil mFile_Name"); -} - -void -morkFile::SetThief(morkEnv* ev, nsIMdbFile* ioThief) -{ - nsIMdbFile_SlotStrongFile(ioThief, ev, &mFile_Thief); -} - -void -morkFile::SetFileName(morkEnv* ev, const char* inName) // inName can be nil -{ - nsIMdbHeap* heap = mFile_SlotHeap; - if ( heap ) - { - char* name = mFile_Name; - if ( name ) - { - mFile_Name = 0; - ev->FreeString(heap, name); - } - if ( ev->Good() && inName ) - mFile_Name = ev->CopyString(heap, inName); - } - else - this->NilSlotHeapError(ev); -} - -void -morkFile::NewFileDownError(morkEnv* ev) const -// call NewFileDownError() when either IsOpenAndActiveFile() -// is false, or when IsOpenActiveAndMutableFile() is false. -{ - if ( this->IsOpenNode() ) - { - if ( this->FileActive() ) - { - if ( this->FileFrozen() ) - { - ev->NewError("file frozen"); - } - else - ev->NewError("unknown file problem"); - } - else - ev->NewError("file not active"); - } - else - ev->NewError("file not open"); -} - -void -morkFile::NewFileErrnoError(morkEnv* ev) const -// call NewFileErrnoError() to convert std C errno into AB fault -{ - const char* errnoString = strerror(errno); - ev->NewError(errnoString); // maybe pass value of strerror() instead -} - -// ````` ````` ````` ````` newlines ````` ````` ````` ````` - -#if defined(MORK_MAC) - static const char morkFile_kNewlines[] = - "\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015"; -# define morkFile_kNewlinesCount 16 -#else -# if defined(MORK_WIN) || defined(MORK_OS2) - static const char morkFile_kNewlines[] = - "\015\012\015\012\015\012\015\012\015\012\015\012\015\012\015\012"; -# define morkFile_kNewlinesCount 8 -# else -# ifdef MORK_UNIX - static const char morkFile_kNewlines[] = - "\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012"; -# define morkFile_kNewlinesCount 16 -# endif /* MORK_UNIX */ -# endif /* MORK_WIN */ -#endif /* MORK_MAC */ - -mork_size -morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines) - // WriteNewlines() returns the number of bytes written. -{ - mork_size outSize = 0; - while ( inNewlines && ev->Good() ) // more newlines to write? - { - mork_u4 quantum = inNewlines; - if ( quantum > morkFile_kNewlinesCount ) - quantum = morkFile_kNewlinesCount; - - mork_size quantumSize = quantum * mork_kNewlineSize; - mdb_size bytesWritten; - this->Write(ev->AsMdbEnv(), morkFile_kNewlines, quantumSize, &bytesWritten); - outSize += quantumSize; - inNewlines -= quantum; - } - return outSize; -} - -NS_IMETHODIMP -morkFile::Eof(nsIMdbEnv* mev, mdb_pos* outPos) -{ - mdb_err outErr = 0; - mdb_pos pos = -1; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - pos = Length(ev); - outErr = ev->AsErr(); - if ( outPos ) - *outPos = pos; - return outErr; -} - -NS_IMETHODIMP -morkFile::Get(nsIMdbEnv* mev, void* outBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize) -{ - nsresult rv = NS_OK; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mdb_pos outPos; - Seek(mev, inPos, &outPos); - if ( ev->Good() ) - rv = Read(mev, outBuf, inSize, outActualSize); - } - return rv; -} - -NS_IMETHODIMP -morkFile::Put(nsIMdbEnv* mev, const void* inBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize) -{ - mdb_err outErr = 0; - *outActualSize = 0; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mdb_pos outPos; - - Seek(mev, inPos, &outPos); - if ( ev->Good() ) - Write(mev, inBuf, inSize, outActualSize); - outErr = ev->AsErr(); - } - return outErr; -} - -// { ----- begin path methods ----- -NS_IMETHODIMP -morkFile::Path(nsIMdbEnv* mev, mdbYarn* outFilePath) -{ - mdb_err outErr = 0; - if ( outFilePath ) - outFilePath->mYarn_Fill = 0; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - ev->StringToYarn(GetFileNameString(), outFilePath); - outErr = ev->AsErr(); - } - return outErr; -} - -// } ----- end path methods ----- - -// { ----- begin replacement methods ----- - - -NS_IMETHODIMP -morkFile::Thief(nsIMdbEnv* mev, nsIMdbFile** acqThief) -{ - mdb_err outErr = 0; - nsIMdbFile* outThief = 0; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - outThief = GetThief(); - NS_IF_ADDREF(outThief); - outErr = ev->AsErr(); - } - if ( acqThief ) - *acqThief = outThief; - return outErr; -} - -// } ----- end replacement methods ----- - -// { ----- begin versioning methods ----- - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkStdioFile::CloseMorkNode(morkEnv* ev) // CloseStdioFile() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseStdioFile(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkStdioFile::~morkStdioFile() // assert CloseStdioFile() executed earlier -{ - if (mStdioFile_File) - CloseStdioFile(mMorkEnv); - MORK_ASSERT(mStdioFile_File==0); -} - -/*public non-poly*/ void -morkStdioFile::CloseStdioFile(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() ) - { - this->CloseStdio(ev); - } - - mStdioFile_File = 0; - - this->CloseFile(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// compatible with the morkFile::MakeFile() entry point - -/*static*/ morkStdioFile* -morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, mork_bool inFrozen) -{ - morkStdioFile* outFile = 0; - if ( ioHeap && inFilePath ) - { - const char* mode = (inFrozen)? "rb" : "rb+"; - outFile = new(*ioHeap, ev) - morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); - - if ( outFile ) - { - outFile->SetFileFrozen(inFrozen); - } - } - else - ev->NilPointerError(); - - return outFile; -} - -/*static*/ morkStdioFile* -morkStdioFile::CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath) -{ - morkStdioFile* outFile = 0; - if ( ioHeap && inFilePath ) - { - const char* mode = "wb+"; - outFile = new(*ioHeap, ev) - morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode); - } - else - ev->NilPointerError(); - - return outFile; -} - - - -NS_IMETHODIMP -morkStdioFile::BecomeTrunk(nsIMdbEnv* ev) - // If this file is a file version branch created by calling AcquireBud(), - // BecomeTrunk() causes this file's content to replace the original - // file's content, typically by assuming the original file's identity. -{ - return Flush(ev); -} - -NS_IMETHODIMP -morkStdioFile::AcquireBud(nsIMdbEnv * mdbev, nsIMdbHeap* ioHeap, nsIMdbFile **acquiredFile) - // AcquireBud() starts a new "branch" version of the file, empty of content, - // so that a new version of the file can be written. This new file - // can later be told to BecomeTrunk() the original file, so the branch - // created by budding the file will replace the original file. Some - // file subclasses might initially take the unsafe but expedient - // approach of simply truncating this file down to zero length, and - // then returning the same morkFile pointer as this, with an extra - // reference count increment. Note that the caller of AcquireBud() is - // expected to eventually call CutStrongRef() on the returned file - // in order to release the strong reference. High quality versions - // of morkFile subclasses will create entirely new files which later - // are renamed to become the old file, so that better transactional - // behavior is exhibited by the file, so crashes protect old files. - // Note that AcquireBud() is an illegal operation on readonly files. -{ - NS_ENSURE_ARG(acquiredFile); - MORK_USED_1(ioHeap); - nsresult rv = NS_OK; - morkFile* outFile = 0; - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - - if ( this->IsOpenAndActiveFile() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { -//#ifdef MORK_WIN -// truncate(file, /*eof*/ 0); -//#else /*MORK_WIN*/ - char* name = mFile_Name; - if ( name ) - { - if ( MORK_FILECLOSE(file) >= 0 ) - { - this->SetFileActive(morkBool_kFalse); - this->SetFileIoOpen(morkBool_kFalse); - mStdioFile_File = 0; - - file = MORK_FILEOPEN(name, "wb+"); // open for write, discarding old content - if ( file ) - { - mStdioFile_File = file; - this->SetFileActive(morkBool_kTrue); - this->SetFileIoOpen(morkBool_kTrue); - this->SetFileFrozen(morkBool_kFalse); - } - else - this->new_stdio_file_fault(ev); - } - else - this->new_stdio_file_fault(ev); - } - else - this->NilFileNameError(ev); - -//#endif /*MORK_WIN*/ - - if ( ev->Good() && this->AddStrongRef(ev->AsMdbEnv()) ) - { - outFile = this; - AddRef(); - } - } - else if ( mFile_Thief ) - { - rv = mFile_Thief->AcquireBud(ev->AsMdbEnv(), ioHeap, acquiredFile); - } - else - this->NewMissingIoError(ev); - } - else this->NewFileDownError(ev); - - *acquiredFile = outFile; - return rv; -} - -mork_pos -morkStdioFile::Length(morkEnv * ev) const -{ - mork_pos outPos = 0; - - if ( this->IsOpenAndActiveFile() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - long start = MORK_FILETELL(file); - if ( start >= 0 ) - { - long fore = MORK_FILESEEK(file, 0, SEEK_END); - if ( fore >= 0 ) - { - long eof = MORK_FILETELL(file); - if ( eof >= 0 ) - { - long back = MORK_FILESEEK(file, start, SEEK_SET); - if ( back >= 0 ) - outPos = eof; - else - this->new_stdio_file_fault(ev); - } - else this->new_stdio_file_fault(ev); - } - else this->new_stdio_file_fault(ev); - } - else this->new_stdio_file_fault(ev); - } - else if ( mFile_Thief ) - mFile_Thief->Eof(ev->AsMdbEnv(), &outPos); - else - this->NewMissingIoError(ev); - } - else this->NewFileDownError(ev); - - return outPos; -} - -NS_IMETHODIMP -morkStdioFile::Tell(nsIMdbEnv* ev, mork_pos *outPos) const -{ - nsresult rv = NS_OK; - NS_ENSURE_ARG(outPos); - morkEnv* mev = morkEnv::FromMdbEnv(ev); - if ( this->IsOpenAndActiveFile() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - long where = MORK_FILETELL(file); - if ( where >= 0 ) - *outPos = where; - else - this->new_stdio_file_fault(mev); - } - else if ( mFile_Thief ) - mFile_Thief->Tell(ev, outPos); - else - this->NewMissingIoError(mev); - } - else this->NewFileDownError(mev); - - return rv; -} - -NS_IMETHODIMP -morkStdioFile::Read(nsIMdbEnv* ev, void* outBuf, mork_size inSize, mork_num *outCount) -{ - nsresult rv = NS_OK; - morkEnv* mev = morkEnv::FromMdbEnv(ev); - if ( this->IsOpenAndActiveFile() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - long count = (long) MORK_FILEREAD(outBuf, inSize, file); - if ( count >= 0 ) - { - *outCount = (mork_num) count; - } - else this->new_stdio_file_fault(mev); - } - else if ( mFile_Thief ) - mFile_Thief->Read(ev, outBuf, inSize, outCount); - else - this->NewMissingIoError(mev); - } - else this->NewFileDownError(mev); - - return rv; -} - -NS_IMETHODIMP -morkStdioFile::Seek(nsIMdbEnv* mdbev, mork_pos inPos, mork_pos *aOutPos) -{ - mork_pos outPos = 0; - nsresult rv = NS_OK; - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - - if ( this->IsOpenOrClosingNode() && this->FileActive() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - long where = MORK_FILESEEK(file, inPos, SEEK_SET); - if ( where >= 0 ) - outPos = inPos; - else - this->new_stdio_file_fault(ev); - } - else if ( mFile_Thief ) - mFile_Thief->Seek(mdbev, inPos, aOutPos); - else - this->NewMissingIoError(ev); - } - else this->NewFileDownError(ev); - - *aOutPos = outPos; - return rv; -} - -NS_IMETHODIMP -morkStdioFile::Write(nsIMdbEnv* mdbev, const void* inBuf, mork_size inSize, mork_size *aOutSize) -{ - mork_num outCount = 0; - nsresult rv = NS_OK; - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - if ( this->IsOpenActiveAndMutableFile() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - fwrite(inBuf, 1, inSize, file); - if ( !ferror(file) ) - outCount = inSize; - else - this->new_stdio_file_fault(ev); - } - else if ( mFile_Thief ) - mFile_Thief->Write(mdbev, inBuf, inSize, &outCount); - else - this->NewMissingIoError(ev); - } - else this->NewFileDownError(ev); - - *aOutSize = outCount; - return rv; -} - -NS_IMETHODIMP -morkStdioFile::Flush(nsIMdbEnv* mdbev) -{ - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - if ( this->IsOpenOrClosingNode() && this->FileActive() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( file ) - { - MORK_FILEFLUSH(file); - - } - else if ( mFile_Thief ) - mFile_Thief->Flush(mdbev); - else - this->NewMissingIoError(ev); - } - else this->NewFileDownError(ev); - return NS_OK; -} - -// ````` ````` ````` ````` ````` ````` ````` ````` -//protected: // protected non-poly morkStdioFile methods - -void -morkStdioFile::new_stdio_file_fault(morkEnv* ev) const -{ - FILE* file = (FILE*) mStdioFile_File; - - int copyErrno = errno; // facilitate seeing error in debugger - - // bunch of stuff not ported here - if ( !copyErrno && file ) - { - copyErrno = ferror(file); - errno = copyErrno; - } - - this->NewFileErrnoError(ev); -} - -// ````` ````` ````` ````` ````` ````` ````` ````` -//public: // public non-poly morkStdioFile methods - - -/*public non-poly*/ -morkStdioFile::morkStdioFile(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkFile(ev, inUsage, ioHeap, ioSlotHeap) -, mStdioFile_File( 0 ) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kStdioFile; -} - -morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, - const char* inName, const char* inMode) - // calls OpenStdio() after construction -: morkFile(ev, inUsage, ioHeap, ioSlotHeap) -, mStdioFile_File( 0 ) -{ - if ( ev->Good() ) - this->OpenStdio(ev, inName, inMode); -} - -morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, - void* ioFile, const char* inName, mork_bool inFrozen) - // calls UseStdio() after construction -: morkFile(ev, inUsage, ioHeap, ioSlotHeap) -, mStdioFile_File( 0 ) -{ - if ( ev->Good() ) - this->UseStdio(ev, ioFile, inName, inFrozen); -} - -void -morkStdioFile::OpenStdio(morkEnv* ev, const char* inName, const char* inMode) - // Open a new FILE with name inName, using mode flags from inMode. -{ - if ( ev->Good() ) - { - if ( !inMode ) - inMode = ""; - - mork_bool frozen = (*inMode == 'r'); // cursory attempt to note readonly - - if ( this->IsOpenNode() ) - { - if ( !this->FileActive() ) - { - this->SetFileIoOpen(morkBool_kFalse); - if ( inName && *inName ) - { - this->SetFileName(ev, inName); - if ( ev->Good() ) - { - FILE* file = MORK_FILEOPEN(inName, inMode); - if ( file ) - { - mStdioFile_File = file; - this->SetFileActive(morkBool_kTrue); - this->SetFileIoOpen(morkBool_kTrue); - this->SetFileFrozen(frozen); - } - else - this->new_stdio_file_fault(ev); - } - } - else ev->NewError("no file name"); - } - else ev->NewError("file already active"); - } - else this->NewFileDownError(ev); - } -} - -void -morkStdioFile::UseStdio(morkEnv* ev, void* ioFile, const char* inName, - mork_bool inFrozen) - // Use an existing file, like stdin/stdout/stderr, which should not - // have the io stream closed when the file is closed. The ioFile - // parameter must actually be of type FILE (but we don't want to make - // this header file include the stdio.h header file). -{ - if ( ev->Good() ) - { - if ( this->IsOpenNode() ) - { - if ( !this->FileActive() ) - { - if ( ioFile ) - { - this->SetFileIoOpen(morkBool_kFalse); - this->SetFileName(ev, inName); - if ( ev->Good() ) - { - mStdioFile_File = ioFile; - this->SetFileActive(morkBool_kTrue); - this->SetFileFrozen(inFrozen); - } - } - else - ev->NilPointerError(); - } - else ev->NewError("file already active"); - } - else this->NewFileDownError(ev); - } -} - -void -morkStdioFile::CloseStdio(morkEnv* ev) - // Close the stream io if both and FileActive() and FileIoOpen(), but - // this does not close this instances (like CloseStdioFile() does). - // If stream io was made active by means of calling UseStdio(), - // then this method does little beyond marking the stream inactive - // because FileIoOpen() is false. -{ - if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( MORK_FILECLOSE(file) < 0 ) - this->new_stdio_file_fault(ev); - - mStdioFile_File = 0; - this->SetFileActive(morkBool_kFalse); - this->SetFileIoOpen(morkBool_kFalse); - } -} - - -NS_IMETHODIMP -morkStdioFile::Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) - // If this file is a file version branch created by calling AcquireBud(), - // BecomeTrunk() causes this file's content to replace the original - // file's content, typically by assuming the original file's identity. -{ - morkEnv *mev = morkEnv::FromMdbEnv(ev); - if ( mStdioFile_File && FileActive() && FileIoOpen() ) - { - FILE* file = (FILE*) mStdioFile_File; - if ( MORK_FILECLOSE(file) < 0 ) - new_stdio_file_fault(mev); - - mStdioFile_File = 0; - } - SetThief(mev, ioThief); - return NS_OK; -} - - -#if defined(MORK_WIN) - -void mork_fileflush(FILE * file) -{ - fflush(file); -#ifndef WINCE - OSVERSIONINFOA vi = { sizeof(OSVERSIONINFOA) }; - if ((GetVersionExA(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) - { - // Win9x/ME - int fd = fileno(file); - HANDLE fh = (HANDLE)_get_osfhandle(fd); - FlushFileBuffers(fh); - } -#endif -} - -#endif /*MORK_WIN*/ - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkFile.h b/db/mork/src/morkFile.h deleted file mode 100644 index e0b6c70c663b..000000000000 --- a/db/mork/src/morkFile.h +++ /dev/null @@ -1,356 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKFILE_ -#define _MORKFILE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*============================================================================= - * morkFile: abstract file interface - */ - -#define morkDerived_kFile /*i*/ 0x4669 /* ascii 'Fi' */ - -class morkFile /*d*/ : public morkObject, public nsIMdbFile { /* ````` simple file API ````` */ - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -// public: // slots inherited from morkObject (meant to inform only) - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected morkFile members (similar to public domain IronDoc) - - mork_u1 mFile_Frozen; // 'F' => file allows only read access - mork_u1 mFile_DoTrace; // 'T' trace if ev->DoTrace() - mork_u1 mFile_IoOpen; // 'O' => io stream is open (& needs a close) - mork_u1 mFile_Active; // 'A' => file is active and usable - - nsIMdbHeap* mFile_SlotHeap; // heap for Name and other allocated slots - char* mFile_Name; // can be nil if SetFileName() is never called - // mFile_Name convention: managed with morkEnv::CopyString()/FreeString() - - nsIMdbFile* mFile_Thief; // from a call to orkinFile::Steal() - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - NS_DECL_ISUPPORTS_INHERITED - virtual void CloseMorkNode(morkEnv* ev); // CloseFile() only if open - virtual ~morkFile(); // assert that CloseFile() executed earlier - -public: // morkFile construction & destruction - morkFile(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbHeap* ioSlotHeap); - void CloseFile(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkFile(const morkFile& other); - morkFile& operator=(const morkFile& other); - -public: // dynamic type identification - mork_bool IsFile() const - { return IsNode() && mNode_Derived == morkDerived_kFile; } -// } ===== end morkNode methods ===== - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public static standard file creation entry point - - static morkFile* OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, mork_bool inFrozen); - // Choose some subclass of morkFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be open and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - - static morkFile* CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath); - // Choose some subclass of morkFile to instantiate, in order to read - // (and write if not frozen) the file known by inFilePath. The file - // returned should be created and ready for use, and presumably positioned - // at the first byte position of the file. The exact manner in which - // files must be opened is considered a subclass specific detail, and - // other portions or Mork source code don't want to know how it's done. - -public: // non-poly morkFile methods - - mork_bool FileFrozen() const { return mFile_Frozen == 'F'; } - mork_bool FileDoTrace() const { return mFile_DoTrace == 'T'; } - mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; } - mork_bool FileActive() const { return mFile_Active == 'A'; } - - void SetFileFrozen(mork_bool b) { mFile_Frozen = (mork_u1) ((b)? 'F' : 0); } - void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (mork_u1) ((b)? 'T' : 0); } - void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (mork_u1) ((b)? 'O' : 0); } - void SetFileActive(mork_bool b) { mFile_Active = (mork_u1) ((b)? 'A' : 0); } - - - mork_bool IsOpenActiveAndMutableFile() const - { return ( IsOpenNode() && FileActive() && !FileFrozen() ); } - // call IsOpenActiveAndMutableFile() before writing a file - - mork_bool IsOpenAndActiveFile() const - { return ( this->IsOpenNode() && this->FileActive() ); } - // call IsOpenAndActiveFile() before using a file - - - nsIMdbFile* GetThief() const { return mFile_Thief; } - void SetThief(morkEnv* ev, nsIMdbFile* ioThief); // ioThief can be nil - - const char* GetFileNameString() const { return mFile_Name; } - void SetFileName(morkEnv* ev, const char* inName); // inName can be nil - static void NilSlotHeapError(morkEnv* ev); - static void NilFileNameError(morkEnv* ev); - static void NonFileTypeError(morkEnv* ev); - - void NewMissingIoError(morkEnv* ev) const; - - void NewFileDownError(morkEnv* ev) const; - // call NewFileDownError() when either IsOpenAndActiveFile() - // is false, or when IsOpenActiveAndMutableFile() is false. - - void NewFileErrnoError(morkEnv* ev) const; - // call NewFileErrnoError() to convert std C errno into AB fault - - mork_size WriteNewlines(morkEnv* ev, mork_count inNewlines); - // WriteNewlines() returns the number of bytes written. - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakFile(morkFile* me, - morkEnv* ev, morkFile** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongFile(morkFile* me, - morkEnv* ev, morkFile** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -public: - virtual mork_pos Length(morkEnv* ev) const = 0; // eof - // nsIMdbFile methods - NS_IMETHOD Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0; - NS_IMETHOD Seek(nsIMdbEnv* ev, mdb_pos inPos, mdb_pos *outPos) = 0; - NS_IMETHOD Eof(nsIMdbEnv* ev, mdb_pos* outPos); - // } ----- end pos methods ----- - - // { ----- begin read methods ----- - NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, - mdb_size* outActualSize) = 0; - NS_IMETHOD Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize); - // } ----- end read methods ----- - - // { ----- begin write methods ----- - NS_IMETHOD Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, - mdb_size* outActualSize) = 0; - NS_IMETHOD Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, - mdb_pos inPos, mdb_size* outActualSize); - NS_IMETHOD Flush(nsIMdbEnv* ev) = 0; - // } ----- end attribute methods ----- - - // { ----- begin path methods ----- - NS_IMETHOD Path(nsIMdbEnv* ev, mdbYarn* outFilePath); - // } ----- end path methods ----- - - // { ----- begin replacement methods ----- - NS_IMETHOD Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0; - NS_IMETHOD Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief); - // } ----- end replacement methods ----- - - // { ----- begin versioning methods ----- - NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev) = 0; - - NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - nsIMdbFile** acqBud) = 0; - // } ----- end versioning methods ----- - -// } ===== end nsIMdbFile methods ===== - -}; - -/*============================================================================= - * morkStdioFile: concrete file using standard C file io - */ - -#define morkDerived_kStdioFile /*i*/ 0x7346 /* ascii 'sF' */ - -class morkStdioFile /*d*/ : public morkFile { /* `` copied from IronDoc `` */ - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected morkStdioFile members - - void* mStdioFile_File; - // actually type FILE*, but using opaque void* type - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseStdioFile() only if open - virtual ~morkStdioFile(); // assert that CloseStdioFile() executed earlier - -public: // morkStdioFile construction & destruction - morkStdioFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseStdioFile(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkStdioFile(const morkStdioFile& other); - morkStdioFile& operator=(const morkStdioFile& other); - -public: // dynamic type identification - mork_bool IsStdioFile() const - { return IsNode() && mNode_Derived == morkDerived_kStdioFile; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonStdioFileTypeError(morkEnv* ev); - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // compatible with the morkFile::OpenOldFile() entry point - - static morkStdioFile* OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath, mork_bool inFrozen); - - static morkStdioFile* CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap, - const char* inFilePath); - - virtual mork_pos Length(morkEnv* ev) const; // eof - - NS_IMETHOD Tell(nsIMdbEnv* ev, mdb_pos* outPos) const; - NS_IMETHOD Seek(nsIMdbEnv* ev, mdb_pos inPos, mdb_pos *outPos); -// NS_IMETHOD Eof(nsIMdbEnv* ev, mdb_pos* outPos); - // } ----- end pos methods ----- - - // { ----- begin read methods ----- - NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, - mdb_size* outActualSize); - - // { ----- begin write methods ----- - NS_IMETHOD Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, - mdb_size* outActualSize); -// NS_IMETHOD Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize, -// mdb_pos inPos, mdb_size* outActualSize); - NS_IMETHOD Flush(nsIMdbEnv* ev); - // } ----- end attribute methods ----- - - NS_IMETHOD Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief); - - - // { ----- begin versioning methods ----- - NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev); - - NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, - nsIMdbFile** acqBud); - // } ----- end versioning methods ----- - -// } ===== end nsIMdbFile methods ===== - -// ````` ````` ````` ````` ````` ````` ````` ````` - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected non-poly morkStdioFile methods - - void new_stdio_file_fault(morkEnv* ev) const; - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkStdioFile methods - - morkStdioFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, - const char* inName, const char* inMode); - // calls OpenStdio() after construction - - morkStdioFile(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, - void* ioFile, const char* inName, mork_bool inFrozen); - // calls UseStdio() after construction - - void OpenStdio(morkEnv* ev, const char* inName, const char* inMode); - // Open a new FILE with name inName, using mode flags from inMode. - - void UseStdio(morkEnv* ev, void* ioFile, const char* inName, - mork_bool inFrozen); - // Use an existing file, like stdin/stdout/stderr, which should not - // have the io stream closed when the file is closed. The ioFile - // parameter must actually be of type FILE (but we don't want to make - // this header file include the stdio.h header file). - - void CloseStdio(morkEnv* ev); - // Close the stream io if both and FileActive() and FileIoOpen(), but - // this does not close this instances (like CloseStdioFile() does). - // If stream io was made active by means of calling UseStdio(), - // then this method does little beyond marking the stream inactive - // because FileIoOpen() is false. - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakStdioFile(morkStdioFile* me, - morkEnv* ev, morkStdioFile** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongStdioFile(morkStdioFile* me, - morkEnv* ev, morkStdioFile** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKFILE_ */ diff --git a/db/mork/src/morkHandle.cpp b/db/mork/src/morkHandle.cpp deleted file mode 100644 index 4f0ecc6bc330..000000000000 --- a/db/mork/src/morkHandle.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKFACTORY_ -#include "morkFactory.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKHANDLE_ -#include "morkHandle.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkHandle::CloseMorkNode(morkEnv* ev) // CloseHandle() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseHandle(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkHandle::~morkHandle() // assert CloseHandle() executed earlier -{ - MORK_ASSERT(mHandle_Env==0); - MORK_ASSERT(mHandle_Face==0); - MORK_ASSERT(mHandle_Object==0); - MORK_ASSERT(mHandle_Magic==0); - MORK_ASSERT(mHandle_Tag==morkHandle_kTag); // should still have correct tag -} - -/*public non-poly*/ -morkHandle::morkHandle(morkEnv* ev, // note morkUsage is always morkUsage_kPool - morkHandleFace* ioFace, // must not be nil, cookie for this handle - morkObject* ioObject, // must not be nil, the object for this handle - mork_magic inMagic) // magic sig to denote specific subclass -: morkNode(ev, morkUsage::kPool, (nsIMdbHeap*) 0L) -, mHandle_Tag( 0 ) -, mHandle_Env( ev ) -, mHandle_Face( ioFace ) -, mHandle_Object( 0 ) -, mHandle_Magic( 0 ) -{ - if ( ioFace && ioObject ) - { - if ( ev->Good() ) - { - mHandle_Tag = morkHandle_kTag; - morkObject::SlotStrongObject(ioObject, ev, &mHandle_Object); - morkHandle::SlotWeakHandle(this, ev, &ioObject->mObject_Handle); - if ( ev->Good() ) - { - mHandle_Magic = inMagic; - mNode_Derived = morkDerived_kHandle; - } - } - else - ev->CantMakeWhenBadError(); - } - else - ev->NilPointerError(); -} - -/*public non-poly*/ void -morkHandle::CloseHandle(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkObject* obj = mHandle_Object; - mork_bool objDidRefSelf = ( obj && obj->mObject_Handle == this ); - if ( objDidRefSelf ) - obj->mObject_Handle = 0; // drop the reference - - morkObject::SlotStrongObject((morkObject*) 0, ev, &mHandle_Object); - mHandle_Magic = 0; - // note mHandle_Tag MUST stay morkHandle_kTag for morkNode::ZapOld() - this->MarkShut(); - - if ( objDidRefSelf ) - this->CutWeakRef(ev); // do last, because it might self destroy - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -void morkHandle::NilFactoryError(morkEnv* ev) const -{ - ev->NewError("nil mHandle_Factory"); -} - -void morkHandle::NilHandleObjectError(morkEnv* ev) const -{ - ev->NewError("nil mHandle_Object"); -} - -void morkHandle::NonNodeObjectError(morkEnv* ev) const -{ - ev->NewError("non-node mHandle_Object"); -} - -void morkHandle::NonOpenObjectError(morkEnv* ev) const -{ - ev->NewError("non-open mHandle_Object"); -} - -void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const -{ - MORK_USED_1(inMagic); - ev->NewError("wrong mHandle_Magic"); -} - -void morkHandle::NewDownHandleError(morkEnv* ev) const -{ - if ( this->IsHandle() ) - { - if ( this->GoodHandleTag() ) - { - if ( this->IsOpenNode() ) - ev->NewError("unknown down morkHandle error"); - else - this->NonOpenNodeError(ev); - } - else - ev->NewError("wrong morkHandle tag"); - } - else - ev->NewError("non morkHandle"); -} - -morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev, - mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const -{ - morkObject* outObject = 0; - if ( this->IsHandle() && this->GoodHandleTag() && - ( inClosedOkay || this->IsOpenNode() ) ) - { - if ( !inMagicType || mHandle_Magic == inMagicType ) - { - morkObject* obj = this->mHandle_Object; - if ( obj ) - { - if ( obj->IsNode() ) - { - if ( inClosedOkay || obj->IsOpenNode() ) - { - if ( this->IsMutable() || !inMutable ) - outObject = obj; - else - this->NonMutableNodeError(ev); - } - else - this->NonOpenObjectError(ev); - } - else - this->NonNodeObjectError(ev); - } - else if ( !inClosedOkay ) - this->NilHandleObjectError(ev); - } - else - this->NewBadMagicHandleError(ev, inMagicType); - } - else - this->NewDownHandleError(ev); - - MORK_ASSERT(outObject || inClosedOkay); - return outObject; -} - - -morkEnv* -morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable, - mork_bool inClosedOkay, mdb_err* outErr) const -{ - morkEnv* outEnv = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkObject* obj = this->GetGoodHandleObject(ev, inMutable, - /*magic*/ 0, inClosedOkay); - if ( obj ) - { - outEnv = ev; - } - *outErr = ev->AsErr(); - } - MORK_ASSERT(outEnv || inClosedOkay); - return outEnv; -} - -// { ===== begin nsIMdbObject methods ===== - -// { ----- begin attribute methods ----- -/*virtual*/ mdb_err -morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly) -{ - mdb_err outErr = 0; - mdb_bool readOnly = mdbBool_kTrue; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - readOnly = mHandle_Object->IsFrozen(); - - outErr = ev->AsErr(); - } - MORK_ASSERT(outIsReadonly); - if ( outIsReadonly ) - *outIsReadonly = readOnly; - - return outErr; -} -// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port. -// } ----- end attribute methods ----- - -// { ----- begin factory methods ----- -/*virtual*/ mdb_err -morkHandle::Handle_GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory) -{ - mdb_err outErr = 0; - nsIMdbFactory* handle = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - morkFactory* factory = ev->mEnv_Factory; - if ( factory ) - { - handle = factory; - NS_ADDREF(handle); - } - else - this->NilFactoryError(ev); - - outErr = ev->AsErr(); - } - - MORK_ASSERT(acqFactory); - if ( acqFactory ) - *acqFactory = handle; - - return outErr; -} -// } ----- end factory methods ----- - -// { ----- begin ref counting for well-behaved cyclic graphs ----- -/*virtual*/ mdb_err -morkHandle::Handle_GetWeakRefCount(nsIMdbEnv* mev, // weak refs - mdb_count* outCount) -{ - mdb_err outErr = 0; - mdb_count count = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - count = this->WeakRefsOnly(); - - outErr = ev->AsErr(); - } - MORK_ASSERT(outCount); - if ( outCount ) - *outCount = count; - - return outErr; -} -/*virtual*/ mdb_err -morkHandle::Handle_GetStrongRefCount(nsIMdbEnv* mev, // strong refs - mdb_count* outCount) -{ - mdb_err outErr = 0; - mdb_count count = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - count = this->StrongRefsOnly(); - - outErr = ev->AsErr(); - } - MORK_ASSERT(outCount); - if ( outCount ) - *outCount = count; - - return outErr; -} - -/*virtual*/ mdb_err -morkHandle::Handle_AddWeakRef(nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - this->AddWeakRef(ev); - outErr = ev->AsErr(); - } - - return outErr; -} -/*virtual*/ mdb_err -morkHandle::Handle_AddStrongRef(nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kFalse, &outErr); - if ( ev ) - { - this->AddStrongRef(ev); - outErr = ev->AsErr(); - } - - return outErr; -} - -/*virtual*/ mdb_err -morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - this->CutWeakRef(ev); - outErr = ev->AsErr(); - } - - return outErr; -} -/*virtual*/ mdb_err -morkHandle::Handle_CutStrongRef(nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - this->CutStrongRef(ev); - outErr = ev->AsErr(); - } - return outErr; -} - -/*virtual*/ mdb_err -morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev) -// called at strong refs zero -{ - // if only one ref, Handle_CutStrongRef will clean up better. - if (mNode_Uses == 1) - return Handle_CutStrongRef(mev); - - mdb_err outErr = 0; - - if ( this->IsNode() && this->IsOpenNode() ) - { - morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, - /*inClosedOkay*/ morkBool_kTrue, &outErr); - if ( ev ) - { - morkObject* object = mHandle_Object; - if ( object && object->IsNode() && object->IsOpenNode() ) - object->CloseMorkNode(ev); - - this->CloseMorkNode(ev); - outErr = ev->AsErr(); - } - } - return outErr; -} - -/*virtual*/ mdb_err -morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen) -{ - MORK_USED_1(mev); - mdb_err outErr = 0; - - MORK_ASSERT(outOpen); - if ( outOpen ) - *outOpen = this->IsOpenNode(); - - return outErr; -} -// } ----- end ref counting ----- - -// } ===== end nsIMdbObject methods ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkHandle.h b/db/mork/src/morkHandle.h deleted file mode 100644 index 9acc1fb68a75..000000000000 --- a/db/mork/src/morkHandle.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKHANDLE_ -#define _MORKHANDLE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class morkPool; -class morkObject; -class morkFactory; - -#define morkDerived_kHandle /*i*/ 0x486E /* ascii 'Hn' */ -#define morkHandle_kTag 0x68416E44 /* ascii 'hAnD' */ - -/*| morkHandle: -|*/ -class morkHandle : public morkNode { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - - mork_u4 mHandle_Tag; // must equal morkHandle_kTag - morkEnv* mHandle_Env; // pool that allocated this handle - morkHandleFace* mHandle_Face; // cookie from pool containing this - morkObject* mHandle_Object; // object this handle wraps for MDB API - mork_magic mHandle_Magic; // magic sig different in each subclass - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseHandle() only if open - virtual ~morkHandle(); // assert that CloseHandle() executed earlier - -public: // morkHandle construction & destruction - morkHandle(morkEnv* ev, // note morkUsage is always morkUsage_kPool - morkHandleFace* ioFace, // must not be nil, cookie for this handle - morkObject* ioObject, // must not be nil, the object for this handle - mork_magic inMagic); // magic sig to denote specific subclass - void CloseHandle(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkHandle(const morkHandle& other); - morkHandle& operator=(const morkHandle& other); - -protected: // special case empty construction for morkHandleFrame - friend class morkHandleFrame; - morkHandle() { } - -public: // dynamic type identification - mork_bool IsHandle() const - { return IsNode() && mNode_Derived == morkDerived_kHandle; } -// } ===== end morkNode methods ===== - -public: // morkHandle memory management operators - void* operator new(size_t inSize, morkPool& ioPool, morkZone& ioZone, morkEnv* ev) CPP_THROW_NEW - { return ioPool.NewHandle(ev, inSize, &ioZone); } - - void* operator new(size_t inSize, morkPool& ioPool, morkEnv* ev) CPP_THROW_NEW - { return ioPool.NewHandle(ev, inSize, (morkZone*) 0); } - - void* operator new(size_t inSize, morkHandleFace* ioFace) CPP_THROW_NEW - { MORK_USED_1(inSize); return ioFace; } - - -public: // other handle methods - mork_bool GoodHandleTag() const - { return mHandle_Tag == morkHandle_kTag; } - - void NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const; - void NewDownHandleError(morkEnv* ev) const; - void NilFactoryError(morkEnv* ev) const; - void NilHandleObjectError(morkEnv* ev) const; - void NonNodeObjectError(morkEnv* ev) const; - void NonOpenObjectError(morkEnv* ev) const; - - morkObject* GetGoodHandleObject(morkEnv* ev, - mork_bool inMutable, mork_magic inMagicType, mork_bool inClosedOkay) const; - -public: // interface supporting mdbObject methods - - morkEnv* CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable, - mork_bool inClosedOkay, mdb_err* outErr) const; - - // { ----- begin mdbObject style methods ----- - mdb_err Handle_IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly); - - mdb_err Handle_GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory); - mdb_err Handle_GetWeakRefCount(nsIMdbEnv* ev, mdb_count* outCount); - mdb_err Handle_GetStrongRefCount(nsIMdbEnv* ev, mdb_count* outCount); - - mdb_err Handle_AddWeakRef(nsIMdbEnv* ev); - mdb_err Handle_AddStrongRef(nsIMdbEnv* ev); - - mdb_err Handle_CutWeakRef(nsIMdbEnv* ev); - mdb_err Handle_CutStrongRef(nsIMdbEnv* ev); - - mdb_err Handle_CloseMdbObject(nsIMdbEnv* ev); - mdb_err Handle_IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen); - // } ----- end mdbObject style methods ----- - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakHandle(morkHandle* me, - morkEnv* ev, morkHandle** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongHandle(morkHandle* me, - morkEnv* ev, morkHandle** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -#define morkHandleFrame_kPadSlotCount 4 - -/*| morkHandleFrame: an object format used for allocating and maintaining -**| instances of morkHandle, with leading slots used to maintain this in a -**| linked list, and following slots to provide extra footprint that might -**| be needed by any morkHandle subclasses that include very little extra -**| space (by virtue of the fact that each morkHandle subclass is expected -**| to multiply inherit from another base class that has only abstact methods -**| for space overhead related only to some vtable representation). -|*/ -class morkHandleFrame { -public: - morkLink mHandleFrame_Link; // list storage without trampling Handle - morkHandle mHandleFrame_Handle; - mork_ip mHandleFrame_Padding[ morkHandleFrame_kPadSlotCount ]; - -public: - morkHandle* AsHandle() { return &mHandleFrame_Handle; } - - morkHandleFrame() {} // actually, morkHandleFrame never gets constructed - -private: // copying is not allowed - morkHandleFrame(const morkHandleFrame& other); - morkHandleFrame& operator=(const morkHandleFrame& other); -}; - -#define morkHandleFrame_kHandleOffset \ - mork_OffsetOf(morkHandleFrame,mHandleFrame_Handle) - -#define morkHandle_AsHandleFrame(h) ((h)->mHandle_Block , \ - ((morkHandleFrame*) (((mork_u1*)(h)) - morkHandleFrame_kHandleOffset))) - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKHANDLE_ */ diff --git a/db/mork/src/morkIntMap.cpp b/db/mork/src/morkIntMap.cpp deleted file mode 100644 index 196d19a76211..000000000000 --- a/db/mork/src/morkIntMap.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKINTMAP_ -#include "morkIntMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkIntMap::CloseMorkNode(morkEnv* ev) // CloseIntMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseIntMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkIntMap::~morkIntMap() // assert CloseIntMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkIntMap::morkIntMap(morkEnv* ev, - const morkUsage& inUsage, mork_size inValSize, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges) -: morkMap(ev, inUsage, ioHeap, sizeof(mork_u4), inValSize, - morkIntMap_kStartSlotCount, ioSlotHeap, inHoldChanges) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kIntMap; -} - -/*public non-poly*/ void -morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CloseMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// { ===== begin morkMap poly interface ===== -/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB) -morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const -{ - MORK_USED_1(ev); - return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB); -} - -/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey) -morkIntMap::Hash(morkEnv* ev, const void* inKey) const -{ - MORK_USED_1(ev); - return *((const mork_u4*) inKey); -} -// } ===== end morkMap poly interface ===== - -mork_bool -morkIntMap::AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress) - // the AddInt() method return value equals ev->Good(). -{ - if ( ev->Good() ) - { - this->Put(ev, &inKey, &ioAddress, - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); - } - - return ev->Good(); -} - -mork_bool -morkIntMap::CutInt(morkEnv* ev, mork_u4 inKey) -{ - return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0, - (mork_change**) 0); -} - -void* -morkIntMap::GetInt(morkEnv* ev, mork_u4 inKey) - // Note the returned val does NOT have an increase in refcount for this. -{ - void* val = 0; // old val in the map - this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0); - - return val; -} - -mork_bool -morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey) - // Note the returned val does NOT have an increase in refcount for this. -{ - return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0, - (mork_change**) 0); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#ifdef MORK_POINTER_MAP_IMPL - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkPointerMap::CloseMorkNode(morkEnv* ev) // ClosePointerMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->ClosePointerMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkPointerMap::~morkPointerMap() // assert ClosePointerMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkPointerMap::morkPointerMap(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkMap(ev, inUsage, ioHeap, sizeof(void*), sizeof(void*), - morkPointerMap_kStartSlotCount, ioSlotHeap, - /*inHoldChanges*/ morkBool_kFalse) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kPointerMap; -} - -/*public non-poly*/ void -morkPointerMap::ClosePointerMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CloseMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// { ===== begin morkMap poly interface ===== -/*virtual*/ mork_bool // *((void**) inKeyA) == *((void**) inKeyB) -morkPointerMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const -{ - MORK_USED_1(ev); - return *((const void**) inKeyA) == *((const void**) inKeyB); -} - -/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey) -morkPointerMap::Hash(morkEnv* ev, const void* inKey) const -{ - MORK_USED_1(ev); - return *((const mork_u4*) inKey); -} -// } ===== end morkMap poly interface ===== - -mork_bool -morkPointerMap::AddPointer(morkEnv* ev, void* inKey, void* ioAddress) - // the AddPointer() method return value equals ev->Good(). -{ - if ( ev->Good() ) - { - this->Put(ev, &inKey, &ioAddress, - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); - } - - return ev->Good(); -} - -mork_bool -morkPointerMap::CutPointer(morkEnv* ev, void* inKey) -{ - return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0, - (mork_change**) 0); -} - -void* -morkPointerMap::GetPointer(morkEnv* ev, void* inKey) - // Note the returned val does NOT have an increase in refcount for this. -{ - void* val = 0; // old val in the map - this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0); - - return val; -} - -mork_bool -morkPointerMap::HasPointer(morkEnv* ev, void* inKey) - // Note the returned val does NOT have an increase in refcount for this. -{ - return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0, - (mork_change**) 0); -} -#endif /*MORK_POINTER_MAP_IMPL*/ - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkIntMap.h b/db/mork/src/morkIntMap.h deleted file mode 100644 index becdfa01f81c..000000000000 --- a/db/mork/src/morkIntMap.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKINTMAP_ -#define _MORKINTMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */ - -#define morkIntMap_kStartSlotCount 256 - -/*| morkIntMap: maps mork_token -> morkNode -|*/ -class morkIntMap : public morkMap { // for mapping tokens to maps - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseIntMap() only if open - virtual ~morkIntMap(); // assert that CloseIntMap() executed earlier - -public: // morkMap construction & destruction - - // keySize for morkIntMap equals sizeof(mork_u4) - morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges); - void CloseIntMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsIntMap() const - { return IsNode() && mNode_Derived == morkDerived_kIntMap; } -// } ===== end morkNode methods ===== - -// { ===== begin morkMap poly interface ===== - virtual mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - - virtual mork_u4 // some integer function of *((mork_u4*) inKey) - Hash(morkEnv* ev, const void* inKey) const; -// } ===== end morkMap poly interface ===== - -public: // other map methods - - mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress); - // the AddInt() boolean return equals ev->Good(). - - mork_bool CutInt(morkEnv* ev, mork_u4 inKey); - // The CutInt() boolean return indicates whether removal happened. - - void* GetInt(morkEnv* ev, mork_u4 inKey); - // Note the returned node does NOT have an increase in refcount for this. - - mork_bool HasInt(morkEnv* ev, mork_u4 inKey); - // Note the returned node does NOT have an increase in refcount for this. - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#ifdef MORK_POINTER_MAP_IMPL - -#define morkDerived_kPointerMap /*i*/ 0x704D /* ascii 'pM' */ - -#define morkPointerMap_kStartSlotCount 256 - -/*| morkPointerMap: maps void* -> void* -**| -**| This pointer map class is equivalent to morkIntMap when sizeof(mork_u4) -**| equals sizeof(void*). However, when these two sizes are different, -**| then we cannot use the same hash table structure very easily without -**| being very careful about the size and usage assumptions of those -**| clients using the smaller data type. So we just go ahead and use -**| morkPointerMap for hash tables using pointer key types. -|*/ -class morkPointerMap : public morkMap { // for mapping tokens to maps - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // ClosePointerMap() only if open - virtual ~morkPointerMap(); // assert that ClosePointerMap() executed earlier - -public: // morkMap construction & destruction - - // keySize for morkPointerMap equals sizeof(mork_u4) - morkPointerMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void ClosePointerMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsPointerMap() const - { return IsNode() && mNode_Derived == morkDerived_kPointerMap; } -// } ===== end morkNode methods ===== - -// { ===== begin morkMap poly interface ===== - virtual mork_bool // *((void**) inKeyA) == *((void**) inKeyB) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - - virtual mork_u4 // some integer function of *((mork_u4*) inKey) - Hash(morkEnv* ev, const void* inKey) const; -// } ===== end morkMap poly interface ===== - -public: // other map methods - - mork_bool AddPointer(morkEnv* ev, void* inKey, void* ioAddress); - // the AddPointer() boolean return equals ev->Good(). - - mork_bool CutPointer(morkEnv* ev, void* inKey); - // The CutPointer() boolean return indicates whether removal happened. - - void* GetPointer(morkEnv* ev, void* inKey); - // Note the returned node does NOT have an increase in refcount for this. - - mork_bool HasPointer(morkEnv* ev, void* inKey); - // Note the returned node does NOT have an increase in refcount for this. - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakIntMap(morkIntMap* me, - morkEnv* ev, morkIntMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongIntMap(morkIntMap* me, - morkEnv* ev, morkIntMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } - -}; -#endif /*MORK_POINTER_MAP_IMPL*/ - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKINTMAP_ */ diff --git a/db/mork/src/morkMap.cpp b/db/mork/src/morkMap.cpp deleted file mode 100644 index 74bc10c04910..000000000000 --- a/db/mork/src/morkMap.cpp +++ /dev/null @@ -1,960 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// This code is mostly a port to C++ from public domain IronDoc C sources. -// Note many code comments here come verbatim from cut-and-pasted IronDoc. - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - - -class morkHashArrays { -public: - nsIMdbHeap* mHashArrays_Heap; // copy of mMap_Heap - mork_count mHashArrays_Slots; // copy of mMap_Slots - - mork_u1* mHashArrays_Keys; // copy of mMap_Keys - mork_u1* mHashArrays_Vals; // copy of mMap_Vals - morkAssoc* mHashArrays_Assocs; // copy of mMap_Assocs - mork_change* mHashArrays_Changes; // copy of mMap_Changes - morkAssoc** mHashArrays_Buckets; // copy of mMap_Buckets - morkAssoc* mHashArrays_FreeList; // copy of mMap_FreeList - -public: - void finalize(morkEnv* ev); -}; - -void morkHashArrays::finalize(morkEnv* ev) -{ - nsIMdbEnv* menv = ev->AsMdbEnv(); - nsIMdbHeap* heap = mHashArrays_Heap; - - if ( heap ) - { - if ( mHashArrays_Keys ) - heap->Free(menv, mHashArrays_Keys); - if ( mHashArrays_Vals ) - heap->Free(menv, mHashArrays_Vals); - if ( mHashArrays_Assocs ) - heap->Free(menv, mHashArrays_Assocs); - if ( mHashArrays_Changes ) - heap->Free(menv, mHashArrays_Changes); - if ( mHashArrays_Buckets ) - heap->Free(menv, mHashArrays_Buckets); - } -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkMap::CloseMorkNode(morkEnv* ev) // CloseMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkMap::~morkMap() // assert CloseMap() executed earlier -{ - MORK_ASSERT(mMap_FreeList==0); - MORK_ASSERT(mMap_Buckets==0); - MORK_ASSERT(mMap_Keys==0); - MORK_ASSERT(mMap_Vals==0); - MORK_ASSERT(mMap_Changes==0); - MORK_ASSERT(mMap_Assocs==0); -} - -/*public non-poly*/ void -morkMap::CloseMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - nsIMdbHeap* heap = mMap_Heap; - if ( heap ) /* need to free the arrays? */ - { - nsIMdbEnv* menv = ev->AsMdbEnv(); - - if ( mMap_Keys ) - heap->Free(menv, mMap_Keys); - - if ( mMap_Vals ) - heap->Free(menv, mMap_Vals); - - if ( mMap_Assocs ) - heap->Free(menv, mMap_Assocs); - - if ( mMap_Buckets ) - heap->Free(menv, mMap_Buckets); - - if ( mMap_Changes ) - heap->Free(menv, mMap_Changes); - } - mMap_Keys = 0; - mMap_Vals = 0; - mMap_Buckets = 0; - mMap_Assocs = 0; - mMap_Changes = 0; - mMap_FreeList = 0; - MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm)); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -void -morkMap::clear_map(morkEnv* ev, nsIMdbHeap* ioSlotHeap) -{ - mMap_Tag = 0; - mMap_Seed = 0; - mMap_Slots = 0; - mMap_Fill = 0; - mMap_Keys = 0; - mMap_Vals = 0; - mMap_Assocs = 0; - mMap_Changes = 0; - mMap_Buckets = 0; - mMap_FreeList = 0; - MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm)); - - mMap_Heap = 0; - if ( ioSlotHeap ) - { - nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mMap_Heap); - } - else - ev->NilPointerError(); -} - -morkMap::morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_size inKeySize, mork_size inValSize, - mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges) -: morkNode(ev, inUsage, ioHeap) -, mMap_Heap( 0 ) -{ - if ( ev->Good() ) - { - this->clear_map(ev, ioSlotHeap); - if ( ev->Good() ) - { - mMap_Form.mMapForm_HoldChanges = inHoldChanges; - - mMap_Form.mMapForm_KeySize = inKeySize; - mMap_Form.mMapForm_ValSize = inValSize; - mMap_Form.mMapForm_KeyIsIP = ( inKeySize == sizeof(mork_ip) ); - mMap_Form.mMapForm_ValIsIP = ( inValSize == sizeof(mork_ip) ); - - this->InitMap(ev, inSlots); - if ( ev->Good() ) - mNode_Derived = morkDerived_kMap; - } - } -} - -void -morkMap::NewIterOutOfSyncError(morkEnv* ev) -{ - ev->NewError("map iter out of sync"); -} - -void morkMap::NewBadMapError(morkEnv* ev) -{ - ev->NewError("bad morkMap tag"); - if ( !this ) - ev->NewError("nil morkMap instance"); -} - -void morkMap::NewSlotsUnderflowWarning(morkEnv* ev) -{ - ev->NewWarning("member count underflow"); -} - -void morkMap::InitMap(morkEnv* ev, mork_size inSlots) -{ - if ( ev->Good() ) - { - morkHashArrays old; - // MORK_MEMCPY(&mMap_Form, &inForm, sizeof(morkMapForm)); - if ( inSlots < 3 ) /* requested capacity absurdly small? */ - inSlots = 3; /* bump it up to a minimum practical level */ - else if ( inSlots > (128 * 1024) ) /* requested slots absurdly big? */ - inSlots = (128 * 1024); /* decrease it to a maximum practical level */ - - if ( this->new_arrays(ev, &old, inSlots) ) - mMap_Tag = morkMap_kTag; - - MORK_MEMSET(&old, 0, sizeof(morkHashArrays)); // do NOT finalize - } -} - -morkAssoc** -morkMap::find(morkEnv* ev, const void* inKey, mork_u4 inHash) const -{ - mork_u1* keys = mMap_Keys; - mork_num keySize = this->FormKeySize(); - // morkMap_mEqual equal = this->FormEqual(); - - morkAssoc** ref = mMap_Buckets + (inHash % mMap_Slots); - morkAssoc* assoc = *ref; - while ( assoc ) /* look at another assoc in the bucket? */ - { - mork_pos i = assoc - mMap_Assocs; /* index of this assoc */ - if ( this->Equal(ev, keys + (i * keySize), inKey) ) /* found? */ - return ref; - - ref = &assoc->mAssoc_Next; /* consider next assoc slot in bucket */ - assoc = *ref; /* if this is null, then we are done */ - } - return 0; -} - -/*| get_assoc: read the key and/or value at index inPos -|*/ -void -morkMap::get_assoc(void* outKey, void* outVal, mork_pos inPos) const -{ - mork_num valSize = this->FormValSize(); - if ( valSize && outVal ) /* map holds values? caller wants the value? */ - { - const mork_u1* value = mMap_Vals + (valSize * inPos); - if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */ - *((mork_ip*) outVal) = *((const mork_ip*) value); - else - MORK_MEMCPY(outVal, value, valSize); - } - if ( outKey ) /* caller wants the key? */ - { - mork_num keySize = this->FormKeySize(); - const mork_u1* key = mMap_Keys + (keySize * inPos); - if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */ - *((mork_ip*) outKey) = *((const mork_ip*) key); - else - MORK_MEMCPY(outKey, key, keySize); - } -} - -/*| put_assoc: write the key and/or value at index inPos -|*/ -void -morkMap::put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const -{ - mork_num valSize = this->FormValSize(); - if ( valSize && inVal ) /* map holds values? caller sends a value? */ - { - mork_u1* value = mMap_Vals + (valSize * inPos); - if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */ - *((mork_ip*) value) = *((const mork_ip*) inVal); - else - MORK_MEMCPY(value, inVal, valSize); - } - if ( inKey ) /* caller sends a key? */ - { - mork_num keySize = this->FormKeySize(); - mork_u1* key = mMap_Keys + (keySize * inPos); - if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */ - *((mork_ip*) key) = *((const mork_ip*) inKey); - else - MORK_MEMCPY(key, inKey, keySize); - } -} - -void* -morkMap::clear_alloc(morkEnv* ev, mork_size inSize) -{ - void* p = 0; - nsIMdbHeap* heap = mMap_Heap; - if ( heap ) - { - if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p ) - { - MORK_MEMSET(p, 0, inSize); - return p; - } - } - else - ev->NilPointerError(); - - return (void*) 0; -} - -void* -morkMap::alloc(morkEnv* ev, mork_size inSize) -{ - void* p = 0; - nsIMdbHeap* heap = mMap_Heap; - if ( heap ) - { - if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p ) - return p; - } - else - ev->NilPointerError(); - - return (void*) 0; -} - -/*| new_keys: allocate an array of inSlots new keys filled with zero. -|*/ -mork_u1* -morkMap::new_keys(morkEnv* ev, mork_num inSlots) -{ - mork_num size = inSlots * this->FormKeySize(); - return (mork_u1*) this->clear_alloc(ev, size); -} - -/*| new_values: allocate an array of inSlots new values filled with zero. -**| When values are zero sized, we just return a null pointer. -|*/ -mork_u1* -morkMap::new_values(morkEnv* ev, mork_num inSlots) -{ - mork_u1* values = 0; - mork_num size = inSlots * this->FormValSize(); - if ( size ) - values = (mork_u1*) this->clear_alloc(ev, size); - return values; -} - -mork_change* -morkMap::new_changes(morkEnv* ev, mork_num inSlots) -{ - mork_change* changes = 0; - mork_num size = inSlots * sizeof(mork_change); - if ( size && mMap_Form.mMapForm_HoldChanges ) - changes = (mork_change*) this->clear_alloc(ev, size); - return changes; -} - -/*| new_buckets: allocate an array of inSlots new buckets filled with zero. -|*/ -morkAssoc** -morkMap::new_buckets(morkEnv* ev, mork_num inSlots) -{ - mork_num size = inSlots * sizeof(morkAssoc*); - return (morkAssoc**) this->clear_alloc(ev, size); -} - -/*| new_assocs: allocate an array of inSlots new assocs, with each assoc -**| linked together in a list with the first array element at the list head -**| and the last element at the list tail. (morkMap::grow() needs this.) -|*/ -morkAssoc* -morkMap::new_assocs(morkEnv* ev, mork_num inSlots) -{ - mork_num size = inSlots * sizeof(morkAssoc); - morkAssoc* assocs = (morkAssoc*) this->alloc(ev, size); - if ( assocs ) /* able to allocate the array? */ - { - morkAssoc* a = assocs + (inSlots - 1); /* the last array element */ - a->mAssoc_Next = 0; /* terminate tail element of the list with null */ - while ( --a >= assocs ) /* another assoc to link into the list? */ - a->mAssoc_Next = a + 1; /* each points to the following assoc */ - } - return assocs; -} - -mork_bool -morkMap::new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots) -{ - mork_bool outNew = morkBool_kFalse; - - /* see if we can allocate all the new arrays before we go any further: */ - morkAssoc** newBuckets = this->new_buckets(ev, inSlots); - morkAssoc* newAssocs = this->new_assocs(ev, inSlots); - mork_u1* newKeys = this->new_keys(ev, inSlots); - mork_u1* newValues = this->new_values(ev, inSlots); - mork_change* newChanges = this->new_changes(ev, inSlots); - - /* it is okay for newChanges to be null when changes are not held: */ - mork_bool okayChanges = ( newChanges || !this->FormHoldChanges() ); - - /* it is okay for newValues to be null when values are zero sized: */ - mork_bool okayValues = ( newValues || !this->FormValSize() ); - - if ( newBuckets && newAssocs && newKeys && okayChanges && okayValues ) - { - outNew = morkBool_kTrue; /* yes, we created all the arrays we need */ - - /* init the old hashArrays with slots from this hash table: */ - old->mHashArrays_Heap = mMap_Heap; - - old->mHashArrays_Slots = mMap_Slots; - old->mHashArrays_Keys = mMap_Keys; - old->mHashArrays_Vals = mMap_Vals; - old->mHashArrays_Assocs = mMap_Assocs; - old->mHashArrays_Buckets = mMap_Buckets; - old->mHashArrays_Changes = mMap_Changes; - - /* now replace all our array slots with the new structures: */ - ++mMap_Seed; /* note the map is now changed */ - mMap_Keys = newKeys; - mMap_Vals = newValues; - mMap_Buckets = newBuckets; - mMap_Assocs = newAssocs; - mMap_FreeList = newAssocs; /* all are free to start with */ - mMap_Changes = newChanges; - mMap_Slots = inSlots; - } - else /* free the partial set of arrays that were actually allocated */ - { - nsIMdbEnv* menv = ev->AsMdbEnv(); - nsIMdbHeap* heap = mMap_Heap; - if ( newBuckets ) - heap->Free(menv, newBuckets); - if ( newAssocs ) - heap->Free(menv, newAssocs); - if ( newKeys ) - heap->Free(menv, newKeys); - if ( newValues ) - heap->Free(menv, newValues); - if ( newChanges ) - heap->Free(menv, newChanges); - - MORK_MEMSET(old, 0, sizeof(morkHashArrays)); - } - - return outNew; -} - -/*| grow: make the map arrays bigger by 33%. The old map is completely -**| full, or else we would not have called grow() to get more space. This -**| means the free list is empty, and also means every old key and value is in -**| use in the old arrays. So every key and value must be copied to the new -**| arrays, and since they are contiguous in the old arrays, we can efficiently -**| bitwise copy them in bulk from the old arrays to the new arrays, without -**| paying any attention to the structure of the old arrays. -**| -**|| The content of the old bucket and assoc arrays need not be copied because -**| this information is going to be completely rebuilt by rehashing all the -**| keys into their new buckets, given the new larger map capacity. The new -**| bucket array from new_arrays() is assumed to contain all zeroes, which is -**| necessary to ensure the lists in each bucket stay null terminated as we -**| build the new linked lists. (Note no old bucket ordering is preserved.) -**| -**|| If the old capacity is N, then in the new arrays the assocs with indexes -**| from zero to N-1 are still allocated and must be rehashed into the map. -**| The new free list contains all the following assocs, starting with the new -**| assoc link at index N. (We call the links in the link array "assocs" -**| because allocating a link is the same as allocating the key/value pair -**| with the same index as the link.) -**| -**|| The new free list is initialized simply by pointing at the first new link -**| in the assoc array after the size of the old assoc array. This assumes -**| that FeHashTable_new_arrays() has already linked all the new assocs into a -**| list with the first at the head of the list and the last at the tail of the -**| list. So by making the free list point to the first of the new uncopied -**| assocs, the list is already well-formed. -|*/ -mork_bool morkMap::grow(morkEnv* ev) -{ - if ( mMap_Heap ) /* can we grow the map? */ - { - mork_num newSlots = (mMap_Slots * 2); /* +100% */ - morkHashArrays old; /* a place to temporarily hold all the old arrays */ - if ( this->new_arrays(ev, &old, newSlots) ) /* have more? */ - { - // morkMap_mHash hash = this->FormHash(); /* for terse loop use */ - - /* figure out the bulk volume sizes of old keys and values to move: */ - mork_num oldSlots = old.mHashArrays_Slots; /* number of old assocs */ - mork_num keyBulk = oldSlots * this->FormKeySize(); /* key volume */ - mork_num valBulk = oldSlots * this->FormValSize(); /* values */ - - /* convenient variables for new arrays that need to be rehashed: */ - morkAssoc** newBuckets = mMap_Buckets; /* new all zeroes */ - morkAssoc* newAssocs = mMap_Assocs; /* hash into buckets */ - morkAssoc* newFreeList = newAssocs + oldSlots; /* new room is free */ - mork_u1* key = mMap_Keys; /* the first key to rehash */ - --newAssocs; /* back up one before preincrement used in while loop */ - - /* move all old keys and values to the new arrays: */ - MORK_MEMCPY(mMap_Keys, old.mHashArrays_Keys, keyBulk); - if ( valBulk ) /* are values nonzero sized? */ - MORK_MEMCPY(mMap_Vals, old.mHashArrays_Vals, valBulk); - - mMap_FreeList = newFreeList; /* remaining assocs are free */ - - while ( ++newAssocs < newFreeList ) /* rehash another old assoc? */ - { - morkAssoc** top = newBuckets + (this->Hash(ev, key) % newSlots); - key += this->FormKeySize(); /* the next key to rehash */ - newAssocs->mAssoc_Next = *top; /* link to prev bucket top */ - *top = newAssocs; /* push assoc on top of bucket */ - } - ++mMap_Seed; /* note the map has changed */ - old.finalize(ev); /* remember to free the old arrays */ - } - } - else ev->OutOfMemoryError(); - - return ev->Good(); -} - - -mork_bool -morkMap::Put(morkEnv* ev, const void* inKey, const void* inVal, - void* outKey, void* outVal, mork_change** outChange) -{ - mork_bool outPut = morkBool_kFalse; - - if ( this->GoodMap() ) /* looks good? */ - { - mork_u4 hash = this->Hash(ev, inKey); - morkAssoc** ref = this->find(ev, inKey, hash); - if ( ref ) /* assoc was found? reuse an existing assoc slot? */ - { - outPut = morkBool_kTrue; /* inKey was indeed already inside the map */ - } - else /* assoc not found -- need to allocate a new assoc slot */ - { - morkAssoc* assoc = this->pop_free_assoc(); - if ( !assoc ) /* no slots remaining in free list? must grow map? */ - { - if ( this->grow(ev) ) /* successfully made map larger? */ - assoc = this->pop_free_assoc(); - } - if ( assoc ) /* allocated new assoc without error? */ - { - ref = mMap_Buckets + (hash % mMap_Slots); - assoc->mAssoc_Next = *ref; /* link to prev bucket top */ - *ref = assoc; /* push assoc on top of bucket */ - - ++mMap_Fill; /* one more member in the collection */ - ++mMap_Seed; /* note the map has changed */ - } - } - if ( ref ) /* did not have an error during possible growth? */ - { - mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */ - if ( outPut && (outKey || outVal) ) /* copy old before cobbering? */ - this->get_assoc(outKey, outVal, i); - - this->put_assoc(inKey, inVal, i); - ++mMap_Seed; /* note the map has changed */ - - if ( outChange ) - { - if ( mMap_Changes ) - *outChange = mMap_Changes + i; - else - *outChange = this->FormDummyChange(); - } - } - } - else this->NewBadMapError(ev); - - return outPut; -} - -mork_num -morkMap::CutAll(morkEnv* ev) -{ - mork_num outCutAll = 0; - - if ( this->GoodMap() ) /* map looks good? */ - { - mork_num slots = mMap_Slots; - morkAssoc* before = mMap_Assocs - 1; /* before first member */ - morkAssoc* assoc = before + slots; /* the very last member */ - - ++mMap_Seed; /* note the map is changed */ - - /* make the assoc array a linked list headed by first & tailed by last: */ - assoc->mAssoc_Next = 0; /* null terminate the new free list */ - while ( --assoc > before ) /* another assoc to link into the list? */ - assoc->mAssoc_Next = assoc + 1; - mMap_FreeList = mMap_Assocs; /* all are free */ - - outCutAll = mMap_Fill; /* we'll cut all of them of course */ - - mMap_Fill = 0; /* the map is completely empty */ - } - else this->NewBadMapError(ev); - - return outCutAll; -} - -mork_bool -morkMap::Cut(morkEnv* ev, const void* inKey, - void* outKey, void* outVal, mork_change** outChange) -{ - mork_bool outCut = morkBool_kFalse; - - if ( this->GoodMap() ) /* looks good? */ - { - mork_u4 hash = this->Hash(ev, inKey); - morkAssoc** ref = this->find(ev, inKey, hash); - if ( ref ) /* found an assoc for key? */ - { - outCut = morkBool_kTrue; - morkAssoc* assoc = *ref; - mork_pos i = assoc - mMap_Assocs; /* index of assoc */ - if ( outKey || outVal ) - this->get_assoc(outKey, outVal, i); - - *ref = assoc->mAssoc_Next; /* unlink the found assoc */ - this->push_free_assoc(assoc); /* and put it in free list */ - - if ( outChange ) - { - if ( mMap_Changes ) - *outChange = mMap_Changes + i; - else - *outChange = this->FormDummyChange(); - } - - ++mMap_Seed; /* note the map has changed */ - if ( mMap_Fill ) /* the count shows nonzero members? */ - --mMap_Fill; /* one less member in the collection */ - else - this->NewSlotsUnderflowWarning(ev); - } - } - else this->NewBadMapError(ev); - - return outCut; -} - -mork_bool -morkMap::Get(morkEnv* ev, const void* inKey, - void* outKey, void* outVal, mork_change** outChange) -{ - mork_bool outGet = morkBool_kFalse; - - if ( this->GoodMap() ) /* looks good? */ - { - mork_u4 hash = this->Hash(ev, inKey); - morkAssoc** ref = this->find(ev, inKey, hash); - if ( ref ) /* found an assoc for inKey? */ - { - mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */ - outGet = morkBool_kTrue; - this->get_assoc(outKey, outVal, i); - if ( outChange ) - { - if ( mMap_Changes ) - *outChange = mMap_Changes + i; - else - *outChange = this->FormDummyChange(); - } - } - } - else this->NewBadMapError(ev); - - return outGet; -} - - -morkMapIter::morkMapIter( ) -: mMapIter_Map( 0 ) -, mMapIter_Seed( 0 ) - -, mMapIter_Bucket( 0 ) -, mMapIter_AssocRef( 0 ) -, mMapIter_Assoc( 0 ) -, mMapIter_Next( 0 ) -{ -} - -void -morkMapIter::InitMapIter(morkEnv* ev, morkMap* ioMap) -{ - mMapIter_Map = 0; - mMapIter_Seed = 0; - - mMapIter_Bucket = 0; - mMapIter_AssocRef = 0; - mMapIter_Assoc = 0; - mMapIter_Next = 0; - - if ( ioMap ) - { - if ( ioMap->GoodMap() ) - { - mMapIter_Map = ioMap; - mMapIter_Seed = ioMap->mMap_Seed; - } - else ioMap->NewBadMapError(ev); - } - else ev->NilPointerError(); -} - -morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap) -: mMapIter_Map( 0 ) -, mMapIter_Seed( 0 ) - -, mMapIter_Bucket( 0 ) -, mMapIter_AssocRef( 0 ) -, mMapIter_Assoc( 0 ) -, mMapIter_Next( 0 ) -{ - if ( ioMap ) - { - if ( ioMap->GoodMap() ) - { - mMapIter_Map = ioMap; - mMapIter_Seed = ioMap->mMap_Seed; - } - else ioMap->NewBadMapError(ev); - } - else ev->NilPointerError(); -} - -void -morkMapIter::CloseMapIter(morkEnv* ev) -{ - MORK_USED_1(ev); - mMapIter_Map = 0; - mMapIter_Seed = 0; - - mMapIter_Bucket = 0; - mMapIter_AssocRef = 0; - mMapIter_Assoc = 0; - mMapIter_Next = 0; -} - -mork_change* -morkMapIter::First(morkEnv* ev, void* outKey, void* outVal) -{ - mork_change* outFirst = 0; - - morkMap* map = mMapIter_Map; - - if ( map && map->GoodMap() ) /* map looks good? */ - { - morkAssoc** bucket = map->mMap_Buckets; - morkAssoc** end = bucket + map->mMap_Slots; /* one past last */ - - mMapIter_Seed = map->mMap_Seed; /* sync the seeds */ - - while ( bucket < end ) /* another bucket in which to look for assocs? */ - { - morkAssoc* assoc = *bucket++; - if ( assoc ) /* found the first map assoc in use? */ - { - mork_pos i = assoc - map->mMap_Assocs; - mork_change* c = map->mMap_Changes; - outFirst = ( c )? (c + i) : map->FormDummyChange(); - - mMapIter_Assoc = assoc; /* current assoc in iteration */ - mMapIter_Next = assoc->mAssoc_Next; /* more in bucket */ - mMapIter_Bucket = --bucket; /* bucket for this assoc */ - mMapIter_AssocRef = bucket; /* slot referencing assoc */ - - map->get_assoc(outKey, outVal, i); - - break; /* end while loop */ - } - } - } - else map->NewBadMapError(ev); - - return outFirst; -} - -mork_change* -morkMapIter::Next(morkEnv* ev, void* outKey, void* outVal) -{ - mork_change* outNext = 0; - - morkMap* map = mMapIter_Map; - - if ( map && map->GoodMap() ) /* map looks good? */ - { - if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */ - { - morkAssoc* here = mMapIter_Assoc; /* current assoc */ - if ( here ) /* iteration is not yet concluded? */ - { - morkAssoc* next = mMapIter_Next; - morkAssoc* assoc = next; /* default new mMapIter_Assoc */ - if ( next ) /* there are more assocs in the same bucket after Here? */ - { - morkAssoc** ref = mMapIter_AssocRef; - - /* (*HereRef) equals Here, except when Here has been cut, after - ** which (*HereRef) always equals Next. So if (*HereRef) is not - ** equal to Next, then HereRef still needs to be updated to point - ** somewhere else other than Here. Otherwise it is fine. - */ - if ( *ref != next ) /* Here was not cut? must update HereRef? */ - mMapIter_AssocRef = &here->mAssoc_Next; - - mMapIter_Next = next->mAssoc_Next; - } - else /* look for the next assoc in the next nonempty bucket */ - { - morkAssoc** bucket = map->mMap_Buckets; - morkAssoc** end = bucket + map->mMap_Slots; /* beyond */ - mMapIter_Assoc = 0; /* default to no more assocs */ - bucket = mMapIter_Bucket; /* last exhausted bucket */ - mMapIter_Assoc = 0; /* default to iteration ended */ - - while ( ++bucket < end ) /* another bucket to search for assocs? */ - { - assoc = *bucket; - if ( assoc ) /* found another map assoc in use? */ - { - mMapIter_Bucket = bucket; - mMapIter_AssocRef = bucket; /* ref to assoc */ - mMapIter_Next = assoc->mAssoc_Next; /* more */ - - break; /* end while loop */ - } - } - } - if ( assoc ) /* did we find another assoc in the iteration? */ - { - mMapIter_Assoc = assoc; /* current assoc */ - mork_pos i = assoc - map->mMap_Assocs; - mork_change* c = map->mMap_Changes; - outNext = ( c )? (c + i) : map->FormDummyChange(); - - map->get_assoc( outKey, outVal, i); - } - } - } - else map->NewIterOutOfSyncError(ev); - } - else map->NewBadMapError(ev); - - return outNext; -} - -mork_change* -morkMapIter::Here(morkEnv* ev, void* outKey, void* outVal) -{ - mork_change* outHere = 0; - - morkMap* map = mMapIter_Map; - - if ( map && map->GoodMap() ) /* map looks good? */ - { - if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */ - { - morkAssoc* here = mMapIter_Assoc; /* current assoc */ - if ( here ) /* iteration is not yet concluded? */ - { - mork_pos i = here - map->mMap_Assocs; - mork_change* c = map->mMap_Changes; - outHere = ( c )? (c + i) : map->FormDummyChange(); - - map->get_assoc(outKey, outVal, i); - } - } - else map->NewIterOutOfSyncError(ev); - } - else map->NewBadMapError(ev); - - return outHere; -} - -mork_change* -morkMapIter::CutHere(morkEnv* ev, void* outKey, void* outVal) -{ - mork_change* outCutHere = 0; - morkMap* map = mMapIter_Map; - - if ( map && map->GoodMap() ) /* map looks good? */ - { - if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */ - { - morkAssoc* here = mMapIter_Assoc; /* current assoc */ - if ( here ) /* iteration is not yet concluded? */ - { - morkAssoc** ref = mMapIter_AssocRef; - if ( *ref != mMapIter_Next ) /* not already cut? */ - { - mork_pos i = here - map->mMap_Assocs; - mork_change* c = map->mMap_Changes; - outCutHere = ( c )? (c + i) : map->FormDummyChange(); - if ( outKey || outVal ) - map->get_assoc(outKey, outVal, i); - - map->push_free_assoc(here); /* add to free list */ - *ref = mMapIter_Next; /* unlink here from bucket list */ - - /* note the map has changed, but we are still in sync: */ - mMapIter_Seed = ++map->mMap_Seed; /* sync */ - - if ( map->mMap_Fill ) /* still has nonzero value? */ - --map->mMap_Fill; /* one less member in the collection */ - else - map->NewSlotsUnderflowWarning(ev); - } - } - } - else map->NewIterOutOfSyncError(ev); - } - else map->NewBadMapError(ev); - - return outCutHere; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkMap.h b/db/mork/src/morkMap.h deleted file mode 100644 index 612c18611f6f..000000000000 --- a/db/mork/src/morkMap.h +++ /dev/null @@ -1,394 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKMAP_ -#define _MORKMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/* (These hash methods closely resemble those in public domain IronDoc.) */ - -/*| Equal: equal for hash table. Note equal(a,b) implies hash(a)==hash(b). -|*/ -typedef mork_bool (* morkMap_mEqual) -(const morkMap* self, morkEnv* ev, const void* inKeyA, const void* inKeyB); - -/*| Hash: hash for hash table. Note equal(a,b) implies hash(a)==hash(b). -|*/ -typedef mork_u4 (* morkMap_mHash) -(const morkMap* self, morkEnv* ev, const void* inKey); - -/*| IsNil: whether a key slot contains a "null" value denoting "no such key". -|*/ -typedef mork_bool (* morkMap_mIsNil) -(const morkMap* self, morkEnv* ev, const void* inKey); - -/*| Note: notify regarding a refcounting change for a key or a value. -|*/ -//typedef void (* morkMap_mNote) -//(morkMap* self, morkEnv* ev, void* inKeyOrVal); - -/*| morkMapForm: slots need to initialize a new dict. (This is very similar -**| to the config object for public domain IronDoc hash tables.) -|*/ -class morkMapForm { // a struct of callback method pointers for morkMap -public: - - // const void* mMapForm_NilKey; // externally defined 'nil' bit pattern - - // void* mMapForm_NilBuf[ 8 ]; // potential place to put NilKey - // If keys are no larger than 8*sizeof(void*), NilKey can be put in NilBuf. - // Note this should be true for all Mork subclasses, and we plan usage so. - - // These three methods must always be provided, so zero will cause errors: - - // morkMap_mEqual mMapForm_Equal; // for comparing two keys for identity - // morkMap_mHash mMapForm_Hash; // deterministic key to hash method - // morkMap_mIsNil mMapForm_IsNil; // to query whether a key equals 'nil' - - // If any of these method slots are nonzero, then morkMap will call the - // appropriate one to notify dict users when a key or value is added or cut. - // Presumably a caller wants to know this in order to perform refcounting or - // some other kind of memory management. These methods are definitely only - // called when references to keys or values are inserted or removed, and are - // never called when the actual number of references does not change (such - // as when added keys are already present or cut keys are alreading missing). - // - // morkMap_mNote mMapForm_AddKey; // if nonzero, notify about add key - // morkMap_mNote mMapForm_CutKey; // if nonzero, notify about cut key - // morkMap_mNote mMapForm_AddVal; // if nonzero, notify about add val - // morkMap_mNote mMapForm_CutVal; // if nonzero, notify about cut val - // - // These note methods have been removed because it seems difficult to - // guarantee suitable alignment of objects passed to notification methods. - - // Note dict clients should pick key and val sizes that provide whatever - // alignment will be required for an array of such keys and values. - mork_size mMapForm_KeySize; // size of every key (cannot be zero) - mork_size mMapForm_ValSize; // size of every val (can indeed be zero) - - mork_bool mMapForm_HoldChanges; // support changes array in the map - mork_change mMapForm_DummyChange; // change used for false HoldChanges - mork_bool mMapForm_KeyIsIP; // key is mork_ip sized - mork_bool mMapForm_ValIsIP; // key is mork_ip sized -}; - -/*| morkAssoc: a canonical association slot in a morkMap. A single assoc -**| instance does nothing except point to the next assoc in the same bucket -**| of a hash table. Each assoc has only two interesting attributes: 1) the -**| address of the assoc, and 2) the next assoc in a bucket's list. The assoc -**| address is interesting because in the context of an array of such assocs, -**| one can determine the index of a particular assoc in the array by address -**| arithmetic, subtracting the array address from the assoc address. And the -**| index of each assoc is the same index as the associated key and val slots -**| in the associated arrays -**| -**|| Think of an assoc instance as really also containing a key slot and a val -**| slot, where each key is mMap_Form.mMapForm_KeySize bytes in size, and -**| each val is mMap_Form.mMapForm_ValSize in size. But the key and val -**| slots are stored in separate arrays with indexes that are parallel to the -**| indexes in the array of morkAssoc instances. We have taken the variable -**| sized slots out of the morkAssoc structure, and put them into parallel -**| arrays associated with each morkAssoc by array index. And this leaves us -**| with only the link field to the next assoc in each assoc instance. -|*/ -class morkAssoc { -public: - morkAssoc* mAssoc_Next; -}; - - -#define morkDerived_kMap /*i*/ 0x4D70 /* ascii 'Mp' */ - -#define morkMap_kTag /*i*/ 0x6D4D6150 /* ascii 'mMaP' */ - -/*| morkMap: a hash table based on the public domain IronDoc hash table -**| (which is in turn rather like a similar OpenDoc hash table). -|*/ -class morkMap : public morkNode { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - - nsIMdbHeap* mMap_Heap; // strong ref to heap allocating all space - mork_u4 mMap_Tag; // must equal morkMap_kTag - - // When a morkMap instance is constructed, the dict form slots must be - // provided in order to properly configure a dict with all runtime needs: - - morkMapForm mMap_Form; // construction time parameterization - - // Whenever the dict changes structure in a way that would affect any - // iteration of the dict associations, the seed increments to show this: - - mork_seed mMap_Seed; // counter for member and structural changes - - // The current total assoc capacity of the dict is mMap_Slots, where - // mMap_Fill of these slots are actually holding content, so mMap_Fill - // is the actual membership count, and mMap_Slots is how larger membership - // can become before the hash table must grow the buffers being used. - - mork_count mMap_Slots; // count of slots in the hash table - mork_fill mMap_Fill; // number of used slots in the hash table - - // Key and value slots are bound to corresponding mMap_Assocs array slots. - // Instead of having a single array like this: {key,val,next}[ mMap_Slots ] - // we have instead three parallel arrays with essentially the same meaning: - // {key}[ mMap_Slots ], {val}[ mMap_Slots ], {assocs}[ mMap_Slots ] - - mork_u1* mMap_Keys; // mMap_Slots * mMapForm_KeySize buffer - mork_u1* mMap_Vals; // mMap_Slots * mMapForm_ValSize buffer - - // An assoc is "used" when it appears in a bucket's linked list of assocs. - // Until an assoc is used, it appears in the FreeList linked list. Every - // assoc that becomes used goes into the bucket determined by hashing the - // key associated with a new assoc. The key associated with a new assoc - // goes in to the slot in mMap_Keys which occupies exactly the same array - // index as the array index of the used assoc in the mMap_Assocs array. - - morkAssoc* mMap_Assocs; // mMap_Slots * sizeof(morkAssoc) buffer - - // The changes array is only needed when the - - mork_change* mMap_Changes; // mMap_Slots * sizeof(mork_change) buffer - - // The Buckets array need not be the same length as the Assocs array, but we - // usually do it that way so the average bucket depth is no more than one. - // (We could pick a different policy, or make it parameterizable, but that's - // tuning we can do some other time.) - - morkAssoc** mMap_Buckets; // mMap_Slots * sizeof(morkAssoc*) buffer - - // The length of the mMap_FreeList should equal (mMap_Slots - mMap_Fill). - // We need a free list instead of a simpler representation because assocs - // can be cut and returned to availability in any kind of unknown pattern. - // (However, when assocs are first allocated, or when the dict is grown, we - // know all new assocs are contiguous and can chain together adjacently.) - - morkAssoc* mMap_FreeList; // list of unused mMap_Assocs array slots - -public: // getters (morkProbeMap compatibility) - mork_fill MapFill() const { return mMap_Fill; } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseMap() only if open - virtual ~morkMap(); // assert that CloseMap() executed earlier - -public: // morkMap construction & destruction - morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioNodeHeap, - mork_size inKeySize, mork_size inValSize, - mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges); - - void CloseMap(morkEnv* ev); // called by - -public: // dynamic type identification - mork_bool IsMap() const - { return IsNode() && mNode_Derived == morkDerived_kMap; } -// } ===== end morkNode methods ===== - -public: // poly map hash table methods - -// { ===== begin morkMap poly interface ===== - virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const = 0; - - virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) - Hash(morkEnv* ev, const void* inKey) const = 0; -// } ===== end morkMap poly interface ===== - -public: // open utitity methods - - mork_bool GoodMapTag() const { return mMap_Tag == morkMap_kTag; } - mork_bool GoodMap() const - { return ( IsNode() && GoodMapTag() ); } - - void NewIterOutOfSyncError(morkEnv* ev); - void NewBadMapError(morkEnv* ev); - void NewSlotsUnderflowWarning(morkEnv* ev); - void InitMap(morkEnv* ev, mork_size inSlots); - -protected: // internal utitity methods - - friend class morkMapIter; - void clear_map(morkEnv* ev, nsIMdbHeap* ioHeap); - - void* alloc(morkEnv* ev, mork_size inSize); - void* clear_alloc(morkEnv* ev, mork_size inSize); - - void push_free_assoc(morkAssoc* ioAssoc) - { - ioAssoc->mAssoc_Next = mMap_FreeList; - mMap_FreeList = ioAssoc; - } - - morkAssoc* pop_free_assoc() - { - morkAssoc* assoc = mMap_FreeList; - if ( assoc ) - mMap_FreeList = assoc->mAssoc_Next; - return assoc; - } - - morkAssoc** find(morkEnv* ev, const void* inKey, mork_u4 inHash) const; - - mork_u1* new_keys(morkEnv* ev, mork_num inSlots); - mork_u1* new_values(morkEnv* ev, mork_num inSlots); - mork_change* new_changes(morkEnv* ev, mork_num inSlots); - morkAssoc** new_buckets(morkEnv* ev, mork_num inSlots); - morkAssoc* new_assocs(morkEnv* ev, mork_num inSlots); - mork_bool new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots); - - mork_bool grow(morkEnv* ev); - - void get_assoc(void* outKey, void* outVal, mork_pos inPos) const; - void put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const; - -public: // inlines to form slots - // const void* FormNilKey() const { return mMap_Form.mMapForm_NilKey; } - - // morkMap_mEqual FormEqual() const { return mMap_Form.mMapForm_Equal; } - // morkMap_mHash FormHash() const { return mMap_Form.mMapForm_Hash; } - // orkMap_mIsNil FormIsNil() const { return mMap_Form.mMapForm_IsNil; } - - // morkMap_mNote FormAddKey() const { return mMap_Form.mMapForm_AddKey; } - // morkMap_mNote FormCutKey() const { return mMap_Form.mMapForm_CutKey; } - // morkMap_mNote FormAddVal() const { return mMap_Form.mMapForm_AddVal; } - // morkMap_mNote FormCutVal() const { return mMap_Form.mMapForm_CutVal; } - - mork_size FormKeySize() const { return mMap_Form.mMapForm_KeySize; } - mork_size FormValSize() const { return mMap_Form.mMapForm_ValSize; } - - mork_bool FormKeyIsIP() const { return mMap_Form.mMapForm_KeyIsIP; } - mork_bool FormValIsIP() const { return mMap_Form.mMapForm_ValIsIP; } - - mork_bool FormHoldChanges() const - { return mMap_Form.mMapForm_HoldChanges; } - - mork_change* FormDummyChange() - { return &mMap_Form.mMapForm_DummyChange; } - -public: // other map methods - - mork_bool Put(morkEnv* ev, const void* inKey, const void* inVal, - void* outKey, void* outVal, mork_change** outChange); - - mork_bool Cut(morkEnv* ev, const void* inKey, - void* outKey, void* outVal, mork_change** outChange); - - mork_bool Get(morkEnv* ev, const void* inKey, - void* outKey, void* outVal, mork_change** outChange); - - mork_num CutAll(morkEnv* ev); - -private: // copying is not allowed - morkMap(const morkMap& other); - morkMap& operator=(const morkMap& other); - - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakMap(morkMap* me, - morkEnv* ev, morkMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongMap(morkMap* me, - morkEnv* ev, morkMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -/*| morkMapIter: an iterator for morkMap and subclasses. This is not a node, -**| and expected usage is as a member of some other node subclass, such as in -**| a cursor subclass or a thumb subclass. Also, iters might be as temp stack -**| objects when scanning the content of a map. -|*/ -class morkMapIter{ // iterator for hash table map - -protected: - morkMap* mMapIter_Map; // map to iterate, NOT refcounted - mork_seed mMapIter_Seed; // cached copy of map's seed - - morkAssoc** mMapIter_Bucket; // one bucket in mMap_Buckets array - morkAssoc** mMapIter_AssocRef; // usually *AtRef equals Here - morkAssoc* mMapIter_Assoc; // the current assoc in an iteration - morkAssoc* mMapIter_Next; // mMapIter_Assoc->mAssoc_Next */ - -public: - morkMapIter(morkEnv* ev, morkMap* ioMap); - void CloseMapIter(morkEnv* ev); - - morkMapIter( ); // everything set to zero -- need to call InitMapIter() - -protected: // we want all subclasses to provide typesafe wrappers: - - void InitMapIter(morkEnv* ev, morkMap* ioMap); - - // The morkAssoc returned below is always either mork_change* or - // else nil (when there is no such assoc). We return a pointer to - // the change rather than a simple bool, because callers might - // want to access change info associated with an assoc. - - mork_change* First(morkEnv* ev, void* outKey, void* outVal); - mork_change* Next(morkEnv* ev, void* outKey, void* outVal); - mork_change* Here(morkEnv* ev, void* outKey, void* outVal); - - mork_change* CutHere(morkEnv* ev, void* outKey, void* outVal); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKMAP_ */ diff --git a/db/mork/src/morkNode.cpp b/db/mork/src/morkNode.cpp deleted file mode 100644 index a58986e0c21f..000000000000 --- a/db/mork/src/morkNode.cpp +++ /dev/null @@ -1,687 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKHANDLE_ -#include "morkHandle.h" -#endif - -/*3456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678*/ - -/* ===== ===== ===== ===== morkUsage ===== ===== ===== ===== */ - -static morkUsage morkUsage_gHeap; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kHeap = morkUsage_gHeap; - -static morkUsage morkUsage_gStack; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kStack = morkUsage_gStack; - -static morkUsage morkUsage_gMember; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kMember = morkUsage_gMember; - -static morkUsage morkUsage_gGlobal; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kGlobal = morkUsage_gGlobal; - -static morkUsage morkUsage_gPool; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kPool = morkUsage_gPool; - -static morkUsage morkUsage_gNone; // ensure EnsureReadyStaticUsage() -const morkUsage& morkUsage::kNone = morkUsage_gNone; - -// This must be structured to allow for non-zero values in global variables -// just before static init time. We can only safely check for whether a -// global has the address of some other global. Please, do not initialize -// either of the variables below to zero, because this could break when a zero -// is assigned at static init time, but after EnsureReadyStaticUsage() runs. - -static mork_u4 morkUsage_g_static_init_target; // only address of this matters -static mork_u4* morkUsage_g_static_init_done; // is address of target above? - -#define morkUsage_do_static_init() \ - ( morkUsage_g_static_init_done = &morkUsage_g_static_init_target ) - -#define morkUsage_need_static_init() \ - ( morkUsage_g_static_init_done != &morkUsage_g_static_init_target ) - -/*static*/ -void morkUsage::EnsureReadyStaticUsage() -{ - if ( morkUsage_need_static_init() ) - { - morkUsage_do_static_init(); - - morkUsage_gHeap.InitUsage(morkUsage_kHeap); - morkUsage_gStack.InitUsage(morkUsage_kStack); - morkUsage_gMember.InitUsage(morkUsage_kMember); - morkUsage_gGlobal.InitUsage(morkUsage_kGlobal); - morkUsage_gPool.InitUsage(morkUsage_kPool); - morkUsage_gNone.InitUsage(morkUsage_kNone); - } -} - -/*static*/ -const morkUsage& morkUsage::GetHeap() // kHeap safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gHeap; -} - -/*static*/ -const morkUsage& morkUsage::GetStack() // kStack safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gStack; -} - -/*static*/ -const morkUsage& morkUsage::GetMember() // kMember safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gMember; -} - -/*static*/ -const morkUsage& morkUsage::GetGlobal() // kGlobal safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gGlobal; -} - -/*static*/ -const morkUsage& morkUsage::GetPool() // kPool safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gPool; -} - -/*static*/ -const morkUsage& morkUsage::GetNone() // kNone safe at static init time -{ - EnsureReadyStaticUsage(); - return morkUsage_gNone; -} - -morkUsage::morkUsage() -{ - if ( morkUsage_need_static_init() ) - { - morkUsage::EnsureReadyStaticUsage(); - } -} - -morkUsage::morkUsage(mork_usage code) - : mUsage_Code(code) -{ - if ( morkUsage_need_static_init() ) - { - morkUsage::EnsureReadyStaticUsage(); - } -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*static*/ void* -morkNode::MakeNew(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) -{ - void* node = 0; - if ( &ioHeap ) - { - ioHeap.Alloc(ev->AsMdbEnv(), inSize, (void **) &node); - if ( !node ) - ev->OutOfMemoryError(); - } - else - ev->NilPointerError(); - - return node; -} - -/*public non-poly*/ void -morkNode::ZapOld(morkEnv* ev, nsIMdbHeap* ioHeap) -{ - if ( this ) - { - if ( this->IsNode() ) - { - mork_usage usage = mNode_Usage; // mNode_Usage before ~morkNode - this->morkNode::~morkNode(); // first call polymorphic destructor - if ( ioHeap ) // was this node heap allocated? - ioHeap->Free(ev->AsMdbEnv(), this); - else if ( usage == morkUsage_kPool ) // mNode_Usage before ~morkNode - { - morkHandle* h = (morkHandle*) this; - if ( h->IsHandle() && h->GoodHandleTag() ) - { - if ( h->mHandle_Face ) - { - if (ev->mEnv_HandlePool) - ev->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face); - else if (h->mHandle_Env && h->mHandle_Env->mEnv_HandlePool) - h->mHandle_Env->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face); - } - else - ev->NilPointerError(); - } - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -/*public virtual*/ void -morkNode::CloseMorkNode(morkEnv* ev) // CloseNode() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseNode(ev); - this->MarkShut(); - } -} -NS_IMETHODIMP -morkNode::CloseMdbObject(nsIMdbEnv* mev) -{ - return morkNode::CloseMdbObject((morkEnv *) mev); -} - -mdb_err morkNode::CloseMdbObject(morkEnv *ev) -{ - // if only one ref, Handle_CutStrongRef will clean up better. - if (mNode_Uses == 1) - return CutStrongRef(ev); - - mdb_err outErr = 0; - - if ( IsNode() && IsOpenNode() ) - { - if ( ev ) - { - CloseMorkNode(ev); - outErr = ev->AsErr(); - } - } - return outErr; -} - -/*public virtual*/ -morkNode::~morkNode() // assert that CloseNode() executed earlier -{ - MORK_ASSERT(this->IsShutNode() || IsDeadNode()); // sometimes we call destructor explictly w/o freeing object. - mNode_Access = morkAccess_kDead; - mNode_Usage = morkUsage_kNone; -} - -/*public virtual*/ -// void CloseMorkNode(morkEnv* ev) = 0; // CloseNode() only if open - // CloseMorkNode() is the polymorphic close method called when uses==0, - // which must do NOTHING at all when IsOpenNode() is not true. Otherwise, - // CloseMorkNode() should call a static close method specific to an object. - // Each such static close method should either call inherited static close - // methods, or else perform the consolidated effect of calling them, where - // subclasses should closely track any changes in base classes with care. - - -/*public non-poly*/ -morkNode::morkNode( mork_usage inCode ) -: mNode_Heap( 0 ) -, mNode_Base( morkBase_kNode ) -, mNode_Derived ( 0 ) // until subclass sets appropriately -, mNode_Access( morkAccess_kOpen ) -, mNode_Usage( inCode ) -, mNode_Mutable( morkAble_kEnabled ) -, mNode_Load( morkLoad_kClean ) -, mNode_Uses( 1 ) -, mNode_Refs( 1 ) -{ -} - -/*public non-poly*/ -morkNode::morkNode(const morkUsage& inUsage, nsIMdbHeap* ioHeap) -: mNode_Heap( ioHeap ) -, mNode_Base( morkBase_kNode ) -, mNode_Derived ( 0 ) // until subclass sets appropriately -, mNode_Access( morkAccess_kOpen ) -, mNode_Usage( inUsage.Code() ) -, mNode_Mutable( morkAble_kEnabled ) -, mNode_Load( morkLoad_kClean ) -, mNode_Uses( 1 ) -, mNode_Refs( 1 ) -{ - if ( !ioHeap && mNode_Usage == morkUsage_kHeap ) - MORK_ASSERT(ioHeap); -} - -/*public non-poly*/ -morkNode::morkNode(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap) -: mNode_Heap( ioHeap ) -, mNode_Base( morkBase_kNode ) -, mNode_Derived ( 0 ) // until subclass sets appropriately -, mNode_Access( morkAccess_kOpen ) -, mNode_Usage( inUsage.Code() ) -, mNode_Mutable( morkAble_kEnabled ) -, mNode_Load( morkLoad_kClean ) -, mNode_Uses( 1 ) -, mNode_Refs( 1 ) -{ - if ( !ioHeap && mNode_Usage == morkUsage_kHeap ) - { - this->NilHeapError(ev); - } -} - -/*protected non-poly*/ void -morkNode::RefsUnderUsesWarning(morkEnv* ev) const -{ - ev->NewError("mNode_Refs < mNode_Uses"); -} - -/*protected non-poly*/ void -morkNode::NonNodeError(morkEnv* ev) const // called when IsNode() is false -{ - ev->NewError("non-morkNode"); -} - -/*protected non-poly*/ void -morkNode::NonOpenNodeError(morkEnv* ev) const // when IsOpenNode() is false -{ - ev->NewError("non-open-morkNode"); -} - -/*protected non-poly*/ void -morkNode::NonMutableNodeError(morkEnv* ev) const // when IsMutable() is false -{ - ev->NewError("non-mutable-morkNode"); -} - -/*protected non-poly*/ void -morkNode::NilHeapError(morkEnv* ev) const // zero mNode_Heap w/ kHeap usage -{ - ev->NewError("nil mNode_Heap"); -} - -/*protected non-poly*/ void -morkNode::RefsOverflowWarning(morkEnv* ev) const // mNode_Refs overflow -{ - ev->NewWarning("mNode_Refs overflow"); -} - -/*protected non-poly*/ void -morkNode::UsesOverflowWarning(morkEnv* ev) const // mNode_Uses overflow -{ - ev->NewWarning("mNode_Uses overflow"); -} - -/*protected non-poly*/ void -morkNode::RefsUnderflowWarning(morkEnv* ev) const // mNode_Refs underflow -{ - ev->NewWarning("mNode_Refs underflow"); -} - -/*protected non-poly*/ void -morkNode::UsesUnderflowWarning(morkEnv* ev) const // mNode_Uses underflow -{ - ev->NewWarning("mNode_Uses underflow"); -} - -/*public non-poly*/ void -morkNode::CloseNode(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - this->MarkShut(); - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - - -extern void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev, - nsIMdbCompare** ioSlot) - // If *ioSlot is non-nil, that compare is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, this is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we take - // expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'. -{ - nsIMdbEnv* menv = ev->AsMdbEnv(); - nsIMdbCompare* compare = *ioSlot; - if ( self != compare ) - { - if ( compare ) - { - *ioSlot = 0; - compare->CutStrongRef(menv); - } - if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() ) - *ioSlot = self; - } -} - - -extern void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot) - // If *ioSlot is non-nil, that file is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, this is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we take - // expression 'nsIMdbFile_SlotStrongFile(0, ev, &slot)'. -{ - nsIMdbFile* file = *ioSlot; - if ( self != file ) - { - if ( file ) - { - *ioSlot = 0; - NS_RELEASE(file); - } - if ( self && ev->Good() && (NS_ADDREF(self)>=0) && ev->Good() ) - *ioSlot = self; - } -} - -void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot) - // If *ioSlot is non-nil, that heap is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, self is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we - // permit expression 'nsIMdbHeap_SlotStrongHeap(0, ev, &slot)'. -{ - nsIMdbEnv* menv = ev->AsMdbEnv(); - nsIMdbHeap* heap = *ioSlot; - if ( self != heap ) - { - if ( heap ) - { - *ioSlot = 0; - heap->HeapCutStrongRef(menv); - } - if ( self && ev->Good() && (self->HeapAddStrongRef(menv)==0) && ev->Good() ) - *ioSlot = self; - } -} - -/*public static*/ void -morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot) - // If *ioSlot is non-nil, that node is released by CutStrongRef() and - // then zeroed out. Then if me is non-nil, this is acquired by - // calling AddStrongRef(), and if positive is returned to show success, - // then me is put into slot *ioSlot. Note me can be nil, so we take - // expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'. -{ - morkNode* node = *ioSlot; - if ( me != node ) - { - if ( node ) - { - // what if this nulls out the ev and causes asserts? - // can we move this after the CutStrongRef()? - *ioSlot = 0; - node->CutStrongRef(ev); - } - if ( me && me->AddStrongRef(ev) ) - *ioSlot = me; - } -} - -/*public static*/ void -morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot) - // If *ioSlot is non-nil, that node is released by CutWeakRef() and - // then zeroed out. Then if me is non-nil, this is acquired by - // calling AddWeakRef(), and if positive is returned to show success, - // then me is put into slot *ioSlot. Note me can be nil, so we - // expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'. -{ - morkNode* node = *ioSlot; - if ( me != node ) - { - if ( node ) - { - *ioSlot = 0; - node->CutWeakRef(ev); - } - if ( me && me->AddWeakRef(ev) ) - *ioSlot = me; - } -} - -/*public non-poly*/ mork_uses -morkNode::AddStrongRef(morkEnv* ev) -{ - mork_uses outUses = 0; - if ( this ) - { - if ( this->IsNode() ) - { - mork_uses uses = mNode_Uses; - mork_refs refs = mNode_Refs; - if ( refs < uses ) // need to fix broken refs/uses relation? - { - this->RefsUnderUsesWarning(ev); - mNode_Refs = mNode_Uses = refs = uses; - } - if ( refs < morkNode_kMaxRefCount ) // not too great? - { - mNode_Refs = ++refs; - mNode_Uses = ++uses; - } - else - this->RefsOverflowWarning(ev); - - outUses = uses; - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); - return outUses; -} - -/*private non-poly*/ mork_bool -morkNode::cut_use_count(morkEnv* ev) // just one part of CutStrongRef() -{ - mork_bool didCut = morkBool_kFalse; - if ( this ) - { - if ( this->IsNode() ) - { - mork_uses uses = mNode_Uses; - if ( uses ) // not yet zero? - mNode_Uses = --uses; - else - this->UsesUnderflowWarning(ev); - - didCut = morkBool_kTrue; - if ( !mNode_Uses ) // last use gone? time to close node? - { - if ( this->IsOpenNode() ) - { - if ( !mNode_Refs ) // no outstanding reference? - { - this->RefsUnderflowWarning(ev); - ++mNode_Refs; // prevent potential crash during close - } - this->CloseMorkNode(ev); // polymorphic self close - // (Note CutNode() is not polymorphic -- so don't call that.) - } - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); - return didCut; -} - -/*public non-poly*/ mork_uses -morkNode::CutStrongRef(morkEnv* ev) -{ - mork_refs outRefs = 0; - if ( this ) - { - if ( this->IsNode() ) - { - if ( this->cut_use_count(ev) ) - outRefs = this->CutWeakRef(ev); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); - return outRefs; -} - -/*public non-poly*/ mork_refs -morkNode::AddWeakRef(morkEnv* ev) -{ - mork_refs outRefs = 0; - if ( this ) - { - if ( this->IsNode() ) - { - mork_refs refs = mNode_Refs; - if ( refs < morkNode_kMaxRefCount ) // not too great? - mNode_Refs = ++refs; - else - this->RefsOverflowWarning(ev); - - outRefs = refs; - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); - return outRefs; -} - -/*public non-poly*/ mork_refs -morkNode::CutWeakRef(morkEnv* ev) -{ - mork_refs outRefs = 0; - if ( this ) - { - if ( this->IsNode() ) - { - mork_uses uses = mNode_Uses; - mork_refs refs = mNode_Refs; - if ( refs ) // not yet zero? - mNode_Refs = --refs; - else - this->RefsUnderflowWarning(ev); - - if ( refs < uses ) // need to fix broken refs/uses relation? - { - this->RefsUnderUsesWarning(ev); - mNode_Refs = mNode_Uses = refs = uses; - } - - outRefs = refs; - if ( !refs ) // last reference gone? time to destroy node? - this->ZapOld(ev, mNode_Heap); // self destroy, use this no longer - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); - return outRefs; -} - -static const char morkNode_kBroken[] = "broken"; - -/*public non-poly*/ const char* -morkNode::GetNodeAccessAsString() const // e.g. "open", "shut", etc. -{ - const char* outString = morkNode_kBroken; - switch( mNode_Access ) - { - case morkAccess_kOpen: outString = "open"; break; - case morkAccess_kClosing: outString = "closing"; break; - case morkAccess_kShut: outString = "shut"; break; - case morkAccess_kDead: outString = "dead"; break; - } - return outString; -} - -/*public non-poly*/ const char* -morkNode::GetNodeUsageAsString() const // e.g. "heap", "stack", etc. -{ - const char* outString = morkNode_kBroken; - switch( mNode_Usage ) - { - case morkUsage_kHeap: outString = "heap"; break; - case morkUsage_kStack: outString = "stack"; break; - case morkUsage_kMember: outString = "member"; break; - case morkUsage_kGlobal: outString = "global"; break; - case morkUsage_kPool: outString = "pool"; break; - case morkUsage_kNone: outString = "none"; break; - } - return outString; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkNode.h b/db/mork/src/morkNode.h deleted file mode 100644 index 24ad9736d579..000000000000 --- a/db/mork/src/morkNode.h +++ /dev/null @@ -1,301 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKNODE_ -#define _MORKNODE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkUsage_kHeap 'h' -#define morkUsage_kStack 's' -#define morkUsage_kMember 'm' -#define morkUsage_kGlobal 'g' -#define morkUsage_kPool 'p' -#define morkUsage_kNone 'n' - -class morkUsage { -public: - mork_usage mUsage_Code; // kHeap, kStack, kMember, or kGhost - -public: - morkUsage(mork_usage inCode); - - morkUsage(); // does nothing except maybe call EnsureReadyStaticUsage() - void InitUsage( mork_usage inCode) - { mUsage_Code = inCode; } - - ~morkUsage() { } - mork_usage Code() const { return mUsage_Code; } - - static void EnsureReadyStaticUsage(); - -public: - static const morkUsage& kHeap; // morkUsage_kHeap - static const morkUsage& kStack; // morkUsage_kStack - static const morkUsage& kMember; // morkUsage_kMember - static const morkUsage& kGlobal; // morkUsage_kGlobal - static const morkUsage& kPool; // morkUsage_kPool - static const morkUsage& kNone; // morkUsage_kNone - - static const morkUsage& GetHeap(); // kHeap, safe at static init time - static const morkUsage& GetStack(); // kStack, safe at static init time - static const morkUsage& GetMember(); // kMember, safe at static init time - static const morkUsage& GetGlobal(); // kGlobal, safe at static init time - static const morkUsage& GetPool(); // kPool, safe at static init time - static const morkUsage& GetNone(); // kNone, safe at static init time - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkNode_kMaxRefCount 0x0FFFF /* count sticks if it hits this */ - -#define morkBase_kNode /*i*/ 0x4E64 /* ascii 'Nd' */ - -/*| morkNode: several groups of two-byte integers that track the basic -**| status of an object that can be used to compose in-memory graphs. -**| This is the base class for nsIMdbObject (which adds members that fit -**| the needs of an nsIMdbObject subclass). The morkNode class is also used -**| as the base class for other Mork db classes with no strong relation to -**| the MDB class hierarchy. -**| -**|| Heap: the heap in which this node was allocated, when the usage equals -**| morkUsage_kHeap to show dynamic allocation. Note this heap is NOT ref- -**| counted, because that would be too great and complex a burden for all -**| the nodes allocated in that heap. So heap users should take care to -**| understand that nodes allocated in that heap are considered protected -**| by some inclusive context in which all those nodes are allocated, and -**| that context must maintain at least one strong refcount for the heap. -**| Occasionally a node subclass will indeed wish to hold a refcounted -**| reference to a heap, and possibly the same heap that is in mNode_Heap, -**| but this is always done in a separate slot that explicitly refcounts, -**| so we avoid confusing what is meant by the mNode_Heap slot. -|*/ -class morkNode /*: public nsISupports */ { // base class for constructing Mork object graphs - -public: // state is public because the entire Mork system is private - -// NS_DECL_ISUPPORTS; - nsIMdbHeap* mNode_Heap; // NON-refcounted heap pointer - - mork_base mNode_Base; // must equal morkBase_kNode - mork_derived mNode_Derived; // depends on specific node subclass - - mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - mork_able mNode_Mutable; // can this node be modified? - mork_load mNode_Load; // is this node clean or dirty? - - mork_uses mNode_Uses; // refcount for strong refs - mork_refs mNode_Refs; // refcount for strong refs + weak refs - -protected: // special case empty construction for morkHandleFrame - friend class morkHandleFrame; - morkNode() { } - -public: // inlines for weird mNode_Mutable and mNode_Load constants - - void SetFrozen() { mNode_Mutable = morkAble_kDisabled; } - void SetMutable() { mNode_Mutable = morkAble_kEnabled; } - void SetAsleep() { mNode_Mutable = morkAble_kAsleep; } - - mork_bool IsFrozen() const { return mNode_Mutable == morkAble_kDisabled; } - mork_bool IsMutable() const { return mNode_Mutable == morkAble_kEnabled; } - mork_bool IsAsleep() const { return mNode_Mutable == morkAble_kAsleep; } - - void SetNodeClean() { mNode_Load = morkLoad_kClean; } - void SetNodeDirty() { mNode_Load = morkLoad_kDirty; } - - mork_bool IsNodeClean() const { return mNode_Load == morkLoad_kClean; } - mork_bool IsNodeDirty() const { return mNode_Load == morkLoad_kDirty; } - -public: // morkNode memory management methods - static void* MakeNew(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev); - - void ZapOld(morkEnv* ev, nsIMdbHeap* ioHeap); // replaces operator delete() - // this->morkNode::~morkNode(); // first call polymorphic destructor - // if ( ioHeap ) // was this node heap allocated? - // ioHeap->Free(ev->AsMdbEnv(), this); - -public: // morkNode memory management operators - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkNode::MakeNew(inSize, ioHeap, ev); } - - -protected: // construction without an anv needed for first env constructed: - morkNode(const morkUsage& inUsage, nsIMdbHeap* ioHeap); - - morkNode(mork_usage inCode); // usage == inCode, heap == nil - -// { ===== begin basic node interface ===== -public: // morkNode virtual methods - // virtual FlushMorkNode(morkEnv* ev, morkStream* ioStream); - // virtual WriteMorkNode(morkEnv* ev, morkStream* ioStream); - - virtual ~morkNode(); // assert that CloseNode() executed earlier - virtual void CloseMorkNode(morkEnv* ev); // CloseNode() only if open - - // CloseMorkNode() is the polymorphic close method called when uses==0, - // which must do NOTHING at all when IsOpenNode() is not true. Otherwise, - // CloseMorkNode() should call a static close method specific to an object. - // Each such static close method should either call inherited static close - // methods, or else perform the consolidated effect of calling them, where - // subclasses should closely track any changes in base classes with care. - -public: // morkNode construction - morkNode(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap); - void CloseNode(morkEnv* ev); // called by CloseMorkNode(); - mdb_err CloseMdbObject(morkEnv *ev); - NS_IMETHOD CloseMdbObject(nsIMdbEnv *ev); -private: // copying is not allowed - morkNode(const morkNode& other); - morkNode& operator=(const morkNode& other); - -public: // dynamic type identification - mork_bool IsNode() const - { return mNode_Base == morkBase_kNode; } -// } ===== end basic node methods ===== - -public: // public error & warning methods - - void RefsUnderUsesWarning(morkEnv* ev) const; // call if mNode_Refs < mNode_Uses - void NonNodeError(morkEnv* ev) const; // call when IsNode() is false - void NilHeapError(morkEnv* ev) const; // zero mNode_Heap when usage is kHeap - void NonOpenNodeError(morkEnv* ev) const; // call when IsOpenNode() is false - - void NonMutableNodeError(morkEnv* ev) const; // when IsMutable() is false - - void RefsOverflowWarning(morkEnv* ev) const; // call on mNode_Refs overflow - void UsesOverflowWarning(morkEnv* ev) const; // call on mNode_Uses overflow - void RefsUnderflowWarning(morkEnv* ev) const; // call on mNode_Refs underflow - void UsesUnderflowWarning(morkEnv* ev) const; // call on mNode_Uses underflow - -private: // private refcounting methods - mork_bool cut_use_count(morkEnv* ev); // just one part of CutStrongRef() - -public: // other morkNode methods - - mork_bool GoodRefs() const { return mNode_Refs >= mNode_Uses; } - mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; } - - mork_uses StrongRefsOnly() const { return mNode_Uses; } - mork_refs WeakRefsOnly() const { return (mork_refs) ( mNode_Refs - mNode_Uses ); } - - // (this refcounting derives from public domain IronDoc node refcounts) - virtual mork_refs AddStrongRef(morkEnv* ev); - virtual mork_refs CutStrongRef(morkEnv* ev); - mork_refs AddWeakRef(morkEnv* ev); - mork_refs CutWeakRef(morkEnv* ev); - - const char* GetNodeAccessAsString() const; // e.g. "open", "shut", etc. - const char* GetNodeUsageAsString() const; // e.g. "heap", "stack", etc. - - mork_usage NodeUsage() const { return mNode_Usage; } - - mork_bool IsHeapNode() const - { return mNode_Usage == morkUsage_kHeap; } - - mork_bool IsOpenNode() const - { return mNode_Access == morkAccess_kOpen; } - - mork_bool IsShutNode() const - { return mNode_Access == morkAccess_kShut; } - - mork_bool IsDeadNode() const - { return mNode_Access == morkAccess_kDead; } - - mork_bool IsClosingNode() const - { return mNode_Access == morkAccess_kClosing; } - - mork_bool IsOpenOrClosingNode() const - { return IsOpenNode() || IsClosingNode(); } - - mork_bool HasNodeAccess() const - { return ( IsOpenNode() || IsShutNode() || IsClosingNode() ); } - - void MarkShut() { mNode_Access = morkAccess_kShut; } - void MarkClosing() { mNode_Access = morkAccess_kClosing; } - void MarkDead() { mNode_Access = morkAccess_kDead; } - -public: // refcounting for typesafe subclass inline methods - static void SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot); - // If *ioSlot is non-nil, that node is released by CutWeakRef() and - // then zeroed out. Then if me is non-nil, this is acquired by - // calling AddWeakRef(), and if positive is returned to show success, - // then this is put into slot *ioSlot. Note me can be nil, so we - // permit expression '((morkNode*) 0L)->SlotWeakNode(ev, &slot)'. - - static void SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot); - // If *ioSlot is non-nil, that node is released by CutStrongRef() and - // then zeroed out. Then if me is non-nil, this is acquired by - // calling AddStrongRef(), and if positive is returned to show success, - // then me is put into slot *ioSlot. Note me can be nil, so we take - // expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'. -}; - -extern void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot); - // If *ioSlot is non-nil, that heap is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, this is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we take - // expression 'nsIMdbHeap_SlotStrongHeap(0, ev, &slot)'. - -extern void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbFile_SlotStrongFile(nsIMdbFile* self, morkEnv* ev, nsIMdbFile** ioSlot); - // If *ioSlot is non-nil, that file is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, this is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we take - // expression 'nsIMdbFile_SlotStrongFile(0, ev, &slot)'. - -extern void // utility method very similar to morkNode::SlotStrongNode(): -nsIMdbCompare_SlotStrongCompare(nsIMdbCompare* self, morkEnv* ev, - nsIMdbCompare** ioSlot); - // If *ioSlot is non-nil, that compare is released by CutStrongRef() and - // then zeroed out. Then if self is non-nil, this is acquired by - // calling AddStrongRef(), and if the return value shows success, - // then self is put into slot *ioSlot. Note self can be nil, so we take - // expression 'nsIMdbCompare_SlotStrongCompare(0, ev, &slot)'. - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKNODE_ */ diff --git a/db/mork/src/morkNodeMap.cpp b/db/mork/src/morkNodeMap.cpp deleted file mode 100644 index 74985d32a64c..000000000000 --- a/db/mork/src/morkNodeMap.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKINTMAP_ -#include "morkIntMap.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkNodeMap::CloseMorkNode(morkEnv* ev) // CloseNodeMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseNodeMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkNodeMap::~morkNodeMap() // assert CloseNodeMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkNodeMap::morkNodeMap(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkIntMap(ev, inUsage, /*valsize*/ sizeof(morkNode*), ioHeap, ioSlotHeap, - /*inHoldChanges*/ morkBool_kTrue) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kNodeMap; -} - -/*public non-poly*/ void -morkNodeMap::CloseNodeMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CutAllNodes(ev); - this->CloseMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -mork_bool -morkNodeMap::AddNode(morkEnv* ev, mork_token inToken, morkNode* ioNode) - // the AddNode() method return value equals ev->Good(). -{ - if ( ioNode && ev->Good() ) - { - morkNode* node = 0; // old val in the map - - mork_bool put = this->Put(ev, &inToken, &ioNode, - /*key*/ (void*) 0, &node, (mork_change**) 0); - - if ( put ) // replaced an existing value for key inToken? - { - if ( node && node != ioNode ) // need to release old node? - node->CutStrongRef(ev); - } - - if ( ev->Bad() || !ioNode->AddStrongRef(ev) ) - { - // problems adding node or increasing refcount? - this->Cut(ev, &inToken, // make sure not in map - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); - } - } - else if ( !ioNode ) - ev->NilPointerError(); - - return ev->Good(); -} - -mork_bool -morkNodeMap::CutNode(morkEnv* ev, mork_token inToken) -{ - morkNode* node = 0; // old val in the map - mork_bool outCutNode = this->Cut(ev, &inToken, - /*key*/ (void*) 0, &node, (mork_change**) 0); - if ( node ) - node->CutStrongRef(ev); - - return outCutNode; -} - -morkNode* -morkNodeMap::GetNode(morkEnv* ev, mork_token inToken) - // Note the returned node does NOT have an increase in refcount for this. -{ - morkNode* node = 0; // old val in the map - this->Get(ev, &inToken, /*key*/ (void*) 0, &node, (mork_change**) 0); - - return node; -} - -mork_num -morkNodeMap::CutAllNodes(morkEnv* ev) - // CutAllNodes() releases all the reference node values. -{ - mork_num outSlots = mMap_Slots; - mork_token key = 0; // old key token in the map - morkNode* val = 0; // old val node in the map - - mork_change* c = 0; - morkNodeMapIter i(ev, this); - for ( c = i.FirstNode(ev, &key, &val); c ; c = i.NextNode(ev, &key, &val) ) - { - if ( val ) - val->CutStrongRef(ev); - i.CutHereNode(ev, /*key*/ (mork_token*) 0, /*val*/ (morkNode**) 0); - } - - return outSlots; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkNodeMap.h b/db/mork/src/morkNodeMap.h deleted file mode 100644 index 6b378247d900..000000000000 --- a/db/mork/src/morkNodeMap.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKNODEMAP_ -#define _MORKNODEMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKINTMAP_ -#include "morkIntMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kNodeMap /*i*/ 0x6E4D /* ascii 'nM' */ - -#define morkNodeMap_kStartSlotCount 512 - -/*| morkNodeMap: maps mork_token -> morkNode -|*/ -class morkNodeMap : public morkIntMap { // for mapping tokens to nodes - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseNodeMap() only if open - virtual ~morkNodeMap(); // assert that CloseNodeMap() executed earlier - -public: // morkMap construction & destruction - morkNodeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - void CloseNodeMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsNodeMap() const - { return IsNode() && mNode_Derived == morkDerived_kNodeMap; } -// } ===== end morkNode methods ===== - -// { ===== begin morkMap poly interface ===== - // use the Equal() and Hash() for mork_u4 inherited from morkIntMap -// } ===== end morkMap poly interface ===== - -protected: // we want all subclasses to provide typesafe wrappers: - - mork_bool AddNode(morkEnv* ev, mork_token inToken, morkNode* ioNode); - // the AddNode() boolean return equals ev->Good(). - - mork_bool CutNode(morkEnv* ev, mork_token inToken); - // The CutNode() boolean return indicates whether removal happened. - - morkNode* GetNode(morkEnv* ev, mork_token inToken); - // Note the returned node does NOT have an increase in refcount for this. - - mork_num CutAllNodes(morkEnv* ev); - // CutAllNodes() releases all the reference node values. -}; - -class morkNodeMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkNodeMapIter(morkEnv* ev, morkNodeMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkNodeMapIter( ) : morkMapIter() { } - void InitNodeMapIter(morkEnv* ev, morkNodeMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* - FirstNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) - { return this->First(ev, outToken, outNode); } - - mork_change* - NextNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) - { return this->Next(ev, outToken, outNode); } - - mork_change* - HereNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) - { return this->Here(ev, outToken, outNode); } - - mork_change* - CutHereNode(morkEnv* ev, mork_token* outToken, morkNode** outNode) - { return this->CutHere(ev, outToken, outNode); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKNODEMAP_ */ diff --git a/db/mork/src/morkObject.cpp b/db/mork/src/morkObject.cpp deleted file mode 100644 index 112666022ba6..000000000000 --- a/db/mork/src/morkObject.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKHANDLE_ -#include "morkHandle.h" -#endif - -#include "nsCOMPtr.h" - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -NS_IMPL_ISUPPORTS1(morkObject, nsIMdbObject) - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkObject::CloseMorkNode(morkEnv* ev) // CloseObject() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseObject(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkObject::~morkObject() // assert CloseObject() executed earlier -{ - if (!IsShutNode()) - CloseMorkNode(this->mMorkEnv); - MORK_ASSERT(mObject_Handle==0); -} - -/*public non-poly*/ -morkObject::morkObject(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor) -: morkBead(inUsage, ioHeap, inBeadColor) -, mObject_Handle( 0 ) -{ - mMorkEnv = nsnull; -} - -/*public non-poly*/ -morkObject::morkObject(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor, morkHandle* ioHandle) -: morkBead(ev, inUsage, ioHeap, inBeadColor) -, mObject_Handle( 0 ) -{ - mMorkEnv = ev; - if ( ev->Good() ) - { - if ( ioHandle ) - morkHandle::SlotWeakHandle(ioHandle, ev, &mObject_Handle); - - if ( ev->Good() ) - mNode_Derived = morkDerived_kObject; - } -} - -/*public non-poly*/ void -morkObject::CloseObject(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - if ( !this->IsShutNode() ) - { - if ( mObject_Handle ) - morkHandle::SlotWeakHandle((morkHandle*) 0L, ev, &mObject_Handle); - - mBead_Color = 0; // this->CloseBead(ev); - this->MarkShut(); - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// { ----- begin factory methods ----- -NS_IMETHODIMP -morkObject::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory) -{ - nsresult rv; - nsCOMPtr obj = do_QueryInterface(mev); - if (obj) - rv = obj->GetMdbFactory(mev, acqFactory); - else - return NS_ERROR_NO_INTERFACE; - - return rv; -} -// } ----- end factory methods ----- - -// { ----- begin ref counting for well-behaved cyclic graphs ----- -NS_IMETHODIMP -morkObject::GetWeakRefCount(nsIMdbEnv* mev, // weak refs - mdb_count* outCount) -{ - *outCount = WeakRefsOnly(); - return NS_OK; -} -NS_IMETHODIMP -morkObject::GetStrongRefCount(nsIMdbEnv* mev, // strong refs - mdb_count* outCount) -{ - *outCount = StrongRefsOnly(); - return NS_OK; -} -// ### TODO - clean up this cast, if required -NS_IMETHODIMP -morkObject::AddWeakRef(nsIMdbEnv* mev) -{ - return morkNode::AddWeakRef((morkEnv *) mev); -} -NS_IMETHODIMP -morkObject::AddStrongRef(nsIMdbEnv* mev) -{ - return morkNode::AddStrongRef((morkEnv *) mev); -} - -NS_IMETHODIMP -morkObject::CutWeakRef(nsIMdbEnv* mev) -{ - return morkNode::CutWeakRef((morkEnv *) mev); -} -NS_IMETHODIMP -morkObject::CutStrongRef(nsIMdbEnv* mev) -{ - return morkNode::CutStrongRef((morkEnv *) mev); -} - - -NS_IMETHODIMP -morkObject::CloseMdbObject(nsIMdbEnv* mev) -{ - return morkNode::CloseMdbObject((morkEnv *) mev); -} - -NS_IMETHODIMP -morkObject::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen) -{ - *outOpen = IsOpenNode(); - return NS_OK; -} -NS_IMETHODIMP -morkObject::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly) -{ - *outIsReadonly = IsFrozen(); - return NS_OK; -} - -//void morkObject::NewNilHandleError(morkEnv* ev) // mObject_Handle is nil -//{ -// ev->NewError("nil mObject_Handle"); -//} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkObject.h b/db/mork/src/morkObject.h deleted file mode 100644 index 9878d0d37d49..000000000000 --- a/db/mork/src/morkObject.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKOBJECT_ -#define _MORKOBJECT_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKBEAD_ -#include "morkBead.h" -#endif - -#ifndef _MORKCONFIG_ -#include "morkConfig.h" -#endif - -#ifndef _ORKINHEAP_ -#include "orkinHeap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kObject /*i*/ 0x6F42 /* ascii 'oB' */ - -/*| morkObject: subclass of morkNode that adds knowledge of db suite factory -**| and containing port to those objects that are exposed as instances of -**| nsIMdbObject in the public interface. -|*/ -class morkObject : public morkBead, public nsIMdbObject { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - -public: // state is public because the entire Mork system is private - - morkHandle* mObject_Handle; // weak ref to handle for this object - - morkEnv * mMorkEnv; // weak ref to environment this object created in. -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseObject() only if open - virtual ~morkObject(); // assert that CloseObject() executed earlier -#ifdef MORK_DEBUG_HEAP_STATS - void operator delete(void* ioAddress, size_t size) - { - mork_u4* array = (mork_u4*) ioAddress; - array -= 3; - orkinHeap *heap = (orkinHeap *) *array; - if (heap) - heap->Free(nsnull, ioAddress); - } -#endif - - NS_DECL_ISUPPORTS - - // { ----- begin attribute methods ----- - NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly); - // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port. - // } ----- end attribute methods ----- - - // { ----- begin factory methods ----- - NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory); - // } ----- end factory methods ----- - - // { ----- begin ref counting for well-behaved cyclic graphs ----- - NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs - mdb_count* outCount); - NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs - mdb_count* outCount); - - NS_IMETHOD AddWeakRef(nsIMdbEnv* ev); - NS_IMETHOD AddStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CutWeakRef(nsIMdbEnv* ev); - NS_IMETHOD CutStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero - NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen); - // } ----- end ref counting ----- - - -protected: // special case construction of first env without preceding env - morkObject(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor); - -public: // morkEnv construction & destruction - morkObject(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - mork_color inBeadColor, morkHandle* ioHandle); // ioHandle can be nil - void CloseObject(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkObject(const morkObject& other); - morkObject& operator=(const morkObject& other); - -public: // dynamic type identification - mork_bool IsObject() const - { return IsNode() && mNode_Derived == morkDerived_kObject; } -// } ===== end morkNode methods ===== - - // void NewNilHandleError(morkEnv* ev); // mObject_Handle is nil - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakObject(morkObject* me, - morkEnv* ev, morkObject** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongObject(morkObject* me, - morkEnv* ev, morkObject** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKOBJECT_ */ diff --git a/db/mork/src/morkParser.cpp b/db/mork/src/morkParser.cpp deleted file mode 100644 index 3489b2244c21..000000000000 --- a/db/mork/src/morkParser.cpp +++ /dev/null @@ -1,1605 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKPARSER_ -#include "morkParser.h" -#endif - -#ifndef _MORKSTREAM_ -#include "morkStream.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKSINK_ -#include "morkSink.h" -#endif - -#ifndef _MORKCH_ -#include "morkCh.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkParser::CloseMorkNode(morkEnv* ev) // CloseParser() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseParser(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkParser::~morkParser() // assert CloseParser() executed earlier -{ - MORK_ASSERT(mParser_Heap==0); - MORK_ASSERT(mParser_Stream==0); -} - -/*public non-poly*/ -morkParser::morkParser(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkStream* ioStream, mdb_count inBytesPerParseSegment, - nsIMdbHeap* ioSlotHeap) -: morkNode(ev, inUsage, ioHeap) -, mParser_Heap( 0 ) -, mParser_Stream( 0 ) -, mParser_MoreGranularity( inBytesPerParseSegment ) -, mParser_State( morkParser_kStartState ) - -, mParser_GroupContentStartPos( 0 ) - -, mParser_TableMid( ) -, mParser_RowMid( ) -, mParser_CellMid( ) - -, mParser_InPort( morkBool_kFalse ) -, mParser_InDict( morkBool_kFalse ) -, mParser_InCell( morkBool_kFalse ) -, mParser_InMeta( morkBool_kFalse ) - -, mParser_InPortRow( morkBool_kFalse ) -, mParser_InRow( morkBool_kFalse ) -, mParser_InTable( morkBool_kFalse ) -, mParser_InGroup( morkBool_kFalse ) - -, mParser_AtomChange( morkChange_kNil ) -, mParser_CellChange( morkChange_kNil ) -, mParser_RowChange( morkChange_kNil ) -, mParser_TableChange( morkChange_kNil ) - -, mParser_Change( morkChange_kNil ) -, mParser_IsBroken( morkBool_kFalse ) -, mParser_IsDone( morkBool_kFalse ) -, mParser_DoMore( morkBool_kTrue ) - -, mParser_Mid() - -, mParser_ScopeCoil(ev, ioSlotHeap) -, mParser_ValueCoil(ev, ioSlotHeap) -, mParser_ColumnCoil(ev, ioSlotHeap) -, mParser_StringCoil(ev, ioSlotHeap) - -, mParser_ScopeSpool(ev, &mParser_ScopeCoil) -, mParser_ValueSpool(ev, &mParser_ValueCoil) -, mParser_ColumnSpool(ev, &mParser_ColumnCoil) -, mParser_StringSpool(ev, &mParser_StringCoil) - -, mParser_MidYarn(ev, morkUsage_kMember, ioSlotHeap) -{ - if ( inBytesPerParseSegment < morkParser_kMinGranularity ) - inBytesPerParseSegment = morkParser_kMinGranularity; - else if ( inBytesPerParseSegment > morkParser_kMaxGranularity ) - inBytesPerParseSegment = morkParser_kMaxGranularity; - - mParser_MoreGranularity = inBytesPerParseSegment; - - if ( ioSlotHeap && ioStream ) - { - nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mParser_Heap); - morkStream::SlotStrongStream(ioStream, ev, &mParser_Stream); - - if ( ev->Good() ) - { - mParser_Tag = morkParser_kTag; - mNode_Derived = morkDerived_kParser; - } - } - else - ev->NilPointerError(); -} - -/*public non-poly*/ void -morkParser::CloseParser(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - if ( !this->IsShutNode() ) - { - mParser_ScopeCoil.CloseCoil(ev); - mParser_ValueCoil.CloseCoil(ev); - mParser_ColumnCoil.CloseCoil(ev); - mParser_StringCoil.CloseCoil(ev); - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mParser_Heap); - morkStream::SlotStrongStream((morkStream*) 0, ev, &mParser_Stream); - this->MarkShut(); - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*protected non-poly*/ void -morkParser::NonGoodParserError(morkEnv* ev) // when GoodParserTag() is false -{ - ev->NewError("non-morkNode"); -} - -/*protected non-poly*/ void -morkParser::NonUsableParserError(morkEnv* ev) // -{ - if ( this->IsNode() ) - { - if ( this->IsOpenNode() ) - { - if ( this->GoodParserTag() ) - { - // okay - } - else - this->NonGoodParserError(ev); - } - else - this->NonOpenNodeError(ev); - } - else - this->NonNodeError(ev); -} - - -/*protected non-poly*/ void -morkParser::StartParse(morkEnv* ev) -{ - MORK_USED_1(ev); - mParser_InCell = morkBool_kFalse; - mParser_InMeta = morkBool_kFalse; - mParser_InDict = morkBool_kFalse; - mParser_InPortRow = morkBool_kFalse; - - mParser_RowMid.ClearMid(); - mParser_TableMid.ClearMid(); - mParser_CellMid.ClearMid(); - - mParser_GroupId = 0; - mParser_InPort = morkBool_kTrue; - - mParser_GroupSpan.ClearSpan(); - mParser_DictSpan.ClearSpan(); - mParser_AliasSpan.ClearSpan(); - mParser_MetaSpan.ClearSpan(); - mParser_TableSpan.ClearSpan(); - mParser_RowSpan.ClearSpan(); - mParser_CellSpan.ClearSpan(); - mParser_ColumnSpan.ClearSpan(); - mParser_SlotSpan.ClearSpan(); - - mParser_PortSpan.ClearSpan(); -} - -/*protected non-poly*/ void -morkParser::StopParse(morkEnv* ev) -{ - if ( mParser_InCell ) - { - mParser_InCell = morkBool_kFalse; - mParser_CellSpan.SetEndWithEnd(mParser_PortSpan); - this->OnCellEnd(ev, mParser_CellSpan); - } - if ( mParser_InMeta ) - { - mParser_InMeta = morkBool_kFalse; - mParser_MetaSpan.SetEndWithEnd(mParser_PortSpan); - this->OnMetaEnd(ev, mParser_MetaSpan); - } - if ( mParser_InDict ) - { - mParser_InDict = morkBool_kFalse; - mParser_DictSpan.SetEndWithEnd(mParser_PortSpan); - this->OnDictEnd(ev, mParser_DictSpan); - } - if ( mParser_InPortRow ) - { - mParser_InPortRow = morkBool_kFalse; - mParser_RowSpan.SetEndWithEnd(mParser_PortSpan); - this->OnPortRowEnd(ev, mParser_RowSpan); - } - if ( mParser_InRow ) - { - mParser_InRow = morkBool_kFalse; - mParser_RowMid.ClearMid(); - mParser_RowSpan.SetEndWithEnd(mParser_PortSpan); - this->OnRowEnd(ev, mParser_RowSpan); - } - if ( mParser_InTable ) - { - mParser_InTable = morkBool_kFalse; - mParser_TableMid.ClearMid(); - mParser_TableSpan.SetEndWithEnd(mParser_PortSpan); - this->OnTableEnd(ev, mParser_TableSpan); - } - if ( mParser_GroupId ) - { - mParser_GroupId = 0; - mParser_GroupSpan.SetEndWithEnd(mParser_PortSpan); - this->OnGroupAbortEnd(ev, mParser_GroupSpan); - } - if ( mParser_InPort ) - { - mParser_InPort = morkBool_kFalse; - this->OnPortEnd(ev, mParser_PortSpan); - } -} - -int morkParser::eat_comment(morkEnv* ev) // last char was '/' -{ - morkStream* s = mParser_Stream; - // Note morkStream::Getc() returns EOF when an error occurs, so - // we don't need to check for both c != EOF and ev->Good() below. - - register int c = s->Getc(ev); - if ( c == '/' ) // C++ style comment? - { - while ( (c = s->Getc(ev)) != EOF && c != 0xA && c != 0xD ) - /* empty */; - - if ( c == 0xA || c == 0xD ) - c = this->eat_line_break(ev, c); - } - else if ( c == '*' ) /* C style comment? */ - { - int depth = 1; // count depth of comments until depth reaches zero - - while ( depth > 0 && c != EOF ) // still looking for comment end(s)? - { - while ( (c = s->Getc(ev)) != EOF && c != '/' && c != '*' ) - { - if ( c == 0xA || c == 0xD ) // need to count a line break? - { - c = this->eat_line_break(ev, c); - if ( c == '/' || c == '*' ) - break; // end while loop - } - } - - if ( c == '*' ) // maybe end of a comment, if next char is '/'? - { - if ( (c = s->Getc(ev)) == '/' ) // end of comment? - { - --depth; // depth of comments has decreased by one - if ( !depth ) // comments all done? - c = s->Getc(ev); // return the byte after end of comment - } - else if ( c != EOF ) // need to put the char back? - s->Ungetc(c); // especially need to put back '*', 0xA, or 0xD - } - else if ( c == '/' ) // maybe nested comemnt, if next char is '*'? - { - if ( (c = s->Getc(ev)) == '*' ) // nested comment? - ++depth; // depth of comments has increased by one - else if ( c != EOF ) // need to put the char back? - s->Ungetc(c); // especially need to put back '/', 0xA, or 0xD - } - - if ( ev->Bad() ) - c = EOF; - } - if ( c == EOF && depth > 0 ) - ev->NewWarning("EOF before end of comment"); - } - else - ev->NewWarning("expected / or *"); - - return c; -} - -int morkParser::eat_line_break(morkEnv* ev, int inLast) -{ - morkStream* s = mParser_Stream; - register int c = s->Getc(ev); // get next char after 0xA or 0xD - this->CountLineBreak(); - if ( c == 0xA || c == 0xD ) // another line break character? - { - if ( c != inLast ) // not the same as the last one? - c = s->Getc(ev); // get next char after two-byte linebreak - } - return c; -} - -int morkParser::eat_line_continue(morkEnv* ev) // last char was '\' -{ - morkStream* s = mParser_Stream; - register int c = s->Getc(ev); - if ( c == 0xA || c == 0xD ) // linebreak follows \ as expected? - { - c = this->eat_line_break(ev, c); - } - else - ev->NewWarning("expected linebreak"); - - return c; -} - -int morkParser::NextChar(morkEnv* ev) // next non-white content -{ - morkStream* s = mParser_Stream; - register int c = s->Getc(ev); - while ( c > 0 && ev->Good() ) - { - if ( c == '/' ) - c = this->eat_comment(ev); - else if ( c == 0xA || c == 0xD ) - c = this->eat_line_break(ev, c); - else if ( c == '\\' ) - c = this->eat_line_continue(ev); - else if ( morkCh_IsWhite(c) ) - c = s->Getc(ev); - else - break; // end while loop when return c is acceptable - } - if ( ev->Bad() ) - { - mParser_State = morkParser_kBrokenState; - mParser_DoMore = morkBool_kFalse; - mParser_IsDone = morkBool_kTrue; - mParser_IsBroken = morkBool_kTrue; - c = EOF; - } - else if ( c == EOF ) - { - mParser_DoMore = morkBool_kFalse; - mParser_IsDone = morkBool_kTrue; - } - return c; -} - -void -morkParser::OnCellState(morkEnv* ev) -{ - ev->StubMethodOnlyError(); -} - -void -morkParser::OnMetaState(morkEnv* ev) -{ - ev->StubMethodOnlyError(); -} - -void -morkParser::OnRowState(morkEnv* ev) -{ - ev->StubMethodOnlyError(); -} - -void -morkParser::OnTableState(morkEnv* ev) -{ - ev->StubMethodOnlyError(); -} - -void -morkParser::OnDictState(morkEnv* ev) -{ - ev->StubMethodOnlyError(); -} - -morkBuf* morkParser::ReadName(morkEnv* ev, register int c) -{ - morkBuf* outBuf = 0; - - if ( !morkCh_IsName(c) ) - ev->NewError("not a name char"); - - morkCoil* coil = &mParser_ColumnCoil; - coil->ClearBufFill(); - - morkSpool* spool = &mParser_ColumnSpool; - spool->Seek(ev, /*pos*/ 0); - - if ( ev->Good() ) - { - spool->Putc(ev, c); - - morkStream* s = mParser_Stream; - while ( (c = s->Getc(ev)) != EOF && morkCh_IsMore(c) && ev->Good() ) - spool->Putc(ev, c); - - if ( ev->Good() ) - { - if ( c != EOF ) - { - s->Ungetc(c); - spool->FlushSink(ev); // update coil->mBuf_Fill - } - else - this->UnexpectedEofError(ev); - - if ( ev->Good() ) - outBuf = coil; - } - } - return outBuf; -} - -mork_bool -morkParser::ReadMid(morkEnv* ev, morkMid* outMid) -{ - outMid->ClearMid(); - - morkStream* s = mParser_Stream; - int next; - outMid->mMid_Oid.mOid_Id = this->ReadHex(ev, &next); - register int c = next; - if ( c == ':' ) - { - if ( (c = s->Getc(ev)) != EOF && ev->Good() ) - { - if ( c == '^' ) - { - outMid->mMid_Oid.mOid_Scope = this->ReadHex(ev, &next); - if ( ev->Good() ) - s->Ungetc(next); - } - else if ( morkCh_IsName(c) ) - { - outMid->mMid_Buf = this->ReadName(ev, c); - } - else - ev->NewError("expected name or hex after ':' following ID"); - } - - if ( c == EOF && ev->Good() ) - this->UnexpectedEofError(ev); - } - else - s->Ungetc(c); - - return ev->Good(); -} - -void -morkParser::ReadCell(morkEnv* ev) -{ - mParser_CellMid.ClearMid(); - // this->StartSpanOnLastByte(ev, &mParser_CellSpan); - morkMid* cellMid = 0; // if mid syntax is used for column - morkBuf* cellBuf = 0; // if naked string is used for column - - morkStream* s = mParser_Stream; - register int c; - if ( (c = s->Getc(ev)) != EOF && ev->Good() ) - { - // this->StartSpanOnLastByte(ev, &mParser_ColumnSpan); - if ( c == '^' ) - { - cellMid = &mParser_CellMid; - this->ReadMid(ev, cellMid); - // if ( !mParser_CellMid.mMid_Oid.mOid_Scope ) - // mParser_CellMid.mMid_Oid.mOid_Scope = (mork_scope) 'c'; - } - else - { - if (mParser_InMeta && c == morkStore_kFormColumn) - { - ReadCellForm(ev, c); - return; - } - else - cellBuf = this->ReadName(ev, c); - } - if ( ev->Good() ) - { - // this->EndSpanOnThisByte(ev, &mParser_ColumnSpan); - - mParser_InCell = morkBool_kTrue; - this->OnNewCell(ev, *mParser_CellSpan.AsPlace(), - cellMid, cellBuf); // , mParser_CellChange - - mParser_CellChange = morkChange_kNil; - if ( (c = this->NextChar(ev)) != EOF && ev->Good() ) - { - // this->StartSpanOnLastByte(ev, &mParser_SlotSpan); - if ( c == '=' ) - { - morkBuf* buf = this->ReadValue(ev); - if ( buf ) - { - // this->EndSpanOnThisByte(ev, &mParser_SlotSpan); - this->OnValue(ev, mParser_SlotSpan, *buf); - } - } - else if ( c == '^' ) - { - if ( this->ReadMid(ev, &mParser_Mid) ) - { - // this->EndSpanOnThisByte(ev, &mParser_SlotSpan); - if ( (c = this->NextChar(ev)) != EOF && ev->Good() ) - { - if ( c != ')' ) - ev->NewError("expected ')' after cell ^ID value"); - } - else if ( c == EOF ) - this->UnexpectedEofError(ev); - - if ( ev->Good() ) - this->OnValueMid(ev, mParser_SlotSpan, mParser_Mid); - } - } - else if ( c == 'r' || c == 't' || c == '"' || c == '\'' ) - { - ev->NewError("cell syntax not yet supported"); - } - else - { - ev->NewError("unknown cell syntax"); - } - } - - // this->EndSpanOnThisByte(ev, &mParser_CellSpan); - mParser_InCell = morkBool_kFalse; - this->OnCellEnd(ev, mParser_CellSpan); - } - } - mParser_CellChange = morkChange_kNil; - - if ( c == EOF && ev->Good() ) - this->UnexpectedEofError(ev); -} - -void morkParser::ReadRowPos(morkEnv* ev) -{ - int c; // next character - mork_pos rowPos = this->ReadHex(ev, &c); - - if ( ev->Good() && c != EOF ) // should put back byte after hex? - mParser_Stream->Ungetc(c); - - this->OnRowPos(ev, rowPos); -} - -void morkParser::ReadRow(morkEnv* ev, int c) -// zm:Row ::= zm:S? '[' zm:S? zm:Id zm:RowItem* zm:S? ']' -// zm:RowItem ::= zm:MetaRow | zm:Cell -// zm:MetaRow ::= zm:S? '[' zm:S? zm:Cell* zm:S? ']' /* meta attributes */ -// zm:Cell ::= zm:S? '(' zm:Column zm:S? zm:Slot? ')' -{ - if ( ev->Good() ) - { - // this->StartSpanOnLastByte(ev, &mParser_RowSpan); - if ( mParser_Change ) - mParser_RowChange = mParser_Change; - - mork_bool cutAllRowCols = morkBool_kFalse; - - if ( c == '[' ) - { - if ( ( c = this->NextChar(ev) ) == '-' ) - cutAllRowCols = morkBool_kTrue; - else if ( ev->Good() && c != EOF ) - mParser_Stream->Ungetc(c); - - if ( this->ReadMid(ev, &mParser_RowMid) ) - { - mParser_InRow = morkBool_kTrue; - this->OnNewRow(ev, *mParser_RowSpan.AsPlace(), - mParser_RowMid, cutAllRowCols); - - mParser_Change = mParser_RowChange = morkChange_kNil; - - while ( (c = this->NextChar(ev)) != EOF && ev->Good() && c != ']' ) - { - switch ( c ) - { - case '(': // cell - this->ReadCell(ev); - break; - - case '[': // meta - this->ReadMeta(ev, ']'); - break; - - // case '+': // plus - // mParser_CellChange = morkChange_kAdd; - // break; - - case '-': // minus - // mParser_CellChange = morkChange_kCut; - this->OnMinusCell(ev); - break; - - // case '!': // bang - // mParser_CellChange = morkChange_kSet; - // break; - - default: - ev->NewWarning("unexpected byte in row"); - break; - } // switch - } // while - - if ( ev->Good() ) - { - if ( (c = this->NextChar(ev)) == '!' ) - this->ReadRowPos(ev); - else if ( c != EOF && ev->Good() ) - mParser_Stream->Ungetc(c); - } - - // this->EndSpanOnThisByte(ev, &mParser_RowSpan); - mParser_InRow = morkBool_kFalse; - this->OnRowEnd(ev, mParser_RowSpan); - - } // if ReadMid - } // if '[' - - else // c != '[' - { - morkStream* s = mParser_Stream; - s->Ungetc(c); - if ( this->ReadMid(ev, &mParser_RowMid) ) - { - mParser_InRow = morkBool_kTrue; - this->OnNewRow(ev, *mParser_RowSpan.AsPlace(), - mParser_RowMid, cutAllRowCols); - - mParser_Change = mParser_RowChange = morkChange_kNil; - - if ( ev->Good() ) - { - if ( (c = this->NextChar(ev)) == '!' ) - this->ReadRowPos(ev); - else if ( c != EOF && ev->Good() ) - s->Ungetc(c); - } - - // this->EndSpanOnThisByte(ev, &mParser_RowSpan); - mParser_InRow = morkBool_kFalse; - this->OnRowEnd(ev, mParser_RowSpan); - } - } - } - - if ( ev->Bad() ) - mParser_State = morkParser_kBrokenState; - else if ( c == EOF ) - mParser_State = morkParser_kDoneState; -} - -void morkParser::ReadTable(morkEnv* ev) -// zm:Table ::= zm:S? '{' zm:S? zm:Id zm:TableItem* zm:S? '}' -// zm:TableItem ::= zm:MetaTable | zm:RowRef | zm:Row -// zm:MetaTable ::= zm:S? '{' zm:S? zm:Cell* zm:S? '}' /* meta attributes */ -{ - // this->StartSpanOnLastByte(ev, &mParser_TableSpan); - - if ( mParser_Change ) - mParser_TableChange = mParser_Change; - - mork_bool cutAllTableRows = morkBool_kFalse; - - int c = this->NextChar(ev); - if ( c == '-' ) - cutAllTableRows = morkBool_kTrue; - else if ( ev->Good() && c != EOF ) - mParser_Stream->Ungetc(c); - - if ( ev->Good() && this->ReadMid(ev, &mParser_TableMid) ) - { - mParser_InTable = morkBool_kTrue; - this->OnNewTable(ev, *mParser_TableSpan.AsPlace(), - mParser_TableMid, cutAllTableRows); - - mParser_Change = mParser_TableChange = morkChange_kNil; - - while ( (c = this->NextChar(ev)) != EOF && ev->Good() && c != '}' ) - { - if ( morkCh_IsHex(c) ) - { - this->ReadRow(ev, c); - } - else - { - switch ( c ) - { - case '[': // row - this->ReadRow(ev, '['); - break; - - case '{': // meta - this->ReadMeta(ev, '}'); - break; - - // case '+': // plus - // mParser_RowChange = morkChange_kAdd; - // break; - - case '-': // minus - // mParser_RowChange = morkChange_kCut; - this->OnMinusRow(ev); - break; - - // case '!': // bang - // mParser_RowChange = morkChange_kSet; - // break; - - default: - ev->NewWarning("unexpected byte in table"); - break; - } - } - } - - // this->EndSpanOnThisByte(ev, &mParser_TableSpan); - mParser_InTable = morkBool_kFalse; - this->OnTableEnd(ev, mParser_TableSpan); - - if ( ev->Bad() ) - mParser_State = morkParser_kBrokenState; - else if ( c == EOF ) - mParser_State = morkParser_kDoneState; - } -} - -mork_id morkParser::ReadHex(morkEnv* ev, int* outNextChar) -// zm:Hex ::= [0-9a-fA-F] /* a single hex digit */ -// zm:Hex+ ::= zm:Hex | zm:Hex zm:Hex+ -{ - mork_id hex = 0; - - morkStream* s = mParser_Stream; - register int c = this->NextChar(ev); - - if ( ev->Good() ) - { - if ( c != EOF ) - { - if ( morkCh_IsHex(c) ) - { - do - { - if ( morkCh_IsDigit(c) ) // '0' through '9'? - c -= '0'; - else if ( morkCh_IsUpper(c) ) // 'A' through 'F'? - c -= ('A' - 10) ; // c = (c - 'A') + 10; - else // 'a' through 'f'? - c -= ('a' - 10) ; // c = (c - 'a') + 10; - - hex = (hex << 4) + c; - } - while ( (c = s->Getc(ev)) != EOF && ev->Good() && morkCh_IsHex(c) ); - } - else - this->ExpectedHexDigitError(ev, c); - } - } - if ( c == EOF ) - this->EofInsteadOfHexError(ev); - - *outNextChar = c; - return hex; -} - -/*static*/ void -morkParser::EofInsteadOfHexError(morkEnv* ev) -{ - ev->NewWarning("eof instead of hex"); -} - -/*static*/ void -morkParser::ExpectedHexDigitError(morkEnv* ev, int c) -{ - MORK_USED_1(c); - ev->NewWarning("expected hex digit"); -} - -/*static*/ void -morkParser::ExpectedEqualError(morkEnv* ev) -{ - ev->NewWarning("expected '='"); -} - -/*static*/ void -morkParser::UnexpectedEofError(morkEnv* ev) -{ - ev->NewWarning("unexpected eof"); -} - - -morkBuf* morkParser::ReadValue(morkEnv* ev) -{ - morkBuf* outBuf = 0; - - morkCoil* coil = &mParser_ValueCoil; - coil->ClearBufFill(); - - morkSpool* spool = &mParser_ValueSpool; - spool->Seek(ev, /*pos*/ 0); - - if ( ev->Good() ) - { - morkStream* s = mParser_Stream; - register int c; - while ( (c = s->Getc(ev)) != EOF && c != ')' && ev->Good() ) - { - if ( c == '\\' ) // next char is escaped by '\'? - { - if ( (c = s->Getc(ev)) == 0xA || c == 0xD ) // linebreak after \? - { - c = this->eat_line_break(ev, c); - if ( c == ')' || c == '\\' || c == '$' ) - { - s->Ungetc(c); // just let while loop test read this again - continue; // goto next iteration of while loop - } - } - if ( c == EOF || ev->Bad() ) - break; // end while loop - } - else if ( c == '$' ) // "$" escapes next two hex digits? - { - if ( (c = s->Getc(ev)) != EOF && ev->Good() ) - { - mork_ch first = (mork_ch) c; // first hex digit - if ( (c = s->Getc(ev)) != EOF && ev->Good() ) - { - mork_ch second = (mork_ch) c; // second hex digit - c = ev->HexToByte(first, second); - } - else - break; // end while loop - } - else - break; // end while loop - } - spool->Putc(ev, c); - } - - if ( ev->Good() ) - { - if ( c != EOF ) - spool->FlushSink(ev); // update coil->mBuf_Fill - else - this->UnexpectedEofError(ev); - - if ( ev->Good() ) - outBuf = coil; - } - } - return outBuf; -} - -void morkParser::ReadDictForm(morkEnv *ev) -{ - int nextChar; - nextChar = this->NextChar(ev); - if (nextChar == '(') - { - nextChar = this->NextChar(ev); - if (nextChar == morkStore_kFormColumn) - { - int dictForm; - - nextChar = this->NextChar(ev); - if (nextChar == '=') - { - dictForm = this->NextChar(ev); - nextChar = this->NextChar(ev); - } - else if (nextChar == '^') - { - dictForm = this->ReadHex(ev, &nextChar); - } - else - { - ev->NewWarning("unexpected byte in dict form"); - return; - } - mParser_ValueCoil.mText_Form = dictForm; - if (nextChar == ')') - { - nextChar = this->NextChar(ev); - if (nextChar == '>') - return; - } - } - } - ev->NewWarning("unexpected byte in dict form"); -} - -void morkParser::ReadCellForm(morkEnv *ev, int c) -{ - MORK_ASSERT (c == morkStore_kFormColumn); - int nextChar; - nextChar = this->NextChar(ev); - int cellForm; - - if (nextChar == '=') - { - cellForm = this->NextChar(ev); - nextChar = this->NextChar(ev); - } - else if (nextChar == '^') - { - cellForm = this->ReadHex(ev, &nextChar); - } - else - { - ev->NewWarning("unexpected byte in cell form"); - return; - } - // ### not sure about this. Which form should we set? - // mBuilder_CellForm = mBuilder_RowForm = cellForm; - if (nextChar == ')') - { - OnCellForm(ev, cellForm); - return; - } - ev->NewWarning("unexpected byte in cell form"); -} - -void morkParser::ReadAlias(morkEnv* ev) -// zm:Alias ::= zm:S? '(' ('#')? zm:Hex+ zm:S? zm:Value ')' -// zm:Value ::= '=' ([^)$\] | '\' zm:NonCRLF | zm:Continue | zm:Dollar)* -{ - // this->StartSpanOnLastByte(ev, &mParser_AliasSpan); - - int nextChar; - mork_id hex = this->ReadHex(ev, &nextChar); - register int c = nextChar; - - mParser_Mid.ClearMid(); - mParser_Mid.mMid_Oid.mOid_Id = hex; - - if ( morkCh_IsWhite(c) && ev->Good() ) - c = this->NextChar(ev); - - if ( ev->Good() ) - { - if ( c == '<') - { - ReadDictForm(ev); - if (ev->Good()) - c = this->NextChar(ev); - } - if ( c == '=' ) - { - mParser_Mid.mMid_Buf = this->ReadValue(ev); - if ( mParser_Mid.mMid_Buf ) - { - // this->EndSpanOnThisByte(ev, &mParser_AliasSpan); - this->OnAlias(ev, mParser_AliasSpan, mParser_Mid); - // need to reset this somewhere. - mParser_ValueCoil.mText_Form = 0; - - } - } - else - this->ExpectedEqualError(ev); - } -} - -void morkParser::ReadMeta(morkEnv* ev, int inEndMeta) -// zm:MetaDict ::= zm:S? '<' zm:S? zm:Cell* zm:S? '>' /* meta attributes */ -// zm:MetaTable ::= zm:S? '{' zm:S? zm:Cell* zm:S? '}' /* meta attributes */ -// zm:MetaRow ::= zm:S? '[' zm:S? zm:Cell* zm:S? ']' /* meta attributes */ -{ - // this->StartSpanOnLastByte(ev, &mParser_MetaSpan); - mParser_InMeta = morkBool_kTrue; - this->OnNewMeta(ev, *mParser_MetaSpan.AsPlace()); - - mork_bool more = morkBool_kTrue; // until end meta - int c; - while ( more && (c = this->NextChar(ev)) != EOF && ev->Good() ) - { - switch ( c ) - { - case '(': // cell - this->ReadCell(ev); - break; - - case '>': // maybe end meta? - if ( inEndMeta == '>' ) - more = morkBool_kFalse; // stop reading meta - else - this->UnexpectedByteInMetaWarning(ev); - break; - - case '}': // maybe end meta? - if ( inEndMeta == '}' ) - more = morkBool_kFalse; // stop reading meta - else - this->UnexpectedByteInMetaWarning(ev); - break; - - case ']': // maybe end meta? - if ( inEndMeta == ']' ) - more = morkBool_kFalse; // stop reading meta - else - this->UnexpectedByteInMetaWarning(ev); - break; - - case '[': // maybe table meta row? - if ( mParser_InTable ) - this->ReadRow(ev, '['); - else - this->UnexpectedByteInMetaWarning(ev); - break; - - default: - if ( mParser_InTable && morkCh_IsHex(c) ) - this->ReadRow(ev, c); - else - this->UnexpectedByteInMetaWarning(ev); - break; - } - } - - // this->EndSpanOnThisByte(ev, &mParser_MetaSpan); - mParser_InMeta = morkBool_kFalse; - this->OnMetaEnd(ev, mParser_MetaSpan); -} - -/*static*/ void -morkParser::UnexpectedByteInMetaWarning(morkEnv* ev) -{ - ev->NewWarning("unexpected byte in meta"); -} - -/*static*/ void -morkParser::NonParserTypeError(morkEnv* ev) -{ - ev->NewError("non morkParser"); -} - -mork_bool morkParser::MatchPattern(morkEnv* ev, const char* inPattern) -{ - // if an error occurs, we want original inPattern in the debugger: - const char* pattern = inPattern; // mutable copy of pointer - morkStream* s = mParser_Stream; - register int c; - while ( *pattern && ev->Good() ) - { - char byte = *pattern++; - if ( (c = s->Getc(ev)) != byte ) - { - ev->NewError("byte not in expected pattern"); - } - } - return ev->Good(); -} - -mork_bool morkParser::FindGroupEnd(morkEnv* ev) -{ - mork_bool foundEnd = morkBool_kFalse; - - // char gidBuf[ 64 ]; // to hold hex pattern we want - // (void) ev->TokenAsHex(gidBuf, mParser_GroupId); - - morkStream* s = mParser_Stream; - register int c; - - while ( (c = s->Getc(ev)) != EOF && ev->Good() && !foundEnd ) - { - if ( c == '@' ) // maybe start of group ending? - { - // this->EndSpanOnThisByte(ev, &mParser_GroupSpan); - if ( (c = s->Getc(ev)) == '$' ) // '$' follows '@' ? - { - if ( (c = s->Getc(ev)) == '$' ) // '$' follows "@$" ? - { - if ( (c = s->Getc(ev)) == '}' ) - { - foundEnd = this->ReadEndGroupId(ev); - // this->EndSpanOnThisByte(ev, &mParser_GroupSpan); - - } - else - ev->NewError("expected '}' after @$$"); - } - } - if ( !foundEnd && c == '@' ) - s->Ungetc(c); - } - } - - return foundEnd && ev->Good(); -} - -void morkParser::ReadGroup(morkEnv* mev) -{ - nsIMdbEnv *ev = mev->AsMdbEnv(); - int next = 0; - mParser_GroupId = this->ReadHex(mev, &next); - if ( next == '{' ) - { - morkStream* s = mParser_Stream; - register int c; - if ( (c = s->Getc(mev)) == '@' ) - { - // we really need the following span inside morkBuilder::OnNewGroup(): - this->StartSpanOnThisByte(mev, &mParser_GroupSpan); - mork_pos startPos = mParser_GroupSpan.mSpan_Start.mPlace_Pos; - - // if ( !store->mStore_FirstCommitGroupPos ) - // store->mStore_FirstCommitGroupPos = startPos; - // else if ( !store->mStore_SecondCommitGroupPos ) - // store->mStore_SecondCommitGroupPos = startPos; - - if ( this->FindGroupEnd(mev) ) - { - mork_pos outPos; - s->Seek(ev, startPos, &outPos); - if ( mev->Good() ) - { - this->OnNewGroup(mev, mParser_GroupSpan.mSpan_Start, - mParser_GroupId); - - this->ReadContent(mev, /*inInsideGroup*/ morkBool_kTrue); - - this->OnGroupCommitEnd(mev, mParser_GroupSpan); - } - } - } - else - mev->NewError("expected '@' after @$${id{"); - } - else - mev->NewError("expected '{' after @$$id"); - -} - -mork_bool morkParser::ReadAt(morkEnv* ev, mork_bool inInsideGroup) -/* groups must be ignored until properly terminated */ -// zm:Group ::= zm:GroupStart zm:Content zm:GroupEnd /* transaction */ -// zm:GroupStart ::= zm:S? '@$${' zm:Hex+ '{@' /* xaction id has own space */ -// zm:GroupEnd ::= zm:GroupCommit | zm:GroupAbort -// zm:GroupCommit ::= zm:S? '@$$}' zm:Hex+ '}@' /* id matches start id */ -// zm:GroupAbort ::= zm:S? '@$$}~~}@' /* id matches start id */ -/* We must allow started transactions to be aborted in summary files. */ -/* Note '$$' will never occur unescaped in values we will see in Mork. */ -{ - if ( this->MatchPattern(ev, "$$") ) - { - morkStream* s = mParser_Stream; - register int c; - if ( ((c = s->Getc(ev)) == '{' || c == '}') && ev->Good() ) - { - if ( c == '{' ) // start of new group? - { - if ( !inInsideGroup ) - this->ReadGroup(ev); - else - ev->NewError("nested @$${ inside another group"); - } - else // c == '}' // end of old group? - { - if ( inInsideGroup ) - { - this->ReadEndGroupId(ev); - mParser_GroupId = 0; - } - else - ev->NewError("unmatched @$$} outside any group"); - } - } - else - ev->NewError("expected '{' or '}' after @$$"); - } - return ev->Good(); -} - -mork_bool morkParser::ReadEndGroupId(morkEnv* ev) -{ - mork_bool outSawGroupId = morkBool_kFalse; - morkStream* s = mParser_Stream; - register int c; - if ( (c = s->Getc(ev)) != EOF && ev->Good() ) - { - if ( c == '~' ) // transaction is aborted? - { - this->MatchPattern(ev, "~}@"); // finish rest of pattern - } - else // push back byte and read expected trailing hex id - { - s->Ungetc(c); - int next = 0; - mork_gid endGroupId = this->ReadHex(ev, &next); - if ( ev->Good() ) - { - if ( endGroupId == mParser_GroupId ) // matches start? - { - if ( next == '}' ) // '}' after @$$}id ? - { - if ( (c = s->Getc(ev)) == '@' ) // '@' after @$$}id} ? - { - // looks good, so return with no error - outSawGroupId = morkBool_kTrue; - mParser_InGroup = false; - } - else - ev->NewError("expected '@' after @$$}id}"); - } - else - ev->NewError("expected '}' after @$$}id"); - } - else - ev->NewError("end group id mismatch"); - } - } - } - return ( outSawGroupId && ev->Good() ); -} - - -void morkParser::ReadDict(morkEnv* ev) -// zm:Dict ::= zm:S? '<' zm:DictItem* zm:S? '>' -// zm:DictItem ::= zm:MetaDict | zm:Alias -// zm:MetaDict ::= zm:S? '<' zm:S? zm:Cell* zm:S? '>' /* meta attributes */ -// zm:Alias ::= zm:S? '(' ('#')? zm:Hex+ zm:S? zm:Value ')' -{ - mParser_Change = morkChange_kNil; - mParser_AtomChange = morkChange_kNil; - - // this->StartSpanOnLastByte(ev, &mParser_DictSpan); - mParser_InDict = morkBool_kTrue; - this->OnNewDict(ev, *mParser_DictSpan.AsPlace()); - - int c; - while ( (c = this->NextChar(ev)) != EOF && ev->Good() && c != '>' ) - { - switch ( c ) - { - case '(': // alias - this->ReadAlias(ev); - break; - - case '<': // meta - this->ReadMeta(ev, '>'); - break; - - default: - ev->NewWarning("unexpected byte in dict"); - break; - } - } - - // this->EndSpanOnThisByte(ev, &mParser_DictSpan); - mParser_InDict = morkBool_kFalse; - this->OnDictEnd(ev, mParser_DictSpan); - - if ( ev->Bad() ) - mParser_State = morkParser_kBrokenState; - else if ( c == EOF ) - mParser_State = morkParser_kDoneState; -} - -void morkParser::EndSpanOnThisByte(morkEnv* mev, morkSpan* ioSpan) -{ - mork_pos here; - nsIMdbEnv *ev = mev->AsMdbEnv(); - nsresult rv = mParser_Stream->Tell(ev, &here); - if (NS_SUCCEEDED(rv) && mev->Good() ) - { - this->SetHerePos(here); - ioSpan->SetEndWithEnd(mParser_PortSpan); - } -} - -void morkParser::EndSpanOnLastByte(morkEnv* mev, morkSpan* ioSpan) -{ - mork_pos here; - nsIMdbEnv *ev = mev->AsMdbEnv(); - nsresult rv= mParser_Stream->Tell(ev, &here); - if ( NS_SUCCEEDED(rv) && mev->Good() ) - { - if ( here > 0 ) - --here; - else - here = 0; - - this->SetHerePos(here); - ioSpan->SetEndWithEnd(mParser_PortSpan); - } -} - -void morkParser::StartSpanOnLastByte(morkEnv* mev, morkSpan* ioSpan) -{ - mork_pos here; - nsIMdbEnv *ev = mev->AsMdbEnv(); - nsresult rv = mParser_Stream->Tell(ev, &here); - if ( NS_SUCCEEDED(rv) && mev->Good() ) - { - if ( here > 0 ) - --here; - else - here = 0; - - this->SetHerePos(here); - ioSpan->SetStartWithEnd(mParser_PortSpan); - ioSpan->SetEndWithEnd(mParser_PortSpan); - } -} - -void morkParser::StartSpanOnThisByte(morkEnv* mev, morkSpan* ioSpan) -{ - mork_pos here; - nsIMdbEnv *ev = mev->AsMdbEnv(); - nsresult rv = mParser_Stream->Tell(ev, &here); - if ( NS_SUCCEEDED(rv) && mev->Good() ) - { - this->SetHerePos(here); - ioSpan->SetStartWithEnd(mParser_PortSpan); - ioSpan->SetEndWithEnd(mParser_PortSpan); - } -} - -mork_bool -morkParser::ReadContent(morkEnv* ev, mork_bool inInsideGroup) -{ - int c; - mork_bool keep_going = true; - while ( keep_going && (c = this->NextChar(ev)) != EOF && ev->Good()) - { - switch ( c ) - { - case '[': // row - this->ReadRow(ev, '['); - keep_going = false; - break; - - case '{': // table - this->ReadTable(ev); - keep_going = false; - break; - - case '<': // dict - this->ReadDict(ev); - keep_going = false; - break; - - case '@': // group - return this->ReadAt(ev, inInsideGroup); - // break; - - // case '+': // plus - // mParser_Change = morkChange_kAdd; - // break; - - // case '-': // minus - // mParser_Change = morkChange_kCut; - // break; - - // case '!': // bang - // mParser_Change = morkChange_kSet; - // break; - - default: - ev->NewWarning("unexpected byte in ReadContent()"); - break; - } - } - if ( ev->Bad() ) - mParser_State = morkParser_kBrokenState; - else if ( c == EOF ) - mParser_State = morkParser_kDoneState; - - return ( ev->Good() && c != EOF ); -} - -void -morkParser::OnPortState(morkEnv* ev) -{ - mork_bool firstTime = !mParser_InPort; - mParser_InPort = morkBool_kTrue; - if (firstTime) - this->OnNewPort(ev, *mParser_PortSpan.AsPlace()); - - mork_bool done = !this->ReadContent(ev, mParser_InGroup/*inInsideGroup*/); - - if (done) - { - mParser_InPort = morkBool_kFalse; - this->OnPortEnd(ev, mParser_PortSpan); - } - - if ( ev->Bad() ) - mParser_State = morkParser_kBrokenState; -} - -void -morkParser::OnStartState(morkEnv* mev) -{ - morkStream* s = mParser_Stream; - nsIMdbEnv *ev = mev->AsMdbEnv(); - if ( s && s->IsNode() && s->IsOpenNode() ) - { - mork_pos outPos; - nsresult rv = s->Seek(ev, 0, &outPos); - if (NS_SUCCEEDED(rv) && mev->Good() ) - { - this->StartParse(mev); - mParser_State = morkParser_kPortState; - } - } - else - mev->NilPointerError(); - - if ( mev->Bad() ) - mParser_State = morkParser_kBrokenState; -} - -/*protected non-poly*/ void -morkParser::ParseChunk(morkEnv* ev) -{ - mParser_Change = morkChange_kNil; - mParser_DoMore = morkBool_kTrue; - - switch ( mParser_State ) - { - case morkParser_kCellState: // 0 - this->OnCellState(ev); break; - - case morkParser_kMetaState: // 1 - this->OnMetaState(ev); break; - - case morkParser_kRowState: // 2 - this->OnRowState(ev); break; - - case morkParser_kTableState: // 3 - this->OnTableState(ev); break; - - case morkParser_kDictState: // 4 - this->OnDictState(ev); break; - - case morkParser_kPortState: // 5 - this->OnPortState(ev); break; - - case morkParser_kStartState: // 6 - this->OnStartState(ev); break; - - case morkParser_kDoneState: // 7 - mParser_DoMore = morkBool_kFalse; - mParser_IsDone = morkBool_kTrue; - this->StopParse(ev); - break; - case morkParser_kBrokenState: // 8 - mParser_DoMore = morkBool_kFalse; - mParser_IsBroken = morkBool_kTrue; - this->StopParse(ev); - break; - default: // ? - MORK_ASSERT(morkBool_kFalse); - mParser_State = morkParser_kBrokenState; - break; - } -} - -/*public non-poly*/ mdb_count -morkParser::ParseMore( // return count of bytes consumed now - morkEnv* ev, // context - mork_pos* outPos, // current byte pos in the stream afterwards - mork_bool* outDone, // is parsing finished? - mork_bool* outBroken // is parsing irreparably dead and broken? - ) -{ - mdb_count outCount = 0; - if ( this->IsNode() && this->GoodParserTag() && this->IsOpenNode() ) - { - mork_pos startPos = this->HerePos(); - - if ( !mParser_IsDone && !mParser_IsBroken ) - this->ParseChunk(ev); - - // HerePos is only updated for groups. I'd like it to be more accurate. - - mork_pos here; - mParser_Stream->Tell(ev, &here); - - if ( outDone ) - *outDone = mParser_IsDone; - if ( outBroken ) - *outBroken = mParser_IsBroken; - if ( outPos ) - *outPos = here; - - if ( here > startPos ) - outCount = (mdb_count) (here - startPos); - } - else - { - this->NonUsableParserError(ev); - if ( outDone ) - *outDone = morkBool_kTrue; - if ( outBroken ) - *outBroken = morkBool_kTrue; - if ( outPos ) - *outPos = 0; - } - return outCount; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkParser.h b/db/mork/src/morkParser.h deleted file mode 100644 index 02951d0692cc..000000000000 --- a/db/mork/src/morkParser.h +++ /dev/null @@ -1,565 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKPARSER_ -#define _MORKPARSER_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKSINK_ -#include "morkSink.h" -#endif - -#ifndef _MORKYARN_ -#include "morkYarn.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*============================================================================= - * morkPlace: stream byte position and stream line count - */ - -class morkPlace { -public: - mork_pos mPlace_Pos; // byte offset in an input stream - mork_line mPlace_Line; // line count in an input stream - - void ClearPlace() - { - mPlace_Pos = 0; mPlace_Line = 0; - } - - void SetPlace(mork_pos inPos, mork_line inLine) - { - mPlace_Pos = inPos; mPlace_Line = inLine; - } - - morkPlace() { mPlace_Pos = 0; mPlace_Line = 0; } - - morkPlace(mork_pos inPos, mork_line inLine) - { mPlace_Pos = inPos; mPlace_Line = inLine; } - - morkPlace(const morkPlace& inPlace) - : mPlace_Pos(inPlace.mPlace_Pos), mPlace_Line(inPlace.mPlace_Line) { } -}; - -/*============================================================================= - * morkGlitch: stream place and error comment describing a parsing error - */ - -class morkGlitch { -public: - morkPlace mGlitch_Place; // place in stream where problem happened - const char* mGlitch_Comment; // null-terminated ASCII C string - - morkGlitch() { mGlitch_Comment = 0; } - - morkGlitch(const morkPlace& inPlace, const char* inComment) - : mGlitch_Place(inPlace), mGlitch_Comment(inComment) { } -}; - -/*============================================================================= - * morkMid: all possible ways needed to express an alias ID in Mork syntax - */ - -/*| morkMid: an abstraction of all the variations we might need to support -**| in order to present an ID through the parser interface most cheaply and -**| with minimum transformation away from the original text format. -**| -**|| An ID can have one of four forms: -**| 1) idHex (mMid_Oid.mOid_Id <- idHex) -**| 2) idHex:^scopeHex (mMid_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex) -**| 3) idHex:scopeName (mMid_Oid.mOid_Id <- idHex, mMid_Buf <- scopeName) -**| 4) columnName (mMid_Buf <- columnName, for columns in cells only) -**| -**|| Typically, mMid_Oid.mOid_Id will hold a nonzero integer value for -**| an ID, but we might have an optional scope specified by either an integer -**| in hex format, or a string name. (Note that while the first ID can be -**| scoped variably, any integer ID for a scope is assumed always located in -**| the same scope, so the second ID need not be disambiguated.) -**| -**|| The only time mMid_Oid.mOid_Id is ever zero is when mMid_Buf alone -**| is nonzero, to indicate an explicit string instead of an alias appeared. -**| This case happens to make the representation of columns in cells somewhat -**| easier to represent, since columns can just appear as a string name; and -**| this unifies those interfaces with row and table APIs expecting IDs. -**| -**|| So when the parser passes an instance of morkMid to a subclass, the -**| mMid_Oid.mOid_Id slot should usually be nonzero. And the other two -**| slots, mMid_Oid.mOid_Scope and mMid_Buf, might both be zero, or at -**| most one of them will be nonzero to indicate an explicit scope; the -**| parser is responsible for ensuring at most one of these is nonzero. -|*/ -class morkMid { -public: - mdbOid mMid_Oid; // mOid_Scope is zero when not specified - const morkBuf* mMid_Buf; // points to some specific buf subclass - - morkMid() - { mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne; - mMid_Buf = 0; } - - void InitMidWithCoil(morkCoil* ioCoil) - { mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne; - mMid_Buf = ioCoil; } - - void ClearMid() - { mMid_Oid.mOid_Scope = 0; mMid_Oid.mOid_Id = morkId_kMinusOne; - mMid_Buf = 0; } - - morkMid(const morkMid& other) - : mMid_Oid(other.mMid_Oid), mMid_Buf(other.mMid_Buf) { } - - mork_bool HasNoId() const // ID is unspecified? - { return ( mMid_Oid.mOid_Id == morkId_kMinusOne ); } - - mork_bool HasSomeId() const // ID is specified? - { return ( mMid_Oid.mOid_Id != morkId_kMinusOne ); } -}; - -/*============================================================================= - * morkSpan: start and end stream byte position and stream line count - */ - -class morkSpan { -public: - morkPlace mSpan_Start; - morkPlace mSpan_End; - -public: // methods - -public: // inlines - morkSpan() { } // use inline empty constructor for each place - - morkPlace* AsPlace() { return &mSpan_Start; } - const morkPlace* AsConstPlace() const { return &mSpan_Start; } - - void SetSpan(mork_pos inFromPos, mork_line inFromLine, - mork_pos inToPos, mork_line inToLine) - { - mSpan_Start.SetPlace(inFromPos, inFromLine); - mSpan_End.SetPlace(inToPos,inToLine); - } - - // setting end, useful to terminate a span using current port span end: - void SetEndWithEnd(const morkSpan& inSpan) // end <- span.end - { mSpan_End = inSpan.mSpan_End; } - - // setting start, useful to initiate a span using current port span end: - void SetStartWithEnd(const morkSpan& inSpan) // start <- span.end - { mSpan_Start = inSpan.mSpan_End; } - - void ClearSpan() - { - mSpan_Start.mPlace_Pos = 0; mSpan_Start.mPlace_Line = 0; - mSpan_End.mPlace_Pos = 0; mSpan_End.mPlace_Line = 0; - } - - morkSpan(mork_pos inFromPos, mork_line inFromLine, - mork_pos inToPos, mork_line inToLine) - : mSpan_Start(inFromPos, inFromLine), mSpan_End(inToPos, inToLine) - { /* empty implementation */ } -}; - -/*============================================================================= - * morkParser: for parsing Mork text syntax - */ - -#define morkParser_kMinGranularity 512 /* parse at least half 0.5K at once */ -#define morkParser_kMaxGranularity (64 * 1024) /* parse at most 64 K at once */ - -#define morkDerived_kParser /*i*/ 0x5073 /* ascii 'Ps' */ -#define morkParser_kTag /*i*/ 0x70417253 /* ascii 'pArS' */ - -// These are states for the simple parsing virtual machine. Needless to say, -// these must be distinct, and preferrably in a contiguous integer range. -// Don't change these constants without looking at switch statements in code. -#define morkParser_kCellState 0 /* cell is tightest scope */ -#define morkParser_kMetaState 1 /* meta is tightest scope */ -#define morkParser_kRowState 2 /* row is tightest scope */ -#define morkParser_kTableState 3 /* table is tightest scope */ -#define morkParser_kDictState 4 /* dict is tightest scope */ -#define morkParser_kPortState 5 /* port is tightest scope */ - -#define morkParser_kStartState 6 /* parsing has not yet begun */ -#define morkParser_kDoneState 7 /* parsing is complete */ -#define morkParser_kBrokenState 8 /* parsing is to broken to work */ - -class morkParser /*d*/ : public morkNode { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected morkParser members - - nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation - morkStream* mParser_Stream; // refcounted input stream - - mork_u4 mParser_Tag; // must equal morkParser_kTag - mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment - - mork_u4 mParser_State; // state where parser should resume - - // after finding ends of group transactions, we can re-seek the start: - mork_pos mParser_GroupContentStartPos; // start of this group - - morkMid mParser_TableMid; // table mid if inside a table - morkMid mParser_RowMid; // row mid if inside a row - morkMid mParser_CellMid; // cell mid if inside a row - mork_gid mParser_GroupId; // group ID if inside a group - - mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd? - mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd? - mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd? - mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd? - - mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd? - mork_bool mParser_InRow; // called OnNewRow but not OnNewRowEnd? - mork_bool mParser_InTable; // called OnNewMeta but not OnMetaEnd? - mork_bool mParser_InGroup; // called OnNewGroup but not OnGroupEnd? - - mork_change mParser_AtomChange; // driven by mParser_Change - mork_change mParser_CellChange; // driven by mParser_Change - mork_change mParser_RowChange; // driven by mParser_Change - mork_change mParser_TableChange; // driven by mParser_Change - - mork_change mParser_Change; // driven by modifier in text - mork_bool mParser_IsBroken; // has the parse become broken? - mork_bool mParser_IsDone; // has the parse finished? - mork_bool mParser_DoMore; // mParser_MoreGranularity not exhausted? - - morkMid mParser_Mid; // current alias being parsed - // note that mParser_Mid.mMid_Buf points at mParser_ScopeCoil below: - - // blob coils allocated in mParser_Heap - morkCoil mParser_ScopeCoil; // place to accumulate ID scope blobs - morkCoil mParser_ValueCoil; // place to accumulate value blobs - morkCoil mParser_ColumnCoil; // place to accumulate column blobs - morkCoil mParser_StringCoil; // place to accumulate string blobs - - morkSpool mParser_ScopeSpool; // writes to mParser_ScopeCoil - morkSpool mParser_ValueSpool; // writes to mParser_ValueCoil - morkSpool mParser_ColumnSpool; // writes to mParser_ColumnCoil - morkSpool mParser_StringSpool; // writes to mParser_StringCoil - - // yarns allocated in mParser_Heap - morkYarn mParser_MidYarn; // place to receive from MidToYarn() - - // span showing current ongoing file position status: - morkSpan mParser_PortSpan; // span of current db port file - - // various spans denoting nested subspaces inside the file's port span: - morkSpan mParser_GroupSpan; // span of current transaction group - morkSpan mParser_DictSpan; - morkSpan mParser_AliasSpan; - morkSpan mParser_MetaSpan; - morkSpan mParser_TableSpan; - morkSpan mParser_RowSpan; - morkSpan mParser_CellSpan; - morkSpan mParser_ColumnSpan; - morkSpan mParser_SlotSpan; - -private: // convenience inlines - - mork_pos HerePos() const - { return mParser_PortSpan.mSpan_End.mPlace_Pos; } - - void SetHerePos(mork_pos inPos) - { mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; } - - void CountLineBreak() - { ++mParser_PortSpan.mSpan_End.mPlace_Line; } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseParser() only if open - virtual ~morkParser(); // assert that CloseParser() executed earlier - -public: // morkYarn construction & destruction - morkParser(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkStream* ioStream, // the readonly stream for input bytes - mdb_count inBytesPerParseSegment, // target for ParseMore() - nsIMdbHeap* ioSlotHeap); - - void CloseParser(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkParser(const morkParser& other); - morkParser& operator=(const morkParser& other); - -public: // dynamic type identification - mork_bool IsParser() const - { return IsNode() && mNode_Derived == morkDerived_kParser; } - -// } ===== end morkNode methods ===== - -public: // errors and warnings - static void UnexpectedEofError(morkEnv* ev); - static void EofInsteadOfHexError(morkEnv* ev); - static void ExpectedEqualError(morkEnv* ev); - static void ExpectedHexDigitError(morkEnv* ev, int c); - static void NonParserTypeError(morkEnv* ev); - static void UnexpectedByteInMetaWarning(morkEnv* ev); - -public: // other type methods - mork_bool GoodParserTag() const { return mParser_Tag == morkParser_kTag; } - void NonGoodParserError(morkEnv* ev); - void NonUsableParserError(morkEnv* ev); - // call when IsNode() or GoodParserTag() is false - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // in virtual morkParser methods, data flow subclass to parser - - virtual void MidToYarn(morkEnv* ev, - const morkMid& inMid, // typically an alias to concat with strings - mdbYarn* outYarn) = 0; - // The parser might ask that some aliases be turned into yarns, so they - // can be concatenated into longer blobs under some circumstances. This - // is an alternative to using a long and complex callback for many parts - // for a single cell value. - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // out virtual morkParser methods, data flow parser to subclass - -// The virtual methods below will be called in a pattern corresponding -// to the following grammar isomorphic to the Mork grammar. There should -// be no exceptions, so subclasses can rely on seeing an appropriate "end" -// method whenever some "new" method has been seen earlier. In the event -// that some error occurs that causes content to be flushed, or sudden early -// termination of a larger containing entity, we will always call a more -// enclosed "end" method before we call an "end" method with greater scope. - -// Note the "mp" prefix stands for "Mork Parser": - -// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd -// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch -// mp:Group ::= OnNewGroup mp:GroupItem* mp:GroupEnd -// mp:GroupItem ::= mp:Content | OnGroupGlitch -// mp:GroupEnd ::= OnGroupCommitEnd | OnGroupAbortEnd -// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row -// mp:PortRow ::= OnNewPortRow mp:RowItem* OnPortRowEnd -// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd -// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch -// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd -// mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch -// mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd -// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd -// mp:MetaItem ::= mp:Cell | OnMetaGlitch -// mp:Row ::= OnMinusRow? OnNewRow mp:RowItem* OnRowEnd -// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch -// mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd -// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch -// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid - - - // Note that in interfaces below, mork_change parameters kAdd and kNil - // both mean about the same thing by default. Only kCut is interesting, - // because this usually means to remove members instead of adding them. - - virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0; - virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0; - virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_change inChange) = 0; - virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllRows) = 0; - virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0; - virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnMinusRow(morkEnv* ev) = 0; - virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace, - const morkMid& inMid, mork_bool inCutAllCols) = 0; - virtual void OnRowPos(morkEnv* ev, mork_pos inRowPos) = 0; - virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0; - virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) = 0; - - virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - - virtual void OnMinusCell(morkEnv* ev) = 0; - virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace, - const morkMid* inMid, const morkBuf* inBuf) = 0; - // Exactly one of inMid and inBuf is nil, and the other is non-nil. - // When hex ID syntax is used for a column, then inMid is not nil, and - // when a naked string names a column, then inBuf is not nil. - - virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0; - virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) = 0; - virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan) = 0; - - virtual void OnValue(morkEnv* ev, const morkSpan& inSpan, - const morkBuf& inBuf) = 0; - - virtual void OnValueMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) = 0; - - virtual void OnRowMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) = 0; - - virtual void OnTableMid(morkEnv* ev, const morkSpan& inSpan, - const morkMid& inMid) = 0; - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected parser helper methods - - void ParseChunk(morkEnv* ev); // find parse continuation and resume - - void StartParse(morkEnv* ev); // prepare for parsing - void StopParse(morkEnv* ev); // terminate parsing & call needed methods - - int NextChar(morkEnv* ev); // next non-white content - - void OnCellState(morkEnv* ev); - void OnMetaState(morkEnv* ev); - void OnRowState(morkEnv* ev); - void OnTableState(morkEnv* ev); - void OnDictState(morkEnv* ev); - void OnPortState(morkEnv* ev); - void OnStartState(morkEnv* ev); - - void ReadCell(morkEnv* ev); - void ReadRow(morkEnv* ev, int c); - void ReadRowPos(morkEnv* ev); - void ReadTable(morkEnv* ev); - void ReadTableMeta(morkEnv* ev); - void ReadDict(morkEnv* ev); - mork_bool ReadContent(morkEnv* ev, mork_bool inInsideGroup); - void ReadGroup(morkEnv* ev); - mork_bool ReadEndGroupId(morkEnv* ev); - mork_bool ReadAt(morkEnv* ev, mork_bool inInsideGroup); - mork_bool FindGroupEnd(morkEnv* ev); - void ReadMeta(morkEnv* ev, int inEndMeta); - void ReadAlias(morkEnv* ev); - mork_id ReadHex(morkEnv* ev, int* outNextChar); - morkBuf* ReadValue(morkEnv* ev); - morkBuf* ReadName(morkEnv* ev, int c); - mork_bool ReadMid(morkEnv* ev, morkMid* outMid); - void ReadDictForm(morkEnv *ev); - void ReadCellForm(morkEnv *ev, int c); - - mork_bool MatchPattern(morkEnv* ev, const char* inPattern); - - void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan); - void EndSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan); - void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan); - - void StartSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan); - - - // void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan) - // { MORK_USED_2(ev,ioSpan); } - - // void EndSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan) - // { MORK_USED_2(ev,ioSpan); } - - // void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan) - // { MORK_USED_2(ev,ioSpan); } - - // void StartSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan) - // { MORK_USED_2(ev,ioSpan); } - - int eat_line_break(morkEnv* ev, int inLast); - int eat_line_continue(morkEnv* ev); // last char was '\\' - int eat_comment(morkEnv* ev); // last char was '/' - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkParser methods - - mdb_count ParseMore( // return count of bytes consumed now - morkEnv* ev, // context - mork_pos* outPos, // current byte pos in the stream afterwards - mork_bool* outDone, // is parsing finished? - mork_bool* outBroken // is parsing irreparably dead and broken? - ); - - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakParser(morkParser* me, - morkEnv* ev, morkParser** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongParser(morkParser* me, - morkEnv* ev, morkParser** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKPARSER_ */ - diff --git a/db/mork/src/morkPool.cpp b/db/mork/src/morkPool.cpp deleted file mode 100644 index f4c33233efe2..000000000000 --- a/db/mork/src/morkPool.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKHANDLE_ -#include "morkHandle.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -#ifndef _MORKZONE_ -#include "morkZone.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkPool::CloseMorkNode(morkEnv* ev) // ClosePool() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->ClosePool(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkPool::~morkPool() // assert ClosePool() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkPool::morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbHeap* ioSlotHeap) -: morkNode(inUsage, ioHeap) -, mPool_Heap( ioSlotHeap ) -, mPool_UsedFramesCount( 0 ) -, mPool_FreeFramesCount( 0 ) -{ - // mPool_Heap is NOT refcounted - MORK_ASSERT(ioSlotHeap); - if ( ioSlotHeap ) - mNode_Derived = morkDerived_kPool; -} - -/*public non-poly*/ -morkPool::morkPool(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkNode(ev, inUsage, ioHeap) -, mPool_Heap( ioSlotHeap ) -, mPool_UsedFramesCount( 0 ) -, mPool_FreeFramesCount( 0 ) -{ - if ( ioSlotHeap ) - { - // mPool_Heap is NOT refcounted: - // nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mPool_Heap); - if ( ev->Good() ) - mNode_Derived = morkDerived_kPool; - } - else - ev->NilPointerError(); -} - -/*public non-poly*/ void -morkPool::ClosePool(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { -#ifdef morkZone_CONFIG_ARENA -#else /*morkZone_CONFIG_ARENA*/ - //MORK_USED_1(ioZone); -#endif /*morkZone_CONFIG_ARENA*/ - - nsIMdbHeap* heap = mPool_Heap; - nsIMdbEnv* mev = ev->AsMdbEnv(); - morkLink* aLink; - morkDeque* d = &mPool_FreeHandleFrames; - while ( (aLink = d->RemoveFirst()) != 0 ) - heap->Free(mev, aLink); - - // if the pool's closed, get rid of the frames in use too. - d = &mPool_UsedHandleFrames; - while ( (aLink = d->RemoveFirst()) != 0 ) - heap->Free(mev, aLink); - - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - - -// alloc and free individual instances of handles (inside hand frames): -morkHandleFace* -morkPool::NewHandle(morkEnv* ev, mork_size inSize, morkZone* ioZone) -{ - void* newBlock = 0; - if ( inSize <= sizeof(morkHandleFrame) ) - { - morkLink* firstLink = mPool_FreeHandleFrames.RemoveFirst(); - if ( firstLink ) - { - newBlock = firstLink; - if ( mPool_FreeFramesCount ) - --mPool_FreeFramesCount; - else - ev->NewWarning("mPool_FreeFramesCount underflow"); - } - else - mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkHandleFrame), - (void**) &newBlock); - } - else - { - ev->NewWarning("inSize > sizeof(morkHandleFrame)"); - mPool_Heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &newBlock); - } -#ifdef morkZone_CONFIG_ARENA -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); -#endif /*morkZone_CONFIG_ARENA*/ - - return (morkHandleFace*) newBlock; -} - -void -morkPool::ZapHandle(morkEnv* ev, morkHandleFace* ioHandle) -{ - if ( ioHandle ) - { - morkLink* handleLink = (morkLink*) ioHandle; - mPool_FreeHandleFrames.AddLast(handleLink); - ++mPool_FreeFramesCount; - // lets free all handles to track down leaks - // - uncomment out next 3 lines, comment out above 2 -// nsIMdbHeap* heap = mPool_Heap; -// nsIMdbEnv* mev = ev->AsMdbEnv(); -// heap->Free(mev, handleLink); - - } -} - - -// alloc and free individual instances of rows: -morkRow* -morkPool::NewRow(morkEnv* ev, morkZone* ioZone) // allocate a new row instance -{ - morkRow* newRow = 0; - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newRow = (morkRow*) ioZone->ZoneNewChip(ev, sizeof(morkRow)); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkRow), (void**) &newRow); -#endif /*morkZone_CONFIG_ARENA*/ - - if ( newRow ) - MORK_MEMSET(newRow, 0, sizeof(morkRow)); - - return newRow; -} - -void -morkPool::ZapRow(morkEnv* ev, morkRow* ioRow, - morkZone* ioZone) // free old row instance -{ -#ifdef morkZone_CONFIG_ARENA - if ( !ioRow ) - ev->NilPointerWarning(); // a zone 'chip' cannot be freed -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - if ( ioRow ) - mPool_Heap->Free(ev->AsMdbEnv(), ioRow); -#endif /*morkZone_CONFIG_ARENA*/ -} - -// alloc and free entire vectors of cells (not just one cell at a time) -morkCell* -morkPool::NewCells(morkEnv* ev, mork_size inSize, - morkZone* ioZone) -{ - morkCell* newCells = 0; - - mork_size size = inSize * sizeof(morkCell); - if ( size ) - { -#ifdef morkZone_CONFIG_ARENA - // a zone 'run' knows its size, and can indeed be deallocated: - newCells = (morkCell*) ioZone->ZoneNewRun(ev, size); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newCells); -#endif /*morkZone_CONFIG_ARENA*/ - } - - // note morkAtom depends on having nil stored in all new mCell_Atom slots: - if ( newCells ) - MORK_MEMSET(newCells, 0, size); - return newCells; -} - -void -morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize, - morkZone* ioZone) -{ - MORK_USED_1(inSize); - - if ( ioVector ) - { -#ifdef morkZone_CONFIG_ARENA - // a zone 'run' knows its size, and can indeed be deallocated: - ioZone->ZoneZapRun(ev, ioVector); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Free(ev->AsMdbEnv(), ioVector); -#endif /*morkZone_CONFIG_ARENA*/ - } -} - -// resize (grow or trim) cell vectors inside a containing row instance -mork_bool -morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize, - morkZone* ioZone) -{ - // note strong implementation similarity to morkArray::Grow() - - MORK_USED_1(ioZone); -#ifdef morkZone_CONFIG_ARENA -#else /*morkZone_CONFIG_ARENA*/ -#endif /*morkZone_CONFIG_ARENA*/ - - mork_fill fill = ioRow->mRow_Length; - if ( ev->Good() && fill < inNewSize ) // need more cells? - { - morkCell* newCells = this->NewCells(ev, inNewSize, ioZone); - if ( newCells ) - { - morkCell* c = newCells; // for iterating during copy - morkCell* oldCells = ioRow->mRow_Cells; - morkCell* end = oldCells + fill; // copy all the old cells - while ( oldCells < end ) - { - *c++ = *oldCells++; // bitwise copy each old cell struct - } - oldCells = ioRow->mRow_Cells; - ioRow->mRow_Cells = newCells; - ioRow->mRow_Length = (mork_u2) inNewSize; - ++ioRow->mRow_Seed; - - if ( oldCells ) - this->ZapCells(ev, oldCells, fill, ioZone); - } - } - return ( ev->Good() && ioRow->mRow_Length >= inNewSize ); -} - -mork_bool -morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow, - mork_size inNewSize, - morkZone* ioZone) -{ - MORK_USED_1(ioZone); -#ifdef morkZone_CONFIG_ARENA -#else /*morkZone_CONFIG_ARENA*/ -#endif /*morkZone_CONFIG_ARENA*/ - - mork_fill fill = ioRow->mRow_Length; - if ( ev->Good() && fill > inNewSize ) // need fewer cells? - { - if ( inNewSize ) // want any row cells at all? - { - morkCell* newCells = this->NewCells(ev, inNewSize, ioZone); - if ( newCells ) - { - morkCell* saveNewCells = newCells; // Keep newcell pos - morkCell* oldCells = ioRow->mRow_Cells; - morkCell* oldEnd = oldCells + fill; // one past all old cells - morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells - while ( oldCells < newEnd ) - { - *newCells++ = *oldCells++; // bitwise copy each old cell struct - } - while ( oldCells < oldEnd ) - { - if ( oldCells->mCell_Atom ) // need to unref old cell atom? - oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom - ++oldCells; - } - oldCells = ioRow->mRow_Cells; - ioRow->mRow_Cells = saveNewCells; - ioRow->mRow_Length = (mork_u2) inNewSize; - ++ioRow->mRow_Seed; - - if ( oldCells ) - this->ZapCells(ev, oldCells, fill, ioZone); - } - } - else // get rid of all row cells - { - morkCell* oldCells = ioRow->mRow_Cells; - ioRow->mRow_Cells = 0; - ioRow->mRow_Length = 0; - ++ioRow->mRow_Seed; - - if ( oldCells ) - this->ZapCells(ev, oldCells, fill, ioZone); - } - } - return ( ev->Good() && ioRow->mRow_Length <= inNewSize ); -} - -// alloc & free individual instances of atoms (lots of atom subclasses): -void -morkPool::ZapAtom(morkEnv* ev, morkAtom* ioAtom, - morkZone* ioZone) // any subclass (by kind) -{ -#ifdef morkZone_CONFIG_ARENA - if ( !ioAtom ) - ev->NilPointerWarning(); // a zone 'chip' cannot be freed -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - if ( ioAtom ) - mPool_Heap->Free(ev->AsMdbEnv(), ioAtom); -#endif /*morkZone_CONFIG_ARENA*/ -} - -morkOidAtom* -morkPool::NewRowOidAtom(morkEnv* ev, const mdbOid& inOid, - morkZone* ioZone) -{ - morkOidAtom* newAtom = 0; - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkOidAtom*) ioZone->ZoneNewChip(ev, sizeof(morkOidAtom)); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom),(void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - - if ( newAtom ) - newAtom->InitRowOidAtom(ev, inOid); - return newAtom; -} - -morkOidAtom* -morkPool::NewTableOidAtom(morkEnv* ev, const mdbOid& inOid, - morkZone* ioZone) -{ - morkOidAtom* newAtom = 0; - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkOidAtom*) ioZone->ZoneNewChip(ev, sizeof(morkOidAtom)); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom), (void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - if ( newAtom ) - newAtom->InitTableOidAtom(ev, inOid); - return newAtom; -} - -morkAtom* -morkPool::NewAnonAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, - morkZone* ioZone) -// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee' -// anon atom will be created, and otherwise a 'big' anon atom. -{ - morkAtom* newAtom = 0; - - mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 ); - mork_size size = ( needBig )? - morkBigAnonAtom::SizeForFill(inBuf.mBuf_Fill) : - morkWeeAnonAtom::SizeForFill(inBuf.mBuf_Fill); - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkAtom*) ioZone->ZoneNewChip(ev, size); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - if ( newAtom ) - { - if ( needBig ) - ((morkBigAnonAtom*) newAtom)->InitBigAnonAtom(ev, inBuf, inForm); - else - ((morkWeeAnonAtom*) newAtom)->InitWeeAnonAtom(ev, inBuf); - } - return newAtom; -} - -morkBookAtom* -morkPool::NewBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid, - morkZone* ioZone) -// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee' -// book atom will be created, and otherwise a 'big' book atom. -{ - morkBookAtom* newAtom = 0; - - mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 ); - mork_size size = ( needBig )? - morkBigBookAtom::SizeForFill(inBuf.mBuf_Fill) : - morkWeeBookAtom::SizeForFill(inBuf.mBuf_Fill); - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkBookAtom*) ioZone->ZoneNewChip(ev, size); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - if ( newAtom ) - { - if ( needBig ) - ((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev, - inBuf, inForm, ioSpace, inAid); - else - ((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev, - inBuf, ioSpace, inAid); - } - return newAtom; -} - -morkBookAtom* -morkPool::NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom, - morkZone* ioZone) - // make the smallest kind of book atom that can hold content in inAtom. - // The inAtom parameter is often expected to be a staged book atom in - // the store, which was used to search an atom space for existing atoms. -{ - morkBookAtom* newAtom = 0; - - mork_cscode form = inAtom.mBigBookAtom_Form; - mork_fill fill = inAtom.mBigBookAtom_Size; - mork_bool needBig = ( form || fill > 255 ); - mork_size size = ( needBig )? - morkBigBookAtom::SizeForFill(fill) : - morkWeeBookAtom::SizeForFill(fill); - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkBookAtom*) ioZone->ZoneNewChip(ev, size); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - if ( newAtom ) - { - morkBuf buf(inAtom.mBigBookAtom_Body, fill); - if ( needBig ) - ((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev, - buf, form, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id); - else - ((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev, - buf, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id); - } - return newAtom; -} - -morkBookAtom* -morkPool::NewFarBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom, - morkZone* ioZone) - // make the smallest kind of book atom that can hold content in inAtom. - // The inAtom parameter is often expected to be a staged book atom in - // the store, which was used to search an atom space for existing atoms. -{ - morkBookAtom* newAtom = 0; - - mork_cscode form = inAtom.mFarBookAtom_Form; - mork_fill fill = inAtom.mFarBookAtom_Size; - mork_bool needBig = ( form || fill > 255 ); - mork_size size = ( needBig )? - morkBigBookAtom::SizeForFill(fill) : - morkWeeBookAtom::SizeForFill(fill); - -#ifdef morkZone_CONFIG_ARENA - // a zone 'chip' remembers no size, and so cannot be deallocated: - newAtom = (morkBookAtom*) ioZone->ZoneNewChip(ev, size); -#else /*morkZone_CONFIG_ARENA*/ - MORK_USED_1(ioZone); - mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom); -#endif /*morkZone_CONFIG_ARENA*/ - if ( newAtom ) - { - morkBuf buf(inAtom.mFarBookAtom_Body, fill); - if ( needBig ) - ((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev, - buf, form, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id); - else - ((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev, - buf, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id); - } - return newAtom; -} - - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkPool.h b/db/mork/src/morkPool.h deleted file mode 100644 index 23a289249ecd..000000000000 --- a/db/mork/src/morkPool.h +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKPOOL_ -#define _MORKPOOL_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class morkHandle; -class morkHandleFrame; -class morkHandleFace; // just an opaque cookie type -class morkBigBookAtom; -class morkFarBookAtom; - -#define morkDerived_kPool /*i*/ 0x706C /* ascii 'pl' */ - -/*| morkPool: a place to manage pools of non-node objects that are memory -**| managed out of large chunks of space, so that per-object management -**| space overhead has no signficant cost. -|*/ -class morkPool : public morkNode { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - nsIMdbHeap* mPool_Heap; // NON-refcounted heap instance - - morkDeque mPool_Blocks; // linked list of large blocks from heap - - // These two lists contain instances of morkHandleFrame: - morkDeque mPool_UsedHandleFrames; // handle frames currently being used - morkDeque mPool_FreeHandleFrames; // handle frames currently in free list - - mork_count mPool_UsedFramesCount; // length of mPool_UsedHandleFrames - mork_count mPool_FreeFramesCount; // length of mPool_UsedHandleFrames - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // ClosePool() only if open - virtual ~morkPool(); // assert that ClosePool() executed earlier - -public: // morkPool construction & destruction - morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbHeap* ioSlotHeap); - morkPool(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbHeap* ioSlotHeap); - void ClosePool(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkPool(const morkPool& other); - morkPool& operator=(const morkPool& other); - -public: // dynamic type identification - mork_bool IsPool() const - { return IsNode() && mNode_Derived == morkDerived_kPool; } -// } ===== end morkNode methods ===== - -public: // typing - void NonPoolTypeError(morkEnv* ev); - -public: // morkNode memory management operators - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkNode::MakeNew(inSize, ioHeap, ev); } - - void* operator new(size_t inSize) CPP_THROW_NEW - { return ::operator new(inSize); } - - -public: // other pool methods - - // alloc and free individual instances of handles (inside hand frames): - morkHandleFace* NewHandle(morkEnv* ev, mork_size inSize, morkZone* ioZone); - void ZapHandle(morkEnv* ev, morkHandleFace* ioHandle); - - // alloc and free individual instances of rows: - morkRow* NewRow(morkEnv* ev, morkZone* ioZone); // alloc new row instance - void ZapRow(morkEnv* ev, morkRow* ioRow, morkZone* ioZone); // free old row instance - - // alloc and free entire vectors of cells (not just one cell at a time) - morkCell* NewCells(morkEnv* ev, mork_size inSize, morkZone* ioZone); - void ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize, morkZone* ioZone); - - // resize (grow or trim) cell vectors inside a containing row instance - mork_bool AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize, morkZone* ioZone); - mork_bool CutRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize, morkZone* ioZone); - - // alloc & free individual instances of atoms (lots of atom subclasses): - void ZapAtom(morkEnv* ev, morkAtom* ioAtom, morkZone* ioZone); // any subclass (by kind) - - morkOidAtom* NewRowOidAtom(morkEnv* ev, const mdbOid& inOid, morkZone* ioZone); - morkOidAtom* NewTableOidAtom(morkEnv* ev, const mdbOid& inOid, morkZone* ioZone); - - morkAtom* NewAnonAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkZone* ioZone); - // if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee' - // anon atom will be created, and otherwise a 'big' anon atom. - - morkBookAtom* NewBookAtom(morkEnv* ev, const morkBuf& inBuf, - mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid, morkZone* ioZone); - // if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee' - // book atom will be created, and otherwise a 'big' book atom. - - morkBookAtom* NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom, morkZone* ioZone); - // make the smallest kind of book atom that can hold content in inAtom. - // The inAtom parameter is often expected to be a staged book atom in - // the store, which was used to search an atom space for existing atoms. - - morkBookAtom* NewFarBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom, morkZone* ioZone); - // make the smallest kind of book atom that can hold content in inAtom. - // The inAtom parameter is often expected to be a staged book atom in - // the store, which was used to search an atom space for existing atoms. - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakPool(morkPool* me, - morkEnv* ev, morkPool** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongPool(morkPool* me, - morkEnv* ev, morkPool** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKPOOL_ */ - diff --git a/db/mork/src/morkPortTableCursor.cpp b/db/mork/src/morkPortTableCursor.cpp deleted file mode 100644 index f4d6581a5688..000000000000 --- a/db/mork/src/morkPortTableCursor.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKPORTTABLECURSOR_ -#include "morkPortTableCursor.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkPortTableCursor::CloseMorkNode(morkEnv* ev) // ClosePortTableCursor() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->ClosePortTableCursor(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed earlier -{ - CloseMorkNode(mMorkEnv); -} - -/*public non-poly*/ -morkPortTableCursor::morkPortTableCursor(morkEnv* ev, - const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope, - mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap) -: morkCursor(ev, inUsage, ioHeap) -, mPortTableCursor_Store( 0 ) -, mPortTableCursor_RowScope( (mdb_scope) -1 ) // we want != inRowScope -, mPortTableCursor_TableKind( (mdb_kind) -1 ) // we want != inTableKind -, mPortTableCursor_LastTable ( 0 ) // not refcounted -, mPortTableCursor_RowSpace( 0 ) // strong ref to row space -, mPortTableCursor_TablesDidEnd( morkBool_kFalse ) -, mPortTableCursor_SpacesDidEnd( morkBool_kFalse ) -{ - if ( ev->Good() ) - { - if ( ioStore && ioSlotHeap ) - { - mCursor_Pos = -1; - mCursor_Seed = 0; // let the iterator do its own seed handling - morkStore::SlotWeakStore(ioStore, ev, &mPortTableCursor_Store); - - if ( this->SetRowScope(ev, inRowScope) ) - this->SetTableKind(ev, inTableKind); - - if ( ev->Good() ) - mNode_Derived = morkDerived_kPortTableCursor; - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkPortTableCursor, morkCursor, nsIMdbPortTableCursor) - -morkEnv* -morkPortTableCursor::CanUsePortTableCursor(nsIMdbEnv* mev, - mork_bool inMutable, mdb_err* outErr) const -{ - morkEnv* outEnv = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( IsPortTableCursor() ) - outEnv = ev; - else - NonPortTableCursorTypeError(ev); - *outErr = ev->AsErr(); - } - MORK_ASSERT(outEnv); - return outEnv; -} - - -/*public non-poly*/ void -morkPortTableCursor::ClosePortTableCursor(morkEnv* ev) -{ - if ( this ) - { - if ( this->IsNode() ) - { - mCursor_Pos = -1; - mCursor_Seed = 0; - mPortTableCursor_LastTable = 0; - morkStore::SlotWeakStore((morkStore*) 0, ev, &mPortTableCursor_Store); - morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev, - &mPortTableCursor_RowSpace); - this->CloseCursor(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkPortTableCursor::NilCursorStoreError(morkEnv* ev) -{ - ev->NewError("nil mPortTableCursor_Store"); -} - -/*static*/ void -morkPortTableCursor::NonPortTableCursorTypeError(morkEnv* ev) -{ - ev->NewError("non morkPortTableCursor"); -} - -mork_bool -morkPortTableCursor::SetRowScope(morkEnv* ev, mork_scope inRowScope) -{ - mPortTableCursor_RowScope = inRowScope; - mPortTableCursor_LastTable = 0; // restart iteration of space - - mPortTableCursor_TableIter.CloseMapIter(ev); - mPortTableCursor_TablesDidEnd = morkBool_kTrue; - mPortTableCursor_SpacesDidEnd = morkBool_kTrue; - - morkStore* store = mPortTableCursor_Store; - if ( store ) - { - morkRowSpace* space = mPortTableCursor_RowSpace; - - if ( inRowScope ) // intend to cover a specific scope only? - { - space = store->LazyGetRowSpace(ev, inRowScope); - morkRowSpace::SlotStrongRowSpace(space, ev, - &mPortTableCursor_RowSpace); - - // We want mPortTableCursor_SpacesDidEnd == morkBool_kTrue - // to show this is the only space to be covered. - } - else // prepare space map iter to cover all space scopes - { - morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter; - rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces); - - space = 0; - (void) rsi->FirstRowSpace(ev, (mork_scope*) 0, &space); - morkRowSpace::SlotStrongRowSpace(space, ev, - &mPortTableCursor_RowSpace); - - if ( space ) // found first space in store - mPortTableCursor_SpacesDidEnd = morkBool_kFalse; - } - - this->init_space_tables_map(ev); - } - else - this->NilCursorStoreError(ev); - - return ev->Good(); -} - -void -morkPortTableCursor::init_space_tables_map(morkEnv* ev) -{ - morkRowSpace* space = mPortTableCursor_RowSpace; - if ( space && ev->Good() ) - { - morkTableMapIter* ti = &mPortTableCursor_TableIter; - ti->InitTableMapIter(ev, &space->mRowSpace_Tables); - if ( ev->Good() ) - mPortTableCursor_TablesDidEnd = morkBool_kFalse; - } -} - - -mork_bool -morkPortTableCursor::SetTableKind(morkEnv* ev, mork_kind inTableKind) -{ - mPortTableCursor_TableKind = inTableKind; - mPortTableCursor_LastTable = 0; // restart iteration of space - - mPortTableCursor_TablesDidEnd = morkBool_kTrue; - - morkRowSpace* space = mPortTableCursor_RowSpace; - if ( !space && mPortTableCursor_RowScope == 0 ) - { - this->SetRowScope(ev, 0); - space = mPortTableCursor_RowSpace; - } - this->init_space_tables_map(ev); - - return ev->Good(); -} - -morkRowSpace* -morkPortTableCursor::NextSpace(morkEnv* ev) -{ - morkRowSpace* outSpace = 0; - mPortTableCursor_LastTable = 0; - mPortTableCursor_SpacesDidEnd = morkBool_kTrue; - mPortTableCursor_TablesDidEnd = morkBool_kTrue; - - if ( !mPortTableCursor_RowScope ) // not just one scope? - { - morkStore* store = mPortTableCursor_Store; - if ( store ) - { - morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter; - - (void) rsi->NextRowSpace(ev, (mork_scope*) 0, &outSpace); - morkRowSpace::SlotStrongRowSpace(outSpace, ev, - &mPortTableCursor_RowSpace); - - if ( outSpace ) // found next space in store - { - mPortTableCursor_SpacesDidEnd = morkBool_kFalse; - - this->init_space_tables_map(ev); - - if ( ev->Bad() ) - outSpace = 0; - } - } - else - this->NilCursorStoreError(ev); - } - - return outSpace; -} - -morkTable * -morkPortTableCursor::NextTable(morkEnv* ev) -{ - mork_kind kind = mPortTableCursor_TableKind; - - do // until spaces end, or until we find a table in a space - { - morkRowSpace* space = mPortTableCursor_RowSpace; - if ( mPortTableCursor_TablesDidEnd ) // current space exhausted? - space = this->NextSpace(ev); // go on to the next space - - if ( space ) // have a space remaining that might hold tables? - { -#ifdef MORK_BEAD_OVER_NODE_MAPS - morkTableMapIter* ti = &mPortTableCursor_TableIter; - morkTable* table = ( mPortTableCursor_LastTable )? - ti->NextTable(ev) : ti->FirstTable(ev); - - for ( ; table && ev->Good(); table = ti->NextTable(ev) ) - -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - mork_tid* key = 0; // ignore keys in table map - morkTable* table = 0; // old value table in the map - morkTableMapIter* ti = &mPortTableCursor_TableIter; - mork_change* c = ( mPortTableCursor_LastTable )? - ti->NextTable(ev, key, &table) : ti->FirstTable(ev, key, &table); - - for ( ; c && ev->Good(); c = ti->NextTable(ev, key, &table) ) -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - { - if ( table && table->IsTable() ) - { - if ( !kind || kind == table->mTable_Kind ) - { - mPortTableCursor_LastTable = table; // ti->NextTable() hence - return table; - } - } - else - table->NonTableTypeWarning(ev); - } - mPortTableCursor_TablesDidEnd = morkBool_kTrue; // space is done - mPortTableCursor_LastTable = 0; // make sure next space starts fresh - } - - } while ( ev->Good() && !mPortTableCursor_SpacesDidEnd ); - - return (morkTable*) 0; -} - - -// { ----- begin table iteration methods ----- - -// { ===== begin nsIMdbPortTableCursor methods ===== - -// { ----- begin attribute methods ----- -NS_IMETHODIMP -morkPortTableCursor::SetPort(nsIMdbEnv* mev, nsIMdbPort* ioPort) -{ - NS_ASSERTION(PR_FALSE,"not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkPortTableCursor::GetPort(nsIMdbEnv* mev, nsIMdbPort** acqPort) -{ - mdb_err outErr = 0; - nsIMdbPort* outPort = 0; - morkEnv* ev = - this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - if ( mPortTableCursor_Store ) - outPort = mPortTableCursor_Store->AcquireStoreHandle(ev); - outErr = ev->AsErr(); - } - if ( acqPort ) - *acqPort = outPort; - return outErr; -} - -NS_IMETHODIMP -morkPortTableCursor::SetRowScope(nsIMdbEnv* mev, // sets pos to -1 - mdb_scope inRowScope) -{ - mdb_err outErr = 0; - morkEnv* ev = - this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - mCursor_Pos = -1; - - SetRowScope(ev, inRowScope); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkPortTableCursor::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope) -{ - mdb_err outErr = 0; - mdb_scope rowScope = 0; - morkEnv* ev = - this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - rowScope = mPortTableCursor_RowScope; - outErr = ev->AsErr(); - } - *outRowScope = rowScope; - return outErr; -} -// setting row scope to zero iterates over all row scopes in port - -NS_IMETHODIMP -morkPortTableCursor::SetTableKind(nsIMdbEnv* mev, // sets pos to -1 - mdb_kind inTableKind) -{ - mdb_err outErr = 0; - morkEnv* ev = - this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - mCursor_Pos = -1; - - SetTableKind(ev, inTableKind); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkPortTableCursor::GetTableKind(nsIMdbEnv* mev, mdb_kind* outTableKind) -// setting table kind to zero iterates over all table kinds in row scope -{ - mdb_err outErr = 0; - mdb_kind tableKind = 0; - morkEnv* ev = - this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - tableKind = mPortTableCursor_TableKind; - outErr = ev->AsErr(); - } - *outTableKind = tableKind; - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin table iteration methods ----- -NS_IMETHODIMP -morkPortTableCursor::NextTable( // get table at next position in the db - nsIMdbEnv* mev, // context - nsIMdbTable** acqTable) -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = - CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = NextTable(ev); - if ( table && ev->Good() ) - outTable = table->AcquireTableHandle(ev); - - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkPortTableCursor.h b/db/mork/src/morkPortTableCursor.h deleted file mode 100644 index a93445035457..000000000000 --- a/db/mork/src/morkPortTableCursor.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKPORTTABLECURSOR_ -#define _MORKPORTTABLECURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class orkinPortTableCursor; -#define morkDerived_kPortTableCursor /*i*/ 0x7443 /* ascii 'tC' */ - -class morkPortTableCursor : public morkCursor, public nsIMdbPortTableCursor { // row iterator -public: - NS_DECL_ISUPPORTS_INHERITED -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkFactory* mObject_Factory; // weak ref to suite factory - - // mork_seed mCursor_Seed; - // mork_pos mCursor_Pos; - // mork_bool mCursor_DoFailOnSeedOutOfSync; - // mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - -public: // state is public because the entire Mork system is private - // { ----- begin attribute methods ----- - NS_IMETHOD SetPort(nsIMdbEnv* ev, nsIMdbPort* ioPort); // sets pos to -1 - NS_IMETHOD GetPort(nsIMdbEnv* ev, nsIMdbPort** acqPort); - - NS_IMETHOD SetRowScope(nsIMdbEnv* ev, // sets pos to -1 - mdb_scope inRowScope); - NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope); - // setting row scope to zero iterates over all row scopes in port - - NS_IMETHOD SetTableKind(nsIMdbEnv* ev, // sets pos to -1 - mdb_kind inTableKind); - NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind); - // setting table kind to zero iterates over all table kinds in row scope - // } ----- end attribute methods ----- - - // { ----- begin table iteration methods ----- - NS_IMETHOD NextTable( // get table at next position in the db - nsIMdbEnv* ev, // context - nsIMdbTable** acqTable); // the next table in the iteration - // } ----- end table iteration methods ----- - morkStore* mPortTableCursor_Store; // weak ref to store - - mdb_scope mPortTableCursor_RowScope; - mdb_kind mPortTableCursor_TableKind; - - // We only care if LastTable is non-nil, so it is not refcounted; - // so you must never access table state or methods using LastTable: - - morkTable* mPortTableCursor_LastTable; // nil or last table (no refcount) - morkRowSpace* mPortTableCursor_RowSpace; // current space (strong ref) - - morkRowSpaceMapIter mPortTableCursor_SpaceIter; // iter over spaces - morkTableMapIter mPortTableCursor_TableIter; // iter over tables - - // these booleans indicate when the table or space iterator is exhausted: - - mork_bool mPortTableCursor_TablesDidEnd; // no more tables? - mork_bool mPortTableCursor_SpacesDidEnd; // no more spaces? - mork_u1 mPortTableCursor_Pad[ 2 ]; // for u4 alignment - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // ClosePortTableCursor() - virtual ~morkPortTableCursor(); // assert that close executed earlier - -public: // morkPortTableCursor construction & destruction - morkPortTableCursor(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope, - mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap); - void ClosePortTableCursor(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkPortTableCursor(const morkPortTableCursor& other); - morkPortTableCursor& operator=(const morkPortTableCursor& other); - -public: // dynamic type identification - mork_bool IsPortTableCursor() const - { return IsNode() && mNode_Derived == morkDerived_kPortTableCursor; } -// } ===== end morkNode methods ===== - -protected: // utilities - - void init_space_tables_map(morkEnv* ev); - -public: // other cursor methods - - static void NilCursorStoreError(morkEnv* ev); - static void NonPortTableCursorTypeError(morkEnv* ev); - - morkEnv* CanUsePortTableCursor(nsIMdbEnv* mev, - mork_bool inMutable, mdb_err* outErr) const; - - - morkRowSpace* NextSpace(morkEnv* ev); - morkTable* NextTable(morkEnv* ev); - - mork_bool SetRowScope(morkEnv* ev, mork_scope inRowScope); - mork_bool SetTableKind(morkEnv* ev, mork_kind inTableKind); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakPortTableCursor(morkPortTableCursor* me, - morkEnv* ev, morkPortTableCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongPortTableCursor(morkPortTableCursor* me, - morkEnv* ev, morkPortTableCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKPORTTABLECURSOR_ */ diff --git a/db/mork/src/morkProbeMap.cpp b/db/mork/src/morkProbeMap.cpp deleted file mode 100644 index 9641b0e27ee1..000000000000 --- a/db/mork/src/morkProbeMap.cpp +++ /dev/null @@ -1,1241 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// This code is a port to NS Mork from public domain Mithril C++ sources. -// Note many code comments here come verbatim from cut-and-pasted Mithril. -// In many places, code is identical; Mithril versions stay public domain. -// Changes in porting are mainly class type and scalar type name changes. - -#include "nscore.h" - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKPROBEMAP_ -#include "morkProbeMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -/*============================================================================*/ -/* morkMapScratch */ - -void morkMapScratch::halt_map_scratch(morkEnv* ev) -{ - nsIMdbHeap* heap = sMapScratch_Heap; - - if ( heap ) - { - if ( sMapScratch_Keys ) - heap->Free(ev->AsMdbEnv(), sMapScratch_Keys); - if ( sMapScratch_Vals ) - heap->Free(ev->AsMdbEnv(), sMapScratch_Vals); - } -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -/*============================================================================*/ -/* morkProbeMap */ - -void morkProbeMap::ProbeMapBadTagError(morkEnv* ev) const -{ - ev->NewError("bad sProbeMap_Tag"); - if ( !this ) - ev->NewError("nil morkProbeMap"); -} - -void morkProbeMap::WrapWithNoVoidSlotError(morkEnv* ev) const -{ - ev->NewError("wrap without void morkProbeMap slot"); -} - -void morkProbeMap::GrowFailsMaxFillError(morkEnv* ev) const -{ - ev->NewError("grow fails morkEnv > sMap_Fill"); -} - -void morkProbeMap::MapKeyIsNotIPError(morkEnv* ev) const -{ - ev->NewError("not sMap_KeyIsIP"); -} - -void morkProbeMap::MapValIsNotIPError(morkEnv* ev) const -{ - ev->NewError("not sMap_ValIsIP"); -} - -void morkProbeMap::rehash_old_map(morkEnv* ev, morkMapScratch* ioScratch) -{ - mork_size keySize = sMap_KeySize; // size of every key bucket - mork_size valSize = sMap_ValSize; // size of every associated value - - mork_count slots = sMap_Slots; // number of new buckets - mork_u1* keys = sMap_Keys; // destination for rehashed keys - mork_u1* vals = sMap_Vals; // destination for any copied values - - mork_bool keyIsIP = ( keys && keySize == sizeof(mork_ip) && sMap_KeyIsIP ); - mork_bool valIsIP = ( vals && valSize == sizeof(mork_ip) && sMap_ValIsIP ); - - mork_count oldSlots = ioScratch->sMapScratch_Slots; // sMap_Slots - mork_u1* oldKeys = ioScratch->sMapScratch_Keys; // sMap_Keys - mork_u1* oldVals = ioScratch->sMapScratch_Vals; // sMap_Vals - mork_u1* end = oldKeys + (keySize * oldSlots); // one byte past last key - - mork_fill fill = 0; // let's count the actual fill for a double check - - while ( oldKeys < end ) // another old key bucket to rehash if non-nil? - { - if ( !this->ProbeMapIsKeyNil(ev, oldKeys) ) // need to rehash? - { - ++fill; // this had better match sMap_Fill when we are all done - mork_u4 hash = this->ProbeMapHashMapKey(ev, oldKeys); - - mork_pos i = hash % slots; // target hash bucket - mork_pos startPos = i; // remember start to detect - - mork_u1* k = keys + (i * keySize); - while ( !this->ProbeMapIsKeyNil(ev, k) ) - { - if ( ++i >= (mork_pos)slots ) // advanced past end? need to wrap around now? - i = 0; // wrap around to first slot in map's hash table - - if ( i == startPos ) // no void slots were found anywhere in map? - { - this->WrapWithNoVoidSlotError(ev); // should never happen - return; // this is bad, and we can't go on with the rehash - } - k = keys + (i * keySize); - } - if ( keyIsIP ) // int special case? - *((mork_ip*) k) = *((const mork_ip*) oldKeys); // fast bitwise copy - else - MORK_MEMCPY(k, oldKeys, keySize); // slow bitwise copy - - if ( oldVals ) // need to copy values as well? - { - mork_size valOffset = (i * valSize); - mork_u1* v = vals + valOffset; - mork_u1* ov = oldVals + valOffset; - if ( valIsIP ) // int special case? - *((mork_ip*) v) = *((const mork_ip*) ov); // fast bitwise copy - else - MORK_MEMCPY(v, ov, valSize); // slow bitwise copy - } - } - oldKeys += keySize; // advance to next key bucket in old map - } - if ( fill != sMap_Fill ) // is the recorded value of sMap_Fill wrong? - { - ev->NewWarning("fill != sMap_Fill"); - sMap_Fill = fill; - } -} - -mork_bool morkProbeMap::grow_probe_map(morkEnv* ev) -{ - if ( sMap_Heap ) // can we grow the map? - { - mork_num newSlots = ((sMap_Slots * 4) / 3) + 1; // +25% - morkMapScratch old; // a place to temporarily hold all the old arrays - if ( this->new_slots(ev, &old, newSlots) ) // have more? - { - ++sMap_Seed; // note the map has changed - this->rehash_old_map(ev, &old); - - if ( ev->Good() ) - { - mork_count slots = sMap_Slots; - mork_num emptyReserve = (slots / 7) + 1; // keep this many empty - mork_fill maxFill = slots - emptyReserve; // new max occupancy - if ( maxFill > sMap_Fill ) // new max is bigger than old occupancy? - sProbeMap_MaxFill = maxFill; // we can install new max for fill - else - this->GrowFailsMaxFillError(ev); // we have invariant failure - } - - if ( ev->Bad() ) // rehash failed? need to revert map to last state? - this->revert_map(ev, &old); // swap the vectors back again - - old.halt_map_scratch(ev); // remember to free the old arrays - } - } - else ev->OutOfMemoryError(); - - return ev->Good(); -} - -void morkProbeMap::revert_map(morkEnv* ev, morkMapScratch* ioScratch) -{ - mork_count tempSlots = ioScratch->sMapScratch_Slots; // sMap_Slots - mork_u1* tempKeys = ioScratch->sMapScratch_Keys; // sMap_Keys - mork_u1* tempVals = ioScratch->sMapScratch_Vals; // sMap_Vals - - ioScratch->sMapScratch_Slots = sMap_Slots; - ioScratch->sMapScratch_Keys = sMap_Keys; - ioScratch->sMapScratch_Vals = sMap_Vals; - - sMap_Slots = tempSlots; - sMap_Keys = tempKeys; - sMap_Vals = tempVals; -} - -void morkProbeMap::put_probe_kv(morkEnv* ev, - const void* inAppKey, const void* inAppVal, mork_pos inPos) -{ - mork_u1* mapVal = 0; - mork_u1* mapKey = 0; - - mork_num valSize = sMap_ValSize; - if ( valSize && inAppVal ) // map holds values? caller sends value? - { - mork_u1* val = sMap_Vals + (valSize * inPos); - if ( valSize == sizeof(mork_ip) && sMap_ValIsIP ) // int special case? - *((mork_ip*) val) = *((const mork_ip*) inAppVal); - else - mapVal = val; // show possible need to call ProbeMapPushIn() - } - if ( inAppKey ) // caller sends the key? - { - mork_num keySize = sMap_KeySize; - mork_u1* key = sMap_Keys + (keySize * inPos); - if ( keySize == sizeof(mork_ip) && sMap_KeyIsIP ) // int special case? - *((mork_ip*) key) = *((const mork_ip*) inAppKey); - else - mapKey = key; // show possible need to call ProbeMapPushIn() - } - else - ev->NilPointerError(); - - if ( ( inAppVal && mapVal ) || ( inAppKey && mapKey ) ) - this->ProbeMapPushIn(ev, inAppKey, inAppVal, mapKey, mapVal); - - if ( sMap_Fill > sProbeMap_MaxFill ) - this->grow_probe_map(ev); -} - -void morkProbeMap::get_probe_kv(morkEnv* ev, - void* outAppKey, void* outAppVal, mork_pos inPos) const -{ - const mork_u1* mapVal = 0; - const mork_u1* mapKey = 0; - - mork_num valSize = sMap_ValSize; - if ( valSize && outAppVal ) // map holds values? caller wants value? - { - const mork_u1* val = sMap_Vals + (valSize * inPos); - if ( valSize == sizeof(mork_ip) && sMap_ValIsIP ) // int special case? - *((mork_ip*) outAppVal) = *((const mork_ip*) val); - else - mapVal = val; // show possible need to call ProbeMapPullOut() - } - if ( outAppKey ) // caller wants the key? - { - mork_num keySize = sMap_KeySize; - const mork_u1* key = sMap_Keys + (keySize * inPos); - if ( keySize == sizeof(mork_ip) && sMap_KeyIsIP ) // int special case? - *((mork_ip*) outAppKey) = *((const mork_ip*) key); - else - mapKey = key; // show possible need to call ProbeMapPullOut() - } - if ( ( outAppVal && mapVal ) || ( outAppKey && mapKey ) ) - this->ProbeMapPullOut(ev, mapKey, mapVal, outAppKey, outAppVal); -} - -mork_test -morkProbeMap::find_key_pos(morkEnv* ev, const void* inAppKey, - mork_u4 inHash, mork_pos* outPos) const -{ - mork_u1* k = sMap_Keys; // array of keys, each of size sMap_KeySize - mork_num size = sMap_KeySize; // number of bytes in each key - mork_count slots = sMap_Slots; // total number of key buckets - mork_pos i = inHash % slots; // target hash bucket - mork_pos startPos = i; // remember start to detect - - mork_test outTest = this->MapTest(ev, k + (i * size), inAppKey); - while ( outTest == morkTest_kMiss ) - { - if ( ++i >= (mork_pos)slots ) // advancing goes beyond end? need to wrap around now? - i = 0; // wrap around to first slot in map's hash table - - if ( i == startPos ) // no void slots were found anywhere in map? - { - this->WrapWithNoVoidSlotError(ev); // should never happen - break; // end loop on kMiss; note caller expects either kVoid or kHit - } - outTest = this->MapTest(ev, k + (i * size), inAppKey); - } - *outPos = i; - - return outTest; -} - -void morkProbeMap::probe_map_lazy_init(morkEnv* ev) -{ - if ( this->need_lazy_init() && sMap_Fill == 0 ) // pending lazy action? - { - // The constructor cannot successfully call virtual ProbeMapClearKey(), - // so we lazily do so now, when we add the first member to the map. - - mork_u1* keys = sMap_Keys; - if ( keys ) // okay to call lazy virtual clear method on new map keys? - { - if ( sProbeMap_ZeroIsClearKey ) // zero is good enough to clear keys? - { - mork_num keyVolume = sMap_Slots * sMap_KeySize; - if ( keyVolume ) - MORK_MEMSET(keys, 0, keyVolume); - } - else - this->ProbeMapClearKey(ev, keys, sMap_Slots); - } - else - this->MapNilKeysError(ev); - } - sProbeMap_LazyClearOnAdd = 0; // don't do this ever again -} - -mork_bool -morkProbeMap::MapAtPut(morkEnv* ev, - const void* inAppKey, const void* inAppVal, - void* outAppKey, void* outAppVal) -{ - mork_bool outPut = morkBool_kFalse; - - if ( this->GoodProbeMap() ) /* looks good? */ - { - if ( this->need_lazy_init() && sMap_Fill == 0 ) // pending lazy action? - this->probe_map_lazy_init(ev); - - if ( ev->Good() ) - { - mork_pos slotPos = 0; - mork_u4 hash = this->MapHash(ev, inAppKey); - mork_test test = this->find_key_pos(ev, inAppKey, hash, &slotPos); - outPut = ( test == morkTest_kHit ); - - if ( outPut ) // replacing an old assoc? no change in member count? - { - if ( outAppKey || outAppVal ) /* copy old before cobber? */ - this->get_probe_kv(ev, outAppKey, outAppVal, slotPos); - } - else // adding a new assoc increases membership by one - { - ++sMap_Fill; /* one more member in the collection */ - } - - if ( test != morkTest_kMiss ) /* found slot to hold new assoc? */ - { - ++sMap_Seed; /* note the map has changed */ - this->put_probe_kv(ev, inAppKey, inAppVal, slotPos); - } - } - } - else this->ProbeMapBadTagError(ev); - - return outPut; -} - -mork_bool -morkProbeMap::MapAt(morkEnv* ev, const void* inAppKey, - void* outAppKey, void* outAppVal) -{ - if ( this->GoodProbeMap() ) /* looks good? */ - { - if ( this->need_lazy_init() && sMap_Fill == 0 ) // pending lazy action? - this->probe_map_lazy_init(ev); - - mork_pos slotPos = 0; - mork_u4 hash = this->MapHash(ev, inAppKey); - mork_test test = this->find_key_pos(ev, inAppKey, hash, &slotPos); - if ( test == morkTest_kHit ) /* found an assoc pair for inAppKey? */ - { - this->get_probe_kv(ev, outAppKey, outAppVal, slotPos); - return morkBool_kTrue; - } - } - else this->ProbeMapBadTagError(ev); - - return morkBool_kFalse; -} - -mork_num -morkProbeMap::MapCutAll(morkEnv* ev) -{ - mork_num outCutAll = 0; - - if ( this->GoodProbeMap() ) /* looks good? */ - { - outCutAll = sMap_Fill; /* number of members cut, which is all of them */ - - if ( sMap_Keys && !sProbeMap_ZeroIsClearKey ) - this->ProbeMapClearKey(ev, sMap_Keys, sMap_Slots); - - sMap_Fill = 0; /* map now has no members */ - } - else this->ProbeMapBadTagError(ev); - - return outCutAll; -} - -// { ===== node interface ===== - -/*virtual*/ -morkProbeMap::~morkProbeMap() // assert NodeStop() finished earlier -{ - MORK_ASSERT(sMap_Keys==0); - MORK_ASSERT(sProbeMap_Tag==0); -} - -/*public virtual*/ void -morkProbeMap::CloseMorkNode(morkEnv* ev) // CloseMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseProbeMap(ev); - this->MarkShut(); - } -} - -void morkProbeMap::CloseProbeMap(morkEnv* ev) -{ - if ( this ) - { - if ( this->IsNode() ) - { - nsIMdbHeap* heap = sMap_Heap; - if ( heap ) // able to free map arrays? - { - void* block = sMap_Keys; - if ( block ) - { - heap->Free(ev->AsMdbEnv(), block); - sMap_Keys = 0; - } - - block = sMap_Vals; - if ( block ) - { - heap->Free(ev->AsMdbEnv(), block); - sMap_Vals = 0; - } - } - sMap_Keys = 0; - sMap_Vals = 0; - - this->CloseNode(ev); - sProbeMap_Tag = 0; - sProbeMap_MaxFill = 0; - - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -void* -morkProbeMap::clear_alloc(morkEnv* ev, mork_size inSize) -{ - void* p = 0; - nsIMdbHeap* heap = sMap_Heap; - if ( heap ) - { - if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p ) - { - MORK_MEMSET(p, 0, inSize); - return p; - } - } - else - ev->NilPointerError(); - - return (void*) 0; -} - -/*| map_new_keys: allocate an array of inSlots new keys filled with zero. -**| (cf IronDoc's FeHashTable_new_keys()) -|*/ -mork_u1* -morkProbeMap::map_new_keys(morkEnv* ev, mork_num inSlots) -{ - mork_num size = inSlots * sMap_KeySize; - return (mork_u1*) this->clear_alloc(ev, size); -} - -/*| map_new_vals: allocate an array of inSlots new values filled with zero. -**| When values are zero sized, we just return a null pointer. -**| -**| (cf IronDoc's FeHashTable_new_values()) -|*/ -mork_u1* -morkProbeMap::map_new_vals(morkEnv* ev, mork_num inSlots) -{ - mork_u1* values = 0; - mork_num size = inSlots * sMap_ValSize; - if ( size ) - values = (mork_u1*) this->clear_alloc(ev, size); - return values; -} - - -void morkProbeMap::MapSeedOutOfSyncError(morkEnv* ev) -{ - ev->NewError("sMap_Seed out of sync"); -} - -void morkProbeMap::MapFillUnderflowWarning(morkEnv* ev) -{ - ev->NewWarning("sMap_Fill underflow"); -} - -void morkProbeMap::MapNilKeysError(morkEnv* ev) -{ - ev->NewError("nil sMap_Keys"); -} - -void morkProbeMap::MapZeroKeySizeError(morkEnv* ev) -{ - ev->NewError("zero sMap_KeySize"); -} - -/*static*/ -void morkProbeMap::ProbeMapCutError(morkEnv* ev) -{ - ev->NewError("morkProbeMap cannot cut"); -} - - -void morkProbeMap::init_probe_map(morkEnv* ev, mork_size inSlots) -{ - // Note we cannot successfully call virtual ProbeMapClearKey() when we - // call init_probe_map() inside the constructor; so we leave this problem - // to the caller. (The constructor will call ProbeMapClearKey() later - // after setting a suitable lazy flag to show this action is pending.) - - if ( ev->Good() ) - { - morkMapScratch old; - - if ( inSlots < 7 ) // capacity too small? - inSlots = 7; // increase to reasonable minimum - else if ( inSlots > (128 * 1024) ) // requested capacity too big? - inSlots = (128 * 1024); // decrease to reasonable maximum - - if ( this->new_slots(ev, &old, inSlots) ) - sProbeMap_Tag = morkProbeMap_kTag; - - mork_count slots = sMap_Slots; - mork_num emptyReserve = (slots / 7) + 1; // keep this many empty - sProbeMap_MaxFill = slots - emptyReserve; - - MORK_MEMSET(&old, 0, sizeof(morkMapScratch)); // don't bother halting - } -} - -mork_bool -morkProbeMap::new_slots(morkEnv* ev, morkMapScratch* old, mork_num inSlots) -{ - mork_bool outNew = morkBool_kFalse; - - // Note we cannot successfully call virtual ProbeMapClearKey() when we - // call new_slots() inside the constructor; so we leave this problem - // to the caller. (The constructor will call ProbeMapClearKey() later - // after setting a suitable lazy flag to show this action is pending.) - - // allocate every new array before we continue: - mork_u1* newKeys = this->map_new_keys(ev, inSlots); - mork_u1* newVals = this->map_new_vals(ev, inSlots); - - // okay for newVals to be null when values are zero sized? - mork_bool okayValues = ( newVals || !sMap_ValSize ); - - if ( newKeys && okayValues ) - { - outNew = morkBool_kTrue; // we created every array needed - - // init mapScratch using slots from current map: - old->sMapScratch_Heap = sMap_Heap; - - old->sMapScratch_Slots = sMap_Slots; - old->sMapScratch_Keys = sMap_Keys; - old->sMapScratch_Vals = sMap_Vals; - - // replace all map array slots using the newly allocated members: - ++sMap_Seed; // the map has changed - sMap_Keys = newKeys; - sMap_Vals = newVals; - sMap_Slots = inSlots; - } - else // free any allocations if only partially successful - { - nsIMdbHeap* heap = sMap_Heap; - if ( newKeys ) - heap->Free(ev->AsMdbEnv(), newKeys); - if ( newVals ) - heap->Free(ev->AsMdbEnv(), newVals); - - MORK_MEMSET(old, 0, sizeof(morkMapScratch)); // zap scratch space - } - - return outNew; -} - -void -morkProbeMap::clear_probe_map(morkEnv* ev, nsIMdbHeap* ioMapHeap) -{ - sProbeMap_Tag = 0; - sMap_Seed = 0; - sMap_Slots = 0; - sMap_Fill = 0; - sMap_Keys = 0; - sMap_Vals = 0; - sProbeMap_MaxFill = 0; - - sMap_Heap = ioMapHeap; - if ( !ioMapHeap ) - ev->NilPointerError(); -} - -morkProbeMap::morkProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, - mork_size inKeySize, mork_size inValSize, - nsIMdbHeap* ioMapHeap, mork_size inSlots, - mork_bool inZeroIsClearKey) - -: morkNode(ev, inUsage, ioNodeHeap) -, sMap_Heap( ioMapHeap ) - -, sMap_Keys( 0 ) -, sMap_Vals( 0 ) - -, sMap_Seed( 0 ) // change count of members or structure - -, sMap_Slots( 0 ) // count of slots in the hash table -, sMap_Fill( 0 ) // number of used slots in the hash table - -, sMap_KeySize( 0 ) // size of each key (cannot be zero) -, sMap_ValSize( 0 ) // size of each val (zero allowed) - -, sMap_KeyIsIP( morkBool_kFalse ) // sMap_KeySize == sizeof(mork_ip) -, sMap_ValIsIP( morkBool_kFalse ) // sMap_ValSize == sizeof(mork_ip) - -, sProbeMap_MaxFill( 0 ) -, sProbeMap_LazyClearOnAdd( 0 ) -, sProbeMap_ZeroIsClearKey( inZeroIsClearKey ) -, sProbeMap_Tag( 0 ) -{ - // Note we cannot successfully call virtual ProbeMapClearKey() when we - // call init_probe_map() inside the constructor; so we leave this problem - // to the caller. (The constructor will call ProbeMapClearKey() later - // after setting a suitable lazy flag to show this action is pending.) - - if ( ev->Good() ) - { - this->clear_probe_map(ev, ioMapHeap); - if ( ev->Good() ) - { - sMap_KeySize = inKeySize; - sMap_ValSize = inValSize; - sMap_KeyIsIP = ( inKeySize == sizeof(mork_ip) ); - sMap_ValIsIP = ( inValSize == sizeof(mork_ip) ); - - this->init_probe_map(ev, inSlots); - if ( ev->Good() ) - { - if ( !inZeroIsClearKey ) // must lazy clear later with virtual method? - sProbeMap_LazyClearOnAdd = morkProbeMap_kLazyClearOnAdd; - - mNode_Derived = morkDerived_kProbeMap; - } - } - } -} - -/*============================================================================*/ - -/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b) -morkProbeMap::MapTest(morkEnv* ev, - const void* inMapKey, const void* inAppKey) const - // Note inMapKey is always a key already stored in the map, while inAppKey - // is always a method argument parameter from a client method call. - // This matters the most in morkProbeMap subclasses, which have the - // responsibility of putting 'app' keys into slots for 'map' keys, and - // the bit pattern representation might be different in such cases. - // morkTest_kHit means that inMapKey equals inAppKey (and this had better - // also imply that hash(inMapKey) == hash(inAppKey)). - // morkTest_kMiss means that inMapKey does NOT equal inAppKey (but this - // implies nothing at all about hash(inMapKey) and hash(inAppKey)). - // morkTest_kVoid means that inMapKey is not a valid key bit pattern, - // which means that key slot in the map is not being used. Note that - // kVoid is only expected as a return value in morkProbeMap subclasses, - // because morkProbeMap must ask whether a key slot is used or not. - // morkChainMap however, always knows when a key slot is used, so only - // key slots expected to have valid bit patterns will be presented to - // the MapTest() methods for morkChainMap subclasses. - // - // NOTE: it is very important that subclasses correctly return the value - // morkTest_kVoid whenever the slot for inMapKey contains a bit pattern - // that means the slot is not being used, because this is the only way a - // probe map can terminate an unsuccessful search for a key in the map. -{ - mork_size keySize = sMap_KeySize; - if ( keySize == sizeof(mork_ip) && sMap_KeyIsIP ) - { - mork_ip mapKey = *((const mork_ip*) inMapKey); - if ( mapKey == *((const mork_ip*) inAppKey) ) - return morkTest_kHit; - else - { - return ( mapKey )? morkTest_kMiss : morkTest_kVoid; - } - } - else - { - mork_bool allSame = morkBool_kTrue; - mork_bool allZero = morkBool_kTrue; - const mork_u1* ak = (const mork_u1*) inAppKey; - const mork_u1* mk = (const mork_u1*) inMapKey; - const mork_u1* end = mk + keySize; - --mk; // prepare for preincrement: - while ( ++mk < end ) - { - mork_u1 byte = *mk; - if ( byte ) // any nonzero byte in map key means slot is not nil? - allZero = morkBool_kFalse; - if ( byte != *ak++ ) // bytes differ in map and app keys? - allSame = morkBool_kFalse; - } - if ( allSame ) - return morkTest_kHit; - else - return ( allZero )? morkTest_kVoid : morkTest_kMiss; - } -} - -/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b) -morkProbeMap::MapHash(morkEnv* ev, const void* inAppKey) const -{ - mork_size keySize = sMap_KeySize; - if ( keySize == sizeof(mork_ip) && sMap_KeyIsIP ) - { - return *((const mork_ip*) inAppKey); - } - else - { - const mork_u1* key = (const mork_u1*) inAppKey; - const mork_u1* end = key + keySize; - --key; // prepare for preincrement: - while ( ++key < end ) - { - if ( *key ) // any nonzero byte in map key means slot is not nil? - return morkBool_kFalse; - } - return morkBool_kTrue; - } - return (mork_u4) NS_PTR_TO_INT32(inAppKey); -} - - -/*============================================================================*/ - -/*virtual*/ mork_u4 -morkProbeMap::ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const - // ProbeMapHashMapKey() does logically the same thing as MapHash(), and - // the default implementation actually calls virtual MapHash(). However, - // Subclasses must override this method whenever the formats of keys in - // the map differ from app keys outside the map, because MapHash() only - // works on keys in 'app' format, while ProbeMapHashMapKey() only works - // on keys in 'map' format. This method is called in order to rehash all - // map keys when a map is grown, and this causes all old map members to - // move into new slot locations. - // - // Note it is absolutely imperative that a hash for a key in 'map' format - // be exactly the same the hash of the same key in 'app' format, or else - // maps will seem corrupt later when keys in 'app' format cannot be found. -{ - return this->MapHash(ev, inMapKey); -} - -/*virtual*/ mork_bool -morkProbeMap::ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey) - // ProbeMapIsKeyNil() must say whether the representation of logical 'nil' - // is currently found inside the key at ioMapKey, for a key found within - // the map. The the map iterator uses this method to find map keys that - // are actually being used for valid map associations; otherwise the - // iterator cannot determine which map slots actually denote used keys. - // The default method version returns true if all the bits equal zero. -{ - if ( sMap_KeySize == sizeof(mork_ip) && sMap_KeyIsIP ) - { - return !*((const mork_ip*) ioMapKey); - } - else - { - const mork_u1* key = (const mork_u1*) ioMapKey; - const mork_u1* end = key + sMap_KeySize; - --key; // prepare for preincrement: - while ( ++key < end ) - { - if ( *key ) // any nonzero byte in map key means slot is not nil? - return morkBool_kFalse; - } - return morkBool_kTrue; - } -} - -/*virtual*/ void -morkProbeMap::ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - void* ioMapKey, mork_count inKeyCount) // array of keys inside map - // ProbeMapClearKey() must put some representation of logical 'nil' into - // every key slot in the map, such that MapTest() will later recognize - // that this bit pattern shows each key slot is not actually being used. - // - // This method is typically called whenever the map is either created or - // grown into a larger size, where ioMapKey is a pointer to an array of - // inKeyCount keys, where each key is this->MapKeySize() bytes in size. - // Note that keys are assumed immediately adjacent with no padding, so - // if any alignment requirements must be met, then subclasses should have - // already accounted for this when specifying a key size in the map. - // - // Since this method will be called when a map is being grown in size, - // nothing should be assumed about the state slots of the map, since the - // ioMapKey array might not yet live in sMap_Keys, and the array length - // inKeyCount might not yet live in sMap_Slots. However, the value kept - // in sMap_KeySize never changes, so this->MapKeySize() is always correct. -{ - if ( ioMapKey && inKeyCount ) - { - MORK_MEMSET(ioMapKey, 0, (inKeyCount * sMap_KeySize)); - } - else - ev->NilPointerWarning(); -} - -/*virtual*/ void -morkProbeMap::ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - const void* inAppKey, const void* inAppVal, // (key,val) outside map - void* outMapKey, void* outMapVal) // (key,val) inside map - // This method actually puts keys and vals in the map in suitable format. - // - // ProbeMapPushIn() must copy a caller key and value in 'app' format - // into the map slots provided, which are in 'map' format. When the - // 'app' and 'map' formats are identical, then this is just a bitwise - // copy of this->MapKeySize() key bytes and this->MapValSize() val bytes, - // and this is exactly what the default implementation performs. However, - // if 'app' and 'map' formats are different, and MapTest() depends on this - // difference in format, then subclasses must override this method to do - // whatever is necessary to store the input app key in output map format. - // - // Do NOT write more than this->MapKeySize() bytes of a map key, or more - // than this->MapValSize() bytes of a map val, or corruption might ensue. - // - // The inAppKey and inAppVal parameters are the same ones passed into a - // call to MapAtPut(), and the outMapKey and outMapVal parameters are ones - // determined by how the map currently positions key inAppKey in the map. - // - // Note any key or val parameter can be a null pointer, in which case - // this method must do nothing with those parameters. In particular, do - // no key move at all when either inAppKey or outMapKey is nil, and do - // no val move at all when either inAppVal or outMapVal is nil. Note that - // outMapVal should always be nil when this->MapValSize() is nil. -{ -} - -/*virtual*/ void -morkProbeMap::ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - const void* inMapKey, const void* inMapVal, // (key,val) inside map - void* outAppKey, void* outAppVal) const // (key,val) outside map - // This method actually gets keys and vals from the map in suitable format. - // - // ProbeMapPullOut() must copy a key and val in 'map' format into the - // caller key and val slots provided, which are in 'app' format. When the - // 'app' and 'map' formats are identical, then this is just a bitwise - // copy of this->MapKeySize() key bytes and this->MapValSize() val bytes, - // and this is exactly what the default implementation performs. However, - // if 'app' and 'map' formats are different, and MapTest() depends on this - // difference in format, then subclasses must override this method to do - // whatever is necessary to store the input map key in output app format. - // - // The outAppKey and outAppVal parameters are the same ones passed into a - // call to either MapAtPut() or MapAt(), while inMapKey and inMapVal are - // determined by how the map currently positions the target key in the map. - // - // Note any key or val parameter can be a null pointer, in which case - // this method must do nothing with those parameters. In particular, do - // no key move at all when either inMapKey or outAppKey is nil, and do - // no val move at all when either inMapVal or outAppVal is nil. Note that - // inMapVal should always be nil when this->MapValSize() is nil. -{ -} - - -/*============================================================================*/ -/* morkProbeMapIter */ - -morkProbeMapIter::morkProbeMapIter(morkEnv* ev, morkProbeMap* ioMap) -: sProbeMapIter_Map( 0 ) -, sProbeMapIter_Seed( 0 ) -, sProbeMapIter_HereIx( morkProbeMapIter_kBeforeIx ) -{ - if ( ioMap ) - { - if ( ioMap->GoodProbeMap() ) - { - if ( ioMap->need_lazy_init() ) // pending lazy action? - ioMap->probe_map_lazy_init(ev); - - sProbeMapIter_Map = ioMap; - sProbeMapIter_Seed = ioMap->sMap_Seed; - } - else ioMap->ProbeMapBadTagError(ev); - } - else ev->NilPointerError(); -} - -void morkProbeMapIter::CloseMapIter(morkEnv* ev) -{ - MORK_USED_1(ev); - sProbeMapIter_Map = 0; - sProbeMapIter_Seed = 0; - - sProbeMapIter_HereIx = morkProbeMapIter_kAfterIx; -} - -morkProbeMapIter::morkProbeMapIter( ) -// zero most slots; caller must call InitProbeMapIter() -{ - sProbeMapIter_Map = 0; - sProbeMapIter_Seed = 0; - - sProbeMapIter_HereIx = morkProbeMapIter_kBeforeIx; -} - -void morkProbeMapIter::InitProbeMapIter(morkEnv* ev, morkProbeMap* ioMap) -{ - sProbeMapIter_Map = 0; - sProbeMapIter_Seed = 0; - - sProbeMapIter_HereIx = morkProbeMapIter_kBeforeIx; - - if ( ioMap ) - { - if ( ioMap->GoodProbeMap() ) - { - if ( ioMap->need_lazy_init() ) // pending lazy action? - ioMap->probe_map_lazy_init(ev); - - sProbeMapIter_Map = ioMap; - sProbeMapIter_Seed = ioMap->sMap_Seed; - } - else ioMap->ProbeMapBadTagError(ev); - } - else ev->NilPointerError(); -} - -mork_bool morkProbeMapIter::IterFirst(morkEnv* ev, - void* outAppKey, void* outAppVal) -{ - sProbeMapIter_HereIx = morkProbeMapIter_kAfterIx; // default to done - morkProbeMap* map = sProbeMapIter_Map; - - if ( map && map->GoodProbeMap() ) /* looks good? */ - { - sProbeMapIter_Seed = map->sMap_Seed; /* sync the seeds */ - - mork_u1* k = map->sMap_Keys; // array of keys, each of size sMap_KeySize - mork_num size = map->sMap_KeySize; // number of bytes in each key - mork_count slots = map->sMap_Slots; // total number of key buckets - mork_pos here = 0; // first hash bucket - - while ( here < (mork_pos)slots ) - { - if ( !map->ProbeMapIsKeyNil(ev, k + (here * size)) ) - { - map->get_probe_kv(ev, outAppKey, outAppVal, here); - - sProbeMapIter_HereIx = (mork_i4) here; - return morkBool_kTrue; - } - ++here; // next bucket - } - } - else map->ProbeMapBadTagError(ev); - - return morkBool_kFalse; -} - -mork_bool morkProbeMapIter::IterNext(morkEnv* ev, - void* outAppKey, void* outAppVal) -{ - morkProbeMap* map = sProbeMapIter_Map; - - if ( map && map->GoodProbeMap() ) /* looks good? */ - { - if ( sProbeMapIter_Seed == map->sMap_Seed ) /* in sync? */ - { - if ( sProbeMapIter_HereIx != morkProbeMapIter_kAfterIx ) - { - mork_pos here = (mork_pos) sProbeMapIter_HereIx; - if ( sProbeMapIter_HereIx < 0 ) - here = 0; - else - ++here; - - sProbeMapIter_HereIx = morkProbeMapIter_kAfterIx; // default to done - - mork_u1* k = map->sMap_Keys; // key array, each of size sMap_KeySize - mork_num size = map->sMap_KeySize; // number of bytes in each key - mork_count slots = map->sMap_Slots; // total number of key buckets - - while ( here < (mork_pos)slots ) - { - if ( !map->ProbeMapIsKeyNil(ev, k + (here * size)) ) - { - map->get_probe_kv(ev, outAppKey, outAppVal, here); - - sProbeMapIter_HereIx = (mork_i4) here; - return morkBool_kTrue; - } - ++here; // next bucket - } - } - } - else map->MapSeedOutOfSyncError(ev); - } - else map->ProbeMapBadTagError(ev); - - return morkBool_kFalse; -} - -mork_bool morkProbeMapIter::IterHere(morkEnv* ev, - void* outAppKey, void* outAppVal) -{ - morkProbeMap* map = sProbeMapIter_Map; - - if ( map && map->GoodProbeMap() ) /* looks good? */ - { - if ( sProbeMapIter_Seed == map->sMap_Seed ) /* in sync? */ - { - mork_pos here = (mork_pos) sProbeMapIter_HereIx; - mork_count slots = map->sMap_Slots; // total number of key buckets - if ( sProbeMapIter_HereIx >= 0 && (here < (mork_pos)slots)) - { - mork_u1* k = map->sMap_Keys; // key array, each of size sMap_KeySize - mork_num size = map->sMap_KeySize; // number of bytes in each key - - if ( !map->ProbeMapIsKeyNil(ev, k + (here * size)) ) - { - map->get_probe_kv(ev, outAppKey, outAppVal, here); - return morkBool_kTrue; - } - } - } - else map->MapSeedOutOfSyncError(ev); - } - else map->ProbeMapBadTagError(ev); - - return morkBool_kFalse; -} - -mork_change* -morkProbeMapIter::First(morkEnv* ev, void* outKey, void* outVal) -{ - if ( this->IterFirst(ev, outKey, outVal) ) - return &sProbeMapIter_Change; - - return (mork_change*) 0; -} - -mork_change* -morkProbeMapIter::Next(morkEnv* ev, void* outKey, void* outVal) -{ - if ( this->IterNext(ev, outKey, outVal) ) - return &sProbeMapIter_Change; - - return (mork_change*) 0; -} - -mork_change* -morkProbeMapIter::Here(morkEnv* ev, void* outKey, void* outVal) -{ - if ( this->IterHere(ev, outKey, outVal) ) - return &sProbeMapIter_Change; - - return (mork_change*) 0; -} - -mork_change* -morkProbeMapIter::CutHere(morkEnv* ev, void* outKey, void* outVal) -{ - morkProbeMap::ProbeMapCutError(ev); - - return (mork_change*) 0; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// NOTE: the following methods ONLY work for sMap_ValIsIP pointer values. -// (Note the implied assumption that zero is never a good value pattern.) - -void* morkProbeMapIter::IterFirstVal(morkEnv* ev, void* outKey) -// equivalent to { void* v=0; this->IterFirst(ev, outKey, &v); return v; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_ValIsIP ) - { - void* v = 0; - this->IterFirst(ev, outKey, &v); - return v; - } - else - map->MapValIsNotIPError(ev); - } - return (void*) 0; -} - -void* morkProbeMapIter::IterNextVal(morkEnv* ev, void* outKey) -// equivalent to { void* v=0; this->IterNext(ev, outKey, &v); return v; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_ValIsIP ) - { - void* v = 0; - this->IterNext(ev, outKey, &v); - return v; - } - else - map->MapValIsNotIPError(ev); - } - return (void*) 0; -} - -void* morkProbeMapIter::IterHereVal(morkEnv* ev, void* outKey) -// equivalent to { void* v=0; this->IterHere(ev, outKey, &v); return v; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_ValIsIP ) - { - void* v = 0; - this->IterHere(ev, outKey, &v); - return v; - } - else - map->MapValIsNotIPError(ev); - } - return (void*) 0; -} - -// NOTE: the following methods ONLY work for sMap_KeyIsIP pointer values. -// (Note the implied assumption that zero is never a good key pattern.) - -void* morkProbeMapIter::IterFirstKey(morkEnv* ev) -// equivalent to { void* k=0; this->IterFirst(ev, &k, 0); return k; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_KeyIsIP ) - { - void* k = 0; - this->IterFirst(ev, &k, (void*) 0); - return k; - } - else - map->MapKeyIsNotIPError(ev); - } - return (void*) 0; -} - -void* morkProbeMapIter::IterNextKey(morkEnv* ev) -// equivalent to { void* k=0; this->IterNext(ev, &k, 0); return k; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_KeyIsIP ) - { - void* k = 0; - this->IterNext(ev, &k, (void*) 0); - return k; - } - else - map->MapKeyIsNotIPError(ev); - } - return (void*) 0; -} - -void* morkProbeMapIter::IterHereKey(morkEnv* ev) -// equivalent to { void* k=0; this->IterHere(ev, &k, 0); return k; } -{ - morkProbeMap* map = sProbeMapIter_Map; - if ( map ) - { - if ( map->sMap_KeyIsIP ) - { - void* k = 0; - this->IterHere(ev, &k, (void*) 0); - return k; - } - else - map->MapKeyIsNotIPError(ev); - } - return (void*) 0; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkProbeMap.h b/db/mork/src/morkProbeMap.h deleted file mode 100644 index 33e8378fd4d1..000000000000 --- a/db/mork/src/morkProbeMap.h +++ /dev/null @@ -1,431 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// This code is a port to NS Mork from public domain Mithril C++ sources. -// Note many code comments here come verbatim from cut-and-pasted Mithril. -// In many places, code is identical; Mithril versions stay public domain. -// Changes in porting are mainly class type and scalar type name changes. - -#ifndef _MORKPROBEMAP_ -#define _MORKPROBEMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class morkMapScratch { // utility class used by map subclasses -public: - nsIMdbHeap* sMapScratch_Heap; // cached sMap_Heap - mork_count sMapScratch_Slots; // cached sMap_Slots - - mork_u1* sMapScratch_Keys; // cached sMap_Keys - mork_u1* sMapScratch_Vals; // cached sMap_Vals - -public: - void halt_map_scratch(morkEnv* ev); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kProbeMap 0x7072 /* ascii 'pr' */ -#define morkProbeMap_kTag 0x70724D50 /* ascii 'prMP' */ - -#define morkProbeMap_kLazyClearOnAdd ((mork_u1) 'c') - -class morkProbeMap: public morkNode { - -protected: - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -protected: - // { begin morkMap slots - nsIMdbHeap* sMap_Heap; // strong ref to heap allocating all space - - mork_u1* sMap_Keys; - mork_u1* sMap_Vals; - - mork_count sMap_Seed; // change count of members or structure - - mork_count sMap_Slots; // count of slots in the hash table - mork_fill sMap_Fill; // number of used slots in the hash table - - mork_size sMap_KeySize; // size of each key (cannot be zero) - mork_size sMap_ValSize; // size of each val (zero allowed) - - mork_bool sMap_KeyIsIP; // sMap_KeySize == sizeof(mork_ip) - mork_bool sMap_ValIsIP; // sMap_ValSize == sizeof(mork_ip) - mork_u1 sMap_Pad[ 2 ]; // for u4 alignment - // } end morkMap slots - - friend class morkProbeMapIter; // for access to protected slots - -public: // getters - mork_count MapSeed() const { return sMap_Seed; } - - mork_count MapSlots() const { return sMap_Slots; } - mork_fill MapFill() const { return sMap_Fill; } - - mork_size MapKeySize() const { return sMap_KeySize; } - mork_size MapValSize() const { return sMap_ValSize; } - - mork_bool MapKeyIsIP() const { return sMap_KeyIsIP; } - mork_bool MapValIsIP() const { return sMap_ValIsIP; } - -protected: // slots - // { begin morkProbeMap slots - - mork_fill sProbeMap_MaxFill; // max sMap_Fill before map must grow - - mork_u1 sProbeMap_LazyClearOnAdd; // true if kLazyClearOnAdd - mork_bool sProbeMap_ZeroIsClearKey; // zero is adequate to clear keys - mork_u1 sProbeMap_Pad[ 2 ]; // for u4 alignment - - mork_u4 sProbeMap_Tag; - - // } end morkProbeMap slots - -public: // lazy clear on add - - mork_bool need_lazy_init() const - { return sProbeMap_LazyClearOnAdd == morkProbeMap_kLazyClearOnAdd; } - -public: // typing - mork_bool GoodProbeMap() const - { return sProbeMap_Tag == morkProbeMap_kTag; } - -protected: // utilities - - void* clear_alloc(morkEnv* ev, mork_size inSize); - - mork_u1* map_new_vals(morkEnv* ev, mork_num inSlots); - mork_u1* map_new_keys(morkEnv* ev, mork_num inSlots); - - void clear_probe_map(morkEnv* ev, nsIMdbHeap* ioMapHeap); - void init_probe_map(morkEnv* ev, mork_size inSlots); - void probe_map_lazy_init(morkEnv* ev); - - mork_bool new_slots(morkEnv* ev, morkMapScratch* old, mork_num inSlots); - - mork_test find_key_pos(morkEnv* ev, const void* inAppKey, - mork_u4 inHash, mork_pos* outPos) const; - - void put_probe_kv(morkEnv* ev, - const void* inAppKey, const void* inAppVal, mork_pos inPos); - void get_probe_kv(morkEnv* ev, - void* outAppKey, void* outAppVal, mork_pos inPos) const; - - mork_bool grow_probe_map(morkEnv* ev); - void rehash_old_map(morkEnv* ev, morkMapScratch* ioScratch); - void revert_map(morkEnv* ev, morkMapScratch* ioScratch); - -public: // errors - void ProbeMapBadTagError(morkEnv* ev) const; - void WrapWithNoVoidSlotError(morkEnv* ev) const; - void GrowFailsMaxFillError(morkEnv* ev) const; - void MapKeyIsNotIPError(morkEnv* ev) const; - void MapValIsNotIPError(morkEnv* ev) const; - - void MapNilKeysError(morkEnv* ev); - void MapZeroKeySizeError(morkEnv* ev); - - void MapSeedOutOfSyncError(morkEnv* ev); - void MapFillUnderflowWarning(morkEnv* ev); - - static void ProbeMapCutError(morkEnv* ev); - - // { ===== begin morkMap methods ===== -public: - - virtual mork_test // hit(a,b) implies hash(a) == hash(b) - MapTest(morkEnv* ev, const void* inMapKey, const void* inAppKey) const; - // Note inMapKey is always a key already stored in the map, while inAppKey - // is always a method argument parameter from a client method call. - // This matters the most in morkProbeMap subclasses, which have the - // responsibility of putting 'app' keys into slots for 'map' keys, and - // the bit pattern representation might be different in such cases. - // morkTest_kHit means that inMapKey equals inAppKey (and this had better - // also imply that hash(inMapKey) == hash(inAppKey)). - // morkTest_kMiss means that inMapKey does NOT equal inAppKey (but this - // implies nothing at all about hash(inMapKey) and hash(inAppKey)). - // morkTest_kVoid means that inMapKey is not a valid key bit pattern, - // which means that key slot in the map is not being used. Note that - // kVoid is only expected as a return value in morkProbeMap subclasses, - // because morkProbeMap must ask whether a key slot is used or not. - // morkChainMap however, always knows when a key slot is used, so only - // key slots expected to have valid bit patterns will be presented to - // the MapTest() methods for morkChainMap subclasses. - // - // NOTE: it is very important that subclasses correctly return the value - // morkTest_kVoid whenever the slot for inMapKey contains a bit pattern - // that means the slot is not being used, because this is the only way a - // probe map can terminate an unsuccessful search for a key in the map. - - virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) - MapHash(morkEnv* ev, const void* inAppKey) const; - - virtual mork_bool - MapAtPut(morkEnv* ev, const void* inAppKey, const void* inAppVal, - void* outAppKey, void* outAppVal); - - virtual mork_bool - MapAt(morkEnv* ev, const void* inAppKey, void* outAppKey, void* outAppVal); - - virtual mork_num - MapCutAll(morkEnv* ev); - // } ===== end morkMap methods ===== - - - // { ===== begin morkProbeMap methods ===== -public: - - virtual mork_u4 - ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const; - // ProbeMapHashMapKey() does logically the same thing as MapHash(), and - // the default implementation actually calls virtual MapHash(). However, - // Subclasses must override this method whenever the formats of keys in - // the map differ from app keys outside the map, because MapHash() only - // works on keys in 'app' format, while ProbeMapHashMapKey() only works - // on keys in 'map' format. This method is called in order to rehash all - // map keys when a map is grown, and this causes all old map members to - // move into new slot locations. - // - // Note it is absolutely imperative that a hash for a key in 'map' format - // be exactly the same the hash of the same key in 'app' format, or else - // maps will seem corrupt later when keys in 'app' format cannot be found. - - virtual mork_bool - ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); - // ProbeMapIsKeyNil() must say whether the representation of logical 'nil' - // is currently found inside the key at ioMapKey, for a key found within - // the map. The the map iterator uses this method to find map keys that - // are actually being used for valid map associations; otherwise the - // iterator cannot determine which map slots actually denote used keys. - // The default method version returns true if all the bits equal zero. - - virtual void - ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - void* ioMapKey, mork_count inKeyCount); // array of keys inside map - // ProbeMapClearKey() must put some representation of logical 'nil' into - // every key slot in the map, such that MapTest() will later recognize - // that this bit pattern shows each key slot is not actually being used. - // - // This method is typically called whenever the map is either created or - // grown into a larger size, where ioMapKey is a pointer to an array of - // inKeyCount keys, where each key is this->MapKeySize() bytes in size. - // Note that keys are assumed immediately adjacent with no padding, so - // if any alignment requirements must be met, then subclasses should have - // already accounted for this when specifying a key size in the map. - // - // Since this method will be called when a map is being grown in size, - // nothing should be assumed about the state slots of the map, since the - // ioMapKey array might not yet live in sMap_Keys, and the array length - // inKeyCount might not yet live in sMap_Slots. However, the value kept - // in sMap_KeySize never changes, so this->MapKeySize() is always correct. - - virtual void - ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - const void* inAppKey, const void* inAppVal, // (key,val) outside map - void* outMapKey, void* outMapVal); // (key,val) inside map - // This method actually puts keys and vals in the map in suitable format. - // - // ProbeMapPushIn() must copy a caller key and value in 'app' format - // into the map slots provided, which are in 'map' format. When the - // 'app' and 'map' formats are identical, then this is just a bitwise - // copy of this->MapKeySize() key bytes and this->MapValSize() val bytes, - // and this is exactly what the default implementation performs. However, - // if 'app' and 'map' formats are different, and MapTest() depends on this - // difference in format, then subclasses must override this method to do - // whatever is necessary to store the input app key in output map format. - // - // Do NOT write more than this->MapKeySize() bytes of a map key, or more - // than this->MapValSize() bytes of a map val, or corruption might ensue. - // - // The inAppKey and inAppVal parameters are the same ones passed into a - // call to MapAtPut(), and the outMapKey and outMapVal parameters are ones - // determined by how the map currently positions key inAppKey in the map. - // - // Note any key or val parameter can be a null pointer, in which case - // this method must do nothing with those parameters. In particular, do - // no key move at all when either inAppKey or outMapKey is nil, and do - // no val move at all when either inAppVal or outMapVal is nil. Note that - // outMapVal should always be nil when this->MapValSize() is nil. - - virtual void - ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - const void* inMapKey, const void* inMapVal, // (key,val) inside map - void* outAppKey, void* outAppVal) const; // (key,val) outside map - // This method actually gets keys and vals from the map in suitable format. - // - // ProbeMapPullOut() must copy a key and val in 'map' format into the - // caller key and val slots provided, which are in 'app' format. When the - // 'app' and 'map' formats are identical, then this is just a bitwise - // copy of this->MapKeySize() key bytes and this->MapValSize() val bytes, - // and this is exactly what the default implementation performs. However, - // if 'app' and 'map' formats are different, and MapTest() depends on this - // difference in format, then subclasses must override this method to do - // whatever is necessary to store the input map key in output app format. - // - // The outAppKey and outAppVal parameters are the same ones passed into a - // call to either MapAtPut() or MapAt(), while inMapKey and inMapVal are - // determined by how the map currently positions the target key in the map. - // - // Note any key or val parameter can be a null pointer, in which case - // this method must do nothing with those parameters. In particular, do - // no key move at all when either inMapKey or outAppKey is nil, and do - // no val move at all when either inMapVal or outAppVal is nil. Note that - // inMapVal should always be nil when this->MapValSize() is nil. - - // } ===== end morkProbeMap methods ===== - - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseProbeMap() only if open - virtual ~morkProbeMap(); // assert that CloseProbeMap() executed earlier - -public: // morkProbeMap construction & destruction - morkProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, - mork_size inKeySize, mork_size inValSize, - nsIMdbHeap* ioMapHeap, mork_size inSlots, - mork_bool inZeroIsClearKey); - - void CloseProbeMap(morkEnv* ev); // called by - -public: // dynamic type identification - mork_bool IsProbeMap() const - { return IsNode() && mNode_Derived == morkDerived_kProbeMap; } -// } ===== end morkNode methods ===== - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakMap(morkMap* me, - morkEnv* ev, morkMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongMap(morkMap* me, - morkEnv* ev, morkMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -/*============================================================================*/ -/* morkProbeMapIter */ - -#define morkProbeMapIter_kBeforeIx ((mork_i4) -1) /* before first member */ -#define morkProbeMapIter_kAfterIx ((mork_i4) -2) /* after last member */ - -class morkProbeMapIter { - -protected: - morkProbeMap* sProbeMapIter_Map; // nonref - mork_num sProbeMapIter_Seed; // iter's cached copy of map's seed - - mork_i4 sProbeMapIter_HereIx; - - mork_change sProbeMapIter_Change; // morkMapIter API simulation dummy - mork_u1 sProbeMapIter_Pad[ 3 ]; // for u4 alignment - -public: - morkProbeMapIter(morkEnv* ev, morkProbeMap* ioMap); - void CloseMapIter(morkEnv* ev); - - morkProbeMapIter( ); // zero most slots; caller must call InitProbeMapIter() - -protected: // protected so subclasses must provide suitable typesafe inlines: - - void InitProbeMapIter(morkEnv* ev, morkProbeMap* ioMap); - - void InitMapIter(morkEnv* ev, morkProbeMap* ioMap) // morkMapIter compatibility - { this->InitProbeMapIter(ev, ioMap); } - - mork_bool IterFirst(morkEnv* ev, void* outKey, void* outVal); - mork_bool IterNext(morkEnv* ev, void* outKey, void* outVal); - mork_bool IterHere(morkEnv* ev, void* outKey, void* outVal); - - // NOTE: the following methods ONLY work for sMap_ValIsIP pointer values. - // (Note the implied assumption that zero is never a good value pattern.) - - void* IterFirstVal(morkEnv* ev, void* outKey); - // equivalent to { void* v=0; this->IterFirst(ev, outKey, &v); return v; } - - void* IterNextVal(morkEnv* ev, void* outKey); - // equivalent to { void* v=0; this->IterNext(ev, outKey, &v); return v; } - - void* IterHereVal(morkEnv* ev, void* outKey); - // equivalent to { void* v=0; this->IterHere(ev, outKey, &v); return v; } - - // NOTE: the following methods ONLY work for sMap_KeyIsIP pointer values. - // (Note the implied assumption that zero is never a good key pattern.) - - void* IterFirstKey(morkEnv* ev); - // equivalent to { void* k=0; this->IterFirst(ev, &k, 0); return k; } - - void* IterNextKey(morkEnv* ev); - // equivalent to { void* k=0; this->IterNext(ev, &k, 0); return k; } - - void* IterHereKey(morkEnv* ev); - // equivalent to { void* k=0; this->IterHere(ev, &k, 0); return k; } - -public: // simulation of the morkMapIter API for morkMap compatibility: - mork_change* First(morkEnv* ev, void* outKey, void* outVal); - mork_change* Next(morkEnv* ev, void* outKey, void* outVal); - mork_change* Here(morkEnv* ev, void* outKey, void* outVal); - - mork_change* CutHere(morkEnv* ev, void* outKey, void* outVal); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKPROBEMAP_ */ diff --git a/db/mork/src/morkQuickSort.cpp b/db/mork/src/morkQuickSort.cpp deleted file mode 100644 index 756cd0c481ba..000000000000 --- a/db/mork/src/morkQuickSort.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* We need this because Solaris' version of qsort is broken and - * causes array bounds reads. - */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKQUICKSORT_ -#include "morkQuickSort.h" -#endif - -#if !defined(DEBUG) && (defined(__cplusplus) || defined(__gcc)) -# ifndef INLINE -# define INLINE inline -# endif -#else -# define INLINE -#endif - -static INLINE mork_u1* -morkQS_med3(mork_u1 *, mork_u1 *, mork_u1 *, mdbAny_Order, void *); - -static INLINE void -morkQS_swapfunc(mork_u1 *, mork_u1 *, int, int); - -/* - * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". - */ -#define morkQS_swapcode(TYPE, parmi, parmj, n) { \ - long i = (n) / sizeof (TYPE); \ - register TYPE *pi = (TYPE *) (parmi); \ - register TYPE *pj = (TYPE *) (parmj); \ - do { \ - register TYPE t = *pi; \ - *pi++ = *pj; \ - *pj++ = t; \ - } while (--i > 0); \ -} - -#define morkQS_SwapInit(a, es) swaptype = (a - (mork_u1 *)0) % sizeof(long) || \ - es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; - -static INLINE void -morkQS_swapfunc(mork_u1* a, mork_u1* b, int n, int swaptype) -{ - if(swaptype <= 1) - morkQS_swapcode(long, a, b, n) - else - morkQS_swapcode(mork_u1, a, b, n) -} - -#define morkQS_swap(a, b) \ - if (swaptype == 0) { \ - long t = *(long *)(a); \ - *(long *)(a) = *(long *)(b); \ - *(long *)(b) = t; \ - } else \ - morkQS_swapfunc(a, b, (int)inSize, swaptype) - -#define morkQS_vecswap(a, b, n) if ((n) > 0) morkQS_swapfunc(a, b, (int)n, swaptype) - -static INLINE mork_u1 * -morkQS_med3(mork_u1* a, mork_u1* b, mork_u1* c, mdbAny_Order cmp, void* closure) -{ - return (*cmp)(a, b, closure) < 0 ? - ((*cmp)(b, c, closure) < 0 ? b : ((*cmp)(a, c, closure) < 0 ? c : a )) - :((*cmp)(b, c, closure) > 0 ? b : ((*cmp)(a, c, closure) < 0 ? a : c )); -} - -#define morkQS_MIN(x,y) ((x)<(y)?(x):(y)) - -void -morkQuickSort(mork_u1* ioVec, mork_u4 inCount, mork_u4 inSize, - mdbAny_Order inOrder, void* ioClosure) -{ - mork_u1* pa, *pb, *pc, *pd, *pl, *pm, *pn; - int d, r, swaptype, swap_cnt; - -tailCall: morkQS_SwapInit(ioVec, inSize); - swap_cnt = 0; - if (inCount < 7) { - for (pm = ioVec + inSize; pm < ioVec + inCount * inSize; pm += inSize) - for (pl = pm; pl > ioVec && (*inOrder)(pl - inSize, pl, ioClosure) > 0; - pl -= inSize) - morkQS_swap(pl, pl - inSize); - return; - } - pm = ioVec + (inCount / 2) * inSize; - if (inCount > 7) { - pl = ioVec; - pn = ioVec + (inCount - 1) * inSize; - if (inCount > 40) { - d = (inCount / 8) * inSize; - pl = morkQS_med3(pl, pl + d, pl + 2 * d, inOrder, ioClosure); - pm = morkQS_med3(pm - d, pm, pm + d, inOrder, ioClosure); - pn = morkQS_med3(pn - 2 * d, pn - d, pn, inOrder, ioClosure); - } - pm = morkQS_med3(pl, pm, pn, inOrder, ioClosure); - } - morkQS_swap(ioVec, pm); - pa = pb = ioVec + inSize; - - pc = pd = ioVec + (inCount - 1) * inSize; - for (;;) { - while (pb <= pc && (r = (*inOrder)(pb, ioVec, ioClosure)) <= 0) { - if (r == 0) { - swap_cnt = 1; - morkQS_swap(pa, pb); - pa += inSize; - } - pb += inSize; - } - while (pb <= pc && (r = (*inOrder)(pc, ioVec, ioClosure)) >= 0) { - if (r == 0) { - swap_cnt = 1; - morkQS_swap(pc, pd); - pd -= inSize; - } - pc -= inSize; - } - if (pb > pc) - break; - morkQS_swap(pb, pc); - swap_cnt = 1; - pb += inSize; - pc -= inSize; - } - if (swap_cnt == 0) { /* Switch to insertion sort */ - for (pm = ioVec + inSize; pm < ioVec + inCount * inSize; pm += inSize) - for (pl = pm; pl > ioVec && (*inOrder)(pl - inSize, pl, ioClosure) > 0; - pl -= inSize) - morkQS_swap(pl, pl - inSize); - return; - } - - pn = ioVec + inCount * inSize; - r = morkQS_MIN(pa - ioVec, pb - pa); - morkQS_vecswap(ioVec, pb - r, r); - r = morkQS_MIN(pd - pc, (int)(pn - pd - inSize)); - morkQS_vecswap(pb, pn - r, r); - if ((r = pb - pa) > (int)inSize) - morkQuickSort(ioVec, r / inSize, inSize, inOrder, ioClosure); - if ((r = pd - pc) > (int)inSize) { - /* Iterate rather than recurse to save stack space */ - ioVec = pn - r; - inCount = r / inSize; - goto tailCall; - } -/* morkQuickSort(pn - r, r / inSize, inSize, inOrder, ioClosure);*/ -} - diff --git a/db/mork/src/morkQuickSort.h b/db/mork/src/morkQuickSort.h deleted file mode 100644 index b55ec2d84fe2..000000000000 --- a/db/mork/src/morkQuickSort.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKQUICKSORT_ -#define _MORKQUICKSORT_ 1 - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -extern void -morkQuickSort(mork_u1* ioVec, mork_u4 inCount, mork_u4 inSize, - mdbAny_Order inOrder, void* ioClosure); - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKQUICKSORT_ */ diff --git a/db/mork/src/morkRow.cpp b/db/mork/src/morkRow.cpp deleted file mode 100644 index 593c0d31faad..000000000000 --- a/db/mork/src/morkRow.cpp +++ /dev/null @@ -1,965 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -#ifndef _MORKCELLOBJECT_ -#include "morkCellObject.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKROWCELLCURSOR_ -#include "morkRowCellCursor.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -// notifications regarding row changes: - -void morkRow::NoteRowAddCol(morkEnv* ev, mork_column inColumn) -{ - if ( !this->IsRowRewrite() ) - { - mork_delta newDelta; - morkDelta_Init(newDelta, inColumn, morkChange_kAdd); - - if ( newDelta != mRow_Delta ) // not repeating existing data? - { - if ( this->HasRowDelta() ) // already have one change recorded? - this->SetRowRewrite(); // just plan to write all row cells - else - this->SetRowDelta(inColumn, morkChange_kAdd); - } - } - else - this->ClearRowDelta(); -} - -void morkRow::NoteRowCutCol(morkEnv* ev, mork_column inColumn) -{ - if ( !this->IsRowRewrite() ) - { - mork_delta newDelta; - morkDelta_Init(newDelta, inColumn, morkChange_kCut); - - if ( newDelta != mRow_Delta ) // not repeating existing data? - { - if ( this->HasRowDelta() ) // already have one change recorded? - this->SetRowRewrite(); // just plan to write all row cells - else - this->SetRowDelta(inColumn, morkChange_kCut); - } - } - else - this->ClearRowDelta(); -} - -void morkRow::NoteRowSetCol(morkEnv* ev, mork_column inColumn) -{ - if ( !this->IsRowRewrite() ) - { - if ( this->HasRowDelta() ) // already have one change recorded? - this->SetRowRewrite(); // just plan to write all row cells - else - this->SetRowDelta(inColumn, morkChange_kSet); - } - else - this->ClearRowDelta(); -} - -void morkRow::NoteRowSetAll(morkEnv* ev) -{ - this->SetRowRewrite(); // just plan to write all row cells - this->ClearRowDelta(); -} - -mork_u2 -morkRow::AddRowGcUse(morkEnv* ev) -{ - if ( this->IsRow() ) - { - if ( mRow_GcUses < morkRow_kMaxGcUses ) // not already maxed out? - ++mRow_GcUses; - } - else - this->NonRowTypeError(ev); - - return mRow_GcUses; -} - -mork_u2 -morkRow::CutRowGcUse(morkEnv* ev) -{ - if ( this->IsRow() ) - { - if ( mRow_GcUses ) // any outstanding uses to cut? - { - if ( mRow_GcUses < morkRow_kMaxGcUses ) // not frozen at max? - --mRow_GcUses; - } - else - this->GcUsesUnderflowWarning(ev); - } - else - this->NonRowTypeError(ev); - - return mRow_GcUses; -} - -/*static*/ void -morkRow::GcUsesUnderflowWarning(morkEnv* ev) -{ - ev->NewWarning("mRow_GcUses underflow"); -} - - -/*static*/ void -morkRow::NonRowTypeError(morkEnv* ev) -{ - ev->NewError("non morkRow"); -} - -/*static*/ void -morkRow::NonRowTypeWarning(morkEnv* ev) -{ - ev->NewWarning("non morkRow"); -} - -/*static*/ void -morkRow::LengthBeyondMaxError(morkEnv* ev) -{ - ev->NewError("mRow_Length over max"); -} - -/*static*/ void -morkRow::ZeroColumnError(morkEnv* ev) -{ - ev->NewError(" zero mork_column"); -} - -/*static*/ void -morkRow::NilCellsError(morkEnv* ev) -{ - ev->NewError("nil mRow_Cells"); -} - -void -morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace, - mork_size inLength, morkPool* ioPool) - // if inLength is nonzero, cells will be allocated from ioPool -{ - if ( ioSpace && ioPool && inOid ) - { - if ( inLength <= morkRow_kMaxLength ) - { - if ( inOid->mOid_Id != morkRow_kMinusOneRid ) - { - mRow_Space = ioSpace; - mRow_Object = 0; - mRow_Cells = 0; - mRow_Oid = *inOid; - - mRow_Length = (mork_u2) inLength; - mRow_Seed = (mork_u2) (mork_ip) this; // "random" assignment - - mRow_GcUses = 0; - mRow_Pad = 0; - mRow_Flags = 0; - mRow_Tag = morkRow_kTag; - - morkZone* zone = &ioSpace->mSpace_Store->mStore_Zone; - - if ( inLength ) - mRow_Cells = ioPool->NewCells(ev, inLength, zone); - - if ( this->MaybeDirtySpaceStoreAndRow() ) // new row might dirty store - { - this->SetRowRewrite(); - this->NoteRowSetAll(ev); - } - } - else - ioSpace->MinusOneRidError(ev); - } - else - this->LengthBeyondMaxError(ev); - } - else - ev->NilPointerError(); -} - -morkRowObject* -morkRow::AcquireRowObject(morkEnv* ev, morkStore* ioStore) -{ - morkRowObject* ro = mRow_Object; - if ( ro ) // need new row object? - ro->AddRef(); - else - { - nsIMdbHeap* heap = ioStore->mPort_Heap; - ro = new(*heap, ev) - morkRowObject(ev, morkUsage::kHeap, heap, this, ioStore); - if ( !ro ) - return (morkRowObject*) 0; - - morkRowObject::SlotWeakRowObject(ro, ev, &mRow_Object); - ro->AddRef(); - } - return ro; -} - -nsIMdbRow* -morkRow::AcquireRowHandle(morkEnv* ev, morkStore* ioStore) -{ - return AcquireRowObject(ev, ioStore); -} - -nsIMdbCell* -morkRow::AcquireCellHandle(morkEnv* ev, morkCell* ioCell, - mdb_column inCol, mork_pos inPos) -{ - nsIMdbHeap* heap = ev->mEnv_Heap; - morkCellObject* cellObj = new(*heap, ev) - morkCellObject(ev, morkUsage::kHeap, heap, this, ioCell, inCol, inPos); - if ( cellObj ) - { - nsIMdbCell* cellHandle = cellObj->AcquireCellHandle(ev); -// cellObj->CutStrongRef(ev->AsMdbEnv()); - return cellHandle; - } - return (nsIMdbCell*) 0; -} - -mork_count -morkRow::CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill) - // Count cells in ioVector that change existing cells in this row when - // ioVector is added to the row (as in TakeCells()). This is the set - // of cells with the same columns in ioVector and mRow_Cells, which do - // not have exactly the same value in mCell_Atom, and which do not both - // have change status equal to morkChange_kCut (because cutting a cut - // cell still yields a cell that has been cut). CountOverlap() also - // modifies the change attribute of any cell in ioVector to kDup when - // the change was previously kCut and the same column cell was found - // in this row with change also equal to kCut; this tells callers later - // they need not look for that cell in the row again on a second pass. -{ - mork_count outCount = 0; - mork_pos pos = 0; // needed by GetCell() - morkCell* cells = ioVector; - morkCell* end = cells + inFill; - --cells; // prepare for preincrement - while ( ++cells < end && ev->Good() ) - { - mork_column col = cells->GetColumn(); - - morkCell* old = this->GetCell(ev, col, &pos); - if ( old ) // same column? - { - mork_change newChg = cells->GetChange(); - mork_change oldChg = old->GetChange(); - if ( newChg != morkChange_kCut || oldChg != newChg ) // not cut+cut? - { - if ( cells->mCell_Atom != old->mCell_Atom ) // not same atom? - ++outCount; // cells will replace old significantly when added - } - else - cells->SetColumnAndChange(col, morkChange_kDup); // note dup status - } - } - return outCount; -} - -void -morkRow::MergeCells(morkEnv* ev, morkCell* ioVector, - mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap) - // MergeCells() is the part of TakeCells() that does the insertion. - // inOldRowFill is the old value of mRow_Length, and inOverlap is the - // number of cells in the intersection that must be updated. -{ - morkCell* newCells = mRow_Cells + inOldRowFill; // 1st new cell in row - morkCell* newEnd = newCells + mRow_Length; // one past last cell - - morkCell* srcCells = ioVector; - morkCell* srcEnd = srcCells + inVecLength; - - --srcCells; // prepare for preincrement - while ( ++srcCells < srcEnd && ev->Good() ) - { - mork_change srcChg = srcCells->GetChange(); - if ( srcChg != morkChange_kDup ) // anything to be done? - { - morkCell* dstCell = 0; - if ( inOverlap ) - { - mork_pos pos = 0; // needed by GetCell() - dstCell = this->GetCell(ev, srcCells->GetColumn(), &pos); - } - if ( dstCell ) - { - --inOverlap; // one fewer intersections to resolve - // swap the atoms in the cells to avoid ref counting here: - morkAtom* dstAtom = dstCell->mCell_Atom; - *dstCell = *srcCells; // bitwise copy, taking src atom - srcCells->mCell_Atom = dstAtom; // forget cell ref, if any - } - else if ( newCells < newEnd ) // another new cell exists? - { - dstCell = newCells++; // alloc another new cell - // take atom from source cell, transferring ref to this row: - *dstCell = *srcCells; // bitwise copy, taking src atom - srcCells->mCell_Atom = 0; // forget cell ref, if any - } - else // oops, we ran out... - ev->NewError("out of new cells"); - } - } -} - -void -morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength, - morkStore* ioStore) -{ - if ( ioVector && inVecLength && ev->Good() ) - { - ++mRow_Seed; // intend to change structure of mRow_Cells - mork_size length = (mork_size) mRow_Length; - - mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength); - - mork_size growth = inVecLength - overlap; // cells to add - mork_size newLength = length + growth; - - if ( growth && ev->Good() ) // need to add any cells? - { - morkZone* zone = &ioStore->mStore_Zone; - morkPool* pool = ioStore->StorePool(); - if ( !pool->AddRowCells(ev, this, length + growth, zone) ) - ev->NewError("cannot take cells"); - } - if ( ev->Good() ) - { - if ( mRow_Length >= newLength ) - this->MergeCells(ev, ioVector, inVecLength, length, overlap); - else - ev->NewError("not enough new cells"); - } - } -} - -mork_bool morkRow::MaybeDirtySpaceStoreAndRow() -{ - morkRowSpace* rowSpace = mRow_Space; - if ( rowSpace ) - { - morkStore* store = rowSpace->mSpace_Store; - if ( store && store->mStore_CanDirty ) - { - store->SetStoreDirty(); - rowSpace->mSpace_CanDirty = morkBool_kTrue; - } - - if ( rowSpace->mSpace_CanDirty ) - { - this->SetRowDirty(); - rowSpace->SetRowSpaceDirty(); - return morkBool_kTrue; - } - } - return morkBool_kFalse; -} - -morkCell* -morkRow::NewCell(morkEnv* ev, mdb_column inColumn, - mork_pos* outPos, morkStore* ioStore) -{ - ++mRow_Seed; // intend to change structure of mRow_Cells - mork_size length = (mork_size) mRow_Length; - *outPos = (mork_pos) length; - morkPool* pool = ioStore->StorePool(); - morkZone* zone = &ioStore->mStore_Zone; - - mork_bool canDirty = this->MaybeDirtySpaceStoreAndRow(); - - if ( pool->AddRowCells(ev, this, length + 1, zone) ) - { - morkCell* cell = mRow_Cells + length; - // next line equivalent to inline morkCell::SetCellDirty(): - if ( canDirty ) - cell->SetCellColumnDirty(inColumn); - else - cell->SetCellColumnClean(inColumn); - - if ( canDirty && !this->IsRowRewrite() ) - this->NoteRowAddCol(ev, inColumn); - - return cell; - } - - return (morkCell*) 0; -} - - - -void morkRow::SeekColumn(morkEnv* ev, mdb_pos inPos, - mdb_column* outColumn, mdbYarn* outYarn) -{ - morkCell* cells = mRow_Cells; - if ( cells && inPos < mRow_Length && inPos >= 0 ) - { - morkCell* c = cells + inPos; - if ( outColumn ) - *outColumn = c->GetColumn(); - if ( outYarn ) - c->mCell_Atom->GetYarn(outYarn); // nil atom works okay here - } - else - { - if ( outColumn ) - *outColumn = 0; - if ( outYarn ) - ((morkAtom*) 0)->GetYarn(outYarn); // yes this will work - } -} - -void -morkRow::NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn) -{ - morkCell* cells = mRow_Cells; - if ( cells ) - { - mork_column last = 0; - mork_column inCol = *ioColumn; - morkCell* end = cells + mRow_Length; - while ( cells < end ) - { - if ( inCol == last ) // found column? - { - if ( outYarn ) - cells->mCell_Atom->GetYarn(outYarn); // nil atom works okay here - *ioColumn = cells->GetColumn(); - return; // stop, we are done - } - else - { - last = cells->GetColumn(); - ++cells; - } - } - } - *ioColumn = 0; - if ( outYarn ) - ((morkAtom*) 0)->GetYarn(outYarn); // yes this will work -} - -morkCell* -morkRow::CellAt(morkEnv* ev, mork_pos inPos) const -{ - MORK_USED_1(ev); - morkCell* cells = mRow_Cells; - if ( cells && inPos < mRow_Length && inPos >= 0 ) - { - return cells + inPos; - } - return (morkCell*) 0; -} - -morkCell* -morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const -{ - MORK_USED_1(ev); - morkCell* cells = mRow_Cells; - if ( cells ) - { - morkCell* end = cells + mRow_Length; - while ( cells < end ) - { - mork_column col = cells->GetColumn(); - if ( col == inColumn ) // found the desired column? - { - *outPos = cells - mRow_Cells; - return cells; - } - else - ++cells; - } - } - *outPos = -1; - return (morkCell*) 0; -} - -mork_aid -morkRow::GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const - // GetCellAtomAid() finds the cell with column inColumn, and sees if the - // atom has a token ID, and returns the atom's ID if there is one. Or - // else zero is returned if there is no such column, or no atom, or if - // the atom has no ID to return. This method is intended to support - // efficient updating of column indexes for rows in a row space. -{ - if ( this && this->IsRow() ) - { - morkCell* cells = mRow_Cells; - if ( cells ) - { - morkCell* end = cells + mRow_Length; - while ( cells < end ) - { - mork_column col = cells->GetColumn(); - if ( col == inColumn ) // found desired column? - { - morkAtom* atom = cells->mCell_Atom; - if ( atom && atom->IsBook() ) - return ((morkBookAtom*) atom)->mBookAtom_Id; - else - return 0; - } - else - ++cells; - } - } - } - else - this->NonRowTypeError(ev); - - return 0; -} - -void -morkRow::EmptyAllCells(morkEnv* ev) -{ - morkCell* cells = mRow_Cells; - if ( cells ) - { - morkStore* store = this->GetRowSpaceStore(ev); - if ( store ) - { - if ( this->MaybeDirtySpaceStoreAndRow() ) - { - this->SetRowRewrite(); - this->NoteRowSetAll(ev); - } - morkPool* pool = store->StorePool(); - morkCell* end = cells + mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end ) - { - if ( cells->mCell_Atom ) - cells->SetAtom(ev, (morkAtom*) 0, pool); - } - } - } -} - -void -morkRow::cut_all_index_entries(morkEnv* ev) -{ - morkRowSpace* rowSpace = mRow_Space; - if ( rowSpace->mRowSpace_IndexCount ) // any indexes? - { - morkCell* cells = mRow_Cells; - if ( cells ) - { - morkCell* end = cells + mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end ) - { - morkAtom* atom = cells->mCell_Atom; - if ( atom ) - { - mork_aid atomAid = atom->GetBookAtomAid(); - if ( atomAid ) - { - mork_column col = cells->GetColumn(); - morkAtomRowMap* map = rowSpace->FindMap(ev, col); - if ( map ) // cut row from index for this column? - map->CutAid(ev, atomAid); - } - } - } - } - } -} - -void -morkRow::CutAllColumns(morkEnv* ev) -{ - morkStore* store = this->GetRowSpaceStore(ev); - if ( store ) - { - if ( this->MaybeDirtySpaceStoreAndRow() ) - { - this->SetRowRewrite(); - this->NoteRowSetAll(ev); - } - morkRowSpace* rowSpace = mRow_Space; - if ( rowSpace->mRowSpace_IndexCount ) // any indexes? - this->cut_all_index_entries(ev); - - morkPool* pool = store->StorePool(); - pool->CutRowCells(ev, this, /*newSize*/ 0, &store->mStore_Zone); - } -} - -void -morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow) -{ - // note inSourceRow might be in another DB, with a different store... - morkStore* store = this->GetRowSpaceStore(ev); - morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev); - if ( store && srcStore ) - { - if ( this->MaybeDirtySpaceStoreAndRow() ) - { - this->SetRowRewrite(); - this->NoteRowSetAll(ev); - } - morkRowSpace* rowSpace = mRow_Space; - mork_count indexes = rowSpace->mRowSpace_IndexCount; // any indexes? - - mork_bool sameStore = ( store == srcStore ); // identical stores? - morkPool* pool = store->StorePool(); - if ( pool->CutRowCells(ev, this, /*newSize*/ 0, &store->mStore_Zone) ) - { - mork_fill fill = inSourceRow->mRow_Length; - if ( pool->AddRowCells(ev, this, fill, &store->mStore_Zone) ) - { - morkCell* dst = mRow_Cells; - morkCell* dstEnd = dst + mRow_Length; - - const morkCell* src = inSourceRow->mRow_Cells; - const morkCell* srcEnd = src + fill; - --dst; --src; // prepare both for preincrement: - - while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() ) - { - morkAtom* atom = src->mCell_Atom; - mork_column dstCol = src->GetColumn(); - // Note we modify the mCell_Atom slot directly instead of using - // morkCell::SetAtom(), because we know it starts equal to nil. - - if ( sameStore ) // source and dest in same store? - { - // next line equivalent to inline morkCell::SetCellDirty(): - dst->SetCellColumnDirty(dstCol); - dst->mCell_Atom = atom; - if ( atom ) // another ref to non-nil atom? - atom->AddCellUse(ev); - } - else // need to dup items from src store in a dest store - { - dstCol = store->CopyToken(ev, dstCol, srcStore); - if ( dstCol ) - { - // next line equivalent to inline morkCell::SetCellDirty(): - dst->SetCellColumnDirty(dstCol); - atom = store->CopyAtom(ev, atom); - dst->mCell_Atom = atom; - if ( atom ) // another ref? - atom->AddCellUse(ev); - } - } - if ( indexes && atom ) - { - mork_aid atomAid = atom->GetBookAtomAid(); - if ( atomAid ) - { - morkAtomRowMap* map = rowSpace->FindMap(ev, dstCol); - if ( map ) - map->AddAid(ev, atomAid, this); - } - } - } - } - } - } -} - -void -morkRow::AddRow(morkEnv* ev, const morkRow* inSourceRow) -{ - if ( mRow_Length ) // any existing cells we might need to keep? - { - ev->StubMethodOnlyError(); - } - else - this->SetRow(ev, inSourceRow); // just exactly duplicate inSourceRow -} - -void -morkRow::OnZeroRowGcUse(morkEnv* ev) -// OnZeroRowGcUse() is called when CutRowGcUse() returns zero. -{ - MORK_USED_1(ev); - // ev->NewWarning("need to implement OnZeroRowGcUse"); -} - -void -morkRow::DirtyAllRowContent(morkEnv* ev) -{ - MORK_USED_1(ev); - - if ( this->MaybeDirtySpaceStoreAndRow() ) - { - this->SetRowRewrite(); - this->NoteRowSetAll(ev); - } - morkCell* cells = mRow_Cells; - if ( cells ) - { - morkCell* end = cells + mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end ) - { - cells->SetCellDirty(); - } - } -} - -morkStore* -morkRow::GetRowSpaceStore(morkEnv* ev) const -{ - morkRowSpace* rowSpace = mRow_Space; - if ( rowSpace ) - { - morkStore* store = rowSpace->mSpace_Store; - if ( store ) - { - if ( store->IsStore() ) - { - return store; - } - else - store->NonStoreTypeError(ev); - } - else - ev->NilPointerError(); - } - else - ev->NilPointerError(); - - return (morkStore*) 0; -} - -void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn) -{ - mork_pos pos = -1; - morkCell* cell = this->GetCell(ev, inColumn, &pos); - if ( cell ) - { - morkStore* store = this->GetRowSpaceStore(ev); - if ( store ) - { - if ( this->MaybeDirtySpaceStoreAndRow() && !this->IsRowRewrite() ) - this->NoteRowCutCol(ev, inColumn); - - morkRowSpace* rowSpace = mRow_Space; - morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )? - rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0; - if ( map ) // this row attribute is indexed by row space? - { - morkAtom* oldAtom = cell->mCell_Atom; - if ( oldAtom ) // need to cut an entry from the index? - { - mork_aid oldAid = oldAtom->GetBookAtomAid(); - if ( oldAid ) // cut old row attribute from row index in space? - map->CutAid(ev, oldAid); - } - } - - morkPool* pool = store->StorePool(); - cell->SetAtom(ev, (morkAtom*) 0, pool); - - mork_fill fill = mRow_Length; // should not be zero - MORK_ASSERT(fill); - if ( fill ) // index < fill for last cell exists? - { - mork_fill last = fill - 1; // index of last cell in row - - if ( pos < (mork_pos)last ) // need to move cells following cut cell? - { - morkCell* lastCell = mRow_Cells + last; - mork_count after = last - pos; // cell count after cut cell - morkCell* next = cell + 1; // next cell after cut cell - MORK_MEMMOVE(cell, next, after * sizeof(morkCell)); - lastCell->SetColumnAndChange(0, 0); - lastCell->mCell_Atom = 0; - } - - if ( ev->Good() ) - pool->CutRowCells(ev, this, fill - 1, &store->mStore_Zone); - } - } - } -} - -morkAtom* morkRow::GetColumnAtom(morkEnv* ev, mdb_column inColumn) -{ - if ( ev->Good() ) - { - mork_pos pos = -1; - morkCell* cell = this->GetCell(ev, inColumn, &pos); - if ( cell ) - return cell->mCell_Atom; - } - return (morkAtom*) 0; -} - -void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn, - const mdbYarn* inYarn, morkStore* ioStore) -{ - if ( ev->Good() ) - { - mork_pos pos = -1; - morkCell* cell = this->GetCell(ev, inColumn, &pos); - morkCell* oldCell = cell; // need to know later whether new - if ( !cell ) // column does not yet exist? - cell = this->NewCell(ev, inColumn, &pos, ioStore); - - if ( cell ) - { - morkAtom* oldAtom = cell->mCell_Atom; - - morkAtom* atom = ioStore->YarnToAtom(ev, inYarn, PR_TRUE /* create */); - if ( atom && atom != oldAtom ) - { - morkRowSpace* rowSpace = mRow_Space; - morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )? - rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0; - - if ( map ) // inColumn is indexed by row space? - { - if ( oldAtom && oldAtom != atom ) // cut old cell from index? - { - mork_aid oldAid = oldAtom->GetBookAtomAid(); - if ( oldAid ) // cut old row attribute from row index in space? - map->CutAid(ev, oldAid); - } - } - - cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom - - if ( oldCell ) // we changed a pre-existing cell in the row? - { - ++mRow_Seed; - if ( this->MaybeDirtySpaceStoreAndRow() && !this->IsRowRewrite() ) - this->NoteRowAddCol(ev, inColumn); - } - - if ( map ) // inColumn is indexed by row space? - { - mork_aid newAid = atom->GetBookAtomAid(); - if ( newAid ) // add new row attribute to row index in space? - map->AddAid(ev, newAid, this); - } - } - } - } -} - -morkRowCellCursor* -morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos) -{ - morkRowCellCursor* outCursor = 0; - if ( ev->Good() ) - { - morkStore* store = this->GetRowSpaceStore(ev); - if ( store ) - { - morkRowObject* rowObj = this->AcquireRowObject(ev, store); - if ( rowObj ) - { - nsIMdbHeap* heap = store->mPort_Heap; - morkRowCellCursor* cursor = new(*heap, ev) - morkRowCellCursor(ev, morkUsage::kHeap, heap, rowObj); - - if ( cursor ) - { - if ( ev->Good() ) - { - cursor->mRowCellCursor_Col = inPos; - outCursor = cursor; - } - else - cursor->CutStrongRef(ev->mEnv_SelfAsMdbEnv); - } - rowObj->Release(); // always cut ref (cursor has its own) - } - } - } - return outCursor; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkRow.h b/db/mork/src/morkRow.h deleted file mode 100644 index 79090feb2677..000000000000 --- a/db/mork/src/morkRow.h +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKROW_ -#define _MORKROW_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class nsIMdbRow; -class nsIMdbCell; -#define morkDerived_kRow /*i*/ 0x5277 /* ascii 'Rw' */ - -#define morkRow_kMaxGcUses 0x0FF /* max for 8-bit unsigned int */ -#define morkRow_kMaxLength 0x0FFFF /* max for 16-bit unsigned int */ -#define morkRow_kMinusOneRid ((mork_rid) -1) - -#define morkRow_kTag 'r' /* magic signature for mRow_Tag */ - -#define morkRow_kNotedBit ((mork_u1) (1 << 0)) /* space has change notes */ -#define morkRow_kRewriteBit ((mork_u1) (1 << 1)) /* must rewrite all cells */ -#define morkRow_kDirtyBit ((mork_u1) (1 << 2)) /* row has been changed */ - -class morkRow{ // row of cells - -public: // state is public because the entire Mork system is private - - morkRowSpace* mRow_Space; // mRow_Space->SpaceScope() is the row scope - morkRowObject* mRow_Object; // refcount & other state for object sharing - morkCell* mRow_Cells; - mdbOid mRow_Oid; - - mork_delta mRow_Delta; // space to note a single column change - - mork_u2 mRow_Length; // physical count of cells in mRow_Cells - mork_u2 mRow_Seed; // count changes in mRow_Cells structure - - mork_u1 mRow_GcUses; // persistent references from tables - mork_u1 mRow_Pad; // for u1 alignment - mork_u1 mRow_Flags; // one-byte flags slot - mork_u1 mRow_Tag; // one-byte tag (need u4 alignment pad) - -public: // interpreting mRow_Delta - - mork_bool HasRowDelta() const { return ( mRow_Delta != 0 ); } - - void ClearRowDelta() { mRow_Delta = 0; } - - void SetRowDelta(mork_column inCol, mork_change inChange) - { morkDelta_Init(mRow_Delta, inCol, inChange); } - - mork_column GetDeltaColumn() const { return morkDelta_Column(mRow_Delta); } - mork_change GetDeltaChange() const { return morkDelta_Change(mRow_Delta); } - -public: // noting row changes - - void NoteRowSetAll(morkEnv* ev); - void NoteRowSetCol(morkEnv* ev, mork_column inCol); - void NoteRowAddCol(morkEnv* ev, mork_column inCol); - void NoteRowCutCol(morkEnv* ev, mork_column inCol); - -public: // flags bit twiddling - - void SetRowNoted() { mRow_Flags |= morkRow_kNotedBit; } - void SetRowRewrite() { mRow_Flags |= morkRow_kRewriteBit; } - void SetRowDirty() { mRow_Flags |= morkRow_kDirtyBit; } - - void ClearRowNoted() { mRow_Flags &= (mork_u1) ~morkRow_kNotedBit; } - void ClearRowRewrite() { mRow_Flags &= (mork_u1) ~morkRow_kRewriteBit; } - void SetRowClean() { mRow_Flags = 0; mRow_Delta = 0; } - - mork_bool IsRowNoted() const - { return ( mRow_Flags & morkRow_kNotedBit ) != 0; } - - mork_bool IsRowRewrite() const - { return ( mRow_Flags & morkRow_kRewriteBit ) != 0; } - - mork_bool IsRowClean() const - { return ( mRow_Flags & morkRow_kDirtyBit ) == 0; } - - mork_bool IsRowDirty() const - { return ( mRow_Flags & morkRow_kDirtyBit ) != 0; } - - mork_bool IsRowUsed() const - { return mRow_GcUses != 0; } - -public: // other row methods - morkRow( ) { } - morkRow(const mdbOid* inOid) :mRow_Oid(*inOid) { } - void InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace, - mork_size inLength, morkPool* ioPool); - // if inLength is nonzero, cells will be allocated from ioPool - - morkRowObject* AcquireRowObject(morkEnv* ev, morkStore* ioStore); - nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore); - nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell, - mdb_column inColumn, mork_pos inPos); - - mork_u2 AddRowGcUse(morkEnv* ev); - mork_u2 CutRowGcUse(morkEnv* ev); - - - mork_bool MaybeDirtySpaceStoreAndRow(); - -public: // internal row methods - - void cut_all_index_entries(morkEnv* ev); - - // void cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell); - - mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill); - // Count cells in ioVector that change existing cells in this row when - // ioVector is added to the row (as in TakeCells()). This is the set - // of cells with the same columns in ioVector and mRow_Cells, which do - // not have exactly the same value in mCell_Atom, and which do not both - // have change status equal to morkChange_kCut (because cutting a cut - // cell still yields a cell that has been cut). CountOverlap() also - // modifies the change attribute of any cell in ioVector to kDup when - // the change was previously kCut and the same column cell was found - // in this row with change also equal to kCut; this tells callers later - // they need not look for that cell in the row again on a second pass. - - void MergeCells(morkEnv* ev, morkCell* ioVector, - mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap); - // MergeCells() is the part of TakeCells() that does the insertion. - // inOldRowFill is the old value of mRow_Length, and inOverlap is the - // number of cells in the intersection that must be updated. - - void TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength, - morkStore* ioStore); - - morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos, - morkStore* ioStore); - morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const; - morkCell* CellAt(morkEnv* ev, mork_pos inPos) const; - - mork_aid GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const; - // GetCellAtomAid() finds the cell with column inColumn, and sees if the - // atom has a token ID, and returns the atom's ID if there is one. Or - // else zero is returned if there is no such column, or no atom, or if - // the atom has no ID to return. This method is intended to support - // efficient updating of column indexes for rows in a row space. - -public: // external row methods - - void DirtyAllRowContent(morkEnv* ev); - - morkStore* GetRowSpaceStore(morkEnv* ev) const; - - void AddColumn(morkEnv* ev, mdb_column inColumn, - const mdbYarn* inYarn, morkStore* ioStore); - - morkAtom* GetColumnAtom(morkEnv* ev, mdb_column inColumn); - - void NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn); - - void SeekColumn(morkEnv* ev, mdb_pos inPos, - mdb_column* outColumn, mdbYarn* outYarn); - - void CutColumn(morkEnv* ev, mdb_column inColumn); - - morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos); - - void EmptyAllCells(morkEnv* ev); - void AddRow(morkEnv* ev, const morkRow* inSourceRow); - void SetRow(morkEnv* ev, const morkRow* inSourceRow); - void CutAllColumns(morkEnv* ev); - - void OnZeroRowGcUse(morkEnv* ev); - // OnZeroRowGcUse() is called when CutRowGcUse() returns zero. - -public: // dynamic typing - - mork_bool IsRow() const { return mRow_Tag == morkRow_kTag; } - -public: // hash and equal - - mork_u4 HashRow() const - { - return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id; - } - - mork_bool EqualRow(const morkRow* ioRow) const - { - return - ( - ( mRow_Oid.mOid_Scope == ioRow->mRow_Oid.mOid_Scope ) - && ( mRow_Oid.mOid_Id == ioRow->mRow_Oid.mOid_Id ) - ); - } - - mork_bool EqualOid(const mdbOid* ioOid) const - { - return - ( - ( mRow_Oid.mOid_Scope == ioOid->mOid_Scope ) - && ( mRow_Oid.mOid_Id == ioOid->mOid_Id ) - ); - } - -public: // errors - static void ZeroColumnError(morkEnv* ev); - static void LengthBeyondMaxError(morkEnv* ev); - static void NilCellsError(morkEnv* ev); - static void NonRowTypeError(morkEnv* ev); - static void NonRowTypeWarning(morkEnv* ev); - static void GcUsesUnderflowWarning(morkEnv* ev); - -private: // copying is not allowed - morkRow(const morkRow& other); - morkRow& operator=(const morkRow& other); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKROW_ */ - diff --git a/db/mork/src/morkRowCellCursor.cpp b/db/mork/src/morkRowCellCursor.cpp deleted file mode 100644 index cec55421418e..000000000000 --- a/db/mork/src/morkRowCellCursor.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKROWCELLCURSOR_ -#include "morkRowCellCursor.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkRowCellCursor::CloseMorkNode(morkEnv* ev) // CloseRowCellCursor() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseRowCellCursor(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkRowCellCursor::~morkRowCellCursor() // CloseRowCellCursor() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkRowCellCursor::morkRowCellCursor(morkEnv* ev, - const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkRowObject* ioRowObject) -: morkCursor(ev, inUsage, ioHeap) -, mRowCellCursor_RowObject( 0 ) -, mRowCellCursor_Col( 0 ) -{ - if ( ev->Good() ) - { - if ( ioRowObject ) - { - morkRow* row = ioRowObject->mRowObject_Row; - if ( row ) - { - if ( row->IsRow() ) - { - mCursor_Pos = -1; - mCursor_Seed = row->mRow_Seed; - - morkRowObject::SlotStrongRowObject(ioRowObject, ev, - &mRowCellCursor_RowObject); - if ( ev->Good() ) - mNode_Derived = morkDerived_kRowCellCursor; - } - else - row->NonRowTypeError(ev); - } - else - ioRowObject->NilRowError(ev); - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkRowCellCursor, morkCursor, nsIMdbRowCellCursor) - -/*public non-poly*/ void -morkRowCellCursor::CloseRowCellCursor(morkEnv* ev) -{ - if ( this ) - { - if ( this->IsNode() ) - { - mCursor_Pos = -1; - mCursor_Seed = 0; - morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev, - &mRowCellCursor_RowObject); - this->CloseCursor(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkRowCellCursor::NilRowObjectError(morkEnv* ev) -{ - ev->NewError("nil mRowCellCursor_RowObject"); -} - -/*static*/ void -morkRowCellCursor::NonRowCellCursorTypeError(morkEnv* ev) -{ - ev->NewError("non morkRowCellCursor"); -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 -// { ----- begin attribute methods ----- -NS_IMETHODIMP -morkRowCellCursor::SetRow(nsIMdbEnv* mev, nsIMdbRow* ioRow) -{ - mdb_err outErr = 0; - morkRow* row = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - row = (morkRow *) ioRow; - morkStore* store = row->GetRowSpaceStore(ev); - if ( store ) - { - morkRowObject* rowObj = row->AcquireRowObject(ev, store); - if ( rowObj ) - { - morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev, - &mRowCellCursor_RowObject); - - mRowCellCursor_RowObject = rowObj; // take this strong ref - mCursor_Seed = row->mRow_Seed; - - row->GetCell(ev, mRowCellCursor_Col, &mCursor_Pos); - } - } - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowCellCursor::GetRow(nsIMdbEnv* mev, nsIMdbRow** acqRow) -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject* rowObj = mRowCellCursor_RowObject; - if ( rowObj ) - outRow = rowObj->AcquireRowHandle(ev); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin cell creation methods ----- -NS_IMETHODIMP -morkRowCellCursor::MakeCell( // get cell at current pos in the row - nsIMdbEnv* mev, // context - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos, // position of cell in row sequence - nsIMdbCell** acqCell) -{ - mdb_err outErr = 0; - nsIMdbCell* outCell = 0; - mdb_pos pos = 0; - mdb_column col = 0; - morkRow* row = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - pos = mCursor_Pos; - morkCell* cell = row->CellAt(ev, pos); - if ( cell ) - { - col = cell->GetColumn(); - outCell = row->AcquireCellHandle(ev, cell, col, pos); - } - outErr = ev->AsErr(); - } - if ( acqCell ) - *acqCell = outCell; - if ( outPos ) - *outPos = pos; - if ( outColumn ) - *outColumn = col; - - return outErr; -} -// } ----- end cell creation methods ----- - -// { ----- begin cell seeking methods ----- -NS_IMETHODIMP -morkRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell() - nsIMdbEnv* mev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - nsIMdbCell** acqCell) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end cell seeking methods ----- - -// { ----- begin cell iteration methods ----- -NS_IMETHODIMP -morkRowCellCursor::NextCell( // get next cell in the row - nsIMdbEnv* mev, // context - nsIMdbCell** acqCell, // changes to the next cell in the iteration - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos) -{ - morkEnv* ev = morkEnv::FromMdbEnv(mev); - mdb_column col = 0; - mdb_pos pos = mRowCellCursor_Col; - if ( pos < 0 ) - pos = 0; - else - ++pos; - - morkCell* cell = mRowCellCursor_RowObject->mRowObject_Row->CellAt(ev, pos); - if ( cell ) - { - col = cell->GetColumn(); - *acqCell = mRowCellCursor_RowObject->mRowObject_Row->AcquireCellHandle(ev, cell, col, pos); - } - else - { - *acqCell = nsnull; - pos = -1; - } - if ( outPos ) - *outPos = pos; - if ( outColumn ) - *outColumn = col; - - mRowCellCursor_Col = pos; - return NS_OK; -} - -NS_IMETHODIMP -morkRowCellCursor::PickNextCell( // get next cell in row within filter set - nsIMdbEnv* mev, // context - nsIMdbCell* ioCell, // changes to the next cell in the iteration - const mdbColumnSet* inFilterSet, // col set of actual caller interest - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos) -// Note that inFilterSet should not have too many (many more than 10?) -// cols, since this might imply a potential excessive consumption of time -// over many cursor calls when looking for column and filter intersection. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -// } ----- end cell iteration methods ----- - -// } ===== end nsIMdbRowCellCursor methods ===== - diff --git a/db/mork/src/morkRowCellCursor.h b/db/mork/src/morkRowCellCursor.h deleted file mode 100644 index 608788f0721b..000000000000 --- a/db/mork/src/morkRowCellCursor.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKROWCELLCURSOR_ -#define _MORKROWCELLCURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class orkinRowCellCursor; -#define morkDerived_kRowCellCursor /*i*/ 0x6343 /* ascii 'cC' */ - -class morkRowCellCursor : public morkCursor, public nsIMdbRowCellCursor { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkFactory* mObject_Factory; // weak ref to suite factory - - // mork_seed mCursor_Seed; - // mork_pos mCursor_Pos; - // mork_bool mCursor_DoFailOnSeedOutOfSync; - // mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - -public: // state is public because the entire Mork system is private - - NS_DECL_ISUPPORTS_INHERITED - morkRowObject* mRowCellCursor_RowObject; // strong ref to row - mork_column mRowCellCursor_Col; // col of cell last at mCursor_Pos - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseRowCellCursor() - virtual ~morkRowCellCursor(); // assert that close executed earlier - -public: // morkRowCellCursor construction & destruction - morkRowCellCursor(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkRowObject* ioRowObject); - void CloseRowCellCursor(morkEnv* ev); // called by CloseMorkNode(); - - // { ----- begin attribute methods ----- - NS_IMETHOD SetRow(nsIMdbEnv* ev, nsIMdbRow* ioRow); // sets pos to -1 - NS_IMETHOD GetRow(nsIMdbEnv* ev, nsIMdbRow** acqRow); - // } ----- end attribute methods ----- - - // { ----- begin cell creation methods ----- - NS_IMETHOD MakeCell( // get cell at current pos in the row - nsIMdbEnv* ev, // context - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos, // position of cell in row sequence - nsIMdbCell** acqCell); // the cell at inPos - // } ----- end cell creation methods ----- - - // { ----- begin cell seeking methods ----- - NS_IMETHOD SeekCell( // same as SetRow() followed by MakeCell() - nsIMdbEnv* ev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - nsIMdbCell** acqCell); // the cell at inPos - // } ----- end cell seeking methods ----- - - // { ----- begin cell iteration methods ----- - NS_IMETHOD NextCell( // get next cell in the row - nsIMdbEnv* ev, // context - nsIMdbCell** acqCell, // changes to the next cell in the iteration - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos); // position of cell in row sequence - - NS_IMETHOD PickNextCell( // get next cell in row within filter set - nsIMdbEnv* ev, // context - nsIMdbCell* ioCell, // changes to the next cell in the iteration - const mdbColumnSet* inFilterSet, // col set of actual caller interest - mdb_column* outColumn, // column for this particular cell - mdb_pos* outPos); // position of cell in row sequence - - // Note that inFilterSet should not have too many (many more than 10?) - // cols, since this might imply a potential excessive consumption of time - // over many cursor calls when looking for column and filter intersection. - // } ----- end cell iteration methods ----- - - -private: // copying is not allowed - morkRowCellCursor(const morkRowCellCursor& other); - morkRowCellCursor& operator=(const morkRowCellCursor& other); - -public: // dynamic type identification - mork_bool IsRowCellCursor() const - { return IsNode() && mNode_Derived == morkDerived_kRowCellCursor; } -// } ===== end morkNode methods ===== - -public: // errors - static void NilRowObjectError(morkEnv* ev); - static void NonRowCellCursorTypeError(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakRowCellCursor(morkRowCellCursor* me, - morkEnv* ev, morkRowCellCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongRowCellCursor(morkRowCellCursor* me, - morkEnv* ev, morkRowCellCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKROWCELLCURSOR_ */ diff --git a/db/mork/src/morkRowMap.cpp b/db/mork/src/morkRowMap.cpp deleted file mode 100644 index 0e2ee320bade..000000000000 --- a/db/mork/src/morkRowMap.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkRowMap::CloseMorkNode(morkEnv* ev) // CloseRowMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseRowMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkRowMap::~morkRowMap() // assert CloseRowMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkRowMap::morkRowMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots) -: morkMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkRow*), /*inValSize*/ 0, - inSlots, ioSlotHeap, /*inHoldChanges*/ morkBool_kFalse) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kRowMap; -} - -/*public non-poly*/ void -morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CloseMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - - -// { ===== begin morkMap poly interface ===== -/*virtual*/ mork_bool // -morkRowMap::Equal(morkEnv* ev, const void* inKeyA, - const void* inKeyB) const -{ - MORK_USED_1(ev); - return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB); -} - -/*virtual*/ mork_u4 // -morkRowMap::Hash(morkEnv* ev, const void* inKey) const -{ - MORK_USED_1(ev); - return (*(const morkRow**) inKey)->HashRow(); -} -// } ===== end morkMap poly interface ===== - - -mork_bool -morkRowMap::AddRow(morkEnv* ev, morkRow* ioRow) -{ - if ( ev->Good() ) - { - this->Put(ev, &ioRow, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0); - } - return ev->Good(); -} - -morkRow* -morkRowMap::CutOid(morkEnv* ev, const mdbOid* inOid) -{ - morkRow row(inOid); - morkRow* key = &row; - morkRow* oldKey = 0; - this->Cut(ev, &key, &oldKey, /*val*/ (void*) 0, - (mork_change**) 0); - - return oldKey; -} - -morkRow* -morkRowMap::CutRow(morkEnv* ev, const morkRow* ioRow) -{ - morkRow* oldKey = 0; - this->Cut(ev, &ioRow, &oldKey, /*val*/ (void*) 0, - (mork_change**) 0); - - return oldKey; -} - -morkRow* -morkRowMap::GetOid(morkEnv* ev, const mdbOid* inOid) -{ - morkRow row(inOid); - morkRow* key = &row; - morkRow* oldKey = 0; - this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0); - - return oldKey; -} - -morkRow* -morkRowMap::GetRow(morkEnv* ev, const morkRow* ioRow) -{ - morkRow* oldKey = 0; - this->Get(ev, &ioRow, &oldKey, /*val*/ (void*) 0, (mork_change**) 0); - - return oldKey; -} - - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkRowProbeMap::CloseMorkNode(morkEnv* ev) // CloseRowProbeMap() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseRowProbeMap(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkRowProbeMap::~morkRowProbeMap() // assert CloseRowProbeMap() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkRowProbeMap::morkRowProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots) -: morkProbeMap(ev, inUsage, ioHeap, - /*inKeySize*/ sizeof(morkRow*), /*inValSize*/ 0, - ioSlotHeap, inSlots, - /*inHoldChanges*/ morkBool_kTrue) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kRowProbeMap; -} - -/*public non-poly*/ void -morkRowProbeMap::CloseRowProbeMap(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - this->CloseProbeMap(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b) -morkRowProbeMap::MapTest(morkEnv* ev, const void* inMapKey, - const void* inAppKey) const -{ - MORK_USED_1(ev); - const morkRow* key = *(const morkRow**) inMapKey; - if ( key ) - { - mork_bool hit = key->EqualRow(*(const morkRow**) inAppKey); - return ( hit ) ? morkTest_kHit : morkTest_kMiss; - } - else - return morkTest_kVoid; -} - -/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b) -morkRowProbeMap::MapHash(morkEnv* ev, const void* inAppKey) const -{ - const morkRow* key = *(const morkRow**) inAppKey; - if ( key ) - return key->HashRow(); - else - { - ev->NilPointerWarning(); - return 0; - } -} - -/*virtual*/ mork_u4 -morkRowProbeMap::ProbeMapHashMapKey(morkEnv* ev, - const void* inMapKey) const -{ - const morkRow* key = *(const morkRow**) inMapKey; - if ( key ) - return key->HashRow(); - else - { - ev->NilPointerWarning(); - return 0; - } -} - -mork_bool -morkRowProbeMap::AddRow(morkEnv* ev, morkRow* ioRow) -{ - if ( ev->Good() ) - { - this->MapAtPut(ev, &ioRow, /*val*/ (void*) 0, - /*key*/ (void*) 0, /*val*/ (void*) 0); - } - return ev->Good(); -} - -morkRow* -morkRowProbeMap::CutOid(morkEnv* ev, const mdbOid* inOid) -{ - MORK_USED_1(inOid); - morkProbeMap::ProbeMapCutError(ev); - - return 0; -} - -morkRow* -morkRowProbeMap::CutRow(morkEnv* ev, const morkRow* ioRow) -{ - MORK_USED_1(ioRow); - morkProbeMap::ProbeMapCutError(ev); - - return 0; -} - -morkRow* -morkRowProbeMap::GetOid(morkEnv* ev, const mdbOid* inOid) -{ - morkRow row(inOid); - morkRow* key = &row; - morkRow* oldKey = 0; - this->MapAt(ev, &key, &oldKey, /*val*/ (void*) 0); - - return oldKey; -} - -morkRow* -morkRowProbeMap::GetRow(morkEnv* ev, const morkRow* ioRow) -{ - morkRow* oldKey = 0; - this->MapAt(ev, &ioRow, &oldKey, /*val*/ (void*) 0); - - return oldKey; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkRowMap.h b/db/mork/src/morkRowMap.h deleted file mode 100644 index 582e559cd731..000000000000 --- a/db/mork/src/morkRowMap.h +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKROWMAP_ -#define _MORKROWMAP_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKPROBEMAP_ -#include "morkProbeMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kRowMap /*i*/ 0x724D /* ascii 'rM' */ - -/*| morkRowMap: maps a set of morkRow by contained Oid -|*/ -class morkRowMap : public morkMap { // for mapping row IDs to rows - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseRowMap() only if open - virtual ~morkRowMap(); // assert that CloseRowMap() executed earlier - -public: // morkMap construction & destruction - morkRowMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots); - void CloseRowMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsRowMap() const - { return IsNode() && mNode_Derived == morkDerived_kRowMap; } -// } ===== end morkNode methods ===== - -// { ===== begin morkMap poly interface ===== - virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) - Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const; - // implemented using morkRow::EqualRow() - - virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) - Hash(morkEnv* ev, const void* inKey) const; - // implemented using morkRow::HashRow() -// } ===== end morkMap poly interface ===== - -public: // other map methods - - mork_bool AddRow(morkEnv* ev, morkRow* ioRow); - // AddRow() returns ev->Good() - - morkRow* CutOid(morkEnv* ev, const mdbOid* inOid); - // CutRid() returns the row removed equal to inRid, if there was one - - morkRow* CutRow(morkEnv* ev, const morkRow* ioRow); - // CutRow() returns the row removed equal to ioRow, if there was one - - morkRow* GetOid(morkEnv* ev, const mdbOid* inOid); - // GetOid() returns the row equal to inRid, or else nil - - morkRow* GetRow(morkEnv* ev, const morkRow* ioRow); - // GetRow() returns the row equal to ioRow, or else nil - - // note the rows are owned elsewhere, usuall by morkRowSpace - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakRowMap(morkRowMap* me, - morkEnv* ev, morkRowMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongRowMap(morkRowMap* me, - morkEnv* ev, morkRowMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -class morkRowMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkRowMapIter(morkEnv* ev, morkRowMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkRowMapIter( ) : morkMapIter() { } - void InitRowMapIter(morkEnv* ev, morkRowMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* FirstRow(morkEnv* ev, morkRow** outRowPtr) - { return this->First(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* NextRow(morkEnv* ev, morkRow** outRowPtr) - { return this->Next(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* HereRow(morkEnv* ev, morkRow** outRowPtr) - { return this->Here(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* CutHereRow(morkEnv* ev, morkRow** outRowPtr) - { return this->CutHere(ev, outRowPtr, /*val*/ (void*) 0); } -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kRowProbeMap /*i*/ 0x726D /* ascii 'rm' */ - -/*| morkRowProbeMap: maps a set of morkRow by contained Oid -|*/ -class morkRowProbeMap : public morkProbeMap { // for mapping row IDs to rows - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseRowProbeMap() only if open - virtual ~morkRowProbeMap(); // assert CloseRowProbeMap() executed earlier - -public: // morkMap construction & destruction - morkRowProbeMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots); - void CloseRowProbeMap(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsRowMap() const - { return IsNode() && mNode_Derived == morkDerived_kRowMap; } -// } ===== end morkNode methods ===== - - // { ===== begin morkProbeMap methods ===== - virtual mork_test // hit(a,b) implies hash(a) == hash(b) - MapTest(morkEnv* ev, const void* inMapKey, const void* inAppKey) const; - - virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) - MapHash(morkEnv* ev, const void* inAppKey) const; - - virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, const void* inMapKey) const; - - // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); - - // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' alls keys inside map - // void* ioMapKey, mork_count inKeyCount); // array of keys inside map - - // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map - // const void* inAppKey, const void* inAppVal, // (key,val) outside map - // void* outMapKey, void* outMapVal); // (key,val) inside map - - // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the map - // const void* inMapKey, const void* inMapVal, // (key,val) inside map - // void* outAppKey, void* outAppVal) const; // (key,val) outside map - // } ===== end morkProbeMap methods ===== - -public: // other map methods - - mork_bool AddRow(morkEnv* ev, morkRow* ioRow); - // AddRow() returns ev->Good() - - morkRow* CutOid(morkEnv* ev, const mdbOid* inOid); - // CutRid() returns the row removed equal to inRid, if there was one - - morkRow* CutRow(morkEnv* ev, const morkRow* ioRow); - // CutRow() returns the row removed equal to ioRow, if there was one - - morkRow* GetOid(morkEnv* ev, const mdbOid* inOid); - // GetOid() returns the row equal to inRid, or else nil - - morkRow* GetRow(morkEnv* ev, const morkRow* ioRow); - // GetRow() returns the row equal to ioRow, or else nil - - // note the rows are owned elsewhere, usuall by morkRowSpace - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakRowProbeMap(morkRowProbeMap* me, - morkEnv* ev, morkRowProbeMap** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongRowProbeMap(morkRowProbeMap* me, - morkEnv* ev, morkRowProbeMap** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -class morkRowProbeMapIter: public morkProbeMapIter{ // typesafe wrapper class - -public: - morkRowProbeMapIter(morkEnv* ev, morkRowProbeMap* ioMap) - : morkProbeMapIter(ev, ioMap) { } - - morkRowProbeMapIter( ) : morkProbeMapIter() { } - void InitRowMapIter(morkEnv* ev, morkRowProbeMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* FirstRow(morkEnv* ev, morkRow** outRowPtr) - { return this->First(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* NextRow(morkEnv* ev, morkRow** outRowPtr) - { return this->Next(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* HereRow(morkEnv* ev, morkRow** outRowPtr) - { return this->Here(ev, outRowPtr, /*val*/ (void*) 0); } - - mork_change* CutHereRow(morkEnv* ev, morkRow** outRowPtr) - { return this->CutHere(ev, outRowPtr, /*val*/ (void*) 0); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKROWMAP_ */ diff --git a/db/mork/src/morkRowObject.cpp b/db/mork/src/morkRowObject.cpp deleted file mode 100644 index 0f75c11c7863..000000000000 --- a/db/mork/src/morkRowObject.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKROWCELLCURSOR_ -#include "morkRowCellCursor.h" -#endif - -#ifndef _MORKCELLOBJECT_ -#include "morkCellObject.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkRowObject::CloseMorkNode(morkEnv* ev) // CloseRowObject() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseRowObject(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkRowObject::~morkRowObject() // assert CloseRowObject() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkRowObject::morkRowObject(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkRow* ioRow, morkStore* ioStore) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mRowObject_Row( 0 ) -, mRowObject_Store( 0 ) -{ - if ( ev->Good() ) - { - if ( ioRow && ioStore ) - { - mRowObject_Row = ioRow; - mRowObject_Store = ioStore; // morkRowObjects don't ref-cnt the owning store. - - if ( ev->Good() ) - mNode_Derived = morkDerived_kRowObject; - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkRowObject, morkObject, nsIMdbRow) -// { ===== begin nsIMdbCollection methods ===== - -// { ----- begin attribute methods ----- -NS_IMETHODIMP -morkRowObject::GetSeed(nsIMdbEnv* mev, - mdb_seed* outSeed) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - *outSeed = (mdb_seed) mRowObject_Row->mRow_Seed; - outErr = ev->AsErr(); - } - return outErr; -} -NS_IMETHODIMP -morkRowObject::GetCount(nsIMdbEnv* mev, - mdb_count* outCount) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - *outCount = (mdb_count) mRowObject_Row->mRow_Length; - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::GetPort(nsIMdbEnv* mev, - nsIMdbPort** acqPort) -{ - mdb_err outErr = 0; - nsIMdbPort* outPort = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowSpace* rowSpace = mRowObject_Row->mRow_Space; - if ( rowSpace && rowSpace->mSpace_Store ) - { - morkStore* store = mRowObject_Row->GetRowSpaceStore(ev); - if ( store ) - outPort = store->AcquireStoreHandle(ev); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqPort ) - *acqPort = outPort; - - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin cursor methods ----- -NS_IMETHODIMP -morkRowObject::GetCursor( // make a cursor starting iter at inMemberPos - nsIMdbEnv* mev, // context - mdb_pos inMemberPos, // zero-based ordinal pos of member in collection - nsIMdbCursor** acqCursor) -{ - return this->GetRowCellCursor(mev, inMemberPos, - (nsIMdbRowCellCursor**) acqCursor); -} -// } ----- end cursor methods ----- - -// { ----- begin ID methods ----- -NS_IMETHODIMP -morkRowObject::GetOid(nsIMdbEnv* mev, - mdbOid* outOid) -{ - *outOid = mRowObject_Row->mRow_Oid; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - return (ev) ? ev->AsErr() : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -morkRowObject::BecomeContent(nsIMdbEnv* mev, - const mdbOid* inOid) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; - // remember row->MaybeDirtySpaceStoreAndRow(); -} -// } ----- end ID methods ----- - -// { ----- begin activity dropping methods ----- -NS_IMETHODIMP -morkRowObject::DropActivity( // tell collection usage no longer expected - nsIMdbEnv* mev) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end activity dropping methods ----- - -// } ===== end nsIMdbCollection methods ===== - -// { ===== begin nsIMdbRow methods ===== - -// { ----- begin cursor methods ----- -NS_IMETHODIMP -morkRowObject::GetRowCellCursor( // make a cursor starting iteration at inCellPos - nsIMdbEnv* mev, // context - mdb_pos inPos, // zero-based ordinal position of cell in row - nsIMdbRowCellCursor** acqCursor) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - nsIMdbRowCellCursor* outCursor = 0; - if ( ev ) - { - morkRowCellCursor* cursor = mRowObject_Row->NewRowCellCursor(ev, inPos); - if ( cursor ) - { - if ( ev->Good() ) - { - cursor->mCursor_Seed = (mork_seed) inPos; - outCursor = cursor; - NS_ADDREF(cursor); - } - } - outErr = ev->AsErr(); - } - if ( acqCursor ) - *acqCursor = outCursor; - return outErr; -} -// } ----- end cursor methods ----- - -// { ----- begin column methods ----- -NS_IMETHODIMP -morkRowObject::AddColumn( // make sure a particular column is inside row - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to add - const mdbYarn* inYarn) -{ - mdb_err outErr = NS_ERROR_FAILURE; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store && mRowObject_Row) - mRowObject_Row->AddColumn(ev, inColumn, inYarn, mRowObject_Store); - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::CutColumn( // make sure a column is absent from the row - nsIMdbEnv* mev, // context - mdb_column inColumn) -{ - mdb_err outErr = NS_ERROR_FAILURE; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mRowObject_Row->CutColumn(ev, inColumn); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::CutAllColumns( // remove all columns from the row - nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mRowObject_Row->CutAllColumns(ev); - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end column methods ----- - -// { ----- begin cell methods ----- -NS_IMETHODIMP -morkRowObject::NewCell( // get cell for specified column, or add new one - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to add - nsIMdbCell** acqCell) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - GetCell(mev, inColumn, acqCell); - if ( !*acqCell ) - { - if ( mRowObject_Store ) - { - mdbYarn yarn; // to pass empty yarn into morkRowObject::AddColumn() - yarn.mYarn_Buf = 0; - yarn.mYarn_Fill = 0; - yarn.mYarn_Size = 0; - yarn.mYarn_More = 0; - yarn.mYarn_Form = 0; - yarn.mYarn_Grow = 0; - AddColumn(ev, inColumn, &yarn); - GetCell(mev, inColumn, acqCell); - } - } - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::AddCell( // copy a cell from another row to this row - nsIMdbEnv* mev, // context - const nsIMdbCell* inCell) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkCell* cell = 0; - morkCellObject* cellObj = (morkCellObject*) inCell; - if ( cellObj->CanUseCell(mev, morkBool_kFalse, &outErr, &cell) ) - { - - morkRow* cellRow = cellObj->mCellObject_Row; - if ( cellRow ) - { - if ( mRowObject_Row != cellRow ) - { - morkStore* store = mRowObject_Row->GetRowSpaceStore(ev); - morkStore* cellStore = cellRow->GetRowSpaceStore(ev); - if ( store && cellStore ) - { - mork_column col = cell->GetColumn(); - morkAtom* atom = cell->mCell_Atom; - mdbYarn yarn; - atom->AliasYarn(&yarn); // works even when atom is nil - - if ( store != cellStore ) - col = store->CopyToken(ev, col, cellStore); - if ( ev->Good() ) - AddColumn(ev, col, &yarn); - } - else - ev->NilPointerError(); - } - } - else - ev->NilPointerError(); - } - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::GetCell( // find a cell in this row - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to find - nsIMdbCell** acqCell) -{ - mdb_err outErr = 0; - nsIMdbCell* outCell = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - - if ( ev ) - { - if ( inColumn ) - { - mork_pos pos = 0; - morkCell* cell = mRowObject_Row->GetCell(ev, inColumn, &pos); - if ( cell ) - { - outCell = mRowObject_Row->AcquireCellHandle(ev, cell, inColumn, pos); - } - } - else - mRowObject_Row->ZeroColumnError(ev); - - outErr = ev->AsErr(); - } - if ( acqCell ) - *acqCell = outCell; - return outErr; -} - -NS_IMETHODIMP -morkRowObject::EmptyAllCells( // make all cells in row empty of content - nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - EmptyAllCells(ev); - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end cell methods ----- - -// { ----- begin row methods ----- -NS_IMETHODIMP -morkRowObject::AddRow( // add all cells in another row to this one - nsIMdbEnv* mev, // context - nsIMdbRow* ioSourceRow) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRow* unsafeSource = (morkRow*) ioSourceRow; // unsafe cast -// if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) ) - { - mRowObject_Row->AddRow(ev, unsafeSource); - } - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::SetRow( // make exact duplicate of another row - nsIMdbEnv* mev, // context - nsIMdbRow* ioSourceRow) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject *sourceObject = (morkRowObject *) ioSourceRow; // unsafe cast - morkRow* unsafeSource = sourceObject->mRowObject_Row; -// if ( unsafeSource->CanUseRow(mev, morkBool_kFalse, &outErr, &source) ) - { - mRowObject_Row->SetRow(ev, unsafeSource); - } - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end row methods ----- - -// { ----- begin blob methods ----- -NS_IMETHODIMP -morkRowObject::SetCellYarn( // synonym for AddColumn() - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to add - const mdbYarn* inYarn) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store ) - AddColumn(ev, inColumn, inYarn); - - outErr = ev->AsErr(); - } - return outErr; -} -NS_IMETHODIMP -morkRowObject::GetCellYarn( - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to read - mdbYarn* outYarn) // writes some yarn slots -// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store && mRowObject_Row) - { - morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn); - atom->GetYarn(outYarn); - // note nil atom works and sets yarn correctly - } - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::AliasCellYarn( - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to alias - mdbYarn* outYarn) // writes ALL yarn slots -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store && mRowObject_Row) - { - morkAtom* atom = mRowObject_Row->GetColumnAtom(ev, inColumn); - atom->AliasYarn(outYarn); - // note nil atom works and sets yarn correctly - } - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::NextCellYarn(nsIMdbEnv* mev, // iterative version of GetCellYarn() - mdb_column* ioColumn, // next column to read - mdbYarn* outYarn) // writes some yarn slots -// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form -// -// The ioColumn argument is an inout parameter which initially contains the -// last column accessed and returns the next column corresponding to the -// content read into the yarn. Callers should start with a zero column -// value to say 'no previous column', which causes the first column to be -// read. Then the value returned in ioColumn is perfect for the next call -// to NextCellYarn(), since it will then be the previous column accessed. -// Callers need only examine the column token returned to see which cell -// in the row is being read into the yarn. When no more columns remain, -// and the iteration has ended, ioColumn will return a zero token again. -// So iterating over cells starts and ends with a zero column token. -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store && mRowObject_Row) - mRowObject_Row->NextColumn(ev, ioColumn, outYarn); - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkRowObject::SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell() - nsIMdbEnv* mev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - mdbYarn* outYarn) // writes some yarn slots -// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form -// Callers can pass nil for outYarn to indicate no interest in content, so -// only the outColumn value is returned. NOTE to subclasses: you must be -// able to ignore outYarn when the pointer is nil; please do not crash. - -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mRowObject_Store && mRowObject_Row) - mRowObject_Row->SeekColumn(ev, inPos, outColumn, outYarn); - - outErr = ev->AsErr(); - } - return outErr; -} - -// } ----- end blob methods ----- - - -// } ===== end nsIMdbRow methods ===== - - - -/*public non-poly*/ void -morkRowObject::CloseRowObject(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkRow* row = mRowObject_Row; - mRowObject_Row = 0; - this->CloseObject(ev); - this->MarkShut(); - - if ( row ) - { - MORK_ASSERT(row->mRow_Object == this); - if ( row->mRow_Object == this ) - { - row->mRow_Object = 0; // just nil this slot -- cut ref down below - - mRowObject_Store = 0; // morkRowObjects don't ref-cnt the owning store. - - this->CutWeakRef(ev->AsMdbEnv()); // do last, because it might self destroy - } - } - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkRowObject::NonRowObjectTypeError(morkEnv* ev) -{ - ev->NewError("non morkRowObject"); -} - -/*static*/ void -morkRowObject::NilRowError(morkEnv* ev) -{ - ev->NewError("nil mRowObject_Row"); -} - -/*static*/ void -morkRowObject::NilStoreError(morkEnv* ev) -{ - ev->NewError("nil mRowObject_Store"); -} - -/*static*/ void -morkRowObject::RowObjectRowNotSelfError(morkEnv* ev) -{ - ev->NewError("mRowObject_Row->mRow_Object != self"); -} - - -nsIMdbRow* -morkRowObject::AcquireRowHandle(morkEnv* ev) // mObject_Handle -{ - AddRef(); - return this; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkRowObject.h b/db/mork/src/morkRowObject.h deleted file mode 100644 index 0bcf4faa809f..000000000000 --- a/db/mork/src/morkRowObject.h +++ /dev/null @@ -1,232 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKROWOBJECT_ -#define _MORKROWOBJECT_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class nsIMdbRow; -#define morkDerived_kRowObject /*i*/ 0x724F /* ascii 'rO' */ - -class morkRowObject : public morkObject, public nsIMdbRow { // - -public: // state is public because the entire Mork system is private - NS_DECL_ISUPPORTS_INHERITED - - morkRow* mRowObject_Row; // non-refcounted alias to morkRow - morkStore* mRowObject_Store; // non-refcounted ptr to store containing row - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseRowObject() only if open - virtual ~morkRowObject(); // assert that CloseRowObject() executed earlier - -public: // morkRowObject construction & destruction - morkRowObject(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkRow* ioRow, morkStore* ioStore); - void CloseRowObject(morkEnv* ev); // called by CloseMorkNode(); - -// { ===== begin nsIMdbCollection methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetSeed(nsIMdbEnv* ev, - mdb_seed* outSeed); // member change count - NS_IMETHOD GetCount(nsIMdbEnv* ev, - mdb_count* outCount); // member count - - NS_IMETHOD GetPort(nsIMdbEnv* ev, - nsIMdbPort** acqPort); // collection container - // } ----- end attribute methods ----- - - // { ----- begin cursor methods ----- - NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos - nsIMdbEnv* ev, // context - mdb_pos inMemberPos, // zero-based ordinal pos of member in collection - nsIMdbCursor** acqCursor); // acquire new cursor instance - // } ----- end cursor methods ----- - - // { ----- begin ID methods ----- - NS_IMETHOD GetOid(nsIMdbEnv* ev, - mdbOid* outOid); // read object identity - NS_IMETHOD BecomeContent(nsIMdbEnv* ev, - const mdbOid* inOid); // exchange content - // } ----- end ID methods ----- - - // { ----- begin activity dropping methods ----- - NS_IMETHOD DropActivity( // tell collection usage no longer expected - nsIMdbEnv* ev); - // } ----- end activity dropping methods ----- - -// } ===== end nsIMdbCollection methods ===== -// { ===== begin nsIMdbRow methods ===== - - // { ----- begin cursor methods ----- - NS_IMETHOD GetRowCellCursor( // make a cursor starting iteration at inRowPos - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbRowCellCursor** acqCursor); // acquire new cursor instance - // } ----- end cursor methods ----- - - // { ----- begin column methods ----- - NS_IMETHOD AddColumn( // make sure a particular column is inside row - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to add - const mdbYarn* inYarn); // cell value to install - - NS_IMETHOD CutColumn( // make sure a column is absent from the row - nsIMdbEnv* ev, // context - mdb_column inColumn); // column to ensure absent from row - - NS_IMETHOD CutAllColumns( // remove all columns from the row - nsIMdbEnv* ev); // context - // } ----- end column methods ----- - - // { ----- begin cell methods ----- - NS_IMETHOD NewCell( // get cell for specified column, or add new one - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to add - nsIMdbCell** acqCell); // cell column and value - - NS_IMETHOD AddCell( // copy a cell from another row to this row - nsIMdbEnv* ev, // context - const nsIMdbCell* inCell); // cell column and value - - NS_IMETHOD GetCell( // find a cell in this row - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to find - nsIMdbCell** acqCell); // cell for specified column, or null - - NS_IMETHOD EmptyAllCells( // make all cells in row empty of content - nsIMdbEnv* ev); // context - // } ----- end cell methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD AddRow( // add all cells in another row to this one - nsIMdbEnv* ev, // context - nsIMdbRow* ioSourceRow); // row to union with - - NS_IMETHOD SetRow( // make exact duplicate of another row - nsIMdbEnv* ev, // context - nsIMdbRow* ioSourceRow); // row to duplicate - // } ----- end row methods ----- - - // { ----- begin blob methods ----- - NS_IMETHOD SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn() - mdb_column inColumn, // column to write - const mdbYarn* inYarn); // reads from yarn slots - // make this text object contain content from the yarn's buffer - - NS_IMETHOD GetCellYarn(nsIMdbEnv* ev, - mdb_column inColumn, // column to read - mdbYarn* outYarn); // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - - NS_IMETHOD AliasCellYarn(nsIMdbEnv* ev, - mdb_column inColumn, // column to alias - mdbYarn* outYarn); // writes ALL yarn slots - - NS_IMETHOD NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn() - mdb_column* ioColumn, // next column to read - mdbYarn* outYarn); // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - // - // The ioColumn argument is an inout parameter which initially contains the - // last column accessed and returns the next column corresponding to the - // content read into the yarn. Callers should start with a zero column - // value to say 'no previous column', which causes the first column to be - // read. Then the value returned in ioColumn is perfect for the next call - // to NextCellYarn(), since it will then be the previous column accessed. - // Callers need only examine the column token returned to see which cell - // in the row is being read into the yarn. When no more columns remain, - // and the iteration has ended, ioColumn will return a zero token again. - // So iterating over cells starts and ends with a zero column token. - - NS_IMETHOD SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell() - nsIMdbEnv* ev, // context - mdb_pos inPos, // position of cell in row sequence - mdb_column* outColumn, // column for this particular cell - mdbYarn* outYarn); // writes some yarn slots - // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form - // Callers can pass nil for outYarn to indicate no interest in content, so - // only the outColumn value is returned. NOTE to subclasses: you must be - // able to ignore outYarn when the pointer is nil; please do not crash. - - // } ----- end blob methods ----- - -// } ===== end nsIMdbRow methods ===== - -private: // copying is not allowed - morkRowObject(const morkRowObject& other); - morkRowObject& operator=(const morkRowObject& other); - -public: // dynamic type identification - mork_bool IsRowObject() const - { return IsNode() && mNode_Derived == morkDerived_kRowObject; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonRowObjectTypeError(morkEnv* ev); - static void NilRowError(morkEnv* ev); - static void NilStoreError(morkEnv* ev); - static void RowObjectRowNotSelfError(morkEnv* ev); - -public: // other row node methods - - nsIMdbRow* AcquireRowHandle(morkEnv* ev); // mObject_Handle - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakRowObject(morkRowObject* me, - morkEnv* ev, morkRowObject** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongRowObject(morkRowObject* me, - morkEnv* ev, morkRowObject** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKROWOBJECT_ */ diff --git a/db/mork/src/morkRowSpace.cpp b/db/mork/src/morkRowSpace.cpp deleted file mode 100644 index 384d9804ab63..000000000000 --- a/db/mork/src/morkRowSpace.cpp +++ /dev/null @@ -1,666 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKATOMMAP_ -#include "morkAtomMap.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkRowSpace::CloseMorkNode(morkEnv* ev) // CloseRowSpace() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseRowSpace(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkRowSpace::~morkRowSpace() // assert CloseRowSpace() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkRowSpace::morkRowSpace(morkEnv* ev, - const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap) -, mRowSpace_SlotHeap( ioSlotHeap ) -, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap, - morkRowSpace_kStartRowMapSlotCount) -, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap) -, mRowSpace_NextTableId( 1 ) -, mRowSpace_NextRowId( 1 ) - -, mRowSpace_IndexCount( 0 ) -{ - morkAtomRowMap** cache = mRowSpace_IndexCache; - morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize; - while ( cache < cacheEnd ) - *cache++ = 0; // put nil into every slot of cache table - - if ( ev->Good() ) - { - if ( ioSlotHeap ) - { - mNode_Derived = morkDerived_kRowSpace; - - // the morkSpace base constructor handles any dirty propagation - } - else - ev->NilPointerError(); - } -} - -/*public non-poly*/ void -morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkAtomRowMap** cache = mRowSpace_IndexCache; - morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize; - --cache; // prepare for preincrement: - while ( ++cache < cacheEnd ) - { - if ( *cache ) - morkAtomRowMap::SlotStrongAtomRowMap(0, ev, cache); - } - - mRowSpace_Tables.CloseMorkNode(ev); - - morkStore* store = mSpace_Store; - if ( store ) - this->CutAllRows(ev, &store->mStore_Pool); - - mRowSpace_Rows.CloseMorkNode(ev); - this->CloseSpace(ev); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkRowSpace::NonRowSpaceTypeError(morkEnv* ev) -{ - ev->NewError("non morkRowSpace"); -} - -/*static*/ void -morkRowSpace::ZeroKindError(morkEnv* ev) -{ - ev->NewError("zero table kind"); -} - -/*static*/ void -morkRowSpace::ZeroScopeError(morkEnv* ev) -{ - ev->NewError("zero row scope"); -} - -/*static*/ void -morkRowSpace::ZeroTidError(morkEnv* ev) -{ - ev->NewError("zero table ID"); -} - -/*static*/ void -morkRowSpace::MinusOneRidError(morkEnv* ev) -{ - ev->NewError("row ID is -1"); -} - -///*static*/ void -//morkRowSpace::ExpectAutoIdOnlyError(morkEnv* ev) -//{ -// ev->NewError("zero row ID"); -//} - -///*static*/ void -//morkRowSpace::ExpectAutoIdNeverError(morkEnv* ev) -//{ -//} - -mork_num -morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool) -{ - if ( this->IsRowSpaceClean() ) - this->MaybeDirtyStoreAndSpace(); - - mork_num outSlots = mRowSpace_Rows.MapFill(); - -#ifdef MORK_ENABLE_ZONE_ARENAS - MORK_USED_2(ev, ioPool); - return 0; -#else /*MORK_ENABLE_ZONE_ARENAS*/ - morkZone* zone = &mSpace_Store->mStore_Zone; - morkRow* r = 0; // old key row in the map - mork_change* c = 0; - -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMapIter i(ev, &mRowSpace_Rows); -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMapIter i(ev, &mRowSpace_Rows); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - - for ( c = i.FirstRow(ev, &r); c && ev->Good(); - c = i.NextRow(ev, &r) ) - { - if ( r ) - { - if ( r->IsRow() ) - { - if ( r->mRow_Object ) - { - morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev, - &r->mRow_Object); - } - ioPool->ZapRow(ev, r, zone); - } - else - r->NonRowTypeWarning(ev); - } - else - ev->NilPointerError(); - -#ifdef MORK_ENABLE_PROBE_MAPS - // cut nothing from the map -#else /*MORK_ENABLE_PROBE_MAPS*/ - i.CutHereRow(ev, /*key*/ (morkRow**) 0); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - } -#endif /*MORK_ENABLE_ZONE_ARENAS*/ - - - return outSlots; -} - -morkTable* -morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind) -{ - if ( inTableKind ) - { -#ifdef MORK_BEAD_OVER_NODE_MAPS - - morkTableMapIter i(ev, &mRowSpace_Tables); - morkTable* table = i.FirstTable(ev); - for ( ; table && ev->Good(); table = i.NextTable(ev) ) - -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - mork_tid* key = 0; // nil pointer to suppress key access - morkTable* table = 0; // old table in the map - - mork_change* c = 0; - morkTableMapIter i(ev, &mRowSpace_Tables); - for ( c = i.FirstTable(ev, key, &table); c && ev->Good(); - c = i.NextTable(ev, key, &table) ) -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - { - if ( table->mTable_Kind == inTableKind ) - return table; - } - } - else - this->ZeroKindError(ev); - - return (morkTable*) 0; -} - -morkTable* -morkRowSpace::NewTableWithTid(morkEnv* ev, mork_tid inTid, - mork_kind inTableKind, - const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying -{ - morkTable* outTable = 0; - morkStore* store = mSpace_Store; - - if ( inTableKind && store ) - { - mdb_bool mustBeUnique = morkBool_kFalse; - nsIMdbHeap* heap = store->mPort_Heap; - morkTable* table = new(*heap, ev) - morkTable(ev, morkUsage::kHeap, heap, store, heap, this, - inOptionalMetaRowOid, inTid, inTableKind, mustBeUnique); - if ( table ) - { - if ( mRowSpace_Tables.AddTable(ev, table) ) - { - outTable = table; - if ( mRowSpace_NextTableId <= inTid ) - mRowSpace_NextTableId = inTid + 1; - } - - if ( this->IsRowSpaceClean() && store->mStore_CanDirty ) - this->MaybeDirtyStoreAndSpace(); // morkTable does already - - } - } - else if ( store ) - this->ZeroKindError(ev); - else - this->NilSpaceStoreError(ev); - - return outTable; -} - -morkTable* -morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind, - mdb_bool inMustBeUnique, - const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying -{ - morkTable* outTable = 0; - morkStore* store = mSpace_Store; - - if ( inTableKind && store ) - { - if ( inMustBeUnique ) // need to look for existing table first? - outTable = this->FindTableByKind(ev, inTableKind); - - if ( !outTable && ev->Good() ) - { - mork_tid id = this->MakeNewTableId(ev); - if ( id ) - { - nsIMdbHeap* heap = mSpace_Store->mPort_Heap; - morkTable* table = new(*heap, ev) - morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this, - inOptionalMetaRowOid, id, inTableKind, inMustBeUnique); - if ( table ) - { - if ( mRowSpace_Tables.AddTable(ev, table) ) - outTable = table; - else - table->Release(); - - if ( this->IsRowSpaceClean() && store->mStore_CanDirty ) - this->MaybeDirtyStoreAndSpace(); // morkTable does already - } - } - } - } - else if ( store ) - this->ZeroKindError(ev); - else - this->NilSpaceStoreError(ev); - - return outTable; -} - -mork_tid -morkRowSpace::MakeNewTableId(morkEnv* ev) -{ - mork_tid outTid = 0; - mork_tid id = mRowSpace_NextTableId; - mork_num count = 9; // try up to eight times - - while ( !outTid && --count ) // still trying to find an unused table ID? - { - if ( !mRowSpace_Tables.GetTable(ev, id) ) - outTid = id; - else - { - MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems - ++id; - } - } - - mRowSpace_NextTableId = id + 1; - return outTid; -} - -mork_rid -morkRowSpace::MakeNewRowId(morkEnv* ev) -{ - mork_rid outRid = 0; - mork_rid id = mRowSpace_NextRowId; - mork_num count = 9; // try up to eight times - mdbOid oid; - oid.mOid_Scope = this->SpaceScope(); - - while ( !outRid && --count ) // still trying to find an unused row ID? - { - oid.mOid_Id = id; - if ( !mRowSpace_Rows.GetOid(ev, &oid) ) - outRid = id; - else - { - MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems - ++id; - } - } - - mRowSpace_NextRowId = id + 1; - return outRid; -} - -morkAtomRowMap* -morkRowSpace::make_index(morkEnv* ev, mork_column inCol) -{ - morkAtomRowMap* outMap = 0; - nsIMdbHeap* heap = mRowSpace_SlotHeap; - if ( heap ) // have expected heap for allocations? - { - morkAtomRowMap* map = new(*heap, ev) - morkAtomRowMap(ev, morkUsage::kHeap, heap, heap, inCol); - - if ( map ) // able to create new map index? - { - if ( ev->Good() ) // no errors during construction? - { -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMapIter i(ev, &mRowSpace_Rows); -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMapIter i(ev, &mRowSpace_Rows); -#endif /*MORK_ENABLE_PROBE_MAPS*/ - mork_change* c = 0; - morkRow* row = 0; - mork_aid aidKey = 0; - - for ( c = i.FirstRow(ev, &row); c && ev->Good(); - c = i.NextRow(ev, &row) ) // another row in space? - { - aidKey = row->GetCellAtomAid(ev, inCol); - if ( aidKey ) // row has indexed attribute? - map->AddAid(ev, aidKey, row); // include in map - } - } - if ( ev->Good() ) // no errors constructing index? - outMap = map; // return from function - else - map->CutStrongRef(ev); // discard map on error - } - } - else - ev->NilPointerError(); - - return outMap; -} - -morkAtomRowMap* -morkRowSpace::ForceMap(morkEnv* ev, mork_column inCol) -{ - morkAtomRowMap* outMap = this->FindMap(ev, inCol); - - if ( !outMap && ev->Good() ) // no such existing index? - { - if ( mRowSpace_IndexCount < morkRowSpace_kMaxIndexCount ) - { - morkAtomRowMap* map = this->make_index(ev, inCol); - if ( map ) // created a new index for col? - { - mork_count wrap = 0; // count times wrap-around occurs - morkAtomRowMap** slot = mRowSpace_IndexCache; // table - morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize; - slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash - while ( *slot ) // empty slot not yet found? - { - if ( ++slot >= end ) // wrap around? - { - slot = mRowSpace_IndexCache; // back to table start - if ( ++wrap > 1 ) // wrapped more than once? - { - ev->NewError("no free cache slots"); // disaster - break; // end while loop - } - } - } - if ( ev->Good() ) // everything went just fine? - { - ++mRowSpace_IndexCount; // note another new map - *slot = map; // install map in the hash table - outMap = map; // return the new map from function - } - else - map->CutStrongRef(ev); // discard map on error - } - } - else - ev->NewError("too many indexes"); // why so many indexes? - } - return outMap; -} - -morkAtomRowMap* -morkRowSpace::FindMap(morkEnv* ev, mork_column inCol) -{ - if ( mRowSpace_IndexCount && ev->Good() ) - { - mork_count wrap = 0; // count times wrap-around occurs - morkAtomRowMap** slot = mRowSpace_IndexCache; // table - morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize; - slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash - morkAtomRowMap* map = *slot; - while ( map ) // another used slot to examine? - { - if ( inCol == map->mAtomRowMap_IndexColumn ) // found col? - return map; - if ( ++slot >= end ) // wrap around? - { - slot = mRowSpace_IndexCache; - if ( ++wrap > 1 ) // wrapped more than once? - return (morkAtomRowMap*) 0; // stop searching - } - map = *slot; - } - } - return (morkAtomRowMap*) 0; -} - -morkRow* -morkRowSpace::FindRow(morkEnv* ev, mork_column inCol, const mdbYarn* inYarn) -{ - morkRow* outRow = 0; - - // if yarn hasn't been atomized, there can't be a corresponding row, - // so pass in PR_FALSE to not create the row - should help history bloat - morkAtom* atom = mSpace_Store->YarnToAtom(ev, inYarn, PR_FALSE); - if ( atom ) // have or created an atom corresponding to input yarn? - { - mork_aid atomAid = atom->GetBookAtomAid(); - if ( atomAid ) // atom has an identity for use in hash table? - { - morkAtomRowMap* map = this->ForceMap(ev, inCol); - if ( map ) // able to find or create index for col? - { - outRow = map->GetAid(ev, atomAid); // search for row - } - } - } - - return outRow; -} - -morkRow* -morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid) -{ - morkRow* outRow = mRowSpace_Rows.GetOid(ev, inOid); - MORK_ASSERT(outRow==0); - if ( !outRow && ev->Good() ) - { - morkStore* store = mSpace_Store; - if ( store ) - { - morkPool* pool = this->GetSpaceStorePool(); - morkRow* row = pool->NewRow(ev, &store->mStore_Zone); - if ( row ) - { - row->InitRow(ev, inOid, this, /*length*/ 0, pool); - - if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) ) - { - outRow = row; - mork_rid rid = inOid->mOid_Id; - if ( mRowSpace_NextRowId <= rid ) - mRowSpace_NextRowId = rid + 1; - } - else - pool->ZapRow(ev, row, &store->mStore_Zone); - - if ( this->IsRowSpaceClean() && store->mStore_CanDirty ) - this->MaybeDirtyStoreAndSpace(); // InitRow() does already - } - } - else - this->NilSpaceStoreError(ev); - } - return outRow; -} - -morkRow* -morkRowSpace::NewRow(morkEnv* ev) -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - mork_rid id = this->MakeNewRowId(ev); - if ( id ) - { - morkStore* store = mSpace_Store; - if ( store ) - { - mdbOid oid; - oid.mOid_Scope = this->SpaceScope(); - oid.mOid_Id = id; - morkPool* pool = this->GetSpaceStorePool(); - morkRow* row = pool->NewRow(ev, &store->mStore_Zone); - if ( row ) - { - row->InitRow(ev, &oid, this, /*length*/ 0, pool); - - if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) ) - outRow = row; - else - pool->ZapRow(ev, row, &store->mStore_Zone); - - if ( this->IsRowSpaceClean() && store->mStore_CanDirty ) - this->MaybeDirtyStoreAndSpace(); // InitRow() does already - } - } - else - this->NilSpaceStoreError(ev); - } - } - return outRow; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -morkRowSpaceMap::~morkRowSpaceMap() -{ -} - -morkRowSpaceMap::morkRowSpaceMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) - : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kRowSpaceMap; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkRowSpace.h b/db/mork/src/morkRowSpace.h deleted file mode 100644 index 6bfec5ac1fd9..000000000000 --- a/db/mork/src/morkRowSpace.h +++ /dev/null @@ -1,265 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKROWSPACE_ -#define _MORKROWSPACE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKARRAY_ -#include "morkArray.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */ - -#define morkRowSpace_kStartRowMapSlotCount 11 - -#define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */ -#define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */ - -class morkAtomRowMap; - -/*| morkRowSpace: -|*/ -class morkRowSpace : public morkSpace { // - -// public: // slots inherited from morkSpace (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkStore* mSpace_Store; // weak ref to containing store - - // mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs - // mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs - // mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment - -public: // state is public because the entire Mork system is private - - nsIMdbHeap* mRowSpace_SlotHeap; - -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMap mRowSpace_Rows; // hash table of morkRow instances -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMap mRowSpace_Rows; // hash table of morkRow instances -#endif /*MORK_ENABLE_PROBE_MAPS*/ - morkTableMap mRowSpace_Tables; // all the tables in this row scope - - mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs - mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs - - mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist - - // every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap: - morkAtomRowMap* mRowSpace_IndexCache[ morkRowSpace_kPrimeCacheSize ]; - - morkDeque mRowSpace_TablesByPriority[ morkPriority_kCount ]; - -public: // more specific dirty methods for row space: - void SetRowSpaceDirty() { this->SetNodeDirty(); } - void SetRowSpaceClean() { this->SetNodeClean(); } - - mork_bool IsRowSpaceClean() const { return this->IsNodeClean(); } - mork_bool IsRowSpaceDirty() const { return this->IsNodeDirty(); } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseRowSpace() only if open - virtual ~morkRowSpace(); // assert that CloseRowSpace() executed earlier - -public: // morkMap construction & destruction - morkRowSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope, - morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap); - void CloseRowSpace(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsRowSpace() const - { return IsNode() && mNode_Derived == morkDerived_kRowSpace; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonRowSpaceTypeError(morkEnv* ev); - static void ZeroScopeError(morkEnv* ev); - static void ZeroKindError(morkEnv* ev); - static void ZeroTidError(morkEnv* ev); - static void MinusOneRidError(morkEnv* ev); - - //static void ExpectAutoIdOnlyError(morkEnv* ev); - //static void ExpectAutoIdNeverError(morkEnv* ev); - -public: // other space methods - - mork_num CutAllRows(morkEnv* ev, morkPool* ioPool); - // CutAllRows() puts all rows and cells back into the pool. - - morkTable* NewTable(morkEnv* ev, mork_kind inTableKind, - mdb_bool inMustBeUnique, const mdbOid* inOptionalMetaRowOid); - - morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid, - mork_kind inTableKind, const mdbOid* inOptionalMetaRowOid); - - morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind); - morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid) - { return mRowSpace_Tables.GetTable(ev, inTid); } - - mork_tid MakeNewTableId(morkEnv* ev); - mork_rid MakeNewRowId(morkEnv* ev); - - // morkRow* FindRowByRid(morkEnv* ev, mork_rid inRid) - // { return (morkRow*) mRowSpace_Rows.GetRow(ev, inRid); } - - morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid); - morkRow* NewRow(morkEnv* ev); - - morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn); - - morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn); - morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn); - -protected: // internal utilities - morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakRowSpace(morkRowSpace* me, - morkEnv* ev, morkRowSpace** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongRowSpace(morkRowSpace* me, - morkEnv* ev, morkRowSpace** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kRowSpaceMap /*i*/ 0x725A /* ascii 'rZ' */ - -/*| morkRowSpaceMap: maps mork_scope -> morkRowSpace -|*/ -class morkRowSpaceMap : public morkNodeMap { // for mapping tokens to tables - -public: - - virtual ~morkRowSpaceMap(); - morkRowSpaceMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - -public: // other map methods - - mork_bool AddRowSpace(morkEnv* ev, morkRowSpace* ioRowSpace) - { return this->AddNode(ev, ioRowSpace->SpaceScope(), ioRowSpace); } - // the AddRowSpace() boolean return equals ev->Good(). - - mork_bool CutRowSpace(morkEnv* ev, mork_scope inScope) - { return this->CutNode(ev, inScope); } - // The CutRowSpace() boolean return indicates whether removal happened. - - morkRowSpace* GetRowSpace(morkEnv* ev, mork_scope inScope) - { return (morkRowSpace*) this->GetNode(ev, inScope); } - // Note the returned space does NOT have an increase in refcount for this. - - mork_num CutAllRowSpaces(morkEnv* ev) - { return this->CutAllNodes(ev); } - // CutAllRowSpaces() releases all the referenced table values. -}; - -class morkRowSpaceMapIter: public morkMapIter{ // typesafe wrapper class - -public: - morkRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkRowSpaceMapIter( ) : morkMapIter() { } - void InitRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* - FirstRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace) - { return this->First(ev, outScope, outRowSpace); } - - mork_change* - NextRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace) - { return this->Next(ev, outScope, outRowSpace); } - - mork_change* - HereRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace) - { return this->Here(ev, outScope, outRowSpace); } - - mork_change* - CutHereRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace) - { return this->CutHere(ev, outScope, outRowSpace); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKROWSPACE_ */ diff --git a/db/mork/src/morkSearchRowCursor.cpp b/db/mork/src/morkSearchRowCursor.cpp deleted file mode 100644 index bafbc1679ae2..000000000000 --- a/db/mork/src/morkSearchRowCursor.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKSEARCHROWCURSOR_ -#include "morkSearchRowCursor.h" -#endif - -#ifndef _MORKUNIQROWCURSOR_ -#include "morkUniqRowCursor.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkSearchRowCursor::CloseMorkNode(morkEnv* ev) // CloseSearchRowCursor() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseSearchRowCursor(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkSearchRowCursor::~morkSearchRowCursor() // CloseSearchRowCursor() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkSearchRowCursor::morkSearchRowCursor(morkEnv* ev, - const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos) -: morkTableRowCursor(ev, inUsage, ioHeap, ioTable, inRowPos) -// , mSortingRowCursor_Sorting( 0 ) -{ - if ( ev->Good() ) - { - if ( ioTable ) - { - // morkSorting::SlotWeakSorting(ioSorting, ev, &mSortingRowCursor_Sorting); - if ( ev->Good() ) - { - // mNode_Derived = morkDerived_kTableRowCursor; - // mNode_Derived must stay equal to kTableRowCursor - } - } - else - ev->NilPointerError(); - } -} - -/*public non-poly*/ void -morkSearchRowCursor::CloseSearchRowCursor(morkEnv* ev) -{ - if ( this ) - { - if ( this->IsNode() ) - { - // morkSorting::SlotWeakSorting((morkSorting*) 0, ev, &mSortingRowCursor_Sorting); - this->CloseTableRowCursor(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkSearchRowCursor::NonSearchRowCursorTypeError(morkEnv* ev) -{ - ev->NewError("non morkSearchRowCursor"); -} - -morkUniqRowCursor* -morkSearchRowCursor::MakeUniqCursor(morkEnv* ev) -{ - morkUniqRowCursor* outCursor = 0; - - return outCursor; -} - -#if 0 -orkinTableRowCursor* -morkSearchRowCursor::AcquireUniqueRowCursorHandle(morkEnv* ev) -{ - orkinTableRowCursor* outCursor = 0; - - morkUniqRowCursor* uniqCursor = this->MakeUniqCursor(ev); - if ( uniqCursor ) - { - outCursor = uniqCursor->AcquireTableRowCursorHandle(ev); - uniqCursor->CutStrongRef(ev); - } - return outCursor; -} -#endif -mork_bool -morkSearchRowCursor::CanHaveDupRowMembers(morkEnv* ev) -{ - return morkBool_kTrue; // true is correct -} - -mork_count -morkSearchRowCursor::GetMemberCount(morkEnv* ev) -{ - morkTable* table = mTableRowCursor_Table; - if ( table ) - return table->mTable_RowArray.mArray_Fill; - else - return 0; -} - -morkRow* -morkSearchRowCursor::NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos) -{ - morkRow* outRow = 0; - mork_pos pos = -1; - - morkTable* table = mTableRowCursor_Table; - if ( table ) - { - } - else - ev->NilPointerError(); - - *outPos = pos; - return outRow; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkSearchRowCursor.h b/db/mork/src/morkSearchRowCursor.h deleted file mode 100644 index 7f3b75d8fd12..000000000000 --- a/db/mork/src/morkSearchRowCursor.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKSEARCHROWCURSOR_ -#define _MORKSEARCHROWCURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKTABLEROWCURSOR_ -#include "morkTableRowCursor.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class morkUniqRowCursor; -class orkinTableRowCursor; -// #define morkDerived_kSearchRowCursor /*i*/ 0x7352 /* ascii 'sR' */ - -class morkSearchRowCursor : public morkTableRowCursor { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkFactory* mObject_Factory; // weak ref to suite factory - - // mork_seed mCursor_Seed; - // mork_pos mCursor_Pos; - // mork_bool mCursor_DoFailOnSeedOutOfSync; - // mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - - // morkTable* mTableRowCursor_Table; // weak ref to table - -public: // state is public because the entire Mork system is private - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseSearchRowCursor() - virtual ~morkSearchRowCursor(); // assert that close executed earlier - -public: // morkSearchRowCursor construction & destruction - morkSearchRowCursor(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos); - void CloseSearchRowCursor(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkSearchRowCursor(const morkSearchRowCursor& other); - morkSearchRowCursor& operator=(const morkSearchRowCursor& other); - -public: // dynamic type identification - // mork_bool IsSearchRowCursor() const - // { return IsNode() && mNode_Derived == morkDerived_kSearchRowCursor; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonSearchRowCursorTypeError(morkEnv* ev); - -public: // uniquify - - morkUniqRowCursor* MakeUniqCursor(morkEnv* ev); - -public: // other search row cursor methods - - virtual mork_bool CanHaveDupRowMembers(morkEnv* ev); - virtual mork_count GetMemberCount(morkEnv* ev); - -#if 0 - virtual orkinTableRowCursor* AcquireUniqueRowCursorHandle(morkEnv* ev); -#endif - - // virtual mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid); - virtual morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakSearchRowCursor(morkSearchRowCursor* me, - morkEnv* ev, morkSearchRowCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongSearchRowCursor(morkSearchRowCursor* me, - morkEnv* ev, morkSearchRowCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKSEARCHROWCURSOR_ */ diff --git a/db/mork/src/morkSink.cpp b/db/mork/src/morkSink.cpp deleted file mode 100644 index c066653894a8..000000000000 --- a/db/mork/src/morkSink.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKSINK_ -#include "morkSink.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*virtual*/ morkSink::~morkSink() -{ - mSink_At = 0; - mSink_End = 0; -} - -/*virtual*/ void -morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill -{ - morkCoil* coil = mSpool_Coil; - if ( coil ) - { - mork_u1* body = (mork_u1*) coil->mBuf_Body; - if ( body ) - { - mork_u1* at = mSink_At; - mork_u1* end = mSink_End; - if ( at >= body && at <= end ) // expected cursor order? - { - mork_fill fill = (mork_fill) (at - body); // current content size - if ( fill <= coil->mBlob_Size ) - coil->mBuf_Fill = fill; - else - { - coil->BlobFillOverSizeError(ev); - coil->mBuf_Fill = coil->mBlob_Size; // make it safe - } - } - else - this->BadSpoolCursorOrderError(ev); - } - else - coil->NilBufBodyError(ev); - } - else - this->NilSpoolCoilError(ev); -} - -/*virtual*/ void -morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte -{ - morkCoil* coil = mSpool_Coil; - if ( coil ) - { - mork_u1* body = (mork_u1*) coil->mBuf_Body; - if ( body ) - { - mork_u1* at = mSink_At; - mork_u1* end = mSink_End; - if ( at >= body && at <= end ) // expected cursor order? - { - mork_size size = coil->mBlob_Size; - mork_fill fill = (mork_fill) (at - body); // current content size - if ( fill <= size ) // less content than medium size? - { - coil->mBuf_Fill = fill; - if ( at >= end ) // need to grow the coil? - { - if ( size > 2048 ) // grow slower over 2K? - size += 512; - else - { - mork_size growth = ( size * 4 ) / 3; // grow by 33% - if ( growth < 64 ) // grow faster under (64 * 3)? - growth = 64; - size += growth; - } - if ( coil->GrowCoil(ev, size) ) // made coil bigger? - { - body = (mork_u1*) coil->mBuf_Body; - if ( body ) // have a coil body? - { - mSink_At = at = body + fill; - mSink_End = end = body + coil->mBlob_Size; - } - else - coil->NilBufBodyError(ev); - } - } - if ( ev->Good() ) // seem ready to write byte c? - { - if ( at < end ) // morkSink::Putc() would succeed? - { - *at++ = (mork_u1) c; - mSink_At = at; - coil->mBuf_Fill = fill + 1; - } - else - this->BadSpoolCursorOrderError(ev); - } - } - else // fill exceeds size - { - coil->BlobFillOverSizeError(ev); - coil->mBuf_Fill = coil->mBlob_Size; // make it safe - } - } - else - this->BadSpoolCursorOrderError(ev); - } - else - coil->NilBufBodyError(ev); - } - else - this->NilSpoolCoilError(ev); -} - -// ````` ````` ````` ````` ````` ````` ````` ````` -// public: // public non-poly morkSink methods - -/*virtual*/ -morkSpool::~morkSpool() -// Zero all slots to show this sink is disabled, but destroy no memory. -// Note it is typically unnecessary to flush this coil sink, since all -// content is written directly to the coil without any buffering. -{ - mSink_At = 0; - mSink_End = 0; - mSpool_Coil = 0; -} - -morkSpool::morkSpool(morkEnv* ev, morkCoil* ioCoil) -// After installing the coil, calls Seek(ev, 0) to prepare for writing. -: morkSink() -, mSpool_Coil( 0 ) -{ - mSink_At = 0; // set correctly later in Seek() - mSink_End = 0; // set correctly later in Seek() - - if ( ev->Good() ) - { - if ( ioCoil ) - { - mSpool_Coil = ioCoil; - this->Seek(ev, /*pos*/ 0); - } - else - ev->NilPointerError(); - } -} - -// ----- All boolean return values below are equal to ev->Good(): ----- - -/*static*/ void -morkSpool::BadSpoolCursorOrderError(morkEnv* ev) -{ - ev->NewError("bad morkSpool cursor order"); -} - -/*static*/ void -morkSpool::NilSpoolCoilError(morkEnv* ev) -{ - ev->NewError("nil mSpool_Coil"); -} - -mork_bool -morkSpool::Seek(morkEnv* ev, mork_pos inPos) -// Changed the current write position in coil's buffer to inPos. -// For example, to start writing the coil from scratch, use inPos==0. -{ - morkCoil* coil = mSpool_Coil; - if ( coil ) - { - mork_size minSize = (mork_size) (inPos + 64); - - if ( coil->mBlob_Size < minSize ) - coil->GrowCoil(ev, minSize); - - if ( ev->Good() ) - { - coil->mBuf_Fill = (mork_fill) inPos; - mork_u1* body = (mork_u1*) coil->mBuf_Body; - if ( body ) - { - mSink_At = body + inPos; - mSink_End = body + coil->mBlob_Size; - } - else - coil->NilBufBodyError(ev); - } - } - else - this->NilSpoolCoilError(ev); - - return ev->Good(); -} - -mork_bool -morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize) -// write inSize bytes of inBuf to current position inside coil's buffer -{ - // This method is conceptually very similar to morkStream::Write(), - // and this code was written while looking at that method for clues. - - morkCoil* coil = mSpool_Coil; - if ( coil ) - { - mork_u1* body = (mork_u1*) coil->mBuf_Body; - if ( body ) - { - if ( inBuf && inSize ) // anything to write? - { - mork_u1* at = mSink_At; - mork_u1* end = mSink_End; - if ( at >= body && at <= end ) // expected cursor order? - { - // note coil->mBuf_Fill can be stale after morkSink::Putc(): - mork_pos fill = at - body; // current content size - mork_num space = (mork_num) (end - at); // space left in body - if ( space < inSize ) // not enough to hold write? - { - mork_size minGrowth = space + 16; - mork_size minSize = coil->mBlob_Size + minGrowth; - if ( coil->GrowCoil(ev, minSize) ) - { - body = (mork_u1*) coil->mBuf_Body; - if ( body ) - { - mSink_At = at = body + fill; - mSink_End = end = body + coil->mBlob_Size; - space = (mork_num) (end - at); // space left in body - } - else - coil->NilBufBodyError(ev); - } - } - if ( ev->Good() ) - { - if ( space >= inSize ) // enough room to hold write? - { - MORK_MEMCPY(at, inBuf, inSize); // into body - mSink_At = at + inSize; // advance past written bytes - coil->mBuf_Fill = fill + inSize; // "flush" to fix fill - } - else - ev->NewError("insufficient morkSpool space"); - } - } - else - this->BadSpoolCursorOrderError(ev); - } - } - else - coil->NilBufBodyError(ev); - } - else - this->NilSpoolCoilError(ev); - - return ev->Good(); -} - -mork_bool -morkSpool::PutString(morkEnv* ev, const char* inString) -// call Write() with inBuf=inString and inSize=strlen(inString), -// unless inString is null, in which case we then do nothing at all. -{ - if ( inString ) - { - mork_size size = MORK_STRLEN(inString); - this->Write(ev, inString, size); - } - return ev->Good(); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkSink.h b/db/mork/src/morkSink.h deleted file mode 100644 index 0efe4110596e..000000000000 --- a/db/mork/src/morkSink.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKSINK_ -#define _MORKSINK_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| morkSink is intended to be a very cheap buffered i/o sink which -**| writes to bufs and other strings a single byte at a time. The -**| basic idea is that writing a single byte has a very cheap average -**| cost, because a polymophic function call need only occur when the -**| space between At and End is exhausted. The rest of the time a -**| very cheap inline method will write a byte, and then bump a pointer. -**| -**|| At: the current position in some sequence of bytes at which to -**| write the next byte put into the sink. Presumably At points into -**| the private storage of some space which is not yet filled (except -**| when At reaches End, and the overflow must then spill). Note both -**| At and End are zeroed in the destructor to help show that a sink -**| is no longer usable; this is safe because At==End causes the case -**| where SpillPutc() is called to handled an exhausted buffer space. -**| -**|| End: an address one byte past the last byte which can be written -**| without needing to make a buffer larger than previously. When At -**| and End are equal, this means there is no space to write a byte, -**| and that some underlying buffer space must be grown before another -**| byte can be written. Note At must always be less than or equal to -**| End, and otherwise an important invariant has failed severely. -**| -**|| Buf: this original class slot has been commented out in the new -**| and more abstract version of this sink class, but the general idea -**| behind this slot should be explained to help design subclasses. -**| Each subclass should provide space into which At and End can point, -**| where End is beyond the last writable byte, and At is less than or -**| equal to this point inside the same buffer. With some kinds of -**| medium, such as writing to an instance of morkBlob, it is feasible -**| to point directly into the final resting place for all the content -**| written to the medium. Other mediums such as files, which write -**| only through function calls, will typically need a local buffer -**| to efficiently accumulate many bytes between such function calls. -**| -**|| FlushSink: this flush method should move any buffered content to -**| its final destination. For example, for buffered writes to a -**| string medium, where string methods are function calls and not just -**| inline macros, it is faster to accumulate many bytes in a small -**| local buffer and then move these en masse later in a single call. -**| -**|| SpillPutc: when At is greater than or equal to End, this means an -**| underlying buffer has become full, so the buffer must be flushed -**| before a new byte can be written. The intention is that SpillPutc() -**| will be equivalent to calling FlushSink() followed by another call -**| to Putc(), where the flush is expected to make At less then End once -**| again. Except that FlushSink() need not make the underlying buffer -**| any larger, and SpillPutc() typically must make room for more bytes. -**| Note subclasses might want to guard against the case that both At -**| and End are null, which happens when a sink is destroyed, which sets -**| both these pointers to null as an indication the sink is disabled. -|*/ -class morkSink { - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public sink virtual methods - - virtual void FlushSink(morkEnv* ev) = 0; - virtual void SpillPutc(morkEnv* ev, int c) = 0; - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // member variables - - mork_u1* mSink_At; // pointer into mSink_Buf - mork_u1* mSink_End; // one byte past last content byte - -// define morkSink_kBufSize 256 /* small enough to go on stack */ - - // mork_u1 mSink_Buf[ morkSink_kBufSize + 4 ]; - // want plus one for any needed end null byte; use plus 4 for alignment - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkSink methods - - virtual ~morkSink(); // zero both At and End; virtual for subclasses - morkSink() { } // does nothing; subclasses must set At and End suitably - - void Putc(morkEnv* ev, int c) - { - if ( mSink_At < mSink_End ) - *mSink_At++ = (mork_u1) c; - else - this->SpillPutc(ev, c); - } -}; - -/*| morkSpool: an output sink that efficiently writes individual bytes -**| or entire byte sequences to a coil instance, which grows as needed by -**| using the heap instance in the coil to grow the internal buffer. -**| -**|| Note we do not "own" the coil referenced by mSpool_Coil, and -**| the lifetime of the coil is expected to equal or exceed that of this -**| sink by some external means. Typical usage might involve keeping an -**| instance of morkCoil and an instance of morkSpool in the same -**| owning parent object, which uses the spool with the associated coil. -|*/ -class morkSpool : public morkSink { // for buffered i/o to a morkCoil - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public sink virtual methods - - // when morkSink::Putc() moves mSink_At, mSpool_Coil->mBuf_Fill is wrong: - - virtual void FlushSink(morkEnv* ev); // sync mSpool_Coil->mBuf_Fill - virtual void SpillPutc(morkEnv* ev, int c); // grow coil and write byte - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // member variables - morkCoil* mSpool_Coil; // destination medium for written bytes - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkSink methods - - static void BadSpoolCursorOrderError(morkEnv* ev); - static void NilSpoolCoilError(morkEnv* ev); - - virtual ~morkSpool(); - // Zero all slots to show this sink is disabled, but destroy no memory. - // Note it is typically unnecessary to flush this coil sink, since all - // content is written directly to the coil without any buffering. - - morkSpool(morkEnv* ev, morkCoil* ioCoil); - // After installing the coil, calls Seek(ev, 0) to prepare for writing. - - // ----- All boolean return values below are equal to ev->Good(): ----- - - mork_bool Seek(morkEnv* ev, mork_pos inPos); - // Changed the current write position in coil's buffer to inPos. - // For example, to start writing the coil from scratch, use inPos==0. - - mork_bool Write(morkEnv* ev, const void* inBuf, mork_size inSize); - // write inSize bytes of inBuf to current position inside coil's buffer - - mork_bool PutBuf(morkEnv* ev, const morkBuf& inBuffer) - { return this->Write(ev, inBuffer.mBuf_Body, inBuffer.mBuf_Fill); } - - mork_bool PutString(morkEnv* ev, const char* inString); - // call Write() with inBuf=inString and inSize=strlen(inString), - // unless inString is null, in which case we then do nothing at all. -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKSINK_ */ diff --git a/db/mork/src/morkSpace.cpp b/db/mork/src/morkSpace.cpp deleted file mode 100644 index 63f6eb919a03..000000000000 --- a/db/mork/src/morkSpace.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKSPACE_ -#include "morkSpace.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkSpace::CloseMorkNode(morkEnv* ev) // CloseSpace() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseSpace(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkSpace::~morkSpace() // assert CloseSpace() executed earlier -{ - MORK_ASSERT(SpaceScope()==0); - MORK_ASSERT(mSpace_Store==0); - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -//morkSpace::morkSpace(morkEnv* ev, const morkUsage& inUsage, -// nsIMdbHeap* ioNodeHeap, const morkMapForm& inForm, -// nsIMdbHeap* ioSlotHeap) -//: morkNode(ev, inUsage, ioNodeHeap) -//, mSpace_Map(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap) -//{ -// ev->StubMethodOnlyError(); -//} - -/*public non-poly*/ -morkSpace::morkSpace(morkEnv* ev, - const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -: morkBead(ev, inUsage, ioHeap, inScope) -, mSpace_Store( 0 ) -, mSpace_DoAutoIDs( morkBool_kFalse ) -, mSpace_HaveDoneAutoIDs( morkBool_kFalse ) -, mSpace_CanDirty( morkBool_kFalse ) // only when store can be dirtied -{ - if ( ev->Good() ) - { - if ( ioStore && ioSlotHeap ) - { - morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store); - - mSpace_CanDirty = ioStore->mStore_CanDirty; - if ( mSpace_CanDirty ) // this new space dirties the store? - this->MaybeDirtyStoreAndSpace(); - - if ( ev->Good() ) - mNode_Derived = morkDerived_kSpace; - } - else - ev->NilPointerError(); - } -} - -/*public non-poly*/ void -morkSpace::CloseSpace(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkStore::SlotWeakStore((morkStore*) 0, ev, &mSpace_Store); - mBead_Color = 0; // this->CloseBead(); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkSpace::NonAsciiSpaceScopeName(morkEnv* ev) -{ - ev->NewError("SpaceScope() > 0x7F"); -} - -/*static*/ void -morkSpace::NilSpaceStoreError(morkEnv* ev) -{ - ev->NewError("nil mSpace_Store"); -} - -morkPool* morkSpace::GetSpaceStorePool() const -{ - return &mSpace_Store->mStore_Pool; -} - -mork_bool morkSpace::MaybeDirtyStoreAndSpace() -{ - morkStore* store = mSpace_Store; - if ( store && store->mStore_CanDirty ) - { - store->SetStoreDirty(); - mSpace_CanDirty = morkBool_kTrue; - } - - if ( mSpace_CanDirty ) - { - this->SetSpaceDirty(); - return morkBool_kTrue; - } - - return morkBool_kFalse; -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkSpace.h b/db/mork/src/morkSpace.h deleted file mode 100644 index 2a7ee2e6538f..000000000000 --- a/db/mork/src/morkSpace.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKSPACE_ -#define _MORKSPACE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKBEAD_ -#include "morkBead.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkSpace_kInitialSpaceSlots /*i*/ 1024 /* default */ -#define morkDerived_kSpace /*i*/ 0x5370 /* ascii 'Sp' */ - -/*| morkSpace: -|*/ -class morkSpace : public morkBead { // - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - -public: // bead color setter & getter replace obsolete member mTable_Id: - - mork_tid SpaceScope() const { return mBead_Color; } - void SetSpaceScope(mork_scope inScope) { mBead_Color = inScope; } - -public: // state is public because the entire Mork system is private - - morkStore* mSpace_Store; // weak ref to containing store - - mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs - mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs - mork_bool mSpace_CanDirty; // changes imply the store becomes dirty? - mork_u1 mSpace_Pad; // pad to u4 alignment - -public: // more specific dirty methods for space: - void SetSpaceDirty() { this->SetNodeDirty(); } - void SetSpaceClean() { this->SetNodeClean(); } - - mork_bool IsSpaceClean() const { return this->IsNodeClean(); } - mork_bool IsSpaceDirty() const { return this->IsNodeDirty(); } - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseSpace() only if open - virtual ~morkSpace(); // assert that CloseSpace() executed earlier - -public: // morkMap construction & destruction - //morkSpace(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioNodeHeap, - // const morkMapForm& inForm, nsIMdbHeap* ioSlotHeap); - - morkSpace(morkEnv* ev, const morkUsage& inUsage,mork_scope inScope, - morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap); - void CloseSpace(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsSpace() const - { return IsNode() && mNode_Derived == morkDerived_kSpace; } -// } ===== end morkNode methods ===== - -public: // other space methods - - mork_bool MaybeDirtyStoreAndSpace(); - - static void NonAsciiSpaceScopeName(morkEnv* ev); - static void NilSpaceStoreError(morkEnv* ev); - - morkPool* GetSpaceStorePool() const; - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakSpace(morkSpace* me, - morkEnv* ev, morkSpace** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongSpace(morkSpace* me, - morkEnv* ev, morkSpace** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKSPACE_ */ diff --git a/db/mork/src/morkStore.cpp b/db/mork/src/morkStore.cpp deleted file mode 100644 index 7475e7c0e686..000000000000 --- a/db/mork/src/morkStore.cpp +++ /dev/null @@ -1,2330 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKFACTORY_ -#include "morkFactory.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKTHUMB_ -#include "morkThumb.h" -#endif -// #ifndef _MORKFILE_ -// #include "morkFile.h" -// #endif - -#ifndef _MORKBUILDER_ -#include "morkBuilder.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKSTREAM_ -#include "morkStream.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKPORTTABLECURSOR_ -#include "morkPortTableCursor.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKPARSER_ -#include "morkParser.h" -#endif - -#include "nsCOMPtr.h" - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkStore::CloseMorkNode(morkEnv* ev) // ClosePort() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseStore(ev); - this->MarkShut(); - } -} - -/*public non-poly*/ void -morkStore::ClosePort(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkFactory::SlotWeakFactory((morkFactory*) 0, ev, &mPort_Factory); - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPort_Heap); - this->CloseObject(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -/*public virtual*/ -morkStore::~morkStore() // assert CloseStore() executed earlier -{ - MOZ_COUNT_DTOR(morkStore); - if (IsOpenNode()) - CloseMorkNode(mMorkEnv); - MORK_ASSERT(this->IsShutNode()); - MORK_ASSERT(mStore_File==0); - MORK_ASSERT(mStore_InStream==0); - MORK_ASSERT(mStore_OutStream==0); - MORK_ASSERT(mStore_Builder==0); - MORK_ASSERT(mStore_OidAtomSpace==0); - MORK_ASSERT(mStore_GroundAtomSpace==0); - MORK_ASSERT(mStore_GroundColumnSpace==0); - MORK_ASSERT(mStore_RowSpaces.IsShutNode()); - MORK_ASSERT(mStore_AtomSpaces.IsShutNode()); - MORK_ASSERT(mStore_Pool.IsShutNode()); -} - -/*public non-poly*/ -morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance - morkFactory* inFactory, // the factory for this - nsIMdbHeap* ioPortHeap // the heap to hold all content in the port - ) -: morkObject(ev, inUsage, ioNodeHeap, morkColor_kNone, (morkHandle*) 0) -, mPort_Env( ev ) -, mPort_Factory( 0 ) -, mPort_Heap( 0 ) -, mStore_OidAtomSpace( 0 ) -, mStore_GroundAtomSpace( 0 ) -, mStore_GroundColumnSpace( 0 ) - -, mStore_File( 0 ) -, mStore_InStream( 0 ) -, mStore_Builder( 0 ) -, mStore_OutStream( 0 ) - -, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap) -, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap) -, mStore_Zone(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap) -, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap) - -, mStore_CommitGroupIdentity( 0 ) - -, mStore_FirstCommitGroupPos( 0 ) -, mStore_SecondCommitGroupPos( 0 ) - -// disable auto-assignment of atom IDs until someone knows it is okay: -, mStore_CanAutoAssignAtomIdentity( morkBool_kFalse ) -, mStore_CanDirty( morkBool_kFalse ) // not until the store is open -, mStore_CanWriteIncremental( morkBool_kTrue ) // always with few exceptions -{ - MOZ_COUNT_CTOR(morkStore); - if ( ev->Good() ) - { - if ( inFactory && ioPortHeap ) - { - morkFactory::SlotWeakFactory(inFactory, ev, &mPort_Factory); - nsIMdbHeap_SlotStrongHeap(ioPortHeap, ev, &mPort_Heap); - if ( ev->Good() ) - mNode_Derived = morkDerived_kPort; - } - else - ev->NilPointerError(); - } - if ( ev->Good() ) - { - mNode_Derived = morkDerived_kStore; - - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkStore, morkObject, nsIMdbStore) - -/*public non-poly*/ void -morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - - nsIMdbFile* file = mStore_File; - file->AddRef(); - - morkFactory::SlotWeakFactory((morkFactory*) 0, ev, &mPort_Factory); - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPort_Heap); - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mStore_OidAtomSpace); - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mStore_GroundAtomSpace); - morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev, - &mStore_GroundColumnSpace); - mStore_RowSpaces.CloseMorkNode(ev); - mStore_AtomSpaces.CloseMorkNode(ev); - morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder); - - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, - &mStore_File); - - file->Release(); - - morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream); - morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_OutStream); - - mStore_Pool.CloseMorkNode(ev); - mStore_Zone.CloseMorkNode(ev); - this->ClosePort(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - - -mork_bool morkStore::DoPreferLargeOverCompressCommit(morkEnv* ev) - // true when mStore_CanWriteIncremental && store has file large enough -{ - nsIMdbFile* file = mStore_File; - if ( file && mStore_CanWriteIncremental ) - { - mdb_pos fileEof = 0; - file->Eof(ev->AsMdbEnv(), &fileEof); - if ( ev->Good() && fileEof > 128 ) - return morkBool_kTrue; - } - return morkBool_kFalse; -} - -mork_percent morkStore::PercentOfStoreWasted(morkEnv* ev) -{ - mork_percent outPercent = 0; - nsIMdbFile* file = mStore_File; - - if ( file ) - { - mork_pos firstPos = mStore_FirstCommitGroupPos; - mork_pos secondPos = mStore_SecondCommitGroupPos; - if ( firstPos || secondPos ) - { - if ( firstPos < 512 && secondPos > firstPos ) - firstPos = secondPos; // better approximation of first commit - - mork_pos fileLength = 0; - file->Eof(ev->AsMdbEnv(), &fileLength); // end of file - if ( ev->Good() && fileLength > firstPos ) - { - mork_size groupContent = fileLength - firstPos; - outPercent = ( groupContent * 100 ) / fileLength; - } - } - } - else - this->NilStoreFileError(ev); - - return outPercent; -} - -void -morkStore::SetStoreAndAllSpacesCanDirty(morkEnv* ev, mork_bool inCanDirty) -{ - mStore_CanDirty = inCanDirty; - - mork_change* c = 0; - mork_scope* key = 0; // ignore keys in maps - - if ( ev->Good() ) - { - morkAtomSpaceMapIter asi(ev, &mStore_AtomSpaces); - - morkAtomSpace* atomSpace = 0; // old val node in the map - - for ( c = asi.FirstAtomSpace(ev, key, &atomSpace); c && ev->Good(); - c = asi.NextAtomSpace(ev, key, &atomSpace) ) - { - if ( atomSpace ) - { - if ( atomSpace->IsAtomSpace() ) - atomSpace->mSpace_CanDirty = inCanDirty; - else - atomSpace->NonAtomSpaceTypeError(ev); - } - else - ev->NilPointerError(); - } - } - - if ( ev->Good() ) - { - morkRowSpaceMapIter rsi(ev, &mStore_RowSpaces); - morkRowSpace* rowSpace = 0; // old val node in the map - - for ( c = rsi.FirstRowSpace(ev, key, &rowSpace); c && ev->Good(); - c = rsi.NextRowSpace(ev, key, &rowSpace) ) - { - if ( rowSpace ) - { - if ( rowSpace->IsRowSpace() ) - rowSpace->mSpace_CanDirty = inCanDirty; - else - rowSpace->NonRowSpaceTypeError(ev); - } - } - } -} - -void -morkStore::RenumberAllCollectableContent(morkEnv* ev) -{ - MORK_USED_1(ev); - // do nothing currently -} - -nsIMdbStore* -morkStore::AcquireStoreHandle(morkEnv* ev) -{ - return this; -} - - -morkFarBookAtom* -morkStore::StageAliasAsFarBookAtom(morkEnv* ev, const morkMid* inMid, - morkAtomSpace* ioSpace, mork_cscode inForm) -{ - if ( inMid && inMid->mMid_Buf ) - { - const morkBuf* buf = inMid->mMid_Buf; - mork_size length = buf->mBuf_Fill; - if ( length <= morkBookAtom_kMaxBodySize ) - { - mork_aid dummyAid = 1; - //mStore_BookAtom.InitMaxBookAtom(ev, *buf, - // inForm, ioSpace, dummyAid); - - mStore_FarBookAtom.InitFarBookAtom(ev, *buf, - inForm, ioSpace, dummyAid); - return &mStore_FarBookAtom; - } - } - else - ev->NilPointerError(); - - return (morkFarBookAtom*) 0; -} - -morkFarBookAtom* -morkStore::StageYarnAsFarBookAtom(morkEnv* ev, const mdbYarn* inYarn, - morkAtomSpace* ioSpace) -{ - if ( inYarn && inYarn->mYarn_Buf ) - { - mork_size length = inYarn->mYarn_Fill; - if ( length <= morkBookAtom_kMaxBodySize ) - { - morkBuf buf(inYarn->mYarn_Buf, length); - mork_aid dummyAid = 1; - //mStore_BookAtom.InitMaxBookAtom(ev, buf, - // inYarn->mYarn_Form, ioSpace, dummyAid); - mStore_FarBookAtom.InitFarBookAtom(ev, buf, - inYarn->mYarn_Form, ioSpace, dummyAid); - return &mStore_FarBookAtom; - } - } - else - ev->NilPointerError(); - - return (morkFarBookAtom*) 0; -} - -morkFarBookAtom* -morkStore::StageStringAsFarBookAtom(morkEnv* ev, const char* inString, - mork_cscode inForm, morkAtomSpace* ioSpace) -{ - if ( inString ) - { - mork_size length = MORK_STRLEN(inString); - if ( length <= morkBookAtom_kMaxBodySize ) - { - morkBuf buf(inString, length); - mork_aid dummyAid = 1; - //mStore_BookAtom.InitMaxBookAtom(ev, buf, inForm, ioSpace, dummyAid); - mStore_FarBookAtom.InitFarBookAtom(ev, buf, inForm, ioSpace, dummyAid); - return &mStore_FarBookAtom; - } - } - else - ev->NilPointerError(); - - return (morkFarBookAtom*) 0; -} - -morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev) -{ - MORK_USED_1(ev); - if ( !mStore_OidAtomSpace ) - { - } - return mStore_OidAtomSpace; -} - -morkAtomSpace* morkStore::LazyGetGroundAtomSpace(morkEnv* ev) -{ - if ( !mStore_GroundAtomSpace ) - { - mork_scope atomScope = morkStore_kValueSpaceScope; - nsIMdbHeap* heap = mPort_Heap; - morkAtomSpace* space = new(*heap, ev) - morkAtomSpace(ev, morkUsage::kHeap, atomScope, this, heap, heap); - - if ( space ) // successful space creation? - { - this->MaybeDirtyStore(); - - mStore_GroundAtomSpace = space; // transfer strong ref to this slot - mStore_AtomSpaces.AddAtomSpace(ev, space); - } - } - return mStore_GroundAtomSpace; -} - -morkAtomSpace* morkStore::LazyGetGroundColumnSpace(morkEnv* ev) -{ - if ( !mStore_GroundColumnSpace ) - { - mork_scope atomScope = morkStore_kGroundColumnSpace; - nsIMdbHeap* heap = mPort_Heap; - morkAtomSpace* space = new(*heap, ev) - morkAtomSpace(ev, morkUsage::kHeap, atomScope, this, heap, heap); - - if ( space ) // successful space creation? - { - this->MaybeDirtyStore(); - - mStore_GroundColumnSpace = space; // transfer strong ref to this slot - mStore_AtomSpaces.AddAtomSpace(ev, space); - } - } - return mStore_GroundColumnSpace; -} - -morkStream* morkStore::LazyGetInStream(morkEnv* ev) -{ - if ( !mStore_InStream ) - { - nsIMdbFile* file = mStore_File; - if ( file ) - { - morkStream* stream = new(*mPort_Heap, ev) - morkStream(ev, morkUsage::kHeap, mPort_Heap, file, - morkStore_kStreamBufSize, /*frozen*/ morkBool_kTrue); - if ( stream ) - { - this->MaybeDirtyStore(); - mStore_InStream = stream; // transfer strong ref to this slot - } - } - else - this->NilStoreFileError(ev); - } - return mStore_InStream; -} - -morkStream* morkStore::LazyGetOutStream(morkEnv* ev) -{ - if ( !mStore_OutStream ) - { - nsIMdbFile* file = mStore_File; - if ( file ) - { - morkStream* stream = new(*mPort_Heap, ev) - morkStream(ev, morkUsage::kHeap, mPort_Heap, file, - morkStore_kStreamBufSize, /*frozen*/ morkBool_kFalse); - if ( stream ) - { - this->MaybeDirtyStore(); - mStore_InStream = stream; // transfer strong ref to this slot - } - } - else - this->NilStoreFileError(ev); - } - return mStore_OutStream; -} - -void -morkStore::ForgetBuilder(morkEnv* ev) -{ - if ( mStore_Builder ) - morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder); - if ( mStore_InStream ) - morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream); -} - -morkBuilder* morkStore::LazyGetBuilder(morkEnv* ev) -{ - if ( !mStore_Builder ) - { - morkStream* stream = this->LazyGetInStream(ev); - if ( stream ) - { - nsIMdbHeap* heap = mPort_Heap; - morkBuilder* builder = new(*heap, ev) - morkBuilder(ev, morkUsage::kHeap, heap, stream, - morkBuilder_kDefaultBytesPerParseSegment, heap, this); - if ( builder ) - { - mStore_Builder = builder; // transfer strong ref to this slot - } - } - } - return mStore_Builder; -} - -morkRowSpace* -morkStore::LazyGetRowSpace(morkEnv* ev, mdb_scope inRowScope) -{ - morkRowSpace* outSpace = mStore_RowSpaces.GetRowSpace(ev, inRowScope); - if ( !outSpace && ev->Good() ) // try to make new space? - { - nsIMdbHeap* heap = mPort_Heap; - outSpace = new(*heap, ev) - morkRowSpace(ev, morkUsage::kHeap, inRowScope, this, heap, heap); - - if ( outSpace ) // successful space creation? - { - this->MaybeDirtyStore(); - - // note adding to node map creates its own strong ref... - if ( mStore_RowSpaces.AddRowSpace(ev, outSpace) ) - outSpace->CutStrongRef(ev); // ...so we can drop our strong ref - } - } - return outSpace; -} - -morkAtomSpace* -morkStore::LazyGetAtomSpace(morkEnv* ev, mdb_scope inAtomScope) -{ - morkAtomSpace* outSpace = mStore_AtomSpaces.GetAtomSpace(ev, inAtomScope); - if ( !outSpace && ev->Good() ) // try to make new space? - { - if ( inAtomScope == morkStore_kValueSpaceScope ) - outSpace = this->LazyGetGroundAtomSpace(ev); - - else if ( inAtomScope == morkStore_kGroundColumnSpace ) - outSpace = this->LazyGetGroundColumnSpace(ev); - else - { - nsIMdbHeap* heap = mPort_Heap; - outSpace = new(*heap, ev) - morkAtomSpace(ev, morkUsage::kHeap, inAtomScope, this, heap, heap); - - if ( outSpace ) // successful space creation? - { - this->MaybeDirtyStore(); - - // note adding to node map creates its own strong ref... - if ( mStore_AtomSpaces.AddAtomSpace(ev, outSpace) ) - outSpace->CutStrongRef(ev); // ...so we can drop our strong ref - } - } - } - return outSpace; -} - -/*static*/ void -morkStore::NonStoreTypeError(morkEnv* ev) -{ - ev->NewError("non morkStore"); -} - -/*static*/ void -morkStore::NilStoreFileError(morkEnv* ev) -{ - ev->NewError("nil mStore_File"); -} - -/*static*/ void -morkStore::CannotAutoAssignAtomIdentityError(morkEnv* ev) -{ - ev->NewError("false mStore_CanAutoAssignAtomIdentity"); -} - - -mork_bool -morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen, - // const char* inFilePath, - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy) -{ - MORK_USED_2(inOpenPolicy,inFrozen); - nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File); - - // if ( ev->Good() ) - // { - // morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap, - // inFilePath, inFrozen); - // if ( ioFile ) - // { - // if ( ev->Good() ) - // morkFile::SlotStrongFile(file, ev, &mStore_File); - // else - // file->CutStrongRef(ev); - // - // } - // } - return ev->Good(); -} - -mork_bool -morkStore::CreateStoreFile(morkEnv* ev, - // const char* inFilePath, - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy) -{ - MORK_USED_1(inOpenPolicy); - nsIMdbFile_SlotStrongFile(ioFile, ev, &mStore_File); - - return ev->Good(); -} - -morkAtom* -morkStore::CopyAtom(morkEnv* ev, const morkAtom* inAtom) -// copy inAtom (from some other store) over to this store -{ - morkAtom* outAtom = 0; - if ( inAtom ) - { - mdbYarn yarn; - if ( inAtom->AliasYarn(&yarn) ) - outAtom = this->YarnToAtom(ev, &yarn, PR_TRUE /* create */); - } - return outAtom; -} - -morkAtom* -morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn, PRBool createIfMissing /* = PR_TRUE */) -{ - morkAtom* outAtom = 0; - if ( ev->Good() ) - { - morkAtomSpace* groundSpace = this->LazyGetGroundAtomSpace(ev); - if ( groundSpace ) - { - morkFarBookAtom* keyAtom = - this->StageYarnAsFarBookAtom(ev, inYarn, groundSpace); - - if ( keyAtom ) - { - morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies; - outAtom = map->GetAtom(ev, keyAtom); - if ( !outAtom && createIfMissing) - { - this->MaybeDirtyStore(); - outAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom); - } - } - else if ( ev->Good() ) - { - morkBuf b(inYarn->mYarn_Buf, inYarn->mYarn_Fill); - morkZone* z = &mStore_Zone; - outAtom = mStore_Pool.NewAnonAtom(ev, b, inYarn->mYarn_Form, z); - } - } - } - return outAtom; -} - -mork_bool -morkStore::MidToOid(morkEnv* ev, const morkMid& inMid, mdbOid* outOid) -{ - *outOid = inMid.mMid_Oid; - const morkBuf* buf = inMid.mMid_Buf; - if ( buf && !outOid->mOid_Scope ) - { - if ( buf->mBuf_Fill <= morkBookAtom_kMaxBodySize ) - { - if ( buf->mBuf_Fill == 1 ) - { - mork_u1* name = (mork_u1*) buf->mBuf_Body; - if ( name ) - { - outOid->mOid_Scope = (mork_scope) *name; - return ev->Good(); - } - } - morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev); - if ( groundSpace ) - { - mork_cscode form = 0; // default - mork_aid aid = 1; // dummy - mStore_FarBookAtom.InitFarBookAtom(ev, *buf, form, groundSpace, aid); - morkFarBookAtom* keyAtom = &mStore_FarBookAtom; - morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies; - morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom); - if ( bookAtom ) - outOid->mOid_Scope = bookAtom->mBookAtom_Id; - else - { - this->MaybeDirtyStore(); - bookAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom); - if ( bookAtom ) - { - outOid->mOid_Scope = bookAtom->mBookAtom_Id; - bookAtom->MakeCellUseForever(ev); - } - } - } - } - } - return ev->Good(); -} - -morkRow* -morkStore::MidToRow(morkEnv* ev, const morkMid& inMid) -{ - mdbOid tempOid; - this->MidToOid(ev, inMid, &tempOid); - return this->OidToRow(ev, &tempOid); -} - -morkTable* -morkStore::MidToTable(morkEnv* ev, const morkMid& inMid) -{ - mdbOid tempOid; - this->MidToOid(ev, inMid, &tempOid); - return this->OidToTable(ev, &tempOid, /*metarow*/ (mdbOid*) 0); -} - -mork_bool -morkStore::MidToYarn(morkEnv* ev, const morkMid& inMid, mdbYarn* outYarn) -{ - mdbOid tempOid; - this->MidToOid(ev, inMid, &tempOid); - return this->OidToYarn(ev, tempOid, outYarn); -} - -mork_bool -morkStore::OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn) -{ - morkBookAtom* atom = 0; - - morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, inOid.mOid_Scope); - if ( atomSpace ) - { - morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids; - atom = map->GetAid(ev, (mork_aid) inOid.mOid_Id); - } - atom->GetYarn(outYarn); // note this is safe even when atom==nil - - return ev->Good(); -} - -morkBookAtom* -morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid) -{ - morkBookAtom* outAtom = 0; - mdbOid oid; - if ( this->MidToOid(ev, inMid, &oid) ) - { - morkAtomSpace* atomSpace = mStore_AtomSpaces.GetAtomSpace(ev, oid.mOid_Scope); - if ( atomSpace ) - { - morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids; - outAtom = map->GetAid(ev, (mork_aid) oid.mOid_Id); - } - } - return outAtom; -} - -/*static*/ void -morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken, - mdbYarn* outYarn) -{ - MORK_USED_1(ev); - if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all? - { - mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic - buf[ 0 ] = (mork_u1) inToken; // write the single byte - outYarn->mYarn_Fill = 1; - outYarn->mYarn_More = 0; - } - else // just record we could not write the single byte - { - outYarn->mYarn_More = 1; - outYarn->mYarn_Fill = 0; - } -} - -void -morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName) -{ - if ( inToken > morkAtomSpace_kMaxSevenBitAid ) - { - morkBookAtom* atom = 0; - morkAtomSpace* space = mStore_GroundColumnSpace; - if ( space ) - atom = space->mAtomSpace_AtomAids.GetAid(ev, (mork_aid) inToken); - - atom->GetYarn(outTokenName); // note this is safe even when atom==nil - } - else // token is an "immediate" single byte string representation? - this->SmallTokenToOneByteYarn(ev, inToken, outTokenName); -} - -// void -// morkStore::SyncTokenIdChange(morkEnv* ev, const morkBookAtom* inAtom, -// const mdbOid* inOid) -// { -// mork_token mStore_MorkNoneToken; // token for "mork:none" // fill=9 -// mork_column mStore_CharsetToken; // token for "charset" // fill=7 -// mork_column mStore_AtomScopeToken; // token for "atomScope" // fill=9 -// mork_column mStore_RowScopeToken; // token for "rowScope" // fill=8 -// mork_column mStore_TableScopeToken; // token for "tableScope" // fill=10 -// mork_column mStore_ColumnScopeToken; // token for "columnScope" // fill=11 -// mork_kind mStore_TableKindToken; // token for "tableKind" // fill=9 -// ---------------------ruler-for-token-length-above---123456789012 -// -// if ( inOid->mOid_Scope == morkStore_kColumnSpaceScope && inAtom->IsWeeBook() ) -// { -// const mork_u1* body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body; -// mork_size size = inAtom->mAtom_Size; -// -// if ( size >= 7 && size <= 11 ) -// { -// if ( size == 9 ) -// { -// if ( *body == 'm' ) -// { -// if ( MORK_MEMCMP(body, "mork:none", 9) == 0 ) -// mStore_MorkNoneToken = inAtom->mBookAtom_Id; -// } -// else if ( *body == 'a' ) -// { -// if ( MORK_MEMCMP(body, "atomScope", 9) == 0 ) -// mStore_AtomScopeToken = inAtom->mBookAtom_Id; -// } -// else if ( *body == 't' ) -// { -// if ( MORK_MEMCMP(body, "tableKind", 9) == 0 ) -// mStore_TableKindToken = inAtom->mBookAtom_Id; -// } -// } -// else if ( size == 7 && *body == 'c' ) -// { -// if ( MORK_MEMCMP(body, "charset", 7) == 0 ) -// mStore_CharsetToken = inAtom->mBookAtom_Id; -// } -// else if ( size == 8 && *body == 'r' ) -// { -// if ( MORK_MEMCMP(body, "rowScope", 8) == 0 ) -// mStore_RowScopeToken = inAtom->mBookAtom_Id; -// } -// else if ( size == 10 && *body == 't' ) -// { -// if ( MORK_MEMCMP(body, "tableScope", 10) == 0 ) -// mStore_TableScopeToken = inAtom->mBookAtom_Id; -// } -// else if ( size == 11 && *body == 'c' ) -// { -// if ( MORK_MEMCMP(body, "columnScope", 11) == 0 ) -// mStore_ColumnScopeToken = inAtom->mBookAtom_Id; -// } -// } -// } -// } - -morkAtom* -morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm) -{ - morkBookAtom* outAtom = 0; - if ( ev->Good() ) - { - const mdbOid* oid = &inMid.mMid_Oid; - morkAtomSpace* atomSpace = this->LazyGetAtomSpace(ev, oid->mOid_Scope); - if ( atomSpace ) - { - morkFarBookAtom* keyAtom = - this->StageAliasAsFarBookAtom(ev, &inMid, atomSpace, inForm); - if ( keyAtom ) - { - morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids; - outAtom = map->GetAid(ev, (mork_aid) oid->mOid_Id); - if ( outAtom ) - { - if ( !outAtom->EqualFormAndBody(ev, keyAtom) ) - ev->NewError("duplicate alias ID"); - } - else - { - this->MaybeDirtyStore(); - keyAtom->mBookAtom_Id = oid->mOid_Id; - outAtom = atomSpace->MakeBookAtomCopyWithAid(ev, - *keyAtom, (mork_aid) oid->mOid_Id); - - // if ( outAtom && outAtom->IsWeeBook() ) - // { - // if ( oid->mOid_Scope == morkStore_kColumnSpaceScope ) - // { - // mork_size size = outAtom->mAtom_Size; - // if ( size >= 7 && size <= 11 ) - // this->SyncTokenIdChange(ev, outAtom, oid); - // } - // } - } - } - } - } - return outAtom; -} - -#define morkStore_kMaxCopyTokenSize 512 /* if larger, cannot be copied */ - -mork_token -morkStore::CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore) -// copy inToken from inStore over to this store -{ - mork_token outToken = 0; - if ( inStore == this ) // same store? - outToken = inToken; // just return token unchanged - else - { - char yarnBuf[ morkStore_kMaxCopyTokenSize ]; - mdbYarn yarn; - yarn.mYarn_Buf = yarnBuf; - yarn.mYarn_Fill = 0; - yarn.mYarn_Size = morkStore_kMaxCopyTokenSize; - yarn.mYarn_More = 0; - yarn.mYarn_Form = 0; - yarn.mYarn_Grow = 0; - - inStore->TokenToString(ev, inToken, &yarn); - if ( ev->Good() ) - { - morkBuf buf(yarn.mYarn_Buf, yarn.mYarn_Fill); - outToken = this->BufToToken(ev, &buf); - } - } - return outToken; -} - -mork_token -morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf) -{ - mork_token outToken = 0; - if ( ev->Good() ) - { - const mork_u1* s = (const mork_u1*) inBuf->mBuf_Body; - mork_bool nonAscii = ( *s > 0x7F ); - mork_size length = inBuf->mBuf_Fill; - if ( nonAscii || length > 1 ) // more than one byte? - { - mork_cscode form = 0; // default charset - morkAtomSpace* space = this->LazyGetGroundColumnSpace(ev); - if ( space ) - { - morkFarBookAtom* keyAtom = 0; - if ( length <= morkBookAtom_kMaxBodySize ) - { - mork_aid aid = 1; // dummy - //mStore_BookAtom.InitMaxBookAtom(ev, *inBuf, form, space, aid); - mStore_FarBookAtom.InitFarBookAtom(ev, *inBuf, form, space, aid); - keyAtom = &mStore_FarBookAtom; - } - if ( keyAtom ) - { - morkAtomBodyMap* map = &space->mAtomSpace_AtomBodies; - morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom); - if ( bookAtom ) - outToken = bookAtom->mBookAtom_Id; - else - { - this->MaybeDirtyStore(); - bookAtom = space->MakeBookAtomCopy(ev, *keyAtom); - if ( bookAtom ) - { - outToken = bookAtom->mBookAtom_Id; - bookAtom->MakeCellUseForever(ev); - } - } - } - } - } - else // only a single byte in inTokenName string: - outToken = *s; - } - - return outToken; -} - -mork_token -morkStore::StringToToken(morkEnv* ev, const char* inTokenName) -{ - mork_token outToken = 0; - if ( ev->Good() ) - { - const mork_u1* s = (const mork_u1*) inTokenName; - mork_bool nonAscii = ( *s > 0x7F ); - if ( nonAscii || ( *s && s[ 1 ] ) ) // more than one byte? - { - mork_cscode form = 0; // default charset - morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev); - if ( groundSpace ) - { - morkFarBookAtom* keyAtom = - this->StageStringAsFarBookAtom(ev, inTokenName, form, groundSpace); - if ( keyAtom ) - { - morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies; - morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom); - if ( bookAtom ) - outToken = bookAtom->mBookAtom_Id; - else - { - this->MaybeDirtyStore(); - bookAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom); - if ( bookAtom ) - { - outToken = bookAtom->mBookAtom_Id; - bookAtom->MakeCellUseForever(ev); - } - } - } - } - } - else // only a single byte in inTokenName string: - outToken = *s; - } - - return outToken; -} - -mork_token -morkStore::QueryToken(morkEnv* ev, const char* inTokenName) -{ - mork_token outToken = 0; - if ( ev->Good() ) - { - const mork_u1* s = (const mork_u1*) inTokenName; - mork_bool nonAscii = ( *s > 0x7F ); - if ( nonAscii || ( *s && s[ 1 ] ) ) // more than one byte? - { - mork_cscode form = 0; // default charset - morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev); - if ( groundSpace ) - { - morkFarBookAtom* keyAtom = - this->StageStringAsFarBookAtom(ev, inTokenName, form, groundSpace); - if ( keyAtom ) - { - morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies; - morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom); - if ( bookAtom ) - { - outToken = bookAtom->mBookAtom_Id; - bookAtom->MakeCellUseForever(ev); - } - } - } - } - else // only a single byte in inTokenName string: - outToken = *s; - } - - return outToken; -} - -mork_bool -morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_count* outTableCount) -{ - MORK_USED_2(inRowScope,inTableKind); - mork_bool outBool = morkBool_kFalse; - mdb_count tableCount = 0; - - ev->StubMethodOnlyError(); - - if ( outTableCount ) - *outTableCount = tableCount; - return outBool; -} - -morkTable* -morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_count* outTableCount, - mdb_bool* outMustBeUnique) -{ - morkTable* outTable = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope); - if ( rowSpace ) - { - outTable = rowSpace->FindTableByKind(ev, inTableKind); - if ( outTable ) - { - if ( outTableCount ) - *outTableCount = outTable->GetRowCount(); - if ( outMustBeUnique ) - *outMustBeUnique = outTable->IsTableUnique(); - } - } - } - return outTable; -} - -morkRow* -morkStore::FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn, - const mdbYarn* inYarn) -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inScope); - if ( rowSpace ) - { - outRow = rowSpace->FindRow(ev, inColumn, inYarn); - } - } - return outRow; -} - -morkRow* -morkStore::GetRow(morkEnv* ev, const mdbOid* inOid) -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope); - if ( rowSpace ) - { - outRow = rowSpace->mRowSpace_Rows.GetOid(ev, inOid); - } - } - return outRow; -} - -morkTable* -morkStore::GetTable(morkEnv* ev, const mdbOid* inOid) -{ - morkTable* outTable = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope); - if ( rowSpace ) - { - outTable = rowSpace->FindTableByTid(ev, inOid->mOid_Id); - } - } - return outTable; -} - -morkTable* -morkStore::NewTable(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_bool inMustBeUnique, - const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying -{ - morkTable* outTable = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope); - if ( rowSpace ) - outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique, - inOptionalMetaRowOid); - } - return outTable; -} - -morkPortTableCursor* -morkStore::GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind) -{ - morkPortTableCursor* outCursor = 0; - if ( ev->Good() ) - { - nsIMdbHeap* heap = mPort_Heap; - outCursor = new(*heap, ev) - morkPortTableCursor(ev, morkUsage::kHeap, heap, this, - inRowScope, inTableKind, heap); - } - NS_IF_ADDREF(outCursor); - return outCursor; -} - -morkRow* -morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope) -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope); - if ( rowSpace ) - outRow = rowSpace->NewRow(ev); - } - return outRow; -} - -morkRow* -morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid) -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope); - if ( rowSpace ) - outRow = rowSpace->NewRowWithOid(ev, inOid); - } - return outRow; -} - -morkRow* -morkStore::OidToRow(morkEnv* ev, const mdbOid* inOid) - // OidToRow() finds old row with oid, or makes new one if not found. -{ - morkRow* outRow = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope); - if ( rowSpace ) - { - outRow = rowSpace->mRowSpace_Rows.GetOid(ev, inOid); - if ( !outRow && ev->Good() ) - outRow = rowSpace->NewRowWithOid(ev, inOid); - } - } - return outRow; -} - -morkTable* -morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid, - const mdbOid* inOptionalMetaRowOid) // can be nil to avoid specifying - // OidToTable() finds old table with oid, or makes new one if not found. -{ - morkTable* outTable = 0; - if ( ev->Good() ) - { - morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope); - if ( rowSpace ) - { - outTable = rowSpace->mRowSpace_Tables.GetTable(ev, inOid->mOid_Id); - if ( !outTable && ev->Good() ) - { - mork_kind tableKind = morkStore_kNoneToken; - outTable = rowSpace->NewTableWithTid(ev, inOid->mOid_Id, tableKind, - inOptionalMetaRowOid); - } - } - } - return outTable; -} - -// { ===== begin nsIMdbObject methods ===== - -// { ----- begin ref counting for well-behaved cyclic graphs ----- -NS_IMETHODIMP -morkStore::GetWeakRefCount(nsIMdbEnv* mev, // weak refs - mdb_count* outCount) -{ - *outCount = WeakRefsOnly(); - return NS_OK; -} -NS_IMETHODIMP -morkStore::GetStrongRefCount(nsIMdbEnv* mev, // strong refs - mdb_count* outCount) -{ - *outCount = StrongRefsOnly(); - return NS_OK; -} -// ### TODO - clean up this cast, if required -NS_IMETHODIMP -morkStore::AddWeakRef(nsIMdbEnv* mev) -{ - morkEnv *ev = morkEnv::FromMdbEnv(mev); - return morkNode::AddWeakRef(ev); -} -NS_IMETHODIMP -morkStore::AddStrongRef(nsIMdbEnv* mev) -{ - return AddRef(); -} - -NS_IMETHODIMP -morkStore::CutWeakRef(nsIMdbEnv* mev) -{ - morkEnv *ev = morkEnv::FromMdbEnv(mev); - return morkNode::CutWeakRef(ev); -} -NS_IMETHODIMP -morkStore::CutStrongRef(nsIMdbEnv* mev) -{ - return Release(); -} - -NS_IMETHODIMP -morkStore::CloseMdbObject(nsIMdbEnv* mev) -{ - morkEnv *ev = morkEnv::FromMdbEnv(mev); - CloseMorkNode(ev); - Release(); - return NS_OK; -} - -NS_IMETHODIMP -morkStore::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen) -{ - *outOpen = IsOpenNode(); - return NS_OK; -} -// } ----- end ref counting ----- - -// } ===== end nsIMdbObject methods ===== - -// { ===== begin nsIMdbPort methods ===== - -// { ----- begin attribute methods ----- -NS_IMETHODIMP -morkStore::GetIsPortReadonly(nsIMdbEnv* mev, mdb_bool* outBool) -{ - mdb_err outErr = 0; - mdb_bool isReadOnly = morkBool_kFalse; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - ev->StubMethodOnlyError(); - outErr = ev->AsErr(); - } - if ( outBool ) - *outBool = isReadOnly; - return outErr; -} - -morkEnv* -morkStore::CanUseStore(nsIMdbEnv* mev, - mork_bool inMutable, mdb_err* outErr) const -{ - morkEnv* outEnv = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if (IsStore()) - outEnv = ev; - else - NonStoreTypeError(ev); - *outErr = ev->AsErr(); - } - MORK_ASSERT(outEnv); - return outEnv; -} - -NS_IMETHODIMP -morkStore::GetIsStore(nsIMdbEnv* mev, mdb_bool* outBool) -{ - MORK_USED_1(mev); - if ( outBool ) - *outBool = morkBool_kTrue; - return 0; -} - -NS_IMETHODIMP -morkStore::GetIsStoreAndDirty(nsIMdbEnv* mev, mdb_bool* outBool) -{ - mdb_err outErr = 0; - mdb_bool isStoreAndDirty = morkBool_kFalse; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - ev->StubMethodOnlyError(); - outErr = ev->AsErr(); - } - if ( outBool ) - *outBool = isStoreAndDirty; - return outErr; -} - -NS_IMETHODIMP -morkStore::GetUsagePolicy(nsIMdbEnv* mev, - mdbUsagePolicy* ioUsagePolicy) -{ - MORK_USED_1(ioUsagePolicy); - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - ev->StubMethodOnlyError(); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::SetUsagePolicy(nsIMdbEnv* mev, - const mdbUsagePolicy* inUsagePolicy) -{ - MORK_USED_1(inUsagePolicy); - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing? - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin memory policy methods ----- -NS_IMETHODIMP -morkStore::IdleMemoryPurge( // do memory management already scheduled - nsIMdbEnv* mev, // context - mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed -{ - mdb_err outErr = 0; - mdb_size estimatedBytesFreed = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing? - outErr = ev->AsErr(); - } - if ( outEstimatedBytesFreed ) - *outEstimatedBytesFreed = estimatedBytesFreed; - return outErr; -} - -NS_IMETHODIMP -morkStore::SessionMemoryPurge( // request specific footprint decrease - nsIMdbEnv* mev, // context - mdb_size inDesiredBytesFreed, // approximate number of bytes wanted - mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed -{ - MORK_USED_1(inDesiredBytesFreed); - mdb_err outErr = 0; - mdb_size estimate = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing? - outErr = ev->AsErr(); - } - if ( outEstimatedBytesFreed ) - *outEstimatedBytesFreed = estimate; - return outErr; -} - -NS_IMETHODIMP -morkStore::PanicMemoryPurge( // desperately free all possible memory - nsIMdbEnv* mev, // context - mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed -{ - mdb_err outErr = 0; - mdb_size estimate = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing? - outErr = ev->AsErr(); - } - if ( outEstimatedBytesFreed ) - *outEstimatedBytesFreed = estimate; - return outErr; -} -// } ----- end memory policy methods ----- - -// { ----- begin filepath methods ----- -NS_IMETHODIMP -morkStore::GetPortFilePath( - nsIMdbEnv* mev, // context - mdbYarn* outFilePath, // name of file holding port content - mdbYarn* outFormatVersion) // file format description -{ - mdb_err outErr = 0; - if ( outFormatVersion ) - outFormatVersion->mYarn_Fill = 0; - if ( outFilePath ) - outFilePath->mYarn_Fill = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - if ( mStore_File ) - mStore_File->Path(mev, outFilePath); - else - NilStoreFileError(ev); - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::GetPortFile( - nsIMdbEnv* mev, // context - nsIMdbFile** acqFile) // acquire file used by port or store -{ - mdb_err outErr = 0; - if ( acqFile ) - *acqFile = 0; - - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - - if ( mStore_File ) - { - if ( acqFile ) - { - mStore_File->AddRef(); - if ( ev->Good() ) - *acqFile = mStore_File; - } - } - else - NilStoreFileError(ev); - - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end filepath methods ----- - -// { ----- begin export methods ----- -NS_IMETHODIMP -morkStore::BestExportFormat( // determine preferred export format - nsIMdbEnv* mev, // context - mdbYarn* outFormatVersion) // file format description -{ - mdb_err outErr = 0; - if ( outFormatVersion ) - outFormatVersion->mYarn_Fill = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - ev->StubMethodOnlyError(); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::CanExportToFormat( // can export content in given specific format? - nsIMdbEnv* mev, // context - const char* inFormatVersion, // file format description - mdb_bool* outCanExport) // whether ExportSource() might succeed -{ - MORK_USED_1(inFormatVersion); - mdb_bool canExport = morkBool_kFalse; - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - ev->StubMethodOnlyError(); - outErr = ev->AsErr(); - } - if ( outCanExport ) - *outCanExport = canExport; - return outErr; -} - -NS_IMETHODIMP -morkStore::ExportToFormat( // export content in given specific format - nsIMdbEnv* mev, // context - // const char* inFilePath, // the file to receive exported content - nsIMdbFile* ioFile, // destination abstract file interface - const char* inFormatVersion, // file format description - nsIMdbThumb** acqThumb) // acquire thumb for incremental export -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the export will be finished. -{ - mdb_err outErr = 0; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - if ( ioFile && inFormatVersion && acqThumb ) - { - ev->StubMethodOnlyError(); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} - -// } ----- end export methods ----- - -// { ----- begin token methods ----- -NS_IMETHODIMP -morkStore::TokenToString( // return a string name for an integer token - nsIMdbEnv* mev, // context - mdb_token inToken, // token for inTokenName inside this port - mdbYarn* outTokenName) // the type of table to access -{ - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - TokenToString(ev, inToken, outTokenName); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::StringToToken( // return an integer token for scope name - nsIMdbEnv* mev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken) // token for inTokenName inside this port - // String token zero is never used and never supported. If the port - // is a mutable store, then StringToToken() to create a new - // association of inTokenName with a new integer token if possible. - // But a readonly port will return zero for an unknown scope name. -{ - mdb_err outErr = 0; - mdb_token token = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - token = StringToToken(ev, inTokenName); - outErr = ev->AsErr(); - } - if ( outToken ) - *outToken = token; - return outErr; -} - - -NS_IMETHODIMP -morkStore::QueryToken( // like StringToToken(), but without adding - nsIMdbEnv* mev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken) // token for inTokenName inside this port - // QueryToken() will return a string token if one already exists, - // but unlike StringToToken(), will not assign a new token if not - // already in use. -{ - mdb_err outErr = 0; - mdb_token token = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - token = QueryToken(ev, inTokenName); - outErr = ev->AsErr(); - } - if ( outToken ) - *outToken = token; - return outErr; -} - - -// } ----- end token methods ----- - -// { ----- begin row methods ----- -NS_IMETHODIMP -morkStore::HasRow( // contains a row with the specified oid? - nsIMdbEnv* mev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_bool* outHasRow) // whether GetRow() might succeed -{ - mdb_err outErr = 0; - mdb_bool hasRow = morkBool_kFalse; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = GetRow(ev, inOid); - if ( row ) - hasRow = morkBool_kTrue; - - outErr = ev->AsErr(); - } - if ( outHasRow ) - *outHasRow = hasRow; - return outErr; -} - -NS_IMETHODIMP -morkStore::GetRow( // access one row with specific oid - nsIMdbEnv* mev, // context - const mdbOid* inOid, // hypothetical row oid - nsIMdbRow** acqRow) // acquire specific row (or null) -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = GetRow(ev, inOid); - if ( row && ev->Good() ) - outRow = row->AcquireRowHandle(ev, this); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP -morkStore::GetRowRefCount( // get number of tables that contain a row - nsIMdbEnv* mev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_count* outRefCount) // number of tables containing inRowKey -{ - mdb_err outErr = 0; - mdb_count count = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = GetRow(ev, inOid); - if ( row && ev->Good() ) - count = row->mRow_GcUses; - - outErr = ev->AsErr(); - } - if ( outRefCount ) - *outRefCount = count; - return outErr; -} - -NS_IMETHODIMP -morkStore::FindRow(nsIMdbEnv* mev, // search for row with matching cell - mdb_scope inRowScope, // row scope for row ids - mdb_column inColumn, // the column to search (and maintain an index) - const mdbYarn* inTargetCellValue, // cell value for which to search - mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match) - nsIMdbRow** acqRow) // acquire matching row (or nil for no match) - // FindRow() searches for one row that has a cell in column inColumn with - // a contained value with the same form (i.e. charset) and is byte-wise - // identical to the blob described by yarn inTargetCellValue. Both content - // and form of the yarn must be an exact match to find a matching row. - // - // (In other words, both a yarn's blob bytes and form are significant. The - // form is not expected to vary in columns used for identity anyway. This - // is intended to make the cost of FindRow() cheaper for MDB implementors, - // since any cell value atomization performed internally must necessarily - // make yarn form significant in order to avoid data loss in atomization.) - // - // FindRow() can lazily create an index on attribute inColumn for all rows - // with that attribute in row space scope inRowScope, so that subsequent - // calls to FindRow() will perform faster. Such an index might or might - // not be persistent (but this seems desirable if it is cheap to do so). - // Note that lazy index creation in readonly DBs is not very feasible. - // - // This FindRow() interface assumes that attribute inColumn is effectively - // an alternative means of unique identification for a row in a rowspace, - // so correct behavior is only guaranteed when no duplicates for this col - // appear in the given set of rows. (If more than one row has the same cell - // value in this column, no more than one will be found; and cutting one of - // two duplicate rows can cause the index to assume no other such row lives - // in the row space, so future calls return nil for negative search results - // even though some duplicate row might still live within the rowspace.) - // - // In other words, the FindRow() implementation is allowed to assume simple - // hash tables mapping unqiue column keys to associated row values will be - // sufficient, where any duplication is not recorded because only one copy - // of a given key need be remembered. Implementors are not required to sort - // all rows by the specified column. -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - mdbOid rowOid; - rowOid.mOid_Scope = 0; - rowOid.mOid_Id = (mdb_id) -1; - - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = FindRow(ev, inRowScope, inColumn, inTargetCellValue); - if ( row && ev->Good() ) - { - rowOid = row->mRow_Oid; - if ( acqRow ) - outRow = row->AcquireRowHandle(ev, this); - } - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - if ( outRowOid ) - *outRowOid = rowOid; - - return outErr; -} - -// } ----- end row methods ----- - -// { ----- begin table methods ----- -NS_IMETHODIMP -morkStore::HasTable( // supports a table with the specified oid? - nsIMdbEnv* mev, // context - const mdbOid* inOid, // hypothetical table oid - mdb_bool* outHasTable) // whether GetTable() might succeed -{ - mdb_err outErr = 0; - mork_bool hasTable = morkBool_kFalse; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = GetTable(ev, inOid); - if ( table ) - hasTable = morkBool_kTrue; - - outErr = ev->AsErr(); - } - if ( outHasTable ) - *outHasTable = hasTable; - return outErr; -} - -NS_IMETHODIMP -morkStore::GetTable( // access one table with specific oid - nsIMdbEnv* mev, // context - const mdbOid* inOid, // hypothetical table oid - nsIMdbTable** acqTable) // acquire specific table (or null) -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = GetTable(ev, inOid); - if ( table && ev->Good() ) - outTable = table->AcquireTableHandle(ev); - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} - -NS_IMETHODIMP -morkStore::HasTableKind( // supports a table of the specified type? - nsIMdbEnv* mev, // context - mdb_scope inRowScope, // rid scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outSupportsTable) // whether GetTableKind() might succeed -{ - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - *outSupportsTable = HasTableKind(ev, inRowScope, - inTableKind, outTableCount); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::GetTableKind( // access one (random) table of specific type - nsIMdbEnv* mev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outMustBeUnique, // whether port can hold only one of these - nsIMdbTable** acqTable) // acquire scoped collection of rows -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = GetTableKind(ev, inRowScope, - inTableKind, outTableCount, outMustBeUnique); - if ( table && ev->Good() ) - outTable = table->AcquireTableHandle(ev); - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} - -NS_IMETHODIMP -morkStore::GetPortTableCursor( // get cursor for all tables of specific type - nsIMdbEnv* mev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - nsIMdbPortTableCursor** acqCursor) // all such tables in the port -{ - mdb_err outErr = 0; - nsIMdbPortTableCursor* outCursor = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkPortTableCursor* cursor = - GetPortTableCursor(ev, inRowScope, - inTableKind); - if ( cursor && ev->Good() ) - outCursor = cursor; - - outErr = ev->AsErr(); - } - if ( acqCursor ) - *acqCursor = outCursor; - return outErr; -} -// } ----- end table methods ----- - -// { ----- begin commit methods ----- - -NS_IMETHODIMP -morkStore::ShouldCompress( // store wastes at least inPercentWaste? - nsIMdbEnv* mev, // context - mdb_percent inPercentWaste, // 0..100 percent file size waste threshold - mdb_percent* outActualWaste, // 0..100 percent of file actually wasted - mdb_bool* outShould) // true when about inPercentWaste% is wasted -{ - mdb_percent actualWaste = 0; - mdb_bool shouldCompress = morkBool_kFalse; - mdb_err outErr = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - actualWaste = PercentOfStoreWasted(ev); - if ( inPercentWaste > 100 ) - inPercentWaste = 100; - shouldCompress = ( actualWaste >= inPercentWaste ); - outErr = ev->AsErr(); - } - if ( outActualWaste ) - *outActualWaste = actualWaste; - if ( outShould ) - *outShould = shouldCompress; - return outErr; -} - - -// } ===== end nsIMdbPort methods ===== - -NS_IMETHODIMP -morkStore::NewTable( // make one new table of specific type - nsIMdbEnv* mev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable) // acquire scoped collection of rows -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = NewTable(ev, inRowScope, - inTableKind, inMustBeUnique, inOptionalMetaRowOid); - if ( table && ev->Good() ) - outTable = table->AcquireTableHandle(ev); - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} - -NS_IMETHODIMP -morkStore::NewTableWithOid( // make one new table of specific type - nsIMdbEnv* mev, // context - const mdbOid* inOid, // caller assigned oid - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable) // acquire scoped collection of rows -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkTable* table = OidToTable(ev, inOid, - inOptionalMetaRowOid); - if ( table && ev->Good() ) - { - table->mTable_Kind = inTableKind; - if ( inMustBeUnique ) - table->SetTableUnique(); - outTable = table->AcquireTableHandle(ev); - } - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} -// } ----- end table methods ----- - -// { ----- begin row scope methods ----- -NS_IMETHODIMP -morkStore::RowScopeHasAssignedIds(nsIMdbEnv* mev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) // nonzero if store db assigned specified -{ - NS_ASSERTION(PR_FALSE, " not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkStore::SetCallerAssignedIds(nsIMdbEnv* mev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) // nonzero if store db assigned specified -{ - NS_ASSERTION(PR_FALSE, " not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkStore::SetStoreAssignedIds(nsIMdbEnv* mev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned) // nonzero if store db assigned specified -{ - NS_ASSERTION(PR_FALSE, " not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end row scope methods ----- - -// { ----- begin row methods ----- -NS_IMETHODIMP -morkStore::NewRowWithOid(nsIMdbEnv* mev, // new row w/ caller assigned oid - const mdbOid* inOid, // caller assigned oid - nsIMdbRow** acqRow) // create new row -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = NewRowWithOid(ev, inOid); - if ( row && ev->Good() ) - outRow = row->AcquireRowHandle(ev, this); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP -morkStore::NewRow(nsIMdbEnv* mev, // new row with db assigned oid - mdb_scope inRowScope, // row scope for row ids - nsIMdbRow** acqRow) // create new row -// Note this row must be added to some table or cell child before the -// store is closed in order to make this row persist across sesssions. -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - morkRow* row = NewRow(ev, inRowScope); - if ( row && ev->Good() ) - outRow = row->AcquireRowHandle(ev, this); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} -// } ----- end row methods ----- - -// { ----- begin inport/export methods ----- -NS_IMETHODIMP -morkStore::ImportContent( // import content from port - nsIMdbEnv* mev, // context - mdb_scope inRowScope, // scope for rows (or zero for all?) - nsIMdbPort* ioPort, // the port with content to add to store - nsIMdbThumb** acqThumb) // acquire thumb for incremental import -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the import will be finished. -{ - NS_ASSERTION(PR_FALSE, " not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkStore::ImportFile( // import content from port - nsIMdbEnv* mev, // context - nsIMdbFile* ioFile, // the file with content to add to store - nsIMdbThumb** acqThumb) // acquire thumb for incremental import -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the import will be finished. -{ - NS_ASSERTION(PR_FALSE, " not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end inport/export methods ----- - -// { ----- begin hinting methods ----- -NS_IMETHODIMP -morkStore::ShareAtomColumnsHint( // advise re shared col content atomizing - nsIMdbEnv* mev, // context - mdb_scope inScopeHint, // zero, or suggested shared namespace - const mdbColumnSet* inColumnSet) // cols desired tokenized together -{ - MORK_USED_2(inColumnSet,inScopeHint); - mdb_err outErr = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing for a hint method - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::AvoidAtomColumnsHint( // advise col w/ poor atomizing prospects - nsIMdbEnv* mev, // context - const mdbColumnSet* inColumnSet) // cols with poor atomizing prospects -{ - MORK_USED_1(inColumnSet); - mdb_err outErr = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // okay to do nothing for a hint method - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end hinting methods ----- - -// { ----- begin commit methods ----- -NS_IMETHODIMP -morkStore::SmallCommit( // save minor changes if convenient and uncostly - nsIMdbEnv* mev) // context -{ - mdb_err outErr = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - // ev->StubMethodOnlyError(); // it's okay to do nothing for small commit - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkStore::LargeCommit( // save important changes if at all possible - nsIMdbEnv* mev, // context - nsIMdbThumb** acqThumb) // acquire thumb for incremental commit -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the commit will be finished. Note the store is effectively write -// locked until commit is finished or canceled through the thumb instance. -// Until the commit is done, the store will report it has readonly status. -{ - nsresult outErr = 0; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - - morkThumb* thumb = 0; - // morkFile* file = store->mStore_File; - if ( DoPreferLargeOverCompressCommit(ev) ) - { - thumb = morkThumb::Make_LargeCommit(ev, mPort_Heap, this); - } - else - { - mork_bool doCollect = morkBool_kFalse; - thumb = morkThumb::Make_CompressCommit(ev, mPort_Heap, this, doCollect); - } - - if ( thumb ) - { - outThumb = thumb; - thumb->AddRef(); - } - - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} - -NS_IMETHODIMP -morkStore::SessionCommit( // save all changes if large commits delayed - nsIMdbEnv* mev, // context - nsIMdbThumb** acqThumb) // acquire thumb for incremental commit -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the commit will be finished. Note the store is effectively write -// locked until commit is finished or canceled through the thumb instance. -// Until the commit is done, the store will report it has readonly status. -{ - nsresult outErr = NS_OK; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - - morkThumb* thumb = 0; - if ( DoPreferLargeOverCompressCommit(ev) ) - { - thumb = morkThumb::Make_LargeCommit(ev, mPort_Heap, this); - } - else - { - mork_bool doCollect = morkBool_kFalse; - thumb = morkThumb::Make_CompressCommit(ev, mPort_Heap, this, doCollect); - } - - if ( thumb ) - { - outThumb = thumb; - thumb->AddRef(); - } - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} - -NS_IMETHODIMP -morkStore::CompressCommit( // commit and make db smaller if possible - nsIMdbEnv* mev, // context - nsIMdbThumb** acqThumb) // acquire thumb for incremental commit -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the commit will be finished. Note the store is effectively write -// locked until commit is finished or canceled through the thumb instance. -// Until the commit is done, the store will report it has readonly status. -{ - nsresult outErr = NS_OK; - nsIMdbThumb* outThumb = 0; - morkEnv* ev = CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr); - if ( ev ) - { - mork_bool doCollect = morkBool_kFalse; - morkThumb* thumb = morkThumb::Make_CompressCommit(ev, mPort_Heap, this, doCollect); - if ( thumb ) - { - outThumb = thumb; - thumb->AddRef(); - mStore_CanWriteIncremental = morkBool_kTrue; - } - - outErr = ev->AsErr(); - } - if ( acqThumb ) - *acqThumb = outThumb; - return outErr; -} - -// } ----- end commit methods ----- - -// } ===== end nsIMdbStore methods ===== - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkStore.h b/db/mork/src/morkStore.h deleted file mode 100644 index f16c4f5c8f11..000000000000 --- a/db/mork/src/morkStore.h +++ /dev/null @@ -1,794 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKSTORE_ -#define _MORKSTORE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -#ifndef _MORKPOOL_ -#include "morkPool.h" -#endif - -#ifndef _MORKZONE_ -#include "morkZone.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kPort /*i*/ 0x7054 /* ascii 'pT' */ - -#define morkDerived_kStore /*i*/ 0x7354 /* ascii 'sT' */ - -/*| kGroundColumnSpace: we use the 'column space' as the default scope -**| for grounding column name IDs, and this is also the default scope for -**| all other explicitly tokenized strings. -|*/ -#define morkStore_kGroundColumnSpace 'c' /* for mStore_GroundColumnSpace*/ -#define morkStore_kColumnSpaceScope ((mork_scope) 'c') /*kGroundColumnSpace*/ -#define morkStore_kValueSpaceScope ((mork_scope) 'v') -#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */ - -#define morkStore_kReservedColumnCount 0x20 /* for well-known columns */ - -#define morkStore_kNoneToken ((mork_token) 'n') -#define morkStore_kFormColumn ((mork_column) 'f') -#define morkStore_kAtomScopeColumn ((mork_column) 'a') -#define morkStore_kRowScopeColumn ((mork_column) 'r') -#define morkStore_kMetaScope ((mork_scope) 'm') -#define morkStore_kKindColumn ((mork_column) 'k') -#define morkStore_kStatusColumn ((mork_column) 's') - -/*| morkStore: -|*/ -class morkStore : public morkObject, public nsIMdbStore { - -public: // state is public because the entire Mork system is private - - NS_DECL_ISUPPORTS_INHERITED - - morkEnv* mPort_Env; // non-refcounted env which created port - morkFactory* mPort_Factory; // weak ref to suite factory - nsIMdbHeap* mPort_Heap; // heap in which this port allocs objects - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - - void ClosePort(morkEnv* ev); // called by CloseMorkNode(); - -public: // dynamic type identification - mork_bool IsPort() const - { return IsNode() && mNode_Derived == morkDerived_kPort; } -// } ===== end morkNode methods ===== - -public: // other port methods - - // { ----- begin attribute methods ----- -// NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly); - // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port. - // } ----- end attribute methods ----- - - // { ----- begin factory methods ----- -// NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory); - // } ----- end factory methods ----- - - // { ----- begin ref counting for well-behaved cyclic graphs ----- - NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs - mdb_count* outCount); - NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs - mdb_count* outCount); - - NS_IMETHOD AddWeakRef(nsIMdbEnv* ev); - NS_IMETHOD AddStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CutWeakRef(nsIMdbEnv* ev); - NS_IMETHOD CutStrongRef(nsIMdbEnv* ev); - - NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero - NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen); - // } ----- end ref counting ----- - -// } ===== end nsIMdbObject methods ===== - -// { ===== begin nsIMdbPort methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetIsPortReadonly(nsIMdbEnv* ev, mdb_bool* outBool); - NS_IMETHOD GetIsStore(nsIMdbEnv* ev, mdb_bool* outBool); - NS_IMETHOD GetIsStoreAndDirty(nsIMdbEnv* ev, mdb_bool* outBool); - - NS_IMETHOD GetUsagePolicy(nsIMdbEnv* ev, - mdbUsagePolicy* ioUsagePolicy); - - NS_IMETHOD SetUsagePolicy(nsIMdbEnv* ev, - const mdbUsagePolicy* inUsagePolicy); - // } ----- end attribute methods ----- - - // { ----- begin memory policy methods ----- - NS_IMETHOD IdleMemoryPurge( // do memory management already scheduled - nsIMdbEnv* ev, // context - mdb_size* outEstimatedBytesFreed); // approximate bytes actually freed - - NS_IMETHOD SessionMemoryPurge( // request specific footprint decrease - nsIMdbEnv* ev, // context - mdb_size inDesiredBytesFreed, // approximate number of bytes wanted - mdb_size* outEstimatedBytesFreed); // approximate bytes actually freed - - NS_IMETHOD PanicMemoryPurge( // desperately free all possible memory - nsIMdbEnv* ev, // context - mdb_size* outEstimatedBytesFreed); // approximate bytes actually freed - // } ----- end memory policy methods ----- - - // { ----- begin filepath methods ----- - NS_IMETHOD GetPortFilePath( - nsIMdbEnv* ev, // context - mdbYarn* outFilePath, // name of file holding port content - mdbYarn* outFormatVersion); // file format description - - NS_IMETHOD GetPortFile( - nsIMdbEnv* ev, // context - nsIMdbFile** acqFile); // acquire file used by port or store - // } ----- end filepath methods ----- - - // { ----- begin export methods ----- - NS_IMETHOD BestExportFormat( // determine preferred export format - nsIMdbEnv* ev, // context - mdbYarn* outFormatVersion); // file format description - - NS_IMETHOD - CanExportToFormat( // can export content in given specific format? - nsIMdbEnv* ev, // context - const char* inFormatVersion, // file format description - mdb_bool* outCanExport); // whether ExportSource() might succeed - - NS_IMETHOD ExportToFormat( // export content in given specific format - nsIMdbEnv* ev, // context - // const char* inFilePath, // the file to receive exported content - nsIMdbFile* ioFile, // destination abstract file interface - const char* inFormatVersion, // file format description - nsIMdbThumb** acqThumb); // acquire thumb for incremental export - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the export will be finished. - - // } ----- end export methods ----- - - // { ----- begin token methods ----- - NS_IMETHOD TokenToString( // return a string name for an integer token - nsIMdbEnv* ev, // context - mdb_token inToken, // token for inTokenName inside this port - mdbYarn* outTokenName); // the type of table to access - - NS_IMETHOD StringToToken( // return an integer token for scope name - nsIMdbEnv* ev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken); // token for inTokenName inside this port - - // String token zero is never used and never supported. If the port - // is a mutable store, then StringToToken() to create a new - // association of inTokenName with a new integer token if possible. - // But a readonly port will return zero for an unknown scope name. - - NS_IMETHOD QueryToken( // like StringToToken(), but without adding - nsIMdbEnv* ev, // context - const char* inTokenName, // Latin1 string to tokenize if possible - mdb_token* outToken); // token for inTokenName inside this port - - // QueryToken() will return a string token if one already exists, - // but unlike StringToToken(), will not assign a new token if not - // already in use. - - // } ----- end token methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD HasRow( // contains a row with the specified oid? - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_bool* outHasRow); // whether GetRow() might succeed - - NS_IMETHOD GetRowRefCount( // get number of tables that contain a row - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - mdb_count* outRefCount); // number of tables containing inRowKey - - NS_IMETHOD GetRow( // access one row with specific oid - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical row oid - nsIMdbRow** acqRow); // acquire specific row (or null) - - NS_IMETHOD FindRow(nsIMdbEnv* ev, // search for row with matching cell - mdb_scope inRowScope, // row scope for row ids - mdb_column inColumn, // the column to search (and maintain an index) - const mdbYarn* inTargetCellValue, // cell value for which to search - mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match) - nsIMdbRow** acqRow); // acquire matching row (or nil for no match) - // can be null if you only want the oid - // FindRow() searches for one row that has a cell in column inColumn with - // a contained value with the same form (i.e. charset) and is byte-wise - // identical to the blob described by yarn inTargetCellValue. Both content - // and form of the yarn must be an exact match to find a matching row. - // - // (In other words, both a yarn's blob bytes and form are significant. The - // form is not expected to vary in columns used for identity anyway. This - // is intended to make the cost of FindRow() cheaper for MDB implementors, - // since any cell value atomization performed internally must necessarily - // make yarn form significant in order to avoid data loss in atomization.) - // - // FindRow() can lazily create an index on attribute inColumn for all rows - // with that attribute in row space scope inRowScope, so that subsequent - // calls to FindRow() will perform faster. Such an index might or might - // not be persistent (but this seems desirable if it is cheap to do so). - // Note that lazy index creation in readonly DBs is not very feasible. - // - // This FindRow() interface assumes that attribute inColumn is effectively - // an alternative means of unique identification for a row in a rowspace, - // so correct behavior is only guaranteed when no duplicates for this col - // appear in the given set of rows. (If more than one row has the same cell - // value in this column, no more than one will be found; and cutting one of - // two duplicate rows can cause the index to assume no other such row lives - // in the row space, so future calls return nil for negative search results - // even though some duplicate row might still live within the rowspace.) - // - // In other words, the FindRow() implementation is allowed to assume simple - // hash tables mapping unqiue column keys to associated row values will be - // sufficient, where any duplication is not recorded because only one copy - // of a given key need be remembered. Implementors are not required to sort - // all rows by the specified column. - // } ----- end row methods ----- - - // { ----- begin table methods ----- - NS_IMETHOD HasTable( // supports a table with the specified oid? - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical table oid - mdb_bool* outHasTable); // whether GetTable() might succeed - - NS_IMETHOD GetTable( // access one table with specific oid - nsIMdbEnv* ev, // context - const mdbOid* inOid, // hypothetical table oid - nsIMdbTable** acqTable); // acquire specific table (or null) - - NS_IMETHOD HasTableKind( // supports a table of the specified type? - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // rid scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outSupportsTable); // whether GetTableKind() might succeed - - NS_IMETHOD GetTableKind( // access one (random) table of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_count* outTableCount, // current number of such tables - mdb_bool* outMustBeUnique, // whether port can hold only one of these - nsIMdbTable** acqTable); // acquire scoped collection of rows - - NS_IMETHOD - GetPortTableCursor( // get cursor for all tables of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - nsIMdbPortTableCursor** acqCursor); // all such tables in the port - // } ----- end table methods ----- - - - // { ----- begin commit methods ----- - - NS_IMETHOD ShouldCompress( // store wastes at least inPercentWaste? - nsIMdbEnv* ev, // context - mdb_percent inPercentWaste, // 0..100 percent file size waste threshold - mdb_percent* outActualWaste, // 0..100 percent of file actually wasted - mdb_bool* outShould); // true when about inPercentWaste% is wasted - // ShouldCompress() returns true if the store can determine that the file - // will shrink by an estimated percentage of inPercentWaste% (or more) if - // CompressCommit() is called, because that percentage of the file seems - // to be recoverable free space. The granularity is only in terms of - // percentage points, and any value over 100 is considered equal to 100. - // - // If a store only has an approximate idea how much space might be saved - // during a compress, then a best guess should be made. For example, the - // Mork implementation might keep track of how much file space began with - // text content before the first updating transaction, and then consider - // all content following the start of the first transaction as potentially - // wasted space if it is all updates and not just new content. (This is - // a safe assumption in the sense that behavior will stabilize on a low - // estimate of wastage after a commit removes all transaction updates.) - // - // Some db formats might attempt to keep a very accurate reckoning of free - // space size, so a very accurate determination can be made. But other db - // formats might have difficulty determining size of free space, and might - // require some lengthy calculation to answer. This is the reason for - // passing in the percentage threshold of interest, so that such lengthy - // computations can terminate early as soon as at least inPercentWaste is - // found, so that the entire file need not be groveled when unnecessary. - // However, we hope implementations will always favor fast but imprecise - // heuristic answers instead of extremely slow but very precise answers. - // - // If the outActualWaste parameter is non-nil, it will be used to return - // the actual estimated space wasted as a percentage of file size. (This - // parameter is provided so callers need not call repeatedly with altered - // inPercentWaste values to isolate the actual wastage figure.) Note the - // actual wastage figure returned can exactly equal inPercentWaste even - // when this grossly underestimates the real figure involved, if the db - // finds it very expensive to determine the extent of wastage after it is - // known to at least exceed inPercentWaste. Note we expect that whenever - // outShould returns true, that outActualWaste returns >= inPercentWaste. - // - // The effect of different inPercentWaste values is not very uniform over - // the permitted range. For example, 50 represents 50% wastage, or a file - // that is about double what it should be ideally. But 99 represents 99% - // wastage, or a file that is about ninety-nine times as big as it should - // be ideally. In the smaller direction, 25 represents 25% wastage, or - // a file that is only 33% larger than it should be ideally. - // - // Callers can determine what policy they want to use for considering when - // a file holds too much wasted space, and express this as a percentage - // of total file size to pass as in the inPercentWaste parameter. A zero - // likely returns always trivially true, and 100 always trivially false. - // The great majority of callers are expected to use values from 25 to 75, - // since most plausible thresholds for compressing might fall between the - // extremes of 133% of ideal size and 400% of ideal size. (Presumably the - // larger a file gets, the more important the percentage waste involved, so - // a sliding scale for compress thresholds might use smaller numbers for - // much bigger file sizes.) - - // } ----- end commit methods ----- - -// } ===== end nsIMdbPort methods ===== - -// { ===== begin nsIMdbStore methods ===== - - // { ----- begin table methods ----- - NS_IMETHOD NewTable( // make one new table of specific type - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // row scope for row ids - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable); // acquire scoped collection of rows - - NS_IMETHOD NewTableWithOid( // make one new table of specific type - nsIMdbEnv* ev, // context - const mdbOid* inOid, // caller assigned oid - mdb_kind inTableKind, // the type of table to access - mdb_bool inMustBeUnique, // whether store can hold only one of these - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - nsIMdbTable** acqTable); // acquire scoped collection of rows - // } ----- end table methods ----- - - // { ----- begin row scope methods ----- - NS_IMETHOD RowScopeHasAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned); // nonzero if store db assigned specified - - NS_IMETHOD SetCallerAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned); // nonzero if store db assigned specified - - NS_IMETHOD SetStoreAssignedIds(nsIMdbEnv* ev, - mdb_scope inRowScope, // row scope for row ids - mdb_bool* outCallerAssigned, // nonzero if caller assigned specified - mdb_bool* outStoreAssigned); // nonzero if store db assigned specified - // } ----- end row scope methods ----- - - // { ----- begin row methods ----- - NS_IMETHOD NewRowWithOid(nsIMdbEnv* ev, // new row w/ caller assigned oid - const mdbOid* inOid, // caller assigned oid - nsIMdbRow** acqRow); // create new row - - NS_IMETHOD NewRow(nsIMdbEnv* ev, // new row with db assigned oid - mdb_scope inRowScope, // row scope for row ids - nsIMdbRow** acqRow); // create new row - // Note this row must be added to some table or cell child before the - // store is closed in order to make this row persist across sesssions. - - // } ----- end row methods ----- - - // { ----- begin inport/export methods ----- - NS_IMETHOD ImportContent( // import content from port - nsIMdbEnv* ev, // context - mdb_scope inRowScope, // scope for rows (or zero for all?) - nsIMdbPort* ioPort, // the port with content to add to store - nsIMdbThumb** acqThumb); // acquire thumb for incremental import - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the import will be finished. - - NS_IMETHOD ImportFile( // import content from port - nsIMdbEnv* ev, // context - nsIMdbFile* ioFile, // the file with content to add to store - nsIMdbThumb** acqThumb); // acquire thumb for incremental import - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the import will be finished. - // } ----- end inport/export methods ----- - - // { ----- begin hinting methods ----- - NS_IMETHOD - ShareAtomColumnsHint( // advise re shared column content atomizing - nsIMdbEnv* ev, // context - mdb_scope inScopeHint, // zero, or suggested shared namespace - const mdbColumnSet* inColumnSet); // cols desired tokenized together - - NS_IMETHOD - AvoidAtomColumnsHint( // advise column with poor atomizing prospects - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet); // cols with poor atomizing prospects - // } ----- end hinting methods ----- - - // { ----- begin commit methods ----- - NS_IMETHOD SmallCommit( // save minor changes if convenient and uncostly - nsIMdbEnv* ev); // context - - NS_IMETHOD LargeCommit( // save important changes if at all possible - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb); // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - NS_IMETHOD SessionCommit( // save all changes if large commits delayed - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb); // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - NS_IMETHOD - CompressCommit( // commit and make db physically smaller if possible - nsIMdbEnv* ev, // context - nsIMdbThumb** acqThumb); // acquire thumb for incremental commit - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the commit will be finished. Note the store is effectively write - // locked until commit is finished or canceled through the thumb instance. - // Until the commit is done, the store will report it has readonly status. - - // } ----- end commit methods ----- - -// } ===== end nsIMdbStore methods ===== - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakPort(morkPort* me, - morkEnv* ev, morkPort** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongPort(morkPort* me, - morkEnv* ev, morkPort** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -// public: // slots inherited from morkPort (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkEnv* mPort_Env; // non-refcounted env which created port - // morkFactory* mPort_Factory; // weak ref to suite factory - // nsIMdbHeap* mPort_Heap; // heap in which this port allocs objects - -public: // state is public because the entire Mork system is private - -// mStore_OidAtomSpace might be unnecessary; I don't remember why I wanted it. - morkAtomSpace* mStore_OidAtomSpace; // ground atom space for oids - morkAtomSpace* mStore_GroundAtomSpace; // ground atom space for scopes - morkAtomSpace* mStore_GroundColumnSpace; // ground column space for scopes - - nsIMdbFile* mStore_File; // the file containing Mork text - morkStream* mStore_InStream; // stream using file used by the builder - morkBuilder* mStore_Builder; // to parse Mork text and build structures - - morkStream* mStore_OutStream; // stream using file used by the writer - - morkRowSpaceMap mStore_RowSpaces; // maps mork_scope -> morkSpace - morkAtomSpaceMap mStore_AtomSpaces; // maps mork_scope -> morkSpace - - morkZone mStore_Zone; - - morkPool mStore_Pool; - - // we alloc a max size book atom to reuse space for atom map key searches: - // morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches - - morkFarBookAtom mStore_FarBookAtom; // staging area for atom map searches - - // GroupIdentity should be one more than largest seen in a parsed db file: - mork_gid mStore_CommitGroupIdentity; // transaction ID number - - // group positions are used to help compute PercentOfStoreWasted(): - mork_pos mStore_FirstCommitGroupPos; // start of first group - mork_pos mStore_SecondCommitGroupPos; // start of second group - // If the first commit group is very near the start of the file (say less - // than 512 bytes), then we might assume the file started nearly empty and - // that most of the first group is not wasted. In that case, the pos of - // the second commit group might make a better estimate of the start of - // transaction space that might represent wasted file space. That's why - // we support fields for both first and second commit group positions. - // - // We assume that a zero in either group pos means that the slot has not - // yet been given a valid value, since the file will always start with a - // tag, and a commit group cannot actually start at position zero. - // - // Either or both the first or second commit group positions might be - // supplied by either morkWriter (while committing) or morkBuilder (while - // parsing), since either reading or writing the file might encounter the - // first transaction groups which came into existence either in the past - // or in the very recent present. - - mork_bool mStore_CanAutoAssignAtomIdentity; - mork_bool mStore_CanDirty; // changes imply the store becomes dirty? - mork_u1 mStore_CanWriteIncremental; // compress not required? - mork_u1 mStore_Pad; // for u4 alignment - - // mStore_CanDirty should be FALSE when parsing a file while building the - // content going into the store, because such data structure modifications - // are actuallly in sync with the file. So content read from a file must - // be clean with respect to the file. After a file is finished parsing, - // the mStore_CanDirty slot should become TRUE, so that any additional - // changes at runtime cause structures to be marked dirty with respect to - // the file which must later be updated with changes during a commit. - // - // It might also make sense to set mStore_CanDirty to FALSE while a commit - // is in progress, lest some internal transformations make more content - // appear dirty when it should not. So anyone modifying content during a - // commit should think about the intended significance regarding dirty. - -public: // more specific dirty methods for store: - void SetStoreDirty() { this->SetNodeDirty(); } - void SetStoreClean() { this->SetNodeClean(); } - - mork_bool IsStoreClean() const { return this->IsNodeClean(); } - mork_bool IsStoreDirty() const { return this->IsNodeDirty(); } - -public: // setting dirty based on CanDirty: - - void MaybeDirtyStore() - { if ( mStore_CanDirty ) this->SetStoreDirty(); } - -public: // space waste analysis - - mork_percent PercentOfStoreWasted(morkEnv* ev); - -public: // setting store and all subspaces canDirty: - - void SetStoreAndAllSpacesCanDirty(morkEnv* ev, mork_bool inCanDirty); - -public: // building an atom inside mStore_FarBookAtom from a char* string - - morkFarBookAtom* StageAliasAsFarBookAtom(morkEnv* ev, - const morkMid* inMid, morkAtomSpace* ioSpace, mork_cscode inForm); - - morkFarBookAtom* StageYarnAsFarBookAtom(morkEnv* ev, - const mdbYarn* inYarn, morkAtomSpace* ioSpace); - - morkFarBookAtom* StageStringAsFarBookAtom(morkEnv* ev, - const char* inString, mork_cscode inForm, morkAtomSpace* ioSpace); - -public: // determining whether incremental writing is a good use of time: - - mork_bool DoPreferLargeOverCompressCommit(morkEnv* ev); - // true when mStore_CanWriteIncremental && store has file large enough - -public: // lazy creation of members and nested row or atom spaces - - morkAtomSpace* LazyGetOidAtomSpace(morkEnv* ev); - morkAtomSpace* LazyGetGroundAtomSpace(morkEnv* ev); - morkAtomSpace* LazyGetGroundColumnSpace(morkEnv* ev); - - morkStream* LazyGetInStream(morkEnv* ev); - morkBuilder* LazyGetBuilder(morkEnv* ev); - void ForgetBuilder(morkEnv* ev); - - morkStream* LazyGetOutStream(morkEnv* ev); - - morkRowSpace* LazyGetRowSpace(morkEnv* ev, mdb_scope inRowScope); - morkAtomSpace* LazyGetAtomSpace(morkEnv* ev, mdb_scope inAtomScope); - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseStore() only if open - virtual ~morkStore(); // assert that CloseStore() executed earlier - -public: // morkStore construction & destruction - morkStore(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance - morkFactory* inFactory, // the factory for this - nsIMdbHeap* ioPortHeap // the heap to hold all content in the port - ); - void CloseStore(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkStore(const morkStore& other); - morkStore& operator=(const morkStore& other); - -public: // dynamic type identification - morkEnv* CanUseStore(nsIMdbEnv* mev, mork_bool inMutable, mdb_err* outErr) const; - mork_bool IsStore() const - { return IsNode() && mNode_Derived == morkDerived_kStore; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonStoreTypeError(morkEnv* ev); - static void NilStoreFileError(morkEnv* ev); - static void CannotAutoAssignAtomIdentityError(morkEnv* ev); - -public: // store utilties - - morkAtom* YarnToAtom(morkEnv* ev, const mdbYarn* inYarn, PRBool createIfMissing = PR_TRUE); - morkAtom* AddAlias(morkEnv* ev, const morkMid& inMid, - mork_cscode inForm); - -public: // other store methods - - void RenumberAllCollectableContent(morkEnv* ev); - - nsIMdbStore* AcquireStoreHandle(morkEnv* ev); // mObject_Handle - - morkPool* StorePool() { return &mStore_Pool; } - - mork_bool OpenStoreFile(morkEnv* ev, // return value equals ev->Good() - mork_bool inFrozen, - // const char* inFilePath, - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy); - - mork_bool CreateStoreFile(morkEnv* ev, // return value equals ev->Good() - // const char* inFilePath, - nsIMdbFile* ioFile, // db abstract file interface - const mdbOpenPolicy* inOpenPolicy); - - morkAtom* CopyAtom(morkEnv* ev, const morkAtom* inAtom); - // copy inAtom (from some other store) over to this store - - mork_token CopyToken(morkEnv* ev, mdb_token inToken, morkStore* inStore); - // copy inToken from inStore over to this store - - mork_token BufToToken(morkEnv* ev, const morkBuf* inBuf); - mork_token StringToToken(morkEnv* ev, const char* inTokenName); - mork_token QueryToken(morkEnv* ev, const char* inTokenName); - void TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName); - - mork_bool MidToOid(morkEnv* ev, const morkMid& inMid, - mdbOid* outOid); - mork_bool OidToYarn(morkEnv* ev, const mdbOid& inOid, mdbYarn* outYarn); - mork_bool MidToYarn(morkEnv* ev, const morkMid& inMid, - mdbYarn* outYarn); - - morkBookAtom* MidToAtom(morkEnv* ev, const morkMid& inMid); - morkRow* MidToRow(morkEnv* ev, const morkMid& inMid); - morkTable* MidToTable(morkEnv* ev, const morkMid& inMid); - - morkRow* OidToRow(morkEnv* ev, const mdbOid* inOid); - // OidToRow() finds old row with oid, or makes new one if not found. - - morkTable* OidToTable(morkEnv* ev, const mdbOid* inOid, - const mdbOid* inOptionalMetaRowOid); - // OidToTable() finds old table with oid, or makes new one if not found. - - static void SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken, - mdbYarn* outYarn); - - mork_bool HasTableKind(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_count* outTableCount); - - morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_count* outTableCount, - mdb_bool* outMustBeUnique); - - morkRow* FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn, - const mdbYarn* inTargetCellValue); - - morkRow* GetRow(morkEnv* ev, const mdbOid* inOid); - morkTable* GetTable(morkEnv* ev, const mdbOid* inOid); - - morkTable* NewTable(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind, mdb_bool inMustBeUnique, - const mdbOid* inOptionalMetaRowOid); - - morkPortTableCursor* GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope, - mdb_kind inTableKind) ; - - morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid); - morkRow* NewRow(morkEnv* ev, mdb_scope inRowScope); - - morkThumb* MakeCompressCommitThumb(morkEnv* ev, mork_bool inDoCollect); - -public: // commit related methods - - mork_bool MarkAllStoreContentDirty(morkEnv* ev); - // MarkAllStoreContentDirty() visits every object in the store and marks - // them dirty, including every table, row, cell, and atom. The return - // equals ev->Good(), to show whether any error happened. This method is - // intended for use in the beginning of a "compress commit" which writes - // all store content, whether dirty or not. We dirty everything first so - // that later iterations over content can mark things clean as they are - // written, and organize the process of serialization so that objects are - // written only at need (because of being dirty). - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakStore(morkStore* me, - morkEnv* ev, morkStore** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongStore(morkStore* me, - morkEnv* ev, morkStore** ioSlot) - { - morkStore* store = *ioSlot; - if ( me != store ) - { - if ( store ) - { - // what if this nulls out the ev and causes asserts? - // can we move this after the CutStrongRef()? - *ioSlot = 0; - store->Release(); - } - if ( me && me->AddRef() ) - *ioSlot = me; - } - } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKSTORE_ */ - diff --git a/db/mork/src/morkStream.cpp b/db/mork/src/morkStream.cpp deleted file mode 100644 index 8b108d1104d4..000000000000 --- a/db/mork/src/morkStream.cpp +++ /dev/null @@ -1,896 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKFILE_ -#include "morkFile.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKSTREAM_ -#include "morkStream.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkStream::CloseMorkNode(morkEnv* ev) // CloseStream() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseStream(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkStream::~morkStream() // assert CloseStream() executed earlier -{ - MORK_ASSERT(mStream_ContentFile==0); - MORK_ASSERT(mStream_Buf==0); -} - -/*public non-poly*/ -morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, - nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen) -: morkFile(ev, inUsage, ioHeap, ioHeap) -, mStream_At( 0 ) -, mStream_ReadEnd( 0 ) -, mStream_WriteEnd( 0 ) - -, mStream_ContentFile( 0 ) - -, mStream_Buf( 0 ) -, mStream_BufSize( inBufSize ) -, mStream_BufPos( 0 ) -, mStream_Dirty( morkBool_kFalse ) -, mStream_HitEof( morkBool_kFalse ) -{ - if ( ev->Good() ) - { - if ( inBufSize < morkStream_kMinBufSize ) - mStream_BufSize = inBufSize = morkStream_kMinBufSize; - else if ( inBufSize > morkStream_kMaxBufSize ) - mStream_BufSize = inBufSize = morkStream_kMaxBufSize; - - if ( ioContentFile && ioHeap ) - { - // if ( ioContentFile->FileFrozen() ) // forced to be readonly? - // inFrozen = morkBool_kTrue; // override the input value - - nsIMdbFile_SlotStrongFile(ioContentFile, ev, &mStream_ContentFile); - if ( ev->Good() ) - { - mork_u1* buf = 0; - ioHeap->Alloc(ev->AsMdbEnv(), inBufSize, (void**) &buf); - if ( buf ) - { - mStream_At = mStream_Buf = buf; - - if ( !inFrozen ) - { - // physical buffer end never moves: - mStream_WriteEnd = buf + inBufSize; - } - else - mStream_WriteEnd = 0; // no writing is allowed - - if ( inFrozen ) - { - // logical buffer end starts at Buf with no content: - mStream_ReadEnd = buf; - this->SetFileFrozen(inFrozen); - } - else - mStream_ReadEnd = 0; // no reading is allowed - - this->SetFileActive(morkBool_kTrue); - this->SetFileIoOpen(morkBool_kTrue); - } - if ( ev->Good() ) - mNode_Derived = morkDerived_kStream; - } - } - else ev->NilPointerError(); - } -} - -/*public non-poly*/ void -morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mStream_ContentFile); - nsIMdbHeap* heap = mFile_SlotHeap; - mork_u1* buf = mStream_Buf; - mStream_Buf = 0; - - if ( heap && buf ) - heap->Free(ev->AsMdbEnv(), buf); - - this->CloseFile(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -#define morkStream_kSpacesPerIndent 1 /* one space per indent */ -#define morkStream_kMaxIndentDepth 70 /* max indent of 70 space bytes */ -static const char morkStream_kSpaces[] // next line to ease length perception -= " "; -// 123456789_123456789_123456789_123456789_123456789_123456789_123456789_ -// morkStream_kSpaces above must contain (at least) 70 spaces (ASCII 0x20) - -mork_size -morkStream::PutIndent(morkEnv* ev, mork_count inDepth) - // PutIndent() puts a linebreak, and then - // "indents" by inDepth, and returns the line length after indentation. -{ - mork_size outLength = 0; - nsIMdbEnv *mev = ev->AsMdbEnv(); - if ( ev->Good() ) - { - this->PutLineBreak(ev); - if ( ev->Good() ) - { - outLength = inDepth; - mdb_size bytesWritten; - if ( inDepth ) - this->Write(mev, morkStream_kSpaces, inDepth, &bytesWritten); - } - } - return outLength; -} - -mork_size -morkStream::PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth) - // PutByteThenIndent() puts the byte, then a linebreak, and then - // "indents" by inDepth, and returns the line length after indentation. -{ - mork_size outLength = 0; - nsIMdbEnv *mev = ev->AsMdbEnv(); - - if ( inDepth > morkStream_kMaxIndentDepth ) - inDepth = morkStream_kMaxIndentDepth; - - this->Putc(ev, inByte); - if ( ev->Good() ) - { - this->PutLineBreak(ev); - if ( ev->Good() ) - { - outLength = inDepth; - mdb_size bytesWritten; - if ( inDepth ) - this->Write(mev, morkStream_kSpaces, inDepth, &bytesWritten); - } - } - return outLength; -} - -mork_size -morkStream::PutStringThenIndent(morkEnv* ev, - const char* inString, mork_count inDepth) -// PutStringThenIndent() puts the string, then a linebreak, and then -// "indents" by inDepth, and returns the line length after indentation. -{ - mork_size outLength = 0; - mdb_size bytesWritten; - nsIMdbEnv *mev = ev->AsMdbEnv(); - - if ( inDepth > morkStream_kMaxIndentDepth ) - inDepth = morkStream_kMaxIndentDepth; - - if ( inString ) - { - mork_size length = MORK_STRLEN(inString); - if ( length && ev->Good() ) // any bytes to write? - this->Write(mev, inString, length, &bytesWritten); - } - - if ( ev->Good() ) - { - this->PutLineBreak(ev); - if ( ev->Good() ) - { - outLength = inDepth; - if ( inDepth ) - this->Write(mev, morkStream_kSpaces, inDepth, &bytesWritten); - } - } - return outLength; -} - -mork_size -morkStream::PutString(morkEnv* ev, const char* inString) -{ - nsIMdbEnv *mev = ev->AsMdbEnv(); - mork_size outSize = 0; - mdb_size bytesWritten; - if ( inString ) - { - outSize = MORK_STRLEN(inString); - if ( outSize && ev->Good() ) // any bytes to write? - { - this->Write(mev, inString, outSize, &bytesWritten); - } - } - return outSize; -} - -mork_size -morkStream::PutStringThenNewline(morkEnv* ev, const char* inString) - // PutStringThenNewline() returns total number of bytes written. -{ - nsIMdbEnv *mev = ev->AsMdbEnv(); - mork_size outSize = 0; - mdb_size bytesWritten; - if ( inString ) - { - outSize = MORK_STRLEN(inString); - if ( outSize && ev->Good() ) // any bytes to write? - { - this->Write(mev, inString, outSize, &bytesWritten); - if ( ev->Good() ) - outSize += this->PutLineBreak(ev); - } - } - return outSize; -} - -mork_size -morkStream::PutByteThenNewline(morkEnv* ev, int inByte) - // PutByteThenNewline() returns total number of bytes written. -{ - mork_size outSize = 1; // one for the following byte - this->Putc(ev, inByte); - if ( ev->Good() ) - outSize += this->PutLineBreak(ev); - return outSize; -} - -mork_size -morkStream::PutLineBreak(morkEnv* ev) -{ -#if defined(MORK_MAC) - - this->Putc(ev, mork_kCR); - return 1; - -#else -# if defined(MORK_WIN) || defined(MORK_OS2) - - this->Putc(ev, mork_kCR); - this->Putc(ev, mork_kLF); - return 2; - -# else -# ifdef MORK_UNIX - - this->Putc(ev, mork_kLF); - return 1; - -# endif /* MORK_UNIX */ -# endif /* MORK_WIN */ -#endif /* MORK_MAC */ -} -// ````` ````` ````` ````` ````` ````` ````` ````` -// public: // virtual morkFile methods - - -NS_IMETHODIMP -morkStream::Steal(nsIMdbEnv* mev, nsIMdbFile* ioThief) - // Steal: tell this file to close any associated i/o stream in the file - // system, because the file ioThief intends to reopen the file in order - // to provide the MDB implementation with more exotic file access than is - // offered by the nsIMdbFile alone. Presumably the thief knows enough - // from Path() in order to know which file to reopen. If Steal() is - // successful, this file should probably delegate all future calls to - // the nsIMdbFile interface down to the thief files, so that even after - // the file has been stolen, it can still be read, written, or forcibly - // closed (by a call to CloseMdbObject()). -{ - MORK_USED_1(ioThief); - morkEnv *ev = morkEnv::FromMdbEnv(mev); - ev->StubMethodOnlyError(); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkStream::BecomeTrunk(nsIMdbEnv* mev) - // If this file is a file version branch created by calling AcquireBud(), - // BecomeTrunk() causes this file's content to replace the original - // file's content, typically by assuming the original file's identity. -{ - morkEnv *ev = morkEnv::FromMdbEnv(mev); - ev->StubMethodOnlyError(); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkStream::AcquireBud(nsIMdbEnv* mev, nsIMdbHeap* ioHeap, nsIMdbFile **acqBud) - // AcquireBud() starts a new "branch" version of the file, empty of content, - // so that a new version of the file can be written. This new file - // can later be told to BecomeTrunk() the original file, so the branch - // created by budding the file will replace the original file. Some - // file subclasses might initially take the unsafe but expedient - // approach of simply truncating this file down to zero length, and - // then returning the same morkFile pointer as this, with an extra - // reference count increment. Note that the caller of AcquireBud() is - // expected to eventually call CutStrongRef() on the returned file - // in order to release the strong reference. High quality versions - // of morkFile subclasses will create entirely new files which later - // are renamed to become the old file, so that better transactional - // behavior is exhibited by the file, so crashes protect old files. - // Note that AcquireBud() is an illegal operation on readonly files. -{ - MORK_USED_1(ioHeap); - morkFile* outFile = 0; - nsIMdbFile* file = mStream_ContentFile; - morkEnv *ev = morkEnv::FromMdbEnv(mev); - if ( this->IsOpenAndActiveFile() && file ) - { - // figure out how this interacts with buffering and mStream_WriteEnd: - ev->StubMethodOnlyError(); - } - else this->NewFileDownError(ev); - - *acqBud = outFile; - return NS_ERROR_NOT_IMPLEMENTED; -} - -mork_pos -morkStream::Length(morkEnv* ev) const // eof -{ - mork_pos outPos = 0; - - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenAndActiveFile() && file ) - { - mork_pos contentEof = 0; - file->Eof(ev->AsMdbEnv(), &contentEof); - if ( ev->Good() ) - { - if ( mStream_WriteEnd ) // this stream supports writing? - { - // the local buffer might have buffered content past content eof - if ( ev->Good() ) // no error happened during Length() above? - { - mork_u1* at = mStream_At; - mork_u1* buf = mStream_Buf; - if ( at >= buf ) // expected cursor order? - { - mork_pos localContent = mStream_BufPos + (at - buf); - if ( localContent > contentEof ) // buffered past eof? - contentEof = localContent; // return new logical eof - - outPos = contentEof; - } - else this->NewBadCursorOrderError(ev); - } - } - else - outPos = contentEof; // frozen files get length from content file - } - } - else this->NewFileDownError(ev); - - return outPos; -} - -void morkStream::NewBadCursorSlotsError(morkEnv* ev) const -{ ev->NewError("bad stream cursor slots"); } - -void morkStream::NewNullStreamBufferError(morkEnv* ev) const -{ ev->NewError("null stream buffer"); } - -void morkStream::NewCantReadSinkError(morkEnv* ev) const -{ ev->NewError("cant read stream sink"); } - -void morkStream::NewCantWriteSourceError(morkEnv* ev) const -{ ev->NewError("cant write stream source"); } - -void morkStream::NewPosBeyondEofError(morkEnv* ev) const -{ ev->NewError("stream pos beyond eof"); } - -void morkStream::NewBadCursorOrderError(morkEnv* ev) const -{ ev->NewError("bad stream cursor order"); } - -NS_IMETHODIMP -morkStream::Tell(nsIMdbEnv* mdbev, mork_pos *aOutPos) const -{ - nsresult rv = NS_OK; - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - - NS_ENSURE_ARG_POINTER(aOutPos); - - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenAndActiveFile() && file ) - { - mork_u1* buf = mStream_Buf; - mork_u1* at = mStream_At; - - mork_u1* readEnd = mStream_ReadEnd; // nonzero only if readonly - mork_u1* writeEnd = mStream_WriteEnd; // nonzero only if writeonly - - if ( writeEnd ) - { - if ( buf && at >= buf && at <= writeEnd ) - { - *aOutPos = mStream_BufPos + (at - buf); - } - else this->NewBadCursorOrderError(ev); - } - else if ( readEnd ) - { - if ( buf && at >= buf && at <= readEnd ) - { - *aOutPos = mStream_BufPos + (at - buf); - } - else this->NewBadCursorOrderError(ev); - } - } - else this->NewFileDownError(ev); - - return rv; -} - -NS_IMETHODIMP -morkStream::Read(nsIMdbEnv* mdbev, void* outBuf, mork_size inSize, mork_size *aOutSize) -{ - NS_ENSURE_ARG_POINTER(aOutSize); - // First we satisfy the request from buffered bytes, if any. Then - // if additional bytes are needed, we satisfy these by direct reads - // from the content file without any local buffering (but we still need - // to adjust the buffer position to reflect the current i/o point). - - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - nsresult rv = NS_OK; - - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenAndActiveFile() && file ) - { - mork_u1* end = mStream_ReadEnd; // byte after last buffered byte - if ( end ) // file is open for read access? - { - if ( inSize ) // caller wants any output? - { - mork_u1* sink = (mork_u1*) outBuf; // where we plan to write bytes - if ( sink ) // caller passed good buffer address? - { - mork_u1* at = mStream_At; - mork_u1* buf = mStream_Buf; - if ( at >= buf && at <= end ) // expected cursor order? - { - mork_num remaining = (mork_num) (end - at); // bytes left in buffer - - mork_num quantum = inSize; // number of bytes to copy - if ( quantum > remaining ) // more than buffer content? - quantum = remaining; // restrict to buffered bytes - - if ( quantum ) // any bytes left in the buffer? - { - MORK_MEMCPY(sink, at, quantum); // from buffer bytes - - at += quantum; // advance past read bytes - mStream_At = at; - *aOutSize += quantum; // this much copied so far - - sink += quantum; // in case we need to copy more - inSize -= quantum; // filled this much of request - mStream_HitEof = morkBool_kFalse; - } - - if ( inSize ) // we still need to read more content? - { - // We need to read more bytes directly from the - // content file, without local buffering. We have - // exhausted the local buffer, so we need to show - // it is now empty, and adjust the current buf pos. - - mork_num posDelta = (mork_num) (at - buf); // old buf content - mStream_BufPos += posDelta; // past now empty buf - - mStream_At = mStream_ReadEnd = buf; // empty buffer - - // file->Seek(ev, mStream_BufPos); // set file pos - // if ( ev->Good() ) // no seek error? - // { - // } - - mork_num actual = 0; - nsIMdbEnv* menv = ev->AsMdbEnv(); - file->Get(menv, sink, inSize, mStream_BufPos, &actual); - if ( ev->Good() ) // no read error? - { - if ( actual ) - { - *aOutSize += actual; - mStream_BufPos += actual; - mStream_HitEof = morkBool_kFalse; - } - else if ( !*aOutSize ) - mStream_HitEof = morkBool_kTrue; - } - } - } - else this->NewBadCursorOrderError(ev); - } - else this->NewNullStreamBufferError(ev); - } - } - else this->NewCantReadSinkError(ev); - } - else this->NewFileDownError(ev); - - if ( ev->Bad() ) - *aOutSize = 0; - - return rv; -} - -NS_IMETHODIMP -morkStream::Seek(nsIMdbEnv * mdbev, mork_pos inPos, mork_pos *aOutPos) -{ - NS_ENSURE_ARG_POINTER(aOutPos); - morkEnv *ev = morkEnv::FromMdbEnv(mdbev); - *aOutPos = 0; - nsresult rv = NS_OK; - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenOrClosingNode() && this->FileActive() && file ) - { - mork_u1* at = mStream_At; // current position in buffer - mork_u1* buf = mStream_Buf; // beginning of buffer - mork_u1* readEnd = mStream_ReadEnd; // nonzero only if readonly - mork_u1* writeEnd = mStream_WriteEnd; // nonzero only if writeonly - - if ( writeEnd ) // file is mutable/writeonly? - { - if ( mStream_Dirty ) // need to commit buffer changes? - this->Flush(mdbev); - - if ( ev->Good() ) // no errors during flush or earlier? - { - if ( at == buf ) // expected post flush cursor value? - { - if ( mStream_BufPos != inPos ) // need to change pos? - { - mork_pos eof = 0; - nsIMdbEnv* menv = ev->AsMdbEnv(); - file->Eof(menv, &eof); - if ( ev->Good() ) // no errors getting length? - { - if ( inPos <= eof ) // acceptable new position? - { - mStream_BufPos = inPos; // new stream position - *aOutPos = inPos; - } - else this->NewPosBeyondEofError(ev); - } - } - } - else this->NewBadCursorOrderError(ev); - } - } - else if ( readEnd ) // file is frozen/readonly? - { - if ( at >= buf && at <= readEnd ) // expected cursor order? - { - mork_pos eof = 0; - nsIMdbEnv* menv = ev->AsMdbEnv(); - file->Eof(menv, &eof); - if ( ev->Good() ) // no errors getting length? - { - if ( inPos <= eof ) // acceptable new position? - { - *aOutPos = inPos; - mStream_BufPos = inPos; // new stream position - mStream_At = mStream_ReadEnd = buf; // empty buffer - if ( inPos == eof ) // notice eof reached? - mStream_HitEof = morkBool_kTrue; - } - else this->NewPosBeyondEofError(ev); - } - } - else this->NewBadCursorOrderError(ev); - } - - } - else this->NewFileDownError(ev); - - return rv; -} - -NS_IMETHODIMP -morkStream::Write(nsIMdbEnv* menv, const void* inBuf, mork_size inSize, mork_size *aOutSize) -{ - mork_num outActual = 0; - morkEnv *ev = morkEnv::FromMdbEnv(menv); - - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenActiveAndMutableFile() && file ) - { - mork_u1* end = mStream_WriteEnd; // byte after last buffered byte - if ( end ) // file is open for write access? - { - if ( inSize ) // caller provided any input? - { - const mork_u1* source = (const mork_u1*) inBuf; // from where - if ( source ) // caller passed good buffer address? - { - mork_u1* at = mStream_At; - mork_u1* buf = mStream_Buf; - if ( at >= buf && at <= end ) // expected cursor order? - { - mork_num space = (mork_num) (end - at); // space left in buffer - - mork_num quantum = inSize; // number of bytes to write - if ( quantum > space ) // more than buffer size? - quantum = space; // restrict to avail space - - if ( quantum ) // any space left in the buffer? - { - mStream_Dirty = morkBool_kTrue; // to ensure later flush - MORK_MEMCPY(at, source, quantum); // into buffer - - mStream_At += quantum; // advance past written bytes - outActual += quantum; // this much written so far - - source += quantum; // in case we need to write more - inSize -= quantum; // filled this much of request - } - - if ( inSize ) // we still need to write more content? - { - // We need to write more bytes directly to the - // content file, without local buffering. We have - // exhausted the local buffer, so we need to flush - // it and empty it, and adjust the current buf pos. - // After flushing, if the rest of the write fits - // inside the buffer, we will put bytes into the - // buffer rather than write them to content file. - - if ( mStream_Dirty ) - this->Flush(menv); // will update mStream_BufPos - - at = mStream_At; - if ( at < buf || at > end ) // bad cursor? - this->NewBadCursorOrderError(ev); - - if ( ev->Good() ) // no errors? - { - space = (mork_num) (end - at); // space left in buffer - if ( space > inSize ) // write to buffer? - { - mStream_Dirty = morkBool_kTrue; // ensure flush - MORK_MEMCPY(at, source, inSize); // copy - - mStream_At += inSize; // past written bytes - outActual += inSize; // this much written - } - else // directly to content file instead - { - // file->Seek(ev, mStream_BufPos); // set pos - // if ( ev->Good() ) // no seek error? - // { - // } - - mork_num actual = 0; - file->Put(menv, source, inSize, mStream_BufPos, &actual); - if ( ev->Good() ) // no write error? - { - outActual += actual; - mStream_BufPos += actual; - } - } - } - } - } - else this->NewBadCursorOrderError(ev); - } - else this->NewNullStreamBufferError(ev); - } - } - else this->NewCantWriteSourceError(ev); - } - else this->NewFileDownError(ev); - - if ( ev->Bad() ) - outActual = 0; - - *aOutSize = outActual; - return ev->AsErr(); -} - -NS_IMETHODIMP -morkStream::Flush(nsIMdbEnv* ev) -{ - morkEnv *mev = morkEnv::FromMdbEnv(ev); - nsresult rv = NS_ERROR_FAILURE; - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenOrClosingNode() && this->FileActive() && file ) - { - if ( mStream_Dirty ) - this->spill_buf(mev); - - rv = file->Flush(ev); - } - else this->NewFileDownError(mev); - return rv; -} - -// ````` ````` ````` ````` ````` ````` ````` ````` -// protected: // protected non-poly morkStream methods (for char io) - -int -morkStream::fill_getc(morkEnv* ev) -{ - int c = EOF; - - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenAndActiveFile() && file ) - { - mork_u1* buf = mStream_Buf; - mork_u1* end = mStream_ReadEnd; // beyond buf after earlier read - if ( end > buf ) // any earlier read bytes buffered? - { - mStream_BufPos += ( end - buf ); // advance past old read - } - - if ( ev->Good() ) // no errors yet? - { - // file->Seek(ev, mStream_BufPos); // set file pos - // if ( ev->Good() ) // no seek error? - // { - // } - - nsIMdbEnv* menv = ev->AsMdbEnv(); - mork_num actual = 0; - file->Get(menv, buf, mStream_BufSize, mStream_BufPos, &actual); - if ( ev->Good() ) // no read errors? - { - if ( actual > mStream_BufSize ) // more than asked for?? - actual = mStream_BufSize; - - mStream_At = buf; - mStream_ReadEnd = buf + actual; - if ( actual ) // any bytes actually read? - { - c = *mStream_At++; // return first byte from buffer - mStream_HitEof = morkBool_kFalse; - } - else - mStream_HitEof = morkBool_kTrue; - } - } - } - else this->NewFileDownError(ev); - - return c; -} - -void -morkStream::spill_putc(morkEnv* ev, int c) -{ - this->spill_buf(ev); - if ( ev->Good() && mStream_At < mStream_WriteEnd ) - this->Putc(ev, c); -} - -void -morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file -{ - nsIMdbFile* file = mStream_ContentFile; - if ( this->IsOpenOrClosingNode() && this->FileActive() && file ) - { - mork_u1* buf = mStream_Buf; - if ( mStream_Dirty ) - { - mork_u1* at = mStream_At; - if ( at >= buf && at <= mStream_WriteEnd ) // order? - { - mork_num count = (mork_num) (at - buf); // bytes buffered - if ( count ) // anything to write to the string? - { - if ( count > mStream_BufSize ) // no more than max? - { - count = mStream_BufSize; - mStream_WriteEnd = buf + mStream_BufSize; - this->NewBadCursorSlotsError(ev); - } - if ( ev->Good() ) - { - // file->Seek(ev, mStream_BufPos); - // if ( ev->Good() ) - // { - // } - nsIMdbEnv* menv = ev->AsMdbEnv(); - mork_num actual = 0; - - file->Put(menv, buf, count, mStream_BufPos, &actual); - if ( ev->Good() ) - { - mStream_BufPos += actual; // past bytes written - mStream_At = buf; // reset buffer cursor - mStream_Dirty = morkBool_kFalse; - } - } - } - } - else this->NewBadCursorOrderError(ev); - } - else - { -#ifdef MORK_DEBUG - ev->NewWarning("stream:spill:not:dirty"); -#endif /*MORK_DEBUG*/ - } - } - else this->NewFileDownError(ev); - -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkStream.h b/db/mork/src/morkStream.h deleted file mode 100644 index fcf21f08326b..000000000000 --- a/db/mork/src/morkStream.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKSTREAM_ -#define _MORKSTREAM_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKFILE_ -#include "morkFile.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*============================================================================= - * morkStream: buffered file i/o - */ - -/*| morkStream exists to define an morkFile subclass that provides buffered -**| i/o for an underlying content file. Naturally this arrangement only makes -**| sense when the underlying content file is itself not efficiently buffered -**| (especially for character by character i/o). -**| -**|| morkStream is intended for either reading use or writing use, but not -**| both simultaneously or interleaved. Pick one when the stream is created -**| and don't change your mind. This restriction is intended to avoid obscure -**| and complex bugs that might arise from interleaved reads and writes -- so -**| just don't do it. A stream is either a sink or a source, but not both. -**| -**|| (When the underlying content file is intended to support both reading and -**| writing, a developer might use two instances of morkStream where one is for -**| reading and the other is for writing. In this case, a developer must take -**| care to keep the two streams in sync because each will maintain a separate -**| buffer representing a cache consistency problem for the other. A simple -**| approach is to invalidate the buffer of one when one uses the other, with -**| the assumption that closely mixed reading and writing is not expected, so -**| that little cost is associated with changing read/write streaming modes.) -**| -**|| Exactly one of mStream_ReadEnd or mStream_WriteEnd must be a null pointer, -**| and this will cause the right thing to occur when inlines use them, because -**| mStream_At < mStream_WriteEnd (for example) will always be false and the -**| else branch of the statement calls a function that raises an appropriate -**| error to complain about either reading a sink or writing a source. -**| -**|| morkStream is a direct clone of ab_Stream from Communicator 4.5's -**| address book code, which in turn was based on the stream class in the -**| public domain Mithril programming language. -|*/ - -#define morkStream_kPrintBufSize /*i*/ 512 /* buffer size used by printf() */ - -#define morkStream_kMinBufSize /*i*/ 512 /* buffer no fewer bytes */ -#define morkStream_kMaxBufSize /*i*/ (32 * 1024) /* buffer no more bytes */ - -#define morkDerived_kStream /*i*/ 0x7A74 /* ascii 'zt' */ - -class morkStream /*d*/ : public morkFile { /* from Mithril's AgStream class */ - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected morkStream members - mork_u1* mStream_At; // pointer into mStream_Buf - mork_u1* mStream_ReadEnd; // null or one byte past last readable byte - mork_u1* mStream_WriteEnd; // null or mStream_Buf + mStream_BufSize - - nsIMdbFile* mStream_ContentFile; // where content is read and written - - mork_u1* mStream_Buf; // dynamically allocated memory to buffer io - mork_size mStream_BufSize; // requested buf size (fixed by min and max) - mork_pos mStream_BufPos; // logical position of byte at mStream_Buf - mork_bool mStream_Dirty; // does the buffer need to be flushed? - mork_bool mStream_HitEof; // has eof been reached? (only frozen streams) - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseStream() only if open - virtual ~morkStream(); // assert that CloseStream() executed earlier - -public: // morkStream construction & destruction - morkStream(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen); - void CloseStream(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkStream(const morkStream& other); - morkStream& operator=(const morkStream& other); - -public: // dynamic type identification - mork_bool IsStream() const - { return IsNode() && mNode_Derived == morkDerived_kStream; } -// } ===== end morkNode methods ===== - -public: // typing - void NonStreamTypeError(morkEnv* ev); - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // virtual morkFile methods - - NS_IMETHOD Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief); - // Steal: tell this file to close any associated i/o stream in the file - // system, because the file ioThief intends to reopen the file in order - // to provide the MDB implementation with more exotic file access than is - // offered by the nsIMdbFile alone. Presumably the thief knows enough - // from Path() in order to know which file to reopen. If Steal() is - // successful, this file should probably delegate all future calls to - // the nsIMdbFile interface down to the thief files, so that even after - // the file has been stolen, it can still be read, written, or forcibly - // closed (by a call to CloseMdbObject()). - - NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev); - // If this file is a file version branch created by calling AcquireBud(), - // BecomeTrunk() causes this file's content to replace the original - // file's content, typically by assuming the original file's identity. - - NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbFile** acqBud); - // AcquireBud() starts a new "branch" version of the file, empty of content, - // so that a new version of the file can be written. This new file - // can later be told to BecomeTrunk() the original file, so the branch - // created by budding the file will replace the original file. Some - // file subclasses might initially take the unsafe but expedient - // approach of simply truncating this file down to zero length, and - // then returning the same morkFile pointer as this, with an extra - // reference count increment. Note that the caller of AcquireBud() is - // expected to eventually call CutStrongRef() on the returned file - // in order to release the strong reference. High quality versions - // of morkFile subclasses will create entirely new files which later - // are renamed to become the old file, so that better transactional - // behavior is exhibited by the file, so crashes protect old files. - // Note that AcquireBud() is an illegal operation on readonly files. - - virtual mork_pos Length(morkEnv* ev) const; // eof - NS_IMETHOD Tell(nsIMdbEnv* ev, mork_pos *aOutPos ) const; - NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mork_size inSize, mork_size *aOutCount); - NS_IMETHOD Seek(nsIMdbEnv* ev, mork_pos inPos, mork_pos *aOutPos); - NS_IMETHOD Write(nsIMdbEnv* ev, const void* inBuf, mork_size inSize, mork_size *aOutCount); - NS_IMETHOD Flush(nsIMdbEnv* ev); - -// ````` ````` ````` ````` ````` ````` ````` ````` -protected: // protected non-poly morkStream methods (for char io) - - int fill_getc(morkEnv* ev); - void spill_putc(morkEnv* ev, int c); - void spill_buf(morkEnv* ev); // spill/flush from buffer to file - -// ````` ````` ````` ````` ````` ````` ````` ````` -public: // public non-poly morkStream methods - - void NewBadCursorSlotsError(morkEnv* ev) const; - void NewBadCursorOrderError(morkEnv* ev) const; - void NewNullStreamBufferError(morkEnv* ev) const; - void NewCantReadSinkError(morkEnv* ev) const; - void NewCantWriteSourceError(morkEnv* ev) const; - void NewPosBeyondEofError(morkEnv* ev) const; - - nsIMdbFile* GetStreamContentFile() const { return mStream_ContentFile; } - mork_size GetStreamBufferSize() const { return mStream_BufSize; } - - mork_size PutIndent(morkEnv* ev, mork_count inDepth); - // PutIndent() puts a linebreak, and then - // "indents" by inDepth, and returns the line length after indentation. - - mork_size PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth); - // PutByteThenIndent() puts the byte, then a linebreak, and then - // "indents" by inDepth, and returns the line length after indentation. - - mork_size PutStringThenIndent(morkEnv* ev, - const char* inString, mork_count inDepth); - // PutStringThenIndent() puts the string, then a linebreak, and then - // "indents" by inDepth, and returns the line length after indentation. - - mork_size PutString(morkEnv* ev, const char* inString); - // PutString() returns the length of the string written. - - mork_size PutStringThenNewline(morkEnv* ev, const char* inString); - // PutStringThenNewline() returns total number of bytes written. - - mork_size PutByteThenNewline(morkEnv* ev, int inByte); - // PutByteThenNewline() returns total number of bytes written. - - // ````` ````` stdio type methods ````` ````` - void Ungetc(int c) /*i*/ - { if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = (mork_u1) c; } - - // Note Getc() returns EOF consistently after any fill_getc() error occurs. - int Getc(morkEnv* ev) /*i*/ - { return ( mStream_At < mStream_ReadEnd )? *mStream_At++ : fill_getc(ev); } - - void Putc(morkEnv* ev, int c) /*i*/ - { - mStream_Dirty = morkBool_kTrue; - if ( mStream_At < mStream_WriteEnd ) - *mStream_At++ = (mork_u1) c; - else - spill_putc(ev, c); - } - - mork_size PutLineBreak(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakStream(morkStream* me, - morkEnv* ev, morkStream** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongStream(morkStream* me, - morkEnv* ev, morkStream** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKSTREAM_ */ diff --git a/db/mork/src/morkTable.cpp b/db/mork/src/morkTable.cpp deleted file mode 100644 index 6de6ae8a7dea..000000000000 --- a/db/mork/src/morkTable.cpp +++ /dev/null @@ -1,1631 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKARRAY_ -#include "morkArray.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKTABLEROWCURSOR_ -#include "morkTableRowCursor.h" -#endif - -#ifndef _MORKROWOBJECT_ -#include "morkRowObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkTable::CloseMorkNode(morkEnv* ev) /*i*/ // CloseTable() only if open -{ - if ( this->IsOpenNode() ) - { - morkObject::CloseMorkNode(ev); // give base class a chance. - this->MarkClosing(); - this->CloseTable(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkTable::~morkTable() /*i*/ // assert CloseTable() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(this->IsShutNode()); - MORK_ASSERT(mTable_Store==0); - MORK_ASSERT(mTable_RowSpace==0); -} - -/*public non-poly*/ -morkTable::morkTable(morkEnv* ev, /*i*/ - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - morkStore* ioStore, nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace, - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - mork_tid inTid, mork_kind inKind, mork_bool inMustBeUnique) -: morkObject(ev, inUsage, ioHeap, (mork_color) inTid, (morkHandle*) 0) -, mTable_Store( 0 ) -, mTable_RowSpace( 0 ) -, mTable_MetaRow( 0 ) - -, mTable_RowMap( 0 ) -// , mTable_RowMap(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap, -// morkTable_kStartRowMapSlotCount) -, mTable_RowArray(ev, morkUsage::kMember, (nsIMdbHeap*) 0, - morkTable_kStartRowArraySize, ioSlotHeap) - -, mTable_ChangeList() -, mTable_ChangesCount( 0 ) -, mTable_ChangesMax( 3 ) // any very small number greater than zero - -, mTable_Kind( inKind ) - -, mTable_Flags( 0 ) -, mTable_Priority( morkPriority_kLo ) // NOT high priority -, mTable_GcUses( 0 ) -, mTable_Pad( 0 ) -{ - this->mLink_Next = 0; - this->mLink_Prev = 0; - - if ( ev->Good() ) - { - if ( ioStore && ioSlotHeap && ioRowSpace ) - { - if ( inKind ) - { - if ( inMustBeUnique ) - this->SetTableUnique(); - mTable_Store = ioStore; - mTable_RowSpace = ioRowSpace; - if ( inOptionalMetaRowOid ) - mTable_MetaRowOid = *inOptionalMetaRowOid; - else - { - mTable_MetaRowOid.mOid_Scope = 0; - mTable_MetaRowOid.mOid_Id = morkRow_kMinusOneRid; - } - if ( ev->Good() ) - { - if ( this->MaybeDirtySpaceStoreAndTable() ) - this->SetTableRewrite(); // everything is dirty - - mNode_Derived = morkDerived_kTable; - } - this->MaybeDirtySpaceStoreAndTable(); // new table might dirty store - } - else - ioRowSpace->ZeroKindError(ev); - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkTable, morkObject, nsIMdbTable) - -/*public non-poly*/ void -morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkRowMap::SlotStrongRowMap((morkRowMap*) 0, ev, &mTable_RowMap); - // mTable_RowMap.CloseMorkNode(ev); - mTable_RowArray.CloseMorkNode(ev); - mTable_Store = 0; - mTable_RowSpace = 0; - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// { ===== begin nsIMdbCollection methods ===== - -// { ----- begin attribute methods ----- -NS_IMETHODIMP -morkTable::GetSeed(nsIMdbEnv* mev, - mdb_seed* outSeed) // member change count -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - *outSeed = mTable_RowArray.mArray_Seed; - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::GetCount(nsIMdbEnv* mev, - mdb_count* outCount) // member count -{ - NS_ENSURE_ARG_POINTER(outCount); - *outCount = mTable_RowArray.mArray_Fill; - return NS_OK; -} - -NS_IMETHODIMP -morkTable::GetPort(nsIMdbEnv* mev, - nsIMdbPort** acqPort) // collection container -{ - (void) morkEnv::FromMdbEnv(mev); - NS_ENSURE_ARG_POINTER(acqPort); - *acqPort = mTable_Store; - return NS_OK; -} -// } ----- end attribute methods ----- - -// { ----- begin cursor methods ----- -NS_IMETHODIMP -morkTable::GetCursor( // make a cursor starting iter at inMemberPos - nsIMdbEnv* mev, // context - mdb_pos inMemberPos, // zero-based ordinal pos of member in collection - nsIMdbCursor** acqCursor) // acquire new cursor instance -{ - return this->GetTableRowCursor(mev, inMemberPos, - (nsIMdbTableRowCursor**) acqCursor); -} -// } ----- end cursor methods ----- - -// { ----- begin ID methods ----- -NS_IMETHODIMP -morkTable::GetOid(nsIMdbEnv* mev, - mdbOid* outOid) // read object identity -{ - morkEnv* ev = morkEnv::FromMdbEnv(mev); - GetTableOid(ev, outOid); - return NS_OK; -} - -NS_IMETHODIMP -morkTable::BecomeContent(nsIMdbEnv* mev, - const mdbOid* inOid) // exchange content -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; - // remember table->MaybeDirtySpaceStoreAndTable(); -} - -// } ----- end ID methods ----- - -// { ----- begin activity dropping methods ----- -NS_IMETHODIMP -morkTable::DropActivity( // tell collection usage no longer expected - nsIMdbEnv* mev) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -// } ----- end activity dropping methods ----- - -// } ===== end nsIMdbCollection methods ===== - -// { ===== begin nsIMdbTable methods ===== - -// { ----- begin attribute methods ----- - -NS_IMETHODIMP -morkTable::SetTablePriority(nsIMdbEnv* mev, mdb_priority inPrio) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( inPrio > morkPriority_kMax ) - inPrio = morkPriority_kMax; - - mTable_Priority = inPrio; - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::GetTablePriority(nsIMdbEnv* mev, mdb_priority* outPrio) -{ - mdb_err outErr = 0; - mork_priority prio = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - prio = mTable_Priority; - if ( prio > morkPriority_kMax ) - { - prio = morkPriority_kMax; - mTable_Priority = prio; - } - outErr = ev->AsErr(); - } - if ( outPrio ) - *outPrio = prio; - return outErr; -} - - -NS_IMETHODIMP -morkTable:: GetTableBeVerbose(nsIMdbEnv* mev, mdb_bool* outBeVerbose) -{ - NS_ENSURE_ARG_POINTER(outBeVerbose); - *outBeVerbose = IsTableVerbose(); - return NS_OK; -} - -NS_IMETHODIMP -morkTable::SetTableBeVerbose(nsIMdbEnv* mev, mdb_bool inBeVerbose) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( inBeVerbose ) - SetTableVerbose(); - else - ClearTableVerbose(); - - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::GetTableIsUnique(nsIMdbEnv* mev, mdb_bool* outIsUnique) -{ - NS_ENSURE_ARG_POINTER(outIsUnique); - *outIsUnique = IsTableUnique(); - return NS_OK; -} - -NS_IMETHODIMP -morkTable::GetTableKind(nsIMdbEnv* mev, mdb_kind* outTableKind) -{ - NS_ENSURE_ARG_POINTER(outTableKind); - *outTableKind = mTable_Kind; - return NS_OK; -} - -NS_IMETHODIMP -morkTable::GetRowScope(nsIMdbEnv* mev, mdb_scope* outRowScope) -{ - mdb_err outErr = 0; - mdb_scope rowScope = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mTable_RowSpace ) - rowScope = mTable_RowSpace->SpaceScope(); - else - NilRowSpaceError(ev); - - outErr = ev->AsErr(); - } - if ( outRowScope ) - *outRowScope = rowScope; - return outErr; -} - -NS_IMETHODIMP -morkTable::GetMetaRow( nsIMdbEnv* mev, - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - mdbOid* outOid, // output meta row oid, can be nil to suppress output - nsIMdbRow** acqRow) // acquire table's unique singleton meta row - // The purpose of a meta row is to support the persistent recording of - // meta info about a table as cells put into the distinguished meta row. - // Each table has exactly one meta row, which is not considered a member - // of the collection of rows inside the table. The only way to tell - // whether a row is a meta row is by the fact that it is returned by this - // GetMetaRow() method from some table. Otherwise nothing distinguishes - // a meta row from any other row. A meta row can be used anyplace that - // any other row can be used, and can even be put into other tables (or - // the same table) as a table member, if this is useful for some reason. - // The first attempt to access a table's meta row using GetMetaRow() will - // cause the meta row to be created if it did not already exist. When the - // meta row is created, it will have the row oid that was previously - // requested for this table's meta row; or if no oid was ever explicitly - // specified for this meta row, then a unique oid will be generated in - // the row scope named "metaScope" (so obviously MDB clients should not - // manually allocate any row IDs from that special meta scope namespace). - // The meta row oid can be specified either when the table is created, or - // else the first time that GetMetaRow() is called, by passing a non-nil - // pointer to an oid for parameter inOptionalMetaRowOid. The meta row's - // actual oid is returned in outOid (if this is a non-nil pointer), and - // it will be different from inOptionalMetaRowOid when the meta row was - // already given a different oid earlier. -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRow* row = GetMetaRow(ev, inOptionalMetaRowOid); - if ( row && ev->Good() ) - { - if ( outOid ) - *outOid = row->mRow_Oid; - - outRow = row->AcquireRowHandle(ev, mTable_Store); - } - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - - if ( ev->Bad() && outOid ) - { - outOid->mOid_Scope = 0; - outOid->mOid_Id = morkRow_kMinusOneRid; - } - return outErr; -} - -// } ----- end attribute methods ----- - -// { ----- begin cursor methods ----- -NS_IMETHODIMP -morkTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos - nsIMdbEnv* mev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbTableRowCursor** acqCursor) // acquire new cursor instance -{ - mdb_err outErr = 0; - nsIMdbTableRowCursor* outCursor = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkTableRowCursor* cursor = NewTableRowCursor(ev, inRowPos); - if ( cursor ) - { - if ( ev->Good() ) - { - // cursor->mCursor_Seed = (mork_seed) inRowPos; - outCursor = cursor; - outCursor->AddRef(); - } - } - - outErr = ev->AsErr(); - } - if ( acqCursor ) - *acqCursor = outCursor; - return outErr; -} -// } ----- end row position methods ----- - -// { ----- begin row position methods ----- -NS_IMETHODIMP -morkTable::PosToOid( // get row member for a table position - nsIMdbEnv* mev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - mdbOid* outOid) // row oid at the specified position -{ - mdb_err outErr = 0; - mdbOid roid; - roid.mOid_Scope = 0; - roid.mOid_Id = (mork_id) -1; - - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRow* row = SafeRowAt(ev, inRowPos); - if ( row ) - roid = row->mRow_Oid; - - outErr = ev->AsErr(); - } - if ( outOid ) - *outOid = roid; - return outErr; -} - -NS_IMETHODIMP -morkTable::OidToPos( // test for the table position of a row member - nsIMdbEnv* mev, // context - const mdbOid* inOid, // row to find in table - mdb_pos* outPos) // zero-based ordinal position of row in table -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mork_pos pos = ArrayHasOid(ev, inOid); - if ( outPos ) - *outPos = pos; - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::PosToRow( // get row member for a table position - nsIMdbEnv* mev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbRow** acqRow) // acquire row at table position inRowPos -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRow* row = SafeRowAt(ev, inRowPos); - if ( row && mTable_Store ) - outRow = row->AcquireRowHandle(ev, mTable_Store); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP -morkTable::RowToPos( // test for the table position of a row member - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_pos* outPos) // zero-based ordinal position of row in table -{ - mdb_err outErr = 0; - mork_pos pos = -1; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject* row = (morkRowObject*) ioRow; - pos = ArrayHasOid(ev, &row->mRowObject_Row->mRow_Oid); - outErr = ev->AsErr(); - } - if ( outPos ) - *outPos = pos; - return outErr; -} - -// Note that HasRow() performs the inverse oid->pos mapping -// } ----- end row position methods ----- - -// { ----- begin oid set methods ----- -NS_IMETHODIMP -morkTable::AddOid( // make sure the row with inOid is a table member - nsIMdbEnv* mev, // context - const mdbOid* inOid) // row to ensure membership in table -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::HasOid( // test for the table position of a row member - nsIMdbEnv* mev, // context - const mdbOid* inOid, // row to find in table - mdb_bool* outHasOid) // whether inOid is a member row -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( outHasOid ) - *outHasOid = MapHasOid(ev, inOid); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::CutOid( // make sure the row with inOid is not a member - nsIMdbEnv* mev, // context - const mdbOid* inOid) // row to remove from table -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( inOid && mTable_Store ) - { - morkRow* row = mTable_Store->GetRow(ev, inOid); - if ( row ) - CutRow(ev, row); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end oid set methods ----- - -// { ----- begin row set methods ----- -NS_IMETHODIMP -morkTable::NewRow( // create a new row instance in table - nsIMdbEnv* mev, // context - mdbOid* ioOid, // please use zero (unbound) rowId for db-assigned IDs - nsIMdbRow** acqRow) // create new row -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( ioOid && mTable_Store ) - { - morkRow* row = 0; - if ( ioOid->mOid_Id == morkRow_kMinusOneRid ) - row = mTable_Store->NewRow(ev, ioOid->mOid_Scope); - else - row = mTable_Store->NewRowWithOid(ev, ioOid); - - if ( row && AddRow(ev, row) ) - outRow = row->AcquireRowHandle(ev, mTable_Store); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP -morkTable::AddRow( // make sure the row with inOid is a table member - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow) // row to ensure membership in table -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject *rowObj = (morkRowObject *) ioRow; - morkRow* row = rowObj->mRowObject_Row; - AddRow(ev, row); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::HasRow( // test for the table position of a row member - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_bool* outBool) // zero-based ordinal position of row in table -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject *rowObj = (morkRowObject *) ioRow; - morkRow* row = rowObj->mRowObject_Row; - if ( outBool ) - *outBool = MapHasOid(ev, &row->mRow_Oid); - outErr = ev->AsErr(); - } - return outErr; -} - - -NS_IMETHODIMP -morkTable::CutRow( // make sure the row with inOid is not a member - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow) // row to remove from table -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject *rowObj = (morkRowObject *) ioRow; - morkRow* row = rowObj->mRowObject_Row; - CutRow(ev, row); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkTable::CutAllRows( // remove all rows from the table - nsIMdbEnv* mev) // context -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - CutAllRows(ev); - outErr = ev->AsErr(); - } - return outErr; -} -// } ----- end row set methods ----- - -// { ----- begin searching methods ----- -NS_IMETHODIMP -morkTable::FindRowMatches( // search variable number of sorted cols - nsIMdbEnv* mev, // context - const mdbYarn* inPrefix, // content to find as prefix in row's column cell - nsIMdbTableRowCursor** acqCursor) // set of matching rows -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::GetSearchColumns( // query columns used by FindRowMatches() - nsIMdbEnv* mev, // context - mdb_count* outCount, // context - mdbColumnSet* outColSet) // caller supplied space to put columns - // GetSearchColumns() returns the columns actually searched when the - // FindRowMatches() method is called. No more than mColumnSet_Count - // slots of mColumnSet_Columns will be written, since mColumnSet_Count - // indicates how many slots are present in the column array. The - // actual number of search column used by the table is returned in - // the outCount parameter; if this number exceeds mColumnSet_Count, - // then a caller needs a bigger array to read the entire column set. - // The minimum of mColumnSet_Count and outCount is the number slots - // in mColumnSet_Columns that were actually written by this method. - // - // Callers are expected to change this set of columns by calls to - // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end searching methods ----- - -// { ----- begin hinting methods ----- -NS_IMETHODIMP -morkTable::SearchColumnsHint( // advise re future expected search cols - nsIMdbEnv* mev, // context - const mdbColumnSet* inColumnSet) // columns likely to be searched -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::SortColumnsHint( // advise re future expected sort columns - nsIMdbEnv* mev, // context - const mdbColumnSet* inColumnSet) // columns for likely sort requests -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::StartBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* mev, // context - const void* inLabel) // intend unique address to match end call - // If batch starts nest by virtue of nesting calls in the stack, then - // the address of a local variable makes a good batch start label that - // can be used at batch end time, and such addresses remain unique. -{ - // we don't do anything here. - return NS_OK; -} - -NS_IMETHODIMP -morkTable::EndBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* mev, // context - const void* inLabel) // label matching start label - // Suppose a table is maintaining one or many sort orders for a table, - // so that every row added to the table must be inserted in each sort, - // and every row cut must be removed from each sort. If a db client - // intends to make many such changes before needing any information - // about the order or positions of rows inside a table, then a client - // might tell the table to start batch changes in order to disable - // sorting of rows for the interim. Presumably a table will then do - // a full sort of all rows at need when the batch changes end, or when - // a surprise request occurs for row position during batch changes. -{ - // we don't do anything here. - return NS_OK; -} -// } ----- end hinting methods ----- - -// { ----- begin sorting methods ----- -// sorting: note all rows are assumed sorted by row ID as a secondary -// sort following the primary column sort, when table rows are sorted. - -NS_IMETHODIMP -morkTable::CanSortColumn( // query which column is currently used for sorting - nsIMdbEnv* mev, // context - mdb_column inColumn, // column to query sorting potential - mdb_bool* outCanSort) // whether the column can be sorted -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::GetSorting( // view same table in particular sorting - nsIMdbEnv* mev, // context - mdb_column inColumn, // requested new column for sorting table - nsIMdbSorting** acqSorting) // acquire sorting for column -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::SetSearchSorting( // use this sorting in FindRowMatches() - nsIMdbEnv* mev, // context - mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn() - nsIMdbSorting* ioSorting) // requested sorting for some column - // SetSearchSorting() attempts to inform the table that ioSorting - // should be used during calls to FindRowMatches() for searching - // the column which is actually sorted by ioSorting. This method - // is most useful in conjunction with nsIMdbSorting::SetCompare(), - // because otherwise a caller would not be able to override the - // comparison ordering method used during searchs. Note that some - // database implementations might be unable to use an arbitrarily - // specified sort order, either due to schema or runtime interface - // constraints, in which case ioSorting might not actually be used. - // Presumably ioSorting is an instance that was returned from some - // earlier call to nsIMdbTable::GetSorting(). A caller can also - // use nsIMdbTable::SearchColumnsHint() to specify desired change - // in which columns are sorted and searched by FindRowMatches(). - // - // A caller can pass a nil pointer for ioSorting to request that - // column inColumn no longer be used at all by FindRowMatches(). - // But when ioSorting is non-nil, then inColumn should match the - // column actually sorted by ioSorting; when these do not agree, - // implementations are instructed to give precedence to the column - // specified by ioSorting (so this means callers might just pass - // zero for inColumn when ioSorting is also provided, since then - // inColumn is both redundant and ignored). -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -// } ----- end sorting methods ----- - -// { ----- begin moving methods ----- -// moving a row does nothing unless a table is currently unsorted - -NS_IMETHODIMP -morkTable::MoveOid( // change position of row in unsorted table - nsIMdbEnv* mev, // context - const mdbOid* inOid, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row inOid - mdb_pos* outActualPos) // actual new position of row in table -{ - mdb_err outErr = 0; - mdb_pos actualPos = -1; // meaning it was never found in table - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( inOid && mTable_Store ) - { - morkRow* row = mTable_Store->GetRow(ev, inOid); - if ( row ) - actualPos = MoveRow(ev, row, inHintFromPos, inToPos); - } - else - ev->NilPointerError(); - - outErr = ev->AsErr(); - } - if ( outActualPos ) - *outActualPos = actualPos; - return outErr; -} - -NS_IMETHODIMP -morkTable::MoveRow( // change position of row in unsorted table - nsIMdbEnv* mev, // context - nsIMdbRow* ioRow, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row ioRow - mdb_pos* outActualPos) // actual new position of row in table -{ - mdb_pos actualPos = -1; // meaning it was never found in table - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - morkRowObject *rowObj = (morkRowObject *) ioRow; - morkRow* row = rowObj->mRowObject_Row; - actualPos = MoveRow(ev, row, inHintFromPos, inToPos); - outErr = ev->AsErr(); - } - if ( outActualPos ) - *outActualPos = actualPos; - return outErr; -} -// } ----- end moving methods ----- - -// { ----- begin index methods ----- -NS_IMETHODIMP -morkTable::AddIndex( // create a sorting index for column if possible - nsIMdbEnv* mev, // context - mdb_column inColumn, // the column to sort by index - nsIMdbThumb** acqThumb) // acquire thumb for incremental index building -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the index addition will be finished. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::CutIndex( // stop supporting a specific column index - nsIMdbEnv* mev, // context - mdb_column inColumn, // the column with index to be removed - nsIMdbThumb** acqThumb) // acquire thumb for incremental index destroy -// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and -// then the index removal will be finished. -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::HasIndex( // query for current presence of a column index - nsIMdbEnv* mev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outHasIndex) // whether column has index for this column -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::EnableIndexOnSort( // create an index for col on first sort - nsIMdbEnv* mev, // context - mdb_column inColumn) // the column to index if ever sorted -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::QueryIndexOnSort( // check whether index on sort is enabled - nsIMdbEnv* mev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outIndexOnSort) // whether column has index-on-sort enabled -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -morkTable::DisableIndexOnSort( // prevent future index creation on sort - nsIMdbEnv* mev, // context - mdb_column inColumn) // the column to index if ever sorted -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} -// } ----- end index methods ----- - -// } ===== end nsIMdbTable methods ===== - -// we override these so that we'll use the xpcom add and release ref. -mork_refs -morkTable::AddStrongRef(morkEnv *ev) -{ - return (mork_refs) AddRef(); -} - -mork_refs -morkTable::CutStrongRef(morkEnv *ev) -{ - return (mork_refs) Release(); -} - -mork_u2 -morkTable::AddTableGcUse(morkEnv* ev) -{ - MORK_USED_1(ev); - if ( mTable_GcUses < morkTable_kMaxTableGcUses ) // not already maxed out? - ++mTable_GcUses; - - return mTable_GcUses; -} - -mork_u2 -morkTable::CutTableGcUse(morkEnv* ev) -{ - if ( mTable_GcUses ) // any outstanding uses to cut? - { - if ( mTable_GcUses < morkTable_kMaxTableGcUses ) // not frozen at max? - --mTable_GcUses; - } - else - this->TableGcUsesUnderflowWarning(ev); - - return mTable_GcUses; -} - -// table dirty handling more complex thatn morkNode::SetNodeDirty() etc. - -void morkTable::SetTableClean(morkEnv* ev) -{ - if ( mTable_ChangeList.HasListMembers() ) - { - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes - } - mTable_ChangesCount = 0; - - mTable_Flags = 0; - this->SetNodeClean(); -} - -// notifications regarding table changes: - -void morkTable::NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos) -{ - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - if ( this->IsTableRewrite() || this->HasChangeOverflow() ) - this->NoteTableSetAll(ev); - else - { - morkTableChange* tableChange = new(*heap, ev) - morkTableChange(ev, ioRow, inPos); - if ( tableChange ) - { - if ( ev->Good() ) - { - mTable_ChangeList.PushTail(tableChange); - ++mTable_ChangesCount; - } - else - { - tableChange->ZapOldNext(ev, heap); - this->SetTableRewrite(); // just plan to write all table rows - } - } - } -} - -void morkTable::note_row_move(morkEnv* ev, morkRow* ioRow, mork_pos inNewPos) -{ - if ( this->IsTableRewrite() || this->HasChangeOverflow() ) - this->NoteTableSetAll(ev); - else - { - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - morkTableChange* tableChange = new(*heap, ev) - morkTableChange(ev, ioRow, inNewPos); - if ( tableChange ) - { - if ( ev->Good() ) - { - mTable_ChangeList.PushTail(tableChange); - ++mTable_ChangesCount; - } - else - { - tableChange->ZapOldNext(ev, heap); - this->NoteTableSetAll(ev); - } - } - } -} - -void morkTable::note_row_change(morkEnv* ev, mork_change inChange, - morkRow* ioRow) -{ - if ( this->IsTableRewrite() || this->HasChangeOverflow() ) - this->NoteTableSetAll(ev); - else - { - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - morkTableChange* tableChange = new(*heap, ev) - morkTableChange(ev, inChange, ioRow); - if ( tableChange ) - { - if ( ev->Good() ) - { - mTable_ChangeList.PushTail(tableChange); - ++mTable_ChangesCount; - } - else - { - tableChange->ZapOldNext(ev, heap); - this->NoteTableSetAll(ev); - } - } - } -} - -void morkTable::NoteTableSetAll(morkEnv* ev) -{ - if ( mTable_ChangeList.HasListMembers() ) - { - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes - } - mTable_ChangesCount = 0; - this->SetTableRewrite(); -} - -/*static*/ void -morkTable::TableGcUsesUnderflowWarning(morkEnv* ev) -{ - ev->NewWarning("mTable_GcUses underflow"); -} - -/*static*/ void -morkTable::NonTableTypeError(morkEnv* ev) -{ - ev->NewError("non morkTable"); -} - -/*static*/ void -morkTable::NonTableTypeWarning(morkEnv* ev) -{ - ev->NewWarning("non morkTable"); -} - -/*static*/ void -morkTable::NilRowSpaceError(morkEnv* ev) -{ - ev->NewError("nil mTable_RowSpace"); -} - -mork_bool morkTable::MaybeDirtySpaceStoreAndTable() -{ - morkRowSpace* rowSpace = mTable_RowSpace; - if ( rowSpace ) - { - morkStore* store = rowSpace->mSpace_Store; - if ( store && store->mStore_CanDirty ) - { - store->SetStoreDirty(); - rowSpace->mSpace_CanDirty = morkBool_kTrue; - } - - if ( rowSpace->mSpace_CanDirty ) // first time being dirtied? - { - if ( this->IsTableClean() ) - { - mork_count rowCount = this->GetRowCount(); - mork_count oneThird = rowCount / 4; // one third of rows - if ( oneThird > 0x07FFF ) // more than half max u2? - oneThird = 0x07FFF; - - mTable_ChangesMax = (mork_u2) oneThird; - } - this->SetTableDirty(); - rowSpace->SetRowSpaceDirty(); - - return morkBool_kTrue; - } - } - return morkBool_kFalse; -} - -morkRow* -morkTable::GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid) -{ - morkRow* outRow = mTable_MetaRow; - if ( !outRow ) - { - morkStore* store = mTable_Store; - mdbOid* oid = &mTable_MetaRowOid; - if ( inOptionalMetaRowOid && !oid->mOid_Scope ) - *oid = *inOptionalMetaRowOid; - - if ( oid->mOid_Scope ) // oid already recorded in table? - outRow = store->OidToRow(ev, oid); - else - { - outRow = store->NewRow(ev, morkStore_kMetaScope); - if ( outRow ) // need to record new oid in table? - *oid = outRow->mRow_Oid; - } - mTable_MetaRow = outRow; - if ( outRow ) // need to note another use of this row? - { - outRow->AddRowGcUse(ev); - - this->SetTableNewMeta(); - if ( this->IsTableClean() ) // catch dirty status of meta row? - this->MaybeDirtySpaceStoreAndTable(); - } - } - - return outRow; -} - -void -morkTable::GetTableOid(morkEnv* ev, mdbOid* outOid) -{ - morkRowSpace* space = mTable_RowSpace; - if ( space ) - { - outOid->mOid_Scope = space->SpaceScope(); - outOid->mOid_Id = this->TableId(); - } - else - this->NilRowSpaceError(ev); -} - -nsIMdbTable* -morkTable::AcquireTableHandle(morkEnv* ev) -{ - AddRef(); - return this; -} - -mork_pos -morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid) -{ - MORK_USED_1(ev); - mork_count count = mTable_RowArray.mArray_Fill; - mork_pos pos = -1; - while ( ++pos < (mork_pos)count ) - { - morkRow* row = (morkRow*) mTable_RowArray.At(pos); - MORK_ASSERT(row); - if ( row && row->EqualOid(inOid) ) - { - return pos; - } - } - return -1; -} - -mork_bool -morkTable::MapHasOid(morkEnv* ev, const mdbOid* inOid) -{ - if ( mTable_RowMap ) - return ( mTable_RowMap->GetOid(ev, inOid) != 0 ); - else - return ( ArrayHasOid(ev, inOid) >= 0 ); -} - -void morkTable::build_row_map(morkEnv* ev) -{ - morkRowMap* map = mTable_RowMap; - if ( !map ) - { - mork_count count = mTable_RowArray.mArray_Fill + 3; - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - map = new(*heap, ev) morkRowMap(ev, morkUsage::kHeap, heap, heap, count); - if ( map ) - { - if ( ev->Good() ) - { - mTable_RowMap = map; // put strong ref here - count = mTable_RowArray.mArray_Fill; - mork_pos pos = -1; - while ( ++pos < (mork_pos)count ) - { - morkRow* row = (morkRow*) mTable_RowArray.At(pos); - if ( row && row->IsRow() ) - map->AddRow(ev, row); - else - row->NonRowTypeError(ev); - } - } - else - map->CutStrongRef(ev); - } - } -} - -morkRow* morkTable::find_member_row(morkEnv* ev, morkRow* ioRow) -{ - if ( mTable_RowMap ) - return mTable_RowMap->GetRow(ev, ioRow); - else - { - mork_count count = mTable_RowArray.mArray_Fill; - mork_pos pos = -1; - while ( ++pos < (mork_pos)count ) - { - morkRow* row = (morkRow*) mTable_RowArray.At(pos); - if ( row == ioRow ) - return row; - } - } - return (morkRow*) 0; -} - -mork_pos -morkTable::MoveRow(morkEnv* ev, morkRow* ioRow, // change row position - mork_pos inHintFromPos, // suggested hint regarding start position - mork_pos inToPos) // desired new position for row ioRow - // MoveRow() returns the actual position of ioRow afterwards; this - // position is -1 if and only if ioRow was not found as a member. -{ - mork_pos outPos = -1; // means ioRow was not a table member - mork_bool canDirty = ( this->IsTableClean() )? - this->MaybeDirtySpaceStoreAndTable() : morkBool_kTrue; - - morkRow** rows = (morkRow**) mTable_RowArray.mArray_Slots; - mork_count count = mTable_RowArray.mArray_Fill; - if ( count && rows && ev->Good() ) // any members at all? no errors? - { - mork_pos lastPos = count - 1; // index of last row slot - - if ( inToPos > lastPos ) // beyond last used array slot? - inToPos = lastPos; // put row into last available slot - else if ( inToPos < 0 ) // before first usable slot? - inToPos = 0; // put row in very first slow - - if ( inHintFromPos > lastPos ) // beyond last used array slot? - inHintFromPos = lastPos; // seek row in last available slot - else if ( inHintFromPos < 0 ) // before first usable slot? - inHintFromPos = 0; // seek row in very first slow - - morkRow** fromSlot = 0; // becomes nonzero of ioRow is ever found - morkRow** rowsEnd = rows + count; // one past last used array slot - - if ( inHintFromPos <= 0 ) // start of table? just scan for row? - { - morkRow** cursor = rows - 1; // before first array slot - while ( ++cursor < rowsEnd ) - { - if ( *cursor == ioRow ) - { - fromSlot = cursor; - break; // end while loop - } - } - } - else // search near the start position and work outwards - { - morkRow** lo = rows + inHintFromPos; // lowest search point - morkRow** hi = lo; // highest search point starts at lowest point - - // Seek ioRow in spiral widening search below and above inHintFromPos. - // This is faster when inHintFromPos is at all accurate, but is slower - // than a straightforward scan when inHintFromPos is nearly random. - - while ( lo >= rows || hi < rowsEnd ) // keep searching? - { - if ( lo >= rows ) // low direction search still feasible? - { - if ( *lo == ioRow ) // actually found the row? - { - fromSlot = lo; - break; // end while loop - } - --lo; // advance further lower - } - if ( hi < rowsEnd ) // high direction search still feasible? - { - if ( *hi == ioRow ) // actually found the row? - { - fromSlot = hi; - break; // end while loop - } - ++hi; // advance further higher - } - } - } - - if ( fromSlot ) // ioRow was found as a table member? - { - outPos = fromSlot - rows; // actual position where row was found - if ( outPos != inToPos ) // actually need to move this row? - { - morkRow** toSlot = rows + inToPos; // slot where row must go - - ++mTable_RowArray.mArray_Seed; // we modify the array now: - - if ( fromSlot < toSlot ) // row is moving upwards? - { - morkRow** up = fromSlot; // leading pointer going upward - while ( ++up <= toSlot ) // have not gone above destination? - { - *fromSlot = *up; // shift down one - fromSlot = up; // shift trailing pointer up - } - } - else // ( fromSlot > toSlot ) // row is moving downwards - { - morkRow** down = fromSlot; // leading pointer going downward - while ( --down >= toSlot ) // have not gone below destination? - { - *fromSlot = *down; // shift up one - fromSlot = down; // shift trailing pointer - } - } - *toSlot = ioRow; - outPos = inToPos; // okay, we actually moved the row here - - if ( canDirty ) - this->note_row_move(ev, ioRow, inToPos); - } - } - } - return outPos; -} - -mork_bool -morkTable::AddRow(morkEnv* ev, morkRow* ioRow) -{ - morkRow* row = this->find_member_row(ev, ioRow); - if ( !row && ev->Good() ) - { - mork_bool canDirty = ( this->IsTableClean() )? - this->MaybeDirtySpaceStoreAndTable() : morkBool_kTrue; - - mork_pos pos = mTable_RowArray.AppendSlot(ev, ioRow); - if ( ev->Good() && pos >= 0 ) - { - ioRow->AddRowGcUse(ev); - if ( mTable_RowMap ) - { - if ( mTable_RowMap->AddRow(ev, ioRow) ) - { - // okay, anything else? - } - else - mTable_RowArray.CutSlot(ev, pos); - } - else if ( mTable_RowArray.mArray_Fill >= morkTable_kMakeRowMapThreshold ) - this->build_row_map(ev); - - if ( canDirty && ev->Good() ) - this->NoteTableAddRow(ev, ioRow); - } - } - return ev->Good(); -} - -mork_bool -morkTable::CutRow(morkEnv* ev, morkRow* ioRow) -{ - morkRow* row = this->find_member_row(ev, ioRow); - if ( row ) - { - mork_bool canDirty = ( this->IsTableClean() )? - this->MaybeDirtySpaceStoreAndTable() : morkBool_kTrue; - - mork_count count = mTable_RowArray.mArray_Fill; - morkRow** rowSlots = (morkRow**) mTable_RowArray.mArray_Slots; - if ( rowSlots ) // array has vector as expected? - { - mork_pos pos = -1; - morkRow** end = rowSlots + count; - morkRow** slot = rowSlots - 1; // prepare for preincrement: - while ( ++slot < end ) // another slot to check? - { - if ( *slot == row ) // found the slot containing row? - { - pos = slot - rowSlots; // record absolute position - break; // end while loop - } - } - if ( pos >= 0 ) // need to cut if from the array? - mTable_RowArray.CutSlot(ev, pos); - else - ev->NewWarning("row not found in array"); - } - else - mTable_RowArray.NilSlotsAddressError(ev); - - if ( mTable_RowMap ) - mTable_RowMap->CutRow(ev, ioRow); - - if ( canDirty ) - this->NoteTableCutRow(ev, ioRow); - - if ( ioRow->CutRowGcUse(ev) == 0 ) - ioRow->OnZeroRowGcUse(ev); - } - return ev->Good(); -} - - -mork_bool -morkTable::CutAllRows(morkEnv* ev) -{ - if ( this->MaybeDirtySpaceStoreAndTable() ) - { - this->SetTableRewrite(); // everything is dirty - this->NoteTableSetAll(ev); - } - - if ( ev->Good() ) - { - mTable_RowArray.CutAllSlots(ev); - if ( mTable_RowMap ) - { - morkRowMapIter i(ev, mTable_RowMap); - mork_change* c = 0; - morkRow* r = 0; - - for ( c = i.FirstRow(ev, &r); c; c = i.NextRow(ev, &r) ) - { - if ( r ) - { - if ( r->CutRowGcUse(ev) == 0 ) - r->OnZeroRowGcUse(ev); - - i.CutHereRow(ev, (morkRow**) 0); - } - else - ev->NewWarning("nil row in table map"); - } - } - } - return ev->Good(); -} - -morkTableRowCursor* -morkTable::NewTableRowCursor(morkEnv* ev, mork_pos inRowPos) -{ - morkTableRowCursor* outCursor = 0; - if ( ev->Good() ) - { - nsIMdbHeap* heap = mTable_Store->mPort_Heap; - morkTableRowCursor* cursor = new(*heap, ev) - morkTableRowCursor(ev, morkUsage::kHeap, heap, this, inRowPos); - if ( cursor ) - { - if ( ev->Good() ) - outCursor = cursor; - else - cursor->CutStrongRef((nsIMdbEnv *) ev); - } - } - return outCursor; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -morkTableChange::morkTableChange(morkEnv* ev, mork_change inChange, - morkRow* ioRow) -// use this constructor for inChange == morkChange_kAdd or morkChange_kCut -: morkNext() -, mTableChange_Row( ioRow ) -, mTableChange_Pos( morkTableChange_kNone ) -{ - if ( ioRow ) - { - if ( ioRow->IsRow() ) - { - if ( inChange == morkChange_kAdd ) - mTableChange_Pos = morkTableChange_kAdd; - else if ( inChange == morkChange_kCut ) - mTableChange_Pos = morkTableChange_kCut; - else - this->UnknownChangeError(ev); - } - else - ioRow->NonRowTypeError(ev); - } - else - ev->NilPointerError(); -} - -morkTableChange::morkTableChange(morkEnv* ev, morkRow* ioRow, mork_pos inPos) -// use this constructor when the row is moved -: morkNext() -, mTableChange_Row( ioRow ) -, mTableChange_Pos( inPos ) -{ - if ( ioRow ) - { - if ( ioRow->IsRow() ) - { - if ( inPos < 0 ) - this->NegativeMovePosError(ev); - } - else - ioRow->NonRowTypeError(ev); - } - else - ev->NilPointerError(); -} - -void morkTableChange::UnknownChangeError(morkEnv* ev) const -// morkChange_kAdd or morkChange_kCut -{ - ev->NewError("mTableChange_Pos neither kAdd nor kCut"); -} - -void morkTableChange::NegativeMovePosError(morkEnv* ev) const -// move must be non-neg position -{ - ev->NewError("negative mTableChange_Pos for row move"); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -morkTableMap::~morkTableMap() -{ -} - -morkTableMap::morkTableMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap) -#ifdef MORK_BEAD_OVER_NODE_MAPS - : morkBeadMap(ev, inUsage, ioHeap, ioSlotHeap) -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap) -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kTableMap; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkTable.h b/db/mork/src/morkTable.h deleted file mode 100644 index 3b35e154632e..000000000000 --- a/db/mork/src/morkTable.h +++ /dev/null @@ -1,753 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKTABLE_ -#define _MORKTABLE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -#ifndef _MORKARRAY_ -#include "morkArray.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKNODEMAP_ -#include "morkNodeMap.h" -#endif - -#ifndef _MORKPROBEMAP_ -#include "morkProbeMap.h" -#endif - -#ifndef _MORKBEAD_ -#include "morkBead.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class nsIMdbTable; -#define morkDerived_kTable /*i*/ 0x5462 /* ascii 'Tb' */ - -/*| kStartRowArraySize: starting physical size of array for mTable_RowArray. -**| We want this number very small, so that a table containing exactly one -**| row member will not pay too significantly in space overhead. But we want -**| a number bigger than one, so there is some space for growth. -|*/ -#define morkTable_kStartRowArraySize 3 /* modest starting size for array */ - -/*| kMakeRowMapThreshold: this is the number of rows in a table which causes -**| a hash table (mTable_RowMap) to be lazily created for faster member row -**| identification, during such operations as cuts and adds. This number must -**| be small enough that linear searches are not bad for member counts less -**| than this; but this number must also be large enough that creating a hash -**| table does not increase the per-row space overhead by a big percentage. -**| For speed, numbers on the order of ten to twenty are all fine; for space, -**| I believe a number as small as ten will have too much space overhead. -|*/ -#define morkTable_kMakeRowMapThreshold 17 /* when to build mTable_RowMap */ - -#define morkTable_kStartRowMapSlotCount 13 -#define morkTable_kMaxTableGcUses 0x0FF /* max for 8-bit unsigned int */ - -#define morkTable_kUniqueBit ((mork_u1) (1 << 0)) -#define morkTable_kVerboseBit ((mork_u1) (1 << 1)) -#define morkTable_kNotedBit ((mork_u1) (1 << 2)) /* space has change notes */ -#define morkTable_kRewriteBit ((mork_u1) (1 << 3)) /* must rewrite all rows */ -#define morkTable_kNewMetaBit ((mork_u1) (1 << 4)) /* new table meta row */ - -class morkTable : public morkObject, public morkLink, public nsIMdbTable { - - // NOTE the morkLink base is for morkRowSpace::mRowSpace_TablesByPriority - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // bead color setter & getter replace obsolete member mTable_Id: - - NS_DECL_ISUPPORTS_INHERITED - mork_tid TableId() const { return mBead_Color; } - void SetTableId(mork_tid inTid) { mBead_Color = inTid; } - - // we override these so we use xpcom ref-counting semantics. - virtual mork_refs AddStrongRef(morkEnv* ev); - virtual mork_refs CutStrongRef(morkEnv* ev); -public: // state is public because the entire Mork system is private - -// { ===== begin nsIMdbCollection methods ===== - - // { ----- begin attribute methods ----- - NS_IMETHOD GetSeed(nsIMdbEnv* ev, - mdb_seed* outSeed); // member change count - NS_IMETHOD GetCount(nsIMdbEnv* ev, - mdb_count* outCount); // member count - - NS_IMETHOD GetPort(nsIMdbEnv* ev, - nsIMdbPort** acqPort); // collection container - // } ----- end attribute methods ----- - - // { ----- begin cursor methods ----- - NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos - nsIMdbEnv* ev, // context - mdb_pos inMemberPos, // zero-based ordinal pos of member in collection - nsIMdbCursor** acqCursor); // acquire new cursor instance - // } ----- end cursor methods ----- - - // { ----- begin ID methods ----- - NS_IMETHOD GetOid(nsIMdbEnv* ev, - mdbOid* outOid); // read object identity - NS_IMETHOD BecomeContent(nsIMdbEnv* ev, - const mdbOid* inOid); // exchange content - // } ----- end ID methods ----- - - // { ----- begin activity dropping methods ----- - NS_IMETHOD DropActivity( // tell collection usage no longer expected - nsIMdbEnv* ev); - // } ----- end activity dropping methods ----- - -// } ===== end nsIMdbCollection methods ===== - NS_IMETHOD SetTablePriority(nsIMdbEnv* ev, mdb_priority inPrio); - NS_IMETHOD GetTablePriority(nsIMdbEnv* ev, mdb_priority* outPrio); - - NS_IMETHOD GetTableBeVerbose(nsIMdbEnv* ev, mdb_bool* outBeVerbose); - NS_IMETHOD SetTableBeVerbose(nsIMdbEnv* ev, mdb_bool inBeVerbose); - - NS_IMETHOD GetTableIsUnique(nsIMdbEnv* ev, mdb_bool* outIsUnique); - - NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind); - NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope); - - NS_IMETHOD GetMetaRow( - nsIMdbEnv* ev, // context - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - mdbOid* outOid, // output meta row oid, can be nil to suppress output - nsIMdbRow** acqRow); // acquire table's unique singleton meta row - // The purpose of a meta row is to support the persistent recording of - // meta info about a table as cells put into the distinguished meta row. - // Each table has exactly one meta row, which is not considered a member - // of the collection of rows inside the table. The only way to tell - // whether a row is a meta row is by the fact that it is returned by this - // GetMetaRow() method from some table. Otherwise nothing distinguishes - // a meta row from any other row. A meta row can be used anyplace that - // any other row can be used, and can even be put into other tables (or - // the same table) as a table member, if this is useful for some reason. - // The first attempt to access a table's meta row using GetMetaRow() will - // cause the meta row to be created if it did not already exist. When the - // meta row is created, it will have the row oid that was previously - // requested for this table's meta row; or if no oid was ever explicitly - // specified for this meta row, then a unique oid will be generated in - // the row scope named "m" (so obviously MDB clients should not - // manually allocate any row IDs from that special meta scope namespace). - // The meta row oid can be specified either when the table is created, or - // else the first time that GetMetaRow() is called, by passing a non-nil - // pointer to an oid for parameter inOptionalMetaRowOid. The meta row's - // actual oid is returned in outOid (if this is a non-nil pointer), and - // it will be different from inOptionalMetaRowOid when the meta row was - // already given a different oid earlier. - // } ----- end meta attribute methods ----- - - - // { ----- begin cursor methods ----- - NS_IMETHOD GetTableRowCursor( // make a cursor, starting iteration at inRowPos - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbTableRowCursor** acqCursor); // acquire new cursor instance - // } ----- end row position methods ----- - - // { ----- begin row position methods ----- - NS_IMETHOD PosToOid( // get row member for a table position - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - mdbOid* outOid); // row oid at the specified position - - NS_IMETHOD OidToPos( // test for the table position of a row member - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row to find in table - mdb_pos* outPos); // zero-based ordinal position of row in table - - NS_IMETHOD PosToRow( // test for the table position of a row member - nsIMdbEnv* ev, // context - mdb_pos inRowPos, // zero-based ordinal position of row in table - nsIMdbRow** acqRow); // acquire row at table position inRowPos - - NS_IMETHOD RowToPos( // test for the table position of a row member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_pos* outPos); // zero-based ordinal position of row in table - // } ----- end row position methods ----- - - // { ----- begin oid set methods ----- - NS_IMETHOD AddOid( // make sure the row with inOid is a table member - nsIMdbEnv* ev, // context - const mdbOid* inOid); // row to ensure membership in table - - NS_IMETHOD HasOid( // test for the table position of a row member - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row to find in table - mdb_bool* outHasOid); // whether inOid is a member row - - NS_IMETHOD CutOid( // make sure the row with inOid is not a member - nsIMdbEnv* ev, // context - const mdbOid* inOid); // row to remove from table - // } ----- end oid set methods ----- - - // { ----- begin row set methods ----- - NS_IMETHOD NewRow( // create a new row instance in table - nsIMdbEnv* ev, // context - mdbOid* ioOid, // please use minus one (unbound) rowId for db-assigned IDs - nsIMdbRow** acqRow); // create new row - - NS_IMETHOD AddRow( // make sure the row with inOid is a table member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow); // row to ensure membership in table - - NS_IMETHOD HasRow( // test for the table position of a row member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row to find in table - mdb_bool* outHasRow); // whether row is a table member - - NS_IMETHOD CutRow( // make sure the row with inOid is not a member - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow); // row to remove from table - - NS_IMETHOD CutAllRows( // remove all rows from the table - nsIMdbEnv* ev); // context - // } ----- end row set methods ----- - - // { ----- begin hinting methods ----- - NS_IMETHOD SearchColumnsHint( // advise re future expected search cols - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet); // columns likely to be searched - - NS_IMETHOD SortColumnsHint( // advise re future expected sort columns - nsIMdbEnv* ev, // context - const mdbColumnSet* inColumnSet); // columns for likely sort requests - - NS_IMETHOD StartBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* ev, // context - const void* inLabel); // intend unique address to match end call - // If batch starts nest by virtue of nesting calls in the stack, then - // the address of a local variable makes a good batch start label that - // can be used at batch end time, and such addresses remain unique. - - NS_IMETHOD EndBatchChangeHint( // advise before many adds and cuts - nsIMdbEnv* ev, // context - const void* inLabel); // label matching start label - // Suppose a table is maintaining one or many sort orders for a table, - // so that every row added to the table must be inserted in each sort, - // and every row cut must be removed from each sort. If a db client - // intends to make many such changes before needing any information - // about the order or positions of rows inside a table, then a client - // might tell the table to start batch changes in order to disable - // sorting of rows for the interim. Presumably a table will then do - // a full sort of all rows at need when the batch changes end, or when - // a surprise request occurs for row position during batch changes. - // } ----- end hinting methods ----- - - // { ----- begin searching methods ----- - NS_IMETHOD FindRowMatches( // search variable number of sorted cols - nsIMdbEnv* ev, // context - const mdbYarn* inPrefix, // content to find as prefix in row's column cell - nsIMdbTableRowCursor** acqCursor); // set of matching rows - - NS_IMETHOD GetSearchColumns( // query columns used by FindRowMatches() - nsIMdbEnv* ev, // context - mdb_count* outCount, // context - mdbColumnSet* outColSet); // caller supplied space to put columns - // GetSearchColumns() returns the columns actually searched when the - // FindRowMatches() method is called. No more than mColumnSet_Count - // slots of mColumnSet_Columns will be written, since mColumnSet_Count - // indicates how many slots are present in the column array. The - // actual number of search column used by the table is returned in - // the outCount parameter; if this number exceeds mColumnSet_Count, - // then a caller needs a bigger array to read the entire column set. - // The minimum of mColumnSet_Count and outCount is the number slots - // in mColumnSet_Columns that were actually written by this method. - // - // Callers are expected to change this set of columns by calls to - // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both. - // } ----- end searching methods ----- - - // { ----- begin sorting methods ----- - // sorting: note all rows are assumed sorted by row ID as a secondary - // sort following the primary column sort, when table rows are sorted. - - NS_IMETHOD - CanSortColumn( // query which column is currently used for sorting - nsIMdbEnv* ev, // context - mdb_column inColumn, // column to query sorting potential - mdb_bool* outCanSort); // whether the column can be sorted - - NS_IMETHOD GetSorting( // view same table in particular sorting - nsIMdbEnv* ev, // context - mdb_column inColumn, // requested new column for sorting table - nsIMdbSorting** acqSorting); // acquire sorting for column - - NS_IMETHOD SetSearchSorting( // use this sorting in FindRowMatches() - nsIMdbEnv* ev, // context - mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn() - nsIMdbSorting* ioSorting); // requested sorting for some column - // SetSearchSorting() attempts to inform the table that ioSorting - // should be used during calls to FindRowMatches() for searching - // the column which is actually sorted by ioSorting. This method - // is most useful in conjunction with nsIMdbSorting::SetCompare(), - // because otherwise a caller would not be able to override the - // comparison ordering method used during searchs. Note that some - // database implementations might be unable to use an arbitrarily - // specified sort order, either due to schema or runtime interface - // constraints, in which case ioSorting might not actually be used. - // Presumably ioSorting is an instance that was returned from some - // earlier call to nsIMdbTable::GetSorting(). A caller can also - // use nsIMdbTable::SearchColumnsHint() to specify desired change - // in which columns are sorted and searched by FindRowMatches(). - // - // A caller can pass a nil pointer for ioSorting to request that - // column inColumn no longer be used at all by FindRowMatches(). - // But when ioSorting is non-nil, then inColumn should match the - // column actually sorted by ioSorting; when these do not agree, - // implementations are instructed to give precedence to the column - // specified by ioSorting (so this means callers might just pass - // zero for inColumn when ioSorting is also provided, since then - // inColumn is both redundant and ignored). - // } ----- end sorting methods ----- - - // { ----- begin moving methods ----- - // moving a row does nothing unless a table is currently unsorted - - NS_IMETHOD MoveOid( // change position of row in unsorted table - nsIMdbEnv* ev, // context - const mdbOid* inOid, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row inRowId - mdb_pos* outActualPos); // actual new position of row in table - - NS_IMETHOD MoveRow( // change position of row in unsorted table - nsIMdbEnv* ev, // context - nsIMdbRow* ioRow, // row oid to find in table - mdb_pos inHintFromPos, // suggested hint regarding start position - mdb_pos inToPos, // desired new position for row inRowId - mdb_pos* outActualPos); // actual new position of row in table - // } ----- end moving methods ----- - - // { ----- begin index methods ----- - NS_IMETHOD AddIndex( // create a sorting index for column if possible - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to sort by index - nsIMdbThumb** acqThumb); // acquire thumb for incremental index building - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the index addition will be finished. - - NS_IMETHOD CutIndex( // stop supporting a specific column index - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column with index to be removed - nsIMdbThumb** acqThumb); // acquire thumb for incremental index destroy - // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and - // then the index removal will be finished. - - NS_IMETHOD HasIndex( // query for current presence of a column index - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outHasIndex); // whether column has index for this column - - - NS_IMETHOD EnableIndexOnSort( // create an index for col on first sort - nsIMdbEnv* ev, // context - mdb_column inColumn); // the column to index if ever sorted - - NS_IMETHOD QueryIndexOnSort( // check whether index on sort is enabled - nsIMdbEnv* ev, // context - mdb_column inColumn, // the column to investigate - mdb_bool* outIndexOnSort); // whether column has index-on-sort enabled - - NS_IMETHOD DisableIndexOnSort( // prevent future index creation on sort - nsIMdbEnv* ev, // context - mdb_column inColumn); // the column to index if ever sorted - // } ----- end index methods ----- - - morkStore* mTable_Store; // non-refcnted ptr to port - - // mTable_RowSpace->SpaceScope() is row scope - morkRowSpace* mTable_RowSpace; // non-refcnted ptr to containing space - - morkRow* mTable_MetaRow; // table's actual meta row - mdbOid mTable_MetaRowOid; // oid for meta row - - morkRowMap* mTable_RowMap; // (strong ref) hash table of all members - morkArray mTable_RowArray; // array of morkRow pointers - - morkList mTable_ChangeList; // list of table changes - mork_u2 mTable_ChangesCount; // length of changes list - mork_u2 mTable_ChangesMax; // max list length before rewrite - - // mork_tid mTable_Id; - mork_kind mTable_Kind; - - mork_u1 mTable_Flags; // bit flags - mork_priority mTable_Priority; // 0..9, any other value equals 9 - mork_u1 mTable_GcUses; // persistent references from cells - mork_u1 mTable_Pad; // for u4 alignment - -public: // flags bit twiddling - - void SetTableUnique() { mTable_Flags |= morkTable_kUniqueBit; } - void SetTableVerbose() { mTable_Flags |= morkTable_kVerboseBit; } - void SetTableNoted() { mTable_Flags |= morkTable_kNotedBit; } - void SetTableRewrite() { mTable_Flags |= morkTable_kRewriteBit; } - void SetTableNewMeta() { mTable_Flags |= morkTable_kNewMetaBit; } - - void ClearTableUnique() { mTable_Flags &= (mork_u1) ~morkTable_kUniqueBit; } - void ClearTableVerbose() { mTable_Flags &= (mork_u1) ~morkTable_kVerboseBit; } - void ClearTableNoted() { mTable_Flags &= (mork_u1) ~morkTable_kNotedBit; } - void ClearTableRewrite() { mTable_Flags &= (mork_u1) ~morkTable_kRewriteBit; } - void ClearTableNewMeta() { mTable_Flags &= (mork_u1) ~morkTable_kNewMetaBit; } - - mork_bool IsTableUnique() const - { return ( mTable_Flags & morkTable_kUniqueBit ) != 0; } - - mork_bool IsTableVerbose() const - { return ( mTable_Flags & morkTable_kVerboseBit ) != 0; } - - mork_bool IsTableNoted() const - { return ( mTable_Flags & morkTable_kNotedBit ) != 0; } - - mork_bool IsTableRewrite() const - { return ( mTable_Flags & morkTable_kRewriteBit ) != 0; } - - mork_bool IsTableNewMeta() const - { return ( mTable_Flags & morkTable_kNewMetaBit ) != 0; } - -public: // table dirty handling more complex than morkNode::SetNodeDirty() etc. - - void SetTableDirty() { this->SetNodeDirty(); } - void SetTableClean(morkEnv* ev); - - mork_bool IsTableClean() const { return this->IsNodeClean(); } - mork_bool IsTableDirty() const { return this->IsNodeDirty(); } - -public: // morkNode memory management operators - void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev) CPP_THROW_NEW - { return morkNode::MakeNew(inSize, ioHeap, ev); } - - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseTable() if open - virtual ~morkTable(); // assert that close executed earlier - -public: // morkTable construction & destruction - morkTable(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, morkStore* ioStore, - nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace, - const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying - mork_tid inTableId, - mork_kind inKind, mork_bool inMustBeUnique); - void CloseTable(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkTable(const morkTable& other); - morkTable& operator=(const morkTable& other); - -public: // dynamic type identification - mork_bool IsTable() const - { return IsNode() && mNode_Derived == morkDerived_kTable; } -// } ===== end morkNode methods ===== - -public: // errors - static void NonTableTypeError(morkEnv* ev); - static void NonTableTypeWarning(morkEnv* ev); - static void NilRowSpaceError(morkEnv* ev); - -public: // warnings - static void TableGcUsesUnderflowWarning(morkEnv* ev); - -public: // noting table changes - - mork_bool HasChangeOverflow() const - { return mTable_ChangesCount >= mTable_ChangesMax; } - - void NoteTableSetAll(morkEnv* ev); - void NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos); - - void note_row_change(morkEnv* ev, mork_change inChange, morkRow* ioRow); - void note_row_move(morkEnv* ev, morkRow* ioRow, mork_pos inNewPos); - - void NoteTableAddRow(morkEnv* ev, morkRow* ioRow) - { this->note_row_change(ev, morkChange_kAdd, ioRow); } - - void NoteTableCutRow(morkEnv* ev, morkRow* ioRow) - { this->note_row_change(ev, morkChange_kCut, ioRow); } - -protected: // internal row map methods - - morkRow* find_member_row(morkEnv* ev, morkRow* ioRow); - void build_row_map(morkEnv* ev); - -public: // other table methods - - mork_bool MaybeDirtySpaceStoreAndTable(); - - morkRow* GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid); - - mork_u2 AddTableGcUse(morkEnv* ev); - mork_u2 CutTableGcUse(morkEnv* ev); - - // void DirtyAllTableContent(morkEnv* ev); - - mork_seed TableSeed() const { return mTable_RowArray.mArray_Seed; } - - morkRow* SafeRowAt(morkEnv* ev, mork_pos inPos) - { return (morkRow*) mTable_RowArray.SafeAt(ev, inPos); } - - nsIMdbTable* AcquireTableHandle(morkEnv* ev); // mObject_Handle - - mork_count GetRowCount() const { return mTable_RowArray.mArray_Fill; } - - mork_bool IsTableUsed() const - { return (mTable_GcUses != 0 || this->GetRowCount() != 0); } - - void GetTableOid(morkEnv* ev, mdbOid* outOid); - mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid); - mork_bool MapHasOid(morkEnv* ev, const mdbOid* inOid); - mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good() - mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good() - mork_bool CutAllRows(morkEnv* ev); // returns ev->Good() - - mork_pos MoveRow(morkEnv* ev, morkRow* ioRow, // change row position - mork_pos inHintFromPos, // suggested hint regarding start position - mork_pos inToPos); // desired new position for row ioRow - // MoveRow() returns the actual position of ioRow afterwards; this - // position is -1 if and only if ioRow was not found as a member. - - - morkTableRowCursor* NewTableRowCursor(morkEnv* ev, mork_pos inRowPos); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakTable(morkTable* me, - morkEnv* ev, morkTable** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongTable(morkTable* me, - morkEnv* ev, morkTable** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// use negative values for kCut and kAdd, to keep non-neg move pos distinct: -#define morkTableChange_kCut ((mork_pos) -1) /* shows row was cut */ -#define morkTableChange_kAdd ((mork_pos) -2) /* shows row was added */ -#define morkTableChange_kNone ((mork_pos) -3) /* unknown change */ - -class morkTableChange : public morkNext { -public: // state is public because the entire Mork system is private - - morkRow* mTableChange_Row; // the row in the change - - mork_pos mTableChange_Pos; // kAdd, kCut, or non-neg for row move - -public: - morkTableChange(morkEnv* ev, mork_change inChange, morkRow* ioRow); - // use this constructor for inChange == morkChange_kAdd or morkChange_kCut - - morkTableChange(morkEnv* ev, morkRow* ioRow, mork_pos inPos); - // use this constructor when the row is moved - -public: - void UnknownChangeError(morkEnv* ev) const; // morkChange_kAdd or morkChange_kCut - void NegativeMovePosError(morkEnv* ev) const; // move must be non-neg position - -public: - - mork_bool IsAddRowTableChange() const - { return ( mTableChange_Pos == morkTableChange_kAdd ); } - - mork_bool IsCutRowTableChange() const - { return ( mTableChange_Pos == morkTableChange_kCut ); } - - mork_bool IsMoveRowTableChange() const - { return ( mTableChange_Pos >= 0 ); } - -public: - - mork_pos GetMovePos() const { return mTableChange_Pos; } - // GetMovePos() assumes that IsMoveRowTableChange() is true. -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkDerived_kTableMap /*i*/ 0x744D /* ascii 'tM' */ - -/*| morkTableMap: maps mork_token -> morkTable -|*/ -#ifdef MORK_BEAD_OVER_NODE_MAPS -class morkTableMap : public morkBeadMap { -#else /*MORK_BEAD_OVER_NODE_MAPS*/ -class morkTableMap : public morkNodeMap { // for mapping tokens to tables -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - -public: - - virtual ~morkTableMap(); - morkTableMap(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap); - -public: // other map methods - -#ifdef MORK_BEAD_OVER_NODE_MAPS - mork_bool AddTable(morkEnv* ev, morkTable* ioTable) - { return this->AddBead(ev, ioTable); } - // the AddTable() boolean return equals ev->Good(). - - mork_bool CutTable(morkEnv* ev, mork_tid inTid) - { return this->CutBead(ev, inTid); } - // The CutTable() boolean return indicates whether removal happened. - - morkTable* GetTable(morkEnv* ev, mork_tid inTid) - { return (morkTable*) this->GetBead(ev, inTid); } - // Note the returned table does NOT have an increase in refcount for this. - - mork_num CutAllTables(morkEnv* ev) - { return this->CutAllBeads(ev); } - // CutAllTables() releases all the referenced table values. - -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - mork_bool AddTable(morkEnv* ev, morkTable* ioTable) - { return this->AddNode(ev, ioTable->TableId(), ioTable); } - // the AddTable() boolean return equals ev->Good(). - - mork_bool CutTable(morkEnv* ev, mork_tid inTid) - { return this->CutNode(ev, inTid); } - // The CutTable() boolean return indicates whether removal happened. - - morkTable* GetTable(morkEnv* ev, mork_tid inTid) - { return (morkTable*) this->GetNode(ev, inTid); } - // Note the returned table does NOT have an increase in refcount for this. - - mork_num CutAllTables(morkEnv* ev) - { return this->CutAllNodes(ev); } - // CutAllTables() releases all the referenced table values. -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - -}; - -#ifdef MORK_BEAD_OVER_NODE_MAPS -class morkTableMapIter: public morkBeadMapIter { -#else /*MORK_BEAD_OVER_NODE_MAPS*/ -class morkTableMapIter: public morkMapIter{ // typesafe wrapper class -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - -public: - -#ifdef MORK_BEAD_OVER_NODE_MAPS - morkTableMapIter(morkEnv* ev, morkTableMap* ioMap) - : morkBeadMapIter(ev, ioMap) { } - - morkTableMapIter( ) : morkBeadMapIter() { } - void InitTableMapIter(morkEnv* ev, morkTableMap* ioMap) - { this->InitBeadMapIter(ev, ioMap); } - - morkTable* FirstTable(morkEnv* ev) - { return (morkTable*) this->FirstBead(ev); } - - morkTable* NextTable(morkEnv* ev) - { return (morkTable*) this->NextBead(ev); } - - morkTable* HereTable(morkEnv* ev) - { return (morkTable*) this->HereBead(ev); } - - -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - morkTableMapIter(morkEnv* ev, morkTableMap* ioMap) - : morkMapIter(ev, ioMap) { } - - morkTableMapIter( ) : morkMapIter() { } - void InitTableMapIter(morkEnv* ev, morkTableMap* ioMap) - { this->InitMapIter(ev, ioMap); } - - mork_change* - FirstTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable) - { return this->First(ev, outTid, outTable); } - - mork_change* - NextTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable) - { return this->Next(ev, outTid, outTable); } - - mork_change* - HereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable) - { return this->Here(ev, outTid, outTable); } - - // cutting while iterating hash map might dirty the parent table: - mork_change* - CutHereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable) - { return this->CutHere(ev, outTid, outTable); } -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKTABLE_ */ - diff --git a/db/mork/src/morkTableRowCursor.cpp b/db/mork/src/morkTableRowCursor.cpp deleted file mode 100644 index ab8c2ae2bb06..000000000000 --- a/db/mork/src/morkTableRowCursor.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Blake Ross (blake@blakeross.com) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKTABLEROWCURSOR_ -#include "morkTableRowCursor.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkTableRowCursor::CloseMorkNode(morkEnv* ev) // CloseTableRowCursor() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseTableRowCursor(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkTableRowCursor::~morkTableRowCursor() // CloseTableRowCursor() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(this->IsShutNode()); -} - -/*public non-poly*/ -morkTableRowCursor::morkTableRowCursor(morkEnv* ev, - const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos) -: morkCursor(ev, inUsage, ioHeap) -, mTableRowCursor_Table( 0 ) -{ - if ( ev->Good() ) - { - if ( ioTable ) - { - mCursor_Pos = inRowPos; - mCursor_Seed = ioTable->TableSeed(); - morkTable::SlotWeakTable(ioTable, ev, &mTableRowCursor_Table); - if ( ev->Good() ) - mNode_Derived = morkDerived_kTableRowCursor; - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkTableRowCursor, morkCursor, nsIMdbTableRowCursor) -/*public non-poly*/ void -morkTableRowCursor::CloseTableRowCursor(morkEnv* ev) -{ - if ( this ) - { - if ( this->IsNode() ) - { - mCursor_Pos = -1; - mCursor_Seed = 0; - morkTable::SlotWeakTable((morkTable*) 0, ev, &mTableRowCursor_Table); - this->CloseCursor(ev); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` -// { ----- begin attribute methods ----- -/*virtual*/ mdb_err -morkTableRowCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount) -{ - mdb_err outErr = 0; - mdb_count count = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - count = GetMemberCount(ev); - outErr = ev->AsErr(); - } - if ( outCount ) - *outCount = count; - return outErr; -} - -/*virtual*/ mdb_err -morkTableRowCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed) -{ - NS_ASSERTION(PR_FALSE, "not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -/*virtual*/ mdb_err -morkTableRowCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos) -{ - mCursor_Pos = inPos; - return NS_OK; -} - -/*virtual*/ mdb_err -morkTableRowCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos) -{ - *outPos = mCursor_Pos; - return NS_OK; -} - -/*virtual*/ mdb_err -morkTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail) -{ - mCursor_DoFailOnSeedOutOfSync = inFail; - return NS_OK; -} - -/*virtual*/ mdb_err -morkTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail) -{ - NS_ENSURE_ARG_POINTER(outFail); - *outFail = mCursor_DoFailOnSeedOutOfSync; - return NS_OK; -} -// } ----- end attribute methods ----- - - -// { ===== begin nsIMdbTableRowCursor methods ===== - -// { ----- begin attribute methods ----- - -NS_IMETHODIMP -morkTableRowCursor::GetTable(nsIMdbEnv* mev, nsIMdbTable** acqTable) -{ - mdb_err outErr = 0; - nsIMdbTable* outTable = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( mTableRowCursor_Table ) - outTable = mTableRowCursor_Table->AcquireTableHandle(ev); - - outErr = ev->AsErr(); - } - if ( acqTable ) - *acqTable = outTable; - return outErr; -} -// } ----- end attribute methods ----- - -// { ----- begin oid iteration methods ----- -NS_IMETHODIMP -morkTableRowCursor::NextRowOid( // get row id of next row in the table - nsIMdbEnv* mev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos) -{ - mdb_err outErr = 0; - mork_pos pos = -1; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( outOid ) - { - pos = NextRowOid(ev, outOid); - } - else - ev->NilPointerError(); - outErr = ev->AsErr(); - } - if ( outRowPos ) - *outRowPos = pos; - return outErr; -} - -NS_IMETHODIMP -morkTableRowCursor::PrevRowOid( // get row id of previous row in the table - nsIMdbEnv* mev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos) -{ - mdb_err outErr = 0; - mork_pos pos = -1; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - if ( outOid ) - { - pos = PrevRowOid(ev, outOid); - } - else - ev->NilPointerError(); - outErr = ev->AsErr(); - } - if ( outRowPos ) - *outRowPos = pos; - return outErr; -} -// } ----- end oid iteration methods ----- - -// { ----- begin row iteration methods ----- -NS_IMETHODIMP -morkTableRowCursor::NextRow( // get row cells from table for cells already in row - nsIMdbEnv* mev, // context - nsIMdbRow** acqRow, // acquire next row in table - mdb_pos* outRowPos) -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - - mdbOid oid; // place to put oid we intend to ignore - morkRow* row = NextRow(ev, &oid, outRowPos); - if ( row ) - { - morkStore* store = row->GetRowSpaceStore(ev); - if ( store ) - outRow = row->AcquireRowHandle(ev, store); - } - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -NS_IMETHODIMP -morkTableRowCursor::PrevRow( // get row cells from table for cells already in row - nsIMdbEnv* mev, // context - nsIMdbRow** acqRow, // acquire previous row in table - mdb_pos* outRowPos) -{ - mdb_err outErr = 0; - nsIMdbRow* outRow = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - - mdbOid oid; // place to put oid we intend to ignore - morkRow* row = PrevRow(ev, &oid, outRowPos); - if ( row ) - { - morkStore* store = row->GetRowSpaceStore(ev); - if ( store ) - outRow = row->AcquireRowHandle(ev, store); - } - outErr = ev->AsErr(); - } - if ( acqRow ) - *acqRow = outRow; - return outErr; -} - -// } ----- end row iteration methods ----- - - -// { ----- begin duplicate row removal methods ----- -NS_IMETHODIMP -morkTableRowCursor::CanHaveDupRowMembers(nsIMdbEnv* mev, // cursor might hold dups? - mdb_bool* outCanHaveDups) -{ - mdb_err outErr = 0; - mdb_bool canHaveDups = mdbBool_kFalse; - - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - canHaveDups = CanHaveDupRowMembers(ev); - outErr = ev->AsErr(); - } - if ( outCanHaveDups ) - *outCanHaveDups = canHaveDups; - return outErr; -} - -NS_IMETHODIMP -morkTableRowCursor::MakeUniqueCursor( // clone cursor, removing duplicate rows - nsIMdbEnv* mev, // context - nsIMdbTableRowCursor** acqCursor) // acquire clone with no dups - // Note that MakeUniqueCursor() is never necessary for a cursor which was - // created by table method nsIMdbTable::GetTableRowCursor(), because a table - // never contains the same row as a member more than once. However, a cursor - // created by table method nsIMdbTable::FindRowMatches() might contain the - // same row more than once, because the same row can generate a hit by more - // than one column with a matching string prefix. Note this method can - // return the very same cursor instance with just an incremented refcount, - // when the original cursor could not contain any duplicate rows (calling - // CanHaveDupRowMembers() shows this case on a false return). Otherwise - // this method returns a different cursor instance. Callers should not use - // this MakeUniqueCursor() method lightly, because it tends to defeat the - // purpose of lazy programming techniques, since it can force creation of - // an explicit row collection in a new cursor's representation, in order to - // inspect the row membership and remove any duplicates; this can have big - // impact if a collection holds tens of thousands of rows or more, when - // the original cursor with dups simply referenced rows indirectly by row - // position ranges, without using an explicit row set representation. - // Callers are encouraged to use nsIMdbCursor::GetCount() to determine - // whether the row collection is very large (tens of thousands), and to - // delay calling MakeUniqueCursor() when possible, until a user interface - // element actually demands the creation of an explicit set representation. -{ - mdb_err outErr = 0; - nsIMdbTableRowCursor* outCursor = 0; - - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - AddRef(); - outCursor = this; - - outErr = ev->AsErr(); - } - if ( acqCursor ) - *acqCursor = outCursor; - return outErr; -} -// } ----- end duplicate row removal methods ----- - -// } ===== end nsIMdbTableRowCursor methods ===== - - -/*static*/ void -morkTableRowCursor::NonTableRowCursorTypeError(morkEnv* ev) -{ - ev->NewError("non morkTableRowCursor"); -} - - -mdb_pos -morkTableRowCursor::NextRowOid(morkEnv* ev, mdbOid* outOid) -{ - mdb_pos outPos = -1; - (void) this->NextRow(ev, outOid, &outPos); - return outPos; -} - -mdb_pos -morkTableRowCursor::PrevRowOid(morkEnv* ev, mdbOid* outOid) -{ - mdb_pos outPos = -1; - (void) this->PrevRow(ev, outOid, &outPos); - return outPos; -} - -mork_bool -morkTableRowCursor::CanHaveDupRowMembers(morkEnv* ev) -{ - return morkBool_kFalse; // false default is correct -} - -mork_count -morkTableRowCursor::GetMemberCount(morkEnv* ev) -{ - morkTable* table = mTableRowCursor_Table; - if ( table ) - return table->mTable_RowArray.mArray_Fill; - else - return 0; -} - -morkRow* -morkTableRowCursor::PrevRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos) -{ - morkRow* outRow = 0; - mork_pos pos = -1; - - morkTable* table = mTableRowCursor_Table; - if ( table ) - { - if ( table->IsOpenNode() ) - { - morkArray* array = &table->mTable_RowArray; - pos = mCursor_Pos - 1; - - if ( pos >= 0 && pos < (mork_pos)(array->mArray_Fill) ) - { - mCursor_Pos = pos; // update for next time - morkRow* row = (morkRow*) array->At(pos); - if ( row ) - { - if ( row->IsRow() ) - { - outRow = row; - *outOid = row->mRow_Oid; - } - else - row->NonRowTypeError(ev); - } - else - ev->NilPointerError(); - } - else - { - outOid->mOid_Scope = 0; - outOid->mOid_Id = morkId_kMinusOne; - } - } - else - table->NonOpenNodeError(ev); - } - else - ev->NilPointerError(); - - *outPos = pos; - return outRow; -} - -morkRow* -morkTableRowCursor::NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos) -{ - morkRow* outRow = 0; - mork_pos pos = -1; - - morkTable* table = mTableRowCursor_Table; - if ( table ) - { - if ( table->IsOpenNode() ) - { - morkArray* array = &table->mTable_RowArray; - pos = mCursor_Pos; - if ( pos < 0 ) - pos = 0; - else - ++pos; - - if ( pos < (mork_pos)(array->mArray_Fill) ) - { - mCursor_Pos = pos; // update for next time - morkRow* row = (morkRow*) array->At(pos); - if ( row ) - { - if ( row->IsRow() ) - { - outRow = row; - *outOid = row->mRow_Oid; - } - else - row->NonRowTypeError(ev); - } - else - ev->NilPointerError(); - } - else - { - outOid->mOid_Scope = 0; - outOid->mOid_Id = morkId_kMinusOne; - } - } - else - table->NonOpenNodeError(ev); - } - else - ev->NilPointerError(); - - *outPos = pos; - return outRow; -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkTableRowCursor.h b/db/mork/src/morkTableRowCursor.h deleted file mode 100644 index 3a6189d2bbcc..000000000000 --- a/db/mork/src/morkTableRowCursor.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Blake Ross (blake@blakeross.com) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKTABLEROWCURSOR_ -#define _MORKTABLEROWCURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class orkinTableRowCursor; -#define morkDerived_kTableRowCursor /*i*/ 0x7243 /* ascii 'rC' */ - -class morkTableRowCursor : public morkCursor, public nsIMdbTableRowCursor { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkFactory* mObject_Factory; // weak ref to suite factory - - // mork_seed mCursor_Seed; - // mork_pos mCursor_Pos; - // mork_bool mCursor_DoFailOnSeedOutOfSync; - // mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - -public: // state is public because the entire Mork system is private - morkTable* mTableRowCursor_Table; // weak ref to table - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseTableRowCursor() - virtual ~morkTableRowCursor(); // assert that close executed earlier - -public: // morkTableRowCursor construction & destruction - morkTableRowCursor(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos); - void CloseTableRowCursor(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkTableRowCursor(const morkTableRowCursor& other); - morkTableRowCursor& operator=(const morkTableRowCursor& other); - -public: - NS_DECL_ISUPPORTS_INHERITED - - // { ----- begin attribute methods ----- - NS_IMETHOD GetCount(nsIMdbEnv* ev, mdb_count* outCount); // readonly - NS_IMETHOD GetSeed(nsIMdbEnv* ev, mdb_seed* outSeed); // readonly - - NS_IMETHOD SetPos(nsIMdbEnv* ev, mdb_pos inPos); // mutable - NS_IMETHOD GetPos(nsIMdbEnv* ev, mdb_pos* outPos); - - NS_IMETHOD SetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool inFail); - NS_IMETHOD GetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool* outFail); - - // } ----- end attribute methods ----- - NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable); - // } ----- end attribute methods ----- - - // { ----- begin duplicate row removal methods ----- - NS_IMETHOD CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups? - mdb_bool* outCanHaveDups); - - NS_IMETHOD MakeUniqueCursor( // clone cursor, removing duplicate rows - nsIMdbEnv* ev, // context - nsIMdbTableRowCursor** acqCursor); // acquire clone with no dups - // } ----- end duplicate row removal methods ----- - - // { ----- begin oid iteration methods ----- - NS_IMETHOD NextRowOid( // get row id of next row in the table - nsIMdbEnv* ev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos); // zero-based position of the row in table - NS_IMETHOD PrevRowOid( // get row id of previous row in the table - nsIMdbEnv* ev, // context - mdbOid* outOid, // out row oid - mdb_pos* outRowPos); // zero-based position of the row in table - // } ----- end oid iteration methods ----- - - // { ----- begin row iteration methods ----- - NS_IMETHOD NextRow( // get row cells from table for cells already in row - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // acquire next row in table - mdb_pos* outRowPos); // zero-based position of the row in table - NS_IMETHOD PrevRow( // get row cells from table for cells already in row - nsIMdbEnv* ev, // context - nsIMdbRow** acqRow, // acquire previous row in table - mdb_pos* outRowPos); // zero-based position of the row in table - // } ----- end row iteration methods ----- - - -public: // dynamic type identification - mork_bool IsTableRowCursor() const - { return IsNode() && mNode_Derived == morkDerived_kTableRowCursor; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonTableRowCursorTypeError(morkEnv* ev); - -public: // oid only iteration - mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid); - mdb_pos PrevRowOid(morkEnv* ev, mdbOid* outOid); - -public: // other table row cursor methods - - virtual mork_bool CanHaveDupRowMembers(morkEnv* ev); - virtual mork_count GetMemberCount(morkEnv* ev); - - virtual morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos); - virtual morkRow* PrevRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakTableRowCursor(morkTableRowCursor* me, - morkEnv* ev, morkTableRowCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongTableRowCursor(morkTableRowCursor* me, - morkEnv* ev, morkTableRowCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKTABLEROWCURSOR_ */ diff --git a/db/mork/src/morkThumb.cpp b/db/mork/src/morkThumb.cpp deleted file mode 100644 index ff79bd044e06..000000000000 --- a/db/mork/src/morkThumb.cpp +++ /dev/null @@ -1,560 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKTHUMB_ -#include "morkThumb.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -// #ifndef _MORKFILE_ -// #include "morkFile.h" -// #endif - -#ifndef _MORKWRITER_ -#include "morkWriter.h" -#endif - -#ifndef _MORKPARSER_ -#include "morkParser.h" -#endif - -#ifndef _MORKBUILDER_ -#include "morkBuilder.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkThumb::CloseMorkNode(morkEnv* ev) // CloseThumb() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseThumb(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkThumb::~morkThumb() // assert CloseThumb() executed earlier -{ - CloseMorkNode(mMorkEnv); - MORK_ASSERT(mThumb_Magic==0); - MORK_ASSERT(mThumb_Store==0); - MORK_ASSERT(mThumb_File==0); -} - -/*public non-poly*/ -morkThumb::morkThumb(morkEnv* ev, - const morkUsage& inUsage, nsIMdbHeap* ioHeap, - nsIMdbHeap* ioSlotHeap, mork_magic inMagic) -: morkObject(ev, inUsage, ioHeap, morkColor_kNone, (morkHandle*) 0) -, mThumb_Magic( 0 ) -, mThumb_Total( 0 ) -, mThumb_Current( 0 ) - -, mThumb_Done( morkBool_kFalse ) -, mThumb_Broken( morkBool_kFalse ) -, mThumb_Seed( 0 ) - -, mThumb_Store( 0 ) -, mThumb_File( 0 ) -, mThumb_Writer( 0 ) -, mThumb_Builder( 0 ) -, mThumb_SourcePort( 0 ) - -, mThumb_DoCollect( morkBool_kFalse ) -{ - if ( ev->Good() ) - { - if ( ioSlotHeap ) - { - mThumb_Magic = inMagic; - mNode_Derived = morkDerived_kThumb; - } - else - ev->NilPointerError(); - } -} - -NS_IMPL_ISUPPORTS_INHERITED1(morkThumb, morkObject, nsIMdbThumb) - -/*public non-poly*/ void -morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - mThumb_Magic = 0; - if ( mThumb_Builder && mThumb_Store ) - mThumb_Store->ForgetBuilder(ev); - morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mThumb_Builder); - - morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer); - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mThumb_File); - morkStore::SlotStrongStore((morkStore*) 0, ev, &mThumb_Store); - morkStore::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -// { ===== begin nsIMdbThumb methods ===== -NS_IMETHODIMP -morkThumb::GetProgress(nsIMdbEnv* mev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - GetProgress(ev, outTotal, outCurrent, outDone, outBroken); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkThumb::DoMore(nsIMdbEnv* mev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - DoMore(ev, outTotal, outCurrent, outDone, outBroken); - outErr = ev->AsErr(); - } - return outErr; -} - -NS_IMETHODIMP -morkThumb::CancelAndBreakThumb(nsIMdbEnv* mev) -{ - mdb_err outErr = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - mThumb_Done = morkBool_kTrue; - mThumb_Broken = morkBool_kTrue; - CloseMorkNode(ev); // should I close this here? - outErr = ev->AsErr(); - } - return outErr; -} -// } ===== end nsIMdbThumb methods ===== - -/*static*/ void morkThumb::NonThumbTypeError(morkEnv* ev) -{ - ev->NewError("non morkThumb"); -} - -/*static*/ void morkThumb::UnsupportedThumbMagicError(morkEnv* ev) -{ - ev->NewError("unsupported mThumb_Magic"); -} - -/*static*/ void morkThumb::NilThumbStoreError(morkEnv* ev) -{ - ev->NewError("nil mThumb_Store"); -} - -/*static*/ void morkThumb::NilThumbFileError(morkEnv* ev) -{ - ev->NewError("nil mThumb_File"); -} - -/*static*/ void morkThumb::NilThumbWriterError(morkEnv* ev) -{ - ev->NewError("nil mThumb_Writer"); -} - -/*static*/ void morkThumb::NilThumbBuilderError(morkEnv* ev) -{ - ev->NewError("nil mThumb_Builder"); -} - -/*static*/ void morkThumb::NilThumbSourcePortError(morkEnv* ev) -{ - ev->NewError("nil mThumb_SourcePort"); -} - -/*static*/ morkThumb* -morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap, - morkStore* ioStore) -{ - morkThumb* outThumb = 0; - if ( ioHeap && ioStore ) - { - nsIMdbFile* file = ioStore->mStore_File; - if ( file ) - { - mork_pos fileEof = 0; - file->Eof(ev->AsMdbEnv(), &fileEof); - if ( ev->Good() ) - { - outThumb = new(*ioHeap, ev) - morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap, - morkThumb_kMagic_OpenFileStore); - - if ( outThumb ) - { - morkBuilder* builder = ioStore->LazyGetBuilder(ev); - if ( builder ) - { - outThumb->mThumb_Total = (mork_count) fileEof; - morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store); - morkBuilder::SlotStrongBuilder(builder, ev, - &outThumb->mThumb_Builder); - } - } - } - } - else - ioStore->NilStoreFileError(ev); - } - else - ev->NilPointerError(); - - return outThumb; -} - - -/*static*/ morkThumb* -morkThumb::Make_LargeCommit(morkEnv* ev, - nsIMdbHeap* ioHeap, morkStore* ioStore) -{ - morkThumb* outThumb = 0; - if ( ioHeap && ioStore ) - { - nsIMdbFile* file = ioStore->mStore_File; - if ( file ) - { - outThumb = new(*ioHeap, ev) - morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap, - morkThumb_kMagic_LargeCommit); - - if ( outThumb ) - { - morkWriter* writer = new(*ioHeap, ev) - morkWriter(ev, morkUsage::kHeap, ioHeap, ioStore, file, ioHeap); - if ( writer ) - { - writer->mWriter_CommitGroupIdentity = - ++ioStore->mStore_CommitGroupIdentity; - writer->mWriter_NeedDirtyAll = morkBool_kFalse; - outThumb->mThumb_DoCollect = morkBool_kFalse; - morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store); - - nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File); - - outThumb->mThumb_Writer = writer; // pass writer ownership to thumb - } - } - } - else - ioStore->NilStoreFileError(ev); - } - else - ev->NilPointerError(); - - return outThumb; -} - -/*static*/ morkThumb* -morkThumb::Make_CompressCommit(morkEnv* ev, - nsIMdbHeap* ioHeap, morkStore* ioStore, mork_bool inDoCollect) -{ - morkThumb* outThumb = 0; - if ( ioHeap && ioStore ) - { - nsIMdbFile* file = ioStore->mStore_File; - if ( file ) - { - outThumb = new(*ioHeap, ev) - morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap, - morkThumb_kMagic_CompressCommit); - - if ( outThumb ) - { - morkWriter* writer = new(*ioHeap, ev) - morkWriter(ev, morkUsage::kHeap, ioHeap, ioStore, file, ioHeap); - if ( writer ) - { - writer->mWriter_NeedDirtyAll = morkBool_kTrue; - outThumb->mThumb_DoCollect = inDoCollect; - morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store); - nsIMdbFile_SlotStrongFile(file, ev, &outThumb->mThumb_File); - outThumb->mThumb_Writer = writer; // pass writer ownership to thumb - - // cope with fact that parsed transaction groups are going away: - ioStore->mStore_FirstCommitGroupPos = 0; - ioStore->mStore_SecondCommitGroupPos = 0; - } - } - } - else - ioStore->NilStoreFileError(ev); - } - else - ev->NilPointerError(); - - return outThumb; -} - -// { ===== begin non-poly methods imitating nsIMdbThumb ===== -void morkThumb::GetProgress(morkEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken) -{ - MORK_USED_1(ev); - if ( outTotal ) - *outTotal = mThumb_Total; - if ( outCurrent ) - *outCurrent = mThumb_Current; - if ( outDone ) - *outDone = mThumb_Done; - if ( outBroken ) - *outBroken = mThumb_Broken; -} - -void morkThumb::DoMore(morkEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken) -{ - if ( !mThumb_Done && !mThumb_Broken ) - { - switch ( mThumb_Magic ) - { - case morkThumb_kMagic_OpenFilePort: // 1 /* factory method */ - this->DoMore_OpenFilePort(ev); break; - - case morkThumb_kMagic_OpenFileStore: // 2 /* factory method */ - this->DoMore_OpenFileStore(ev); break; - - case morkThumb_kMagic_ExportToFormat: // 3 /* port method */ - this->DoMore_ExportToFormat(ev); break; - - case morkThumb_kMagic_ImportContent: // 4 /* store method */ - this->DoMore_ImportContent(ev); break; - - case morkThumb_kMagic_LargeCommit: // 5 /* store method */ - this->DoMore_LargeCommit(ev); break; - - case morkThumb_kMagic_SessionCommit: // 6 /* store method */ - this->DoMore_SessionCommit(ev); break; - - case morkThumb_kMagic_CompressCommit: // 7 /* store method */ - this->DoMore_CompressCommit(ev); break; - - case morkThumb_kMagic_SearchManyColumns: // 8 /* table method */ - this->DoMore_SearchManyColumns(ev); break; - - case morkThumb_kMagic_NewSortColumn: // 9 /* table metho) */ - this->DoMore_NewSortColumn(ev); break; - - case morkThumb_kMagic_NewSortColumnWithCompare: // 10 /* table method */ - this->DoMore_NewSortColumnWithCompare(ev); break; - - case morkThumb_kMagic_CloneSortColumn: // 11 /* table method */ - this->DoMore_CloneSortColumn(ev); break; - - case morkThumb_kMagic_AddIndex: // 12 /* table method */ - this->DoMore_AddIndex(ev); break; - - case morkThumb_kMagic_CutIndex: // 13 /* table method */ - this->DoMore_CutIndex(ev); break; - - default: - this->UnsupportedThumbMagicError(ev); - break; - } - } - if ( outTotal ) - *outTotal = mThumb_Total; - if ( outCurrent ) - *outCurrent = mThumb_Current; - if ( outDone ) - *outDone = mThumb_Done; - if ( outBroken ) - *outBroken = mThumb_Broken; -} - -void morkThumb::CancelAndBreakThumb(morkEnv* ev) -{ - MORK_USED_1(ev); - mThumb_Broken = morkBool_kTrue; -} - -// } ===== end non-poly methods imitating nsIMdbThumb ===== - -morkStore* -morkThumb::ThumbToOpenStore(morkEnv* ev) -// for orkinFactory::ThumbToOpenStore() after OpenFileStore() -{ - MORK_USED_1(ev); - return mThumb_Store; -} - -void morkThumb::DoMore_OpenFilePort(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_OpenFileStore(morkEnv* ev) -{ - morkBuilder* builder = mThumb_Builder; - if ( builder ) - { - mork_pos pos = 0; - builder->ParseMore(ev, &pos, &mThumb_Done, &mThumb_Broken); - // mThumb_Total = builder->mBuilder_TotalCount; - // mThumb_Current = builder->mBuilder_DoneCount; - mThumb_Current = (mork_count) pos; - } - else - { - this->NilThumbBuilderError(ev); - mThumb_Broken = morkBool_kTrue; - mThumb_Done = morkBool_kTrue; - } -} - -void morkThumb::DoMore_ExportToFormat(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_ImportContent(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_LargeCommit(morkEnv* ev) -{ - this->DoMore_Commit(ev); -} - -void morkThumb::DoMore_SessionCommit(morkEnv* ev) -{ - this->DoMore_Commit(ev); -} - -void morkThumb::DoMore_Commit(morkEnv* ev) -{ - morkWriter* writer = mThumb_Writer; - if ( writer ) - { - writer->WriteMore(ev); - mThumb_Total = writer->mWriter_TotalCount; - mThumb_Current = writer->mWriter_DoneCount; - mThumb_Done = ( ev->Bad() || writer->IsWritingDone() ); - mThumb_Broken = ev->Bad(); - } - else - { - this->NilThumbWriterError(ev); - mThumb_Broken = morkBool_kTrue; - mThumb_Done = morkBool_kTrue; - } -} - -void morkThumb::DoMore_CompressCommit(morkEnv* ev) -{ - this->DoMore_Commit(ev); -} - -void morkThumb::DoMore_SearchManyColumns(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_NewSortColumn(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_NewSortColumnWithCompare(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_CloneSortColumn(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_AddIndex(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - -void morkThumb::DoMore_CutIndex(morkEnv* ev) -{ - this->UnsupportedThumbMagicError(ev); -} - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkThumb.h b/db/mork/src/morkThumb.h deleted file mode 100644 index 2cb1a6ae0700..000000000000 --- a/db/mork/src/morkThumb.h +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKTHUMB_ -#define _MORKTHUMB_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKOBJECT_ -#include "morkObject.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -#define morkThumb_kMagic_OpenFilePort 1 /* factory method */ -#define morkThumb_kMagic_OpenFileStore 2 /* factory method */ -#define morkThumb_kMagic_ExportToFormat 3 /* port method */ -#define morkThumb_kMagic_ImportContent 4 /* store method */ -#define morkThumb_kMagic_LargeCommit 5 /* store method */ -#define morkThumb_kMagic_SessionCommit 6 /* store method */ -#define morkThumb_kMagic_CompressCommit 7 /* store method */ -#define morkThumb_kMagic_SearchManyColumns 8 /* table method */ -#define morkThumb_kMagic_NewSortColumn 9 /* table metho) */ -#define morkThumb_kMagic_NewSortColumnWithCompare 10 /* table method */ -#define morkThumb_kMagic_CloneSortColumn 11 /* table method */ -#define morkThumb_kMagic_AddIndex 12 /* table method */ -#define morkThumb_kMagic_CutIndex 13 /* table method */ - -#define morkDerived_kThumb /*i*/ 0x5468 /* ascii 'Th' */ - -/*| morkThumb: -|*/ -class morkThumb : public morkObject, public nsIMdbThumb { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // mork_color mBead_Color; // ID for this bead - // morkHandle* mObject_Handle; // weak ref to handle for this object - -public: // state is public because the entire Mork system is private - NS_DECL_ISUPPORTS_INHERITED - -// { ===== begin nsIMdbThumb methods ===== - NS_IMETHOD GetProgress(nsIMdbEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken); - - NS_IMETHOD DoMore(nsIMdbEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken); - - NS_IMETHOD CancelAndBreakThumb(nsIMdbEnv* ev); -// } ===== end nsIMdbThumb methods ===== - - // might as well include all the return values here: - - mork_magic mThumb_Magic; // magic sig different in each thumb type - mork_count mThumb_Total; - mork_count mThumb_Current; - - mork_bool mThumb_Done; - mork_bool mThumb_Broken; - mork_u2 mThumb_Seed; // optional seed for u4 alignment padding - - morkStore* mThumb_Store; // weak ref to created store - nsIMdbFile* mThumb_File; // strong ref to file (store, import, export) - morkWriter* mThumb_Writer; // strong ref to writer (for commit) - morkBuilder* mThumb_Builder; // strong ref to builder (for store open) - morkPort* mThumb_SourcePort; // strong ref to port for import - - mork_bool mThumb_DoCollect; // influence whether a collect happens - mork_bool mThumb_Pad[ 3 ]; // padding for u4 alignment - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseThumb() only if open - virtual ~morkThumb(); // assert that CloseThumb() executed earlier - -public: // morkThumb construction & destruction - morkThumb(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_magic inMagic); - void CloseThumb(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkThumb(const morkThumb& other); - morkThumb& operator=(const morkThumb& other); - -public: // dynamic type identification - mork_bool IsThumb() const - { return IsNode() && mNode_Derived == morkDerived_kThumb; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonThumbTypeError(morkEnv* ev); - static void UnsupportedThumbMagicError(morkEnv* ev); - - static void NilThumbStoreError(morkEnv* ev); - static void NilThumbFileError(morkEnv* ev); - static void NilThumbWriterError(morkEnv* ev); - static void NilThumbBuilderError(morkEnv* ev); - static void NilThumbSourcePortError(morkEnv* ev); - -public: // 'do more' methods - - void DoMore_OpenFilePort(morkEnv* ev); - void DoMore_OpenFileStore(morkEnv* ev); - void DoMore_ExportToFormat(morkEnv* ev); - void DoMore_ImportContent(morkEnv* ev); - void DoMore_LargeCommit(morkEnv* ev); - void DoMore_SessionCommit(morkEnv* ev); - void DoMore_CompressCommit(morkEnv* ev); - void DoMore_Commit(morkEnv* ev); - void DoMore_SearchManyColumns(morkEnv* ev); - void DoMore_NewSortColumn(morkEnv* ev); - void DoMore_NewSortColumnWithCompare(morkEnv* ev); - void DoMore_CloneSortColumn(morkEnv* ev); - void DoMore_AddIndex(morkEnv* ev); - void DoMore_CutIndex(morkEnv* ev); - -public: // other thumb methods - - morkStore* ThumbToOpenStore(morkEnv* ev); - // for orkinFactory::ThumbToOpenStore() after OpenFileStore() - -public: // assorted thumb constructors - - static morkThumb* Make_OpenFileStore(morkEnv* ev, - nsIMdbHeap* ioHeap, morkStore* ioStore); - - static morkThumb* Make_CompressCommit(morkEnv* ev, - nsIMdbHeap* ioHeap, morkStore* ioStore, mork_bool inDoCollect); - - static morkThumb* Make_LargeCommit(morkEnv* ev, - nsIMdbHeap* ioHeap, morkStore* ioStore); - -// { ===== begin non-poly methods imitating nsIMdbThumb ===== - void GetProgress(morkEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken); - - void DoMore(morkEnv* ev, mdb_count* outTotal, - mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken); - - void CancelAndBreakThumb(morkEnv* ev); -// } ===== end non-poly methods imitating nsIMdbThumb ===== - - - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakThumb(morkThumb* me, - morkEnv* ev, morkThumb** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongThumb(morkThumb* me, - morkEnv* ev, morkThumb** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKTHUMB_ */ diff --git a/db/mork/src/morkUniqRowCursor.h b/db/mork/src/morkUniqRowCursor.h deleted file mode 100644 index b4b231e88363..000000000000 --- a/db/mork/src/morkUniqRowCursor.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKUNIQROWCURSOR_ -#define _MORKUNIQROWCURSOR_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKCURSOR_ -#include "morkCursor.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -class orkinTableRowCursor; -// #define morkDerived_kUniqRowCursor /*i*/ 0x7352 /* ascii 'sR' */ - -class morkUniqRowCursor : public morkTableRowCursor { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - - // morkFactory* mObject_Factory; // weak ref to suite factory - - // mork_seed mCursor_Seed; - // mork_pos mCursor_Pos; - // mork_bool mCursor_DoFailOnSeedOutOfSync; - // mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment - - // morkTable* mTableRowCursor_Table; // weak ref to table - -public: // state is public because the entire Mork system is private - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseUniqRowCursor() - virtual ~morkUniqRowCursor(); // assert that close executed earlier - -public: // morkUniqRowCursor construction & destruction - morkUniqRowCursor(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos); - void CloseUniqRowCursor(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkUniqRowCursor(const morkUniqRowCursor& other); - morkUniqRowCursor& operator=(const morkUniqRowCursor& other); - -public: // dynamic type identification - // mork_bool IsUniqRowCursor() const - // { return IsNode() && mNode_Derived == morkDerived_kUniqRowCursor; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonUniqRowCursorTypeError(morkEnv* ev); - -public: // other search row cursor methods - - virtual mork_bool CanHaveDupRowMembers(morkEnv* ev); - virtual mork_count GetMemberCount(morkEnv* ev); - - virtual orkinTableRowCursor* AcquireUniqueRowCursorHandle(morkEnv* ev); - - // virtual mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid); - virtual morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakUniqRowCursor(morkUniqRowCursor* me, - morkEnv* ev, morkUniqRowCursor** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongUniqRowCursor(morkUniqRowCursor* me, - morkEnv* ev, morkUniqRowCursor** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKUNIQROWCURSOR_ */ diff --git a/db/mork/src/morkWriter.cpp b/db/mork/src/morkWriter.cpp deleted file mode 100644 index 2e84d0189b54..000000000000 --- a/db/mork/src/morkWriter.cpp +++ /dev/null @@ -1,2243 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKBLOB_ -#include "morkBlob.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKARRAY_ -#include "morkWriter.h" -#endif - -// #ifndef _MORKFILE_ -// #include "morkFile.h" -// #endif - -#ifndef _MORKSTREAM_ -#include "morkStream.h" -#endif - -#ifndef _MORKSTORE_ -#include "morkStore.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKATOMMAP_ -#include "morkAtomMap.h" -#endif - -#ifndef _MORKROW_ -#include "morkRow.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKCELL_ -#include "morkCell.h" -#endif - -#ifndef _MORKATOM_ -#include "morkAtom.h" -#endif - -#ifndef _MORKCH_ -#include "morkCh.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkWriter::CloseMorkNode(morkEnv* ev) // CloseTable() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseWriter(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkWriter::~morkWriter() // assert CloseTable() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); - MORK_ASSERT(mWriter_Store==0); -} - -/*public non-poly*/ -morkWriter::morkWriter(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile, - nsIMdbHeap* ioSlotHeap) -: morkNode(ev, inUsage, ioHeap) -, mWriter_Store( 0 ) -, mWriter_File( 0 ) -, mWriter_Bud( 0 ) -, mWriter_Stream( 0 ) -, mWriter_SlotHeap( 0 ) - -, mWriter_CommitGroupIdentity( 0 ) // see mStore_CommitGroupIdentity -, mWriter_GroupBufFill( 0 ) - -, mWriter_TotalCount( morkWriter_kCountNumberOfPhases ) -, mWriter_DoneCount( 0 ) - -, mWriter_LineSize( 0 ) -, mWriter_MaxIndent( morkWriter_kMaxIndent ) -, mWriter_MaxLine( morkWriter_kMaxLine ) - -, mWriter_TableForm( 0 ) -, mWriter_TableAtomScope( 'v' ) -, mWriter_TableRowScope( 0 ) -, mWriter_TableKind( 0 ) - -, mWriter_RowForm( 0 ) -, mWriter_RowAtomScope( 0 ) -, mWriter_RowScope( 0 ) - -, mWriter_DictForm( 0 ) -, mWriter_DictAtomScope( 'v' ) - -, mWriter_NeedDirtyAll( morkBool_kFalse ) -, mWriter_Incremental( morkBool_kTrue ) // opposite of mWriter_NeedDirtyAll -, mWriter_DidStartDict( morkBool_kFalse ) -, mWriter_DidEndDict( morkBool_kTrue ) - -, mWriter_SuppressDirtyRowNewline( morkBool_kFalse ) -, mWriter_DidStartGroup( morkBool_kFalse ) -, mWriter_DidEndGroup( morkBool_kTrue ) -, mWriter_Phase( morkWriter_kPhaseNothingDone ) - -, mWriter_BeVerbose( ev->mEnv_BeVerbose ) - -, mWriter_TableRowArrayPos( 0 ) - -// empty constructors for map iterators: -, mWriter_StoreAtomSpacesIter( ) -, mWriter_AtomSpaceAtomAidsIter( ) - -, mWriter_StoreRowSpacesIter( ) -, mWriter_RowSpaceTablesIter( ) -, mWriter_RowSpaceRowsIter( ) -{ - mWriter_GroupBuf[ 0 ] = 0; - - mWriter_SafeNameBuf[ 0 ] = 0; - mWriter_SafeNameBuf[ morkWriter_kMaxColumnNameSize * 2 ] = 0; - mWriter_ColNameBuf[ 0 ] = 0; - mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize ] = 0; - - mdbYarn* y = &mWriter_ColYarn; - y->mYarn_Buf = mWriter_ColNameBuf; // where to put col bytes - y->mYarn_Fill = 0; // set later by writer - y->mYarn_Size = morkWriter_kMaxColumnNameSize; // our buf size - y->mYarn_More = 0; // set later by writer - y->mYarn_Form = 0; // set later by writer - y->mYarn_Grow = 0; // do not allow buffer growth - - y = &mWriter_SafeYarn; - y->mYarn_Buf = mWriter_SafeNameBuf; // where to put col bytes - y->mYarn_Fill = 0; // set later by writer - y->mYarn_Size = morkWriter_kMaxColumnNameSize * 2; // our buf size - y->mYarn_More = 0; // set later by writer - y->mYarn_Form = 0; // set later by writer - y->mYarn_Grow = 0; // do not allow buffer growth - - if ( ev->Good() ) - { - if ( ioSlotHeap && ioFile && ioStore ) - { - morkStore::SlotWeakStore(ioStore, ev, &mWriter_Store); - nsIMdbFile_SlotStrongFile(ioFile, ev, &mWriter_File); - nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mWriter_SlotHeap); - if ( ev->Good() ) - { - mNode_Derived = morkDerived_kWriter; - } - } - else - ev->NilPointerError(); - } -} - - -void -morkWriter::MakeWriterStream(morkEnv* ev) // give writer a suitable stream -{ - mWriter_Incremental = !mWriter_NeedDirtyAll; // opposites - - if ( !mWriter_Stream && ev->Good() ) - { - if ( mWriter_File ) - { - morkStream* stream = 0; - mork_bool frozen = morkBool_kFalse; // need to modify - nsIMdbHeap* heap = mWriter_SlotHeap; - - if ( mWriter_Incremental ) - { - stream = new(*heap, ev) - morkStream(ev, morkUsage::kHeap, heap, mWriter_File, - morkWriter_kStreamBufSize, frozen); - } - else // compress commit - { - nsIMdbFile* bud = 0; - mWriter_File->AcquireBud(ev->AsMdbEnv(), heap, &bud); - if ( bud ) - { - if ( ev->Good() ) - { - mWriter_Bud = bud; - stream = new(*heap, ev) - morkStream(ev, morkUsage::kHeap, heap, bud, - morkWriter_kStreamBufSize, frozen); - } - else - bud->Release(); - } - } - - if ( stream ) - { - if ( ev->Good() ) - mWriter_Stream = stream; - else - stream->CutStrongRef(ev->AsMdbEnv()); - } - } - else - this->NilWriterFileError(ev); - } -} - -/*public non-poly*/ void -morkWriter::CloseWriter(morkEnv* ev) // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - { - morkStore::SlotWeakStore((morkStore*) 0, ev, &mWriter_Store); - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_File); - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud); - morkStream::SlotStrongStream((morkStream*) 0, ev, &mWriter_Stream); - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mWriter_SlotHeap); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkWriter::NonWriterTypeError(morkEnv* ev) -{ - ev->NewError("non morkWriter"); -} - -/*static*/ void -morkWriter::NilWriterStoreError(morkEnv* ev) -{ - ev->NewError("nil mWriter_Store"); -} - -/*static*/ void -morkWriter::NilWriterBudError(morkEnv* ev) -{ - ev->NewError("nil mWriter_Bud"); -} - -/*static*/ void -morkWriter::NilWriterFileError(morkEnv* ev) -{ - ev->NewError("nil mWriter_File"); -} - -/*static*/ void -morkWriter::NilWriterStreamError(morkEnv* ev) -{ - ev->NewError("nil mWriter_Stream"); -} - -/*static*/ void -morkWriter::UnsupportedPhaseError(morkEnv* ev) -{ - ev->NewError("unsupported mWriter_Phase"); -} - -mork_bool -morkWriter::WriteMore(morkEnv* ev) // call until IsWritingDone() is true -{ - if ( this->IsOpenNode() ) - { - if ( this->IsWriter() ) - { - if ( !mWriter_Stream ) - this->MakeWriterStream(ev); - - if ( mWriter_Stream ) - { - if ( ev->Bad() ) - { - ev->NewWarning("writing stops on error"); - mWriter_Phase = morkWriter_kPhaseWritingDone; - } - switch( mWriter_Phase ) - { - case morkWriter_kPhaseNothingDone: - OnNothingDone(ev); break; - - case morkWriter_kPhaseDirtyAllDone: - OnDirtyAllDone(ev); break; - - case morkWriter_kPhasePutHeaderDone: - OnPutHeaderDone(ev); break; - - case morkWriter_kPhaseRenumberAllDone: - OnRenumberAllDone(ev); break; - - case morkWriter_kPhaseStoreAtomSpaces: - OnStoreAtomSpaces(ev); break; - - case morkWriter_kPhaseAtomSpaceAtomAids: - OnAtomSpaceAtomAids(ev); break; - - case morkWriter_kPhaseStoreRowSpacesTables: - OnStoreRowSpacesTables(ev); break; - - case morkWriter_kPhaseRowSpaceTables: - OnRowSpaceTables(ev); break; - - case morkWriter_kPhaseTableRowArray: - OnTableRowArray(ev); break; - - case morkWriter_kPhaseStoreRowSpacesRows: - OnStoreRowSpacesRows(ev); break; - - case morkWriter_kPhaseRowSpaceRows: - OnRowSpaceRows(ev); break; - - case morkWriter_kPhaseContentDone: - OnContentDone(ev); break; - - case morkWriter_kPhaseWritingDone: - OnWritingDone(ev); break; - - default: - this->UnsupportedPhaseError(ev); - } - } - else - this->NilWriterStreamError(ev); - } - else - this->NonWriterTypeError(ev); - } - else - this->NonOpenNodeError(ev); - - return ev->Good(); -} - -static const char morkWriter_kHexDigits[] = "0123456789ABCDEF"; - -mork_size -morkWriter::WriteYarn(morkEnv* ev, const mdbYarn* inYarn) - // return number of atom bytes written on the current line (which - // implies that escaped line breaks will make the size value smaller - // than the entire yarn's size, since only part goes on a last line). -{ - - - mork_size outSize = 0; - mork_size lineSize = mWriter_LineSize; - morkStream* stream = mWriter_Stream; - - const mork_u1* b = (const mork_u1*) inYarn->mYarn_Buf; - if ( b ) - { - register int c; - mork_fill fill = inYarn->mYarn_Fill; - - const mork_u1* end = b + fill; - while ( b < end && ev->Good() ) - { - if ( lineSize + outSize >= mWriter_MaxLine ) // continue line? - { - stream->PutByteThenNewline(ev, '\\'); - mWriter_LineSize = lineSize = outSize = 0; - } - - c = *b++; // next byte to print - if ( morkCh_IsValue(c) ) - { - stream->Putc(ev, c); - ++outSize; // c - } - else if ( c == ')' || c == '$' || c == '\\' ) - { - stream->Putc(ev, '\\'); - stream->Putc(ev, c); - outSize += 2; // '\' c - } - else - { - outSize += 3; // '$' hex hex - stream->Putc(ev, '$'); - stream->Putc(ev, morkWriter_kHexDigits[ (c >> 4) & 0x0F ]); - stream->Putc(ev, morkWriter_kHexDigits[ c & 0x0F ]); - } - } - } - mWriter_LineSize += outSize; - - return outSize; -} - -mork_size -morkWriter::WriteAtom(morkEnv* ev, const morkAtom* inAtom) - // return number of atom bytes written on the current line (which - // implies that escaped line breaks will make the size value smaller - // than the entire atom's size, since only part goes on a last line). -{ - mork_size outSize = 0; - mdbYarn yarn; // to ref content inside atom - - if ( inAtom->AliasYarn(&yarn) ) - { - if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm ) - this->ChangeDictForm(ev, yarn.mYarn_Form); - - outSize = this->WriteYarn(ev, &yarn); - // mWriter_LineSize += stream->Write(ev, inYarn->mYarn_Buf, outSize); - } - else - inAtom->BadAtomKindError(ev); - - return outSize; -} - -void -morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace) -{ - morkStream* stream = mWriter_Stream; - nsIMdbEnv *mdbev = ev->AsMdbEnv(); - mork_scope scope = ioSpace->SpaceScope(); - if ( scope < 0x80 ) - { - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - stream->PutString(ev, "< <(a="); - stream->Putc(ev, (int) scope); - ++mWriter_LineSize; - stream->PutString(ev, ")> // (f=iso-8859-1)"); - mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth); - } - else - ioSpace->NonAsciiSpaceScopeName(ev); - - if ( ev->Good() ) - { - mdbYarn yarn; // to ref content inside atom - char buf[ 64 ]; // buffer for staging the dict alias hex ID - char* idBuf = buf + 1; // where the id always starts - buf[ 0 ] = '('; // we always start with open paren - morkBookAtom* atom = 0; - morkAtomAidMapIter* ai = &mWriter_AtomSpaceAtomAidsIter; - ai->InitAtomAidMapIter(ev, &ioSpace->mAtomSpace_AtomAids); - mork_change* c = 0; - - for ( c = ai->FirstAtom(ev, &atom); c && ev->Good(); - c = ai->NextAtom(ev, &atom) ) - { - if ( atom ) - { - if ( atom->IsAtomDirty() ) - { - atom->SetAtomClean(); // neutralize change - - atom->AliasYarn(&yarn); - mork_size size = ev->TokenAsHex(idBuf, atom->mBookAtom_Id); - - if ( yarn.mYarn_Form != mWriter_DictForm ) - this->ChangeDictForm(ev, yarn.mYarn_Form); - - mork_size pending = yarn.mYarn_Fill + size + - morkWriter_kYarnEscapeSlop + 4; - this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth); - mork_size bytesWritten; - stream->Write(mdbev, buf, size+1, &bytesWritten); // + '(' - mWriter_LineSize += bytesWritten; - - pending -= ( size + 1 ); - this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasValueDepth); - stream->Putc(ev, '='); // start alias - ++mWriter_LineSize; - - this->WriteYarn(ev, &yarn); - stream->Putc(ev, ')'); // end alias - ++mWriter_LineSize; - - ++mWriter_DoneCount; - } - } - else - ev->NilPointerError(); - } - ai->CloseMapIter(ev); - } - - if ( ev->Good() ) - { - ioSpace->SetAtomSpaceClean(); - // this->IndentAsNeeded(ev, 0); - // stream->PutByteThenNewline(ev, '>'); // end dict - - stream->Putc(ev, '>'); // end dict - ++mWriter_LineSize; - } -} - -/* -(I'm putting the text of this message in file morkWriter.cpp.) - -I'm making a change which should cause rows and tables to go away -when a Mork db is compress committed, when the rows and tables -are no longer needed. Because this is subtle, I'm describing it -here in case misbehavior is ever observed. Otherwise you'll have -almost no hope of fixing a related bug. - -This is done entirely in morkWriter.cpp: morkWriter::DirtyAll(), -which currently marks all rows and tables dirty so they will be -written in a later phase of the commit. My change is to merely -selectively not mark certain rows and tables dirty, when they seem -to be superfluous. - -A row is no longer needed when the mRow_GcUses slot hits zero, and -this is used by the following inline morkRow method: - - mork_bool IsRowUsed() const { return mRow_GcUses != 0; } - -Naturally disaster ensues if mRow_GcUses is ever smaller than right. - -Similarly, we should drop tables when mTable_GcUses hits zero, but -only when a table contains no row members. We consider tables to -self reference (and prevent collection) when they contain content. -Again, disaster ensues if mTable_GcUses is ever smaller than right. - - mork_count GetRowCount() const - { return mTable_RowArray.mArray_Fill; } - - mork_bool IsTableUsed() const - { return (mTable_GcUses != 0 || this->GetRowCount() != 0); } - -Now let's question why the design involves filtering what gets set -to dirty. Why not apply a filter in the later phase when we write -content? Because I'm afraid of missing some subtle interaction in -updating table and row relationships. It seems safer to write a row -or table when it starts out dirty, before morkWriter::DirtyAll() is -called. So this design calls for writing out rows and tables when -they are still clearly used, and additionally, when we have just -been actively writing to them right before this commit. - -Presumably if they are truly useless, they will no longer be dirtied -in later sessions and will get collected during the next compress -commit. So we wait to collect them until they become all dead, and -not just mostly dead. (At which time you can feel free to go through -their pockets looking for loose change.) -*/ - -mork_bool -morkWriter::DirtyAll(morkEnv* ev) - // DirtyAll() visits every store sub-object and marks - // them dirty, including every table, row, cell, and atom. The return - // equals ev->Good(), to show whether any error happened. This method is - // intended for use in the beginning of a "compress commit" which writes - // all store content, whether dirty or not. We dirty everything first so - // that later iterations over content can mark things clean as they are - // written, and organize the process of serialization so that objects are - // written only at need (because of being dirty). Note the method can - // stop early when any error happens, since this will abort any commit. -{ - morkStore* store = mWriter_Store; - if ( store ) - { - store->SetStoreDirty(); - mork_change* c = 0; - - if ( ev->Good() ) - { - morkAtomSpaceMapIter* asi = &mWriter_StoreAtomSpacesIter; - asi->InitAtomSpaceMapIter(ev, &store->mStore_AtomSpaces); - - mork_scope* key = 0; // ignore keys in map - morkAtomSpace* space = 0; // old val node in the map - - for ( c = asi->FirstAtomSpace(ev, key, &space); c && ev->Good(); - c = asi->NextAtomSpace(ev, key, &space) ) - { - if ( space ) - { - if ( space->IsAtomSpace() ) - { - space->SetAtomSpaceDirty(); - morkBookAtom* atom = 0; - morkAtomAidMapIter* ai = &mWriter_AtomSpaceAtomAidsIter; - ai->InitAtomAidMapIter(ev, &space->mAtomSpace_AtomAids); - - for ( c = ai->FirstAtom(ev, &atom); c && ev->Good(); - c = ai->NextAtom(ev, &atom) ) - { - if ( atom ) - { - atom->SetAtomDirty(); - ++mWriter_TotalCount; - } - else - ev->NilPointerError(); - } - - ai->CloseMapIter(ev); - } - else - space->NonAtomSpaceTypeError(ev); - } - else - ev->NilPointerError(); - } - } - - if ( ev->Good() ) - { - morkRowSpaceMapIter* rsi = &mWriter_StoreRowSpacesIter; - rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces); - - mork_scope* key = 0; // ignore keys in map - morkRowSpace* space = 0; // old val node in the map - - for ( c = rsi->FirstRowSpace(ev, key, &space); c && ev->Good(); - c = rsi->NextRowSpace(ev, key, &space) ) - { - if ( space ) - { - if ( space->IsRowSpace() ) - { - space->SetRowSpaceDirty(); - if ( ev->Good() ) - { -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMapIter* ri = &mWriter_RowSpaceRowsIter; -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMapIter* ri = &mWriter_RowSpaceRowsIter; -#endif /*MORK_ENABLE_PROBE_MAPS*/ - ri->InitRowMapIter(ev, &space->mRowSpace_Rows); - - morkRow* row = 0; // old key row in the map - - for ( c = ri->FirstRow(ev, &row); c && ev->Good(); - c = ri->NextRow(ev, &row) ) - { - if ( row && row->IsRow() ) // need to dirty row? - { - if ( row->IsRowUsed() || row->IsRowDirty() ) - { - row->DirtyAllRowContent(ev); - ++mWriter_TotalCount; - } - } - else - row->NonRowTypeWarning(ev); - } - ri->CloseMapIter(ev); - } - - if ( ev->Good() ) - { - morkTableMapIter* ti = &mWriter_RowSpaceTablesIter; - ti->InitTableMapIter(ev, &space->mRowSpace_Tables); - -#ifdef MORK_BEAD_OVER_NODE_MAPS - morkTable* table = ti->FirstTable(ev); - - for ( ; table && ev->Good(); table = ti->NextTable(ev) ) -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - mork_tid* tableKey = 0; // ignore keys in table map - morkTable* table = 0; // old key row in the map - - for ( c = ti->FirstTable(ev, tableKey, &table); c && ev->Good(); - c = ti->NextTable(ev, tableKey, &table) ) -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - { - if ( table && table->IsTable() ) // need to dirty table? - { - if ( table->IsTableUsed() || table->IsTableDirty() ) - { - // table->DirtyAllTableContent(ev); - // only necessary to mark table itself dirty: - table->SetTableDirty(); - table->SetTableRewrite(); - ++mWriter_TotalCount; - } - } - else - table->NonTableTypeWarning(ev); - } - ti->CloseMapIter(ev); - } - } - else - space->NonRowSpaceTypeError(ev); - } - else - ev->NilPointerError(); - } - } - } - else - this->NilWriterStoreError(ev); - - return ev->Good(); -} - - -mork_bool -morkWriter::OnNothingDone(morkEnv* ev) -{ - mWriter_Incremental = !mWriter_NeedDirtyAll; // opposites - - if (!mWriter_Store->IsStoreDirty() && !mWriter_NeedDirtyAll) - { - mWriter_Phase = morkWriter_kPhaseWritingDone; - return morkBool_kTrue; - } - - // morkStream* stream = mWriter_Stream; - if ( mWriter_NeedDirtyAll ) - this->DirtyAll(ev); - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseDirtyAllDone; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::StartGroup(morkEnv* ev) -{ - nsIMdbEnv *mdbev = ev->AsMdbEnv(); - morkStream* stream = mWriter_Stream; - mWriter_DidStartGroup = morkBool_kTrue; - mWriter_DidEndGroup = morkBool_kFalse; - - char buf[ 64 ]; - char* p = buf; - *p++ = '@'; - *p++ = '$'; - *p++ = '$'; - *p++ = '{'; - - mork_token groupID = mWriter_CommitGroupIdentity; - mork_fill idFill = ev->TokenAsHex(p, groupID); - mWriter_GroupBufFill = 0; - // ev->TokenAsHex(mWriter_GroupBuf, groupID); - if ( idFill < morkWriter_kGroupBufSize ) - { - MORK_MEMCPY(mWriter_GroupBuf, p, idFill + 1); - mWriter_GroupBufFill = idFill; - } - else - *mWriter_GroupBuf = 0; - - p += idFill; - *p++ = '{'; - *p++ = '@'; - *p = 0; - - stream->PutLineBreak(ev); - - morkStore* store = mWriter_Store; - if ( store ) // might need to capture commit group position? - { - mork_pos groupPos; - stream->Tell(mdbev, &groupPos); - if ( !store->mStore_FirstCommitGroupPos ) - store->mStore_FirstCommitGroupPos = groupPos; - else if ( !store->mStore_SecondCommitGroupPos ) - store->mStore_SecondCommitGroupPos = groupPos; - } - - mork_size bytesWritten; - stream->Write(mdbev, buf, idFill + 6, &bytesWritten); // '@$${' + idFill + '{@' - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - - return ev->Good(); -} - -mork_bool -morkWriter::CommitGroup(morkEnv* ev) -{ - if ( mWriter_DidStartGroup ) - { - nsIMdbEnv *mdbev = ev->AsMdbEnv(); - mork_size bytesWritten; - morkStream* stream = mWriter_Stream; - - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - stream->Putc(ev, '@'); - stream->Putc(ev, '$'); - stream->Putc(ev, '$'); - stream->Putc(ev, '}'); - - mork_fill bufFill = mWriter_GroupBufFill; - if ( bufFill ) - stream->Write(mdbev, mWriter_GroupBuf, bufFill, &bytesWritten); - - stream->Putc(ev, '}'); - stream->Putc(ev, '@'); - stream->PutLineBreak(ev); - - mWriter_LineSize = 0; - } - - mWriter_DidStartGroup = morkBool_kFalse; - mWriter_DidEndGroup = morkBool_kTrue; - - return ev->Good(); -} - -mork_bool -morkWriter::AbortGroup(morkEnv* ev) -{ - if ( mWriter_DidStartGroup ) - { - morkStream* stream = mWriter_Stream; - stream->PutLineBreak(ev); - stream->PutStringThenNewline(ev, "@$$}~~}@"); - mWriter_LineSize = 0; - } - - mWriter_DidStartGroup = morkBool_kFalse; - mWriter_DidEndGroup = morkBool_kTrue; - - return ev->Good(); -} - - -mork_bool -morkWriter::OnDirtyAllDone(morkEnv* ev) -{ - if ( ev->Good() ) - { - nsIMdbEnv *mdbev = ev->AsMdbEnv(); - morkStream* stream = mWriter_Stream; - mork_pos resultPos; - if ( mWriter_NeedDirtyAll ) // compress commit - { - - stream->Seek(mdbev, 0, &resultPos); // beginning of stream - stream->PutStringThenNewline(ev, morkWriter_kFileHeader); - mWriter_LineSize = 0; - } - else // else mWriter_Incremental - { - mork_pos eos = stream->Length(ev); // length is end of stream - if ( ev->Good() ) - { - stream->Seek(mdbev, eos, &resultPos); // goto end of stream - if ( eos < 128 ) // maybe need file header? - { - stream->PutStringThenNewline(ev, morkWriter_kFileHeader); - mWriter_LineSize = 0; - } - this->StartGroup(ev); // begin incremental transaction - } - } - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhasePutHeaderDone; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnPutHeaderDone(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnPutHeaderDone()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - morkStore* store = mWriter_Store; - if ( store ) - store->RenumberAllCollectableContent(ev); - else - this->NilWriterStoreError(ev); - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseRenumberAllDone; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnRenumberAllDone(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnRenumberAllDone()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreAtomSpaces; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnStoreAtomSpaces(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnStoreAtomSpaces()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - { - morkStore* store = mWriter_Store; - if ( store ) - { - morkAtomSpace* space = store->LazyGetGroundColumnSpace(ev); - if ( space && space->IsAtomSpaceDirty() ) - { - // stream->PutStringThenNewline(ev, "// ground column space dict:"); - - if ( mWriter_LineSize ) - { - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - } - this->WriteAtomSpaceAsDict(ev, space); - space->SetAtomSpaceClean(); - } - } - else - this->NilWriterStoreError(ev); - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreRowSpacesTables; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnAtomSpaceAtomAids(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnAtomSpaceAtomAids()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreRowSpacesTables; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -void -morkWriter::WriteAllStoreTables(morkEnv* ev) -{ - morkStore* store = mWriter_Store; - if ( store && ev->Good() ) - { - morkRowSpaceMapIter* rsi = &mWriter_StoreRowSpacesIter; - rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces); - - mork_scope* key = 0; // ignore keys in map - morkRowSpace* space = 0; // old val node in the map - mork_change* c = 0; - - for ( c = rsi->FirstRowSpace(ev, key, &space); c && ev->Good(); - c = rsi->NextRowSpace(ev, key, &space) ) - { - if ( space ) - { - if ( space->IsRowSpace() ) - { - space->SetRowSpaceClean(); - if ( ev->Good() ) - { - morkTableMapIter* ti = &mWriter_RowSpaceTablesIter; - ti->InitTableMapIter(ev, &space->mRowSpace_Tables); - -#ifdef MORK_BEAD_OVER_NODE_MAPS - morkTable* table = ti->FirstTable(ev); - - for ( ; table && ev->Good(); table = ti->NextTable(ev) ) -#else /*MORK_BEAD_OVER_NODE_MAPS*/ - mork_tid* key2 = 0; // ignore keys in table map - morkTable* table = 0; // old key row in the map - - for ( c = ti->FirstTable(ev, key2, &table); c && ev->Good(); - c = ti->NextTable(ev, key2, &table) ) -#endif /*MORK_BEAD_OVER_NODE_MAPS*/ - { - if ( table && table->IsTable() ) - { - if ( table->IsTableDirty() ) - { - mWriter_BeVerbose = - ( ev->mEnv_BeVerbose || table->IsTableVerbose() ); - - if ( this->PutTableDict(ev, table) ) - this->PutTable(ev, table); - - table->SetTableClean(ev); - mWriter_BeVerbose = ev->mEnv_BeVerbose; - } - } - else - table->NonTableTypeWarning(ev); - } - ti->CloseMapIter(ev); - } - if ( ev->Good() ) - { - mWriter_TableRowScope = 0; // ensure no table context now - -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMapIter* ri = &mWriter_RowSpaceRowsIter; -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMapIter* ri = &mWriter_RowSpaceRowsIter; -#endif /*MORK_ENABLE_PROBE_MAPS*/ - ri->InitRowMapIter(ev, &space->mRowSpace_Rows); - - morkRow* row = 0; // old row in the map - - for ( c = ri->FirstRow(ev, &row); c && ev->Good(); - c = ri->NextRow(ev, &row) ) - { - if ( row && row->IsRow() ) - { - // later we should also check that table use count is nonzero: - if ( row->IsRowDirty() ) // && row->IsRowUsed() ?? - { - mWriter_BeVerbose = ev->mEnv_BeVerbose; - if ( this->PutRowDict(ev, row) ) - { - if ( ev->Good() && mWriter_DidStartDict ) - { - this->EndDict(ev); - if ( mWriter_LineSize < 32 && ev->Good() ) - mWriter_SuppressDirtyRowNewline = morkBool_kTrue; - } - - if ( ev->Good() ) - this->PutRow(ev, row); - } - mWriter_BeVerbose = ev->mEnv_BeVerbose; - } - } - else - row->NonRowTypeWarning(ev); - } - ri->CloseMapIter(ev); - } - } - else - space->NonRowSpaceTypeError(ev); - } - else - ev->NilPointerError(); - } - } -} - -mork_bool -morkWriter::OnStoreRowSpacesTables(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnStoreRowSpacesTables()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - // later we'll break this up, but today we'll write all in one shot: - this->WriteAllStoreTables(ev); - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnRowSpaceTables(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnRowSpaceTables()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnTableRowArray(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnTableRowArray()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseStoreRowSpacesRows; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnStoreRowSpacesRows(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnStoreRowSpacesRows()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseContentDone; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnRowSpaceRows(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnRowSpaceRows()"); - mWriter_LineSize = 0; - - if ( mWriter_NeedDirtyAll ) // compress commit - { - } - - if ( ev->Good() ) - mWriter_Phase = morkWriter_kPhaseContentDone; - else - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop on error - - return ev->Good(); -} - -mork_bool -morkWriter::OnContentDone(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - - // if ( mWriter_NeedDirtyAll ) - // stream->PutStringThenNewline(ev, "// OnContentDone()"); - mWriter_LineSize = 0; - - if ( mWriter_Incremental ) - { - if ( ev->Good() ) - this->CommitGroup(ev); - else - this->AbortGroup(ev); - } - else if ( mWriter_Store && ev->Good() ) - { - // after rewriting everything, there are no transaction groups: - mWriter_Store->mStore_FirstCommitGroupPos = 0; - mWriter_Store->mStore_SecondCommitGroupPos = 0; - } - - stream->Flush(ev->AsMdbEnv()); - nsIMdbFile* bud = mWriter_Bud; - if ( bud ) - { - bud->Flush(ev->AsMdbEnv()); - bud->BecomeTrunk(ev->AsMdbEnv()); - nsIMdbFile_SlotStrongFile((nsIMdbFile*) 0, ev, &mWriter_Bud); - } - else if ( !mWriter_Incremental ) // should have a bud? - this->NilWriterBudError(ev); - - mWriter_Phase = morkWriter_kPhaseWritingDone; // stop always - mWriter_DoneCount = mWriter_TotalCount; - - return ev->Good(); -} - -mork_bool -morkWriter::OnWritingDone(morkEnv* ev) -{ - mWriter_DoneCount = mWriter_TotalCount; - ev->NewWarning("writing is done"); - return ev->Good(); -} - -mork_bool -morkWriter::PutTableChange(morkEnv* ev, const morkTableChange* inChange) -{ - nsIMdbEnv *mdbev = ev->AsMdbEnv(); - if ( inChange->IsAddRowTableChange() ) - { - this->PutRow(ev, inChange->mTableChange_Row ); // row alone means add - } - else if ( inChange->IsCutRowTableChange() ) - { - mWriter_Stream->Putc(ev, '-'); // prefix '-' indicates cut row - ++mWriter_LineSize; - this->PutRow(ev, inChange->mTableChange_Row ); - } - else if ( inChange->IsMoveRowTableChange() ) - { - this->PutRow(ev, inChange->mTableChange_Row ); - char buf[ 64 ]; - char* p = buf; - *p++ = '!'; // for moves, position is indicated by prefix '!' - mork_size posSize = ev->TokenAsHex(p, inChange->mTableChange_Pos); - p += posSize; - *p++ = ' '; - mork_size bytesWritten; - mWriter_Stream->Write(mdbev, buf, posSize + 2, &bytesWritten); - mWriter_LineSize += bytesWritten; - } - else - inChange->UnknownChangeError(ev); - - return ev->Good(); -} - -mork_bool -morkWriter::PutTable(morkEnv* ev, morkTable* ioTable) -{ - if ( ev->Good() ) - this->StartTable(ev, ioTable); - - if ( ev->Good() ) - { - if ( ioTable->IsTableRewrite() || mWriter_NeedDirtyAll ) - { - morkArray* array = &ioTable->mTable_RowArray; // vector of rows - mork_fill fill = array->mArray_Fill; // count of rows - morkRow** rows = (morkRow**) array->mArray_Slots; - if ( rows && fill ) - { - morkRow** end = rows + fill; - while ( rows < end && ev->Good() ) - { - morkRow* r = *rows++; // next row to consider - this->PutRow(ev, r); - } - } - } - else // incremental write only table changes - { - morkList* list = &ioTable->mTable_ChangeList; - morkNext* next = list->GetListHead(); - while ( next && ev->Good() ) - { - this->PutTableChange(ev, (morkTableChange*) next); - next = next->GetNextLink(); - } - } - } - - if ( ev->Good() ) - this->EndTable(ev); - - ioTable->SetTableClean(ev); // note this also cleans change list - mWriter_TableRowScope = 0; - - ++mWriter_DoneCount; - return ev->Good(); -} - -mork_bool -morkWriter::PutTableDict(morkEnv* ev, morkTable* ioTable) -{ - morkRowSpace* space = ioTable->mTable_RowSpace; - mWriter_TableRowScope = space->SpaceScope(); - mWriter_TableForm = 0; // (f=iso-8859-1) - mWriter_TableAtomScope = 'v'; // (a=v) - mWriter_TableKind = ioTable->mTable_Kind; - - mWriter_RowForm = mWriter_TableForm; - mWriter_RowAtomScope = mWriter_TableAtomScope; - mWriter_RowScope = mWriter_TableRowScope; - - mWriter_DictForm = mWriter_TableForm; - mWriter_DictAtomScope = mWriter_TableAtomScope; - - // if ( ev->Good() ) - // this->StartDict(ev); // delay as long as possible - - if ( ev->Good() ) - { - morkRow* r = ioTable->mTable_MetaRow; - if ( r ) - { - if ( r->IsRow() ) - this->PutRowDict(ev, r); - else - r->NonRowTypeError(ev); - } - morkArray* array = &ioTable->mTable_RowArray; // vector of rows - mork_fill fill = array->mArray_Fill; // count of rows - morkRow** rows = (morkRow**) array->mArray_Slots; - if ( rows && fill ) - { - morkRow** end = rows + fill; - while ( rows < end && ev->Good() ) - { - r = *rows++; // next row to consider - if ( r && r->IsRow() ) - this->PutRowDict(ev, r); - else - r->NonRowTypeError(ev); - } - } - // we may have a change for a row which is no longer in the - // table, but contains a cell with something not in the dictionary. - // So, loop through the rows in the change log, writing out any - // dirty dictionary elements. - morkList* list = &ioTable->mTable_ChangeList; - morkNext* next = list->GetListHead(); - while ( next && ev->Good() ) - { - r = ((morkTableChange*) next)->mTableChange_Row; - if ( r && r->IsRow() ) - this->PutRowDict(ev, r); - next = next->GetNextLink(); - } - } - if ( ev->Good() ) - this->EndDict(ev); - - return ev->Good(); -} - -void -morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev, - mork_token inCol, mork_token inValue) -{ - morkStream* stream = mWriter_Stream; - mork_bool isKindCol = ( morkStore_kKindColumn == inCol ); - mork_u1 valSep = (mork_u1) (( isKindCol )? '^' : '='); - - char buf[ 128 ]; // buffer for staging the two hex IDs - char* p = buf; - - mork_size bytesWritten; - if ( inCol < 0x80 ) - { - stream->Putc(ev, '('); - stream->Putc(ev, (char) inCol); - stream->Putc(ev, valSep); - } - else - { - *p++ = '('; // we always start with open paren - - *p++ = '^'; // indicates col is hex ID - mork_size colSize = ev->TokenAsHex(p, inCol); - p += colSize; - *p++ = (char) valSep; - stream->Write(ev->AsMdbEnv(), buf, colSize + 3, &bytesWritten); - - mWriter_LineSize += bytesWritten; - } - - if ( isKindCol ) - { - p = buf; - mork_size valSize = ev->TokenAsHex(p, inValue); - p += valSize; - *p++ = ':'; - *p++ = 'c'; - *p++ = ')'; - stream->Write(ev->AsMdbEnv(), buf, valSize + 3, &bytesWritten); - mWriter_LineSize += bytesWritten; - } - else - { - this->IndentAsNeeded(ev, morkWriter_kTableMetaCellValueDepth); - mdbYarn* yarn = &mWriter_ColYarn; - // mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf; - mWriter_Store->TokenToString(ev, inValue, yarn); - this->WriteYarn(ev, yarn); - stream->Putc(ev, ')'); - ++mWriter_LineSize; - } - - // mork_fill fill = yarn->mYarn_Fill; - // yarnBuf[ fill ] = ')'; // append terminator - // mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')' -} - -void -morkWriter::WriteStringToTokenDictCell(morkEnv* ev, - const char* inCol, mork_token inValue) - // Note inCol should begin with '(' and end with '=', with col in between. -{ - morkStream* stream = mWriter_Stream; - mWriter_LineSize += stream->PutString(ev, inCol); - - this->IndentAsNeeded(ev, morkWriter_kDictMetaCellValueDepth); - mdbYarn* yarn = &mWriter_ColYarn; - // mork_u1* yarnBuf = (mork_u1*) yarn->mYarn_Buf; - mWriter_Store->TokenToString(ev, inValue, yarn); - this->WriteYarn(ev, yarn); - stream->Putc(ev, ')'); - ++mWriter_LineSize; - - // mork_fill fill = yarn->mYarn_Fill; - // yarnBuf[ fill ] = ')'; // append terminator - // mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')' -} - -void -morkWriter::ChangeDictAtomScope(morkEnv* ev, mork_scope inScope) -{ - if ( inScope != mWriter_DictAtomScope ) - { - ev->NewWarning("unexpected atom scope change"); - - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - - char buf[ 128 ]; // buffer for staging the two hex IDs - char* p = buf; - *p++ = '<'; // we always start with open paren - *p++ = '('; // we always start with open paren - *p++ = (char) morkStore_kAtomScopeColumn; - - mork_size scopeSize = 1; // default to one byte - if ( inScope >= 0x80 ) - { - *p++ = '^'; // indicates col is hex ID - scopeSize = ev->TokenAsHex(p, inScope); - p += scopeSize; - } - else - { - *p++ = '='; // indicates col is imm byte - *p++ = (char) (mork_u1) inScope; - } - - *p++ = ')'; - *p++ = '>'; - *p = 0; - - mork_size pending = scopeSize + 6; - this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth); - mork_size bytesWritten; - - stream->Write(ev->AsMdbEnv(), buf, pending, &bytesWritten); - mWriter_LineSize += bytesWritten; - - mWriter_DictAtomScope = inScope; - } -} - -void -morkWriter::ChangeRowForm(morkEnv* ev, mork_cscode inNewForm) -{ - if ( inNewForm != mWriter_RowForm ) - { - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - - char buf[ 128 ]; // buffer for staging the two hex IDs - char* p = buf; - *p++ = '['; // we always start with open bracket - *p++ = '('; // we always start with open paren - *p++ = (char) morkStore_kFormColumn; - - mork_size formSize = 1; // default to one byte - if (! morkCh_IsValue(inNewForm)) - { - *p++ = '^'; // indicates col is hex ID - formSize = ev->TokenAsHex(p, inNewForm); - p += formSize; - } - else - { - *p++ = '='; // indicates col is imm byte - *p++ = (char) (mork_u1) inNewForm; - } - - *p++ = ')'; - *p++ = ']'; - *p = 0; - - mork_size pending = formSize + 6; - this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth); - mork_size bytesWritten; - stream->Write(ev->AsMdbEnv(), buf, pending, &bytesWritten); - mWriter_LineSize += bytesWritten; - - mWriter_RowForm = inNewForm; - } -} - -void -morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm) -{ - if ( inNewForm != mWriter_DictForm ) - { - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - - char buf[ 128 ]; // buffer for staging the two hex IDs - char* p = buf; - *p++ = '<'; // we always start with open angle - *p++ = '('; // we always start with open paren - *p++ = (char) morkStore_kFormColumn; - - mork_size formSize = 1; // default to one byte - if (! morkCh_IsValue(inNewForm)) - { - *p++ = '^'; // indicates col is hex ID - formSize = ev->TokenAsHex(p, inNewForm); - p += formSize; - } - else - { - *p++ = '='; // indicates col is imm byte - *p++ = (char) (mork_u1) inNewForm; - } - - *p++ = ')'; - *p++ = '>'; - *p = 0; - - mork_size pending = formSize + 6; - this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth); - - mork_size bytesWritten; - stream->Write(ev->AsMdbEnv(), buf, pending, &bytesWritten); - mWriter_LineSize += bytesWritten; - - mWriter_DictForm = inNewForm; - } -} - -void -morkWriter::StartDict(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_DidStartDict ) - { - stream->Putc(ev, '>'); // end dict - ++mWriter_LineSize; - } - mWriter_DidStartDict = morkBool_kTrue; - mWriter_DidEndDict = morkBool_kFalse; - - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - - if ( mWriter_TableRowScope ) // blank line before table's dict? - stream->PutLineBreak(ev); - - if ( mWriter_DictForm || mWriter_DictAtomScope != 'v' ) - { - stream->Putc(ev, '<'); - stream->Putc(ev, ' '); - stream->Putc(ev, '<'); - mWriter_LineSize = 3; - if ( mWriter_DictForm ) - this->WriteStringToTokenDictCell(ev, "(f=", mWriter_DictForm); - if ( mWriter_DictAtomScope != 'v' ) - this->WriteStringToTokenDictCell(ev, "(a=", mWriter_DictAtomScope); - - stream->Putc(ev, '>'); - ++mWriter_LineSize; - - mWriter_LineSize = stream->PutIndent(ev, morkWriter_kDictAliasDepth); - } - else - { - stream->Putc(ev, '<'); - // stream->Putc(ev, ' '); - ++mWriter_LineSize; - } -} - -void -morkWriter::EndDict(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - if ( mWriter_DidStartDict ) - { - stream->Putc(ev, '>'); // end dict - ++mWriter_LineSize; - } - mWriter_DidStartDict = morkBool_kFalse; - mWriter_DidEndDict = morkBool_kTrue; -} - -void -morkWriter::StartTable(morkEnv* ev, morkTable* ioTable) -{ - mdbOid toid; // to receive table oid - ioTable->GetTableOid(ev, &toid); - - if ( ev->Good() ) - { - morkStream* stream = mWriter_Stream; - if ( mWriter_LineSize ) - stream->PutLineBreak(ev); - mWriter_LineSize = 0; - // stream->PutLineBreak(ev); - - char buf[ 64 + 16 ]; // buffer for staging hex - char* p = buf; - *p++ = '{'; // punct 1 - mork_size punctSize = (mWriter_BeVerbose) ? 10 : 3; // counting "{ {/*r=*/ " - - if ( ioTable->IsTableRewrite() && mWriter_Incremental ) - { - *p++ = '-'; - ++punctSize; // counting '-' // punct ++ - ++mWriter_LineSize; - } - mork_size oidSize = ev->OidAsHex(p, toid); - p += oidSize; - *p++ = ' '; // punct 2 - *p++ = '{'; // punct 3 - if (mWriter_BeVerbose) - { - - *p++ = '/'; // punct=4 - *p++ = '*'; // punct=5 - *p++ = 'r'; // punct=6 - *p++ = '='; // punct=7 - - mork_token tableUses = (mork_token) ioTable->mTable_GcUses; - mork_size usesSize = ev->TokenAsHex(p, tableUses); - punctSize += usesSize; - p += usesSize; - - *p++ = '*'; // punct=8 - *p++ = '/'; // punct=9 - *p++ = ' '; // punct=10 - } - mork_size bytesWritten; - - stream->Write(ev->AsMdbEnv(), buf, oidSize + punctSize, &bytesWritten); - mWriter_LineSize += bytesWritten; - - mork_kind tk = mWriter_TableKind; - if ( tk ) - { - this->IndentAsNeeded(ev, morkWriter_kTableMetaCellDepth); - this->WriteTokenToTokenMetaCell(ev, morkStore_kKindColumn, tk); - } - - stream->Putc(ev, '('); // start 's' col cell - stream->Putc(ev, 's'); // column - stream->Putc(ev, '='); // column - mWriter_LineSize += 3; - - int prio = (int) ioTable->mTable_Priority; - if ( prio > 9 ) // need to force down to max decimal digit? - prio = 9; - prio += '0'; // add base digit zero - stream->Putc(ev, prio); // priority: (s=0 - ++mWriter_LineSize; - - if ( ioTable->IsTableUnique() ) - { - stream->Putc(ev, 'u'); // (s=0u - ++mWriter_LineSize; - } - if ( ioTable->IsTableVerbose() ) - { - stream->Putc(ev, 'v'); // (s=0uv - ++mWriter_LineSize; - } - - // stream->Putc(ev, ':'); // (s=0uv: - // stream->Putc(ev, 'c'); // (s=0uv:c - stream->Putc(ev, ')'); // end 's' col cell (s=0uv:c) - mWriter_LineSize += 1; // maybe 3 if we add ':' and 'c' - - morkRow* r = ioTable->mTable_MetaRow; - if ( r ) - { - if ( r->IsRow() ) - { - mWriter_SuppressDirtyRowNewline = morkBool_kTrue; - this->PutRow(ev, r); - } - else - r->NonRowTypeError(ev); - } - - stream->Putc(ev, '}'); // end meta - ++mWriter_LineSize; - - if ( mWriter_LineSize < mWriter_MaxIndent ) - { - stream->Putc(ev, ' '); // nice white space - ++mWriter_LineSize; - } - } -} - -void -morkWriter::EndTable(morkEnv* ev) -{ - morkStream* stream = mWriter_Stream; - stream->Putc(ev, '}'); // end table - ++mWriter_LineSize; - - mWriter_TableAtomScope = 'v'; // (a=v) -} - -mork_bool -morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow) -{ - mWriter_RowForm = mWriter_TableForm; - - morkCell* cells = ioRow->mRow_Cells; - if ( cells ) - { - morkStream* stream = mWriter_Stream; - mdbYarn yarn; // to ref content inside atom - char buf[ 64 ]; // buffer for staging the dict alias hex ID - char* idBuf = buf + 1; // where the id always starts - buf[ 0 ] = '('; // we always start with open paren - - morkCell* end = cells + ioRow->mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end && ev->Good() ) - { - morkAtom* atom = cells->GetAtom(); - if ( atom && atom->IsAtomDirty() ) - { - if ( atom->IsBook() ) // is it possible to write atom ID? - { - if ( !this->DidStartDict() ) - { - this->StartDict(ev); - if ( ev->Bad() ) - break; - } - atom->SetAtomClean(); // neutralize change - - this->IndentAsNeeded(ev, morkWriter_kDictAliasDepth); - morkBookAtom* ba = (morkBookAtom*) atom; - mork_size size = ev->TokenAsHex(idBuf, ba->mBookAtom_Id); - mork_size bytesWritten; - stream->Write(ev->AsMdbEnv(), buf, size+1, &bytesWritten); // '(' - mWriter_LineSize += bytesWritten; - - if ( atom->AliasYarn(&yarn) ) - { - mork_scope atomScope = atom->GetBookAtomSpaceScope(ev); - if ( atomScope && atomScope != mWriter_DictAtomScope ) - this->ChangeDictAtomScope(ev, atomScope); - - if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm ) - this->ChangeDictForm(ev, yarn.mYarn_Form); - - mork_size pending = yarn.mYarn_Fill + morkWriter_kYarnEscapeSlop + 1; - this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasValueDepth); - - stream->Putc(ev, '='); // start value - ++mWriter_LineSize; - - this->WriteYarn(ev, &yarn); - - stream->Putc(ev, ')'); // end value - ++mWriter_LineSize; - } - else - atom->BadAtomKindError(ev); - - ++mWriter_DoneCount; - } - } - } - } - return ev->Good(); -} - -mork_bool -morkWriter::IsYarnAllValue(const mdbYarn* inYarn) -{ - mork_fill fill = inYarn->mYarn_Fill; - const mork_u1* buf = (const mork_u1*) inYarn->mYarn_Buf; - const mork_u1* end = buf + fill; - --buf; // prepare for preincrement - while ( ++buf < end ) - { - mork_ch c = *buf; - if ( !morkCh_IsValue(c) ) - return morkBool_kFalse; - } - return morkBool_kTrue; -} - -mork_bool -morkWriter::PutVerboseCell(morkEnv* ev, morkCell* ioCell, mork_bool inWithVal) -{ - morkStream* stream = mWriter_Stream; - morkStore* store = mWriter_Store; - - mdbYarn* colYarn = &mWriter_ColYarn; - - morkAtom* atom = (inWithVal)? ioCell->GetAtom() : (morkAtom*) 0; - - mork_column col = ioCell->GetColumn(); - store->TokenToString(ev, col, colYarn); - - mdbYarn yarn; // to ref content inside atom - atom->AliasYarn(&yarn); // works even when atom==nil - - if ( yarn.mYarn_Form != mWriter_RowForm ) - this->ChangeRowForm(ev, yarn.mYarn_Form); - - mork_size pending = yarn.mYarn_Fill + colYarn->mYarn_Fill + - morkWriter_kYarnEscapeSlop + 3; - this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth); - - stream->Putc(ev, '('); // start cell - ++mWriter_LineSize; - - this->WriteYarn(ev, colYarn); // column - - pending = yarn.mYarn_Fill + morkWriter_kYarnEscapeSlop; - this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellValueDepth); - stream->Putc(ev, '='); - ++mWriter_LineSize; - - this->WriteYarn(ev, &yarn); // value - - stream->Putc(ev, ')'); // end cell - ++mWriter_LineSize; - - return ev->Good(); -} - -mork_bool -morkWriter::PutVerboseRowCells(morkEnv* ev, morkRow* ioRow) -{ - morkCell* cells = ioRow->mRow_Cells; - if ( cells ) - { - - morkCell* end = cells + ioRow->mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end && ev->Good() ) - { - // note we prefer to avoid writing cells here with no value: - if ( cells->GetAtom() ) // does cell have any value? - this->PutVerboseCell(ev, cells, /*inWithVal*/ morkBool_kTrue); - } - } - return ev->Good(); -} - - -mork_bool -morkWriter::PutCell(morkEnv* ev, morkCell* ioCell, mork_bool inWithVal) -{ - morkStream* stream = mWriter_Stream; - char buf[ 128 ]; // buffer for staging hex ids - char* idBuf = buf + 2; // where the id always starts - buf[ 0 ] = '('; // we always start with open paren - buf[ 1 ] = '^'; // column is always a hex ID - - mork_size colSize = 0; // the size of col hex ID - mork_size bytesWritten; - - morkAtom* atom = (inWithVal)? ioCell->GetAtom() : (morkAtom*) 0; - - mork_column col = ioCell->GetColumn(); - char* p = idBuf; - colSize = ev->TokenAsHex(p, col); - p += colSize; - - mdbYarn yarn; // to ref content inside atom - atom->AliasYarn(&yarn); // works even when atom==nil - - if ( yarn.mYarn_Form != mWriter_RowForm ) - this->ChangeRowForm(ev, yarn.mYarn_Form); - - if ( atom && atom->IsBook() ) // is it possible to write atom ID? - { - this->IndentAsNeeded(ev, morkWriter_kRowCellDepth); - *p++ = '^'; - morkBookAtom* ba = (morkBookAtom*) atom; - - mork_size valSize = ev->TokenAsHex(p, ba->mBookAtom_Id); - mork_fill yarnFill = yarn.mYarn_Fill; - mork_bool putImmYarn = ( yarnFill <= valSize ); - if ( putImmYarn ) - putImmYarn = this->IsYarnAllValue(&yarn); - - if ( putImmYarn ) // value no bigger than id? - { - p[ -1 ] = '='; // go back and clobber '^' with '=' instead - if ( yarnFill ) - { - MORK_MEMCPY(p, yarn.mYarn_Buf, yarnFill); - p += yarnFill; - } - *p++ = ')'; - mork_size distance = (mork_size) (p - buf); - stream->Write(ev->AsMdbEnv(), buf, distance, &bytesWritten); - mWriter_LineSize += bytesWritten; - } - else - { - p += valSize; - *p = ')'; - stream->Write(ev->AsMdbEnv(), buf, colSize + valSize + 4, &bytesWritten); - mWriter_LineSize += bytesWritten; - } - - if ( atom->IsAtomDirty() ) - { - atom->SetAtomClean(); - ++mWriter_DoneCount; - } - } - else // must write an anonymous atom - { - mork_size pending = yarn.mYarn_Fill + colSize + - morkWriter_kYarnEscapeSlop + 2; - this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth); - - mork_size bytesWritten; - stream->Write(ev->AsMdbEnv(), buf, colSize + 2, &bytesWritten); - mWriter_LineSize += bytesWritten; - - pending -= ( colSize + 2 ); - this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth); - stream->Putc(ev, '='); - ++mWriter_LineSize; - - this->WriteYarn(ev, &yarn); - stream->Putc(ev, ')'); // end cell - ++mWriter_LineSize; - } - return ev->Good(); -} - -mork_bool -morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow) -{ - morkCell* cells = ioRow->mRow_Cells; - if ( cells ) - { - morkCell* end = cells + ioRow->mRow_Length; - --cells; // prepare for preincrement: - while ( ++cells < end && ev->Good() ) - { - // note we prefer to avoid writing cells here with no value: - if ( cells->GetAtom() ) // does cell have any value? - this->PutCell(ev, cells, /*inWithVal*/ morkBool_kTrue); - } - } - return ev->Good(); -} - -mork_bool -morkWriter::PutRow(morkEnv* ev, morkRow* ioRow) -{ - if ( ioRow && ioRow->IsRow() ) - { - mWriter_RowForm = mWriter_TableForm; - - mork_size bytesWritten; - morkStream* stream = mWriter_Stream; - char buf[ 128 + 16 ]; // buffer for staging hex - char* p = buf; - mdbOid* roid = &ioRow->mRow_Oid; - mork_size ridSize = 0; - - mork_scope tableScope = mWriter_TableRowScope; - - if ( ioRow->IsRowDirty() ) - { - if ( mWriter_SuppressDirtyRowNewline || !mWriter_LineSize ) - mWriter_SuppressDirtyRowNewline = morkBool_kFalse; - else - { - if ( tableScope ) // in a table? - mWriter_LineSize = stream->PutIndent(ev, morkWriter_kRowDepth); - else - mWriter_LineSize = stream->PutIndent(ev, 0); // no indent - } - -// mork_rid rid = roid->mOid_Id; - *p++ = '['; // start row punct=1 - mork_size punctSize = (mWriter_BeVerbose) ? 9 : 1; // counting "[ /*r=*/ " - - mork_bool rowRewrite = ioRow->IsRowRewrite(); - - if ( rowRewrite && mWriter_Incremental ) - { - *p++ = '-'; - ++punctSize; // counting '-' - ++mWriter_LineSize; - } - - if ( tableScope && roid->mOid_Scope == tableScope ) - ridSize = ev->TokenAsHex(p, roid->mOid_Id); - else - ridSize = ev->OidAsHex(p, *roid); - - p += ridSize; - - if (mWriter_BeVerbose) - { - *p++ = ' '; // punct=2 - *p++ = '/'; // punct=3 - *p++ = '*'; // punct=4 - *p++ = 'r'; // punct=5 - *p++ = '='; // punct=6 - - mork_size usesSize = ev->TokenAsHex(p, (mork_token) ioRow->mRow_GcUses); - punctSize += usesSize; - p += usesSize; - - *p++ = '*'; // punct=7 - *p++ = '/'; // punct=8 - *p++ = ' '; // punct=9 - } - stream->Write(ev->AsMdbEnv(), buf, ridSize + punctSize, &bytesWritten); - mWriter_LineSize += bytesWritten; - - // special case situation where row puts exactly one column: - if ( !rowRewrite && mWriter_Incremental && ioRow->HasRowDelta() ) - { - mork_column col = ioRow->GetDeltaColumn(); - morkCell dummy(col, morkChange_kNil, (morkAtom*) 0); - morkCell* cell = 0; - - mork_bool withVal = ( ioRow->GetDeltaChange() != morkChange_kCut ); - - if ( withVal ) - { - mork_pos cellPos = 0; // dummy pos - cell = ioRow->GetCell(ev, col, &cellPos); - } - if ( !cell ) - cell = &dummy; - - if ( mWriter_BeVerbose ) - this->PutVerboseCell(ev, cell, withVal); - else - this->PutCell(ev, cell, withVal); - } - else // put entire row? - { - if ( mWriter_BeVerbose ) - this->PutVerboseRowCells(ev, ioRow); // write all, verbosely - else - this->PutRowCells(ev, ioRow); // write all, hex notation - } - - stream->Putc(ev, ']'); // end row - ++mWriter_LineSize; - } - else - { - this->IndentAsNeeded(ev, morkWriter_kRowDepth); - - if ( tableScope && roid->mOid_Scope == tableScope ) - ridSize = ev->TokenAsHex(p, roid->mOid_Id); - else - ridSize = ev->OidAsHex(p, *roid); - - stream->Write(ev->AsMdbEnv(), buf, ridSize, &bytesWritten); - mWriter_LineSize += bytesWritten; - stream->Putc(ev, ' '); - ++mWriter_LineSize; - } - - ++mWriter_DoneCount; - - ioRow->SetRowClean(); // try to do this at the very last - } - else - ioRow->NonRowTypeWarning(ev); - - return ev->Good(); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - diff --git a/db/mork/src/morkWriter.h b/db/mork/src/morkWriter.h deleted file mode 100644 index 18d420a60d6f..000000000000 --- a/db/mork/src/morkWriter.h +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKWRITER_ -#define _MORKWRITER_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKMAP_ -#include "morkMap.h" -#endif - -#ifndef _MORKROWMAP_ -#include "morkRowMap.h" -#endif - -#ifndef _MORKTABLE_ -#include "morkTable.h" -#endif - -#ifndef _MORKATOMMAP_ -#include "morkAtomMap.h" -#endif - -#ifndef _MORKATOMSPACE_ -#include "morkAtomSpace.h" -#endif - -#ifndef _MORKROWSPACE_ -#include "morkRowSpace.h" -#endif - -#ifndef _MORKSTREAM_ -#include "morkStream.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -#define morkWriter_kStreamBufSize /*i*/ (16 * 1024) /* buffer size for stream */ - -#define morkDerived_kWriter /*i*/ 0x5772 /* ascii 'Wr' */ - -#define morkWriter_kPhaseNothingDone 0 /* nothing has yet been done */ -#define morkWriter_kPhaseDirtyAllDone 1 /* DirtyAll() is done */ -#define morkWriter_kPhasePutHeaderDone 2 /* PutHeader() is done */ - -#define morkWriter_kPhaseRenumberAllDone 3 /* RenumberAll() is done */ - -#define morkWriter_kPhaseStoreAtomSpaces 4 /*mWriter_StoreAtomSpacesIter*/ -#define morkWriter_kPhaseAtomSpaceAtomAids 5 /*mWriter_AtomSpaceAtomAidsIter*/ - -#define morkWriter_kPhaseStoreRowSpacesTables 6 /*mWriter_StoreRowSpacesIter*/ -#define morkWriter_kPhaseRowSpaceTables 7 /*mWriter_RowSpaceTablesIter*/ -#define morkWriter_kPhaseTableRowArray 8 /*mWriter_TableRowArrayPos */ - -#define morkWriter_kPhaseStoreRowSpacesRows 9 /*mWriter_StoreRowSpacesIter*/ -#define morkWriter_kPhaseRowSpaceRows 10 /*mWriter_RowSpaceRowsIter*/ - -#define morkWriter_kPhaseContentDone 11 /* all content written */ -#define morkWriter_kPhaseWritingDone 12 /* everthing has been done */ - -#define morkWriter_kCountNumberOfPhases 13 /* part of mWrite_TotalCount */ - -#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */ - -#define morkWriter_kMaxIndent 66 /* default value for mWriter_MaxIndent */ -#define morkWriter_kMaxLine 78 /* default value for mWriter_MaxLine */ - -#define morkWriter_kYarnEscapeSlop 4 /* guess average yarn escape overhead */ - -#define morkWriter_kTableMetaCellDepth 4 /* */ -#define morkWriter_kTableMetaCellValueDepth 6 /* */ - -#define morkWriter_kDictMetaCellDepth 4 /* */ -#define morkWriter_kDictMetaCellValueDepth 6 /* */ - -#define morkWriter_kDictAliasDepth 2 /* */ -#define morkWriter_kDictAliasValueDepth 4 /* */ - -#define morkWriter_kRowDepth 2 /* */ -#define morkWriter_kRowCellDepth 4 /* */ -#define morkWriter_kRowCellValueDepth 6 /* */ - -#define morkWriter_kGroupBufSize 64 /* */ - -// v=1.1 retired on 23-Mar-99 (for metainfo one char column names) -// v=1.2 retired on 20-Apr-99 (for ":c" suffix on table kind hex refs) -// v=1.3 retired on 20-Apr-99 (for 1CE:m instead of ill-formed 1CE:^6D) -#define morkWriter_kFileHeader "// " - -class morkWriter : public morkNode { // row iterator - -// public: // slots inherited from morkObject (meant to inform only) - // nsIMdbHeap* mNode_Heap; - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - - morkStore* mWriter_Store; // weak ref to committing store - nsIMdbFile* mWriter_File; // strong ref to store's file - nsIMdbFile* mWriter_Bud; // strong ref to bud of mWriter_File - morkStream* mWriter_Stream; // strong ref to stream on bud file - nsIMdbHeap* mWriter_SlotHeap; // strong ref to slot heap - - // GroupIdentity should be based on mStore_CommitGroupIdentity: - mork_gid mWriter_CommitGroupIdentity; // transaction ID number - - // GroupBuf holds a hex version of mWriter_CommitGroupIdentity: - char mWriter_GroupBuf[ morkWriter_kGroupBufSize ]; - mork_fill mWriter_GroupBufFill; // actual bytes in GroupBuf - - mork_count mWriter_TotalCount; // count of all things to be written - mork_count mWriter_DoneCount; // count of things already written - - mork_size mWriter_LineSize; // length of current line being written - mork_size mWriter_MaxIndent; // line size forcing a line break - mork_size mWriter_MaxLine; // line size forcing a value continuation - - mork_cscode mWriter_TableForm; // current charset metainfo - mork_scope mWriter_TableAtomScope; // current atom scope - mork_scope mWriter_TableRowScope; // current row scope - mork_kind mWriter_TableKind; // current table kind - - mork_cscode mWriter_RowForm; // current charset metainfo - mork_scope mWriter_RowAtomScope; // current atom scope - mork_scope mWriter_RowScope; // current row scope - - mork_cscode mWriter_DictForm; // current charset metainfo - mork_scope mWriter_DictAtomScope; // current atom scope - - mork_bool mWriter_NeedDirtyAll; // need to call DirtyAll() - mork_bool mWriter_Incremental; // opposite of mWriter_NeedDirtyAll - mork_bool mWriter_DidStartDict; // true when a dict has been started - mork_bool mWriter_DidEndDict; // true when a dict has been ended - - mork_bool mWriter_SuppressDirtyRowNewline; // for table meta rows - mork_bool mWriter_DidStartGroup; // true when a group has been started - mork_bool mWriter_DidEndGroup; // true when a group has been ended - mork_u1 mWriter_Phase; // status of writing process - - mork_bool mWriter_BeVerbose; // driven by env and table verbose settings: - // mWriter_BeVerbose equals ( ev->mEnv_BeVerbose || table->IsTableVerbose() ) - - mork_u1 mWriter_Pad[ 3 ]; // for u4 alignment - - mork_pos mWriter_TableRowArrayPos; // index into mTable_RowArray - - char mWriter_SafeNameBuf[ (morkWriter_kMaxColumnNameSize * 2) + 4 ]; - // Note: extra four bytes in ColNameBuf means we can always append to yarn - - char mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize + 4 ]; - // Note: extra four bytes in ColNameBuf means we can always append to yarn - - mdbYarn mWriter_ColYarn; // a yarn to describe space in ColNameBuf: - // mYarn_Buf == mWriter_ColNameBuf, mYarn_Size == morkWriter_kMaxColumnNameSize - - mdbYarn mWriter_SafeYarn; // a yarn to describe space in ColNameBuf: - // mYarn_Buf == mWriter_SafeNameBuf, mYarn_Size == (kMaxColumnNameSize * 2) - - morkAtomSpaceMapIter mWriter_StoreAtomSpacesIter; // for mStore_AtomSpaces - morkAtomAidMapIter mWriter_AtomSpaceAtomAidsIter; // for AtomSpace_AtomAids - - morkRowSpaceMapIter mWriter_StoreRowSpacesIter; // for mStore_RowSpaces - morkTableMapIter mWriter_RowSpaceTablesIter; // for mRowSpace_Tables - -#ifdef MORK_ENABLE_PROBE_MAPS - morkRowProbeMapIter mWriter_RowSpaceRowsIter; // for mRowSpace_Rows -#else /*MORK_ENABLE_PROBE_MAPS*/ - morkRowMapIter mWriter_RowSpaceRowsIter; // for mRowSpace_Rows -#endif /*MORK_ENABLE_PROBE_MAPS*/ - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseWriter() - virtual ~morkWriter(); // assert that close executed earlier - -public: // morkWriter construction & destruction - morkWriter(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioHeap, morkStore* ioStore, nsIMdbFile* ioFile, - nsIMdbHeap* ioSlotHeap); - void CloseWriter(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkWriter(const morkWriter& other); - morkWriter& operator=(const morkWriter& other); - -public: // dynamic type identification - mork_bool IsWriter() const - { return IsNode() && mNode_Derived == morkDerived_kWriter; } -// } ===== end morkNode methods ===== - -public: // typing & errors - static void NonWriterTypeError(morkEnv* ev); - static void NilWriterStoreError(morkEnv* ev); - static void NilWriterBudError(morkEnv* ev); - static void NilWriterStreamError(morkEnv* ev); - static void NilWriterFileError(morkEnv* ev); - static void UnsupportedPhaseError(morkEnv* ev); - -public: // utitlities - void ChangeRowForm(morkEnv* ev, mork_cscode inNewForm); - void ChangeDictForm(morkEnv* ev, mork_cscode inNewForm); - void ChangeDictAtomScope(morkEnv* ev, mork_scope inScope); - -public: // inlines - mork_bool DidStartDict() const { return mWriter_DidStartDict; } - mork_bool DidEndDict() const { return mWriter_DidEndDict; } - - void IndentAsNeeded(morkEnv* ev, mork_size inDepth) - { - if ( mWriter_LineSize > mWriter_MaxIndent ) - mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth); - } - - void IndentOverMaxLine(morkEnv* ev, - mork_size inPendingSize, mork_size inDepth) - { - if ( mWriter_LineSize + inPendingSize > mWriter_MaxLine ) - mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth); - } - -public: // delayed construction - - void MakeWriterStream(morkEnv* ev); // give writer a suitable stream - -public: // iterative/asynchronous writing - - mork_bool WriteMore(morkEnv* ev); // call until IsWritingDone() is true - - mork_bool IsWritingDone() const // don't call WriteMore() any longer? - { return mWriter_Phase == morkWriter_kPhaseWritingDone; } - -public: // marking all content dirty - mork_bool DirtyAll(morkEnv* ev); - // DirtyAll() visits every store sub-object and marks - // them dirty, including every table, row, cell, and atom. The return - // equals ev->Good(), to show whether any error happened. This method is - // intended for use in the beginning of a "compress commit" which writes - // all store content, whether dirty or not. We dirty everything first so - // that later iterations over content can mark things clean as they are - // written, and organize the process of serialization so that objects are - // written only at need (because of being dirty). Note the method can - // stop early when any error happens, since this will abort any commit. - -public: // group commit transactions - - mork_bool StartGroup(morkEnv* ev); - mork_bool CommitGroup(morkEnv* ev); - mork_bool AbortGroup(morkEnv* ev); - -public: // phase methods - mork_bool OnNothingDone(morkEnv* ev); - mork_bool OnDirtyAllDone(morkEnv* ev); - mork_bool OnPutHeaderDone(morkEnv* ev); - - mork_bool OnRenumberAllDone(morkEnv* ev); - - mork_bool OnStoreAtomSpaces(morkEnv* ev); - mork_bool OnAtomSpaceAtomAids(morkEnv* ev); - - mork_bool OnStoreRowSpacesTables(morkEnv* ev); - mork_bool OnRowSpaceTables(morkEnv* ev); - mork_bool OnTableRowArray(morkEnv* ev); - - mork_bool OnStoreRowSpacesRows(morkEnv* ev); - mork_bool OnRowSpaceRows(morkEnv* ev); - - mork_bool OnContentDone(morkEnv* ev); - mork_bool OnWritingDone(morkEnv* ev); - -public: // writing dict items first pass - mork_bool PutTableDict(morkEnv* ev, morkTable* ioTable); - mork_bool PutRowDict(morkEnv* ev, morkRow* ioRow); - -public: // writing node content second pass - mork_bool PutTable(morkEnv* ev, morkTable* ioTable); - mork_bool PutRow(morkEnv* ev, morkRow* ioRow); - mork_bool PutRowCells(morkEnv* ev, morkRow* ioRow); - mork_bool PutVerboseRowCells(morkEnv* ev, morkRow* ioRow); - - mork_bool PutCell(morkEnv* ev, morkCell* ioCell, mork_bool inWithVal); - mork_bool PutVerboseCell(morkEnv* ev, morkCell* ioCell, mork_bool inWithVal); - - mork_bool PutTableChange(morkEnv* ev, const morkTableChange* inChange); - -public: // other writer methods - - mork_bool IsYarnAllValue(const mdbYarn* inYarn); - - mork_size WriteYarn(morkEnv* ev, const mdbYarn* inYarn); - // return number of atom bytes written on the current line (which - // implies that escaped line breaks will make the size value smaller - // than the entire yarn's size, since only part goes on a last line). - - mork_size WriteAtom(morkEnv* ev, const morkAtom* inAtom); - // return number of atom bytes written on the current line (which - // implies that escaped line breaks will make the size value smaller - // than the entire atom's size, since only part goes on a last line). - - void WriteAllStoreTables(morkEnv* ev); - void WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace); - - void WriteTokenToTokenMetaCell(morkEnv* ev, mork_token inCol, - mork_token inValue); - void WriteStringToTokenDictCell(morkEnv* ev, const char* inCol, - mork_token inValue); - // Note inCol should begin with '(' and end with '=', with col in between. - - void StartDict(morkEnv* ev); - void EndDict(morkEnv* ev); - - void StartTable(morkEnv* ev, morkTable* ioTable); - void EndTable(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakWriter(morkWriter* me, - morkEnv* ev, morkWriter** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongWriter(morkWriter* me, - morkEnv* ev, morkWriter** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKTABLEROWCURSOR_ */ diff --git a/db/mork/src/morkYarn.cpp b/db/mork/src/morkYarn.cpp deleted file mode 100644 index cf7647d73e37..000000000000 --- a/db/mork/src/morkYarn.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#ifndef _MORKYARN_ -#include "morkYarn.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// ````` ````` ````` ````` ````` -// { ===== begin morkNode interface ===== - -/*public virtual*/ void -morkYarn::CloseMorkNode(morkEnv* ev) /*i*/ // CloseYarn() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseYarn(ev); - this->MarkShut(); - } -} - -/*public virtual*/ -morkYarn::~morkYarn() /*i*/ // assert CloseYarn() executed earlier -{ - MORK_ASSERT(mYarn_Body.mYarn_Buf==0); -} - -/*public non-poly*/ -morkYarn::morkYarn(morkEnv* ev, /*i*/ - const morkUsage& inUsage, nsIMdbHeap* ioHeap) - : morkNode(ev, inUsage, ioHeap) -{ - if ( ev->Good() ) - mNode_Derived = morkDerived_kYarn; -} - -/*public non-poly*/ void -morkYarn::CloseYarn(morkEnv* ev) /*i*/ // called by CloseMorkNode(); -{ - if ( this ) - { - if ( this->IsNode() ) - this->MarkShut(); - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== -// ````` ````` ````` ````` ````` - -/*static*/ void -morkYarn::NonYarnTypeError(morkEnv* ev) -{ - ev->NewError("non morkYarn"); -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/morkYarn.h b/db/mork/src/morkYarn.h deleted file mode 100644 index 49db2eb3d826..000000000000 --- a/db/mork/src/morkYarn.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKYARN_ -#define _MORKYARN_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -#define morkDerived_kYarn /*i*/ 0x7952 /* ascii 'yR' */ - -/*| morkYarn: a reference counted nsIMdbYarn C struct. This is for use in those -**| few cases where single instances of reference counted buffers are needed -**| in Mork, and we expect few enough instances that overhead is not a factor -**| in decided whether to use such a thing. -|*/ -class morkYarn : public morkNode { // refcounted yarn - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - mdbYarn mYarn_Body; - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseYarn() only if open - virtual ~morkYarn(); // assert that CloseYarn() executed earlier - -public: // morkYarn construction & destruction - morkYarn(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap); - void CloseYarn(morkEnv* ev); // called by CloseMorkNode(); - -private: // copying is not allowed - morkYarn(const morkYarn& other); - morkYarn& operator=(const morkYarn& other); - -public: // dynamic type identification - mork_bool IsYarn() const - { return IsNode() && mNode_Derived == morkDerived_kYarn; } -// } ===== end morkNode methods ===== - -public: // typing - static void NonYarnTypeError(morkEnv* ev); - -public: // typesafe refcounting inlines calling inherited morkNode methods - static void SlotWeakYarn(morkYarn* me, - morkEnv* ev, morkYarn** ioSlot) - { morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); } - - static void SlotStrongYarn(morkYarn* me, - morkEnv* ev, morkYarn** ioSlot) - { morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); } -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKYARN_ */ diff --git a/db/mork/src/morkZone.cpp b/db/mork/src/morkZone.cpp deleted file mode 100644 index c599252c5b5a..000000000000 --- a/db/mork/src/morkZone.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKZONE_ -#include "morkZone.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// { ===== begin morkNode interface ===== -// public: // morkNode virtual methods -void morkZone::CloseMorkNode(morkEnv* ev) // CloseZone() only if open -{ - if ( this->IsOpenNode() ) - { - this->MarkClosing(); - this->CloseZone(ev); - this->MarkShut(); - } -} - -morkZone::~morkZone() // assert that CloseZone() executed earlier -{ - MORK_ASSERT(this->IsShutNode()); -} - -// public: // morkMap construction & destruction -morkZone::morkZone(morkEnv* ev, const morkUsage& inUsage, - nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioZoneHeap) -: morkNode(ev, inUsage, ioNodeHeap) -, mZone_Heap( 0 ) -, mZone_HeapVolume( 0 ) -, mZone_BlockVolume( 0 ) -, mZone_RunVolume( 0 ) -, mZone_ChipVolume( 0 ) - -, mZone_FreeOldRunVolume( 0 ) - -, mZone_HunkCount( 0 ) -, mZone_FreeOldRunCount( 0 ) - -, mZone_HunkList( 0 ) -, mZone_FreeOldRunList( 0 ) - -, mZone_At( 0 ) -, mZone_AtSize( 0 ) - - // morkRun* mZone_FreeRuns[ morkZone_kBuckets + 1 ]; -{ - - morkRun** runs = mZone_FreeRuns; - morkRun** end = runs + (morkZone_kBuckets + 1); // one past last slot - --runs; // prepare for preincrement - while ( ++runs < end ) // another slot in array? - *runs = 0; // clear all the slots - - if ( ev->Good() ) - { - if ( ioZoneHeap ) - { - nsIMdbHeap_SlotStrongHeap(ioZoneHeap, ev, &mZone_Heap); - if ( ev->Good() ) - mNode_Derived = morkDerived_kZone; - } - else - ev->NilPointerError(); - } -} - -void morkZone::CloseZone(morkEnv* ev) // called by CloseMorkNode() -{ - if ( this ) - { - if ( this->IsNode() ) - { - nsIMdbHeap* heap = mZone_Heap; - if ( heap ) - { - morkHunk* hunk = 0; - nsIMdbEnv* mev = ev->AsMdbEnv(); - - morkHunk* next = mZone_HunkList; - while ( ( hunk = next ) != 0 ) - { -#ifdef morkHunk_USE_TAG_SLOT - if ( !hunk->HunkGoodTag() ) - hunk->BadHunkTagWarning(ev); -#endif /* morkHunk_USE_TAG_SLOT */ - - next = hunk->HunkNext(); - heap->Free(mev, hunk); - } - } - nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mZone_Heap); - this->MarkShut(); - } - else - this->NonNodeError(ev); - } - else - ev->NilPointerError(); -} - -// } ===== end morkNode methods ===== - -/*static*/ void -morkZone::NonZoneTypeError(morkEnv* ev) -{ - ev->NewError("non morkZone"); -} - -/*static*/ void -morkZone::NilZoneHeapError(morkEnv* ev) -{ - ev->NewError("nil mZone_Heap"); -} - -/*static*/ void -morkHunk::BadHunkTagWarning(morkEnv* ev) -{ - ev->NewWarning("bad mHunk_Tag"); -} - -/*static*/ void -morkRun::BadRunTagError(morkEnv* ev) -{ - ev->NewError("bad mRun_Tag"); -} - -/*static*/ void -morkRun::RunSizeAlignError(morkEnv* ev) -{ - ev->NewError("bad RunSize() alignment"); -} - -// { ===== begin morkZone methods ===== - - -mork_size morkZone::zone_grow_at(morkEnv* ev, mork_size inNeededSize) -{ - mZone_At = 0; // remove any ref to current hunk - mZone_AtSize = 0; // zero available bytes in current hunk - - mork_size runSize = 0; // actual size of a particular run - - // try to find a run in old run list with at least inNeededSize bytes: - morkRun* run = mZone_FreeOldRunList; // cursor in list scan - morkRun* prev = 0; // the node before run in the list scan - - while ( run ) // another run in list to check? - { - morkOldRun* oldRun = (morkOldRun*) run; - mork_size oldSize = oldRun->OldSize(); - if ( oldSize >= inNeededSize ) // found one big enough? - { - runSize = oldSize; - break; // end while loop early - } - prev = run; // remember last position in singly linked list - run = run->RunNext(); // advance cursor to next node in list - } - if ( runSize && run ) // found a usable old run? - { - morkRun* next = run->RunNext(); - if ( prev ) // another node in free list precedes run? - prev->RunSetNext(next); // unlink run - else - mZone_FreeOldRunList = next; // unlink run from head of list - - morkOldRun *oldRun = (morkOldRun *) run; - oldRun->OldSetSize(runSize); - mZone_At = (mork_u1*) run; - mZone_AtSize = runSize; - -#ifdef morkZone_CONFIG_DEBUG -#ifdef morkZone_CONFIG_ALIGN_8 - mork_ip lowThree = ((mork_ip) mZone_At) & 7; - if ( lowThree ) // not 8 byte aligned? -#else /*morkZone_CONFIG_ALIGN_8*/ - mork_ip lowTwo = ((mork_ip) mZone_At) & 3; - if ( lowTwo ) // not 4 byte aligned? -#endif /*morkZone_CONFIG_ALIGN_8*/ - ev->NewWarning("mZone_At not aligned"); -#endif /*morkZone_CONFIG_DEBUG*/ - } - else // need to allocate a brand new run - { - inNeededSize += 7; // allow for possible alignment padding - mork_size newSize = ( inNeededSize > morkZone_kNewHunkSize )? - inNeededSize : morkZone_kNewHunkSize; - - morkHunk* hunk = this->zone_new_hunk(ev, newSize); - if ( hunk ) - { - morkRun* hunkRun = hunk->HunkRun(); - mork_u1* at = (mork_u1*) hunkRun->RunAsBlock(); - mork_ip lowBits = ((mork_ip) at) & 7; - if ( lowBits ) // not 8 byte aligned? - { - mork_ip skip = (8 - lowBits); // skip the complement to align - at += skip; - newSize -= skip; - } - mZone_At = at; - mZone_AtSize = newSize; - } - } - - return mZone_AtSize; -} - -morkHunk* morkZone::zone_new_hunk(morkEnv* ev, mdb_size inSize) // alloc -{ - mdb_size hunkSize = inSize + sizeof(morkHunk); - void* outBlock = 0; // we are going straight to the heap: - mZone_Heap->Alloc(ev->AsMdbEnv(), hunkSize, &outBlock); - if ( outBlock ) - { -#ifdef morkZone_CONFIG_VOL_STATS - mZone_HeapVolume += hunkSize; // track all heap allocations -#endif /* morkZone_CONFIG_VOL_STATS */ - - morkHunk* hunk = (morkHunk*) outBlock; -#ifdef morkHunk_USE_TAG_SLOT - hunk->HunkInitTag(); -#endif /* morkHunk_USE_TAG_SLOT */ - - hunk->HunkSetNext(mZone_HunkList); - mZone_HunkList = hunk; - ++mZone_HunkCount; - - morkRun* run = hunk->HunkRun(); - run->RunSetSize(inSize); -#ifdef morkRun_USE_TAG_SLOT - run->RunInitTag(); -#endif /* morkRun_USE_TAG_SLOT */ - - return hunk; - } - if ( ev->Good() ) // got this far without any error reported yet? - ev->OutOfMemoryError(); - return (morkHunk*) 0; -} - -void* morkZone::zone_new_chip(morkEnv* ev, mdb_size inSize) // alloc -{ -#ifdef morkZone_CONFIG_VOL_STATS - mZone_BlockVolume += inSize; // sum sizes of both chips and runs -#endif /* morkZone_CONFIG_VOL_STATS */ - - mork_u1* at = mZone_At; - mork_size atSize = mZone_AtSize; // available bytes in current hunk - if ( atSize >= inSize ) // current hunk can satisfy request? - { - mZone_At = at + inSize; - mZone_AtSize = atSize - inSize; - return at; - } - else if ( atSize > morkZone_kMaxHunkWaste ) // over max waste allowed? - { - morkHunk* hunk = this->zone_new_hunk(ev, inSize); - if ( hunk ) - return hunk->HunkRun(); - - return (void*) 0; // show allocation has failed - } - else // get ourselves a new hunk for suballocation: - { - atSize = this->zone_grow_at(ev, inSize); // get a new hunk - } - - if ( atSize >= inSize ) // current hunk can satisfy request? - { - at = mZone_At; - mZone_At = at + inSize; - mZone_AtSize = atSize - inSize; - return at; - } - - if ( ev->Good() ) // got this far without any error reported yet? - ev->OutOfMemoryError(); - - return (void*) 0; // show allocation has failed -} - -void* morkZone::ZoneNewChip(morkEnv* ev, mdb_size inSize) // alloc -{ -#ifdef morkZone_CONFIG_ARENA - -#ifdef morkZone_CONFIG_DEBUG - if ( !this->IsZone() ) - this->NonZoneTypeError(ev); - else if ( !mZone_Heap ) - this->NilZoneHeapError(ev); -#endif /*morkZone_CONFIG_DEBUG*/ - -#ifdef morkZone_CONFIG_ALIGN_8 - inSize += 7; - inSize &= ~((mork_ip) 7); // force to multiple of 8 bytes -#else /*morkZone_CONFIG_ALIGN_8*/ - inSize += 3; - inSize &= ~((mork_ip) 3); // force to multiple of 4 bytes -#endif /*morkZone_CONFIG_ALIGN_8*/ - -#ifdef morkZone_CONFIG_VOL_STATS - mZone_ChipVolume += inSize; // sum sizes of chips only -#endif /* morkZone_CONFIG_VOL_STATS */ - - return this->zone_new_chip(ev, inSize); - -#else /*morkZone_CONFIG_ARENA*/ - void* outBlock = 0; - mZone_Heap->Alloc(ev->AsMdbEnv(), inSize, &outBlock); - return outBlock; -#endif /*morkZone_CONFIG_ARENA*/ - -} - -// public: // ...but runs do indeed know how big they are -void* morkZone::ZoneNewRun(morkEnv* ev, mdb_size inSize) // alloc -{ -#ifdef morkZone_CONFIG_ARENA - -#ifdef morkZone_CONFIG_DEBUG - if ( !this->IsZone() ) - this->NonZoneTypeError(ev); - else if ( !mZone_Heap ) - this->NilZoneHeapError(ev); -#endif /*morkZone_CONFIG_DEBUG*/ - - inSize += morkZone_kRoundAdd; - inSize &= morkZone_kRoundMask; - if ( inSize <= morkZone_kMaxCachedRun ) - { - morkRun** bucket = mZone_FreeRuns + (inSize >> morkZone_kRoundBits); - morkRun* hit = *bucket; - if ( hit ) // cache hit? - { - *bucket = hit->RunNext(); - hit->RunSetSize(inSize); - return hit->RunAsBlock(); - } - } - mdb_size blockSize = inSize + sizeof(morkRun); // plus run overhead -#ifdef morkZone_CONFIG_VOL_STATS - mZone_RunVolume += blockSize; // sum sizes of runs only -#endif /* morkZone_CONFIG_VOL_STATS */ - morkRun* run = (morkRun*) this->zone_new_chip(ev, blockSize); - if ( run ) - { - run->RunSetSize(inSize); -#ifdef morkRun_USE_TAG_SLOT - run->RunInitTag(); -#endif /* morkRun_USE_TAG_SLOT */ - return run->RunAsBlock(); - } - - if ( ev->Good() ) // got this far without any error reported yet? - ev->OutOfMemoryError(); - - return (void*) 0; // indicate failed allocation - -#else /*morkZone_CONFIG_ARENA*/ - void* outBlock = 0; - mZone_Heap->Alloc(ev->AsMdbEnv(), inSize, &outBlock); - return outBlock; -#endif /*morkZone_CONFIG_ARENA*/ -} - -void morkZone::ZoneZapRun(morkEnv* ev, void* ioRunBlock) // free -{ -#ifdef morkZone_CONFIG_ARENA - - morkRun* run = morkRun::BlockAsRun(ioRunBlock); - mdb_size runSize = run->RunSize(); -#ifdef morkZone_CONFIG_VOL_STATS - mZone_BlockVolume -= runSize; // tracking sizes of both chips and runs -#endif /* morkZone_CONFIG_VOL_STATS */ - -#ifdef morkZone_CONFIG_DEBUG - if ( !this->IsZone() ) - this->NonZoneTypeError(ev); - else if ( !mZone_Heap ) - this->NilZoneHeapError(ev); - else if ( !ioRunBlock ) - ev->NilPointerError(); - else if ( runSize & morkZone_kRoundAdd ) - run->RunSizeAlignError(ev); -#ifdef morkRun_USE_TAG_SLOT - else if ( !run->RunGoodTag() ) - run->BadRunTagError(ev); -#endif /* morkRun_USE_TAG_SLOT */ -#endif /*morkZone_CONFIG_DEBUG*/ - - if ( runSize <= morkZone_kMaxCachedRun ) // goes into free run list? - { - morkRun** bucket = mZone_FreeRuns + (runSize >> morkZone_kRoundBits); - run->RunSetNext(*bucket); // push onto free run list - *bucket = run; - } - else // free old run list - { - run->RunSetNext(mZone_FreeOldRunList); // push onto free old run list - mZone_FreeOldRunList = run; - ++mZone_FreeOldRunCount; -#ifdef morkZone_CONFIG_VOL_STATS - mZone_FreeOldRunVolume += runSize; -#endif /* morkZone_CONFIG_VOL_STATS */ - - morkOldRun* oldRun = (morkOldRun*) run; // to access extra size slot - oldRun->OldSetSize(runSize); // so we know how big this is later - } - -#else /*morkZone_CONFIG_ARENA*/ - mZone_Heap->Free(ev->AsMdbEnv(), ioRunBlock); -#endif /*morkZone_CONFIG_ARENA*/ -} - -void* morkZone::ZoneGrowRun(morkEnv* ev, void* ioRunBlock, mdb_size inSize) -{ -#ifdef morkZone_CONFIG_ARENA - - morkRun* run = morkRun::BlockAsRun(ioRunBlock); - mdb_size runSize = run->RunSize(); - -#ifdef morkZone_CONFIG_DEBUG - if ( !this->IsZone() ) - this->NonZoneTypeError(ev); - else if ( !mZone_Heap ) - this->NilZoneHeapError(ev); -#endif /*morkZone_CONFIG_DEBUG*/ - -#ifdef morkZone_CONFIG_ALIGN_8 - inSize += 7; - inSize &= ~((mork_ip) 7); // force to multiple of 8 bytes -#else /*morkZone_CONFIG_ALIGN_8*/ - inSize += 3; - inSize &= ~((mork_ip) 3); // force to multiple of 4 bytes -#endif /*morkZone_CONFIG_ALIGN_8*/ - - if ( inSize > runSize ) - { - void* newBuf = this->ZoneNewRun(ev, inSize); - if ( newBuf ) - { - MORK_MEMCPY(newBuf, ioRunBlock, runSize); - this->ZoneZapRun(ev, ioRunBlock); - - return newBuf; - } - } - else - return ioRunBlock; // old size is big enough - - if ( ev->Good() ) // got this far without any error reported yet? - ev->OutOfMemoryError(); - - return (void*) 0; // indicate failed allocation - -#else /*morkZone_CONFIG_ARENA*/ - void* outBlock = 0; - mZone_Heap->Free(ev->AsMdbEnv(), ioRunBlock); - return outBlock; -#endif /*morkZone_CONFIG_ARENA*/ -} - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -// { ===== begin nsIMdbHeap methods ===== -/*virtual*/ mdb_err -morkZone::Alloc(nsIMdbEnv* mev, // allocate a piece of memory - mdb_size inSize, // requested size of new memory block - void** outBlock) // memory block of inSize bytes, or nil -{ - mdb_err outErr = 0; - void* block = 0; - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - block = this->ZoneNewRun(ev, inSize); - outErr = ev->AsErr(); - } - else - outErr = 1; - - if ( outBlock ) - *outBlock = block; - - return outErr; -} - -/*virtual*/ mdb_err -morkZone::Free(nsIMdbEnv* mev, // free block allocated earlier by Alloc() - void* inBlock) -{ - mdb_err outErr = 0; - if ( inBlock ) - { - morkEnv* ev = morkEnv::FromMdbEnv(mev); - if ( ev ) - { - this->ZoneZapRun(ev, inBlock); - outErr = ev->AsErr(); - } - else - outErr = 1; - } - - return outErr; -} - -/*virtual*/ mdb_err -morkZone::HeapAddStrongRef(nsIMdbEnv* mev) // does nothing -{ - MORK_USED_1(mev); - return 0; -} - -/*virtual*/ mdb_err -morkZone::HeapCutStrongRef(nsIMdbEnv* mev) // does nothing -{ - MORK_USED_1(mev); - return 0; -} - -// } ===== end nsIMdbHeap methods ===== - diff --git a/db/mork/src/morkZone.h b/db/mork/src/morkZone.h deleted file mode 100644 index 52409558159c..000000000000 --- a/db/mork/src/morkZone.h +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MORKZONE_ -#define _MORKZONE_ 1 - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _MORKNODE_ -#include "morkNode.h" -#endif - -#ifndef _MORKDEQUE_ -#include "morkDeque.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| CONFIG_DEBUG: do paranoid debug checks if defined. -|*/ -#ifdef MORK_DEBUG -#define morkZone_CONFIG_DEBUG 1 /* debug paranoid if defined */ -#endif /*MORK_DEBUG*/ - -/*| CONFIG_STATS: keep volume and usage statistics. -|*/ -#define morkZone_CONFIG_VOL_STATS 1 /* count space used by zone instance */ - -/*| CONFIG_ARENA: if this is defined, then the morkZone class will alloc big -**| blocks from the zone's heap, and suballocate from these. If undefined, -**| then morkZone will just pass all calls through to the zone's heap. -|*/ -#ifdef MORK_ENABLE_ZONE_ARENAS -#define morkZone_CONFIG_ARENA 1 /* be arena, if defined; otherwise no-op */ -#endif /*MORK_ENABLE_ZONE_ARENAS*/ - -/*| CONFIG_ALIGN_8: if this is defined, then the morkZone class will give -**| blocks 8 byte alignment instead of only 4 byte alignment. -|*/ -#ifdef MORK_CONFIG_ALIGN_8 -#define morkZone_CONFIG_ALIGN_8 1 /* ifdef: align to 8 bytes, otherwise 4 */ -#endif /*MORK_CONFIG_ALIGN_8*/ - -/*| CONFIG_PTR_SIZE_4: if this is defined, then the morkZone class will -**| assume sizeof(void*) == 4, so a tag slot for padding is needed. -|*/ -#ifdef MORK_CONFIG_PTR_SIZE_4 -#define morkZone_CONFIG_PTR_SIZE_4 1 /* ifdef: sizeof(void*) == 4 */ -#endif /*MORK_CONFIG_PTR_SIZE_4*/ - -/*| morkZone_USE_TAG_SLOT: if this is defined, then define slot mRun_Tag -**| in order to achieve eight byte alignment after the mRun_Next slot. -|*/ -#if defined(morkZone_CONFIG_ALIGN_8) && defined(morkZone_CONFIG_PTR_SIZE_4) -#define morkRun_USE_TAG_SLOT 1 /* need mRun_Tag slot inside morkRun */ -#define morkHunk_USE_TAG_SLOT 1 /* need mHunk_Tag slot inside morkHunk */ -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkRun_kTag ((mork_u4) 0x6D52754E ) /* ascii 'mRuN' */ - -/*| morkRun: structure used by morkZone for sized blocks -|*/ -class morkRun { - -protected: // member variable slots -#ifdef morkRun_USE_TAG_SLOT - mork_u4 mRun_Tag; // force 8 byte alignment after mRun_Next -#endif /* morkRun_USE_TAG_SLOT */ - - morkRun* mRun_Next; - -public: // pointer interpretation of mRun_Next (when inside a list): - morkRun* RunNext() const { return mRun_Next; } - void RunSetNext(morkRun* ioNext) { mRun_Next = ioNext; } - -public: // size interpretation of mRun_Next (when not inside a list): - mork_size RunSize() const { return (mork_size) ((mork_ip) mRun_Next); } - void RunSetSize(mork_size inSize) - { mRun_Next = (morkRun*) ((mork_ip) inSize); } - -public: // maintenance and testing of optional tag magic signature slot: -#ifdef morkRun_USE_TAG_SLOT - void RunInitTag() { mRun_Tag = morkRun_kTag; } - mork_bool RunGoodTag() { return ( mRun_Tag == morkRun_kTag ); } -#endif /* morkRun_USE_TAG_SLOT */ - -public: // conversion back and forth to inline block following run instance: - void* RunAsBlock() { return (((mork_u1*) this) + sizeof(morkRun)); } - - static morkRun* BlockAsRun(void* ioBlock) - { return (morkRun*) (((mork_u1*) ioBlock) - sizeof(morkRun)); } - -public: // typing & errors - static void BadRunTagError(morkEnv* ev); - static void RunSizeAlignError(morkEnv* ev); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -/*| morkOldRun: more space to record size when run is put into old free list -|*/ -class morkOldRun : public morkRun { - -protected: // need another size field when mRun_Next is used for linkage: - mdb_size mOldRun_Size; - -public: // size getter/setter - mork_size OldSize() const { return mOldRun_Size; } - void OldSetSize(mork_size inSize) { mOldRun_Size = inSize; } - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define morkHunk_kTag ((mork_u4) 0x68556E4B ) /* ascii 'hUnK' */ - -/*| morkHunk: structure used by morkZone for heap allocations. -|*/ -class morkHunk { - -protected: // member variable slots - -#ifdef morkHunk_USE_TAG_SLOT - mork_u4 mHunk_Tag; // force 8 byte alignment after mHunk_Next -#endif /* morkHunk_USE_TAG_SLOT */ - - morkHunk* mHunk_Next; - - morkRun mHunk_Run; - -public: // setters - void HunkSetNext(morkHunk* ioNext) { mHunk_Next = ioNext; } - -public: // getters - morkHunk* HunkNext() const { return mHunk_Next; } - - morkRun* HunkRun() { return &mHunk_Run; } - -public: // maintenance and testing of optional tag magic signature slot: -#ifdef morkHunk_USE_TAG_SLOT - void HunkInitTag() { mHunk_Tag = morkHunk_kTag; } - mork_bool HunkGoodTag() { return ( mHunk_Tag == morkHunk_kTag ); } -#endif /* morkHunk_USE_TAG_SLOT */ - -public: // typing & errors - static void BadHunkTagWarning(morkEnv* ev); - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -/*| kNewHunkSize: the default size for a hunk, assuming we must allocate -**| a new one whenever the free hunk list does not already have. Note this -**| number should not be changed without also considering suitable changes -**| in the related kMaxHunkWaste and kMinHunkSize constants. -|*/ -#define morkZone_kNewHunkSize ((mork_size) (64 * 1024)) /* 64K per hunk */ - -/*| kMaxFreeVolume: some number of bytes of free space in the free hunk list -**| over which we no longer want to add more free hunks to the list, for fear -**| of accumulating too much unused, fragmented free space. This should be a -**| small multiple of kNewHunkSize, say about two to four times as great, to -**| allow for no more free hunk space than fits in a handful of new hunks. -**| This strategy will let us usefuly accumulate "some" free space in the -**| free hunk list, but without accumulating "too much" free space that way. -|*/ -#define morkZone_kMaxFreeVolume (morkZone_kNewHunkSize * 3) - -/*| kMaxHunkWaste: if a current request is larger than this, and we cannot -**| satisfy the request with the current hunk, then we just allocate the -**| block from the heap without changing the current hunk. Basically this -**| number represents the largest amount of memory we are willing to waste, -**| since a block request barely less than this can cause the current hunk -**| to be retired (with any unused space wasted) as well get a new hunk. -|*/ -#define morkZone_kMaxHunkWaste ((mork_size) 4096) /* 1/16 kNewHunkSize */ - -/*| kRound*: the algorithm for rounding up allocation sizes for caching -**| in free lists works like the following. We add kRoundAdd to any size -**| requested, and then bitwise AND with kRoundMask, and this will give us -**| the smallest multiple of kRoundSize that is at least as large as the -**| requested size. Then if we rightshift this number by kRoundBits, we -**| will have the index into the mZone_FreeRuns array which will hold any -**| cache runs of that size. So 4 bits of shift gives us a granularity -**| of 16 bytes, so that free lists will hold successive runs that are -**| 16 bytes greater than the next smaller run size. If we have 256 free -**| lists of nonzero sized runs altogether, then the largest run that can -**| be cached is 4096, or 4K (since 4096 == 16 * 256). A larger run that -**| gets freed will go in to the free hunk list (or back to the heap). -|*/ -#define morkZone_kRoundBits 4 /* bits to round-up size for free lists */ -#define morkZone_kRoundSize (1 << morkZone_kRoundBits) -#define morkZone_kRoundAdd ((1 << morkZone_kRoundBits) - 1) -#define morkZone_kRoundMask (~ ((mork_ip) morkZone_kRoundAdd)) - -#define morkZone_kBuckets 256 /* number of distinct free lists */ - -/*| kMaxCachedRun: the largest run that will be stored inside a free -**| list of old zapped runs. A run larger than this cannot be put in -**| a free list, and must be allocated from the heap at need, and put -**| into the free hunk list when discarded. -|*/ -#define morkZone_kMaxCachedRun (morkZone_kBuckets * morkZone_kRoundSize) - -#define morkDerived_kZone /*i*/ 0x5A6E /* ascii 'Zn' */ - -/*| morkZone: a pooled memory allocator like an NSPR arena. The term 'zone' -**| is roughly synonymous with 'heap'. I avoid calling this class a "heap" -**| to avoid any confusion with nsIMdbHeap, and I avoid calling this class -**| an arean to avoid confusion with NSPR usage. -|*/ -class morkZone : public morkNode, public nsIMdbHeap { - -// public: // slots inherited from morkNode (meant to inform only) - // nsIMdbHeap* mNode_Heap; - - // mork_base mNode_Base; // must equal morkBase_kNode - // mork_derived mNode_Derived; // depends on specific node subclass - - // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead - // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone - // mork_able mNode_Mutable; // can this node be modified? - // mork_load mNode_Load; // is this node clean or dirty? - - // mork_uses mNode_Uses; // refcount for strong refs - // mork_refs mNode_Refs; // refcount for strong refs + weak refs - -public: // state is public because the entire Mork system is private - - nsIMdbHeap* mZone_Heap; // strong ref to heap allocating all space - - mork_size mZone_HeapVolume; // total bytes allocated from heap - mork_size mZone_BlockVolume; // total bytes in all zone blocks - mork_size mZone_RunVolume; // total bytes in all zone runs - mork_size mZone_ChipVolume; // total bytes in all zone chips - - mork_size mZone_FreeOldRunVolume; // total bytes in all used hunks - - mork_count mZone_HunkCount; // total number of used hunks - mork_count mZone_FreeOldRunCount; // total free old runs - - morkHunk* mZone_HunkList; // linked list of all used hunks - morkRun* mZone_FreeOldRunList; // linked list of free old runs - - // note mZone_At is a byte pointer for single byte address arithmetic: - mork_u1* mZone_At; // current position in most recent hunk - mork_size mZone_AtSize; // number of bytes remaining in this hunk - - // kBuckets+1 so indexes zero through kBuckets are all okay to use: - - morkRun* mZone_FreeRuns[ morkZone_kBuckets + 1 ]; - // Each piece of memory stored in list mZone_FreeRuns[ i ] has an - // allocation size equal to sizeof(morkRun) + (i * kRoundSize), so - // that callers can be given a piece of memory with (i * kRoundSize) - // bytes of writeable space while reserving the first sizeof(morkRun) - // bytes to keep track of size information for later re-use. Note - // that mZone_FreeRuns[ 0 ] is unused because no run will be zero - // bytes in size (and morkZone plans to complain about zero sizes). - -protected: // zone utilities - - mork_size zone_grow_at(morkEnv* ev, mork_size inNeededSize); - - void* zone_new_chip(morkEnv* ev, mdb_size inSize); // alloc - morkHunk* zone_new_hunk(morkEnv* ev, mdb_size inRunSize); // alloc - -// { ===== begin nsIMdbHeap methods ===== -public: - NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory - mdb_size inSize, // requested size of new memory block - void** outBlock); // memory block of inSize bytes, or nil - - NS_IMETHOD Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc() - void* inBlock); - - NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev); // does nothing - NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev); // does nothing -// } ===== end nsIMdbHeap methods ===== - -// { ===== begin morkNode interface ===== -public: // morkNode virtual methods - virtual void CloseMorkNode(morkEnv* ev); // CloseZone() only if open - virtual ~morkZone(); // assert that CloseMap() executed earlier - -public: // morkMap construction & destruction - morkZone(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioNodeHeap, - nsIMdbHeap* ioZoneHeap); - - void CloseZone(morkEnv* ev); // called by CloseMorkNode() - -public: // dynamic type identification - mork_bool IsZone() const - { return IsNode() && mNode_Derived == morkDerived_kZone; } -// } ===== end morkNode methods ===== - -// { ===== begin morkZone methods ===== -public: // chips do not know how big they are... - void* ZoneNewChip(morkEnv* ev, mdb_size inSize); // alloc - -public: // ...but runs do indeed know how big they are - void* ZoneNewRun(morkEnv* ev, mdb_size inSize); // alloc - void ZoneZapRun(morkEnv* ev, void* ioRunBody); // free - void* ZoneGrowRun(morkEnv* ev, void* ioRunBody, mdb_size inSize); // realloc - -// } ===== end morkZone methods ===== - -public: // typing & errors - static void NonZoneTypeError(morkEnv* ev); - static void NilZoneHeapError(morkEnv* ev); - static void BadZoneTagError(morkEnv* ev); -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _MORKZONE_ */ diff --git a/db/mork/src/orkinHeap.cpp b/db/mork/src/orkinHeap.cpp deleted file mode 100644 index da3776696045..000000000000 --- a/db/mork/src/orkinHeap.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -#ifndef _ORKINHEAP_ -#include "orkinHeap.h" -#endif - -#ifndef _MORKENV_ -#include "morkEnv.h" -#endif - -#include - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - - -orkinHeap::orkinHeap() // does nothing -#ifdef MORK_DEBUG_HEAP_STATS - : sHeap_AllocCount( 0 ) - , sHeap_FreeCount( 0 ) - , sHeap_BlockCount( 0 ) - - , sHeap_BlockVolume( 0 ) - , sHeap_HighWaterVolume( 0 ) - , sHeap_HighWaterTenKilo( 0 ) - , sHeap_HighWaterHundredKilo( 0 ) -#endif /*MORK_DEBUG_HEAP_STATS*/ -{ -} - -/*virtual*/ -orkinHeap::~orkinHeap() // does nothing -{ -} - -// { ===== begin nsIMdbHeap methods ===== -/*virtual*/ mdb_err -orkinHeap::Alloc(nsIMdbEnv* mev, // allocate a piece of memory - mdb_size inSize, // requested size of new memory block - void** outBlock) // memory block of inSize bytes, or nil -{ -#ifdef MORK_DEBUG_HEAP_STATS - mdb_size realSize = inSize; - inSize += 12; // sizeof(mork_u4) * 3 - ++sHeap_AllocCount; -#endif /*MORK_DEBUG_HEAP_STATS*/ - - MORK_USED_1(mev); - mdb_err outErr = 0; - void* block = malloc(inSize); - if ( !block ) - outErr = morkEnv_kOutOfMemoryError; -#ifdef MORK_DEBUG_HEAP_STATS - else - { - printf("%lx allocating %d\n", this, realSize); - mork_u4* array = (mork_u4*) block; - *array++ = (mork_u4) this; - *array++ = realSize; - *array++ = orkinHeap_kTag; - block = array; - ++sHeap_BlockCount; - mork_num blockVol = sHeap_BlockVolume + realSize; - sHeap_BlockVolume = blockVol; - if ( blockVol > sHeap_HighWaterVolume ) - { - sHeap_HighWaterVolume = blockVol; - - mork_num tenKiloVol = blockVol / (10 * 1024); - if ( tenKiloVol > sHeap_HighWaterTenKilo ) - { - sHeap_HighWaterTenKilo = tenKiloVol; - - mork_num hundredKiloVol = blockVol / (100 * 1024); - if ( hundredKiloVol > sHeap_HighWaterHundredKilo ) - sHeap_HighWaterHundredKilo = hundredKiloVol; - } - } - } -#endif /*MORK_DEBUG_HEAP_STATS*/ - - MORK_ASSERT(outBlock); - if ( outBlock ) - *outBlock = block; - return outErr; -} - -/*virtual*/ mdb_err -orkinHeap::Free(nsIMdbEnv* mev, // free block allocated earlier by Alloc() - void* inBlock) -{ -#ifdef MORK_DEBUG_HEAP_STATS - ++sHeap_FreeCount; -#endif /*MORK_DEBUG_HEAP_STATS*/ - - MORK_USED_1(mev); - MORK_ASSERT(inBlock); - if ( inBlock ) - { -#ifdef MORK_DEBUG_HEAP_STATS - morkEnv* ev = 0; //morkEnv::FromMdbEnv(mev); - mork_u4* array = (mork_u4*) inBlock; - if ( *--array != orkinHeap_kTag ) - { - if ( ev ) - ev->NewWarning("heap block tag not hEaP"); - } - mork_u4 realSize = *--array; - inBlock = --array; // skip over heap ptr too. - - printf("%lx freeing %d\n", this, realSize); - if ( sHeap_BlockCount ) - --sHeap_BlockCount; - else if ( ev ) - ev->NewWarning("sHeap_BlockCount underflow"); - - if ( sHeap_BlockVolume >= realSize ) - sHeap_BlockVolume -= realSize; - else if ( ev ) - { - sHeap_BlockVolume = 0; - ev->NewWarning("sHeap_BlockVolume underflow"); - } -#endif /*MORK_DEBUG_HEAP_STATS*/ - - free(inBlock); - } - return 0; -} - -/*virtual*/ mdb_err -orkinHeap::HeapAddStrongRef(nsIMdbEnv* ev) // does nothing -{ - MORK_USED_1(ev); - return 0; -} - -/*virtual*/ mdb_err -orkinHeap::HeapCutStrongRef(nsIMdbEnv* ev) // does nothing -{ - MORK_USED_1(ev); - return 0; -} - -// } ===== end nsIMdbHeap methods ===== - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 diff --git a/db/mork/src/orkinHeap.h b/db/mork/src/orkinHeap.h deleted file mode 100644 index d7109d579596..000000000000 --- a/db/mork/src/orkinHeap.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _ORKINHEAP_ -#define _ORKINHEAP_ 1 - -#ifndef _MDB_ -#include "mdb.h" -#endif - -#ifndef _MORK_ -#include "mork.h" -#endif - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#define orkinHeap_kTag 0x68456150 /* ascii 'hEaP' */ - -/*| orkinHeap: -|*/ -class orkinHeap : public nsIMdbHeap { // - -#ifdef MORK_DEBUG_HEAP_STATS -protected: - mork_num sHeap_AllocCount; // number of times Alloc() is called - mork_num sHeap_FreeCount; // number of times Free() is called - mork_num sHeap_BlockCount; // number of outstanding blocks - - mork_num sHeap_BlockVolume; // sum of sizes for all outstanding blocks - mork_num sHeap_HighWaterVolume; // largest value of sHeap_BlockVolume seen - mork_num sHeap_HighWaterTenKilo; // HighWaterVolume in 10K granularity - mork_num sHeap_HighWaterHundredKilo; // HighWaterVolume in 100K granularity - -public: // getters - mork_num HeapAllocCount() const { return sHeap_AllocCount; } - mork_num HeapFreeCount() const { return sHeap_FreeCount; } - mork_num HeapBlockCount() const { return sHeap_AllocCount - sHeap_FreeCount; } - - mork_num HeapBlockVolume() const { return sHeap_BlockVolume; } - mork_num HeapHighWaterVolume() const { return sHeap_HighWaterVolume; } -#endif /*MORK_DEBUG_HEAP_STATS*/ - -public: - orkinHeap(); // does nothing - virtual ~orkinHeap(); // does nothing - -private: // copying is not allowed - orkinHeap(const orkinHeap& other); - orkinHeap& operator=(const orkinHeap& other); - -public: - -// { ===== begin nsIMdbHeap methods ===== - NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory - mdb_size inSize, // requested size of new memory block - void** outBlock); // memory block of inSize bytes, or nil - - NS_IMETHOD Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc() - void* inBlock); - - NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev); // does nothing - NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev); // does nothing -// } ===== end nsIMdbHeap methods ===== - -}; - -//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 - -#endif /* _ORKINHEAP_ */ diff --git a/db/morkreader/Makefile.in b/db/morkreader/Makefile.in deleted file mode 100644 index 5dd3f4ee703d..000000000000 --- a/db/morkreader/Makefile.in +++ /dev/null @@ -1,58 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is Places code -# -# The Initial Developer of the Original Code is -# Google Inc. -# Portions created by the Initial Developer are Copyright (C) 2006 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Brian Ryner -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -DIRS = external -MODULE = morkreader -LIBRARY_NAME = morkreader_s -LIBXUL_LIBRARY = 1 -FORCE_STATIC_LIB = 1 -EXPORT_LIBRARY = 1 - - -EXPORTS = nsMorkReader.h -CPPSRCS = nsMorkReader.cpp - -include $(topsrcdir)/config/rules.mk - diff --git a/db/morkreader/external/Makefile.in b/db/morkreader/external/Makefile.in deleted file mode 100644 index 64b6f77eaa15..000000000000 --- a/db/morkreader/external/Makefile.in +++ /dev/null @@ -1,60 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is Places code -# -# The Initial Developer of the Original Code is -# Google Inc. -# Portions created by the Initial Developer are Copyright (C) 2006 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Brian Ryner -# -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = morkreader -LIBRARY_NAME = morkreader_external_s -MOZILLA_INTERNAL_API = 1 -FORCE_STATIC_LIB = 1 - - -CPPSRCS = nsMorkReader.cpp - -include $(topsrcdir)/config/rules.mk - -nsMorkReader.cpp: $(srcdir)/../nsMorkReader.cpp - $(INSTALL) $^ . - -GARBAGE += nsMorkReader.cpp diff --git a/db/morkreader/nsMorkReader.cpp b/db/morkreader/nsMorkReader.cpp deleted file mode 100644 index 1320b1398003..000000000000 --- a/db/morkreader/nsMorkReader.cpp +++ /dev/null @@ -1,579 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mork Reader. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsMorkReader.h" -#include "prio.h" -#include "nsNetUtil.h" -#include "nsVoidArray.h" - -// A FixedString implementation that can hold 2 80-character lines -class nsCLineString : public nsFixedCString -{ -public: - nsCLineString() : fixed_string_type(mStorage, sizeof(mStorage), 0) {} - explicit nsCLineString(const substring_type& str) - : fixed_string_type(mStorage, sizeof(mStorage), 0) - { - Assign(str); - } - -private: - char_type mStorage[160]; -}; - -// Convert a hex character (0-9, A-F) to its corresponding byte value. -// The character pointed to by 'c' is modified in place. -inline PRBool -ConvertChar(char *c) -{ - char c1 = *c; - if ('0' <= c1 && c1 <= '9') { - *c = c1 - '0'; - return PR_TRUE; - } - if ('A' <= c1 && c1 <= 'F') { - *c = c1 - 'A' + 10; - return PR_TRUE; - } - return PR_FALSE; -} - -// Unescape a Mork value. Mork uses $xx escaping to encode non-ASCII -// characters. Additionally, '$' and '\' are backslash-escaped. -// The result of the unescape is in returned into aResult. - -static void -MorkUnescape(const nsCSubstring &aString, nsCString &aResult) -{ - PRUint32 len = aString.Length(); - - // We optimize for speed over space here -- size the result buffer to - // the size of the source, which is an upper bound on the size of the - // unescaped string. - // FIXME: Mork assume there will never be errors - if (!EnsureStringLength(aResult, len)) { - aResult.Truncate(); - return; // out of memory. - } - - char *result = aResult.BeginWriting(); - const char *source = aString.BeginReading(); - const char *sourceEnd = source + len; - - const char *startPos = nsnull; - PRUint32 bytes; - for (; source < sourceEnd; ++source) { - char c = *source; - if (c == '\\') { - if (startPos) { - bytes = source - startPos; - memcpy(result, startPos, bytes); - result += bytes; - startPos = nsnull; - } - if (source < sourceEnd - 1) { - *(result++) = *(++source); - } - } else if (c == '$') { - if (startPos) { - bytes = source - startPos; - memcpy(result, startPos, bytes); - result += bytes; - startPos = nsnull; - } - if (source < sourceEnd - 2) { - // Would be nice to use ToInteger() here, but it currently - // requires a null-terminated string. - char c2 = *(++source); - char c3 = *(++source); - if (ConvertChar(&c2) && ConvertChar(&c3)) { - *(result++) = ((c2 << 4) | c3); - } - } - } else if (!startPos) { - startPos = source; - } - } - if (startPos) { - bytes = source - startPos; - memcpy(result, startPos, bytes); - result += bytes; - } - aResult.SetLength(result - aResult.BeginReading()); -} - -nsresult -nsMorkReader::Init() -{ - NS_ENSURE_TRUE(mValueMap.Init(), NS_ERROR_OUT_OF_MEMORY); - NS_ENSURE_TRUE(mTable.Init(), NS_ERROR_OUT_OF_MEMORY); - return NS_OK; -} - -static PLDHashOperator -DeleteStringArray(const nsCSubstring& aKey, - nsTArray *aData, - void *aUserArg) -{ - delete aData; - return PL_DHASH_NEXT; -} - -nsMorkReader::~nsMorkReader() -{ - mTable.EnumerateRead(DeleteStringArray, nsnull); -} - -struct AddColumnClosure -{ - AddColumnClosure(nsTArray *a, - nsMorkReader::IndexMap *c) - : array(a), columnMap(c), result(NS_OK) {} - - nsTArray *array; - nsMorkReader::IndexMap *columnMap; - nsresult result; -}; - -static PLDHashOperator -AddColumn(const nsCSubstring &id, nsCString name, void *userData) -{ - AddColumnClosure *closure = static_cast(userData); - nsTArray *array = closure->array; - - if (!array->AppendElement(nsMorkReader::MorkColumn(id, name)) || - !closure->columnMap->Put(id, array->Length() - 1)) { - closure->result = NS_ERROR_OUT_OF_MEMORY; - return PL_DHASH_STOP; - } - - return PL_DHASH_NEXT; -} - -nsresult -nsMorkReader::Read(nsIFile *aFile) -{ - nsCOMPtr stream = - do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID); - NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); - - nsresult rv = stream->Init(aFile, PR_RDONLY, 0, 0); - NS_ENSURE_SUCCESS(rv, rv); - - mStream = do_QueryInterface(stream); - NS_ASSERTION(mStream, "file input stream must impl nsILineInputStream"); - - nsCLineString line; - rv = ReadLine(line); - if (!line.EqualsLiteral("// ")) { - return NS_ERROR_FAILURE; // unexpected file format - } - - IndexMap columnMap; - NS_ENSURE_TRUE(columnMap.Init(), NS_ERROR_OUT_OF_MEMORY); - - while (NS_SUCCEEDED(ReadLine(line))) { - // Trim off leading spaces - PRUint32 idx = 0, len = line.Length(); - while (idx < len && line[idx] == ' ') { - ++idx; - } - if (idx >= len) { - continue; - } - - const nsCSubstring &l = Substring(line, idx); - - // Look at the line to figure out what section type this is - if (StringBeginsWith(l, NS_LITERAL_CSTRING("< <(a=c)>"))) { - // Column map. We begin by creating a hash of column id to column name. - StringMap columnNameMap; - NS_ENSURE_TRUE(columnNameMap.Init(), NS_ERROR_OUT_OF_MEMORY); - - rv = ParseMap(l, &columnNameMap); - NS_ENSURE_SUCCESS(rv, rv); - - // Now that we have the list of columns, we put them into a flat array. - // Rows will have value arrays of the same size, with indexes that - // correspond to the columns array. As we insert each column into the - // array, we also make an entry in columnMap so that we can look up the - // index given the column id. - mColumns.SetCapacity(columnNameMap.Count()); - - AddColumnClosure closure(&mColumns, &columnMap); - columnNameMap.EnumerateRead(AddColumn, &closure); - if (NS_FAILED(closure.result)) { - return closure.result; - } - } else if (StringBeginsWith(l, NS_LITERAL_CSTRING("<("))) { - // Value map - rv = ParseMap(l, &mValueMap); - NS_ENSURE_SUCCESS(rv, rv); - } else if (l[0] == '{' || l[0] == '[') { - // Table / table row - rv = ParseTable(l, columnMap); - NS_ENSURE_SUCCESS(rv, rv); - } else { - // Don't know, hopefully don't care - } - } - - return NS_OK; -} - -void -nsMorkReader::EnumerateRows(RowEnumerator aCallback, void *aUserData) const -{ - // Constify the table values - typedef const nsDataHashtable* > ConstTable; - reinterpret_cast(&mTable)->EnumerateRead(aCallback, - aUserData); -} - -// Parses a key/value map of the form -// <(k1=v1)(k2=v2)...> - -nsresult -nsMorkReader::ParseMap(const nsCSubstring &aLine, StringMap *aMap) -{ - nsCLineString line(aLine); - nsCAutoString key; - nsresult rv = NS_OK; - - // If the first line is the a=c line (column map), just skip over it. - if (StringBeginsWith(line, NS_LITERAL_CSTRING("< <(a=c)>"))) { - rv = ReadLine(line); - } - - for (; NS_SUCCEEDED(rv); rv = ReadLine(line)) { - PRUint32 idx = 0; - PRUint32 len = line.Length(); - PRUint32 tokenStart; - - while (idx < len) { - switch (line[idx++]) { - case '(': - // Beginning of a key/value pair - if (!key.IsEmpty()) { - NS_WARNING("unterminated key/value pair?"); - key.Truncate(0); - } - - tokenStart = idx; - while (idx < len && line[idx] != '=') { - ++idx; - } - key = Substring(line, tokenStart, idx - tokenStart); - break; - case '=': - { - // Beginning of the value - if (key.IsEmpty()) { - NS_WARNING("stray value"); - break; - } - - tokenStart = idx; - while (idx < len && line[idx] != ')') { - if (line[idx] == '\\') { - ++idx; // skip escaped ')' characters - } - ++idx; - } - PRUint32 tokenEnd = NS_MIN(idx, len); - ++idx; - - nsCString value; - MorkUnescape(Substring(line, tokenStart, tokenEnd - tokenStart), - value); - aMap->Put(key, value); - key.Truncate(0); - break; - } - case '>': - // End of the map. - NS_WARN_IF_FALSE(key.IsEmpty(), - "map terminates inside of key/value pair"); - return NS_OK; - } - } - } - - // We ran out of lines and the map never terminated. This probably indicates - // a parsing error. - NS_WARNING("didn't find end of key/value map"); - return NS_ERROR_FAILURE; -} - -// Parses a table row of the form [123(^45^67)..] -// (row id 123 has the value with id 67 for the column with id 45). -// A '^' prefix for a column or value references an entry in the column or -// value map. '=' is used as the separator when the value is a literal. - -nsresult -nsMorkReader::ParseTable(const nsCSubstring &aLine, const IndexMap &aColumnMap) -{ - nsCLineString line(aLine); - const PRUint32 columnCount = mColumns.Length(); // total number of columns - - PRInt32 columnIndex = -1; // column index of the cell we're parsing - // value array for the row we're parsing - nsTArray *currentRow = nsnull; - PRBool inMetaRow = PR_FALSE; - - do { - PRUint32 idx = 0; - PRUint32 len = line.Length(); - PRUint32 tokenStart, tokenEnd; - - while (idx < len) { - switch (line[idx++]) { - case '{': - // This marks the beginning of a table section. There's a lot of - // junk before the first row that looks like cell values but isn't. - // Skip to the first '['. - while (idx < len && line[idx] != '[') { - if (line[idx] == '{') { - inMetaRow = PR_TRUE; // the meta row is enclosed in { } - } else if (line[idx] == '}') { - inMetaRow = PR_FALSE; - } - ++idx; - } - break; - case '[': - { - // Start of a new row. Consume the row id, up to the first '('. - // Row edits also have a table namespace, separated from the row id - // by a colon. We don't make use of the namespace, but we need to - // make sure not to consider it part of the row id. - if (currentRow) { - NS_WARNING("unterminated row?"); - currentRow = nsnull; - } - - // Check for a '-' at the start of the id. This signifies that - // if the row already exists, we should delete all columns from it - // before adding the new values. - PRBool cutColumns; - if (idx < len && line[idx] == '-') { - cutColumns = PR_TRUE; - ++idx; - } else { - cutColumns = PR_FALSE; - } - - tokenStart = idx; - while (idx < len && - line[idx] != '(' && - line[idx] != ']' && - line[idx] != ':') { - ++idx; - } - tokenEnd = idx; - while (idx < len && line[idx] != '(' && line[idx] != ']') { - ++idx; - } - - if (inMetaRow) { - mMetaRow = NewVoidStringArray(columnCount); - NS_ENSURE_TRUE(mMetaRow, NS_ERROR_OUT_OF_MEMORY); - currentRow = mMetaRow; - } else { - const nsCSubstring& row = Substring(line, tokenStart, - tokenEnd - tokenStart); - if (!mTable.Get(row, ¤tRow)) { - currentRow = NewVoidStringArray(columnCount); - NS_ENSURE_TRUE(currentRow, NS_ERROR_OUT_OF_MEMORY); - - NS_ENSURE_TRUE(mTable.Put(row, currentRow), - NS_ERROR_OUT_OF_MEMORY); - } - } - if (cutColumns) { - // Set all of the columns to void - // (this differentiates them from columns which are empty strings). - for (PRUint32 i = 0; i < columnCount; ++i) { - currentRow->ElementAt(i).SetIsVoid(PR_TRUE); - } - } - break; - } - case ']': - // We're done with the row - currentRow = nsnull; - inMetaRow = PR_FALSE; - break; - case '(': - { - if (!currentRow) { - NS_WARNING("cell value outside of row"); - break; - } - - NS_WARN_IF_FALSE(columnIndex == -1, "unterminated cell?"); - - PRBool columnIsAtom; - if (line[idx] == '^') { - columnIsAtom = PR_TRUE; - ++idx; // this is not part of the column id, advance past it - } else { - columnIsAtom = PR_FALSE; - } - tokenStart = idx; - while (idx < len && line[idx] != '^' && line[idx] != '=') { - if (line[idx] == '\\') { - ++idx; // skip escaped characters - } - ++idx; - } - - tokenEnd = NS_MIN(idx, len); - - nsCAutoString column; - const nsCSubstring &colValue = - Substring(line, tokenStart, tokenEnd - tokenStart); - if (columnIsAtom) { - column.Assign(colValue); - } else { - MorkUnescape(colValue, column); - } - - if (!aColumnMap.Get(colValue, &columnIndex)) { - NS_WARNING("Column not in column map, discarding it"); - columnIndex = -1; - } - } - break; - case '=': - case '^': - { - if (columnIndex == -1) { - NS_WARNING("stray ^ or = marker"); - break; - } - - PRBool valueIsAtom = (line[idx - 1] == '^'); - tokenStart = idx - 1; // include the '=' or '^' marker in the value - while (idx < len && line[idx] != ')') { - if (line[idx] == '\\') { - ++idx; // skip escaped characters - } - ++idx; - } - tokenEnd = NS_MIN(idx, len); - ++idx; - - const nsCSubstring &value = - Substring(line, tokenStart, tokenEnd - tokenStart); - if (valueIsAtom) { - (*currentRow)[columnIndex] = value; - } else { - nsCAutoString value2; - MorkUnescape(value, value2); - (*currentRow)[columnIndex] = value2; - } - columnIndex = -1; - } - break; - } - } - } while (currentRow && NS_SUCCEEDED(ReadLine(line))); - - return NS_OK; -} - -nsresult -nsMorkReader::ReadLine(nsCString &aLine) -{ - PRBool res; - nsresult rv = mStream->ReadLine(aLine, &res); - NS_ENSURE_SUCCESS(rv, rv); - if (!res) { - return NS_ERROR_NOT_AVAILABLE; - } - - while (!aLine.IsEmpty() && aLine.Last() == '\\') { - // There is a continuation for this line. Read it and append. - nsCLineString line2; - rv = mStream->ReadLine(line2, &res); - NS_ENSURE_SUCCESS(rv, rv); - if (!res) { - return NS_ERROR_NOT_AVAILABLE; - } - aLine.Truncate(aLine.Length() - 1); - aLine.Append(line2); - } - - return NS_OK; -} - -void -nsMorkReader::NormalizeValue(nsCString &aValue) const -{ - PRUint32 len = aValue.Length(); - if (len == 0) { - return; - } - const nsCSubstring &str = Substring(aValue, 1, len - 1); - char c = aValue[0]; - if (c == '^') { - if (!mValueMap.Get(str, &aValue)) { - aValue.Truncate(0); - } - } else if (c == '=') { - aValue.Assign(str); - } else { - aValue.Truncate(0); - } -} - -/* static */ nsTArray* -nsMorkReader::NewVoidStringArray(PRInt32 aCount) -{ - nsAutoPtr< nsTArray > array(new nsTArray(aCount)); - NS_ENSURE_TRUE(array, nsnull); - - for (PRInt32 i = 0; i < aCount; ++i) { - nsCString *elem = array->AppendElement(); - NS_ENSURE_TRUE(elem, nsnull); - elem->SetIsVoid(PR_TRUE); - } - - return array.forget(); -} diff --git a/db/morkreader/nsMorkReader.h b/db/morkreader/nsMorkReader.h deleted file mode 100644 index aabc24e1f353..000000000000 --- a/db/morkreader/nsMorkReader.h +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mork Reader. - * - * The Initial Developer of the Original Code is - * Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsMorkReader_h_ -#define nsMorkReader_h_ - -#include "nsDataHashtable.h" -#include "nsILineInputStream.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" - -// The nsMorkReader object allows a consumer to read in a mork-format -// file and enumerate the rows that it contains. It does not provide -// any functionality for modifying mork tables. - -// References: -// http://www.mozilla.org/mailnews/arch/mork/primer.txt -// http://www.mozilla.org/mailnews/arch/mork/grammar.txt -// http://www.jwz.org/hacks/mork.pl - -class NS_STACK_CLASS nsMorkReader -{ - public: - // This string type has built-in storage for the hex string representation - // of a 32-bit row id or atom map key, plus the terminating null. - class IDString : public nsFixedCString - { - public: - IDString() : fixed_string_type(mStorage, sizeof(mStorage), 0) {} - IDString(const substring_type &str) : - fixed_string_type(mStorage, sizeof(mStorage), 0) - { - Assign(str); - } - - private: - char_type mStorage[9]; - }; - - // Hashtable key type that contains an IDString - class IDKey : public PLDHashEntryHdr - { - public: - typedef const nsCSubstring& KeyType; - typedef const nsCSubstring* KeyTypePointer; - - IDKey(KeyTypePointer aStr) : mStr(*aStr) { } - IDKey(const IDKey& toCopy) : mStr(toCopy.mStr) { } - ~IDKey() { } - - KeyType GetKey() const { return mStr; } - PRBool KeyEquals(const KeyTypePointer aKey) const - { - return mStr.Equals(*aKey); - } - - static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } - static PLDHashNumber HashKey(const KeyTypePointer aKey) - { - return HashString(*aKey); - } - enum { ALLOW_MEMMOVE = PR_FALSE }; - - private: - const IDString mStr; - }; - - // A convenience typedef for an IDKey-to-string mapping. - typedef nsDataHashtable StringMap; - - // A convenience typdef for an IDKey-to-index mapping, used for the - // column index hashtable. - typedef nsDataHashtable IndexMap; - - // A MorkColumn represents the data associated with a single table column. - struct MorkColumn - { - MorkColumn(const nsCSubstring &i, const nsCSubstring &n) - : id(i), name(n) {} - - IDString id; - nsCString name; - }; - - // Enumerator callback type for processing table rows. - // A row contains cells. Each cell specifies a column id, and the value - // for the column for that row. - // rowID is the table-unique row id - // values contains the cell values, in an order which corresponds to - // the columns returned by GetColumns(). - // You should call NormalizeValue() on any cell value that you plan to use. - // userData is the opaque pointer passed to EnumerateRows() - // The callback can return PL_DHASH_NEXT to continue enumerating, - // or PL_DHASH_STOP to stop. - typedef PLDHashOperator - (* RowEnumerator)(const nsCSubstring &rowID, - const nsTArray *values, - void *userData); - - // Initialize the importer object's data structures - nsresult Init(); - - // Read in the given mork file - // Note: currently, only single-table mork files are supported - nsresult Read(nsIFile *aFile); - - // Returns the list of columns in the current table. - const nsTArray& GetColumns() const { return mColumns; } - - // Enumerate the rows in the current table. - void EnumerateRows(RowEnumerator aCallback, void *aUserData) const; - - // Get the "meta row" for the table. Each table has at most one meta row, - // which records information about the table. Like normal rows, the - // meta row contains columns in the same order as returned by GetColumns(). - // Returns null if there is no meta row for this table. - const nsTArray* GetMetaRow() const { return mMetaRow; } - - // Normalizes the cell value (resolves references to the value map). - // aValue is modified in-place. - void NormalizeValue(nsCString &aValue) const; - - nsMorkReader() {} - ~nsMorkReader(); - -private: - // Parses a line of the file which contains key/value pairs (either - // the column map or the value map). Additional lines are read from - // mStream if the line ends mid-entry. The pairs are added to aMap. - nsresult ParseMap(const nsCSubstring &aLine, StringMap *aMap); - - // Parses a line of the file which contains a table or row definition. - // Additional lines are read from mStream of the line ends mid-row. - // An entry is added to mTable using the row ID as the key, which contains - // a column array for the row. The supplied column hash table maps from - // column id to an index in mColumns. - nsresult ParseTable(const nsCSubstring &aLine, const IndexMap &aColumnMap); - - // Reads a single logical line from mStream into aLine. - // Any continuation lines are consumed and appended to the line. - nsresult ReadLine(nsCString &aLine); - - // Create a new nsCString array and fill it with the supplied number - // of void strings. Returns null on out-of-memory. - static nsTArray* NewVoidStringArray(PRInt32 aSize); - - nsTArray mColumns; - StringMap mValueMap; - nsAutoPtr< nsTArray > mMetaRow; - nsDataHashtable< IDKey,nsTArray* > mTable; - nsCOMPtr mStream; - nsCString mEmptyString; // note: not EmptyCString() since that's not sharable -}; - -#endif // nsMorkReader_h_ diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index a2f0c0b8de75..70931c8b8a36 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4136,10 +4136,10 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, mFailedLoadType = mLoadType; if (mLSHE) { - // If we don't give mLSHE a new doc identifier here, when we go back or - // forward to another SHEntry with the same doc identifier, the error - // page will persist. - mLSHE->SetUniqueDocIdentifier(); + // Abandon mLSHE's BFCache entry and create a new one. This way, if + // we go back or forward to another SHEntry with the same doc + // identifier, the error page won't persist. + mLSHE->AbandonBFCacheEntry(); } nsCAutoString url; @@ -4412,10 +4412,10 @@ nsDocShell::LoadPage(nsISupports *aPageDescriptor, PRUint32 aDisplayType) nsresult rv = shEntryIn->Clone(getter_AddRefs(shEntry)); NS_ENSURE_SUCCESS(rv, rv); - // Give our cloned shEntry a new document identifier so this load is - // independent of all other loads. (This is important, in particular, - // for bugs 582795 and 585298.) - rv = shEntry->SetUniqueDocIdentifier(); + // Give our cloned shEntry a new bfcache entry so this load is independent + // of all other loads. (This is important, in particular, for bugs 582795 + // and 585298.) + rv = shEntry->AbandonBFCacheEntry(); NS_ENSURE_SUCCESS(rv, rv); // @@ -8403,17 +8403,15 @@ nsDocShell::InternalLoad(nsIURI * aURI, NS_SUCCEEDED(splitRv2) && curBeforeHash.Equals(newBeforeHash); - PRBool sameDocIdent = PR_FALSE; + // XXX rename + PRBool sameDocument = PR_FALSE; if (mOSHE && aSHEntry) { // We're doing a history load. - PRUint64 ourDocIdent, otherDocIdent; - mOSHE->GetDocIdentifier(&ourDocIdent); - aSHEntry->GetDocIdentifier(&otherDocIdent); - sameDocIdent = (ourDocIdent == otherDocIdent); + mOSHE->SharesDocumentWith(aSHEntry, &sameDocument); #ifdef DEBUG - if (sameDocIdent) { + if (sameDocument) { nsCOMPtr currentPostData; mOSHE->GetPostData(getter_AddRefs(currentPostData)); NS_ASSERTION(currentPostData == aPostData, @@ -8436,7 +8434,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, // The restriction tha the SHEntries in (a) must be different ensures // that history.go(0) and the like trigger full refreshes, rather than // short-circuited loads. - PRBool doShortCircuitedLoad = (sameDocIdent && mOSHE != aSHEntry) || + PRBool doShortCircuitedLoad = (sameDocument && mOSHE != aSHEntry) || (!aSHEntry && aPostData == nsnull && sameExceptHashes && !newHash.IsEmpty()); @@ -8487,7 +8485,6 @@ nsDocShell::InternalLoad(nsIURI * aURI, OnNewURI(aURI, nsnull, owner, mLoadType, PR_TRUE, PR_TRUE, PR_TRUE); nsCOMPtr postData; - PRUint64 docIdent = PRUint64(-1); nsCOMPtr cacheKey; if (mOSHE) { @@ -8501,8 +8498,12 @@ nsDocShell::InternalLoad(nsIURI * aURI, // wouldn't want here. if (aLoadType & LOAD_CMD_NORMAL) { mOSHE->GetPostData(getter_AddRefs(postData)); - mOSHE->GetDocIdentifier(&docIdent); mOSHE->GetCacheKey(getter_AddRefs(cacheKey)); + + // Link our new SHEntry to the old SHEntry's back/forward + // cache data, since the two SHEntries correspond to the + // same document. + mLSHE->AdoptBFCacheEntry(mOSHE); } } @@ -8522,11 +8523,6 @@ nsDocShell::InternalLoad(nsIURI * aURI, // cache first if (cacheKey) mOSHE->SetCacheKey(cacheKey); - - // Propagate our document identifier to the new mOSHE so that - // we'll know it's related by an anchor navigation or pushState. - if (docIdent != PRUint64(-1)) - mOSHE->SetDocIdentifier(docIdent); } /* restore previous position of scroller(s), if we're moving @@ -8570,7 +8566,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, } } - if (sameDocIdent) { + if (sameDocument) { // Set the doc's URI according to the new history entry's URI nsCOMPtr newURI; mOSHE->GetURI(getter_AddRefs(newURI)); @@ -8587,10 +8583,10 @@ nsDocShell::InternalLoad(nsIURI * aURI, // Dispatch the popstate and hashchange events, as appropriate. nsCOMPtr window = do_QueryInterface(mScriptGlobal); if (window) { - // Need the doHashchange check here since sameDocIdent is + // Need the doHashchange check here since sameDocument is // false if we're navigating to a new shentry (i.e. a aSHEntry // is null), such as when clicking a . - if (sameDocIdent || doHashchange) { + if (sameDocument || doHashchange) { window->DispatchSyncPopState(); } @@ -9420,11 +9416,11 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner, } // If the response status indicates an error, unlink this session - // history entry from any entries sharing its doc ident. + // history entry from any entries sharing its document. PRUint32 responseStatus; nsresult rv = httpChannel->GetResponseStatus(&responseStatus); if (mLSHE && NS_SUCCEEDED(rv) && responseStatus >= 400) { - mLSHE->SetUniqueDocIdentifier(); + mLSHE->AbandonBFCacheEntry(); } } } @@ -9653,9 +9649,9 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle, // It's important that this function not run arbitrary scripts after step 1 // and before completing step 5. For example, if a script called // history.back() before we completed step 5, bfcache might destroy an - // active content viewer. Since EvictContentViewers at the end of step 5 - // might run script, we can't just put a script blocker around the critical - // section. + // active content viewer. Since EvictOutOfRangeContentViewers at the end of + // step 5 might run script, we can't just put a script blocker around the + // critical section. // // Note that we completely ignore the aTitle parameter. @@ -9835,11 +9831,9 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle, NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE); - // Set the new SHEntry's document identifier, if we can. - PRUint64 ourDocIdent; - NS_ENSURE_SUCCESS(oldOSHE->GetDocIdentifier(&ourDocIdent), - NS_ERROR_FAILURE); - NS_ENSURE_SUCCESS(newSHEntry->SetDocIdentifier(ourDocIdent), + // Link the new SHEntry to the old SHEntry's BFCache entry, since the + // two entries correspond to the same document. + NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE), NS_ERROR_FAILURE); // Set the new SHEntry's title (bug 655273). @@ -9885,7 +9879,7 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle, PRInt32 curIndex = -1; rv = rootSH->GetIndex(&curIndex); if (NS_SUCCEEDED(rv) && curIndex > -1) { - internalSH->EvictContentViewers(curIndex - 1, curIndex); + internalSH->EvictOutOfRangeContentViewers(curIndex); } } diff --git a/docshell/base/nsIContentViewer.idl b/docshell/base/nsIContentViewer.idl index d8a3a638645e..fb409cb4b8d1 100644 --- a/docshell/base/nsIContentViewer.idl +++ b/docshell/base/nsIContentViewer.idl @@ -126,7 +126,7 @@ interface nsIContentViewer : nsISupports * Change the layout to view the document with page layout (like print preview), but * dynamic and editable (like Galley layout). */ - void setPageMode(in PRBool aPageMode, in nsIPrintSettings aPrintSettings); + void setPageMode(in boolean aPageMode, in nsIPrintSettings aPrintSettings); /** * Get the history entry that this viewer will save itself into when diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index c9b190f01732..e1afa1e6e93c 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -66,6 +66,7 @@ // session history #include "nsSHEntry.h" +#include "nsSHEntryShared.h" #include "nsSHistory.h" #include "nsSHTransaction.h" @@ -87,15 +88,15 @@ Initialize() nsresult rv = nsSHistory::Startup(); NS_ENSURE_SUCCESS(rv, rv); - rv = nsSHEntry::Startup(); - return rv; + nsSHEntryShared::Startup(); + return NS_OK; } static void Shutdown() { nsSHistory::Shutdown(); - nsSHEntry::Shutdown(); + nsSHEntryShared::Shutdown(); gInitialized = PR_FALSE; } diff --git a/docshell/shistory/public/Makefile.in b/docshell/shistory/public/Makefile.in index 434b098b1c90..36e14517ada2 100644 --- a/docshell/shistory/public/Makefile.in +++ b/docshell/shistory/public/Makefile.in @@ -56,6 +56,7 @@ XPIDLSRCS = \ nsISHContainer.idl \ nsISHTransaction.idl \ nsISHistoryInternal.idl \ + nsIBFCacheEntry.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/db/mork/build/nsMorkCID.h b/docshell/shistory/public/nsIBFCacheEntry.idl similarity index 74% rename from db/mork/build/nsMorkCID.h rename to docshell/shistory/public/nsIBFCacheEntry.idl index 0f314a09a9aa..99d1e371f6f7 100644 --- a/db/mork/build/nsMorkCID.h +++ b/docshell/shistory/public/nsIBFCacheEntry.idl @@ -14,13 +14,10 @@ * * The Original Code is mozilla.org code. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * - * Contributor(s): - * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), @@ -35,19 +32,16 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef nsMorkCID_h__ -#define nsMorkCID_h__ +#include "nsISupports.idl" -#include "nsISupports.h" -#include "nsIFactory.h" -#include "nsIComponentManager.h" +/** + * This interface lets you evict a document from the back/forward cache. + */ +[scriptable, uuid(a576060e-c7df-4d81-aa8c-5b52bd6ad25d)] +interface nsIBFCacheEntry : nsISupports +{ + void RemoveFromBFCacheSync(); + void RemoveFromBFCacheAsync(); -#define NS_MORK_CONTRACTID \ - "@mozilla.org/db/mork;1" - -// 36d90300-27f5-11d3-8d74-00805f8a6617 -#define NS_MORK_CID \ -{ 0x36d90300, 0x27f5, 0x11d3, \ - { 0x8d, 0x74, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0x17 } } - -#endif + readonly attribute unsigned long long ID; +}; diff --git a/docshell/shistory/public/nsISHEntry.idl b/docshell/shistory/public/nsISHEntry.idl index 155ae63e2f29..3daa1f1a0306 100644 --- a/docshell/shistory/public/nsISHEntry.idl +++ b/docshell/shistory/public/nsISHEntry.idl @@ -51,15 +51,18 @@ interface nsIInputStream; interface nsIDocShellTreeItem; interface nsISupportsArray; interface nsIStructuredCloneContainer; +interface nsIBFCacheEntry; + %{C++ struct nsIntRect; class nsDocShellEditorData; +class nsSHEntryShared; %} [ref] native nsIntRect(nsIntRect); [ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData); +[ptr] native nsSHEntryShared(nsSHEntryShared); - -[scriptable, uuid(b92d403e-f5ec-4b81-b0e3-6e6c241cef2d)] +[scriptable, uuid(6443FD72-A50F-4B8B-BB82-BB1FA04CB15D)] interface nsISHEntry : nsIHistoryEntry { /** URI for the document */ @@ -140,21 +143,6 @@ interface nsISHEntry : nsIHistoryEntry */ attribute unsigned long ID; - /** - * docIdentifier is an integer that should be the same for two entries - * attached to the same docshell if and only if the two entries are entries - * for the same document. In practice, two entries A and B will have the - * same docIdentifier if we arrived at B by clicking an anchor link in A or - * if B was created by A's calling history.pushState(). - */ - attribute unsigned long long docIdentifier; - - /** - * Changes this entry's doc identifier to a new value which is unique - * among those of all other entries. - */ - void setUniqueDocIdentifier(); - /** attribute to set and get the cache key for the entry */ attribute nsISupports cacheKey; @@ -252,6 +240,36 @@ interface nsISHEntry : nsIHistoryEntry * The history ID of the docshell. */ attribute unsigned long long docshellID; + + readonly attribute nsIBFCacheEntry BFCacheEntry; + + /** + * Does this SHEntry point to the given BFCache entry? If so, evicting + * the BFCache entry will evict the SHEntry, since the two entries + * correspond to the same document. + */ + [notxpcom, noscript] + boolean hasBFCacheEntry(in nsIBFCacheEntry aEntry); + + /** + * Adopt aEntry's BFCacheEntry, so now both this and aEntry point to + * aEntry's BFCacheEntry. + */ + void adoptBFCacheEntry(in nsISHEntry aEntry); + + /** + * Create a new BFCache entry and drop our reference to our old one. This + * call unlinks this SHEntry from any other SHEntries for its document. + */ + void abandonBFCacheEntry(); + + /** + * Does this SHEntry correspond to the same document as aEntry? This is + * true iff the two SHEntries have the same BFCacheEntry. So in + * particular, sharesDocumentWith(aEntry) is guaranteed to return true if + * it's preceeded by a call to adoptBFCacheEntry(aEntry). + */ + boolean sharesDocumentWith(in nsISHEntry aEntry); }; [scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)] @@ -264,6 +282,17 @@ interface nsISHEntryInternal : nsISupports * A number that is assigned by the sHistory when the entry is activated */ attribute unsigned long lastTouched; + + /** + * Some state, particularly that related to the back/forward cache, is + * shared between SHEntries which correspond to the same document. This + * method gets a pointer to that shared state. + * + * This shared state is the SHEntry's BFCacheEntry. So + * hasBFCacheEntry(getSharedState()) is guaranteed to return true. + */ + [noscript, notxpcom] + nsSHEntryShared getSharedState(); }; %{ C++ diff --git a/docshell/shistory/public/nsISHistoryInternal.idl b/docshell/shistory/public/nsISHistoryInternal.idl index 338acec23468..1f5b0b683659 100644 --- a/docshell/shistory/public/nsISHistoryInternal.idl +++ b/docshell/shistory/public/nsISHistoryInternal.idl @@ -57,7 +57,7 @@ struct nsTArrayDefaultAllocator; [ref] native nsDocshellIDArray(nsTArray); -[scriptable, uuid(2dede933-25e1-47a3-8f61-0127c785ea01)] +[scriptable, uuid(e27cf38e-c19f-4294-bd31-d7e0916e7fa2)] interface nsISHistoryInternal: nsISupports { /** @@ -96,20 +96,25 @@ interface nsISHistoryInternal: nsISupports */ readonly attribute nsISHistoryListener listener; - /** - * Evict content viewers until the number of content viewers per tab - * is no more than gHistoryMaxViewers. Also, count - * total number of content viewers globally and evict one if we are over - * our total max. This is always called in Show(), after we destroy - * the previous viewer. - */ - void evictContentViewers(in long previousIndex, in long index); + /** + * Evict content viewers which don't lie in the "safe" range around aIndex. + * In practice, this should leave us with no more than gHistoryMaxViewers + * viewers associated with this SHistory object. + * + * Also make sure that the total number of content viewers in all windows is + * not greater than our global max; if it is, evict viewers as appropriate. + * + * @param aIndex - The index around which the "safe" range is centered. In + * general, if you just navigated the history, aIndex should be the index + * history was navigated to. + */ + void evictOutOfRangeContentViewers(in long aIndex); /** - * Evict the content viewer associated with a session history entry + * Evict the content viewer associated with a bfcache entry * that has timed out. */ - void evictExpiredContentViewerForEntry(in nsISHEntry aEntry); + void evictExpiredContentViewerForEntry(in nsIBFCacheEntry aEntry); /** * Evict all the content viewers in this session history diff --git a/docshell/shistory/src/Makefile.in b/docshell/shistory/src/Makefile.in index e1debfbd983c..7d8eedde7983 100644 --- a/docshell/shistory/src/Makefile.in +++ b/docshell/shistory/src/Makefile.in @@ -48,10 +48,13 @@ LIBRARY_NAME = shistory_s FORCE_STATIC_LIB = 1 LIBXUL_LIBRARY = 1 +EXPORTS = nsSHEntryShared.h \ + $(NULL) CPPSRCS = nsSHEntry.cpp \ nsSHTransaction.cpp \ nsSHistory.cpp \ + nsSHEntryShared.cpp \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index 1f6c1de258b1..136b001cde61 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -36,10 +36,6 @@ * * ***** END LICENSE BLOCK ***** */ -#ifdef DEBUG_bryner -#define DEBUG_PAGE_CACHE -#endif - // Local Includes #include "nsSHEntry.h" #include "nsXPIDLString.h" @@ -48,103 +44,44 @@ #include "nsIDocShellTreeItem.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" -#include "nsAutoPtr.h" -#include "nsThreadUtils.h" -#include "nsIWebNavigation.h" #include "nsISHistory.h" #include "nsISHistoryInternal.h" #include "nsDocShellEditorData.h" -#include "nsIDocShell.h" +#include "nsSHEntryShared.h" +#include "nsILayoutHistoryState.h" +#include "nsIContentViewer.h" +#include "nsISupportsArray.h" namespace dom = mozilla::dom; -// Hardcode this to time out unused content viewers after 30 minutes -#define CONTENT_VIEWER_TIMEOUT_SECONDS 30*60 - -typedef nsExpirationTracker HistoryTrackerBase; -class HistoryTracker : public HistoryTrackerBase { -public: - // Expire cached contentviewers after 20-30 minutes in the cache. - HistoryTracker() : HistoryTrackerBase((CONTENT_VIEWER_TIMEOUT_SECONDS/2)*1000) {} - -protected: - virtual void NotifyExpired(nsSHEntry* aObj) { - RemoveObject(aObj); - aObj->Expire(); - } -}; - -static HistoryTracker *gHistoryTracker = nsnull; static PRUint32 gEntryID = 0; -static PRUint64 gEntryDocIdentifier = 0; - -nsresult nsSHEntry::Startup() -{ - gHistoryTracker = new HistoryTracker(); - return gHistoryTracker ? NS_OK : NS_ERROR_OUT_OF_MEMORY; -} - -void nsSHEntry::Shutdown() -{ - delete gHistoryTracker; - gHistoryTracker = nsnull; -} - -static void StopTrackingEntry(nsSHEntry *aEntry) -{ - if (aEntry->GetExpirationState()->IsTracked()) { - gHistoryTracker->RemoveObject(aEntry); - } -} //***************************************************************************** //*** nsSHEntry: Object Management //***************************************************************************** -nsSHEntry::nsSHEntry() +nsSHEntry::nsSHEntry() : mLoadType(0) , mID(gEntryID++) - , mDocIdentifier(gEntryDocIdentifier++) , mScrollPositionX(0) , mScrollPositionY(0) , mURIWasModified(PR_FALSE) - , mIsFrameNavigation(PR_FALSE) - , mSaveLayoutState(PR_TRUE) - , mExpired(PR_FALSE) - , mSticky(PR_TRUE) - , mDynamicallyCreated(PR_FALSE) - , mParent(nsnull) - , mViewerBounds(0, 0, 0, 0) - , mDocShellID(0) - , mLastTouched(0) { + mShared = new nsSHEntryShared(); } nsSHEntry::nsSHEntry(const nsSHEntry &other) - : mURI(other.mURI) + : mShared(other.mShared) + , mURI(other.mURI) , mReferrerURI(other.mReferrerURI) - // XXX why not copy mDocument? , mTitle(other.mTitle) , mPostData(other.mPostData) - , mLayoutHistoryState(other.mLayoutHistoryState) , mLoadType(0) // XXX why not copy? , mID(other.mID) - , mDocIdentifier(other.mDocIdentifier) , mScrollPositionX(0) // XXX why not copy? , mScrollPositionY(0) // XXX why not copy? , mURIWasModified(other.mURIWasModified) - , mIsFrameNavigation(other.mIsFrameNavigation) - , mSaveLayoutState(other.mSaveLayoutState) - , mExpired(other.mExpired) - , mSticky(PR_TRUE) - , mDynamicallyCreated(other.mDynamicallyCreated) - // XXX why not copy mContentType? - , mCacheKey(other.mCacheKey) - , mParent(other.mParent) - , mViewerBounds(0, 0, 0, 0) - , mOwner(other.mOwner) - , mDocShellID(other.mDocShellID) , mStateData(other.mStateData) { } @@ -160,37 +97,16 @@ ClearParentPtr(nsISHEntry* aEntry, void* /* aData */) nsSHEntry::~nsSHEntry() { - StopTrackingEntry(this); - - // Since we never really remove kids from SHEntrys, we need to null - // out the mParent pointers on all our kids. + // Null out the mParent pointers on all our kids. mChildren.EnumerateForwards(ClearParentPtr, nsnull); - mChildren.Clear(); - - if (mContentViewer) { - // RemoveFromBFCacheSync is virtual, so call the nsSHEntry version - // explicitly - nsSHEntry::RemoveFromBFCacheSync(); - } - - mEditorData = nsnull; - -#ifdef DEBUG - // This is not happening as far as I can tell from breakpad as of early November 2007 - nsExpirationTracker::Iterator iterator(gHistoryTracker); - nsSHEntry* elem; - while ((elem = iterator.Next()) != nsnull) { - NS_ASSERTION(elem != this, "Found dead entry still in the tracker!"); - } -#endif } //***************************************************************************** // nsSHEntry: nsISupports //***************************************************************************** -NS_IMPL_ISUPPORTS5(nsSHEntry, nsISHContainer, nsISHEntry, nsIHistoryEntry, - nsIMutationObserver, nsISHEntryInternal) +NS_IMPL_ISUPPORTS4(nsSHEntry, nsISHContainer, nsISHEntry, nsIHistoryEntry, + nsISHEntryInternal) //***************************************************************************** // nsSHEntry: nsISHEntry @@ -251,35 +167,13 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI) NS_IMETHODIMP nsSHEntry::SetContentViewer(nsIContentViewer *aViewer) { - NS_PRECONDITION(!aViewer || !mContentViewer, "SHEntry already contains viewer"); - - if (mContentViewer || !aViewer) { - DropPresentationState(); - } - - mContentViewer = aViewer; - - if (mContentViewer) { - gHistoryTracker->AddObject(this); - - nsCOMPtr domDoc; - mContentViewer->GetDOMDocument(getter_AddRefs(domDoc)); - // Store observed document in strong pointer in case it is removed from - // the contentviewer - mDocument = do_QueryInterface(domDoc); - if (mDocument) { - mDocument->SetBFCacheEntry(this); - mDocument->AddMutationObserver(this); - } - } - - return NS_OK; + return mShared->SetContentViewer(aViewer); } NS_IMETHODIMP nsSHEntry::GetContentViewer(nsIContentViewer **aResult) { - *aResult = mContentViewer; + *aResult = mShared->mContentViewer; NS_IF_ADDREF(*aResult); return NS_OK; } @@ -319,14 +213,14 @@ nsSHEntry::GetAnyContentViewer(nsISHEntry **aOwnerEntry, NS_IMETHODIMP nsSHEntry::SetSticky(PRBool aSticky) { - mSticky = aSticky; + mShared->mSticky = aSticky; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetSticky(PRBool *aSticky) { - *aSticky = mSticky; + *aSticky = mShared->mSticky; return NS_OK; } @@ -365,16 +259,18 @@ NS_IMETHODIMP nsSHEntry::SetPostData(nsIInputStream* aPostData) NS_IMETHODIMP nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult) { - *aResult = mLayoutHistoryState; + *aResult = mShared->mLayoutHistoryState; NS_IF_ADDREF(*aResult); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState) { - mLayoutHistoryState = aState; - if (mLayoutHistoryState) - mLayoutHistoryState->SetScrollPositionOnly(!mSaveLayoutState); + mShared->mLayoutHistoryState = aState; + if (mShared->mLayoutHistoryState) { + mShared->mLayoutHistoryState-> + SetScrollPositionOnly(!mShared->mSaveLayoutState); + } return NS_OK; } @@ -403,91 +299,73 @@ NS_IMETHODIMP nsSHEntry::SetID(PRUint32 aID) return NS_OK; } -NS_IMETHODIMP nsSHEntry::GetDocIdentifier(PRUint64 * aResult) +nsSHEntryShared* nsSHEntry::GetSharedState() { - *aResult = mDocIdentifier; - return NS_OK; -} - -NS_IMETHODIMP nsSHEntry::SetDocIdentifier(PRUint64 aDocIdentifier) -{ - // This ensures that after a session restore, gEntryDocIdentifier is greater - // than all SHEntries' docIdentifiers, which ensures that we'll never repeat - // a doc identifier. - if (aDocIdentifier >= gEntryDocIdentifier) - gEntryDocIdentifier = aDocIdentifier + 1; - - mDocIdentifier = aDocIdentifier; - return NS_OK; -} - -NS_IMETHODIMP nsSHEntry::SetUniqueDocIdentifier() -{ - mDocIdentifier = gEntryDocIdentifier++; - return NS_OK; + return mShared; } NS_IMETHODIMP nsSHEntry::GetIsSubFrame(PRBool * aFlag) { - *aFlag = mIsFrameNavigation; + *aFlag = mShared->mIsFrameNavigation; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetIsSubFrame(PRBool aFlag) { - mIsFrameNavigation = aFlag; + mShared->mIsFrameNavigation = aFlag; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetCacheKey(nsISupports** aResult) { - *aResult = mCacheKey; + *aResult = mShared->mCacheKey; NS_IF_ADDREF(*aResult); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetCacheKey(nsISupports* aCacheKey) { - mCacheKey = aCacheKey; + mShared->mCacheKey = aCacheKey; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetSaveLayoutStateFlag(PRBool * aFlag) { - *aFlag = mSaveLayoutState; + *aFlag = mShared->mSaveLayoutState; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetSaveLayoutStateFlag(PRBool aFlag) { - mSaveLayoutState = aFlag; - if (mLayoutHistoryState) - mLayoutHistoryState->SetScrollPositionOnly(!aFlag); + mShared->mSaveLayoutState = aFlag; + if (mShared->mLayoutHistoryState) { + mShared->mLayoutHistoryState->SetScrollPositionOnly(!aFlag); + } return NS_OK; } NS_IMETHODIMP nsSHEntry::GetExpirationStatus(PRBool * aFlag) { - *aFlag = mExpired; + *aFlag = mShared->mExpired; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetExpirationStatus(PRBool aFlag) { - mExpired = aFlag; + mShared->mExpired = aFlag; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetContentType(nsACString& aContentType) { - aContentType = mContentType; + aContentType = mShared->mContentType; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetContentType(const nsACString& aContentType) { - mContentType = aContentType; + mShared->mContentType = aContentType; return NS_OK; } @@ -502,26 +380,27 @@ nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, mURI = aURI; mTitle = aTitle; mPostData = aInputStream; - mCacheKey = aCacheKey; - mContentType = aContentType; - mOwner = aOwner; - mDocShellID = aDocShellID; - mDynamicallyCreated = aDynamicCreation; // Set the LoadType by default to loadHistory during creation mLoadType = (PRUint32) nsIDocShellLoadInfo::loadHistory; + mShared->mCacheKey = aCacheKey; + mShared->mContentType = aContentType; + mShared->mOwner = aOwner; + mShared->mDocShellID = aDocShellID; + mShared->mDynamicallyCreated = aDynamicCreation; + // By default all entries are set false for subframe flag. // nsDocShell::CloneAndReplace() which creates entries for // all subframe navigations, sets the flag to true. - mIsFrameNavigation = PR_FALSE; + mShared->mIsFrameNavigation = PR_FALSE; // By default we save LayoutHistoryState - mSaveLayoutState = PR_TRUE; - mLayoutHistoryState = aLayoutHistoryState; + mShared->mSaveLayoutState = PR_TRUE; + mShared->mLayoutHistoryState = aLayoutHistoryState; //By default the page is not expired - mExpired = PR_FALSE; + mShared->mExpired = PR_FALSE; return NS_OK; } @@ -530,8 +409,6 @@ NS_IMETHODIMP nsSHEntry::Clone(nsISHEntry ** aResult) { *aResult = new nsSHEntry(*this); - if (!*aResult) - return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*aResult); return NS_OK; } @@ -540,7 +417,7 @@ NS_IMETHODIMP nsSHEntry::GetParent(nsISHEntry ** aResult) { NS_ENSURE_ARG_POINTER(aResult); - *aResult = mParent; + *aResult = mShared->mParent; NS_IF_ADDREF(*aResult); return NS_OK; } @@ -553,49 +430,95 @@ nsSHEntry::SetParent(nsISHEntry * aParent) * * XXX this method should not be scriptable if this is the case!! */ - mParent = aParent; + mShared->mParent = aParent; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetWindowState(nsISupports *aState) { - mWindowState = aState; + mShared->mWindowState = aState; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetWindowState(nsISupports **aState) { - NS_IF_ADDREF(*aState = mWindowState); + NS_IF_ADDREF(*aState = mShared->mWindowState); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetViewerBounds(const nsIntRect &aBounds) { - mViewerBounds = aBounds; + mShared->mViewerBounds = aBounds; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetViewerBounds(nsIntRect &aBounds) { - aBounds = mViewerBounds; + aBounds = mShared->mViewerBounds; return NS_OK; } NS_IMETHODIMP nsSHEntry::GetOwner(nsISupports **aOwner) { - NS_IF_ADDREF(*aOwner = mOwner); + NS_IF_ADDREF(*aOwner = mShared->mOwner); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetOwner(nsISupports *aOwner) { - mOwner = aOwner; + mShared->mOwner = aOwner; + return NS_OK; +} + +NS_IMETHODIMP +nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry **aEntry) +{ + NS_ENSURE_ARG_POINTER(aEntry); + NS_IF_ADDREF(*aEntry = mShared); + return NS_OK; +} + +PRBool +nsSHEntry::HasBFCacheEntry(nsIBFCacheEntry *aEntry) +{ + return static_cast(mShared) == aEntry; +} + +NS_IMETHODIMP +nsSHEntry::AdoptBFCacheEntry(nsISHEntry *aEntry) +{ + nsCOMPtr shEntry = do_QueryInterface(aEntry); + NS_ENSURE_STATE(shEntry); + + nsSHEntryShared *shared = shEntry->GetSharedState(); + NS_ENSURE_STATE(shared); + + mShared = shared; + return NS_OK; +} + +NS_IMETHODIMP +nsSHEntry::SharesDocumentWith(nsISHEntry *aEntry, PRBool *aOut) +{ + NS_ENSURE_ARG_POINTER(aOut); + + nsCOMPtr internal = do_QueryInterface(aEntry); + NS_ENSURE_STATE(internal); + + *aOut = mShared == internal->GetSharedState(); + return NS_OK; +} + +NS_IMETHODIMP +nsSHEntry::AbandonBFCacheEntry() +{ + mShared = nsSHEntryShared::Duplicate(mShared); return NS_OK; } @@ -753,256 +676,77 @@ NS_IMETHODIMP nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) { NS_ASSERTION(aShell, "Null child shell added to history entry"); - mChildShells.AppendObject(aShell); + mShared->mChildShells.AppendObject(aShell); return NS_OK; } NS_IMETHODIMP nsSHEntry::ChildShellAt(PRInt32 aIndex, nsIDocShellTreeItem **aShell) { - NS_IF_ADDREF(*aShell = mChildShells.SafeObjectAt(aIndex)); + NS_IF_ADDREF(*aShell = mShared->mChildShells.SafeObjectAt(aIndex)); return NS_OK; } NS_IMETHODIMP nsSHEntry::ClearChildShells() { - mChildShells.Clear(); + mShared->mChildShells.Clear(); return NS_OK; } NS_IMETHODIMP nsSHEntry::GetRefreshURIList(nsISupportsArray **aList) { - NS_IF_ADDREF(*aList = mRefreshURIList); + NS_IF_ADDREF(*aList = mShared->mRefreshURIList); return NS_OK; } NS_IMETHODIMP nsSHEntry::SetRefreshURIList(nsISupportsArray *aList) { - mRefreshURIList = aList; + mShared->mRefreshURIList = aList; return NS_OK; } NS_IMETHODIMP nsSHEntry::SyncPresentationState() { - if (mContentViewer && mWindowState) { - // If we have a content viewer and a window state, we should be ok. - return NS_OK; - } - - DropPresentationState(); - - return NS_OK; + return mShared->SyncPresentationState(); } -void -nsSHEntry::DropPresentationState() -{ - nsRefPtr kungFuDeathGrip = this; - - if (mDocument) { - mDocument->SetBFCacheEntry(nsnull); - mDocument->RemoveMutationObserver(this); - mDocument = nsnull; - } - if (mContentViewer) - mContentViewer->ClearHistoryEntry(); - - StopTrackingEntry(this); - mContentViewer = nsnull; - mSticky = PR_TRUE; - mWindowState = nsnull; - mViewerBounds.SetRect(0, 0, 0, 0); - mChildShells.Clear(); - mRefreshURIList = nsnull; - mEditorData = nsnull; -} - -void -nsSHEntry::Expire() -{ - // This entry has timed out. If we still have a content viewer, we need to - // get it evicted. - if (!mContentViewer) - return; - nsCOMPtr container; - mContentViewer->GetContainer(getter_AddRefs(container)); - nsCOMPtr treeItem = do_QueryInterface(container); - if (!treeItem) - return; - // We need to find the root DocShell since only that object has an - // SHistory and we need the SHistory to evict content viewers - nsCOMPtr root; - treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root)); - nsCOMPtr webNav = do_QueryInterface(root); - nsCOMPtr history; - webNav->GetSessionHistory(getter_AddRefs(history)); - nsCOMPtr historyInt = do_QueryInterface(history); - if (!historyInt) - return; - historyInt->EvictExpiredContentViewerForEntry(this); -} - -//***************************************************************************** -// nsSHEntry: nsIMutationObserver -//***************************************************************************** - -void -nsSHEntry::NodeWillBeDestroyed(const nsINode* aNode) -{ - NS_NOTREACHED("Document destroyed while we're holding a strong ref to it"); -} - -void -nsSHEntry::CharacterDataWillChange(nsIDocument* aDocument, - nsIContent* aContent, - CharacterDataChangeInfo* aInfo) -{ -} - -void -nsSHEntry::CharacterDataChanged(nsIDocument* aDocument, - nsIContent* aContent, - CharacterDataChangeInfo* aInfo) -{ - RemoveFromBFCacheAsync(); -} - -void -nsSHEntry::AttributeWillChange(nsIDocument* aDocument, - dom::Element* aContent, - PRInt32 aNameSpaceID, - nsIAtom* aAttribute, - PRInt32 aModType) -{ -} - -void -nsSHEntry::AttributeChanged(nsIDocument* aDocument, - dom::Element* aElement, - PRInt32 aNameSpaceID, - nsIAtom* aAttribute, - PRInt32 aModType) -{ - RemoveFromBFCacheAsync(); -} - -void -nsSHEntry::ContentAppended(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aFirstNewContent, - PRInt32 /* unused */) -{ - RemoveFromBFCacheAsync(); -} - -void -nsSHEntry::ContentInserted(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 /* unused */) -{ - RemoveFromBFCacheAsync(); -} - -void -nsSHEntry::ContentRemoved(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInContainer, - nsIContent* aPreviousSibling) -{ - RemoveFromBFCacheAsync(); -} - -void -nsSHEntry::ParentChainChanged(nsIContent *aContent) -{ -} - -class DestroyViewerEvent : public nsRunnable -{ -public: - DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument) - : mViewer(aViewer), - mDocument(aDocument) - {} - - NS_IMETHOD Run() - { - if (mViewer) - mViewer->Destroy(); - return NS_OK; - } - - nsCOMPtr mViewer; - nsCOMPtr mDocument; -}; - void nsSHEntry::RemoveFromBFCacheSync() { - NS_ASSERTION(mContentViewer && mDocument, - "we're not in the bfcache!"); - - nsCOMPtr viewer = mContentViewer; - DropPresentationState(); - - // Warning! The call to DropPresentationState could have dropped the last - // reference to this nsSHEntry, so no accessing members beyond here. - - if (viewer) { - viewer->Destroy(); - } + mShared->RemoveFromBFCacheSync(); } void nsSHEntry::RemoveFromBFCacheAsync() { - NS_ASSERTION(mContentViewer && mDocument, - "we're not in the bfcache!"); - - // Release the reference to the contentviewer asynchronously so that the - // document doesn't get nuked mid-mutation. - - nsCOMPtr evt = - new DestroyViewerEvent(mContentViewer, mDocument); - nsresult rv = NS_DispatchToCurrentThread(evt); - if (NS_FAILED(rv)) { - NS_WARNING("failed to dispatch DestroyViewerEvent"); - } - else { - // Drop presentation. Also ensures that we don't post more then one - // PLEvent. Only do this if we succeeded in posting the event since - // otherwise the document could be torn down mid mutation causing crashes. - DropPresentationState(); - } - // Warning! The call to DropPresentationState could have dropped the last - // reference to this nsSHEntry, so no accessing members beyond here. + mShared->RemoveFromBFCacheAsync(); } nsDocShellEditorData* nsSHEntry::ForgetEditorData() { - return mEditorData.forget(); + // XXX jlebar Check how this is used. + return mShared->mEditorData.forget(); } void nsSHEntry::SetEditorData(nsDocShellEditorData* aData) { - NS_ASSERTION(!(aData && mEditorData), + NS_ASSERTION(!(aData && mShared->mEditorData), "We're going to overwrite an owning ref!"); - if (mEditorData != aData) - mEditorData = aData; + if (mShared->mEditorData != aData) { + mShared->mEditorData = aData; + } } PRBool nsSHEntry::HasDetachedEditor() { - return mEditorData != nsnull; + return mShared->mEditorData != nsnull; } NS_IMETHODIMP @@ -1023,7 +767,7 @@ nsSHEntry::SetStateData(nsIStructuredCloneContainer *aContainer) NS_IMETHODIMP nsSHEntry::IsDynamicallyAdded(PRBool* aAdded) { - *aAdded = mDynamicallyCreated; + *aAdded = mShared->mDynamicallyCreated; return NS_OK; } @@ -1046,14 +790,14 @@ nsSHEntry::HasDynamicallyAddedChild(PRBool* aAdded) NS_IMETHODIMP nsSHEntry::GetDocshellID(PRUint64* aID) { - *aID = mDocShellID; + *aID = mShared->mDocShellID; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetDocshellID(PRUint64 aID) { - mDocShellID = aID; + mShared->mDocShellID = aID; return NS_OK; } @@ -1061,14 +805,13 @@ nsSHEntry::SetDocshellID(PRUint64 aID) NS_IMETHODIMP nsSHEntry::GetLastTouched(PRUint32 *aLastTouched) { - *aLastTouched = mLastTouched; + *aLastTouched = mShared->mLastTouched; return NS_OK; } NS_IMETHODIMP nsSHEntry::SetLastTouched(PRUint32 aLastTouched) { - mLastTouched = aLastTouched; + mShared->mLastTouched = aLastTouched; return NS_OK; } - diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h index cd44eb0d8e3c..ded9c796cadd 100644 --- a/docshell/shistory/src/nsSHEntry.h +++ b/docshell/shistory/src/nsSHEntry.h @@ -42,28 +42,21 @@ // Helper Classes #include "nsCOMPtr.h" +#include "nsAutoPtr.h" #include "nsCOMArray.h" #include "nsString.h" -#include "nsAutoPtr.h" // Interfaces needed -#include "nsIContentViewer.h" #include "nsIInputStream.h" -#include "nsILayoutHistoryState.h" #include "nsISHEntry.h" #include "nsISHContainer.h" #include "nsIURI.h" -#include "nsIEnumerator.h" #include "nsIHistoryEntry.h" -#include "nsRect.h" -#include "nsISupportsArray.h" -#include "nsIMutationObserver.h" -#include "nsExpirationTracker.h" -#include "nsDocShellEditorData.h" + +class nsSHEntryShared; class nsSHEntry : public nsISHEntry, public nsISHContainer, - public nsIMutationObserver, public nsISHEntryInternal { public: @@ -75,51 +68,30 @@ public: NS_DECL_NSISHENTRY NS_DECL_NSISHENTRYINTERNAL NS_DECL_NSISHCONTAINER - NS_DECL_NSIMUTATIONOBSERVER void DropPresentationState(); - void Expire(); - - nsExpirationState *GetExpirationState() { return &mExpirationState; } - static nsresult Startup(); static void Shutdown(); private: ~nsSHEntry(); - nsCOMPtr mURI; - nsCOMPtr mReferrerURI; - nsCOMPtr mContentViewer; - nsCOMPtr mDocument; // document currently being observed - nsString mTitle; - nsCOMPtr mPostData; - nsCOMPtr mLayoutHistoryState; - nsCOMArray mChildren; - PRUint32 mLoadType; - PRUint32 mID; - PRInt64 mDocIdentifier; - PRInt32 mScrollPositionX; - PRInt32 mScrollPositionY; - PRPackedBool mURIWasModified; - PRPackedBool mIsFrameNavigation; - PRPackedBool mSaveLayoutState; - PRPackedBool mExpired; - PRPackedBool mSticky; - PRPackedBool mDynamicallyCreated; - nsCString mContentType; - nsCOMPtr mCacheKey; - nsISHEntry * mParent; // weak reference - nsCOMPtr mWindowState; - nsIntRect mViewerBounds; - nsCOMArray mChildShells; - nsCOMPtr mRefreshURIList; - nsCOMPtr mOwner; - nsExpirationState mExpirationState; - nsAutoPtr mEditorData; - PRUint64 mDocShellID; - PRUint32 mLastTouched; + // We share the state in here with other SHEntries which correspond to the + // same document. + nsRefPtr mShared; + + // See nsSHEntry.idl for comments on these members. + nsCOMPtr mURI; + nsCOMPtr mReferrerURI; + nsString mTitle; + nsCOMPtr mPostData; + PRUint32 mLoadType; + PRUint32 mID; + PRInt32 mScrollPositionX; + PRInt32 mScrollPositionY; + nsCOMArray mChildren; + PRPackedBool mURIWasModified; nsCOMPtr mStateData; }; diff --git a/docshell/shistory/src/nsSHEntryShared.cpp b/docshell/shistory/src/nsSHEntryShared.cpp new file mode 100644 index 000000000000..02723ae62bce --- /dev/null +++ b/docshell/shistory/src/nsSHEntryShared.cpp @@ -0,0 +1,400 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla.org code. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Justin Lebar + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsSHEntryShared.h" +#include "nsISHistory.h" +#include "nsISHistoryInternal.h" +#include "nsIDocument.h" +#include "nsIWebNavigation.h" +#include "nsIContentViewer.h" +#include "nsIDocShellTreeItem.h" +#include "nsISupportsArray.h" +#include "nsDocShellEditorData.h" +#include "nsThreadUtils.h" +#include "nsILayoutHistoryState.h" +#include "prprf.h" + +namespace dom = mozilla::dom; + +namespace { + +PRUint64 gSHEntrySharedID = 0; + +} // anonymous namespace + +// Hardcode this to time out unused content viewers after 30 minutes +// XXX jlebar shouldn't this be a pref? +#define CONTENT_VIEWER_TIMEOUT_SECONDS (30*60) + +typedef nsExpirationTracker HistoryTrackerBase; +class HistoryTracker : public HistoryTrackerBase { +public: + // Expire cached contentviewers after 20-30 minutes in the cache. + HistoryTracker() + : HistoryTrackerBase(1000 * CONTENT_VIEWER_TIMEOUT_SECONDS / 2) + { + } + +protected: + virtual void NotifyExpired(nsSHEntryShared *aObj) { + RemoveObject(aObj); + aObj->Expire(); + } +}; + +static HistoryTracker *gHistoryTracker = nsnull; + +void +nsSHEntryShared::Startup() +{ + gHistoryTracker = new HistoryTracker(); +} + +void +nsSHEntryShared::Shutdown() +{ + delete gHistoryTracker; + gHistoryTracker = nsnull; +} + +nsSHEntryShared::nsSHEntryShared() + : mDocShellID(0) + , mParent(nsnull) + , mIsFrameNavigation(PR_FALSE) + , mSaveLayoutState(PR_TRUE) + , mSticky(PR_TRUE) + , mDynamicallyCreated(PR_FALSE) + , mLastTouched(0) + , mID(gSHEntrySharedID++) + , mExpired(PR_FALSE) + , mViewerBounds(0, 0, 0, 0) +{ +} + +nsSHEntryShared::~nsSHEntryShared() +{ + RemoveFromExpirationTracker(); + +#ifdef DEBUG + // Check that we're not still on track to expire. We shouldn't be, because + // we just removed ourselves! + nsExpirationTracker::Iterator + iterator(gHistoryTracker); + + nsSHEntryShared *elem; + while ((elem = iterator.Next()) != nsnull) { + NS_ASSERTION(elem != this, "Found dead entry still in the tracker!"); + } +#endif + + if (mContentViewer) { + RemoveFromBFCacheSync(); + } +} + +NS_IMPL_ISUPPORTS2(nsSHEntryShared, nsIBFCacheEntry, nsIMutationObserver) + +already_AddRefed +nsSHEntryShared::Duplicate(nsSHEntryShared *aEntry) +{ + nsRefPtr newEntry = new nsSHEntryShared(); + + newEntry->mDocShellID = aEntry->mDocShellID; + newEntry->mChildShells.AppendObjects(aEntry->mChildShells); + newEntry->mOwner = aEntry->mOwner; + newEntry->mParent = aEntry->mParent; + newEntry->mContentType.Assign(aEntry->mContentType); + newEntry->mIsFrameNavigation = aEntry->mIsFrameNavigation; + newEntry->mSaveLayoutState = aEntry->mSaveLayoutState; + newEntry->mSticky = aEntry->mSticky; + newEntry->mDynamicallyCreated = aEntry->mDynamicallyCreated; + newEntry->mCacheKey = aEntry->mCacheKey; + newEntry->mLastTouched = aEntry->mLastTouched; + + return newEntry.forget(); +} + +void nsSHEntryShared::RemoveFromExpirationTracker() +{ + if (GetExpirationState()->IsTracked()) { + gHistoryTracker->RemoveObject(this); + } +} + +nsresult +nsSHEntryShared::SyncPresentationState() +{ + if (mContentViewer && mWindowState) { + // If we have a content viewer and a window state, we should be ok. + return NS_OK; + } + + DropPresentationState(); + + return NS_OK; +} + +void +nsSHEntryShared::DropPresentationState() +{ + nsRefPtr kungFuDeathGrip = this; + + if (mDocument) { + mDocument->SetBFCacheEntry(nsnull); + mDocument->RemoveMutationObserver(this); + mDocument = nsnull; + } + if (mContentViewer) { + mContentViewer->ClearHistoryEntry(); + } + + RemoveFromExpirationTracker(); + mContentViewer = nsnull; + mSticky = PR_TRUE; + mWindowState = nsnull; + mViewerBounds.SetRect(0, 0, 0, 0); + mChildShells.Clear(); + mRefreshURIList = nsnull; + mEditorData = nsnull; +} + +void +nsSHEntryShared::Expire() +{ + // This entry has timed out. If we still have a content viewer, we need to + // evict it. + if (!mContentViewer) { + return; + } + nsCOMPtr container; + mContentViewer->GetContainer(getter_AddRefs(container)); + nsCOMPtr treeItem = do_QueryInterface(container); + if (!treeItem) { + return; + } + // We need to find the root DocShell since only that object has an + // SHistory and we need the SHistory to evict content viewers + nsCOMPtr root; + treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root)); + nsCOMPtr webNav = do_QueryInterface(root); + nsCOMPtr history; + webNav->GetSessionHistory(getter_AddRefs(history)); + nsCOMPtr historyInt = do_QueryInterface(history); + if (!historyInt) { + return; + } + historyInt->EvictExpiredContentViewerForEntry(this); +} + +nsresult +nsSHEntryShared::SetContentViewer(nsIContentViewer *aViewer) +{ + NS_PRECONDITION(!aViewer || !mContentViewer, + "SHEntryShared already contains viewer"); + + if (mContentViewer || !aViewer) { + DropPresentationState(); + } + + mContentViewer = aViewer; + + if (mContentViewer) { + gHistoryTracker->AddObject(this); + + nsCOMPtr domDoc; + mContentViewer->GetDOMDocument(getter_AddRefs(domDoc)); + // Store observed document in strong pointer in case it is removed from + // the contentviewer + mDocument = do_QueryInterface(domDoc); + if (mDocument) { + mDocument->SetBFCacheEntry(this); + mDocument->AddMutationObserver(this); + } + } + + return NS_OK; +} + +nsresult +nsSHEntryShared::RemoveFromBFCacheSync() +{ + NS_ASSERTION(mContentViewer && mDocument, + "we're not in the bfcache!"); + + nsCOMPtr viewer = mContentViewer; + DropPresentationState(); + + // Warning! The call to DropPresentationState could have dropped the last + // reference to this object, so don't access members beyond here. + + if (viewer) { + viewer->Destroy(); + } + + return NS_OK; +} + +class DestroyViewerEvent : public nsRunnable +{ +public: + DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument) + : mViewer(aViewer), + mDocument(aDocument) + {} + + NS_IMETHOD Run() + { + if (mViewer) { + mViewer->Destroy(); + } + return NS_OK; + } + + nsCOMPtr mViewer; + nsCOMPtr mDocument; +}; + +nsresult +nsSHEntryShared::RemoveFromBFCacheAsync() +{ + NS_ASSERTION(mContentViewer && mDocument, + "we're not in the bfcache!"); + + // Release the reference to the contentviewer asynchronously so that the + // document doesn't get nuked mid-mutation. + + nsCOMPtr evt = + new DestroyViewerEvent(mContentViewer, mDocument); + nsresult rv = NS_DispatchToCurrentThread(evt); + if (NS_FAILED(rv)) { + NS_WARNING("failed to dispatch DestroyViewerEvent"); + } else { + // Drop presentation. Only do this if we succeeded in posting the event + // since otherwise the document could be torn down mid-mutation, causing + // crashes. + DropPresentationState(); + } + + // Careful! The call to DropPresentationState could have dropped the last + // reference to this nsSHEntryShared, so don't access members beyond here. + + return NS_OK; +} + +nsresult +nsSHEntryShared::GetID(PRUint64 *aID) +{ + *aID = mID; + return NS_OK; +} + +//***************************************************************************** +// nsSHEntryShared: nsIMutationObserver +//***************************************************************************** + +void +nsSHEntryShared::NodeWillBeDestroyed(const nsINode* aNode) +{ + NS_NOTREACHED("Document destroyed while we're holding a strong ref to it"); +} + +void +nsSHEntryShared::CharacterDataWillChange(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ +} + +void +nsSHEntryShared::CharacterDataChanged(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ + RemoveFromBFCacheAsync(); +} + +void +nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument, + dom::Element* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType) +{ +} + +void +nsSHEntryShared::AttributeChanged(nsIDocument* aDocument, + dom::Element* aElement, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType) +{ + RemoveFromBFCacheAsync(); +} + +void +nsSHEntryShared::ContentAppended(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aFirstNewContent, + PRInt32 /* unused */) +{ + RemoveFromBFCacheAsync(); +} + +void +nsSHEntryShared::ContentInserted(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 /* unused */) +{ + RemoveFromBFCacheAsync(); +} + +void +nsSHEntryShared::ContentRemoved(nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer, + nsIContent* aPreviousSibling) +{ + RemoveFromBFCacheAsync(); +} + +void +nsSHEntryShared::ParentChainChanged(nsIContent *aContent) +{ +} diff --git a/docshell/shistory/src/nsSHEntryShared.h b/docshell/shistory/src/nsSHEntryShared.h new file mode 100644 index 000000000000..e1e2808ebaed --- /dev/null +++ b/docshell/shistory/src/nsSHEntryShared.h @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla.org code. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Justin Lebar + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsSHEntryShared_h__ +#define nsSHEntryShared_h__ + +#include "nsCOMPtr.h" +#include "nsAutoPtr.h" +#include "nsCOMArray.h" +#include "nsIBFCacheEntry.h" +#include "nsIMutationObserver.h" +#include "nsExpirationTracker.h" +#include "nsRect.h" + +class nsSHEntry; +class nsISHEntry; +class nsIDocument; +class nsIContentViewer; +class nsIDocShellTreeItem; +class nsILayoutHistoryState; +class nsISupportsArray; +class nsDocShellEditorData; + +// A document may have multiple SHEntries, either due to hash navigations or +// calls to history.pushState. SHEntries corresponding to the same document +// share many members; in particular, they share state related to the +// back/forward cache. +// +// nsSHEntryShared is the vehicle for this sharing. +class nsSHEntryShared : public nsIBFCacheEntry, + public nsIMutationObserver +{ + public: + static void Startup(); + static void Shutdown(); + + nsSHEntryShared(); + ~nsSHEntryShared(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMUTATIONOBSERVER + NS_DECL_NSIBFCACHEENTRY + + private: + friend class nsSHEntry; + + friend class HistoryTracker; + friend class nsExpirationTracker; + nsExpirationState *GetExpirationState() { return &mExpirationState; } + + static already_AddRefed Duplicate(nsSHEntryShared *aEntry); + void SetDocIdentifier(PRUint64 aDocIdentifier); + + void RemoveFromExpirationTracker(); + void Expire(); + nsresult SyncPresentationState(); + void DropPresentationState(); + + nsresult SetContentViewer(nsIContentViewer *aViewer); + + // See nsISHEntry.idl for an explanation of these members. + + // These members are copied by nsSHEntryShared::Duplicate(). If you add a + // member here, be sure to update the Duplicate() implementation. + PRUint64 mDocShellID; + nsCOMArray mChildShells; + nsCOMPtr mOwner; + nsISHEntry* mParent; + nsCString mContentType; + PRPackedBool mIsFrameNavigation; + PRPackedBool mSaveLayoutState; + PRPackedBool mSticky; + PRPackedBool mDynamicallyCreated; + nsCOMPtr mCacheKey; + PRUint32 mLastTouched; + + // These members aren't copied by nsSHEntryShared::Duplicate() because + // they're specific to a particular content viewer. + PRUint64 mID; + nsCOMPtr mContentViewer; + nsCOMPtr mDocument; + nsCOMPtr mLayoutHistoryState; + PRPackedBool mExpired; + nsCOMPtr mWindowState; + nsIntRect mViewerBounds; + nsCOMPtr mRefreshURIList; + nsExpirationState mExpirationState; + nsAutoPtr mEditorData; +}; + +#endif diff --git a/docshell/shistory/src/nsSHistory.cpp b/docshell/shistory/src/nsSHistory.cpp index 366d261408e4..d17eacdf54f8 100644 --- a/docshell/shistory/src/nsSHistory.cpp +++ b/docshell/shistory/src/nsSHistory.cpp @@ -72,12 +72,10 @@ using namespace mozilla; #define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries" #define PREF_SHISTORY_MAX_TOTAL_VIEWERS "browser.sessionhistory.max_total_viewers" -#define PREF_SHISTORY_OPTIMIZE_EVICTION "browser.sessionhistory.optimize_eviction" static const char* kObservedPrefs[] = { PREF_SHISTORY_SIZE, PREF_SHISTORY_MAX_TOTAL_VIEWERS, - PREF_SHISTORY_OPTIMIZE_EVICTION, nsnull }; @@ -90,16 +88,46 @@ static PRCList gSHistoryList; // means we will calculate how many viewers to cache based on total memory PRInt32 nsSHistory::sHistoryMaxTotalViewers = -1; -// Whether we should optimize the search for which entry to evict, -// by evicting older entries first. See entryLastTouched in -// nsSHistory::EvictGlobalContentViewer(). -// NB: After 4.0, we should remove this option and the corresponding -// pref - optimization should always be used -static PRBool gOptimizeEviction = PR_FALSE; // A counter that is used to be able to know the order in which // entries were touched, so that we can evict older entries first. static PRUint32 gTouchCounter = 0; +static PRLogModuleInfo* gLogModule = PR_LOG_DEFINE("nsSHistory"); +#define LOG(format) PR_LOG(gLogModule, PR_LOG_DEBUG, format) + +// This macro makes it easier to print a log message which includes a URI's +// spec. Example use: +// +// nsIURI *uri = [...]; +// LOG_SPEC(("The URI is %s.", _spec), uri); +// +#define LOG_SPEC(format, uri) \ + PR_BEGIN_MACRO \ + if (PR_LOG_TEST(gLogModule, PR_LOG_DEBUG)) { \ + nsCAutoString _specStr(NS_LITERAL_CSTRING("(null)"));\ + if (uri) { \ + uri->GetSpec(_specStr); \ + } \ + const char* _spec = _specStr.get(); \ + LOG(format); \ + } \ + PR_END_MACRO + +// This macro makes it easy to log a message including an SHEntry's URI. +// For example: +// +// nsCOMPtr shentry = [...]; +// LOG_SHENTRY_SPEC(("shentry %p has uri %s.", shentry.get(), _spec), shentry); +// +#define LOG_SHENTRY_SPEC(format, shentry) \ + PR_BEGIN_MACRO \ + if (PR_LOG_TEST(gLogModule, PR_LOG_DEBUG)) { \ + nsCOMPtr uri; \ + shentry->GetURI(getter_AddRefs(uri)); \ + LOG_SPEC(format, uri); \ + } \ + PR_END_MACRO + enum HistCmd{ HIST_CMD_BACK, HIST_CMD_FORWARD, @@ -134,15 +162,60 @@ nsSHistoryObserver::Observe(nsISupports *aSubject, const char *aTopic, { if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { nsSHistory::UpdatePrefs(); - nsSHistory::EvictGlobalContentViewer(); + nsSHistory::GloballyEvictContentViewers(); } else if (!strcmp(aTopic, NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID) || !strcmp(aTopic, "memory-pressure")) { - nsSHistory::EvictAllContentViewersGlobally(); + nsSHistory::GloballyEvictAllContentViewers(); } return NS_OK; } +namespace { + +already_AddRefed +GetContentViewerForTransaction(nsISHTransaction *aTrans) +{ + nsCOMPtr entry; + aTrans->GetSHEntry(getter_AddRefs(entry)); + if (!entry) { + return nsnull; + } + + nsCOMPtr ownerEntry; + nsCOMPtr viewer; + entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), + getter_AddRefs(viewer)); + return viewer.forget(); +} + +void +EvictContentViewerForTransaction(nsISHTransaction *aTrans) +{ + nsCOMPtr entry; + aTrans->GetSHEntry(getter_AddRefs(entry)); + nsCOMPtr viewer; + nsCOMPtr ownerEntry; + entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), + getter_AddRefs(viewer)); + if (viewer) { + NS_ASSERTION(ownerEntry, + "Content viewer exists but its SHEntry is null"); + + LOG_SHENTRY_SPEC(("Evicting content viewer 0x%p for " + "owning SHEntry 0x%p at %s.", + viewer.get(), ownerEntry.get(), _spec), ownerEntry); + + // Drop the presentation state before destroying the viewer, so that + // document teardown is able to correctly persist the state. + ownerEntry->SetContentViewer(nsnull); + ownerEntry->SyncPresentationState(); + viewer->Destroy(); + } +} + +} // anonymous namespace + //***************************************************************************** //*** nsSHistory: Object Management //***************************************************************************** @@ -240,7 +313,6 @@ nsSHistory::UpdatePrefs() Preferences::GetInt(PREF_SHISTORY_SIZE, &gHistoryMaxSize); Preferences::GetInt(PREF_SHISTORY_MAX_TOTAL_VIEWERS, &sHistoryMaxTotalViewers); - Preferences::GetBool(PREF_SHISTORY_OPTIMIZE_EVICTION, &gOptimizeEviction); // If the pref is negative, that means we calculate how many viewers // we think we should cache, based on total memory if (sHistoryMaxTotalViewers < 0) { @@ -689,12 +761,12 @@ nsSHistory::GetListener(nsISHistoryListener ** aListener) } NS_IMETHODIMP -nsSHistory::EvictContentViewers(PRInt32 aPreviousIndex, PRInt32 aIndex) +nsSHistory::EvictOutOfRangeContentViewers(PRInt32 aIndex) { // Check our per SHistory object limit in the currently navigated SHistory - EvictWindowContentViewers(aPreviousIndex, aIndex); + EvictOutOfRangeWindowContentViewers(aIndex); // Check our total limit across all SHistory objects - EvictGlobalContentViewer(); + GloballyEvictContentViewers(); return NS_OK; } @@ -703,7 +775,14 @@ nsSHistory::EvictAllContentViewers() { // XXXbz we don't actually do a good job of evicting things as we should, so // we might have viewers quite far from mIndex. So just evict everything. - EvictContentViewersInRange(0, mLength); + nsCOMPtr trans = mListRoot; + while (trans) { + EvictContentViewerForTransaction(trans); + + nsISHTransaction *temp = trans; + temp->GetNext(getter_AddRefs(trans)); + } + return NS_OK; } @@ -847,103 +926,78 @@ nsSHistory::ReloadCurrentEntry() } void -nsSHistory::EvictWindowContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex) +nsSHistory::EvictOutOfRangeWindowContentViewers(PRInt32 aIndex) { - // To enforce the per SHistory object limit on cached content viewers, we - // need to release all of the content viewers that are no longer in the - // "window" that now ends/begins at aToIndex. Existing content viewers - // should be in the window from - // aFromIndex - gHistoryMaxViewers to aFromIndex + gHistoryMaxViewers + // XXX rename method to EvictContentViewersExceptAroundIndex, or something. + + // We need to release all content viewers that are no longer in the range // - // We make the assumption that entries outside this range have no viewers so - // that we don't have to walk the whole entire session history checking for - // content viewers. + // aIndex - gHistoryMaxViewers to aIndex + gHistoryMaxViewers + // + // to ensure that this SHistory object isn't responsible for more than + // gHistoryMaxViewers content viewers. But our job is complicated by the + // fact that two transactions which are related by either hash navigations or + // history.pushState will have the same content viewer. + // + // To illustrate the issue, suppose gHistoryMaxViewers = 3 and we have four + // linked transactions in our history. Suppose we then add a new content + // viewer and call into this function. So the history looks like: + // + // A A A A B + // + * + // + // where the letters are content viewers and + and * denote the beginning and + // end of the range aIndex +/- gHistoryMaxViewers. + // + // Although one copy of the content viewer A exists outside the range, we + // don't want to evict A, because it has other copies in range! + // + // We therefore adjust our eviction strategy to read: + // + // Evict each content viewer outside the range aIndex -/+ + // gHistoryMaxViewers, unless that content viewer also appears within the + // range. + // + // (Note that it's entirely legal to have two copies of one content viewer + // separated by a different content viewer -- call pushState twice, go back + // once, and refresh -- so we can't rely on identical viewers only appearing + // adjacent to one another.) - // This can happen on the first load of a page in a particular window - if (aFromIndex < 0 || aToIndex < 0) { + if (aIndex < 0) { return; } - NS_ASSERTION(aFromIndex < mLength, "aFromIndex is out of range"); - NS_ASSERTION(aToIndex < mLength, "aToIndex is out of range"); - if (aFromIndex >= mLength || aToIndex >= mLength) { + NS_ASSERTION(aIndex < mLength, "aIndex is out of range"); + if (aIndex >= mLength) { return; } - // These indices give the range of SHEntries whose content viewers will be - // evicted - PRInt32 startIndex, endIndex; - if (aToIndex > aFromIndex) { // going forward - endIndex = aToIndex - gHistoryMaxViewers; - if (endIndex <= 0) { - return; - } - startIndex = NS_MAX(0, aFromIndex - gHistoryMaxViewers); - } else { // going backward - startIndex = aToIndex + gHistoryMaxViewers + 1; - if (startIndex >= mLength) { - return; - } - endIndex = NS_MIN(mLength, aFromIndex + gHistoryMaxViewers + 1); - } + // Calculate the range that's safe from eviction. + PRInt32 startSafeIndex = PR_MAX(0, aIndex - gHistoryMaxViewers); + PRInt32 endSafeIndex = PR_MIN(mLength, aIndex + gHistoryMaxViewers); -#ifdef DEBUG + LOG(("EvictOutOfRangeWindowContentViewers(index=%d), " + "mLength=%d. Safe range [%d, %d]", + aIndex, mLength, startSafeIndex, endSafeIndex)); + + // The content viewers in range aIndex -/+ gHistoryMaxViewers will not be + // evicted. Collect a set of them so we don't accidentally evict one of them + // if it appears outside this range. + nsCOMArray safeViewers; nsCOMPtr trans; + GetTransactionAtIndex(startSafeIndex, getter_AddRefs(trans)); + for (PRUint32 i = startSafeIndex; trans && i <= endSafeIndex; i++) { + nsCOMPtr viewer = GetContentViewerForTransaction(trans); + safeViewers.AppendObject(viewer); + nsISHTransaction *temp = trans; + temp->GetNext(getter_AddRefs(trans)); + } + + // Walk the SHistory list and evict any content viewers that aren't safe. GetTransactionAtIndex(0, getter_AddRefs(trans)); - - // Walk the full session history and check that entries outside the window - // around aFromIndex have no content viewers - for (PRInt32 i = 0; trans && i < mLength; ++i) { - if (i < aFromIndex - gHistoryMaxViewers || - i > aFromIndex + gHistoryMaxViewers) { - nsCOMPtr entry; - trans->GetSHEntry(getter_AddRefs(entry)); - nsCOMPtr viewer; - nsCOMPtr ownerEntry; - entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), - getter_AddRefs(viewer)); - NS_WARN_IF_FALSE(!viewer, - "ContentViewer exists outside gHistoryMaxViewer range"); - } - - nsISHTransaction *temp = trans; - temp->GetNext(getter_AddRefs(trans)); - } -#endif - - EvictContentViewersInRange(startIndex, endIndex); -} - -void -nsSHistory::EvictContentViewersInRange(PRInt32 aStart, PRInt32 aEnd) -{ - nsCOMPtr trans; - GetTransactionAtIndex(aStart, getter_AddRefs(trans)); - - for (PRInt32 i = aStart; trans && i < aEnd; ++i) { - nsCOMPtr entry; - trans->GetSHEntry(getter_AddRefs(entry)); - nsCOMPtr viewer; - nsCOMPtr ownerEntry; - entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), - getter_AddRefs(viewer)); - if (viewer) { - NS_ASSERTION(ownerEntry, - "ContentViewer exists but its SHEntry is null"); -#ifdef DEBUG_PAGE_CACHE - nsCOMPtr uri; - ownerEntry->GetURI(getter_AddRefs(uri)); - nsCAutoString spec; - if (uri) - uri->GetSpec(spec); - - printf("per SHistory limit: evicting content viewer: %s\n", spec.get()); -#endif - - // Drop the presentation state before destroying the viewer, so that - // document teardown is able to correctly persist the state. - ownerEntry->SetContentViewer(nsnull); - ownerEntry->SyncPresentationState(); - viewer->Destroy(); + while (trans) { + nsCOMPtr viewer = GetContentViewerForTransaction(trans); + if (safeViewers.IndexOf(viewer) == -1) { + EvictContentViewerForTransaction(trans); } nsISHTransaction *temp = trans; @@ -951,138 +1005,153 @@ nsSHistory::EvictContentViewersInRange(PRInt32 aStart, PRInt32 aEnd) } } -// static -void -nsSHistory::EvictGlobalContentViewer() +namespace { + +class TransactionAndDistance { - // true until the total number of content viewers is <= total max - // The usual case is that we only need to evict one content viewer. - // However, if somebody resets the pref value, we might occasionally - // need to evict more than one. - PRBool shouldTryEviction = PR_TRUE; - while (shouldTryEviction) { - // Walk through our list of SHistory objects, looking for content - // viewers in the possible active window of all of the SHEntry objects. - // Keep track of the SHEntry object that has a ContentViewer and is - // farthest from the current focus in any SHistory object. The - // ContentViewer associated with that SHEntry will be evicted - PRInt32 distanceFromFocus = 0; - PRUint32 candidateLastTouched = 0; - nsCOMPtr evictFromSHE; - nsCOMPtr evictViewer; - PRInt32 totalContentViewers = 0; - nsSHistory* shist = static_cast - (PR_LIST_HEAD(&gSHistoryList)); - while (shist != &gSHistoryList) { - // Calculate the window of SHEntries that could possibly have a content - // viewer. There could be up to gHistoryMaxViewers content viewers, - // but we don't know whether they are before or after the mIndex position - // in the SHEntry list. Just check both sides, to be safe. - PRInt32 startIndex = NS_MAX(0, shist->mIndex - gHistoryMaxViewers); - PRInt32 endIndex = NS_MIN(shist->mLength - 1, - shist->mIndex + gHistoryMaxViewers); - nsCOMPtr trans; - shist->GetTransactionAtIndex(startIndex, getter_AddRefs(trans)); +public: + TransactionAndDistance(nsISHTransaction *aTrans, PRUint32 aDist) + : mTransaction(aTrans) + , mDistance(aDist) + { + mViewer = GetContentViewerForTransaction(aTrans); + NS_ASSERTION(mViewer, "Transaction should have a content viewer"); - for (PRInt32 i = startIndex; trans && i <= endIndex; ++i) { - nsCOMPtr entry; - trans->GetSHEntry(getter_AddRefs(entry)); - nsCOMPtr viewer; - nsCOMPtr ownerEntry; - entry->GetAnyContentViewer(getter_AddRefs(ownerEntry), - getter_AddRefs(viewer)); + nsCOMPtr shentry; + mTransaction->GetSHEntry(getter_AddRefs(shentry)); - PRUint32 entryLastTouched = 0; - if (gOptimizeEviction) { - nsCOMPtr entryInternal = do_QueryInterface(entry); - if (entryInternal) { - // Find when this entry was last activated - entryInternal->GetLastTouched(&entryLastTouched); - } - } - -#ifdef DEBUG_PAGE_CACHE - nsCOMPtr uri; - if (ownerEntry) { - ownerEntry->GetURI(getter_AddRefs(uri)); - } else { - entry->GetURI(getter_AddRefs(uri)); - } - nsCAutoString spec; - if (uri) { - uri->GetSpec(spec); - printf("Considering for eviction: %s\n", spec.get()); - } -#endif - - // This SHEntry has a ContentViewer, so check how far away it is from - // the currently used SHEntry within this SHistory object - if (viewer) { - PRInt32 distance = NS_ABS(shist->mIndex - i); - -#ifdef DEBUG_PAGE_CACHE - printf("Has a cached content viewer: %s\n", spec.get()); - printf("mIndex: %d i: %d\n", shist->mIndex, i); -#endif - totalContentViewers++; - - // If this entry is further away from focus than any previously found - // or at the same distance but it is longer time since it was activated - // then take this entry as the new candiate for eviction - if (distance > distanceFromFocus || (distance == distanceFromFocus && candidateLastTouched > entryLastTouched)) { - -#ifdef DEBUG_PAGE_CACHE - printf("Choosing as new eviction candidate: %s\n", spec.get()); -#endif - candidateLastTouched = entryLastTouched; - distanceFromFocus = distance; - evictFromSHE = ownerEntry; - evictViewer = viewer; - } - } - nsISHTransaction* temp = trans; - temp->GetNext(getter_AddRefs(trans)); - } - shist = static_cast(PR_NEXT_LINK(shist)); - } - -#ifdef DEBUG_PAGE_CACHE - printf("Distance from focus: %d\n", distanceFromFocus); - printf("Total max viewers: %d\n", sHistoryMaxTotalViewers); - printf("Total number of viewers: %d\n", totalContentViewers); -#endif - - if (totalContentViewers > sHistoryMaxTotalViewers && evictViewer) { -#ifdef DEBUG_PAGE_CACHE - nsCOMPtr uri; - evictFromSHE->GetURI(getter_AddRefs(uri)); - nsCAutoString spec; - if (uri) { - uri->GetSpec(spec); - printf("Evicting content viewer: %s\n", spec.get()); - } -#endif - - // Drop the presentation state before destroying the viewer, so that - // document teardown is able to correctly persist the state. - evictFromSHE->SetContentViewer(nsnull); - evictFromSHE->SyncPresentationState(); - evictViewer->Destroy(); - - // If we only needed to evict one content viewer, then we are done. - // Otherwise, continue evicting until we reach the max total limit. - if (totalContentViewers - sHistoryMaxTotalViewers == 1) { - shouldTryEviction = PR_FALSE; - } + nsCOMPtr shentryInternal = do_QueryInterface(shentry); + if (shentryInternal) { + shentryInternal->GetLastTouched(&mLastTouched); } else { - // couldn't find a content viewer to evict, so we are done - shouldTryEviction = PR_FALSE; + NS_WARNING("Can't cast to nsISHEntryInternal?"); + mLastTouched = 0; } - } // while shouldTryEviction + } + + bool operator<(const TransactionAndDistance &aOther) const + { + // Compare distances first, and fall back to last-accessed times. + if (aOther.mDistance != this->mDistance) { + return this->mDistance < aOther.mDistance; + } + + return this->mLastTouched < aOther.mLastTouched; + } + + bool operator==(const TransactionAndDistance &aOther) const + { + // This is a little silly; we need == so the default comaprator can be + // instantiated, but this function is never actually called when we sort + // the list of TransactionAndDistance objects. + return aOther.mDistance == this->mDistance && + aOther.mLastTouched == this->mLastTouched; + } + + nsCOMPtr mTransaction; + nsCOMPtr mViewer; + PRUint32 mLastTouched; + PRInt32 mDistance; +}; + +} // anonymous namespace + +//static +void +nsSHistory::GloballyEvictContentViewers() +{ + // First, collect from each SHistory object the transactions which have a + // cached content viewer. Associate with each transaction its distance from + // its SHistory's current index. + + nsTArray transactions; + + nsSHistory *shist = static_cast(PR_LIST_HEAD(&gSHistoryList)); + while (shist != &gSHistoryList) { + + // Maintain a list of the transactions which have viewers and belong to + // this particular shist object. We'll add this list to the global list, + // |transactions|, eventually. + nsTArray shTransactions; + + // Content viewers are likely to exist only within shist->mIndex -/+ + // gHistoryMaxViewers, so only search within that range. + // + // A content viewer might exist outside that range due to either: + // + // * history.pushState or hash navigations, in which case a copy of the + // content viewer should exist within the range, or + // + // * bugs which cause us not to call nsSHistory::EvictContentViewers() + // often enough. Once we do call EvictContentViewers() for the + // SHistory object in question, we'll do a full search of its history + // and evict the out-of-range content viewers, so we don't bother here. + // + PRInt32 startIndex = NS_MAX(0, shist->mIndex - gHistoryMaxViewers); + PRInt32 endIndex = NS_MIN(shist->mLength - 1, + shist->mIndex + gHistoryMaxViewers); + nsCOMPtr trans; + shist->GetTransactionAtIndex(startIndex, getter_AddRefs(trans)); + for (PRInt32 i = startIndex; trans && i <= endIndex; i++) { + nsCOMPtr contentViewer = + GetContentViewerForTransaction(trans); + + if (contentViewer) { + // Because one content viewer might belong to multiple SHEntries, we + // have to search through shTransactions to see if we already know + // about this content viewer. If we find the viewer, update its + // distance from the SHistory's index and continue. + PRBool found = PR_FALSE; + for (PRUint32 j = 0; j < shTransactions.Length(); j++) { + TransactionAndDistance &container = shTransactions[j]; + if (container.mViewer == contentViewer) { + container.mDistance = PR_MIN(container.mDistance, + PR_ABS(i - shist->mIndex)); + found = PR_TRUE; + break; + } + } + + // If we didn't find a TransactionAndDistance for this content viewer, make a new + // one. + if (!found) { + TransactionAndDistance container(trans, PR_ABS(i - shist->mIndex)); + shTransactions.AppendElement(container); + } + } + + nsISHTransaction *temp = trans; + temp->GetNext(getter_AddRefs(trans)); + } + + // We've found all the transactions belonging to shist which have viewers. + // Add those transactions to our global list and move on. + transactions.AppendElements(shTransactions); + shist = static_cast(PR_NEXT_LINK(shist)); + } + + // We now have collected all cached content viewers. First check that we + // have enough that we actually need to evict some. + if ((PRInt32)transactions.Length() <= sHistoryMaxTotalViewers) { + return; + } + + // If we need to evict, sort our list of transactions and evict the largest + // ones. (We could of course get better algorithmic complexity here by using + // a heap or something more clever. But sHistoryMaxTotalViewers isn't large, + // so let's not worry about it.) + transactions.Sort(); + + for (PRInt32 i = transactions.Length() - 1; + i >= sHistoryMaxTotalViewers; --i) { + + EvictContentViewerForTransaction(transactions[i].mTransaction); + + } } -NS_IMETHODIMP -nsSHistory::EvictExpiredContentViewerForEntry(nsISHEntry *aEntry) +nsresult +nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry *aEntry) { PRInt32 startIndex = NS_MAX(0, mIndex - gHistoryMaxViewers); PRInt32 endIndex = NS_MIN(mLength - 1, @@ -1094,8 +1163,11 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsISHEntry *aEntry) for (i = startIndex; trans && i <= endIndex; ++i) { nsCOMPtr entry; trans->GetSHEntry(getter_AddRefs(entry)); - if (entry == aEntry) + + // Does entry have the same BFCacheEntry as the argument to this method? + if (entry->HasBFCacheEntry(aEntry)) { break; + } nsISHTransaction *temp = trans; temp->GetNext(getter_AddRefs(trans)); @@ -1103,21 +1175,13 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsISHEntry *aEntry) if (i > endIndex) return NS_OK; - NS_ASSERTION(i != mIndex, "How did the current session entry expire?"); - if (i == mIndex) + if (i == mIndex) { + NS_WARNING("How did the current SHEntry expire?"); return NS_OK; - - // We evict content viewers for the expired entry and any other entries that - // we would have to go through the expired entry to get to (i.e. the entries - // that have the expired entry between them and the current entry). Those - // other entries should have timed out already, actually, but this is just - // to be on the safe side. - if (i < mIndex) { - EvictContentViewersInRange(startIndex, i + 1); - } else { - EvictContentViewersInRange(i, endIndex + 1); } - + + EvictContentViewerForTransaction(trans); + return NS_OK; } @@ -1128,11 +1192,11 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsISHEntry *aEntry) //static void -nsSHistory::EvictAllContentViewersGlobally() +nsSHistory::GloballyEvictAllContentViewers() { PRInt32 maxViewers = sHistoryMaxTotalViewers; sHistoryMaxTotalViewers = 0; - EvictGlobalContentViewer(); + GloballyEvictContentViewers(); sHistoryMaxTotalViewers = maxViewers; } diff --git a/docshell/shistory/src/nsSHistory.h b/docshell/shistory/src/nsSHistory.h index 01cdf4654548..103cf7ef92bd 100644 --- a/docshell/shistory/src/nsSHistory.h +++ b/docshell/shistory/src/nsSHistory.h @@ -101,12 +101,11 @@ protected: nsresult PrintHistory(); #endif - // Evict the viewers at indices between aStartIndex and aEndIndex, - // including aStartIndex but not aEndIndex. - void EvictContentViewersInRange(PRInt32 aStartIndex, PRInt32 aEndIndex); - void EvictWindowContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex); - static void EvictGlobalContentViewer(); - static void EvictAllContentViewersGlobally(); + // Evict content viewers in this window which don't lie in the "safe" range + // around aIndex. + void EvictOutOfRangeWindowContentViewers(PRInt32 aIndex); + static void GloballyEvictContentViewers(); + static void GloballyEvictAllContentViewers(); // Calculates a max number of total // content viewers to cache, based on amount of total memory diff --git a/docshell/test/Makefile.in b/docshell/test/Makefile.in index 408272f975f0..f6e2fc101ef2 100644 --- a/docshell/test/Makefile.in +++ b/docshell/test/Makefile.in @@ -119,6 +119,7 @@ _TEST_FILES = \ test_bug669671.html \ file_bug669671.sjs \ test_bug675587.html \ + test_bfcache_plus_hash.html \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) diff --git a/docshell/test/chrome/bug396519_window.xul b/docshell/test/chrome/bug396519_window.xul index d45e07cd90c7..179e094633c0 100644 --- a/docshell/test/chrome/bug396519_window.xul +++ b/docshell/test/chrome/bug396519_window.xul @@ -50,6 +50,9 @@ const LISTEN_EVENTS = ["pageshow"]; + const Cc = Components.classes; + const Ci = Components.interfaces; + var gBrowser; var gTestCount = 0; var gTestsIterator; @@ -96,6 +99,23 @@ QueryInterface(Components.interfaces.nsISHEntry); is(!!shEntry.contentViewer, gExpected[i], "content viewer "+i+", test "+gTestCount); } + + // Make sure none of the SHEntries share bfcache entries with one + // another. + for (var i = 0; i < history.count; i++) { + for (var j = 0; j < history.count; j++) { + if (j == i) + continue; + + let shentry1 = history.getEntryAtIndex(i, false) + .QueryInterface(Ci.nsISHEntry); + let shentry2 = history.getEntryAtIndex(j, false) + .QueryInterface(Ci.nsISHEntry); + ok(!shentry1.sharesDocumentWith(shentry2), + 'Test ' + gTestCount + ': shentry[' + i + "] shouldn't " + + "share document with shentry[" + j + ']'); + } + } } else { is(history.count, gExpected.length, "Wrong history length in test "+gTestCount); diff --git a/docshell/test/test_bfcache_plus_hash.html b/docshell/test/test_bfcache_plus_hash.html new file mode 100644 index 000000000000..d75a4d8272e8 --- /dev/null +++ b/docshell/test/test_bfcache_plus_hash.html @@ -0,0 +1,121 @@ + + + + + Test for Bug 646641 + + + + + + +Mozilla Bug 646641 +

+ +
+
+
+ + diff --git a/docshell/test/unit/head_docshell.js b/docshell/test/unit/head_docshell.js index cd3c0dc59862..3c80b97d9920 100644 --- a/docshell/test/unit/head_docshell.js +++ b/docshell/test/unit/head_docshell.js @@ -56,14 +56,6 @@ var provider = { retVal.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); return retVal; } - if (prop == "UHist") { - var retVal = dirSvc.get("CurProcD", Ci.nsILocalFile); - retVal.append("test_docshell_profile"); - if (!retVal.exists()) - retVal.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); - retVal.append("history.dat"); - return retVal; - } throw Cr.NS_ERROR_FAILURE; }, QueryInterface: function(iid) { diff --git a/dom/Makefile.in b/dom/Makefile.in index 2798eb318404..bc456356aa41 100644 --- a/dom/Makefile.in +++ b/dom/Makefile.in @@ -71,7 +71,6 @@ DIRS += interfaces/smil endif DIRS += \ - public/coreEvents \ base \ src \ locales \ diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index e72685a13a43..bbb937c07558 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -285,6 +285,7 @@ #include "nsIDOMHTMLLinkElement.h" #include "nsIDOMHTMLMapElement.h" #include "nsIDOMHTMLMenuElement.h" +#include "nsIDOMHTMLMenuItemElement.h" #include "nsIDOMHTMLMetaElement.h" #include "nsIDOMHTMLModElement.h" #include "nsIDOMHTMLOListElement.h" @@ -836,6 +837,8 @@ static nsDOMClassInfoData sClassInfoData[] = { ELEMENT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(HTMLMenuElement, nsElementSH, ELEMENT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(HTMLMenuItemElement, nsElementSH, + ELEMENT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(HTMLMetaElement, nsElementSH, ELEMENT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(HTMLModElement, nsElementSH, @@ -1594,45 +1597,6 @@ jsid nsDOMClassInfo::sScreenX_id = JSID_VOID; jsid nsDOMClassInfo::sScreenY_id = JSID_VOID; jsid nsDOMClassInfo::sStatus_id = JSID_VOID; jsid nsDOMClassInfo::sName_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmousedown_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmouseup_id = JSID_VOID; -jsid nsDOMClassInfo::sOnclick_id = JSID_VOID; -jsid nsDOMClassInfo::sOndblclick_id = JSID_VOID; -jsid nsDOMClassInfo::sOncontextmenu_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmouseover_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmouseout_id = JSID_VOID; -jsid nsDOMClassInfo::sOnkeydown_id = JSID_VOID; -jsid nsDOMClassInfo::sOnkeyup_id = JSID_VOID; -jsid nsDOMClassInfo::sOnkeypress_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmousemove_id = JSID_VOID; -jsid nsDOMClassInfo::sOnfocus_id = JSID_VOID; -jsid nsDOMClassInfo::sOnblur_id = JSID_VOID; -jsid nsDOMClassInfo::sOnsubmit_id = JSID_VOID; -jsid nsDOMClassInfo::sOnreset_id = JSID_VOID; -jsid nsDOMClassInfo::sOnchange_id = JSID_VOID; -jsid nsDOMClassInfo::sOninput_id = JSID_VOID; -jsid nsDOMClassInfo::sOninvalid_id = JSID_VOID; -jsid nsDOMClassInfo::sOnselect_id = JSID_VOID; -jsid nsDOMClassInfo::sOnload_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpopstate_id = JSID_VOID; -jsid nsDOMClassInfo::sOnbeforeunload_id = JSID_VOID; -jsid nsDOMClassInfo::sOnunload_id = JSID_VOID; -jsid nsDOMClassInfo::sOnhashchange_id = JSID_VOID; -jsid nsDOMClassInfo::sOnreadystatechange_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpageshow_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpagehide_id = JSID_VOID; -jsid nsDOMClassInfo::sOnabort_id = JSID_VOID; -jsid nsDOMClassInfo::sOnerror_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpaint_id = JSID_VOID; -jsid nsDOMClassInfo::sOnresize_id = JSID_VOID; -jsid nsDOMClassInfo::sOnscroll_id = JSID_VOID; -jsid nsDOMClassInfo::sOndrag_id = JSID_VOID; -jsid nsDOMClassInfo::sOndragend_id = JSID_VOID; -jsid nsDOMClassInfo::sOndragenter_id = JSID_VOID; -jsid nsDOMClassInfo::sOndragleave_id = JSID_VOID; -jsid nsDOMClassInfo::sOndragover_id = JSID_VOID; -jsid nsDOMClassInfo::sOndragstart_id = JSID_VOID; -jsid nsDOMClassInfo::sOndrop_id = JSID_VOID; jsid nsDOMClassInfo::sScrollX_id = JSID_VOID; jsid nsDOMClassInfo::sScrollY_id = JSID_VOID; jsid nsDOMClassInfo::sScrollMaxX_id = JSID_VOID; @@ -1651,51 +1615,22 @@ jsid nsDOMClassInfo::sAddEventListener_id= JSID_VOID; jsid nsDOMClassInfo::sBaseURIObject_id = JSID_VOID; jsid nsDOMClassInfo::sNodePrincipal_id = JSID_VOID; jsid nsDOMClassInfo::sDocumentURIObject_id=JSID_VOID; -jsid nsDOMClassInfo::sOncopy_id = JSID_VOID; -jsid nsDOMClassInfo::sOncut_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpaste_id = JSID_VOID; jsid nsDOMClassInfo::sJava_id = JSID_VOID; jsid nsDOMClassInfo::sPackages_id = JSID_VOID; -jsid nsDOMClassInfo::sOnloadstart_id = JSID_VOID; -jsid nsDOMClassInfo::sOnprogress_id = JSID_VOID; -jsid nsDOMClassInfo::sOnsuspend_id = JSID_VOID; -jsid nsDOMClassInfo::sOnemptied_id = JSID_VOID; -jsid nsDOMClassInfo::sOnstalled_id = JSID_VOID; -jsid nsDOMClassInfo::sOnplay_id = JSID_VOID; -jsid nsDOMClassInfo::sOnpause_id = JSID_VOID; -jsid nsDOMClassInfo::sOnloadedmetadata_id= JSID_VOID; -jsid nsDOMClassInfo::sOnloadeddata_id = JSID_VOID; -jsid nsDOMClassInfo::sOnwaiting_id = JSID_VOID; -jsid nsDOMClassInfo::sOnplaying_id = JSID_VOID; -jsid nsDOMClassInfo::sOncanplay_id = JSID_VOID; -jsid nsDOMClassInfo::sOncanplaythrough_id= JSID_VOID; -jsid nsDOMClassInfo::sOnseeking_id = JSID_VOID; -jsid nsDOMClassInfo::sOnseeked_id = JSID_VOID; -jsid nsDOMClassInfo::sOntimeupdate_id = JSID_VOID; -jsid nsDOMClassInfo::sOnended_id = JSID_VOID; -jsid nsDOMClassInfo::sOnratechange_id = JSID_VOID; -jsid nsDOMClassInfo::sOndurationchange_id= JSID_VOID; -jsid nsDOMClassInfo::sOnvolumechange_id = JSID_VOID; -jsid nsDOMClassInfo::sOnmessage_id = JSID_VOID; -jsid nsDOMClassInfo::sOnbeforescriptexecute_id = JSID_VOID; -jsid nsDOMClassInfo::sOnafterscriptexecute_id = JSID_VOID; jsid nsDOMClassInfo::sWrappedJSObject_id = JSID_VOID; jsid nsDOMClassInfo::sURL_id = JSID_VOID; jsid nsDOMClassInfo::sKeyPath_id = JSID_VOID; jsid nsDOMClassInfo::sAutoIncrement_id = JSID_VOID; jsid nsDOMClassInfo::sUnique_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchstart_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchend_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchmove_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchenter_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchleave_id = JSID_VOID; -jsid nsDOMClassInfo::sOntouchcancel_id = JSID_VOID; -jsid nsDOMClassInfo::sOnbeforeprint_id = JSID_VOID; -jsid nsDOMClassInfo::sOnafterprint_id = JSID_VOID; - -jsid nsDOMClassInfo::sOndevicemotion_id = JSID_VOID; -jsid nsDOMClassInfo::sOndeviceorientation_id = JSID_VOID; +#define EVENT(name_, id_, type_, struct_) \ +jsid nsDOMClassInfo::sOn##name_##_id = JSID_VOID; +#define WINDOW_ONLY_EVENT EVENT +#define TOUCH_EVENT EVENT +#include "nsEventNameList.h" +#undef TOUCH_EVENT +#undef WINDOW_ONLY_EVENT +#undef EVENT static const JSClass *sObjectClass = nsnull; @@ -1932,45 +1867,6 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx) SET_JSID_TO_STRING(sScreenY_id, cx, "screenY"); SET_JSID_TO_STRING(sStatus_id, cx, "status"); SET_JSID_TO_STRING(sName_id, cx, "name"); - SET_JSID_TO_STRING(sOnmousedown_id, cx, "onmousedown"); - SET_JSID_TO_STRING(sOnmouseup_id, cx, "onmouseup"); - SET_JSID_TO_STRING(sOnclick_id, cx, "onclick"); - SET_JSID_TO_STRING(sOndblclick_id, cx, "ondblclick"); - SET_JSID_TO_STRING(sOncontextmenu_id, cx, "oncontextmenu"); - SET_JSID_TO_STRING(sOnmouseover_id, cx, "onmouseover"); - SET_JSID_TO_STRING(sOnmouseout_id, cx, "onmouseout"); - SET_JSID_TO_STRING(sOnkeydown_id, cx, "onkeydown"); - SET_JSID_TO_STRING(sOnkeyup_id, cx, "onkeyup"); - SET_JSID_TO_STRING(sOnkeypress_id, cx, "onkeypress"); - SET_JSID_TO_STRING(sOnmousemove_id, cx, "onmousemove"); - SET_JSID_TO_STRING(sOnfocus_id, cx, "onfocus"); - SET_JSID_TO_STRING(sOnblur_id, cx, "onblur"); - SET_JSID_TO_STRING(sOnsubmit_id, cx, "onsubmit"); - SET_JSID_TO_STRING(sOnreset_id, cx, "onreset"); - SET_JSID_TO_STRING(sOnchange_id, cx, "onchange"); - SET_JSID_TO_STRING(sOninput_id, cx, "oninput"); - SET_JSID_TO_STRING(sOninvalid_id, cx, "oninvalid"); - SET_JSID_TO_STRING(sOnselect_id, cx, "onselect"); - SET_JSID_TO_STRING(sOnload_id, cx, "onload"); - SET_JSID_TO_STRING(sOnpopstate_id, cx, "onpopstate"); - SET_JSID_TO_STRING(sOnbeforeunload_id, cx, "onbeforeunload"); - SET_JSID_TO_STRING(sOnunload_id, cx, "onunload"); - SET_JSID_TO_STRING(sOnhashchange_id, cx, "onhashchange"); - SET_JSID_TO_STRING(sOnreadystatechange_id, cx, "onreadystatechange"); - SET_JSID_TO_STRING(sOnpageshow_id, cx, "onpageshow"); - SET_JSID_TO_STRING(sOnpagehide_id, cx, "onpagehide"); - SET_JSID_TO_STRING(sOnabort_id, cx, "onabort"); - SET_JSID_TO_STRING(sOnerror_id, cx, "onerror"); - SET_JSID_TO_STRING(sOnpaint_id, cx, "onpaint"); - SET_JSID_TO_STRING(sOnresize_id, cx, "onresize"); - SET_JSID_TO_STRING(sOnscroll_id, cx, "onscroll"); - SET_JSID_TO_STRING(sOndrag_id, cx, "ondrag"); - SET_JSID_TO_STRING(sOndragend_id, cx, "ondragend"); - SET_JSID_TO_STRING(sOndragenter_id, cx, "ondragenter"); - SET_JSID_TO_STRING(sOndragleave_id, cx, "ondragleave"); - SET_JSID_TO_STRING(sOndragover_id, cx, "ondragover"); - SET_JSID_TO_STRING(sOndragstart_id, cx, "ondragstart"); - SET_JSID_TO_STRING(sOndrop_id, cx, "ondrop"); SET_JSID_TO_STRING(sScrollX_id, cx, "scrollX"); SET_JSID_TO_STRING(sScrollY_id, cx, "scrollY"); SET_JSID_TO_STRING(sScrollMaxX_id, cx, "scrollMaxX"); @@ -1989,53 +1885,22 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx) SET_JSID_TO_STRING(sBaseURIObject_id, cx, "baseURIObject"); SET_JSID_TO_STRING(sNodePrincipal_id, cx, "nodePrincipal"); SET_JSID_TO_STRING(sDocumentURIObject_id,cx,"documentURIObject"); - SET_JSID_TO_STRING(sOncopy_id, cx, "oncopy"); - SET_JSID_TO_STRING(sOncut_id, cx, "oncut"); - SET_JSID_TO_STRING(sOnpaste_id, cx, "onpaste"); SET_JSID_TO_STRING(sJava_id, cx, "java"); SET_JSID_TO_STRING(sPackages_id, cx, "Packages"); -#ifdef MOZ_MEDIA - SET_JSID_TO_STRING(sOnloadstart_id, cx, "onloadstart"); - SET_JSID_TO_STRING(sOnprogress_id, cx, "onprogress"); - SET_JSID_TO_STRING(sOnsuspend_id, cx, "onsuspend"); - SET_JSID_TO_STRING(sOnemptied_id, cx, "onemptied"); - SET_JSID_TO_STRING(sOnstalled_id, cx, "onstalled"); - SET_JSID_TO_STRING(sOnplay_id, cx, "onplay"); - SET_JSID_TO_STRING(sOnpause_id, cx, "onpause"); - SET_JSID_TO_STRING(sOnloadedmetadata_id,cx, "onloadedmetadata"); - SET_JSID_TO_STRING(sOnloadeddata_id, cx, "onloadeddata"); - SET_JSID_TO_STRING(sOnwaiting_id, cx, "onwaiting"); - SET_JSID_TO_STRING(sOnplaying_id, cx, "onplaying"); - SET_JSID_TO_STRING(sOncanplay_id, cx, "oncanplay"); - SET_JSID_TO_STRING(sOncanplaythrough_id,cx, "oncanplaythrough"); - SET_JSID_TO_STRING(sOnseeking_id, cx, "onseeking"); - SET_JSID_TO_STRING(sOnseeked_id, cx, "onseeked"); - SET_JSID_TO_STRING(sOntimeupdate_id, cx, "ontimeupdate"); - SET_JSID_TO_STRING(sOnended_id, cx, "onended"); - SET_JSID_TO_STRING(sOnratechange_id, cx, "onratechange"); - SET_JSID_TO_STRING(sOndurationchange_id,cx, "ondurationchange"); - SET_JSID_TO_STRING(sOnvolumechange_id, cx, "onvolumechange"); - SET_JSID_TO_STRING(sOnmessage_id, cx, "onmessage"); - SET_JSID_TO_STRING(sOnbeforescriptexecute_id, cx, "onbeforescriptexecute"); - SET_JSID_TO_STRING(sOnafterscriptexecute_id, cx, "onafterscriptexecute"); -#endif // MOZ_MEDIA SET_JSID_TO_STRING(sWrappedJSObject_id, cx, "wrappedJSObject"); SET_JSID_TO_STRING(sURL_id, cx, "URL"); SET_JSID_TO_STRING(sKeyPath_id, cx, "keyPath"); SET_JSID_TO_STRING(sAutoIncrement_id, cx, "autoIncrement"); SET_JSID_TO_STRING(sUnique_id, cx, "unique"); - SET_JSID_TO_STRING(sOntouchstart_id, cx, "ontouchstart"); - SET_JSID_TO_STRING(sOntouchend_id, cx, "ontouchend"); - SET_JSID_TO_STRING(sOntouchmove_id, cx, "ontouchmove"); - SET_JSID_TO_STRING(sOntouchenter_id, cx, "ontouchenter"); - SET_JSID_TO_STRING(sOntouchleave_id, cx, "ontouchleave"); - SET_JSID_TO_STRING(sOntouchcancel_id, cx, "ontouchcancel"); - SET_JSID_TO_STRING(sOnbeforeprint_id, cx, "onbeforeprint"); - SET_JSID_TO_STRING(sOnafterprint_id, cx, "onafterprint"); - - SET_JSID_TO_STRING(sOndevicemotion_id, cx, "ondevicemotion"); - SET_JSID_TO_STRING(sOndeviceorientation_id, cx, "ondeviceorientation"); +#define EVENT(name_, id_, type_, struct_) \ + SET_JSID_TO_STRING(sOn##name_##_id, cx, "on" #name_); +#define WINDOW_ONLY_EVENT EVENT +#define TOUCH_EVENT EVENT +#include "nsEventNameList.h" +#undef TOUCH_EVENT +#undef WINDOW_ONLY_EVENT +#undef EVENT return NS_OK; } @@ -2833,6 +2698,11 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(HTMLMenuItemElement, nsIDOMHTMLMenuItemElement) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLMenuItemElement) + DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES + DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(HTMLMetaElement, nsIDOMHTMLMetaElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLMetaElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES @@ -5021,44 +4891,6 @@ nsDOMClassInfo::ShutDown() sScreenY_id = JSID_VOID; sStatus_id = JSID_VOID; sName_id = JSID_VOID; - sOnmousedown_id = JSID_VOID; - sOnmouseup_id = JSID_VOID; - sOnclick_id = JSID_VOID; - sOndblclick_id = JSID_VOID; - sOncontextmenu_id = JSID_VOID; - sOnmouseover_id = JSID_VOID; - sOnmouseout_id = JSID_VOID; - sOnkeydown_id = JSID_VOID; - sOnkeyup_id = JSID_VOID; - sOnkeypress_id = JSID_VOID; - sOnmousemove_id = JSID_VOID; - sOnfocus_id = JSID_VOID; - sOnblur_id = JSID_VOID; - sOnsubmit_id = JSID_VOID; - sOnreset_id = JSID_VOID; - sOnchange_id = JSID_VOID; - sOninput_id = JSID_VOID; - sOninvalid_id = JSID_VOID; - sOnselect_id = JSID_VOID; - sOnload_id = JSID_VOID; - sOnbeforeunload_id = JSID_VOID; - sOnunload_id = JSID_VOID; - sOnhashchange_id = JSID_VOID; - sOnreadystatechange_id = JSID_VOID; - sOnpageshow_id = JSID_VOID; - sOnpagehide_id = JSID_VOID; - sOnabort_id = JSID_VOID; - sOnerror_id = JSID_VOID; - sOnpaint_id = JSID_VOID; - sOnresize_id = JSID_VOID; - sOnscroll_id = JSID_VOID; - sOndrag_id = JSID_VOID; - sOndragend_id = JSID_VOID; - sOndragenter_id = JSID_VOID; - sOndragleave_id = JSID_VOID; - sOndragover_id = JSID_VOID; - sOndragstart_id = JSID_VOID; - sOndrop_id = JSID_VOID; sScrollX_id = JSID_VOID; sScrollY_id = JSID_VOID; sScrollMaxX_id = JSID_VOID; @@ -5076,47 +4908,21 @@ nsDOMClassInfo::ShutDown() sBaseURIObject_id = JSID_VOID; sNodePrincipal_id = JSID_VOID; sDocumentURIObject_id=JSID_VOID; - sOncopy_id = JSID_VOID; - sOncut_id = JSID_VOID; - sOnpaste_id = JSID_VOID; sJava_id = JSID_VOID; sPackages_id = JSID_VOID; - sOnloadstart_id = JSID_VOID; - sOnprogress_id = JSID_VOID; - sOnsuspend_id = JSID_VOID; - sOnemptied_id = JSID_VOID; - sOnstalled_id = JSID_VOID; - sOnplay_id = JSID_VOID; - sOnpause_id = JSID_VOID; - sOnloadedmetadata_id= JSID_VOID; - sOnloadeddata_id = JSID_VOID; - sOnwaiting_id = JSID_VOID; - sOnplaying_id = JSID_VOID; - sOncanplay_id = JSID_VOID; - sOncanplaythrough_id= JSID_VOID; - sOnseeking_id = JSID_VOID; - sOnseeked_id = JSID_VOID; - sOntimeupdate_id = JSID_VOID; - sOnended_id = JSID_VOID; - sOnratechange_id = JSID_VOID; - sOndurationchange_id= JSID_VOID; - sOnvolumechange_id = JSID_VOID; - sOnmessage_id = JSID_VOID; - sOnbeforescriptexecute_id = JSID_VOID; - sOnafterscriptexecute_id = JSID_VOID; sWrappedJSObject_id = JSID_VOID; sKeyPath_id = JSID_VOID; sAutoIncrement_id = JSID_VOID; sUnique_id = JSID_VOID; - sOntouchstart_id = JSID_VOID; - sOntouchend_id = JSID_VOID; - sOntouchmove_id = JSID_VOID; - sOntouchenter_id = JSID_VOID; - sOntouchleave_id = JSID_VOID; - sOntouchcancel_id = JSID_VOID; - sOnbeforeprint_id = JSID_VOID; - sOnafterprint_id = JSID_VOID; +#define EVENT(name_, id_, type_, struct_) \ + sOn##name_##_id = JSID_VOID; +#define WINDOW_ONLY_EVENT EVENT +#define TOUCH_EVENT EVENT +#include "nsEventNameList.h" +#undef TOUCH_EVENT +#undef WINDOW_ONLY_EVENT +#undef EVENT NS_IF_RELEASE(sXPConnect); NS_IF_RELEASE(sSecMan); @@ -5391,7 +5197,7 @@ nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj, static already_AddRefed -GetChildFrame(nsGlobalWindow *win, jsid id) +GetChildFrame(nsGlobalWindow *win, PRUint32 index) { nsCOMPtr frames; win->GetFrames(getter_AddRefs(frames)); @@ -5399,7 +5205,7 @@ GetChildFrame(nsGlobalWindow *win, jsid id) nsIDOMWindow *frame = nsnull; if (frames) { - frames->Item(JSID_TO_INT(id), &frame); + frames->Item(index, &frame); } return frame; @@ -5436,16 +5242,14 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // whacky, that's because this method is *extremely* performace // critical. Don't touch this unless you know what you're doing. - if (JSID_IS_INT(id)) { + if (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0) { // If we're accessing a numeric property we'll treat that as if // window.frames[n] is accessed (since window.frames === window), // if window.frames[n] is a child frame, wrap the frame and return // it without doing a security check. - - nsCOMPtr frame = GetChildFrame(win, id); + PRUint32 index = PRUint32(JSID_TO_INT(id)); nsresult rv = NS_OK; - - if (frame) { + if (nsCOMPtr frame = GetChildFrame(win, index)) { // A numeric property accessed and the numeric property is a // child frame, wrap the child frame without doing a security // check and return. @@ -6706,19 +6510,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper); if (!JSID_IS_STRING(id)) { - if (JSID_IS_INT(id) && !(flags & JSRESOLVE_ASSIGNING)) { + if (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0 && !(flags & JSRESOLVE_ASSIGNING)) { // If we're resolving a numeric property, treat that as if // window.frames[n] is resolved (since window.frames === // window), if window.frames[n] is a child frame, define a // property for this index. - - nsCOMPtr frame = GetChildFrame(win, id); - - if (frame) { + PRUint32 index = PRUint32(JSID_TO_INT(id)); + if (nsCOMPtr frame = GetChildFrame(win, index)) { // A numeric property accessed and the numeric property is a // child frame. Define a property for this index. - *_retval = ::JS_DefineElement(cx, obj, JSID_TO_INT(id), JSVAL_VOID, + *_retval = ::JS_DefineElement(cx, obj, index, JSVAL_VOID, nsnull, nsnull, JSPROP_SHARED); if (*_retval) { @@ -7680,8 +7482,7 @@ nsEventReceiverSH::ReallyIsEventName(jsid id, jschar aFirstChar) id == sOnmousedown_id || id == sOnmessage_id); case 'p' : - return (id == sOnpaint_id || - id == sOnpageshow_id || + return (id == sOnpageshow_id || id == sOnpagehide_id || id == sOnpaste_id || id == sOnpopstate_id || @@ -7696,6 +7497,7 @@ nsEventReceiverSH::ReallyIsEventName(jsid id, jschar aFirstChar) id == sOnratechange_id); case 's' : return (id == sOnscroll_id || + id == sOnshow_id || id == sOnselect_id || id == sOnsubmit_id || id == sOnseeked_id || @@ -8110,8 +7912,9 @@ nsGenericArraySH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsresult rv = GetLength(wrapper, cx, obj, &length); NS_ENSURE_SUCCESS(rv, rv); - if ((PRUint32)n < length) { - *_retval = ::JS_DefineElement(cx, obj, n, JSVAL_VOID, nsnull, nsnull, + PRUint32 index = PRUint32(n); + if (index < length) { + *_retval = ::JS_DefineElement(cx, obj, index, JSVAL_VOID, nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_SHARED); *objp = obj; } @@ -9137,12 +8940,7 @@ nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id, JSBool ok = JS_TRUE; if (v != JSVAL_VOID) { - if (JSID_IS_STRING(id)) { - ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, 0); - } else { - ok = ::JS_DefineElement(cx, obj, JSID_TO_INT(id), v, nsnull, nsnull, 0); - } - + ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, 0); *objp = obj; } @@ -9685,7 +9483,7 @@ nsHTMLSelectElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext nsISupports *node = options->GetNodeAt(n); if (node) { *objp = obj; - *_retval = JS_DefineElement(cx, obj, n, JSVAL_VOID, nsnull, nsnull, + *_retval = JS_DefineElement(cx, obj, PRUint32(n), JSVAL_VOID, nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_SHARED); return NS_OK; @@ -10035,24 +9833,14 @@ nsHTMLPluginObjElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSBool found = PR_FALSE; if (!ObjectIsNativeWrapper(cx, obj)) { - if (JSID_IS_STRING(id)) { - *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); - } else { - *_retval = ::JS_HasElement(cx, pi_obj, JSID_TO_INT(id), &found); - } - + *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); if (!*_retval) { return NS_ERROR_UNEXPECTED; } } if (found) { - if (JSID_IS_STRING(id)) { - *_retval = ::JS_GetPropertyById(cx, pi_obj, id, vp); - } else { - *_retval = ::JS_GetElement(cx, pi_obj, JSID_TO_INT(id), vp); - } - + *_retval = ::JS_GetPropertyById(cx, pi_obj, id, vp); return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE; } @@ -10074,24 +9862,14 @@ nsHTMLPluginObjElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSBool found = PR_FALSE; if (!ObjectIsNativeWrapper(cx, obj)) { - if (JSID_IS_STRING(id)) { - *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); - } else { - *_retval = ::JS_HasElement(cx, pi_obj, JSID_TO_INT(id), &found); - } - + *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); if (!*_retval) { return NS_ERROR_UNEXPECTED; } } if (found) { - if (JSID_IS_STRING(id)) { - *_retval = ::JS_SetPropertyById(cx, pi_obj, id, vp); - } else { - *_retval = ::JS_SetElement(cx, pi_obj, JSID_TO_INT(id), vp); - } - + *_retval = ::JS_SetPropertyById(cx, pi_obj, id, vp); return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE; } diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index e1d4ccade48a..8133fd68a504 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -267,45 +267,6 @@ public: static jsid sScreenY_id; static jsid sStatus_id; static jsid sName_id; - static jsid sOnmousedown_id; - static jsid sOnmouseup_id; - static jsid sOnclick_id; - static jsid sOndblclick_id; - static jsid sOncontextmenu_id; - static jsid sOnmouseover_id; - static jsid sOnmouseout_id; - static jsid sOnkeydown_id; - static jsid sOnkeyup_id; - static jsid sOnkeypress_id; - static jsid sOnmousemove_id; - static jsid sOnfocus_id; - static jsid sOnblur_id; - static jsid sOnsubmit_id; - static jsid sOnreset_id; - static jsid sOnchange_id; - static jsid sOninput_id; - static jsid sOninvalid_id; - static jsid sOnselect_id; - static jsid sOnload_id; - static jsid sOnpopstate_id; - static jsid sOnbeforeunload_id; - static jsid sOnunload_id; - static jsid sOnhashchange_id; - static jsid sOnreadystatechange_id; - static jsid sOnpageshow_id; - static jsid sOnpagehide_id; - static jsid sOnabort_id; - static jsid sOnerror_id; - static jsid sOnpaint_id; - static jsid sOnresize_id; - static jsid sOnscroll_id; - static jsid sOndrag_id; - static jsid sOndragend_id; - static jsid sOndragenter_id; - static jsid sOndragleave_id; - static jsid sOndragover_id; - static jsid sOndragstart_id; - static jsid sOndrop_id; static jsid sScrollX_id; static jsid sScrollY_id; static jsid sScrollMaxX_id; @@ -324,52 +285,23 @@ public: static jsid sBaseURIObject_id; static jsid sNodePrincipal_id; static jsid sDocumentURIObject_id; - static jsid sOncopy_id; - static jsid sOncut_id; - static jsid sOnpaste_id; static jsid sJava_id; static jsid sPackages_id; - static jsid sOnloadstart_id; - static jsid sOnprogress_id; - static jsid sOnsuspend_id; - static jsid sOnemptied_id; - static jsid sOnstalled_id; - static jsid sOnplay_id; - static jsid sOnpause_id; - static jsid sOnloadedmetadata_id; - static jsid sOnloadeddata_id; - static jsid sOnwaiting_id; - static jsid sOnplaying_id; - static jsid sOncanplay_id; - static jsid sOncanplaythrough_id; - static jsid sOnseeking_id; - static jsid sOnseeked_id; - static jsid sOntimeupdate_id; - static jsid sOnended_id; - static jsid sOnratechange_id; - static jsid sOndurationchange_id; - static jsid sOnvolumechange_id; - static jsid sOnmessage_id; - static jsid sOnbeforescriptexecute_id; - static jsid sOnafterscriptexecute_id; static jsid sWrappedJSObject_id; static jsid sURL_id; static jsid sKeyPath_id; static jsid sAutoIncrement_id; static jsid sUnique_id; + +#define EVENT(name_, id_, type_, struct_) \ + static jsid sOn##name_##_id; +#define WINDOW_ONLY_EVENT EVENT +#define TOUCH_EVENT EVENT +#include "nsEventNameList.h" +#undef TOUCH_EVENT +#undef WINDOW_ONLY_EVENT +#undef EVENT - static jsid sOntouchstart_id; - static jsid sOntouchend_id; - static jsid sOntouchmove_id; - static jsid sOntouchenter_id; - static jsid sOntouchleave_id; - static jsid sOntouchcancel_id; - static jsid sOnbeforeprint_id; - static jsid sOnafterprint_id; - - static jsid sOndevicemotion_id; - static jsid sOndeviceorientation_id; - protected: static JSPropertyOp sXPCNativeWrapperGetPropertyOp; static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp; diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index c2cf31260f99..b6517a1e9539 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -120,6 +120,7 @@ DOMCI_CLASS(HTMLLegendElement) DOMCI_CLASS(HTMLLinkElement) DOMCI_CLASS(HTMLMapElement) DOMCI_CLASS(HTMLMenuElement) +DOMCI_CLASS(HTMLMenuItemElement) DOMCI_CLASS(HTMLMetaElement) DOMCI_CLASS(HTMLModElement) DOMCI_CLASS(HTMLOListElement) diff --git a/dom/base/nsDOMNavigationTiming.cpp b/dom/base/nsDOMNavigationTiming.cpp index 3422949934ad..ebc639e310a1 100644 --- a/dom/base/nsDOMNavigationTiming.cpp +++ b/dom/base/nsDOMNavigationTiming.cpp @@ -91,6 +91,17 @@ nsDOMNavigationTiming::TimeStampToDOM(mozilla::TimeStamp aStamp, return NS_OK; } +nsresult +nsDOMNavigationTiming::TimeStampToDOMOrFetchStart(mozilla::TimeStamp aStamp, + DOMTimeMilliSec* aResult) +{ + if (!aStamp.IsNull()) { + return TimeStampToDOM(aStamp, aResult); + } else { + return GetFetchStart(aResult); + } +} + DOMTimeMilliSec nsDOMNavigationTiming::DurationFromStart(){ DOMTimeMilliSec result; TimeStampToDOM(mozilla::TimeStamp::Now(), &result); diff --git a/dom/base/nsDOMNavigationTiming.h b/dom/base/nsDOMNavigationTiming.h index 0577bd6e0504..4effb3648220 100644 --- a/dom/base/nsDOMNavigationTiming.h +++ b/dom/base/nsDOMNavigationTiming.h @@ -92,6 +92,8 @@ public: void NotifyDOMContentLoadedStart(nsIURI* aURI); void NotifyDOMContentLoadedEnd(nsIURI* aURI); nsresult TimeStampToDOM(mozilla::TimeStamp aStamp, DOMTimeMilliSec* aResult); + nsresult TimeStampToDOMOrFetchStart(mozilla::TimeStamp aStamp, + DOMTimeMilliSec* aResult); private: nsDOMNavigationTiming(const nsDOMNavigationTiming &){}; diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index b4feb88a0b95..109a80763975 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5952,7 +5952,7 @@ class PostMessageEvent : public nsRunnable private: nsRefPtr mSource; nsString mCallerOrigin; - uint64* mMessage; + JSUint64* mMessage; size_t mMessageLen; nsRefPtr mTargetWindow; nsCOMPtr mProvidedOrigin; @@ -7259,30 +7259,6 @@ nsGlobalWindow::AddEventListener(const nsAString& aType, aWantsUntrusted); } -nsresult -nsGlobalWindow::AddEventListenerByIID(nsIDOMEventListener* aListener, - const nsIID& aIID) -{ - nsEventListenerManager* manager = GetListenerManager(PR_TRUE); - NS_ENSURE_STATE(manager); - return manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); -} - -nsresult -nsGlobalWindow::RemoveEventListenerByIID(nsIDOMEventListener* aListener, - const nsIID& aIID) -{ - FORWARD_TO_INNER(RemoveEventListenerByIID, (aListener, aIID), - NS_ERROR_NOT_INITIALIZED); - - if (mListenerManager) { - mListenerManager->RemoveEventListenerByIID(aListener, aIID, - NS_EVENT_FLAG_BUBBLE); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - nsEventListenerManager* nsGlobalWindow::GetListenerManager(PRBool aCreateIfNotFound) { @@ -8057,7 +8033,6 @@ nsGlobalWindow::GetGlobalStorage(nsIDOMStorageList ** aGlobalStorage) { NS_ENSURE_ARG_POINTER(aGlobalStorage); -#ifdef MOZ_STORAGE if (!Preferences::GetBool(kStorageEnabled)) { *aGlobalStorage = nsnull; return NS_OK; @@ -8072,9 +8047,6 @@ nsGlobalWindow::GetGlobalStorage(nsIDOMStorageList ** aGlobalStorage) NS_IF_ADDREF(*aGlobalStorage); return NS_OK; -#else - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; -#endif } NS_IMETHODIMP diff --git a/dom/base/nsPerformance.cpp b/dom/base/nsPerformance.cpp index fcf211e5ed7a..a5bebf34fab0 100644 --- a/dom/base/nsPerformance.cpp +++ b/dom/base/nsPerformance.cpp @@ -114,7 +114,7 @@ nsPerformanceTiming::GetDomainLookupStart(DOMTimeMilliSec* aTime) } mozilla::TimeStamp stamp; mChannel->GetDomainLookupStart(&stamp); - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -125,7 +125,7 @@ nsPerformanceTiming::GetDomainLookupEnd(DOMTimeMilliSec* aTime) } mozilla::TimeStamp stamp; mChannel->GetDomainLookupEnd(&stamp); - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -136,7 +136,7 @@ nsPerformanceTiming::GetConnectStart(DOMTimeMilliSec* aTime) } mozilla::TimeStamp stamp; mChannel->GetConnectStart(&stamp); - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -147,7 +147,7 @@ nsPerformanceTiming::GetConnectEnd(DOMTimeMilliSec* aTime) } mozilla::TimeStamp stamp; mChannel->GetConnectEnd(&stamp); - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -158,7 +158,7 @@ nsPerformanceTiming::GetRequestStart(DOMTimeMilliSec* aTime) } mozilla::TimeStamp stamp; mChannel->GetRequestStart(&stamp); - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -174,7 +174,7 @@ nsPerformanceTiming::GetResponseStart(DOMTimeMilliSec* aTime) if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) { stamp = cacheStamp; } - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP @@ -190,7 +190,7 @@ nsPerformanceTiming::GetResponseEnd(DOMTimeMilliSec* aTime) if (stamp.IsNull() || (!cacheStamp.IsNull() && cacheStamp < stamp)) { stamp = cacheStamp; } - return mDOMTiming->TimeStampToDOM(stamp, aTime); + return mDOMTiming->TimeStampToDOMOrFetchStart(stamp, aTime); } NS_IMETHODIMP diff --git a/dom/base/nsWindowRoot.cpp b/dom/base/nsWindowRoot.cpp index 3e419b6fdb87..9dfb91a72b0b 100644 --- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -149,24 +149,6 @@ nsWindowRoot::AddEventListener(const nsAString& aType, return elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); } -nsresult -nsWindowRoot::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID) -{ - nsEventListenerManager* manager = GetListenerManager(PR_TRUE); - NS_ENSURE_STATE(manager); - return manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); -} - -nsresult -nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID) -{ - nsEventListenerManager* manager = GetListenerManager(PR_TRUE); - if (manager) { - manager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE); - } - return NS_OK; -} - nsEventListenerManager* nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound) { diff --git a/dom/indexedDB/AsyncConnectionHelper.cpp b/dom/indexedDB/AsyncConnectionHelper.cpp index de7585de32cc..ca981329d6f0 100644 --- a/dom/indexedDB/AsyncConnectionHelper.cpp +++ b/dom/indexedDB/AsyncConnectionHelper.cpp @@ -98,8 +98,7 @@ ConvertCloneBuffersToArrayInternal( return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - jsint count = jsint(aBuffers.Length()); - for (jsint index = 0; index < count; index++) { + for (uint32 index = 0, count = aBuffers.Length(); index < count; index++) { JSAutoStructuredCloneBuffer& buffer = aBuffers[index]; jsval val; diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h index 14af825b23b8..5a2ab7f582ec 100644 --- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -153,7 +153,6 @@ private: // Only touched on the main thread. nsRefPtr mOnErrorListener; nsRefPtr mOnVersionChangeListener; - nsRefPtr mOnBlockedListener; }; END_INDEXEDDB_NAMESPACE diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index ad13fd4a15a1..172cac9c3c42 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -924,8 +924,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx, return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - jsint count = jsint(keys.Length()); - for (jsint index = 0; index < count; index++) { + for (uint32 index = 0, count = keys.Length(); index < count; index++) { const Key& key = keys[index]; NS_ASSERTION(!key.IsUnset(), "Bad key!"); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index b9d4f60f5fae..c466d044e3d7 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -835,7 +835,7 @@ IDBObjectStore::GetStructuredCloneDataFromStatement( nsresult rv = aStatement->GetSharedBlob(aIndex, &dataLength, &data); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - return aBuffer.copy(reinterpret_cast(data), dataLength) ? + return aBuffer.copy(reinterpret_cast(data), dataLength) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 0cd5b428f141..42c355b2b034 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -173,12 +173,9 @@ public: // First check if the document the IDBDatabase is part of is bfcached nsCOMPtr ownerDoc = database->GetOwnerDocument(); - nsISHEntry* shEntry; - if (ownerDoc && (shEntry = ownerDoc->GetBFCacheEntry())) { - nsCOMPtr sheInternal = do_QueryInterface(shEntry); - if (sheInternal) { - sheInternal->RemoveFromBFCacheSync(); - } + nsIBFCacheEntry* bfCacheEntry; + if (ownerDoc && (bfCacheEntry = ownerDoc->GetBFCacheEntry())) { + bfCacheEntry->RemoveFromBFCacheSync(); NS_ASSERTION(database->IsClosed(), "Kicking doc out of bfcache should have closed database"); continue; diff --git a/dom/interfaces/base/nsIFocusManager.idl b/dom/interfaces/base/nsIFocusManager.idl index 59fb1409de22..6de2b32bc25c 100644 --- a/dom/interfaces/base/nsIFocusManager.idl +++ b/dom/interfaces/base/nsIFocusManager.idl @@ -158,7 +158,7 @@ interface nsIFocusManager : nsISupports * * @throws NS_ERROR_INVALID_ARG if aWindow is null */ - nsIDOMElement getFocusedElementForWindow(in nsIDOMWindow aWindow, in PRBool aDeep, + nsIDOMElement getFocusedElementForWindow(in nsIDOMWindow aWindow, in boolean aDeep, out nsIDOMWindow aFocusedWindow); /** @@ -249,7 +249,7 @@ interface nsIFocusManager : nsISupports * If aNeedsFocus is true, then focus events are expected to be fired on the * window if this window is in the focused window chain. */ - [noscript] void windowShown(in nsIDOMWindow aWindow, in PRBool aNeedsFocus); + [noscript] void windowShown(in nsIDOMWindow aWindow, in boolean aNeedsFocus); /** * Called when a document in a window has been hidden or otherwise can no diff --git a/dom/interfaces/events/nsIDOMDataTransfer.idl b/dom/interfaces/events/nsIDOMDataTransfer.idl index 71e1e264fea7..9cdd3cf4c40d 100644 --- a/dom/interfaces/events/nsIDOMDataTransfer.idl +++ b/dom/interfaces/events/nsIDOMDataTransfer.idl @@ -181,7 +181,7 @@ interface nsIDOMNSDataTransfer : nsISupports * user cancelled flag. */ [noscript] nsIDOMDataTransfer clone(in PRUint32 aEventType, - in PRBool aUserCancelled); + in boolean aUserCancelled); /** * The number of items being dragged. diff --git a/dom/interfaces/events/nsIDOMEventTarget.idl b/dom/interfaces/events/nsIDOMEventTarget.idl index 4a8f2012d20d..701306de358b 100644 --- a/dom/interfaces/events/nsIDOMEventTarget.idl +++ b/dom/interfaces/events/nsIDOMEventTarget.idl @@ -253,19 +253,6 @@ interface nsIDOMEventTarget : nsISupports [notxpcom, nostdcall] nsEventListenerManagerPtr GetListenerManager(in boolean aMayCreate); - /** - * Add an event listener for nsIID. - */ - [noscript, nostdcall] - void AddEventListenerByIID(in nsIDOMEventListener aListener, - in nsIIDRef aIID); - /** - * Remove event listener for nsIID. - */ - [noscript, nostdcall] - void RemoveEventListenerByIID(in nsIDOMEventListener aListener, - in nsIIDRef aIID); - /** * Get the script context in which the event handlers should be run. * May return null. diff --git a/dom/interfaces/html/Makefile.in b/dom/interfaces/html/Makefile.in index e0b55765e91c..1814bafc3dcf 100644 --- a/dom/interfaces/html/Makefile.in +++ b/dom/interfaces/html/Makefile.in @@ -55,6 +55,7 @@ SDK_XPIDLSRCS = \ nsIDOMHTMLBodyElement.idl \ nsIDOMHTMLButtonElement.idl \ nsIDOMHTMLCollection.idl \ + nsIDOMHTMLCommandElement.idl \ nsIDOMHTMLDataListElement.idl \ nsIDOMHTMLDListElement.idl \ nsIDOMHTMLDirectoryElement.idl \ @@ -80,6 +81,7 @@ SDK_XPIDLSRCS = \ nsIDOMHTMLLinkElement.idl \ nsIDOMHTMLMapElement.idl \ nsIDOMHTMLMenuElement.idl \ + nsIDOMHTMLMenuItemElement.idl \ nsIDOMHTMLMetaElement.idl \ nsIDOMHTMLModElement.idl \ nsIDOMHTMLOListElement.idl \ diff --git a/dom/public/coreEvents/nsIDOMTextListener.h b/dom/interfaces/html/nsIDOMHTMLCommandElement.idl similarity index 61% rename from dom/public/coreEvents/nsIDOMTextListener.h rename to dom/interfaces/html/nsIDOMHTMLCommandElement.idl index a7d135d8fa6e..3b5ebbd5e019 100644 --- a/dom/public/coreEvents/nsIDOMTextListener.h +++ b/dom/interfaces/html/nsIDOMHTMLCommandElement.idl @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -12,11 +12,10 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is mozilla.org code. + * The Original Code is Mozilla. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -35,30 +34,26 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef nsIDOMTextListener_h__ -#define nsIDOMTextListener_h__ +#include "nsIDOMHTMLElement.idl" -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Key pressed / released / typed listener interface. +/** + * The nsIDOMHTMLCommandElement interface is the interface to a HTML + * element. + * + * For more information on this interface, please see + * http://www.whatwg.org/specs/web-apps/current-work/#the-command-element + * + * @status UNDER_DEVELOPMENT */ -// {C6296E81-D823-11d2-9E7F-0060089FE59B} -#define NS_IDOMTEXTLISTENER_IID \ -{ 0xc6296e81, 0xd823, 0x11d2, { 0x9e, 0x7f, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } } - -class nsIDOMTextListener : public nsIDOMEventListener +[scriptable, uuid(df4a19b4-81f1-412e-a971-fcbe7312a9b6)] +interface nsIDOMHTMLCommandElement : nsIDOMHTMLElement { -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMTEXTLISTENER_IID) - - NS_IMETHOD HandleText(nsIDOMEvent* aTextEvent) = 0; - + attribute DOMString type; + attribute DOMString label; + attribute DOMString icon; + attribute boolean disabled; + attribute boolean defaultChecked; + attribute boolean checked; + attribute DOMString radiogroup; }; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMTextListener, NS_IDOMTEXTLISTENER_IID) - -#endif // nsIDOMTextListener_h__ diff --git a/dom/interfaces/html/nsIDOMHTMLMenuElement.idl b/dom/interfaces/html/nsIDOMHTMLMenuElement.idl index 2b0cc66b4c2c..55e0c6f14249 100644 --- a/dom/interfaces/html/nsIDOMHTMLMenuElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLMenuElement.idl @@ -50,8 +50,11 @@ * http://www.whatwg.org/specs/web-apps/current-work/ */ -[scriptable, uuid(318d9314-f97b-4b7e-96ff-95f0cb203fdf)] +[scriptable, uuid(43aa6818-f67f-420c-a400-59a2668e9fe5)] interface nsIDOMHTMLMenuElement : nsIDOMHTMLElement { attribute boolean compact; + + attribute DOMString type; + attribute DOMString label; }; diff --git a/toolkit/components/webapps/nsWebappsSupport.h b/dom/interfaces/html/nsIDOMHTMLMenuItemElement.idl similarity index 69% rename from toolkit/components/webapps/nsWebappsSupport.h rename to dom/interfaces/html/nsIDOMHTMLMenuItemElement.idl index 49b4cc79482a..7152c412ec7c 100644 --- a/toolkit/components/webapps/nsWebappsSupport.h +++ b/dom/interfaces/html/nsIDOMHTMLMenuItemElement.idl @@ -1,5 +1,5 @@ -/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version @@ -12,18 +12,17 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Mozilla Webapp code. + * The Original Code is Mozilla. * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Fabrice Desré * * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to @@ -35,22 +34,16 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef nsWebappsSupport_h__ -#define nsWebappsSupport_h__ +#include "nsIDOMHTMLCommandElement.idl" -#include "nsIWebappsSupport.h" +/** + * The nsIDOMHTMLMenuItemElement interface is the interface to a HTML + * element. + * + * @status UNDER_DEVELOPMENT + */ -class nsWebappsSupport : public nsIWebappsSupport +[scriptable, uuid(613f28ee-01f5-42dc-8224-161f85f0f20b)] +interface nsIDOMHTMLMenuItemElement : nsIDOMHTMLCommandElement { -public: - - NS_DECL_ISUPPORTS - NS_DECL_NSIWEBAPPSSUPPORT - - nsWebappsSupport() {}; - ~nsWebappsSupport() {}; - }; - -#endif // nsWebappsSupport_h__ - diff --git a/dom/interfaces/html/nsIDOMNSHTMLElement.idl b/dom/interfaces/html/nsIDOMNSHTMLElement.idl index 0000b619d2ec..08d85f553b12 100644 --- a/dom/interfaces/html/nsIDOMNSHTMLElement.idl +++ b/dom/interfaces/html/nsIDOMNSHTMLElement.idl @@ -39,8 +39,9 @@ #include "domstubs.idl" interface nsIDOMDOMStringMap; +interface nsIDOMHTMLMenuElement; -[scriptable, uuid(4012e9a9-f6fb-48b3-9a80-b096c1dcb5ba)] +[scriptable, uuid(0c3b4b63-30b2-4c93-906d-f983ee9af584)] interface nsIDOMNSHTMLElement : nsISupports { readonly attribute long offsetTop; @@ -71,7 +72,8 @@ interface nsIDOMNSHTMLElement : nsISupports [optional_argc] void scrollIntoView([optional] in boolean top); + readonly attribute nsIDOMHTMLMenuElement contextMenu; attribute boolean spellcheck; - + readonly attribute nsIDOMDOMStringMap dataset; }; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 86675d4caa30..d23d92bea4c8 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -565,8 +565,11 @@ bool ContentParent::RecvGetSystemColors(const PRUint32& colorsCount, InfallibleTArray* colors) { #ifdef ANDROID - if (!AndroidBridge::Bridge()) - return false; + NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available"); + if (AndroidBridge::Bridge() == nsnull) { + // Do not fail - the colors won't be right, but it's not critical + return true; + } colors->AppendElements(colorsCount); @@ -581,8 +584,11 @@ bool ContentParent::RecvGetIconForExtension(const nsCString& aFileExt, const PRUint32& aIconSize, InfallibleTArray* bits) { #ifdef ANDROID - if (!AndroidBridge::Bridge()) - return false; + NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available"); + if (AndroidBridge::Bridge() == nsnull) { + // Do not fail - just no icon will be shown + return true; + } bits->AppendElements(aIconSize * aIconSize * 4); diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 4440fcc6b105..d66aab478ad6 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -70,7 +70,6 @@ using mozilla::DefaultXDisplay; #include "nsContentUtils.h" #include "nsRect.h" #include "nsSize.h" -#include "nsIDOMContextMenuListener.h" #include "nsDisplayList.h" #include "ImageLayers.h" #include "nsIDOMEventTarget.h" @@ -124,23 +123,18 @@ using namespace mozilla; // special class for handeling DOM context menu events because for // some reason it starves other mouse events if implemented on the // same class -class nsPluginDOMContextMenuListener : public nsIDOMContextMenuListener +class nsPluginDOMContextMenuListener : public nsIDOMEventListener { public: nsPluginDOMContextMenuListener(); virtual ~nsPluginDOMContextMenuListener(); NS_DECL_ISUPPORTS + NS_DECL_NSIDOMEVENTLISTENER - NS_IMETHOD ContextMenu(nsIDOMEvent* aContextMenuEvent); - nsresult Init(nsIContent* aContent); nsresult Destroy(nsIContent* aContent); - NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) - { - return NS_OK; - } nsEventStatus ProcessEvent(const nsGUIEvent& anEvent) { return nsEventStatus_eConsumeNoDefault; @@ -385,19 +379,10 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner() } } -NS_IMPL_ADDREF(nsPluginInstanceOwner) -NS_IMPL_RELEASE(nsPluginInstanceOwner) - -NS_INTERFACE_MAP_BEGIN(nsPluginInstanceOwner) - NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner) - NS_INTERFACE_MAP_ENTRY(nsIPluginTagInfo) - NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) - NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener) - NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener) - NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPluginInstanceOwner) -NS_INTERFACE_MAP_END +NS_IMPL_ISUPPORTS3(nsPluginInstanceOwner, + nsIPluginInstanceOwner, + nsIPluginTagInfo, + nsIDOMEventListener) nsresult nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance) @@ -1673,19 +1658,6 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY) #endif } -/*=============== nsIDOMFocusListener ======================*/ -nsresult nsPluginInstanceOwner::Focus(nsIDOMEvent * aFocusEvent) -{ - mContentFocused = PR_TRUE; - return DispatchFocusToPlugin(aFocusEvent); -} - -nsresult nsPluginInstanceOwner::Blur(nsIDOMEvent * aFocusEvent) -{ - mContentFocused = PR_FALSE; - return DispatchFocusToPlugin(aFocusEvent); -} - nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) { #ifndef XP_MACOSX @@ -1715,18 +1687,6 @@ nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) return NS_OK; } - -/*=============== nsIKeyListener ======================*/ -nsresult nsPluginInstanceOwner::KeyDown(nsIDOMEvent* aKeyEvent) -{ - return DispatchKeyToPlugin(aKeyEvent); -} - -nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent) -{ - return DispatchKeyToPlugin(aKeyEvent); -} - nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent) { #ifdef XP_MACOSX @@ -1738,11 +1698,10 @@ nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent) nsCOMPtr privateEvent(do_QueryInterface(aKeyEvent)); if (privateEvent) { nsEvent *theEvent = privateEvent->GetInternalNSEvent(); - const nsGUIEvent *guiEvent = (nsGUIEvent*)theEvent; - const EventRecord *ev = (EventRecord*)(guiEvent->pluginEvent); - if (guiEvent && - guiEvent->message == NS_KEY_PRESS && - ev && + const EventRecord *ev; + if (theEvent && + theEvent->message == NS_KEY_PRESS && + (ev = (EventRecord*)(((nsGUIEvent*)theEvent)->pluginEvent)) && ev->what == keyDown) return aKeyEvent->PreventDefault(); // consume event } @@ -1789,9 +1748,9 @@ nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent) if (mInstance) { nsCOMPtr privateEvent(do_QueryInterface(aKeyEvent)); if (privateEvent) { - nsKeyEvent *keyEvent = (nsKeyEvent *) privateEvent->GetInternalNSEvent(); - if (keyEvent) { - nsEventStatus rv = ProcessEvent(*keyEvent); + nsEvent *event = privateEvent->GetInternalNSEvent(); + if (event && event->eventStructType == NS_KEY_EVENT) { + nsEventStatus rv = ProcessEvent(*static_cast(event)); if (nsEventStatus_eConsumeNoDefault == rv) { aKeyEvent->PreventDefault(); aKeyEvent->StopPropagation(); @@ -1805,39 +1764,6 @@ nsresult nsPluginInstanceOwner::DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent) return NS_OK; } -/*=============== nsIDOMMouseMotionListener ======================*/ - -nsresult -nsPluginInstanceOwner::MouseMove(nsIDOMEvent* aMouseEvent) -{ -#if !defined(XP_MACOSX) - if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) - return aMouseEvent->PreventDefault(); // consume event - // continue only for cases without child window -#endif - - // don't send mouse events if we are hidden - if (!mWidgetVisible) - return NS_OK; - - nsCOMPtr privateEvent(do_QueryInterface(aMouseEvent)); - if (privateEvent) { - nsMouseEvent* mouseEvent = (nsMouseEvent *) privateEvent->GetInternalNSEvent(); - if (mouseEvent) { - nsEventStatus rv = ProcessEvent(*mouseEvent); - if (nsEventStatus_eConsumeNoDefault == rv) { - return aMouseEvent->PreventDefault(); // consume event - } - } - else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::MouseMove failed, mouseEvent null"); - } - else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::MouseMove failed, privateEvent null"); - - return NS_OK; -} - -/*=============== nsIDOMMouseListener ======================*/ - nsresult nsPluginInstanceOwner::MouseDown(nsIDOMEvent* aMouseEvent) { @@ -1861,9 +1787,9 @@ nsPluginInstanceOwner::MouseDown(nsIDOMEvent* aMouseEvent) nsCOMPtr privateEvent(do_QueryInterface(aMouseEvent)); if (privateEvent) { - nsMouseEvent* mouseEvent = (nsMouseEvent *) privateEvent->GetInternalNSEvent(); - if (mouseEvent) { - nsEventStatus rv = ProcessEvent(*mouseEvent); + nsEvent* event = privateEvent->GetInternalNSEvent(); + if (event && event->eventStructType == NS_MOUSE_EVENT) { + nsEventStatus rv = ProcessEvent(*static_cast(event)); if (nsEventStatus_eConsumeNoDefault == rv) { return aMouseEvent->PreventDefault(); // consume event } @@ -1875,44 +1801,6 @@ nsPluginInstanceOwner::MouseDown(nsIDOMEvent* aMouseEvent) return NS_OK; } -nsresult -nsPluginInstanceOwner::MouseUp(nsIDOMEvent* aMouseEvent) -{ - // Don't send a mouse-up event to the plugin if it isn't focused. This can - // happen if the previous mouse-down was sent to a DOM element above the - // plugin, the mouse is still above the plugin, and the mouse-down event - // caused the element to disappear. See bug 627649. - if (!mContentFocused) { - aMouseEvent->PreventDefault(); - return NS_OK; - } - return DispatchMouseToPlugin(aMouseEvent); -} - -nsresult -nsPluginInstanceOwner::MouseClick(nsIDOMEvent* aMouseEvent) -{ - return DispatchMouseToPlugin(aMouseEvent); -} - -nsresult -nsPluginInstanceOwner::MouseDblClick(nsIDOMEvent* aMouseEvent) -{ - return DispatchMouseToPlugin(aMouseEvent); -} - -nsresult -nsPluginInstanceOwner::MouseOver(nsIDOMEvent* aMouseEvent) -{ - return DispatchMouseToPlugin(aMouseEvent); -} - -nsresult -nsPluginInstanceOwner::MouseOut(nsIDOMEvent* aMouseEvent) -{ - return DispatchMouseToPlugin(aMouseEvent); -} - nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent) { #if !defined(XP_MACOSX) @@ -1926,9 +1814,9 @@ nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent) nsCOMPtr privateEvent(do_QueryInterface(aMouseEvent)); if (privateEvent) { - nsMouseEvent* mouseEvent = (nsMouseEvent *) privateEvent->GetInternalNSEvent(); - if (mouseEvent) { - nsEventStatus rv = ProcessEvent(*mouseEvent); + nsEvent* event = privateEvent->GetInternalNSEvent(); + if (event && event->eventStructType == NS_MOUSE_EVENT) { + nsEventStatus rv = ProcessEvent(*static_cast(event)); if (nsEventStatus_eConsumeNoDefault == rv) { aMouseEvent->PreventDefault(); aMouseEvent->StopPropagation(); @@ -1944,10 +1832,49 @@ nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent) nsresult nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent) { - if (mInstance) { + nsAutoString eventType; + aEvent->GetType(eventType); + if (eventType.EqualsLiteral("focus")) { + mContentFocused = PR_TRUE; + return DispatchFocusToPlugin(aEvent); + } + if (eventType.EqualsLiteral("blur")) { + mContentFocused = PR_FALSE; + return DispatchFocusToPlugin(aEvent); + } + if (eventType.EqualsLiteral("mousedown")) { + return MouseDown(aEvent); + } + if (eventType.EqualsLiteral("mouseup")) { + // Don't send a mouse-up event to the plugin if it isn't focused. This can + // happen if the previous mouse-down was sent to a DOM element above the + // plugin, the mouse is still above the plugin, and the mouse-down event + // caused the element to disappear. See bug 627649. + if (!mContentFocused) { + aEvent->PreventDefault(); + return NS_OK; + } + return DispatchMouseToPlugin(aEvent); + } + if (eventType.EqualsLiteral("mousemove") || + eventType.EqualsLiteral("click") || + eventType.EqualsLiteral("dblclick") || + eventType.EqualsLiteral("mouseover") || + eventType.EqualsLiteral("mouseout")) { + return DispatchMouseToPlugin(aEvent); + } + if (eventType.EqualsLiteral("keydown") || + eventType.EqualsLiteral("keyup")) { + return DispatchKeyToPlugin(aEvent); + } + if (eventType.EqualsLiteral("keypress")) { + return KeyPress(aEvent); + } + + nsCOMPtr dragEvent(do_QueryInterface(aEvent)); + if (dragEvent && mInstance) { nsCOMPtr privateEvent(do_QueryInterface(aEvent)); - nsCOMPtr dragEvent(do_QueryInterface(aEvent)); - if (privateEvent && dragEvent) { + if (privateEvent) { nsEvent* ievent = privateEvent->GetInternalNSEvent(); if (ievent && NS_IS_TRUSTED_EVENT(ievent) && (ievent->message == NS_DRAGDROP_ENTER || ievent->message == NS_DRAGDROP_OVER)) { @@ -2506,38 +2433,28 @@ nsPluginInstanceOwner::Destroy() mCXMenuListener = nsnull; } - nsCOMPtr target(do_QueryInterface(mContent)); - if (target) { - - nsCOMPtr listener; - QueryInterface(NS_GET_IID(nsIDOMEventListener), getter_AddRefs(listener)); - - // Unregister focus event listener - mContent->RemoveEventListenerByIID(listener, NS_GET_IID(nsIDOMFocusListener)); - - // Unregister mouse event listener - mContent->RemoveEventListenerByIID(listener, NS_GET_IID(nsIDOMMouseListener)); - - // now for the mouse motion listener - mContent->RemoveEventListenerByIID(listener, NS_GET_IID(nsIDOMMouseMotionListener)); - - // Unregister key event listener; - target->RemoveEventListener(NS_LITERAL_STRING("keypress"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("keydown"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("keyup"), listener, PR_TRUE); - - // Unregister drag event listener; - target->RemoveEventListener(NS_LITERAL_STRING("drop"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragdrop"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("drag"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragenter"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragover"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragexit"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragleave"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragstart"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("draggesture"), listener, PR_TRUE); - target->RemoveEventListener(NS_LITERAL_STRING("dragend"), listener, PR_TRUE); - } + mContent->RemoveEventListener(NS_LITERAL_STRING("focus"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dblclick"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, PR_FALSE); + mContent->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("drop"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragdrop"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("drag"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragenter"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragover"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragleave"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragexit"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragstart"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("draggesture"), this, PR_TRUE); + mContent->RemoveEventListener(NS_LITERAL_STRING("dragend"), this, PR_TRUE); if (mWidget) { nsCOMPtr pluginWidget = do_QueryInterface(mWidget); @@ -2967,38 +2884,37 @@ nsresult nsPluginInstanceOwner::Init(nsPresContext* aPresContext, mCXMenuListener->Init(aContent); } - nsCOMPtr target(do_QueryInterface(mContent)); - if (target) { - - nsCOMPtr listener; - QueryInterface(NS_GET_IID(nsIDOMEventListener), getter_AddRefs(listener)); - - // Register focus listener - mContent->AddEventListenerByIID(listener, NS_GET_IID(nsIDOMFocusListener)); - - // Register mouse listener - mContent->AddEventListenerByIID(listener, NS_GET_IID(nsIDOMMouseListener)); - - // now do the mouse motion listener - mContent->AddEventListenerByIID(listener, NS_GET_IID(nsIDOMMouseMotionListener)); - - // Register key listener - target->AddEventListener(NS_LITERAL_STRING("keypress"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("keydown"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("keyup"), listener, PR_TRUE); - - // Register drag listener - target->AddEventListener(NS_LITERAL_STRING("drop"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragdrop"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("drag"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragenter"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragover"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragleave"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragexit"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragstart"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("draggesture"), listener, PR_TRUE); - target->AddEventListener(NS_LITERAL_STRING("dragend"), listener, PR_TRUE); - } + mContent->AddEventListener(NS_LITERAL_STRING("focus"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, PR_FALSE, + PR_FALSE); + mContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("drop"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragdrop"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("drag"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragenter"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragover"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragleave"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragexit"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragstart"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("draggesture"), this, PR_TRUE); + mContent->AddEventListener(NS_LITERAL_STRING("dragend"), this, PR_TRUE); // Register scroll position listeners // We need to register a scroll position listener on every scrollable @@ -3393,14 +3309,13 @@ nsPluginDOMContextMenuListener::~nsPluginDOMContextMenuListener() { } -NS_IMPL_ISUPPORTS2(nsPluginDOMContextMenuListener, - nsIDOMContextMenuListener, +NS_IMPL_ISUPPORTS1(nsPluginDOMContextMenuListener, nsIDOMEventListener) NS_IMETHODIMP -nsPluginDOMContextMenuListener::ContextMenu(nsIDOMEvent* aContextMenuEvent) +nsPluginDOMContextMenuListener::HandleEvent(nsIDOMEvent* aEvent) { - aContextMenuEvent->PreventDefault(); // consume event + aEvent->PreventDefault(); // consume event return NS_OK; } diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 620eafda67cd..21eeac2bfa7f 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -52,15 +52,17 @@ #include "nsCOMPtr.h" #include "nsIPluginInstanceOwner.h" #include "nsIPluginTagInfo.h" -#include "nsIDOMMouseListener.h" -#include "nsIDOMMouseMotionListener.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMFocusListener.h" +#include "nsIDOMEventListener.h" #include "nsIScrollPositionListener.h" #include "nsPluginHost.h" #include "nsPluginNativeWindow.h" #include "gfxRect.h" +// X.h defines KeyPress +#ifdef KeyPress +#undef KeyPress +#endif + #ifdef XP_MACOSX #include "nsCoreAnimationSupport.h" #include @@ -90,12 +92,14 @@ class gfxXlibSurface; #include #endif +// X.h defines KeyPress +#ifdef KeyPress +#undef KeyPress +#endif + class nsPluginInstanceOwner : public nsIPluginInstanceOwner, public nsIPluginTagInfo, - public nsIDOMMouseListener, - public nsIDOMMouseMotionListener, - public nsIDOMKeyListener, - public nsIDOMFocusListener, + public nsIDOMEventListener, public nsIScrollPositionListener { public: @@ -119,28 +123,12 @@ public: //nsIPluginTagInfo interface NS_DECL_NSIPLUGINTAGINFO - // nsIDOMMouseListener interfaces - NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent); - NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent); - NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent); - NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent); - NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent); - NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent); - NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); - - // nsIDOMMouseMotionListener interfaces - NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent); - NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent) { return NS_OK; } - - // nsIDOMKeyListener interfaces - NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent); - NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent); - NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent); - - // nsIDOMFocusListener interfaces - NS_IMETHOD Focus(nsIDOMEvent * aFocusEvent); - NS_IMETHOD Blur(nsIDOMEvent * aFocusEvent); + // nsIDOMEventListener interfaces + NS_DECL_NSIDOMEVENTLISTENER + nsresult MouseDown(nsIDOMEvent* aKeyEvent); + nsresult KeyPress(nsIDOMEvent* aKeyEvent); + nsresult Destroy(); void PrepareToStop(PRBool aDelayedStop); diff --git a/dom/plugins/test/testplugin/nptest_gtk2.cpp b/dom/plugins/test/testplugin/nptest_gtk2.cpp index ba6632c8aba9..cc66bc8cec42 100644 --- a/dom/plugins/test/testplugin/nptest_gtk2.cpp +++ b/dom/plugins/test/testplugin/nptest_gtk2.cpp @@ -303,15 +303,15 @@ pluginWidgetInit(InstanceData* instanceData, void* oldWindow) /* all the events that our widget wants to receive */ gtk_widget_add_events(plug, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - g_signal_connect(G_OBJECT(plug), "expose-event", G_CALLBACK(ExposeWidget), + g_signal_connect(plug, "expose-event", G_CALLBACK(ExposeWidget), instanceData); - g_signal_connect(G_OBJECT(plug), "motion_notify_event", G_CALLBACK(MotionEvent), + g_signal_connect(plug, "motion_notify_event", G_CALLBACK(MotionEvent), instanceData); - g_signal_connect(G_OBJECT(plug), "button_press_event", G_CALLBACK(ButtonEvent), + g_signal_connect(plug, "button_press_event", G_CALLBACK(ButtonEvent), instanceData); - g_signal_connect(G_OBJECT(plug), "button_release_event", G_CALLBACK(ButtonEvent), + g_signal_connect(plug, "button_release_event", G_CALLBACK(ButtonEvent), instanceData); - g_signal_connect(G_OBJECT(plug), "delete-event", G_CALLBACK(DeleteWidget), + g_signal_connect(plug, "delete-event", G_CALLBACK(DeleteWidget), instanceData); gtk_widget_show(plug); @@ -374,7 +374,7 @@ pluginHandleEvent(InstanceData* instanceData, void* event) gdk_x11_colormap_foreign_new(gdkVisual, instanceData->platformData->colormap); gdk_drawable_set_colormap(gdkDrawable, gdkColormap); - g_object_unref(G_OBJECT(gdkColormap)); + g_object_unref(gdkColormap); } const NPRect& clip = window.clipRect; diff --git a/dom/public/coreEvents/Makefile.in b/dom/public/coreEvents/Makefile.in deleted file mode 100644 index 0f66d2cc03ee..000000000000 --- a/dom/public/coreEvents/Makefile.in +++ /dev/null @@ -1,61 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = dom - -EXPORTS = \ - nsIDOMFocusListener.h \ - nsIDOMFormListener.h \ - nsIDOMKeyListener.h \ - nsIDOMLoadListener.h \ - nsIDOMMouseListener.h \ - nsIDOMMouseMotionListener.h \ - nsIDOMTextListener.h \ - nsIDOMCompositionListener.h \ - nsIDOMContextMenuListener.h \ - nsIDOMUIListener.h \ - $(NULL) - -include $(topsrcdir)/config/rules.mk - diff --git a/dom/public/coreEvents/nsIDOMCompositionListener.h b/dom/public/coreEvents/nsIDOMCompositionListener.h deleted file mode 100644 index 1b234c97543a..000000000000 --- a/dom/public/coreEvents/nsIDOMCompositionListener.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsIDOMCompositionListener_h__ -#define nsIDOMCompositionListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Key pressed / released / typed listener interface. - */ -// {47F158C0-C534-43a1-8415-8B17706E2FBC} -#define NS_IDOMCOMPOSITIONLISTENER_IID \ -{ 0x47f158c0, 0xc534, 0x43a1, \ -{ 0x84, 0x15, 0x8b, 0x17, 0x70, 0x6e, 0x2f, 0xbc } } - - -class nsIDOMCompositionListener : public nsIDOMEventListener { - -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMCOMPOSITIONLISTENER_IID) - - NS_IMETHOD HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0; - NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMCompositionListener, - NS_IDOMCOMPOSITIONLISTENER_IID) - -#endif // nsIDOMCompositionListener_h__ diff --git a/dom/public/coreEvents/nsIDOMFormListener.h b/dom/public/coreEvents/nsIDOMFormListener.h deleted file mode 100644 index 2a3238f5a393..000000000000 --- a/dom/public/coreEvents/nsIDOMFormListener.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef nsIDOMFormListener_h__ -#define nsIDOMFormListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Form submit/reset listener - * - */ -#define NS_IDOMFORMLISTENER_IID \ -{ /* 566c3f80-28ab-11d2-bd89-00805f8ae3f4 */ \ -0x566c3f80, 0x28ab, 0x11d2, \ -{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } - -class nsIDOMFormListener : public nsIDOMEventListener { - -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMFORMLISTENER_IID) - /** - * Processes a form submit event - * @param aEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Submit(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a form reset event - * @param aEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Reset(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a form change event - * @param aEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Change(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a form select event - * @param aEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Select(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a form input event - * @param aEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Input(nsIDOMEvent* aEvent) = 0; - -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMFormListener, NS_IDOMFORMLISTENER_IID) - -#endif // nsIDOMFormListener_h__ diff --git a/dom/public/coreEvents/nsIDOMKeyListener.h b/dom/public/coreEvents/nsIDOMKeyListener.h deleted file mode 100644 index a9f1a6c0730f..000000000000 --- a/dom/public/coreEvents/nsIDOMKeyListener.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsIDOMKeyListener_h__ -#define nsIDOMKeyListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -// X.h defines KeyPress -#ifdef KeyPress -#undef KeyPress -#endif - -/* - * Key pressed / released / typed listener interface. - */ -#define NS_IDOMKEYLISTENER_IID \ -{ /* 35f0d080-da38-11d1-bd85-00805f8ae3f4 */ \ -0x35f0d080, 0xda38, 0x11d1, \ -{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } - -class nsIDOMKeyListener : public nsIDOMEventListener { - -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMKEYLISTENER_IID) - - /** - * Processes a key pressed event - * @param aKeyEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent) = 0; - - /** - * Processes a key release event - * @param aKeyEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent) = 0; - - /** - * Processes a key typed event - * @param aKeyEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - * - */ - NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent) = 0; - -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMKeyListener, NS_IDOMKEYLISTENER_IID) - -#endif // nsIDOMKeyListener_h__ diff --git a/dom/public/coreEvents/nsIDOMLoadListener.h b/dom/public/coreEvents/nsIDOMLoadListener.h deleted file mode 100644 index d2d3af464c7e..000000000000 --- a/dom/public/coreEvents/nsIDOMLoadListener.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef nsIDOMLoadListener_h__ -#define nsIDOMLoadListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Document load related event listener - * - */ -#define NS_IDOMLOADLISTENER_IID \ -{ /* d1810238-14f8-4cab-9b96-96bedb9de7be */ \ -0xd1810238, 0x14f8, 0x4cab, \ -{0x9b, 0x96, 0x96, 0xbe, 0xdb, 0x9d, 0xe7, 0xbe} } - -class nsIDOMLoadListener : public nsIDOMEventListener { - -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMLOADLISTENER_IID) - /** - * Processes a page or image load event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Load(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a page beforeUnload event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a page unload event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Unload(nsIDOMEvent* aEvent) = 0; - - /** - * Processes a load abort event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - * - */ - NS_IMETHOD Abort(nsIDOMEvent* aEvent) = 0; - - /** - * Processes an load error event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD Error(nsIDOMEvent* aEvent) = 0; - -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMLoadListener, NS_IDOMLOADLISTENER_IID) - -#endif // nsIDOMLoadListener_h__ diff --git a/dom/public/coreEvents/nsIDOMMouseListener.h b/dom/public/coreEvents/nsIDOMMouseListener.h deleted file mode 100644 index f09c2b732196..000000000000 --- a/dom/public/coreEvents/nsIDOMMouseListener.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef nsIDOMMouseListener_h__ -#define nsIDOMMouseListener_h__ - -#include "nsIDOMEvent.h" -#include "nsIDOMEventListener.h" - -/* - * Mouse up/down/move event listener - * - */ -#define NS_IDOMMOUSELISTENER_IID \ -{ /* ccd7fa30-da37-11d1-bd85-00805f8ae3f4 */ \ -0xccd7fa30, 0xda37, 0x11d1, \ -{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } - -class nsIDOMMouseListener : public nsIDOMEventListener { - -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMMOUSELISTENER_IID) - - /** - * Processes a mouse down event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a mouse up event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a mouse click event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - * - */ - NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a mouse click event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - * - */ - NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a mouse enter event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent) = 0; - - /** - * Processes a mouse leave event - * @param aMouseEvent @see nsIDOMEvent.h - * @returns whether the event was consumed or ignored. @see nsresult - */ - NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent) = 0; - -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMMouseListener, NS_IDOMMOUSELISTENER_IID) - -#endif // nsIDOMMouseListener_h__ diff --git a/dom/public/coreEvents/nsIDOMUIListener.h b/dom/public/coreEvents/nsIDOMUIListener.h deleted file mode 100644 index 6ec746606021..000000000000 --- a/dom/public/coreEvents/nsIDOMUIListener.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsIDOMUIListener_h__ -#define nsIDOMUIListener_h__ - -#include "nsIDOMEventListener.h" - -class nsIDOMEvent; - -/* - * UI event listener interface. - */ -// {5cb5527a-512f-4163-9393-ca95ceddbc13} -#define NS_IDOMUILISTENER_IID \ -{ 0x5cb5527a, 0x512f, 0x4163, { 0x93, 0x93, 0xca, 0x95, 0xce, 0xdd, 0xbc, 0x13 } } - -class nsIDOMUIListener : public nsIDOMEventListener { - public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMUILISTENER_IID) - - NS_IMETHOD Activate(nsIDOMEvent* aEvent) = 0; - NS_IMETHOD FocusIn(nsIDOMEvent* aEvent) = 0; - NS_IMETHOD FocusOut(nsIDOMEvent* aEvent) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMUIListener, NS_IDOMUILISTENER_IID) - -#endif // nsIDOMUIListener_h__ diff --git a/dom/src/events/nsJSEventListener.h b/dom/src/events/nsJSEventListener.h index f80d96c2d86f..eb85495138e4 100644 --- a/dom/src/events/nsJSEventListener.h +++ b/dom/src/events/nsJSEventListener.h @@ -40,7 +40,7 @@ #include "nsIDOMKeyEvent.h" #include "nsIJSEventListener.h" -#include "nsIDOMMouseListener.h" +#include "nsIDOMEventListener.h" #include "jsapi.h" #include "nsCOMPtr.h" #include "nsIAtom.h" diff --git a/dom/src/storage/Makefile.in b/dom/src/storage/Makefile.in index 9faf2150cf43..f7ca95019e21 100644 --- a/dom/src/storage/Makefile.in +++ b/dom/src/storage/Makefile.in @@ -46,20 +46,17 @@ MODULE = dom LIBRARY_NAME = jsdomstorage_s LIBXUL_LIBRARY = 1 - - -CPPSRCS = \ - nsDOMStorage.cpp \ +CPPSRCS = \ + nsDOMStorage.cpp \ + nsDOMStorageDBWrapper.cpp \ + nsDOMStoragePersistentDB.cpp \ + nsDOMStorageMemoryDB.cpp \ + StorageChild.cpp \ + StorageParent.cpp \ $(NULL) -ifdef MOZ_STORAGE -CPPSRCS += nsDOMStorageDBWrapper.cpp nsDOMStoragePersistentDB.cpp nsDOMStorageMemoryDB.cpp - -CPPSRCS += StorageChild.cpp StorageParent.cpp - EXPORTS_NAMESPACES = mozilla/dom EXPORTS_mozilla/dom = StorageChild.h StorageParent.h -endif # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1 diff --git a/dom/src/storage/nsDOMStorage.cpp b/dom/src/storage/nsDOMStorage.cpp index 89e1fd018316..3aaeefeb52d8 100644 --- a/dom/src/storage/nsDOMStorage.cpp +++ b/dom/src/storage/nsDOMStorage.cpp @@ -286,12 +286,10 @@ nsDOMStorageManager::Initialize() os->AddObserver(gStorageManager, "profile-after-change", PR_FALSE); os->AddObserver(gStorageManager, "perm-changed", PR_FALSE); os->AddObserver(gStorageManager, "browser:purge-domain-data", PR_FALSE); -#ifdef MOZ_STORAGE // Used for temporary table flushing os->AddObserver(gStorageManager, "profile-before-change", PR_FALSE); os->AddObserver(gStorageManager, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); os->AddObserver(gStorageManager, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_FALSE); -#endif return NS_OK; } @@ -313,10 +311,8 @@ nsDOMStorageManager::Shutdown() NS_IF_RELEASE(gStorageManager); gStorageManager = nsnull; -#ifdef MOZ_STORAGE delete DOMStorageImpl::gStorageDB; DOMStorageImpl::gStorageDB = nsnull; -#endif } static PLDHashOperator @@ -389,17 +385,14 @@ nsDOMStorageManager::Observe(nsISupports *aSubject, pbs->GetPrivateBrowsingEnabled(&gStorageManager->mInPrivateBrowsing); } else if (!strcmp(aTopic, "offline-app-removed")) { -#ifdef MOZ_STORAGE nsresult rv = DOMStorageImpl::InitDB(); NS_ENSURE_SUCCESS(rv, rv); return DOMStorageImpl::gStorageDB->RemoveOwner(NS_ConvertUTF16toUTF8(aData), PR_TRUE); -#endif } else if (!strcmp(aTopic, "cookie-changed") && !nsCRT::strcmp(aData, NS_LITERAL_STRING("cleared").get())) { mStorages.EnumerateEntries(ClearStorage, nsnull); -#ifdef MOZ_STORAGE nsresult rv = DOMStorageImpl::InitDB(); NS_ENSURE_SUCCESS(rv, rv); @@ -408,19 +401,16 @@ nsDOMStorageManager::Observe(nsISupports *aSubject, rv = GetOfflineDomains(domains); NS_ENSURE_SUCCESS(rv, rv); return DOMStorageImpl::gStorageDB->RemoveOwners(domains, PR_TRUE, PR_FALSE); -#endif } else if (!strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC)) { mStorages.EnumerateEntries(ClearStorage, nsnull); if (!nsCRT::strcmp(aData, NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).get())) mInPrivateBrowsing = PR_TRUE; else if (!nsCRT::strcmp(aData, NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).get())) mInPrivateBrowsing = PR_FALSE; -#ifdef MOZ_STORAGE nsresult rv = DOMStorageImpl::InitDB(); NS_ENSURE_SUCCESS(rv, rv); return DOMStorageImpl::gStorageDB->DropPrivateBrowsingStorages(); -#endif } else if (!strcmp(aTopic, "perm-changed")) { // Check for cookie permission change nsCOMPtr perm(do_QueryInterface(aSubject)); @@ -441,12 +431,10 @@ nsDOMStorageManager::Observe(nsISupports *aSubject, if (host.IsEmpty()) return NS_OK; -#ifdef MOZ_STORAGE nsresult rv = DOMStorageImpl::InitDB(); NS_ENSURE_SUCCESS(rv, rv); return DOMStorageImpl::gStorageDB->DropSessionOnlyStoragesForHost(host); -#endif } } else if (!strcmp(aTopic, "timer-callback")) { nsCOMPtr obsserv = mozilla::services::GetObserverService(); @@ -474,7 +462,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject, // Clear the storage entries for matching domains mStorages.EnumerateEntries(ClearStorageIfDomainMatches, &key); -#ifdef MOZ_STORAGE rv = DOMStorageImpl::InitDB(); NS_ENSURE_SUCCESS(rv, rv); @@ -492,7 +479,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject, if (NS_FAILED(rv)) NS_WARNING("DOMStorage: temporary table commit failed"); } -#endif } return NS_OK; @@ -565,9 +551,7 @@ nsDOMStorageManager::RemoveFromStoragesHash(DOMStorageImpl* aStorage) // nsDOMStorage // -#ifdef MOZ_STORAGE nsDOMStorageDBWrapper* DOMStorageImpl::gStorageDB = nsnull; -#endif nsDOMStorageEntry::nsDOMStorageEntry(KeyTypePointer aStr) : nsVoidPtrHashKey(aStr), mStorage(nsnull) @@ -647,11 +631,9 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI) // won't get to InitAsSessionStorage. aDomainURI->GetAsciiHost(mDomain); -#ifdef MOZ_STORAGE mUseDB = PR_FALSE; mScopeDBKey.Truncate(); mQuotaDomainDBKey.Truncate(); -#endif mStorageType = nsPIDOMStorage::SessionStorage; } @@ -667,7 +649,6 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI, // mPrincipal in bug 455070. It is not even used for localStorage. aDomainURI->GetAsciiHost(mDomain); -#ifdef MOZ_STORAGE nsDOMStorageDBWrapper::CreateOriginScopeDBKey(aDomainURI, mScopeDBKey); // XXX Bug 357323, we have to solve the issue how to define @@ -680,7 +661,6 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI, PR_TRUE, PR_FALSE, mQuotaDomainDBKey); nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(mDomain, PR_TRUE, PR_TRUE, mQuotaETLDplus1DomainDBKey); -#endif mCanUseChromePersist = aCanUseChromePersist; mStorageType = nsPIDOMStorage::LocalStorage; } @@ -690,7 +670,6 @@ DOMStorageBase::InitAsGlobalStorage(const nsACString& aDomainDemanded) { mDomain = aDomainDemanded; -#ifdef MOZ_STORAGE nsDOMStorageDBWrapper::CreateDomainScopeDBKey(aDomainDemanded, mScopeDBKey); // XXX Bug 357323, we have to solve the issue how to define @@ -704,7 +683,6 @@ DOMStorageBase::InitAsGlobalStorage(const nsACString& aDomainDemanded) PR_TRUE, PR_FALSE, mQuotaDomainDBKey); nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomainDemanded, PR_TRUE, PR_TRUE, mQuotaETLDplus1DomainDBKey); -#endif mStorageType = nsPIDOMStorage::GlobalStorage; } @@ -764,7 +742,6 @@ DOMStorageImpl::~DOMStorageImpl() nsresult DOMStorageImpl::InitDB() { -#ifdef MOZ_STORAGE if (!gStorageDB) { gStorageDB = new nsDOMStorageDBWrapper(); if (!gStorageDB) @@ -782,7 +759,6 @@ DOMStorageImpl::InitDB() return rv; } } -#endif return NS_OK; } @@ -871,7 +847,6 @@ DOMStorageImpl::GetDBValue(const nsAString& aKey, nsAString& aValue, { aValue.Truncate(); -#ifdef MOZ_STORAGE if (!UseDB()) return NS_OK; @@ -890,7 +865,6 @@ DOMStorageImpl::GetDBValue(const nsAString& aKey, nsAString& aValue, return rv; aValue.Assign(value); -#endif return NS_OK; } @@ -900,7 +874,6 @@ DOMStorageImpl::SetDBValue(const nsAString& aKey, const nsAString& aValue, PRBool aSecure) { -#ifdef MOZ_STORAGE if (!UseDB()) return NS_OK; @@ -940,24 +913,18 @@ DOMStorageImpl::SetDBValue(const nsAString& aKey, NS_ConvertUTF8toUTF16(mDomain).get()); } -#endif - return NS_OK; } nsresult DOMStorageImpl::SetSecure(const nsAString& aKey, PRBool aSecure) { -#ifdef MOZ_STORAGE if (UseDB()) { nsresult rv = InitDB(); NS_ENSURE_SUCCESS(rv, rv); return gStorageDB->SetSecure(this, aKey, aSecure); } -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif nsSessionStorageEntry *entry = mItems.GetEntry(aKey); NS_ASSERTION(entry, "Don't use SetSecure() with nonexistent keys!"); @@ -1027,7 +994,6 @@ DOMStorageImpl::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat) nsresult DOMStorageImpl::CacheKeysFromDB() { -#ifdef MOZ_STORAGE // cache all the keys in the hash. This is used by the Length and Key methods // use this cache for better performance. The disadvantage is that the // order may break if someone changes the keys in the database directly. @@ -1042,7 +1008,6 @@ DOMStorageImpl::CacheKeysFromDB() mItemsCached = PR_TRUE; } -#endif return NS_OK; } @@ -1275,7 +1240,6 @@ DOMStorageImpl::RemoveValue(bool aCallerSecure, const nsAString& aKey, } if (UseDB()) { -#ifdef MOZ_STORAGE nsresult rv = InitDB(); NS_ENSURE_SUCCESS(rv, rv); @@ -1293,7 +1257,6 @@ DOMStorageImpl::RemoveValue(bool aCallerSecure, const nsAString& aKey, NS_ENSURE_SUCCESS(rv, rv); // Before bug 536544 got fixed we were dropping mItemsCached flag here -#endif } else if (entry) { // clear string as StorageItems may be referencing this item @@ -1335,7 +1298,6 @@ DOMStorageImpl::Clear(bool aCallerSecure, PRInt32* aOldCount) return NS_ERROR_DOM_SECURITY_ERR; } -#ifdef MOZ_STORAGE if (UseDB()) { nsresult rv = InitDB(); NS_ENSURE_SUCCESS(rv, rv); @@ -1343,7 +1305,6 @@ DOMStorageImpl::Clear(bool aCallerSecure, PRInt32* aOldCount) rv = gStorageDB->ClearStorage(this); NS_ENSURE_SUCCESS(rv, rv); } -#endif *aOldCount = oldCount; mItems.Clear(); diff --git a/dom/src/storage/nsDOMStorage.h b/dom/src/storage/nsDOMStorage.h index 171ff852d777..a2eec438db56 100644 --- a/dom/src/storage/nsDOMStorage.h +++ b/dom/src/storage/nsDOMStorage.h @@ -64,9 +64,7 @@ #define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer" -#ifdef MOZ_STORAGE #include "nsDOMStorageDBWrapper.h" -#endif #define IS_PERMISSION_ALLOWED(perm) \ ((perm) != nsIPermissionManager::UNKNOWN_ACTION && \ @@ -311,9 +309,7 @@ public: virtual bool CacheStoragePermissions(); private: -#ifdef MOZ_STORAGE static nsDOMStorageDBWrapper* gStorageDB; -#endif friend class nsDOMStorageManager; friend class nsDOMStoragePersistentDB; friend class StorageParent; diff --git a/dom/src/storage/nsDOMStorageDBWrapper.cpp b/dom/src/storage/nsDOMStorageDBWrapper.cpp index 3b411e29f9f4..83de9cd571f6 100644 --- a/dom/src/storage/nsDOMStorageDBWrapper.cpp +++ b/dom/src/storage/nsDOMStorageDBWrapper.cpp @@ -42,6 +42,7 @@ #include "nsDOMStorage.h" #include "nsDOMStorageDBWrapper.h" #include "nsIFile.h" +#include "nsIURL.h" #include "nsIVariant.h" #include "nsIEffectiveTLDService.h" #include "nsAppDirectoryServiceDefs.h" @@ -354,15 +355,22 @@ nsDOMStorageDBWrapper::CreateDomainScopeDBKey(nsIURI* aUri, nsACString& aKey) if (domainScope.IsEmpty()) { // About pages have an empty host but a valid path. Since they are handled // internally by our own redirector, we can trust them and use path as key. - PRBool isAboutUrl = PR_FALSE; - if ((NS_SUCCEEDED(aUri->SchemeIs("about", &isAboutUrl)) && isAboutUrl) || - (NS_SUCCEEDED(aUri->SchemeIs("moz-safe-about", &isAboutUrl)) && isAboutUrl)) { + // if file:/// protocol, let's make the exact directory the domain + PRBool isScheme = PR_FALSE; + if ((NS_SUCCEEDED(aUri->SchemeIs("about", &isScheme)) && isScheme) || + (NS_SUCCEEDED(aUri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) { rv = aUri->GetPath(domainScope); NS_ENSURE_SUCCESS(rv, rv); // While the host is always canonicalized to lowercase, the path is not, // thus need to force the casing. ToLowerCase(domainScope); } + else if (NS_SUCCEEDED(aUri->SchemeIs("file", &isScheme)) && isScheme) { + nsCOMPtr url = do_QueryInterface(aUri, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = url->GetDirectory(domainScope); + NS_ENSURE_SUCCESS(rv, rv); + } } rv = CreateDomainScopeDBKey(domainScope, aKey); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 1d35f6637fd8..0883e7ead827 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -291,16 +291,16 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate) class WorkerMemoryReporter : public nsIMemoryMultiReporter { - JSRuntime* mRuntime; + WorkerPrivate* mWorkerPrivate; nsCString mPathPrefix; public: NS_DECL_ISUPPORTS - WorkerMemoryReporter(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) - : mRuntime(aRuntime) + WorkerMemoryReporter(WorkerPrivate* aWorkerPrivate) + : mWorkerPrivate(aWorkerPrivate) { - NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); + aWorkerPrivate->AssertIsOnWorkerThread(); nsCString escapedDomain(aWorkerPrivate->Domain()); escapedDomain.ReplaceChar('/', '\\'); @@ -331,10 +331,8 @@ public: { AssertIsOnMainThread(); - JS_TriggerAllOperationCallbacks(mRuntime); - IterateData data; - if (!CollectCompartmentStatsForRuntime(mRuntime, &data)) { + if (!mWorkerPrivate->BlockAndCollectRuntimeStats(&data)) { return NS_ERROR_FAILURE; } @@ -372,16 +370,17 @@ public: return NS_ERROR_FAILURE; } - JSRuntime* rt = JS_GetRuntime(cx); - nsRefPtr reporter = - new WorkerMemoryReporter(workerPrivate, rt); + new WorkerMemoryReporter(workerPrivate); if (NS_FAILED(NS_RegisterMemoryMultiReporter(reporter))) { NS_WARNING("Failed to register memory reporter!"); reporter = nsnull; } - workerPrivate->DoRunLoop(cx); + { + JSAutoRequest ar(cx); + workerPrivate->DoRunLoop(cx); + } if (reporter) { if (NS_FAILED(NS_UnregisterMemoryMultiReporter(reporter))) { @@ -390,6 +389,8 @@ public: reporter = nsnull; } + JSRuntime* rt = JS_GetRuntime(cx); + // XXX Bug 666963 - CTypes can create another JSContext for use with // closures, and then it holds that context in a reserved slot on the CType // prototype object. We have to destroy that context before we can destroy diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index ae743619d47e..0e9ff4dc44e4 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -64,6 +64,7 @@ #include "nsJSUtils.h" #include "nsNetUtil.h" #include "nsThreadUtils.h" +#include "xpcpublic.h" #include "Events.h" #include "Exceptions.h" @@ -83,6 +84,7 @@ using mozilla::MutexAutoLock; using mozilla::TimeDuration; using mozilla::TimeStamp; using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode; +using mozilla::xpconnect::memory::IterateData; USING_WORKERS_NAMESPACE @@ -1070,6 +1072,60 @@ public: }; #endif +class CollectRuntimeStatsRunnable : public WorkerControlRunnable +{ + typedef mozilla::Mutex Mutex; + typedef mozilla::CondVar CondVar; + + Mutex* mMutex; + CondVar* mCondVar; + volatile bool* mDoneFlag; + IterateData* mData; + volatile bool* mSucceeded; + +public: + CollectRuntimeStatsRunnable(WorkerPrivate* aWorkerPrivate, Mutex* aMutex, + CondVar* aCondVar, volatile bool* aDoneFlag, + IterateData* aData, volatile bool* aSucceeded) + : WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount), + mMutex(aMutex), mCondVar(aCondVar), mDoneFlag(aDoneFlag), mData(aData), + mSucceeded(aSucceeded) + { } + + bool + PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + AssertIsOnMainThread(); + return true; + } + + void + PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate, + bool aDispatchResult) + { + AssertIsOnMainThread(); + } + + bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + JSAutoSuspendRequest asr(aCx); + + *mSucceeded = CollectCompartmentStatsForRuntime(JS_GetRuntime(aCx), mData); + + { + MutexAutoLock lock(*mMutex); + + NS_ASSERTION(!*mDoneFlag, "Should be false!"); + + *mDoneFlag = true; + mCondVar->Notify(); + } + + return true; + } +}; + } /* anonymous namespace */ #ifdef DEBUG @@ -2042,8 +2098,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx) { MutexAutoUnlock unlock(mMutex); - JSAutoRequest ar(aCx); - #ifdef EXTRA_GC // Find GC bugs... JS_GC(aCx); @@ -2056,8 +2110,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx) currentStatus = mStatus; } - JSAutoRequest ar(aCx); - #ifdef EXTRA_GC // Find GC bugs... JS_GC(aCx); @@ -2097,8 +2149,6 @@ WorkerPrivate::OperationCallback(JSContext* aCx) { AssertIsOnWorkerThread(); - JS_YieldRequest(aCx); - bool mayContinue = true; for (;;) { @@ -2133,7 +2183,6 @@ WorkerPrivate::OperationCallback(JSContext* aCx) break; } - JSAutoSuspendRequest asr(aCx); mCondVar.Wait(PR_MillisecondsToInterval(RemainingRunTimeMS())); } } @@ -2184,6 +2233,36 @@ WorkerPrivate::ScheduleDeletion(bool aWasPending) } } +bool +WorkerPrivate::BlockAndCollectRuntimeStats(IterateData* aData) +{ + AssertIsOnMainThread(); + mMutex.AssertNotCurrentThreadOwns(); + NS_ASSERTION(aData, "Null data!"); + + mozilla::Mutex mutex("BlockAndCollectRuntimeStats mutex"); + mozilla::CondVar condvar(mutex, "BlockAndCollectRuntimeStats condvar"); + volatile bool doneFlag = false; + volatile bool succeeded = false; + + nsRefPtr runnable = + new CollectRuntimeStatsRunnable(this, &mutex, &condvar, &doneFlag, aData, + &succeeded); + if (!runnable->Dispatch(nsnull)) { + NS_WARNING("Failed to dispatch runnable!"); + return false; + } + + { + MutexAutoLock lock(mutex); + while (!doneFlag) { + condvar.Wait(); + } + } + + return succeeded; +} + bool WorkerPrivate::Dispatch(WorkerRunnable* aEvent, EventQueue* aQueue) { @@ -2488,7 +2567,6 @@ WorkerPrivate::RunSyncLoop(JSContext* aCx, PRUint32 aSyncLoopKey) MutexAutoLock lock(mMutex); while (!mControlQueue.Pop(event) && !syncQueue->mQueue.Pop(event)) { - JSAutoSuspendRequest asr(aCx); mCondVar.Wait(); } } diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index ba18e7bce523..d823c6c8c42c 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -68,6 +68,16 @@ class nsIURI; class nsPIDOMWindow; class nsITimer; +namespace mozilla { +namespace xpconnect { +namespace memory { + +struct IterateData; + +} // namespace memory +} // namespace xpconnect +} // namespace mozilla + BEGIN_WORKERS_NAMESPACE class WorkerPrivate; @@ -640,6 +650,9 @@ public: void ScheduleDeletion(bool aWasPending); + bool + BlockAndCollectRuntimeStats(mozilla::xpconnect::memory::IterateData* aData); + #ifdef JS_GC_ZEAL void UpdateGCZealInternal(JSContext* aCx, PRUint8 aGCZeal); diff --git a/editor/idl/nsIContentFilter.idl b/editor/idl/nsIContentFilter.idl index cebfe64b4bf8..38bfbd3384d7 100644 --- a/editor/idl/nsIContentFilter.idl +++ b/editor/idl/nsIContentFilter.idl @@ -105,7 +105,7 @@ interface nsIContentFilter : nsISupports void notifyOfInsertion(in AString mimeType, in nsIURL contentSourceURL, in nsIDOMDocument sourceDocument, - in PRBool willDeleteSelection, + in boolean willDeleteSelection, inout nsIDOMNode docFragment, inout nsIDOMNode contentStartNode, inout long contentStartOffset, diff --git a/editor/idl/nsIEditorStyleSheets.idl b/editor/idl/nsIEditorStyleSheets.idl index b00f885078e6..3b7556d4623e 100644 --- a/editor/idl/nsIEditorStyleSheets.idl +++ b/editor/idl/nsIEditorStyleSheets.idl @@ -106,7 +106,7 @@ interface nsIEditorStyleSheets : nsISupports * @param aURL The style sheet to be enabled or disabled * @param aEnable true to enable, or false to disable the style sheet */ - void enableStyleSheet(in AString aURL, in PRBool aEnable); + void enableStyleSheet(in AString aURL, in boolean aEnable); /** Get the nsCSSStyleSheet associated with the given URL. * diff --git a/editor/libeditor/base/nsEditPropertyAtomList.h b/editor/libeditor/base/nsEditPropertyAtomList.h index adbbbfe833fb..2ebe92365e89 100644 --- a/editor/libeditor/base/nsEditPropertyAtomList.h +++ b/editor/libeditor/base/nsEditPropertyAtomList.h @@ -147,6 +147,7 @@ EDITOR_ATOM(legend, "legend") EDITOR_ATOM(li, "li") EDITOR_ATOM(map, "map") EDITOR_ATOM(mark, "mark") +EDITOR_ATOM(menuitem, "menuitem") EDITOR_ATOM(mozdirty, "_moz_dirty") EDITOR_ATOM(mozEditorBogusNode, "_moz_editor_bogus_node") EDITOR_ATOM(name, "name") diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index b69cac740dce..262d8bbc077c 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -51,8 +51,6 @@ #include "nsIDOMEventTarget.h" #include "nsIDOMNSEvent.h" #include "nsIDOMKeyEvent.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMMouseListener.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMComment.h" #include "nsISelection.h" diff --git a/editor/libeditor/html/nsHTMLEditUtils.cpp b/editor/libeditor/html/nsHTMLEditUtils.cpp index 333c8a34352a..dfc6433ed034 100644 --- a/editor/libeditor/html/nsHTMLEditUtils.cpp +++ b/editor/libeditor/html/nsHTMLEditUtils.cpp @@ -662,7 +662,8 @@ static const nsElementInfo kElements[eHTMLTag_userdefined] = { ELEM(map, PR_TRUE, PR_TRUE, GROUP_SPECIAL, GROUP_BLOCK | GROUP_MAP_CONTENT), ELEM(mark, PR_TRUE, PR_TRUE, GROUP_PHRASE, GROUP_INLINE_ELEMENT), ELEM(marquee, PR_FALSE, PR_FALSE, GROUP_NONE, GROUP_NONE), - ELEM(menu, PR_TRUE, PR_FALSE, GROUP_BLOCK, GROUP_LI), + ELEM(menu, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_LI | GROUP_FLOW_ELEMENT), + ELEM(menuitem, PR_FALSE, PR_FALSE, GROUP_NONE, GROUP_NONE), ELEM(meta, PR_FALSE, PR_FALSE, GROUP_HEAD_CONTENT, GROUP_NONE), ELEM(multicol, PR_FALSE, PR_FALSE, GROUP_NONE, GROUP_NONE), ELEM(nav, PR_TRUE, PR_TRUE, GROUP_BLOCK, GROUP_FLOW_ELEMENT), diff --git a/editor/libeditor/html/nsHTMLEditorStyle.cpp b/editor/libeditor/html/nsHTMLEditorStyle.cpp index 2751b42ce291..c7fd0836f5fb 100644 --- a/editor/libeditor/html/nsHTMLEditorStyle.cpp +++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp @@ -44,8 +44,6 @@ #include "nsHTMLEditUtils.h" #include "nsIDOMNodeList.h" #include "nsIDOMAttr.h" -#include "nsIDOMKeyListener.h" -#include "nsIDOMMouseListener.h" #include "nsIDOMMouseEvent.h" #include "nsISelection.h" #include "nsISelectionPrivate.h" diff --git a/editor/libeditor/text/nsPlaintextEditor.cpp b/editor/libeditor/text/nsPlaintextEditor.cpp index e420debb037e..0d72da1d4677 100644 --- a/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/editor/libeditor/text/nsPlaintextEditor.cpp @@ -48,7 +48,6 @@ #include "nsIDocument.h" #include "nsIDOMEventTarget.h" #include "nsIDOMKeyEvent.h" -#include "nsIDOMMouseListener.h" #include "nsISelection.h" #include "nsISelectionPrivate.h" #include "nsISelectionController.h" diff --git a/embedding/android/GeckoApp.java b/embedding/android/GeckoApp.java index 7055efd38d6f..9a61be3807c1 100644 --- a/embedding/android/GeckoApp.java +++ b/embedding/android/GeckoApp.java @@ -68,6 +68,9 @@ abstract public class GeckoApp { public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK"; public static final String ACTION_ALERT_CLEAR = "org.mozilla.gecko.ACTION_ALERT_CLEAR"; + public static final String ACTION_WEBAPP = "org.mozilla.gecko.WEBAPP"; + public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG"; + public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK"; public static FrameLayout mainLayout; public static GeckoSurfaceView surfaceView; @@ -297,7 +300,7 @@ abstract public class GeckoApp return; } final String action = intent.getAction(); - if ("org.mozilla.gecko.DEBUG".equals(action) && + if (ACTION_DEBUG.equals(action) && checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitButton)) { final Button launchButton = new Button(this); launchButton.setText("Launch"); // don't need to localize @@ -315,20 +318,25 @@ abstract public class GeckoApp if (checkLaunchState(LaunchState.WaitButton) || launch(intent)) return; - if (Intent.ACTION_VIEW.equals(action)) { + if (Intent.ACTION_MAIN.equals(action)) { + Log.i("GeckoApp", "Intent : ACTION_MAIN"); + GeckoAppShell.sendEventToGecko(new GeckoEvent("")); + } + else if (Intent.ACTION_VIEW.equals(action)) { String uri = intent.getDataString(); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); Log.i("GeckoApp","onNewIntent: "+uri); } - else if (Intent.ACTION_MAIN.equals(action)) { - Log.i("GeckoApp", "Intent : ACTION_MAIN"); - GeckoAppShell.sendEventToGecko(new GeckoEvent("")); - } - else if (action.equals("org.mozilla.gecko.WEBAPP")) { + else if (ACTION_WEBAPP.equals(action)) { String uri = intent.getStringExtra("args"); GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); Log.i("GeckoApp","Intent : WEBAPP - " + uri); } + else if (ACTION_BOOKMARK.equals(action)) { + String args = intent.getStringExtra("args"); + GeckoAppShell.sendEventToGecko(new GeckoEvent(args)); + Log.i("GeckoApp","Intent : BOOKMARK - " + args); + } } @Override diff --git a/embedding/android/GeckoAppShell.java b/embedding/android/GeckoAppShell.java index ac3f5762b775..bd03aded95f0 100644 --- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -682,14 +682,20 @@ public class GeckoAppShell } // "Installs" an application by creating a shortcut - static void installWebApplication(String aURI, String aTitle, String aIconData) { - Log.w("GeckoAppJava", "installWebApplication for " + aURI + " [" + aTitle + "]"); + static void createShortcut(String aTitle, String aURI, String aIconData, String aType) { + Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "]"); // the intent to be launched by the shortcut - Intent shortcutIntent = new Intent("org.mozilla.gecko.WEBAPP"); + Intent shortcutIntent = new Intent(); + if (aType == "webapp") { + shortcutIntent.setAction("org.mozilla.gecko.WEBAPP"); + shortcutIntent.putExtra("args", "--webapp=" + aURI); + } else { + shortcutIntent.setAction("org.mozilla.gecko.BOOKMARK"); + shortcutIntent.putExtra("args", "--url=" + aURI); + } shortcutIntent.setClassName(GeckoApp.mAppContext, GeckoApp.mAppContext.getPackageName() + ".App"); - shortcutIntent.putExtra("args", "--webapp=" + aURI); Intent intent = new Intent(); intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); @@ -835,7 +841,7 @@ public class GeckoAppShell getHandler().post(new Runnable() { public void run() { Context context = GeckoApp.surfaceView.getContext(); - ClipboardManager cm = (ClipboardManager) + android.text.ClipboardManager cm = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); try { sClipboardQueue.put(cm.hasText() ? cm.getText().toString() : ""); @@ -852,7 +858,7 @@ public class GeckoAppShell getHandler().post(new Runnable() { public void run() { Context context = GeckoApp.surfaceView.getContext(); - ClipboardManager cm = (ClipboardManager) + android.text.ClipboardManager cm = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); cm.setText(text); }}); diff --git a/embedding/android/GeckoSurfaceView.java b/embedding/android/GeckoSurfaceView.java index 65778f84171b..7c940f48ddab 100644 --- a/embedding/android/GeckoSurfaceView.java +++ b/embedding/android/GeckoSurfaceView.java @@ -599,6 +599,7 @@ class GeckoSurfaceView // KeyListener returns true if it handled the event for us. if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || + keyCode == KeyEvent.KEYCODE_DEL || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || !mKeyListener.onKeyDown(this, mEditable, keyCode, event)) GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); @@ -617,6 +618,7 @@ class GeckoSurfaceView } if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || + keyCode == KeyEvent.KEYCODE_DEL || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || !mKeyListener.onKeyUp(this, mEditable, keyCode, event)) GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); diff --git a/embedding/browser/webBrowser/nsIWebBrowserChrome3.idl b/embedding/browser/webBrowser/nsIWebBrowserChrome3.idl index 6a5e5d06f701..22acd7142fc5 100644 --- a/embedding/browser/webBrowser/nsIWebBrowserChrome3.idl +++ b/embedding/browser/webBrowser/nsIWebBrowserChrome3.idl @@ -62,5 +62,5 @@ interface nsIWebBrowserChrome3 : nsIWebBrowserChrome2 AString onBeforeLinkTraversal(in AString originalTarget, in nsIURI linkURI, in nsIDOMNode linkNode, - in PRBool isAppTab); + in boolean isAppTab); }; diff --git a/gfx/src/nsScriptableRegion.cpp b/gfx/src/nsScriptableRegion.cpp index adf02f0ea976..2e0f137c2001 100644 --- a/gfx/src/nsScriptableRegion.cpp +++ b/gfx/src/nsScriptableRegion.cpp @@ -184,7 +184,7 @@ NS_IMETHODIMP nsScriptableRegion::GetRects() { *retvalPtr = OBJECT_TO_JSVAL(destArray); ncc->SetReturnValueWasSet(PR_TRUE); - int n = 0; + uint32 n = 0; nsIntRegionRectIterator iter(mRegion); const nsIntRect *rect; diff --git a/js/jsd/idl/jsdIDebuggerService.idl b/js/jsd/idl/jsdIDebuggerService.idl index 7c3ac77c9a66..6618c5a9e322 100644 --- a/js/jsd/idl/jsdIDebuggerService.idl +++ b/js/jsd/idl/jsdIDebuggerService.idl @@ -249,7 +249,7 @@ interface jsdIDebuggerService : nsISupports /** * Recompile all active scripts in the runtime for debugMode. */ - [noscript] void recompileForDebugMode(in JSContext cx, in JSCompartment comp, in PRBool mode); + [noscript] void recompileForDebugMode(in JSContext cx, in JSCompartment comp, in boolean mode); /** * Turn the debugger off. This will invalidate all of your jsdIEphemeral @@ -1056,7 +1056,7 @@ interface jsdIScript : jsdIEphemeral /** * Call interrupt hook at least once per source line */ - void enableSingleStepInterrupts(in PRBool mode); + void enableSingleStepInterrupts(in boolean mode); }; /** diff --git a/js/src/configure.in b/js/src/configure.in index 15750634f4f7..f954635b2407 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3807,63 +3807,6 @@ if test "x$ac_cv_va_val_copy" = "xno"; then fi AC_MSG_RESULT($ac_cv_va_val_copy) -dnl Check for dll-challenged libc's. -dnl This check is apparently only needed for Linux. -case "$target" in - *-linux*) - dnl =================================================================== - _curdir=`pwd` - export _curdir - rm -rf conftest* _conftest - mkdir _conftest - cat >> conftest.C <<\EOF -#include -#include -#include -#ifdef _dl_loaded -void __dump_link_map(void) { - struct link_map *map = _dl_loaded; - while (NULL != map) {printf("0x%08x %s\n", map->l_addr, map->l_name); map = map->l_next;} -} -int main() { - dlopen("./conftest1.so",RTLD_LAZY); - dlopen("./../_conftest/conftest1.so",RTLD_LAZY); - dlopen("CURDIR/_conftest/conftest1.so",RTLD_LAZY); - dlopen("CURDIR/_conftest/../_conftest/conftest1.so",RTLD_LAZY); - __dump_link_map(); -} -#else -/* _dl_loaded isn't defined, so this should be either a libc5 (glibc1) system, or a glibc2 system that doesn't have the multiple load bug (i.e., RH6.0).*/ -int main() { printf("./conftest1.so\n"); } -#endif -EOF - - $PERL -p -i -e "s/CURDIR/\$ENV{_curdir}/g;" conftest.C - - cat >> conftest1.C <<\EOF -#include -void foo(void) {printf("foo in dll called\n");} -EOF - ${CXX-g++} -fPIC -c -g conftest1.C - ${CXX-g++} -shared -Wl,-h -Wl,conftest1.so -o conftest1.so conftest1.o - ${CXX-g++} -g conftest.C -o conftest -ldl - cp -f conftest1.so conftest _conftest - cd _conftest - if test `./conftest | grep conftest1.so | wc -l` -gt 1 - then - echo - echo "*** Your libc has a bug that can result in loading the same dynamic" - echo "*** library multiple times. This bug is known to be fixed in glibc-2.0.7-32" - echo "*** or later. However, if you choose not to upgrade, the only effect" - echo "*** will be excessive memory usage at runtime." - echo - fi - cd ${_curdir} - rm -rf conftest* _conftest - dnl =================================================================== - ;; -esac - dnl =================================================================== dnl ======================================================== dnl Put your C++ language/feature checks below diff --git a/js/src/jit-test/tests/basic/bug619004.js b/js/src/jit-test/tests/basic/bug619004.js index 8c7cec43917c..90d3bca9931c 100644 --- a/js/src/jit-test/tests/basic/bug619004.js +++ b/js/src/jit-test/tests/basic/bug619004.js @@ -1,4 +1,3 @@ -// don't crash -gczeal(2) -evalcx('split') - +// don't crash +gczeal(2); +evalcx('lazy'); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 9fb90b08a689..053d383e944e 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3240,9 +3240,13 @@ JS_LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp) } JS_PUBLIC_API(JSBool) -JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +JS_LookupElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp) { - return JS_LookupPropertyById(cx, obj, INT_TO_JSID(index), vp); + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return JS_LookupPropertyById(cx, obj, id, vp); } JS_PUBLIC_API(JSBool) @@ -3294,9 +3298,13 @@ JS_HasPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp) } JS_PUBLIC_API(JSBool) -JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp) +JS_HasElement(JSContext *cx, JSObject *obj, uint32 index, JSBool *foundp) { - return JS_HasPropertyById(cx, obj, INT_TO_JSID(index), foundp); + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return JS_HasPropertyById(cx, obj, id, foundp); } JS_PUBLIC_API(JSBool) @@ -3336,9 +3344,13 @@ JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foun } JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp) +JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, uint32 index, JSBool *foundp) { - return JS_AlreadyHasOwnPropertyById(cx, obj, INT_TO_JSID(index), foundp); + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp); } JS_PUBLIC_API(JSBool) @@ -3387,10 +3399,14 @@ JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value, } JS_PUBLIC_API(JSBool) -JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, +JS_DefineElement(JSContext *cx, JSObject *obj, uint32 index, jsval value, JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs) { - return DefinePropertyById(cx, obj, INT_TO_JSID(index), Valueify(value), + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return DefinePropertyById(cx, obj, id, Valueify(value), Valueify(getter), Valueify(setter), attrs, 0, 0); } @@ -3698,9 +3714,13 @@ JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsva } JS_PUBLIC_API(JSBool) -JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +JS_GetElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp) { - return JS_GetPropertyById(cx, obj, INT_TO_JSID(index), vp); + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return JS_GetPropertyById(cx, obj, id, vp); } JS_PUBLIC_API(JSBool) @@ -3753,8 +3773,12 @@ JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp) } JS_PUBLIC_API(JSBool) -JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +JS_SetElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp) { + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; return JS_SetPropertyById(cx, obj, INT_TO_JSID(index), vp); } @@ -3782,9 +3806,13 @@ JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval) } JS_PUBLIC_API(JSBool) -JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval) +JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32 index, jsval *rval) { - return JS_DeletePropertyById2(cx, obj, INT_TO_JSID(index), rval); + CHECK_REQUEST(cx); + jsid id; + if (!IndexToId(cx, index, &id)) + return false; + return JS_DeletePropertyById2(cx, obj, id, rval); } JS_PUBLIC_API(JSBool) @@ -3809,7 +3837,7 @@ JS_DeletePropertyById(JSContext *cx, JSObject *obj, jsid id) } JS_PUBLIC_API(JSBool) -JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index) +JS_DeleteElement(JSContext *cx, JSObject *obj, uint32 index) { jsval junk; return JS_DeleteElement2(cx, obj, index, &junk); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 7f6ed991e9f2..ab201bc4a196 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2486,30 +2486,29 @@ extern JS_PUBLIC_API(JSBool) JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length); extern JS_PUBLIC_API(JSBool) -JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, +JS_DefineElement(JSContext *cx, JSObject *obj, uint32 index, jsval value, JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); extern JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, - JSBool *foundp); +JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, uint32 index, JSBool *foundp); extern JS_PUBLIC_API(JSBool) -JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp); +JS_HasElement(JSContext *cx, JSObject *obj, uint32 index, JSBool *foundp); extern JS_PUBLIC_API(JSBool) -JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); +JS_LookupElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); extern JS_PUBLIC_API(JSBool) -JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); +JS_GetElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); extern JS_PUBLIC_API(JSBool) -JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); +JS_SetElement(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); extern JS_PUBLIC_API(JSBool) -JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index); +JS_DeleteElement(JSContext *cx, JSObject *obj, uint32 index); extern JS_PUBLIC_API(JSBool) -JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval); +JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32 index, jsval *rval); extern JS_PUBLIC_API(void) JS_ClearScope(JSContext *cx, JSObject *obj); diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index 4d8a1fdddd59..22fa1e41ab57 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -2054,7 +2054,7 @@ ethogram_getAllEvents(JSContext *cx, uintN argc, jsval *vp) JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(rarray)); - for (int i = 0; !p->isEmpty(); i++) { + for (uint32 i = 0; !p->isEmpty(); i++) { JSObject *x = JS_NewObject(cx, NULL, NULL, NULL); if (x == NULL) diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 0e1095ca2b62..08321b179fba 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -75,6 +75,8 @@ #include "jsxml.h" #endif +#include "vm/GlobalObject.h" + #include "jsobjinlines.h" #include "vm/Stack-inl.h" @@ -1406,32 +1408,81 @@ static JSFunctionSpec generator_methods[] = { #endif /* JS_HAS_GENERATORS */ +static bool +InitIteratorClass(JSContext *cx, GlobalObject *global) +{ + JSObject *iteratorProto = global->createBlankPrototype(cx, &js_IteratorClass); + if (!iteratorProto) + return false; + + JSFunction *ctor = global->createConstructor(cx, Iterator, &js_IteratorClass, + CLASS_ATOM(cx, Iterator), 2); + if (!ctor) + return false; + + if (!LinkConstructorAndPrototype(cx, ctor, iteratorProto)) + return false; + + if (!DefinePropertiesAndBrand(cx, iteratorProto, NULL, iterator_methods)) + return false; + + return DefineConstructorAndPrototype(cx, global, JSProto_Iterator, ctor, iteratorProto); +} + +static bool +InitGeneratorClass(JSContext *cx, GlobalObject *global) +{ +#if JS_HAS_GENERATORS + JSObject *proto = global->createBlankPrototype(cx, &js_GeneratorClass); + if (!proto) + return false; + + if (!DefinePropertiesAndBrand(cx, proto, NULL, generator_methods)) + return false; + + /* This should use a non-JSProtoKey'd slot, but this is easier for now. */ + return DefineConstructorAndPrototype(cx, global, JSProto_Generator, proto, proto); +#else + return true; +#endif +} + +static JSObject * +InitStopIterationClass(JSContext *cx, GlobalObject *global) +{ + JSObject *proto = global->createBlankPrototype(cx, &js_StopIterationClass); + if (!proto || !proto->freeze(cx)) + return NULL; + + /* This should use a non-JSProtoKey'd slot, but this is easier for now. */ + if (!DefineConstructorAndPrototype(cx, global, JSProto_StopIteration, proto, proto)) + return NULL; + + MarkStandardClassInitializedNoProto(global, &js_StopIterationClass); + + return proto; +} + JSObject * js_InitIteratorClasses(JSContext *cx, JSObject *obj) { - JSObject *proto, *stop; + JS_ASSERT(obj->isNative()); - /* Idempotency required: we initialize several things, possibly lazily. */ - if (!js_GetClassObject(cx, obj, JSProto_StopIteration, &stop)) + GlobalObject *global = obj->asGlobal(); + + /* + * Bail if Iterator has already been initialized. We test for Iterator + * rather than for StopIteration because if js_InitIteratorClasses recurs, + * as happens when the StopIteration object is frozen, initializing the + * Iterator class a second time will assert. + */ + JSObject *iter; + if (!js_GetClassObject(cx, global, JSProto_Iterator, &iter)) return NULL; - if (stop) - return stop; + if (iter) + return iter; - proto = js_InitClass(cx, obj, NULL, &js_IteratorClass, Iterator, 2, - NULL, iterator_methods, NULL, NULL); - if (!proto) + if (!InitIteratorClass(cx, global) || !InitGeneratorClass(cx, global)) return NULL; - -#if JS_HAS_GENERATORS - /* Initialize the generator internals if configured. */ - if (!js_InitClass(cx, obj, NULL, &js_GeneratorClass, NULL, 0, - NULL, generator_methods, NULL, NULL)) { - return NULL; - } -#endif - - MarkStandardClassInitializedNoProto(obj, &js_StopIterationClass); - - return js_InitClass(cx, obj, NULL, &js_StopIterationClass, NULL, 0, - NULL, NULL, NULL, NULL); + return InitStopIterationClass(cx, global); } diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index c2bb15327e9f..25d22af52dd0 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4483,6 +4483,9 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, { JS_ASSERT(!(flags & Shape::METHOD)); + /* Convert string indices to integers if appropriate. */ + id = js_CheckForStringIndex(id); + /* * Purge the property cache of now-shadowed id in obj's scope chain. Do * this optimistically (assuming no failure below) before locking obj, so @@ -4493,8 +4496,6 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, if (!obj->ensureClassReservedSlots(cx)) return NULL; - /* Convert string indices to integers if appropriate. */ - id = js_CheckForStringIndex(id); return obj->putProperty(cx, id, getter, setter, slot, attrs, flags, shortid); } diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 5c64cc60642a..50fe072cb289 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -1373,7 +1373,7 @@ CopyInitializerObject(JSContext *cx, JSObject *baseobj) inline bool DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global, - JSProtoKey key, JSFunction *ctor, JSObject *proto) + JSProtoKey key, JSObject *ctor, JSObject *proto) { JS_ASSERT(!global->nativeEmpty()); /* reserved slots already allocated */ JS_ASSERT(ctor); diff --git a/js/src/jsval.h b/js/src/jsval.h index 84b038b7be5f..e40b3b44bd8c 100644 --- a/js/src/jsval.h +++ b/js/src/jsval.h @@ -317,6 +317,7 @@ typedef union jsval_layout } s; double asDouble; void *asPtr; + jsuword asWord; } jsval_layout; # endif /* JS_BITS_PER_WORD */ #else /* defined(IS_LITTLE_ENDIAN) */ @@ -358,6 +359,7 @@ typedef union jsval_layout } s; double asDouble; void *asPtr; + jsuword asWord; } jsval_layout; # endif /* JS_BITS_PER_WORD */ #endif /* defined(IS_LITTLE_ENDIAN) */ diff --git a/js/src/jsvalue.h b/js/src/jsvalue.h index 345b64179a7f..6ea99461bd89 100644 --- a/js/src/jsvalue.h +++ b/js/src/jsvalue.h @@ -295,7 +295,6 @@ JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(jsval_layout l) } #ifdef __cplusplus -JS_STATIC_ASSERT(offsetof(jsval_layout, s.payload) == 0); JS_STATIC_ASSERT((JSVAL_TYPE_NONFUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); JS_STATIC_ASSERT((JSVAL_TYPE_FUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); #endif @@ -744,9 +743,9 @@ class Value const jsuword *payloadWord() const { #if JS_BITS_PER_WORD == 32 - return reinterpret_cast(&data.s.payload.word); + return &data.s.payload.word; #elif JS_BITS_PER_WORD == 64 - return reinterpret_cast(&data.asBits); + return &data.asWord; #endif } diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index d110357a8f10..16ff7da99985 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -227,9 +227,6 @@ DestroyContext(JSContext *cx, bool withGC); static const JSErrorFormatString * my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); -static JSObject * -split_setup(JSContext *cx, JSBool evalcx); - #ifdef EDITLINE JS_BEGIN_EXTERN_C JS_EXTERN_API(char) *readline(const char *prompt); @@ -2474,7 +2471,7 @@ DumpStack(JSContext *cx, uintN argc, Value *vp) JS_ASSERT(iter.nativeArgs().callee().getFunctionPrivate()->native() == DumpStack); ++iter; - jsint index = 0; + uint32 index = 0; for (; !iter.done(); ++index, ++iter) { Value v; if (iter.isScript()) { @@ -2701,7 +2698,6 @@ GetPDA(JSContext *cx, uintN argc, jsval *vp) JSBool ok; JSPropertyDescArray pda; JSPropertyDesc *pd; - uint32 i; jsval v; if (!JS_ValueToObject(cx, argc == 0 ? JSVAL_VOID : vp[2], &vobj)) @@ -2720,7 +2716,7 @@ GetPDA(JSContext *cx, uintN argc, jsval *vp) if (!ok) return JS_FALSE; pd = pda.array; - for (i = 0; i < pda.length; i++, pd++) { + for (uint32 i = 0; i < pda.length; i++, pd++) { pdobj = JS_NewObject(cx, NULL, NULL, NULL); if (!pdobj) { ok = JS_FALSE; @@ -2834,379 +2830,6 @@ typedef struct ComplexObject { JSObject *outer; } ComplexObject; -static JSObject * -split_create_outer(JSContext *cx); - -static JSObject * -split_create_inner(JSContext *cx, JSObject *outer); - -static ComplexObject * -split_get_private(JSContext *cx, JSObject *obj); - -static JSBool -split_addProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) -{ - ComplexObject *cpx; - - cpx = split_get_private(cx, obj); - if (!cpx) - return JS_TRUE; - if (!cpx->isInner && cpx->inner) { - /* Make sure to define this property on the inner object. */ - return JS_DefinePropertyById(cx, cpx->inner, id, *vp, NULL, NULL, JSPROP_ENUMERATE); - } - return JS_TRUE; -} - -static JSBool -split_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) -{ - ComplexObject *cpx; - - cpx = split_get_private(cx, obj); - if (!cpx) - return JS_TRUE; - - if (JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "isInner")) { - *vp = BOOLEAN_TO_JSVAL(cpx->isInner); - return JS_TRUE; - } - - if (!cpx->isInner && cpx->inner) { - if (JSID_IS_ATOM(id)) { - JSString *str = JSID_TO_STRING(id); - - size_t length; - const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length); - if (!chars) - return false; - - return JS_GetUCProperty(cx, cpx->inner, chars, length, vp); - } - if (JSID_IS_INT(id)) - return JS_GetElement(cx, cpx->inner, JSID_TO_INT(id), vp); - return JS_TRUE; - } - - return JS_TRUE; -} - -static JSBool -split_setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) -{ - ComplexObject *cpx; - - cpx = split_get_private(cx, obj); - if (!cpx) - return true; - if (!cpx->isInner && cpx->inner) { - if (JSID_IS_ATOM(id)) { - JSString *str = JSID_TO_STRING(id); - - size_t length; - const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length); - if (!chars) - return false; - - return JS_SetUCProperty(cx, cpx->inner, chars, length, vp); - } - if (JSID_IS_INT(id)) - return JS_SetElement(cx, cpx->inner, JSID_TO_INT(id), vp); - return true; - } - - return true; -} - -static JSBool -split_delProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) -{ - ComplexObject *cpx; - jsid asId; - - cpx = split_get_private(cx, obj); - if (!cpx) - return JS_TRUE; - if (!cpx->isInner && cpx->inner) { - /* Make sure to define this property on the inner object. */ - if (!JS_ValueToId(cx, *vp, &asId)) - return JS_FALSE; - return cpx->inner->deleteProperty(cx, asId, Valueify(vp), true); - } - return JS_TRUE; -} - -static JSBool -split_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, - jsval *statep, jsid *idp) -{ - ComplexObject *cpx; - JSObject *iterator; - - switch (enum_op) { - case JSENUMERATE_INIT: - case JSENUMERATE_INIT_ALL: - cpx = (ComplexObject *) JS_GetPrivate(cx, obj); - - if (!cpx->isInner && cpx->inner) - obj = cpx->inner; - - iterator = JS_NewPropertyIterator(cx, obj); - if (!iterator) - return JS_FALSE; - - *statep = OBJECT_TO_JSVAL(iterator); - if (idp) - *idp = INT_TO_JSID(0); - break; - - case JSENUMERATE_NEXT: - iterator = (JSObject*)JSVAL_TO_OBJECT(*statep); - if (!JS_NextProperty(cx, iterator, idp)) - return JS_FALSE; - - if (!JSID_IS_VOID(*idp)) - break; - /* Fall through. */ - - case JSENUMERATE_DESTROY: - /* Let GC at our iterator object. */ - *statep = JSVAL_NULL; - break; - } - - return JS_TRUE; -} - -static JSBool -split_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp) -{ - ComplexObject *cpx; - - if (JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "isInner")) { - *objp = obj; - return JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, NULL, NULL, JSPROP_SHARED); - } - - cpx = split_get_private(cx, obj); - if (!cpx) - return JS_TRUE; - if (!cpx->isInner && cpx->inner) { - JSProperty *prop; - return cpx->inner->lookupProperty(cx, id, objp, &prop); - } - -#ifdef LAZY_STANDARD_CLASSES - if (!(flags & JSRESOLVE_ASSIGNING)) { - JSBool resolved; - - if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) - return JS_FALSE; - - if (resolved) { - *objp = obj; - return JS_TRUE; - } - } -#endif - - /* XXX For additional realism, let's resolve some random property here. */ - return JS_TRUE; -} - -static void -split_finalize(JSContext *cx, JSObject *obj) -{ - JS_free(cx, JS_GetPrivate(cx, obj)); -} - -static void -split_trace(JSTracer *trc, JSObject *obj) -{ - ComplexObject *cpx; - - cpx = (ComplexObject *) JS_GetPrivate(trc->context, obj); - - if (!cpx) - return; /* The object is not fully constructed. */ - - if (!cpx->isInner && cpx->inner) { - /* Mark the inner object. */ - JS_CALL_TRACER(trc, cpx->inner, JSTRACE_OBJECT, "ComplexObject.inner"); - } - - if (cpx->isInner && cpx->outer) { - /* Mark the inner object. */ - JS_CALL_TRACER(trc, cpx->outer, JSTRACE_OBJECT, "ComplexObject.outer"); - } -} - -static JSObject * -split_outerObject(JSContext *cx, JSObject *obj) -{ - ComplexObject *cpx; - - cpx = (ComplexObject *) JS_GetPrivate(cx, obj); - return cpx->isInner ? cpx->outer : obj; -} - -static JSObject * -split_thisObject(JSContext *cx, JSObject *obj) -{ - OBJ_TO_OUTER_OBJECT(cx, obj); - if (!obj) - return NULL; - return obj; -} - - -static JSBool -split_equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); - -static JSObject * -split_innerObject(JSContext *cx, JSObject *obj) -{ - ComplexObject *cpx; - - cpx = (ComplexObject *) JS_GetPrivate(cx, obj); - if (cpx->frozen) { - JS_ASSERT(!cpx->isInner); - return obj; - } - return !cpx->isInner ? cpx->inner : obj; -} - -static Class split_global_class = { - "split_global", - JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, - Valueify(split_addProperty), - Valueify(split_delProperty), - Valueify(split_getProperty), - Valueify(split_setProperty), - (JSEnumerateOp)split_enumerate, - (JSResolveOp)split_resolve, - ConvertStub, - split_finalize, - NULL, /* reserved0 */ - NULL, /* checkAccess */ - NULL, /* call */ - NULL, /* construct */ - NULL, /* xdrObject */ - NULL, /* hasInstance */ - split_trace, - { - Valueify(split_equality), - split_outerObject, - split_innerObject, - NULL, /* iteratorObject */ - NULL, /* wrappedObject */ - }, - { - NULL, /* lookupProperty */ - NULL, /* defineProperty */ - NULL, /* getProperty */ - NULL, /* setProperty */ - NULL, /* getAttributes */ - NULL, /* setAttributes */ - NULL, /* deleteProperty */ - NULL, /* enumerate */ - NULL, /* typeOf */ - NULL, /* fix */ - split_thisObject, - NULL, /* clear */ - }, -}; - -static JSBool -split_equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp) -{ - *bp = JS_FALSE; - if (JSVAL_IS_PRIMITIVE(*v)) - return JS_TRUE; - - JSObject *obj2 = JSVAL_TO_OBJECT(*v); - if (obj2->getClass() != &split_global_class) - return JS_TRUE; - - ComplexObject *cpx = (ComplexObject *) JS_GetPrivate(cx, obj2); - JS_ASSERT(!cpx->isInner); - - ComplexObject *ourCpx = (ComplexObject *) JS_GetPrivate(cx, obj); - JS_ASSERT(!ourCpx->isInner); - - *bp = (cpx == ourCpx); - return JS_TRUE; -} - -JSObject * -split_create_outer(JSContext *cx) -{ - ComplexObject *cpx; - JSObject *obj; - - cpx = (ComplexObject *) JS_malloc(cx, sizeof *obj); - if (!cpx) - return NULL; - cpx->isInner = JS_FALSE; - cpx->frozen = JS_TRUE; - cpx->inner = NULL; - cpx->outer = NULL; - - obj = JS_NewGlobalObject(cx, Jsvalify(&split_global_class)); - if (!obj) { - JS_free(cx, cpx); - return NULL; - } - - if (!JS_SetPrivate(cx, obj, cpx)) { - JS_free(cx, cpx); - return NULL; - } - - return obj; -} - -static JSObject * -split_create_inner(JSContext *cx, JSObject *outer) -{ - ComplexObject *cpx, *outercpx; - JSObject *obj; - - JS_ASSERT(outer->getClass() == &split_global_class); - - cpx = (ComplexObject *) JS_malloc(cx, sizeof *cpx); - if (!cpx) - return NULL; - cpx->isInner = JS_TRUE; - cpx->frozen = JS_FALSE; - cpx->inner = NULL; - cpx->outer = outer; - - obj = JS_NewGlobalObject(cx, Jsvalify(&split_global_class)); - if (!obj || !JS_SetPrivate(cx, obj, cpx)) { - JS_free(cx, cpx); - return NULL; - } - - outercpx = (ComplexObject *) JS_GetPrivate(cx, outer); - outercpx->inner = obj; - outercpx->frozen = JS_FALSE; - - return obj; -} - -static ComplexObject * -split_get_private(JSContext *cx, JSObject *obj) -{ - do { - if (obj->getClass() == &split_global_class) - return (ComplexObject *) JS_GetPrivate(cx, obj); - obj = JS_GetParent(cx, obj); - } while (obj); - - return NULL; -} - static JSBool sandbox_enumerate(JSContext *cx, JSObject *obj) { @@ -3254,7 +2877,7 @@ static JSClass sandbox_class = { }; static JSObject * -NewSandbox(JSContext *cx, bool lazy, bool split) +NewSandbox(JSContext *cx, bool lazy) { JSObject *obj = JS_NewCompartmentAndGlobalObject(cx, &sandbox_class, NULL); if (!obj) @@ -3265,20 +2888,12 @@ NewSandbox(JSContext *cx, bool lazy, bool split) if (!ac.enter(cx, obj)) return NULL; - if (split) { - obj = split_setup(cx, JS_TRUE); - if (!obj) - return NULL; - } if (!lazy && !JS_InitStandardClasses(cx, obj)) return NULL; AutoValueRooter root(cx, BooleanValue(lazy)); if (!JS_SetProperty(cx, obj, "lazy", root.jsval_addr())) return NULL; - - if (split) - obj = split_outerObject(cx, obj); } AutoObjectRooter objroot(cx, obj); @@ -3300,21 +2915,16 @@ EvalInContext(JSContext *cx, uintN argc, jsval *vp) if (!src) return false; - bool split = false, lazy = false; + bool lazy = false; if (srclen == 4) { if (src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') { lazy = true; srclen = 0; } - } else if (srclen == 5) { - if (src[0] == 's' && src[1] == 'p' && src[2] == 'l' && src[3] == 'i' && src[4] == 't') { - split = lazy = true; - srclen = 0; - } } if (!sobj) { - sobj = NewSandbox(cx, lazy, split); + sobj = NewSandbox(cx, lazy); if (!sobj) return false; } @@ -3747,7 +3357,7 @@ Scatter(JSContext *cx, uintN argc, jsval *vp) sd.threads[i].fn = JSVAL_NULL; ok = JS_AddValueRoot(cx, &sd.threads[i].fn); - if (ok && !JS_GetElement(cx, inArr, (jsint) i, &sd.threads[i].fn)) { + if (ok && !JS_GetElement(cx, inArr, i, &sd.threads[i].fn)) { JS_RemoveValueRoot(cx, &sd.threads[i].fn); ok = JS_FALSE; } @@ -4684,8 +4294,7 @@ static const char *const shell_help_messages[] = { "evalcx(s[, o])\n" " Evaluate s in optional sandbox object o\n" " if (s == '' && !o) return new o with eager standard classes\n" -" if (s == 'lazy' && !o) return new o with lazy standard classes\n" -" if (s == 'split' && !o) return new split-object o with lazy standard classes", +" if (s == 'lazy' && !o) return new o with lazy standard classes", "evalInFrame(n,str,save) Evaluate 'str' in the nth up frame.\n" " If 'save' (default false), save the frame chain", "shapeOf(obj) Get the shape of obj (an implementation detail)", @@ -4847,47 +4456,6 @@ Help(JSContext *cx, uintN argc, jsval *vp) return JS_TRUE; } -static JSObject * -split_setup(JSContext *cx, JSBool evalcx) -{ - JSObject *outer, *inner, *arguments; - - outer = split_create_outer(cx); - if (!outer) - return NULL; - AutoObjectRooter root(cx, outer); - if (!evalcx) - JS_SetGlobalObject(cx, outer); - - inner = split_create_inner(cx, outer); - if (!inner) - return NULL; - - if (!evalcx) { - if (!JS_DefineFunctions(cx, inner, shell_functions) || - !JS_DefineProfilingFunctions(cx, inner)) { - return NULL; - } - - /* Create a dummy arguments object. */ - arguments = JS_NewArrayObject(cx, 0, NULL); - if (!arguments || - !JS_DefineProperty(cx, inner, "arguments", OBJECT_TO_JSVAL(arguments), - NULL, NULL, 0)) { - return NULL; - } - } - - JS_ClearScope(cx, outer); - -#ifndef LAZY_STANDARD_CLASSES - if (!JS_InitStandardClasses(cx, inner)) - return NULL; -#endif - - return inner; -} - /* * Define a JS object called "it". Give it class operations that printf why * they're being called for tutorial purposes. diff --git a/js/src/tests/js1_8_1/extensions/regress-520572.js b/js/src/tests/js1_8_1/extensions/regress-520572.js index 581f4818f85f..95386a0547d3 100644 --- a/js/src/tests/js1_8_1/extensions/regress-520572.js +++ b/js/src/tests/js1_8_1/extensions/regress-520572.js @@ -24,7 +24,7 @@ function test() if ("evalcx" in this) { // shell - let s = evalcx("split"); + let s = evalcx("lazy"); s.n = 0; evalcx('this.watch("x", function(){ n++; }); this.x = 4; x = 6', s); actual = s.n; diff --git a/js/src/tests/js1_8_5/regress/jstests.list b/js/src/tests/js1_8_5/regress/jstests.list index 0d97bd726643..faee6d5b008d 100644 --- a/js/src/tests/js1_8_5/regress/jstests.list +++ b/js/src/tests/js1_8_5/regress/jstests.list @@ -75,8 +75,9 @@ script regress-601399.js script regress-602621.js fails-if(!xulRuntime.shell) script regress-607799.js fails-if(!xulRuntime.shell) script regress-607863.js -script regress-610026.js script regress-609617.js +script regress-610026.js +script regress-614714.js script regress-617405-1.js script regress-617405-2.js script regress-618572.js @@ -86,8 +87,8 @@ script regress-619003-1.js script regress-619003-2.js skip-if(Android) script regress-620376-1.js script regress-620376-2.js -script regress-621814.js script regress-620750.js +script regress-621814.js script regress-624199.js script regress-624547.js script regress-624968.js @@ -101,14 +102,14 @@ script regress-635195.js script regress-636394.js script regress-636364.js script regress-640075.js +script regress-643222.js script regress-646820-1.js script regress-646820-2.js script regress-646820-3.js -script regress-643222.js -script regress-614714.js script regress-665355.js -script regress-667047.js script regress-666599.js +script regress-667047.js script regress-673070-1.js script regress-673070-2.js script regress-673070-3.js +script regress-675581.js diff --git a/js/src/tests/js1_8_5/regress/regress-675581.js b/js/src/tests/js1_8_5/regress/regress-675581.js new file mode 100644 index 000000000000..2edf6ac4df8c --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-675581.js @@ -0,0 +1,7 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +x= +x.(-0 in x) + +reportCompare(0, 0, 'ok'); diff --git a/js/src/xpconnect/idl/nsIXPCScriptable.idl b/js/src/xpconnect/idl/nsIXPCScriptable.idl index c36339bad50b..fbec93b4baff 100644 --- a/js/src/xpconnect/idl/nsIXPCScriptable.idl +++ b/js/src/xpconnect/idl/nsIXPCScriptable.idl @@ -126,64 +126,64 @@ interface nsIXPCScriptable : nsISupports void postCreate(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); - PRBool addProperty(in nsIXPConnectWrappedNative wrapper, + boolean addProperty(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); - PRBool delProperty(in nsIXPConnectWrappedNative wrapper, + boolean delProperty(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); // The returnCode should be set to NS_SUCCESS_I_DID_SOMETHING if // this method does something. - PRBool getProperty(in nsIXPConnectWrappedNative wrapper, + boolean getProperty(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); // The returnCode should be set to NS_SUCCESS_I_DID_SOMETHING if // this method does something. - PRBool setProperty(in nsIXPConnectWrappedNative wrapper, + boolean setProperty(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); - PRBool enumerate(in nsIXPConnectWrappedNative wrapper, + boolean enumerate(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); - PRBool newEnumerate(in nsIXPConnectWrappedNative wrapper, + boolean newEnumerate(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out jsid idp); - PRBool newResolve(in nsIXPConnectWrappedNative wrapper, + boolean newResolve(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in PRUint32 flags, out JSObjectPtr objp); - PRBool convert(in nsIXPConnectWrappedNative wrapper, + boolean convert(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 type, in JSValPtr vp); void finalize(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); - PRBool checkAccess(in nsIXPConnectWrappedNative wrapper, + boolean checkAccess(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in PRUint32 mode, in JSValPtr vp); - PRBool call(in nsIXPConnectWrappedNative wrapper, + boolean call(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); - PRBool construct(in nsIXPConnectWrappedNative wrapper, + boolean construct(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); - PRBool hasInstance(in nsIXPConnectWrappedNative wrapper, + boolean hasInstance(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, - in jsval val, out PRBool bp); + in jsval val, out boolean bp); void trace(in nsIXPConnectWrappedNative wrapper, in JSTracerPtr trc, in JSObjectPtr obj); - PRBool equality(in nsIXPConnectWrappedNative wrapper, + boolean equality(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val); JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper, diff --git a/js/src/xpconnect/idl/nsIXPConnect.idl b/js/src/xpconnect/idl/nsIXPConnect.idl index c5bb7418e0e6..5bd864553e98 100644 --- a/js/src/xpconnect/idl/nsIXPConnect.idl +++ b/js/src/xpconnect/idl/nsIXPConnect.idl @@ -378,7 +378,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports nsISupports TranslateThis(in nsISupports aInitialThis, in nsIInterfaceInfo aInterfaceInfo, in PRUint16 aMethodIndex, - out PRBool aHideFirstParamFromJS, + out boolean aHideFirstParamFromJS, out nsIIDPtr aIIDOfResult); }; @@ -590,9 +590,9 @@ interface nsIXPConnect : nsISupports void debugDump(in short depth); void debugDumpObject(in nsISupports aCOMObj, in short depth); - void debugDumpJSStack(in PRBool showArgs, - in PRBool showLocals, - in PRBool showThisProps); + void debugDumpJSStack(in boolean showArgs, + in boolean showLocals, + in boolean showThisProps); void debugDumpEvalInJSStackFrame(in PRUint32 aFrameNumber, in string aSourceText); @@ -653,7 +653,7 @@ interface nsIXPConnect : nsISupports in JSObjectPtr aScope, in nsIClassInfo aClassInfo); - void releaseJSContext(in JSContextPtr aJSContext, in PRBool noGC); + void releaseJSContext(in JSContextPtr aJSContext, in boolean noGC); jsval variantToJS(in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); nsIVariant JSToVariant(in JSContextPtr ctx, in jsval value); @@ -700,7 +700,7 @@ interface nsIXPConnect : nsISupports */ [noscript] jsval evalInSandboxObject(in AString source, in JSContextPtr cx, in nsIXPConnectJSObjectHolder sandbox, - in PRBool returnStringOnly); + in boolean returnStringOnly); /** * Root JS objects held by aHolder. @@ -761,7 +761,7 @@ interface nsIXPConnect : nsISupports * The interfaces the class implements; interfaceArray and * interfaceCount are like what nsIClassInfo.getInterfaces returns. */ - [noscript,notxpcom] PRBool defineDOMQuickStubs( + [noscript,notxpcom] boolean defineDOMQuickStubs( in JSContextPtr cx, in JSObjectPtr proto, in PRUint32 flags, @@ -802,5 +802,5 @@ interface nsIXPConnect : nsISupports * This method will turn debug mode on or off when the context * stack reaches zero length. */ - [noscript] void setDebugModeWhenPossible(in PRBool mode); + [noscript] void setDebugModeWhenPossible(in boolean mode); }; diff --git a/js/src/xpconnect/loader/ISO8601DateUtils.jsm b/js/src/xpconnect/loader/ISO8601DateUtils.jsm deleted file mode 100644 index f53dfd7248a7..000000000000 --- a/js/src/xpconnect/loader/ISO8601DateUtils.jsm +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Robert Sayre. - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Flock Inc. - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -const HOURS_TO_MINUTES = 60; -const MINUTES_TO_SECONDS = 60; -const SECONDS_TO_MILLISECONDS = 1000; -const MINUTES_TO_MILLISECONDS = MINUTES_TO_SECONDS * SECONDS_TO_MILLISECONDS; -const HOURS_TO_MILLISECONDS = HOURS_TO_MINUTES * MINUTES_TO_MILLISECONDS; - -var EXPORTED_SYMBOLS = ["ISO8601DateUtils"]; - -debug("*** loading ISO8601DateUtils\n"); - -var ISO8601DateUtils = { - - /** - * XXX Thunderbird's W3C-DTF function - * - * Converts a W3C-DTF (subset of ISO 8601) date string to a Javascript - * date object. W3C-DTF is described in this note: - * http://www.w3.org/TR/NOTE-datetime IETF is obtained via the Date - * object's toUTCString() method. The object's toString() method is - * insufficient because it spells out timezones on Win32 - * (f.e. "Pacific Standard Time" instead of "PST"), which Mail doesn't - * grok. For info, see - * http://lxr.mozilla.org/mozilla/source/js/src/jsdate.c#1526. - */ - parse: function ISO8601_parse(aDateString) { - var dateString = aDateString; - if (!dateString.match('-')) { - // Workaround for server sending - // dates such as: 20030530T11:18:50-08:00 - // instead of: 2003-05-30T11:18:50-08:00 - var year = dateString.slice(0, 4); - var month = dateString.slice(4, 6); - var rest = dateString.slice(6, dateString.length); - dateString = year + "-" + month + "-" + rest; - } - - var parts = dateString.match(/(\d{4})(-(\d{2,3}))?(-(\d{2}))?(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|([+-])(\d{2}):(\d{2}))?)?/); - - // Here's an example of a W3C-DTF date string and what .match returns for it. - // - // date: 2003-05-30T11:18:50.345-08:00 - // date.match returns array values: - // - // 0: 2003-05-30T11:18:50-08:00, - // 1: 2003, - // 2: -05, - // 3: 05, - // 4: -30, - // 5: 30, - // 6: T11:18:50-08:00, - // 7: 11, - // 8: 18, - // 9: :50, - // 10: 50, - // 11: .345, - // 12: 345, - // 13: -08:00, - // 14: -, - // 15: 08, - // 16: 00 - - // Create a Date object from the date parts. Note that the Date - // object apparently can't deal with empty string parameters in lieu - // of numbers, so optional values (like hours, minutes, seconds, and - // milliseconds) must be forced to be numbers. - var date = new Date(parts[1], parts[3] - 1, parts[5], parts[7] || 0, - parts[8] || 0, parts[10] || 0, parts[12] || 0); - - // We now have a value that the Date object thinks is in the local - // timezone but which actually represents the date/time in the - // remote timezone (f.e. the value was "10:00 EST", and we have - // converted it to "10:00 PST" instead of "07:00 PST"). We need to - // correct that. To do so, we're going to add the offset between - // the remote timezone and UTC (to convert the value to UTC), then - // add the offset between UTC and the local timezone //(to convert - // the value to the local timezone). - - // Ironically, W3C-DTF gives us the offset between UTC and the - // remote timezone rather than the other way around, while the - // getTimezoneOffset() method of a Date object gives us the offset - // between the local timezone and UTC rather than the other way - // around. Both of these are the additive inverse (i.e. -x for x) - // of what we want, so we have to invert them to use them by - // multipying by -1 (f.e. if "the offset between UTC and the remote - // timezone" is -5 hours, then "the offset between the remote - // timezone and UTC" is -5*-1 = 5 hours). - - // Note that if the timezone portion of the date/time string is - // absent (which violates W3C-DTF, although ISO 8601 allows it), we - // assume the value to be in UTC. - - // The offset between the remote timezone and UTC in milliseconds. - var remoteToUTCOffset = 0; - if (parts[13] && parts[13] != "Z") { - var direction = (parts[14] == "+" ? 1 : -1); - if (parts[15]) - remoteToUTCOffset += direction * parts[15] * HOURS_TO_MILLISECONDS; - if (parts[16]) - remoteToUTCOffset += direction * parts[16] * MINUTES_TO_MILLISECONDS; - } - remoteToUTCOffset = remoteToUTCOffset * -1; // invert it - - // The offset between UTC and the local timezone in milliseconds. - var UTCToLocalOffset = date.getTimezoneOffset() * MINUTES_TO_MILLISECONDS; - UTCToLocalOffset = UTCToLocalOffset * -1; // invert it - date.setTime(date.getTime() + remoteToUTCOffset + UTCToLocalOffset); - - return date; - }, - - create: function ISO8601_create(aDate) { - function zeropad (s, l) { - s = s.toString(); // force it to a string - while (s.length < l) { - s = '0' + s; - } - return s; - } - - var myDate; - // if d is a number, turn it into a date - if (typeof aDate == 'number') { - myDate = new Date() - myDate.setTime(aDate); - } else { - myDate = aDate; - } - - // YYYY-MM-DDThh:mm:ssZ - var result = zeropad(myDate.getUTCFullYear (), 4) + - zeropad(myDate.getUTCMonth () + 1, 2) + - zeropad(myDate.getUTCDate (), 2) + 'T' + - zeropad(myDate.getUTCHours (), 2) + ':' + - zeropad(myDate.getUTCMinutes (), 2) + ':' + - zeropad(myDate.getUTCSeconds (), 2) + 'Z'; - - return result; - } -} diff --git a/js/src/xpconnect/loader/Makefile.in b/js/src/xpconnect/loader/Makefile.in index def3717d2dec..d8d504f93626 100644 --- a/js/src/xpconnect/loader/Makefile.in +++ b/js/src/xpconnect/loader/Makefile.in @@ -49,7 +49,7 @@ LOCAL_INCLUDES += -I$(srcdir)/../src CPPSRCS = mozJSComponentLoader.cpp mozJSSubScriptLoader.cpp mozJSLoaderUtils.cpp -EXTRA_JS_MODULES = XPCOMUtils.jsm ISO8601DateUtils.jsm +EXTRA_JS_MODULES = XPCOMUtils.jsm include $(topsrcdir)/config/rules.mk diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp index 0645a7d59a48..fa604b7459a1 100644 --- a/js/src/xpconnect/shell/xpcshell.cpp +++ b/js/src/xpconnect/shell/xpcshell.cpp @@ -1152,7 +1152,7 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) { const char rcfilename[] = "xpcshell.js"; FILE *rcfile; - int i, j, length; + int i; JSObject *argsObj; char *filename = NULL; JSBool isInteractive = JS_TRUE; @@ -1198,8 +1198,7 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) return 1; } - length = argc - i; - for (j = 0; j < length; j++) { + for (size_t j = 0, length = argc - i; j < length; j++) { JSString *str = JS_NewStringCopyZ(cx, argv[i++]); if (!str) return 1; diff --git a/js/src/xpconnect/src/dom_quickstubs.qsconf b/js/src/xpconnect/src/dom_quickstubs.qsconf index 72bca2d20e45..8c1f7e3110dc 100644 --- a/js/src/xpconnect/src/dom_quickstubs.qsconf +++ b/js/src/xpconnect/src/dom_quickstubs.qsconf @@ -213,6 +213,7 @@ members = [ # but it is also present in other objects where it isn't shadowed. # Quick stubs handle the shadowing the same as XPConnect. 'nsIDOMHTMLCollection.length', + 'nsIDOMHTMLCommandElement.*', 'nsIDOMHTMLDocument.body', 'nsIDOMHTMLDocument.getElementsByName', 'nsIDOMHTMLDocument.anchors', @@ -261,6 +262,8 @@ members = [ 'nsIDOMHTMLInputElement.selectionDirection', 'nsIDOMHTMLInputElement.setSelectionRange', 'nsIDOMHTMLLinkElement.disabled', + 'nsIDOMHTMLMenuElement.*', + 'nsIDOMHTMLMenuItemElement.*', 'nsIDOMHTMLOptionElement.index', 'nsIDOMHTMLOptionElement.selected', 'nsIDOMHTMLOptionElement.form', diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index 20e484d0332c..a7521608a57a 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -1323,8 +1323,8 @@ CompartmentCallback(JSContext *cx, void *vdata, JSCompartment *compartment) // Append a new CompartmentStats to the vector. IterateData *data = static_cast(vdata); CompartmentStats compartmentStats(cx, compartment); - data->compartmentStatsVector.infallibleAppend(compartmentStats); - CompartmentStats *curr = data->compartmentStatsVector.end() - 1; + CompartmentStats *curr = + data->compartmentStatsVector.AppendElement(compartmentStats); data->currCompartmentStats = curr; // Get the compartment-level numbers. @@ -1610,8 +1610,7 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data) { JSAutoRequest ar(cx); - if (!data->compartmentStatsVector.reserve(rt->compartments.length())) - return false; + data->compartmentStatsVector.SetCapacity(rt->compartments.length()); data->gcHeapChunkCleanUnused = PRInt64(JS_GetGCParameter(rt, JSGC_UNUSED_CHUNKS)) * @@ -1635,17 +1634,19 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data) data->gcHeapChunkCleanUnused; data->gcHeapArenaUnused = 0; - for(CompartmentStats *stats = data->compartmentStatsVector.begin(); - stats != data->compartmentStatsVector.end(); - ++stats) + for(PRUint32 index = 0; + index < data->compartmentStatsVector.Length(); + index++) { + CompartmentStats &stats = data->compartmentStatsVector[index]; + data->gcHeapChunkDirtyUnused -= - stats->gcHeapArenaHeaders + stats->gcHeapArenaPadding + - stats->gcHeapArenaUnused + - stats->gcHeapObjects + stats->gcHeapStrings + - stats->gcHeapShapes + stats->gcHeapXml; + stats.gcHeapArenaHeaders + stats.gcHeapArenaPadding + + stats.gcHeapArenaUnused + + stats.gcHeapObjects + stats.gcHeapStrings + + stats.gcHeapShapes + stats.gcHeapXml; - data->gcHeapArenaUnused += stats->gcHeapArenaUnused; + data->gcHeapArenaUnused += stats.gcHeapArenaUnused; } size_t numDirtyChunks = (data->gcHeapChunkTotal - @@ -1808,11 +1809,12 @@ ReportJSRuntimeStats(const IterateData &data, const nsACString &pathPrefix, nsIMemoryMultiReporterCallback *callback, nsISupports *closure) { - for(const CompartmentStats *stats = data.compartmentStatsVector.begin(); - stats != data.compartmentStatsVector.end(); - ++stats) + for(PRUint32 index = 0; + index < data.compartmentStatsVector.Length(); + index++) { - ReportCompartmentStats(*stats, pathPrefix, callback, closure); + ReportCompartmentStats(data.compartmentStatsVector[index], pathPrefix, + callback, closure); } ReportMemoryBytes(pathPrefix + NS_LITERAL_CSTRING("stack"), diff --git a/js/src/xpconnect/src/xpcpublic.h b/js/src/xpconnect/src/xpcpublic.h index ee356388ba83..b8e4e962cdd1 100644 --- a/js/src/xpconnect/src/xpcpublic.h +++ b/js/src/xpconnect/src/xpcpublic.h @@ -49,6 +49,7 @@ #include "nsIPrincipal.h" #include "nsWrapperCache.h" #include "nsStringGlue.h" +#include "nsTArray.h" class nsIPrincipal; @@ -242,7 +243,7 @@ struct IterateData PRInt64 gcHeapChunkAdmin; PRInt64 gcHeapUnusedPercentage; - js::Vector compartmentStatsVector; + nsTArray compartmentStatsVector; CompartmentStats *currCompartmentStats; }; diff --git a/layout/base/nsAutoLayoutPhase.h b/layout/base/nsAutoLayoutPhase.h new file mode 100644 index 000000000000..3b274fe700ff --- /dev/null +++ b/layout/base/nsAutoLayoutPhase.h @@ -0,0 +1,133 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron , Mozilla Corporation (original author) + * Timothy Nikkel + * Boris Zbarsky + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsAutoLayoutPhase_h +#define nsAutoLayoutPhase_h + +#ifdef DEBUG + +#include "nsPresContext.h" +#include "nsContentUtils.h" + +struct nsAutoLayoutPhase { + nsAutoLayoutPhase(nsPresContext* aPresContext, nsLayoutPhase aPhase) + : mPresContext(aPresContext), mPhase(aPhase), mCount(0) + { + Enter(); + } + + ~nsAutoLayoutPhase() + { + Exit(); + NS_ASSERTION(mCount == 0, "imbalanced"); + } + + void Enter() + { + switch (mPhase) { + case eLayoutPhase_Paint: + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, + "recurring into paint"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, + "painting in the middle of reflow"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, + "painting in the middle of frame construction"); + break; + case eLayoutPhase_Reflow: + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, + "reflowing in the middle of a paint"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, + "recurring into reflow"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, + "reflowing in the middle of frame construction"); + break; + case eLayoutPhase_FrameC: + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, + "constructing frames in the middle of a paint"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, + "constructing frames in the middle of reflow"); + NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, + "recurring into frame construction"); + NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), + "constructing frames and scripts are not blocked"); + break; + default: + break; + } + ++(mPresContext->mLayoutPhaseCount[mPhase]); + ++mCount; + } + + void Exit() + { + NS_ASSERTION(mCount > 0 && mPresContext->mLayoutPhaseCount[mPhase] > 0, + "imbalanced"); + --(mPresContext->mLayoutPhaseCount[mPhase]); + --mCount; + } + +private: + nsPresContext* mPresContext; + nsLayoutPhase mPhase; + PRUint32 mCount; +}; + +#define AUTO_LAYOUT_PHASE_ENTRY_POINT(pc_, phase_) \ + nsAutoLayoutPhase autoLayoutPhase((pc_), (eLayoutPhase_##phase_)) +#define LAYOUT_PHASE_TEMP_EXIT() \ + PR_BEGIN_MACRO \ + autoLayoutPhase.Exit(); \ + PR_END_MACRO +#define LAYOUT_PHASE_TEMP_REENTER() \ + PR_BEGIN_MACRO \ + autoLayoutPhase.Enter(); \ + PR_END_MACRO + +#else + +#define AUTO_LAYOUT_PHASE_ENTRY_POINT(pc_, phase_) \ + PR_BEGIN_MACRO PR_END_MACRO +#define LAYOUT_PHASE_TEMP_EXIT() \ + PR_BEGIN_MACRO PR_END_MACRO +#define LAYOUT_PHASE_TEMP_REENTER() \ + PR_BEGIN_MACRO PR_END_MACRO + +#endif + +#endif // nsAutoLayoutPhase_h diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index c1a08399faa3..1ca03ea77156 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -118,6 +118,7 @@ #include "nsGenericDOMDataNode.h" #include "mozilla/dom/Element.h" #include "FrameLayerBuilder.h" +#include "nsAutoLayoutPhase.h" #ifdef MOZ_XUL #include "nsIRootBox.h" diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 46c75b07fc88..7c100ca0d7b5 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -108,10 +108,12 @@ public: */ PRBool PrepareImage(); /** - * @return the image size in appunits. CSS gradient images don't have an - * intrinsic size so we have to pass in a default that they will use. + * @return the image size in appunits when rendered, after accounting for the + * background positioning area, background-size, and the image's intrinsic + * dimensions (if any). */ - nsSize ComputeSize(const nsSize& aDefault); + nsSize ComputeSize(const nsStyleBackground::Size& aLayerSize, + const nsSize& aBgPositioningArea); /** * Draws the image to the target rendering context. * @see nsLayoutUtils::DrawImage() for other parameters @@ -124,6 +126,29 @@ public: const nsRect& aDirty); private: + /* + * Compute the "unscaled" dimensions of the image in aUnscaled{Width,Height} + * and aRatio. Whether the image has a height and width are indicated by + * aHaveWidth and aHaveHeight. If the image doesn't have a ratio, aRatio will + * be (0, 0). + */ + void ComputeUnscaledDimensions(const nsSize& aBgPositioningArea, + nscoord& aUnscaledWidth, bool& aHaveWidth, + nscoord& aUnscaledHeight, bool& aHaveHeight, + nsSize& aRatio); + + /* + * Using the previously-computed unscaled width and height (if each are + * valid, as indicated by aHaveWidth/aHaveHeight), compute the size at which + * the image should actually render. + */ + nsSize + ComputeDrawnSize(const nsStyleBackground::Size& aLayerSize, + const nsSize& aBgPositioningArea, + nscoord aUnscaledWidth, bool aHaveWidth, + nscoord aUnscaledHeight, bool aHaveHeight, + const nsSize& aIntrinsicRatio); + nsIFrame* mForFrame; const nsStyleImage* mImage; nsStyleImageType mType; @@ -132,7 +157,7 @@ private: nsIFrame* mPaintServerFrame; nsLayoutUtils::SurfaceFromElementResult mImageElementSurface; PRBool mIsReady; - nsSize mSize; + nsSize mSize; // unscaled size of the image, in app units PRUint32 mFlags; }; @@ -2432,27 +2457,6 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, } } -static inline float -ScaleDimension(const nsStyleBackground::Size::Dimension& aDimension, - PRUint8 aType, - nscoord aLength, nscoord aAvailLength) -{ - switch (aType) { - case nsStyleBackground::Size::eLengthPercentage: - // negative values could result from calc() - return NS_MAX(double(aDimension.mPercent) * double(aAvailLength) + - double(aDimension.mLength), - 0.0) / - double(aLength); - default: - NS_ABORT_IF_FALSE(PR_FALSE, "bad aDimension.mType"); - return 1.0f; - case nsStyleBackground::Size::eAuto: - NS_ABORT_IF_FALSE(PR_FALSE, "aDimension.mType == eAuto isn't handled"); - return 1.0f; - } -} - static inline PRBool IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame) { @@ -2647,52 +2651,12 @@ PrepareBackgroundLayer(nsPresContext* aPresContext, } } - nsSize imageSize = state.mImageRenderer.ComputeSize(bgPositioningArea.Size()); - if (imageSize.width <= 0 || imageSize.height <= 0) - return state; - // Scale the image as specified for background-size and as required for // proper background positioning when background-position is defined with // percentages. - float scaleX, scaleY; - switch (aLayer.mSize.mWidthType) { - case nsStyleBackground::Size::eContain: - case nsStyleBackground::Size::eCover: { - float scaleFitX = double(bgPositioningArea.width) / imageSize.width; - float scaleFitY = double(bgPositioningArea.height) / imageSize.height; - if (aLayer.mSize.mWidthType == nsStyleBackground::Size::eCover) { - scaleX = scaleY = NS_MAX(scaleFitX, scaleFitY); - } else { - scaleX = scaleY = NS_MIN(scaleFitX, scaleFitY); - } - break; - } - default: { - if (aLayer.mSize.mWidthType == nsStyleBackground::Size::eAuto) { - if (aLayer.mSize.mHeightType == nsStyleBackground::Size::eAuto) { - scaleX = scaleY = 1.0f; - } else { - scaleX = scaleY = - ScaleDimension(aLayer.mSize.mHeight, aLayer.mSize.mHeightType, - imageSize.height, bgPositioningArea.height); - } - } else { - if (aLayer.mSize.mHeightType == nsStyleBackground::Size::eAuto) { - scaleX = scaleY = - ScaleDimension(aLayer.mSize.mWidth, aLayer.mSize.mWidthType, - imageSize.width, bgPositioningArea.width); - } else { - scaleX = ScaleDimension(aLayer.mSize.mWidth, aLayer.mSize.mWidthType, - imageSize.width, bgPositioningArea.width); - scaleY = ScaleDimension(aLayer.mSize.mHeight, aLayer.mSize.mHeightType, - imageSize.height, bgPositioningArea.height); - } - } - break; - } - } - imageSize.width = NSCoordSaturatingNonnegativeMultiply(imageSize.width, scaleX); - imageSize.height = NSCoordSaturatingNonnegativeMultiply(imageSize.height, scaleY); + nsSize imageSize = state.mImageRenderer.ComputeSize(aLayer.mSize, bgPositioningArea.Size()); + if (imageSize.width <= 0 || imageSize.height <= 0) + return state; // Compute the position of the background now that the background's size is // determined. @@ -3861,8 +3825,33 @@ ImageRenderer::PrepareImage() return mIsReady; } -nsSize -ImageRenderer::ComputeSize(const nsSize& aDefault) +enum FitType { CONTAIN, COVER }; + +static nsSize +ComputeContainCoverSizeFromRatio(const nsSize& aBgPositioningArea, + const nsSize& aRatio, FitType fitType) +{ + NS_ABORT_IF_FALSE(aRatio.width > 0, "width division by zero"); + NS_ABORT_IF_FALSE(aRatio.height > 0, "height division by zero"); + + float scaleX = double(aBgPositioningArea.width) / aRatio.width; + float scaleY = double(aBgPositioningArea.height) / aRatio.height; + nsSize size; + if ((fitType == CONTAIN) == (scaleX < scaleY)) { + size.width = aBgPositioningArea.width; + size.height = NSCoordSaturatingNonnegativeMultiply(aRatio.height, scaleX); + } else { + size.width = NSCoordSaturatingNonnegativeMultiply(aRatio.width, scaleY); + size.height = aBgPositioningArea.height; + } + return size; +} + +void +ImageRenderer::ComputeUnscaledDimensions(const nsSize& aBgPositioningArea, + nscoord& aUnscaledWidth, bool& aHaveWidth, + nscoord& aUnscaledHeight, bool& aHaveHeight, + nsSize& aRatio) { NS_ASSERTION(mIsReady, "Ensure PrepareImage() has returned true " "before calling me"); @@ -3871,28 +3860,35 @@ ImageRenderer::ComputeSize(const nsSize& aDefault) case eStyleImageType_Image: { nsIntSize imageIntSize; - PRBool gotHeight, gotWidth; nsLayoutUtils::ComputeSizeForDrawing(mImageContainer, imageIntSize, - gotWidth, gotHeight); - - mSize.width = gotWidth ? - nsPresContext::CSSPixelsToAppUnits(imageIntSize.width) : - aDefault.width; - - mSize.height = gotHeight ? - nsPresContext::CSSPixelsToAppUnits(imageIntSize.height) : - aDefault.height; - - break; + aRatio, aHaveWidth, aHaveHeight); + if (aHaveWidth) { + aUnscaledWidth = nsPresContext::CSSPixelsToAppUnits(imageIntSize.width); + } + if (aHaveHeight) { + aUnscaledHeight = nsPresContext::CSSPixelsToAppUnits(imageIntSize.height); + } + return; } case eStyleImageType_Gradient: - mSize = aDefault; - break; + // Per , gradients have no + // intrinsic dimensions. + aHaveWidth = aHaveHeight = false; + aRatio = nsSize(0, 0); + return; case eStyleImageType_Element: { + // XXX element() should have the width/height of the referenced element, + // and that element's ratio, if it matches. If it doesn't match, it + // should have no width/height or ratio. See element() in CSS3: + // . + // Make sure to change nsStyleBackground::Size::DependsOnFrameSize + // when fixing this! + aHaveWidth = aHaveHeight = true; + nsSize size; if (mPaintServerFrame) { if (mPaintServerFrame->IsFrameOfType(nsIFrame::eSVG)) { - mSize = aDefault; + size = aBgPositioningArea; } else { // The intrinsic image size for a generic nsIFrame paint server is // the frame's bbox size rounded to device pixels. @@ -3900,25 +3896,216 @@ ImageRenderer::ComputeSize(const nsSize& aDefault) mForFrame->PresContext()->AppUnitsPerDevPixel(); nsRect rect = nsSVGIntegrationUtils::GetNonSVGUserSpace(mPaintServerFrame); - nsRect size = rect - rect.TopLeft(); - nsIntRect rounded = size.ToNearestPixels(appUnitsPerDevPixel); - mSize = rounded.ToAppUnits(appUnitsPerDevPixel).Size(); + nsRect rectSize = rect - rect.TopLeft(); + nsIntRect rounded = rectSize.ToNearestPixels(appUnitsPerDevPixel); + size = rounded.ToAppUnits(appUnitsPerDevPixel).Size(); } } else { NS_ASSERTION(mImageElementSurface.mSurface, "Surface should be ready."); - gfxIntSize size = mImageElementSurface.mSize; - mSize.width = nsPresContext::CSSPixelsToAppUnits(size.width); - mSize.height = nsPresContext::CSSPixelsToAppUnits(size.height); + gfxIntSize surfaceSize = mImageElementSurface.mSize; + size.width = nsPresContext::CSSPixelsToAppUnits(surfaceSize.width); + size.height = nsPresContext::CSSPixelsToAppUnits(surfaceSize.height); } - break; + aRatio = size; + aUnscaledWidth = size.width; + aUnscaledHeight = size.height; + return; } case eStyleImageType_Null: default: - mSize.SizeTo(0, 0); - break; + aHaveWidth = aHaveHeight = true; + aUnscaledWidth = aUnscaledHeight = 0; + aRatio = nsSize(0, 0); + return; + } +} + +nsSize +ImageRenderer::ComputeDrawnSize(const nsStyleBackground::Size& aLayerSize, + const nsSize& aBgPositioningArea, + nscoord aUnscaledWidth, bool aHaveWidth, + nscoord aUnscaledHeight, bool aHaveHeight, + const nsSize& aIntrinsicRatio) +{ + NS_ABORT_IF_FALSE(aIntrinsicRatio.width >= 0, + "image ratio with nonsense width"); + NS_ABORT_IF_FALSE(aIntrinsicRatio.height >= 0, + "image ratio with nonsense height"); + + // Bail early if the image is empty. + if ((aHaveWidth && aUnscaledWidth <= 0) || + (aHaveHeight && aUnscaledHeight <= 0)) { + return nsSize(0, 0); } - return mSize; + // If the image has an intrinsic ratio but either component of it is zero, + // then the image would eventually scale to nothingness, so again we can bail. + bool haveRatio = aIntrinsicRatio != nsSize(0, 0); + if (haveRatio && + (aIntrinsicRatio.width == 0 || aIntrinsicRatio.height == 0)) { + return nsSize(0, 0); + } + + // Easiest case: background-size completely specifies the size. + if (aLayerSize.mWidthType == nsStyleBackground::Size::eLengthPercentage && + aLayerSize.mHeightType == nsStyleBackground::Size::eLengthPercentage) { + return nsSize(aLayerSize.ResolveWidthLengthPercentage(aBgPositioningArea), + aLayerSize.ResolveHeightLengthPercentage(aBgPositioningArea)); + } + + // The harder cases: contain/cover. + if (aLayerSize.mWidthType == nsStyleBackground::Size::eContain || + aLayerSize.mWidthType == nsStyleBackground::Size::eCover) { + FitType fitType = aLayerSize.mWidthType == nsStyleBackground::Size::eCover + ? COVER + : CONTAIN; + if (!haveRatio) { + // If we don't have an intrinsic ratio, then proportionally scaling to + // either largest-fitting or smallest-covering size means scaling to the + // background positioning area's size. + return aBgPositioningArea; + } + + return ComputeContainCoverSizeFromRatio(aBgPositioningArea, aIntrinsicRatio, + fitType); + } + + // Harder case: all-auto. + if (aLayerSize.mWidthType == nsStyleBackground::Size::eAuto && + aLayerSize.mHeightType == nsStyleBackground::Size::eAuto) { + // If the image has all its dimensions, we're done. + if (aHaveWidth && aHaveHeight) + return nsSize(aUnscaledWidth, aUnscaledHeight); + + // If the image has no dimensions, treat it as if for contain. + if (!aHaveWidth && !aHaveHeight) { + if (!haveRatio) { + // As above, max-contain without a ratio means the whole area. + return aBgPositioningArea; + } + + // Otherwise determine size using the intrinsic ratio. + return ComputeContainCoverSizeFromRatio(aBgPositioningArea, + aIntrinsicRatio, CONTAIN); + } + + NS_ABORT_IF_FALSE(aHaveWidth != aHaveHeight, "logic error"); + + if (haveRatio) { + // Resolve missing dimensions using the intrinsic ratio. + nsSize size; + if (aHaveWidth) { + size.width = aUnscaledWidth; + size.height = + NSCoordSaturatingNonnegativeMultiply(size.width, + double(aIntrinsicRatio.height) / + aIntrinsicRatio.width); + } else { + size.height = aUnscaledHeight; + size.width = + NSCoordSaturatingNonnegativeMultiply(size.height, + double(aIntrinsicRatio.width) / + aIntrinsicRatio.height); + } + + return size; + } + + // Without a ratio we must fall back to the relevant dimension of the + // area to determine the missing dimension. + return aHaveWidth ? nsSize(aUnscaledWidth, aBgPositioningArea.height) + : nsSize(aBgPositioningArea.width, aUnscaledHeight); + } + + // Hardest case: only one auto. Prepare to negotiate amongst intrinsic + // dimensions, intrinsic ratio, *and* a specific background-size! + NS_ABORT_IF_FALSE((aLayerSize.mWidthType == nsStyleBackground::Size::eAuto) != + (aLayerSize.mHeightType == nsStyleBackground::Size::eAuto), + "logic error"); + + bool isAutoWidth = aLayerSize.mWidthType == nsStyleBackground::Size::eAuto; + + if (haveRatio) { + // Use the specified dimension, and compute the other from the ratio. + NS_ABORT_IF_FALSE(aIntrinsicRatio.width > 0, + "ratio width out of sync with width?"); + NS_ABORT_IF_FALSE(aIntrinsicRatio.height > 0, + "ratio height out of sync with width?"); + nsSize size; + if (isAutoWidth) { + size.height = aLayerSize.ResolveHeightLengthPercentage(aBgPositioningArea); + size.width = + NSCoordSaturatingNonnegativeMultiply(size.height, + double(aIntrinsicRatio.width) / + aIntrinsicRatio.height); + } else { + size.width = aLayerSize.ResolveWidthLengthPercentage(aBgPositioningArea); + size.height = + NSCoordSaturatingNonnegativeMultiply(size.width, + double(aIntrinsicRatio.height) / + aIntrinsicRatio.width); + } + + return size; + } + + NS_ABORT_IF_FALSE(!(aHaveWidth && aHaveHeight), + "if we have width and height, we must have had a ratio"); + + // We have a specified dimension and an auto dimension, with no ratio to + // preserve. A specified dimension trumps all, so use that. For the other + // dimension, resolve auto to the intrinsic dimension (if present) or to 100%. + nsSize size; + if (isAutoWidth) { + size.width = aHaveWidth ? aUnscaledWidth : aBgPositioningArea.width; + size.height = aLayerSize.ResolveHeightLengthPercentage(aBgPositioningArea); + } else { + size.width = aLayerSize.ResolveWidthLengthPercentage(aBgPositioningArea); + size.height = aHaveHeight ? aUnscaledHeight : aBgPositioningArea.height; + } + + return size; +} + +/* + * The size returned by this method differs from the value of mSize, which this + * method also computes, in that mSize is the image's "preferred" size for this + * particular rendering, while the size returned here is the actual rendered + * size after accounting for background-size. The preferred size is most often + * the image's intrinsic dimensions. But for images with incomplete intrinsic + * dimensions, the preferred size varies, depending on the background + * positioning area, the specified background-size, and the intrinsic ratio and + * dimensions of the image (if it has them). + * + * This distinction is necessary because the components of a vector image are + * specified with respect to its preferred size for a rendering situation, not + * to its actual rendered size after background-size is applied. For example, + * consider a 4px wide vector image with no height which contains a left-aligned + * 2px wide black rectangle with height 100%. If the background-size width is + * auto (or 4px), the vector image will render 4px wide, and the black rectangle + * will be 2px wide. If the background-size width is 8px, the vector image will + * render 8px wide, and the black rectangle will be 4px wide -- *not* 2px wide. + * In both cases mSize.width will be 4px; but in the first case the returned + * width will be 4px, while in the second case the returned width will be 8px. + */ +nsSize +ImageRenderer::ComputeSize(const nsStyleBackground::Size& aLayerSize, + const nsSize& aBgPositioningArea) +{ + bool haveWidth, haveHeight; + nsSize ratio; + nscoord unscaledWidth, unscaledHeight; + ComputeUnscaledDimensions(aBgPositioningArea, + unscaledWidth, haveWidth, + unscaledHeight, haveHeight, + ratio); + nsSize drawnSize = ComputeDrawnSize(aLayerSize, aBgPositioningArea, + unscaledWidth, haveWidth, + unscaledHeight, haveHeight, + ratio); + mSize.width = haveWidth ? unscaledWidth : drawnSize.width; + mSize.height = haveHeight ? unscaledHeight : drawnSize.height; + return drawnSize; } void @@ -3947,7 +4134,9 @@ ImageRenderer::Draw(nsPresContext* aPresContext, PRUint32 drawFlags = (mFlags & FLAG_SYNC_DECODE_IMAGES) ? (PRUint32) imgIContainer::FLAG_SYNC_DECODE : (PRUint32) imgIContainer::FLAG_NONE; - nsLayoutUtils::DrawImage(&aRenderingContext, mImageContainer, + nsLayoutUtils::DrawBackgroundImage(&aRenderingContext, mImageContainer, + nsIntSize(nsPresContext::AppUnitsToIntCSSPixels(mSize.width), + nsPresContext::AppUnitsToIntCSSPixels(mSize.height)), graphicsFilter, aDest, aFill, aAnchor, aDirty, drawFlags); break; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 4b22670d2723..0fb5623320f3 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1023,12 +1023,15 @@ nsDisplayBackground::HitTest(nsDisplayListBuilder* aBuilder, HitTestState* aState, nsTArray *aOutFrames) { - // For theme backgrounds, assume that any point in our bounds is a hit. - // We don't know the true hit region of the theme background. - if (!mIsThemed && - !RoundedBorderIntersectsRect(mFrame, ToReferenceFrame(), aRect)) { - // aRect doesn't intersect our border-radius curve. - return; + if (mIsThemed) { + // For theme backgrounds, assume that any point in our border rect is a hit. + if (!nsRect(ToReferenceFrame(), mFrame->GetSize()).Intersects(aRect)) + return; + } else { + if (!RoundedBorderIntersectsRect(mFrame, ToReferenceFrame(), aRect)) { + // aRect doesn't intersect our border-radius curve. + return; + } } aOutFrames->AppendElement(mFrame); diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 3ec60813e784..f3169b6b65c7 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1980,7 +1980,7 @@ DocumentViewerImpl::Show(void) printf("About to evict content viewers: prev=%d, loaded=%d\n", prevIndex, loadedIndex); #endif - historyInt->EvictContentViewers(prevIndex, loadedIndex); + historyInt->EvictOutOfRangeContentViewers(loadedIndex); } } } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 735cd510298b..f0f9170ac2b7 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3569,46 +3569,47 @@ nsLayoutUtils::DrawSingleImage(nsRenderingContext* aRenderingContext, /* static */ void nsLayoutUtils::ComputeSizeForDrawing(imgIContainer *aImage, nsIntSize& aImageSize, /*outparam*/ - PRBool& aGotWidth, /*outparam*/ - PRBool& aGotHeight /*outparam*/) + nsSize& aIntrinsicRatio, /*outparam*/ + bool& aGotWidth, /*outparam*/ + bool& aGotHeight /*outparam*/) { aGotWidth = NS_SUCCEEDED(aImage->GetWidth(&aImageSize.width)); aGotHeight = NS_SUCCEEDED(aImage->GetHeight(&aImageSize.height)); - if ((aGotWidth && aGotHeight) || // Trivial success! - (!aGotWidth && !aGotHeight)) { // Trivial failure! + if (aGotWidth && aGotHeight) { + aIntrinsicRatio = nsSize(aImageSize.width, aImageSize.height); return; } - // If we get here, we succeeded at querying *either* the width *or* the - // height, but not both. - NS_ASSERTION(aImage->GetType() == imgIContainer::TYPE_VECTOR, - "GetWidth and GetHeight should only fail for vector images"); - - nsIFrame* rootFrame = aImage->GetRootLayoutFrame(); - NS_ASSERTION(rootFrame, - "We should have a VectorImage, which should have a rootFrame"); - - // This falls back on failure, if we somehow end up without a rootFrame. - nsSize ratio = rootFrame ? rootFrame->GetIntrinsicRatio() : nsSize(0,0); - if (!aGotWidth) { // Have height, missing width - if (ratio.height != 0) { // don't divide by zero - aImageSize.width = NSToCoordRound(aImageSize.height * - float(ratio.width) / - float(ratio.height)); - aGotWidth = PR_TRUE; - } - } else { // Have width, missing height - if (ratio.width != 0) { // don't divide by zero - aImageSize.height = NSToCoordRound(aImageSize.width * - float(ratio.height) / - float(ratio.width)); - aGotHeight = PR_TRUE; - } + // If we failed to get width or height, we either have a vector image and + // should return its intrinsic ratio, or we hit an error (say, because the + // image failed to load or couldn't be decoded) and should return zero size. + if (nsIFrame* rootFrame = aImage->GetRootLayoutFrame()) { + aIntrinsicRatio = rootFrame->GetIntrinsicRatio(); + } else { + aGotWidth = aGotHeight = true; + aImageSize = nsIntSize(0, 0); + aIntrinsicRatio = nsSize(0, 0); } } +/* static */ nsresult +nsLayoutUtils::DrawBackgroundImage(nsRenderingContext* aRenderingContext, + imgIContainer* aImage, + const nsIntSize& aImageSize, + GraphicsFilter aGraphicsFilter, + const nsRect& aDest, + const nsRect& aFill, + const nsPoint& aAnchor, + const nsRect& aDirty, + PRUint32 aImageFlags) +{ + return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter, + aDest, aFill, aAnchor, aDirty, + aImageSize, aImageFlags); +} + /* static */ nsresult nsLayoutUtils::DrawImage(nsRenderingContext* aRenderingContext, imgIContainer* aImage, @@ -3620,10 +3621,32 @@ nsLayoutUtils::DrawImage(nsRenderingContext* aRenderingContext, PRUint32 aImageFlags) { nsIntSize imageSize; - PRBool gotHeight, gotWidth; - ComputeSizeForDrawing(aImage, imageSize, gotWidth, gotHeight); + nsSize imageRatio; + bool gotHeight, gotWidth; + ComputeSizeForDrawing(aImage, imageSize, imageRatio, gotWidth, gotHeight); + + // XXX Dimensionless images shouldn't fall back to filled-area size -- the + // caller should provide the image size, a la DrawBackgroundImage. + if (gotWidth != gotHeight) { + if (!gotWidth) { + if (imageRatio.height != 0) { + imageSize.width = + NSCoordSaturatingNonnegativeMultiply(imageSize.height, + float(imageRatio.width) / + float(imageRatio.height)); + gotWidth = true; + } + } else { + if (imageRatio.width != 0) { + imageSize.height = + NSCoordSaturatingNonnegativeMultiply(imageSize.width, + float(imageRatio.height) / + float(imageRatio.width)); + gotHeight = true; + } + } + } - // fallback size based on aFill. if (!gotWidth) { imageSize.width = nsPresContext::AppUnitsToIntCSSPixels(aFill.width); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 7694bec6f883..95b5ed680008 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1048,6 +1048,38 @@ public: * functions below is the type of the aImage argument. */ + /** + * Draw a background image. The image's dimensions are as specified in aDest; + * the image itself is not consulted to determine a size. + * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering + * @param aRenderingContext Where to draw the image, set up with an + * appropriate scale and transform for drawing in + * app units. + * @param aImage The image. + * @param aImageSize The unscaled size of the image being drawn. + * (This might be the image's size if no scaling + * occurs, or it might be the image's size if + * the image is a vector image being rendered at + * that size.) + * @param aDest The position and scaled area where one copy of + * the image should be drawn. + * @param aFill The area to be filled with copies of the + * image. + * @param aAnchor A point in aFill which we will ensure is + * pixel-aligned in the output. + * @param aDirty Pixels outside this area may be skipped. + * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety + */ + static nsresult DrawBackgroundImage(nsRenderingContext* aRenderingContext, + imgIContainer* aImage, + const nsIntSize& aImageSize, + GraphicsFilter aGraphicsFilter, + const nsRect& aDest, + const nsRect& aFill, + const nsPoint& aAnchor, + const nsRect& aDirty, + PRUint32 aImageFlags); + /** * Draw an image. * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering @@ -1152,7 +1184,9 @@ public: * Given an imgIContainer, this method attempts to obtain an intrinsic * px-valued height & width for it. If the imgIContainer has a non-pixel * value for either height or width, this method tries to generate a pixel - * value for that dimension using the intrinsic ratio (if available). + * value for that dimension using the intrinsic ratio (if available). The + * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no + * intrinsic ratio then (0, 0) will be assigned. * * This method will always set aGotWidth and aGotHeight to indicate whether * we were able to successfully obtain (or compute) a value for each @@ -1164,8 +1198,9 @@ public: */ static void ComputeSizeForDrawing(imgIContainer* aImage, nsIntSize& aImageSize, - PRBool& aGotWidth, - PRBool& aGotHeight); + nsSize& aIntrinsicRatio, + bool& aGotWidth, + bool& aGotHeight); /** * Given a source area of an image (in appunits) and a destination area diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index eeb100f0b6a9..4cde40db4af2 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -1348,93 +1348,6 @@ nsPresContext::ForgetUpdatePluginGeometryFrame(nsIFrame* aFrame) } } -#ifdef DEBUG - -struct nsAutoLayoutPhase { - nsAutoLayoutPhase(nsPresContext* aPresContext, nsLayoutPhase aPhase) - : mPresContext(aPresContext), mPhase(aPhase), mCount(0) - { - Enter(); - } - - ~nsAutoLayoutPhase() - { - Exit(); - NS_ASSERTION(mCount == 0, "imbalanced"); - } - - void Enter() - { - switch (mPhase) { - case eLayoutPhase_Paint: - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, - "recurring into paint"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, - "painting in the middle of reflow"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, - "painting in the middle of frame construction"); - break; - case eLayoutPhase_Reflow: - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, - "reflowing in the middle of a paint"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, - "recurring into reflow"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, - "reflowing in the middle of frame construction"); - break; - case eLayoutPhase_FrameC: - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Paint] == 0, - "constructing frames in the middle of a paint"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_Reflow] == 0, - "constructing frames in the middle of reflow"); - NS_ASSERTION(mPresContext->mLayoutPhaseCount[eLayoutPhase_FrameC] == 0, - "recurring into frame construction"); - NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), - "constructing frames and scripts are not blocked"); - break; - default: - break; - } - ++(mPresContext->mLayoutPhaseCount[mPhase]); - ++mCount; - } - - void Exit() - { - NS_ASSERTION(mCount > 0 && mPresContext->mLayoutPhaseCount[mPhase] > 0, - "imbalanced"); - --(mPresContext->mLayoutPhaseCount[mPhase]); - --mCount; - } - -private: - nsPresContext *mPresContext; - nsLayoutPhase mPhase; - PRUint32 mCount; -}; - -#define AUTO_LAYOUT_PHASE_ENTRY_POINT(pc_, phase_) \ - nsAutoLayoutPhase autoLayoutPhase((pc_), (eLayoutPhase_##phase_)) -#define LAYOUT_PHASE_TEMP_EXIT() \ - PR_BEGIN_MACRO \ - autoLayoutPhase.Exit(); \ - PR_END_MACRO -#define LAYOUT_PHASE_TEMP_REENTER() \ - PR_BEGIN_MACRO \ - autoLayoutPhase.Enter(); \ - PR_END_MACRO - -#else - -#define AUTO_LAYOUT_PHASE_ENTRY_POINT(pc_, phase_) \ - PR_BEGIN_MACRO PR_END_MACRO -#define LAYOUT_PHASE_TEMP_EXIT() \ - PR_BEGIN_MACRO PR_END_MACRO -#define LAYOUT_PHASE_TEMP_REENTER() \ - PR_BEGIN_MACRO PR_END_MACRO - -#endif - #ifdef MOZ_REFLOW_PERF #define DO_GLOBAL_REFLOW_COUNT(_name) \ diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 3c025a256b99..b62c5e67319f 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -135,7 +135,7 @@ #include "nsDisplayList.h" #include "nsRegion.h" #include "nsRenderingContext.h" - +#include "nsAutoLayoutPhase.h" #ifdef MOZ_REFLOW_PERF #include "nsFontMetrics.h" #endif @@ -9416,9 +9416,11 @@ PresShell::SetIsActive(PRBool aIsActive) &aIsActive); nsresult rv = UpdateImageLockingState(); #ifdef ACCESSIBILITY - nsAccessibilityService* accService = AccService(); - if (accService) { - accService->PresShellActivated(this); + if (aIsActive) { + nsAccessibilityService* accService = AccService(); + if (accService) { + accService->PresShellActivated(this); + } } #endif return rv; diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index aa28af73d1ff..0a21e165919a 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -97,6 +97,7 @@ static const char* const gHTMLTypes[] = { APPLICATION_JAVASCRIPT, APPLICATION_ECMASCRIPT, APPLICATION_XJAVASCRIPT, + APPLICATION_JSON, VIEWSOURCE_CONTENT_TYPE, APPLICATION_XHTML_XML, 0 diff --git a/layout/build/nsContentDLF.h b/layout/build/nsContentDLF.h index 87463f68b413..3301722f80e8 100644 --- a/layout/build/nsContentDLF.h +++ b/layout/build/nsContentDLF.h @@ -107,6 +107,7 @@ NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult); { "Gecko-Content-Viewers", APPLICATION_JAVASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \ { "Gecko-Content-Viewers", APPLICATION_ECMASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \ { "Gecko-Content-Viewers", APPLICATION_XJAVASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \ + { "Gecko-Content-Viewers", APPLICATION_JSON, "@mozilla.org/content/document-loader-factory;1" }, \ { "Gecko-Content-Viewers", APPLICATION_XHTML_XML, "@mozilla.org/content/document-loader-factory;1" }, \ { "Gecko-Content-Viewers", TEXT_XML, "@mozilla.org/content/document-loader-factory;1" }, \ { "Gecko-Content-Viewers", APPLICATION_XML, "@mozilla.org/content/document-loader-factory;1" }, \ diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 84dc69c98ac6..1d7ada910bc8 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -403,32 +403,21 @@ GetMaxOptionHeight(nsIFrame* aContainer) return result; } -static inline PRBool -IsOptGroup(nsIContent *aContent) -{ - return (aContent->NodeInfo()->Equals(nsGkAtoms::optgroup) && - aContent->IsHTML()); -} - -static inline PRBool -IsOption(nsIContent *aContent) -{ - return (aContent->NodeInfo()->Equals(nsGkAtoms::option) && - aContent->IsHTML()); -} - static PRUint32 GetNumberOfOptionsRecursive(nsIContent* aContent) { + if (!aContent) { + return 0; + } + PRUint32 optionCount = 0; - const PRUint32 childCount = aContent ? aContent->GetChildCount() : 0; - for (PRUint32 index = 0; index < childCount; ++index) { - nsIContent* child = aContent->GetChildAt(index); - if (::IsOption(child)) { + for (nsIContent* cur = aContent->GetFirstChild(); + cur; + cur = cur->GetNextSibling()) { + if (cur->IsHTML(nsGkAtoms::option)) { ++optionCount; - } - else if (::IsOptGroup(child)) { - optionCount += ::GetNumberOfOptionsRecursive(child); + } else if (cur->IsHTML(nsGkAtoms::optgroup)) { + optionCount += GetNumberOfOptionsRecursive(cur); } } return optionCount; @@ -762,21 +751,6 @@ nsListControlFrame::ShouldPropagateComputedHeightToScrolledContent() const } //--------------------------------------------------------- -PRBool -nsListControlFrame::IsOptionElement(nsIContent* aContent) -{ - PRBool result = PR_FALSE; - - nsCOMPtr optElem; - if (NS_SUCCEEDED(aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLOptionElement),(void**) getter_AddRefs(optElem)))) { - if (optElem != nsnull) { - result = PR_TRUE; - } - } - - return result; -} - nsIFrame* nsListControlFrame::GetContentInsertionFrame() { return GetOptionsContainer()->GetContentInsertionFrame(); @@ -790,7 +764,7 @@ nsIContent * nsListControlFrame::GetOptionFromContent(nsIContent *aContent) { for (nsIContent* content = aContent; content; content = content->GetParent()) { - if (IsOptionElement(content)) { + if (content->IsHTML(nsGkAtoms::option)) { return content; } } diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index b785006f1fa3..63a32f17e5fc 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -369,7 +369,6 @@ protected: */ PRBool IsContentSelectedByIndex(PRInt32 aIndex) const; - PRBool IsOptionElement(nsIContent* aContent); PRBool CheckIfAllFramesHere(); PRInt32 GetIndexFromContent(nsIContent *aContent); PRBool IsLeftButton(nsIDOMEvent* aMouseEvent); diff --git a/layout/forms/nsSelectsAreaFrame.cpp b/layout/forms/nsSelectsAreaFrame.cpp index cd98c76d2d92..ffbcf9316605 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -59,32 +59,6 @@ NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsStyleContext* aContext, PRUint32 NS_IMPL_FRAMEARENA_HELPERS(nsSelectsAreaFrame) //--------------------------------------------------------- -PRBool -nsSelectsAreaFrame::IsOptionElement(nsIContent* aContent) -{ - PRBool result = PR_FALSE; - - nsCOMPtr optElem; - if (NS_SUCCEEDED(aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLOptionElement),(void**) getter_AddRefs(optElem)))) { - if (optElem != nsnull) { - result = PR_TRUE; - } - } - - return result; -} - -//--------------------------------------------------------- -PRBool -nsSelectsAreaFrame::IsOptionElementFrame(nsIFrame *aFrame) -{ - nsIContent *content = aFrame->GetContent(); - if (content) { - return IsOptionElement(content); - } - return PR_FALSE; -} - /** * This wrapper class lets us redirect mouse hits from the child frame of * an option element to the element's own frame. @@ -115,7 +89,8 @@ void nsDisplayOptionEventGrabber::HitTest(nsDisplayListBuilder* aBuilder, for (PRUint32 i = 0; i < outFrames.Length(); i++) { nsIFrame* selectedFrame = outFrames.ElementAt(i); while (selectedFrame && - !nsSelectsAreaFrame::IsOptionElementFrame(selectedFrame)) { + !(selectedFrame->GetContent() && + selectedFrame->GetContent()->IsHTML(nsGkAtoms::option))) { selectedFrame = selectedFrame->GetParent(); } if (selectedFrame) { diff --git a/layout/forms/nsSelectsAreaFrame.h b/layout/forms/nsSelectsAreaFrame.h index 623e79e5f8c3..e5213ecdd986 100644 --- a/layout/forms/nsSelectsAreaFrame.h +++ b/layout/forms/nsSelectsAreaFrame.h @@ -38,7 +38,6 @@ #define nsSelectsAreaFrame_h___ #include "nsBlockFrame.h" -class nsIContent; class nsSelectsAreaFrame : public nsBlockFrame { @@ -60,9 +59,6 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); - static PRBool IsOptionElement(nsIContent* aContent); - static PRBool IsOptionElementFrame(nsIFrame *aFrame); - nscoord HeightOfARow() const { return mHeightOfARow; } protected: diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index fbd41d81ae8d..0a8a6bc9714c 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -89,7 +89,6 @@ #include "nsIDOMNSEvent.h" #include "nsIDOMNSUIEvent.h" -#include "nsIDOMFocusListener.h" //onchange events #include "nsIDOMCharacterData.h" //for selection setting helper func #include "nsIDOMNodeList.h" //for selection setting helper func #include "nsIDOMRange.h" //for selection setting helper func @@ -105,7 +104,6 @@ #include "nsIDOMText.h" //for multiline getselection #include "nsNodeInfoManager.h" #include "nsContentCreatorFunctions.h" -#include "nsIDOMKeyListener.h" #include "nsINativeKeyBindings.h" #include "nsIJSContextStack.h" #include "nsFocusManager.h" diff --git a/layout/forms/test/Makefile.in b/layout/forms/test/Makefile.in index 3ab81f33d270..dc9ef65201eb 100644 --- a/layout/forms/test/Makefile.in +++ b/layout/forms/test/Makefile.in @@ -82,16 +82,9 @@ _TEST_FILES = test_bug231389.html \ _CHROME_FILES = \ test_bug536567.html \ - $(NULL) - -ifeq (WINNT,$(OS_ARCH)) -$(warning test_bug665540.html disabled due to bug 670053) -else -_CHROME_FILES += \ test_bug665540.html \ bug665540_window.xul \ $(NULL) -endif libs:: $(_TEST_FILES) $(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) diff --git a/layout/forms/test/test_bug665540.html b/layout/forms/test/test_bug665540.html index dabe56a5055c..85c2cdad945c 100644 --- a/layout/forms/test/test_bug665540.html +++ b/layout/forms/test/test_bug665540.html @@ -24,6 +24,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=665540 SimpleTest.waitForExplicitFinish(); var win; +var select; var optiona; var eventType = "mouseover"; var timeoutID; @@ -54,7 +55,7 @@ function childFocused() { } function openSelect() { - var select = win.document.getElementById("select"); + select = win.document.getElementById("select"); synthesizeMouseAtCenter(select, {}, win); // A yield was required on X11 tinderbox machines. // (Wasn't required on other platforms nor on an X11 system with kwin.) @@ -90,6 +91,13 @@ function eventReceived(event) { } function finish() { + if (select && navigator.platform.indexOf("Win") >= 0) { + todo(false, + "Should not have to close select before closing its window"); + // This avoids mochitest "Unable to restore focus" errors (bug 670053). + synthesizeMouseAtCenter(select, {}, win); + } + // bug 670026 ((navigator.platform.indexOf("Mac") < 0) ? is : todo_is) (win.windowState, win.STATE_FULLSCREEN, diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index c2660fe08096..88e33b9877dd 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -55,7 +55,7 @@ #include "nsWidgetsCID.h" #include "nsIView.h" #include "nsIViewManager.h" -#include "nsIDOMKeyListener.h" +#include "nsIDOMEventListener.h" #include "nsIDOMDragEvent.h" #include "nsPluginHost.h" #include "nsString.h" @@ -84,10 +84,6 @@ #include "nsIDOMHTMLEmbedElement.h" #include "nsIDOMHTMLAppletElement.h" #include "nsIDOMWindow.h" -#include "nsIDOMMouseListener.h" -#include "nsIDOMMouseMotionListener.h" -#include "nsIDOMFocusListener.h" -#include "nsIDOMContextMenuListener.h" #include "nsIDOMEventTarget.h" #include "nsIDOMNSEvent.h" #include "nsIPrivateDOMEvent.h" diff --git a/layout/mathml/mathml.css b/layout/mathml/mathml.css index 37d6cbd946e0..6b221335766f 100644 --- a/layout/mathml/mathml.css +++ b/layout/mathml/mathml.css @@ -385,16 +385,16 @@ mtd[_moz-math-columnline="dashed"] { Authors can make elements on a document to be stretched with different fonts, e.g., - To request the use of TeX fonts, you can add a with: - ... with the associated CSS declaration - mo[myfonts="tex"]::-moz-math-stretchy { - font-family: CMSY10, CMEX10; + To request the use of STIX fonts, you can add a with: + ... with the associated CSS declaration + mo[myfonts="stix"]::-moz-math-stretchy { + font-family: STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral; } - To request the use of Mathematica fonts, you can add a with: - ... with the associated CSS declaration - mo[myfonts="mathematica"]::-moz-math-stretchy { - font-family: Math1, Math2, Math4; + To request the use of Asana fonts, you can add a with: + ... with the associated CSS declaration + mo[myfonts="asana"]::-moz-math-stretchy { + font-family: Asana Math; } Of course, if you just want all of the stretchy characters in your diff --git a/layout/mathml/nsMathMLmunderoverFrame.cpp b/layout/mathml/nsMathMLmunderoverFrame.cpp index dc2c36796e95..b55de350a3be 100644 --- a/layout/mathml/nsMathMLmunderoverFrame.cpp +++ b/layout/mathml/nsMathMLmunderoverFrame.cpp @@ -361,7 +361,10 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, underDelta2 = ruleThickness; } // empty under? - if (!(bmUnder.ascent + bmUnder.descent)) underDelta1 = 0; + if (!(bmUnder.ascent + bmUnder.descent)) { + underDelta1 = 0; + underDelta2 = 0; + } nscoord overDelta1 = 0; // gap between base and overscript nscoord overDelta2 = 0; // extra space above overscript @@ -391,7 +394,10 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, overDelta2 = ruleThickness; } // empty over? - if (!(bmOver.ascent + bmOver.descent)) overDelta1 = 0; + if (!(bmOver.ascent + bmOver.descent)) { + overDelta1 = 0; + overDelta2 = 0; + } nscoord dxBase, dxOver = 0, dxUnder = 0; @@ -419,8 +425,7 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, mBoundingMetrics.ascent = bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent; - mBoundingMetrics.descent = - bmBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent; + mBoundingMetrics.descent = bmBase.descent; mBoundingMetrics.leftBearing = NS_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); mBoundingMetrics.rightBearing = @@ -437,6 +442,7 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, nscoord ascentAnonymousBase = NS_MAX(mBoundingMetrics.ascent + overDelta2, overSize.ascent + bmOver.descent + overDelta1 + bmBase.ascent); + ascentAnonymousBase = NS_MAX(ascentAnonymousBase, baseSize.ascent); GetItalicCorrection(bmAnonymousBase, correction); @@ -463,6 +469,9 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, mBoundingMetrics.width = NS_MAX(dxAnonymousBase + bmAnonymousBase.width, dxUnder + bmUnder.width); + // At this point, mBoundingMetrics.ascent = bmAnonymousBase.ascent + mBoundingMetrics.descent = + bmAnonymousBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent; mBoundingMetrics.leftBearing = NS_MIN(dxAnonymousBase + bmAnonymousBase.leftBearing, dxUnder + bmUnder.leftBearing); mBoundingMetrics.rightBearing = @@ -473,6 +482,9 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext, NS_MAX(mBoundingMetrics.descent + underDelta2, bmAnonymousBase.descent + underDelta1 + bmUnder.ascent + underSize.height - underSize.ascent); + aDesiredSize.height = NS_MAX(aDesiredSize.height, + aDesiredSize.ascent + + baseSize.height - baseSize.ascent); aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index 840dc24d9b1a..1edaae4bcdea 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -101,7 +101,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro // Focus #include "nsIDOMEventTarget.h" -#include "nsIDOMFocusListener.h" #include "nsISelectionController.h" // Misc diff --git a/layout/reftests/backgrounds/gradient/reftest.list b/layout/reftests/backgrounds/gradient/reftest.list new file mode 100644 index 000000000000..e853b376dc98 --- /dev/null +++ b/layout/reftests/backgrounds/gradient/reftest.list @@ -0,0 +1 @@ +== scaled-color-stop-position.html scaled-color-stop-position-ref.html diff --git a/layout/reftests/backgrounds/gradient/scaled-color-stop-position-ref.html b/layout/reftests/backgrounds/gradient/scaled-color-stop-position-ref.html new file mode 100644 index 000000000000..07ddedefe96d --- /dev/null +++ b/layout/reftests/backgrounds/gradient/scaled-color-stop-position-ref.html @@ -0,0 +1,27 @@ + + + + + Color stop positioning for scaled gradients as backgrounds reference + + + +
+ + diff --git a/layout/reftests/backgrounds/gradient/scaled-color-stop-position.html b/layout/reftests/backgrounds/gradient/scaled-color-stop-position.html new file mode 100644 index 000000000000..3b11fca9d97c --- /dev/null +++ b/layout/reftests/backgrounds/gradient/scaled-color-stop-position.html @@ -0,0 +1,25 @@ + + + + + Color stop positioning for scaled gradients as backgrounds + + + +
+ + diff --git a/layout/reftests/backgrounds/no-intrinsic-size.svg b/layout/reftests/backgrounds/no-intrinsic-size.svg deleted file mode 100644 index 584de90778a2..000000000000 --- a/layout/reftests/backgrounds/no-intrinsic-size.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Image with no intrinsic size - - diff --git a/layout/reftests/backgrounds/reftest.list b/layout/reftests/backgrounds/reftest.list index 793cd63e95aa..03946b8af773 100644 --- a/layout/reftests/backgrounds/reftest.list +++ b/layout/reftests/backgrounds/reftest.list @@ -1,3 +1,6 @@ +include gradient/reftest.list +include vector/reftest.list + == layers-stacking-order.xhtml layers-stacking-order-ref.xhtml == layers-layer-count-cascade-1.xhtml layers-layer-count-1-ref.xhtml == layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml @@ -101,13 +104,6 @@ fails-if(Android) == viewport-translucent-color-3.html viewport-translucent-colo # doesn't sample too far astray from the boundaries). fails == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html -# background-size affects images without intrinsic dimensions specially; we may -# not support such image formats right now, but when we do, we want -# background-size to be changed accordingly, and hopefully these tests should -# start failing when we do. -fails == background-size-no-intrinsic-width-image.html background-size-no-intrinsic-width-image-ref.html -fails == background-size-no-intrinsic-height-image.html background-size-no-intrinsic-height-image-ref.html - # -moz-default-background-color and -moz-default-color (bug 591341) == background-moz-default-background-color.html background-moz-default-background-color-ref.html diff --git a/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background-ref.html b/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background-ref.html new file mode 100644 index 000000000000..e8a181ee8884 --- /dev/null +++ b/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background-ref.html @@ -0,0 +1,22 @@ + + + + Scaled vector image without intrinsic dimensions as background, with rendering dependent on the diagonal + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background.html b/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background.html new file mode 100644 index 000000000000..afe51e9ede6c --- /dev/null +++ b/layout/reftests/backgrounds/vector/diagonal-percentage-vector-background.html @@ -0,0 +1,22 @@ + + + + Scaled vector image without intrinsic dimensions as background, with rendering dependent on the diagonal + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/diagonal-scaled-fixed.svg b/layout/reftests/backgrounds/vector/diagonal-scaled-fixed.svg new file mode 100644 index 000000000000..bf0dcfb59b5e --- /dev/null +++ b/layout/reftests/backgrounds/vector/diagonal-scaled-fixed.svg @@ -0,0 +1,10 @@ + + + Vector image with intrinsic dimensions, reference for diagonal-scaled.svg + + + + diff --git a/layout/reftests/backgrounds/vector/diagonal-scaled.svg b/layout/reftests/backgrounds/vector/diagonal-scaled.svg new file mode 100644 index 000000000000..391a9abe84b3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/diagonal-scaled.svg @@ -0,0 +1,21 @@ + + + Vector image without intrinsic dimensions with percentage stroke-width (proportional to the diagonal) + + + + + diff --git a/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-no-dimensions.svg b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-no-dimensions.svg new file mode 100644 index 000000000000..e116d8f1f796 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-no-dimensions.svg @@ -0,0 +1,10 @@ + + + Image with zero-width ratio, no dimensions + + diff --git a/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-height.svg b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-height.svg new file mode 100644 index 000000000000..e691e3f91890 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-height.svg @@ -0,0 +1,11 @@ + + + Image with zero-height ratio, width + + diff --git a/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-width.svg b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-width.svg new file mode 100644 index 000000000000..df365316714b --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/intrinsic-ratio-zero-width.svg @@ -0,0 +1,11 @@ + + + Image with zero-width ratio, width + + diff --git a/layout/reftests/backgrounds/vector/empty/nonpercent-width-omitted-height-extreme-viewbox.svg b/layout/reftests/backgrounds/vector/empty/nonpercent-width-omitted-height-extreme-viewbox.svg new file mode 100644 index 000000000000..052ed2ab3934 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/nonpercent-width-omitted-height-extreme-viewbox.svg @@ -0,0 +1,11 @@ + + + Image with non-percent width, omitted height, extreme viewbox + + diff --git a/layout/reftests/backgrounds/vector/empty/omitted-width-nonpercent-height-extreme-viewbox.svg b/layout/reftests/backgrounds/vector/empty/omitted-width-nonpercent-height-extreme-viewbox.svg new file mode 100644 index 000000000000..9e9b0b431ae3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/omitted-width-nonpercent-height-extreme-viewbox.svg @@ -0,0 +1,11 @@ + + + Image with omitted width, non-percent height, extreme viewbox + + diff --git a/layout/reftests/backgrounds/vector/empty/ref-tall-empty.html b/layout/reftests/backgrounds/vector/empty/ref-tall-empty.html new file mode 100644 index 000000000000..4578d3917b0b --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/ref-tall-empty.html @@ -0,0 +1,19 @@ + + + + tall reference, empty + + + +
+ + diff --git a/layout/reftests/backgrounds/background-size-no-intrinsic-height-image-ref.html b/layout/reftests/backgrounds/vector/empty/ref-tall-lime.html similarity index 51% rename from layout/reftests/backgrounds/background-size-no-intrinsic-height-image-ref.html rename to layout/reftests/backgrounds/vector/empty/ref-tall-lime.html index c453fed751d1..4b0f6a4fadf5 100644 --- a/layout/reftests/backgrounds/background-size-no-intrinsic-height-image-ref.html +++ b/layout/reftests/backgrounds/vector/empty/ref-tall-lime.html @@ -1,19 +1,19 @@ - background-size: 32px auto; for image with no intrinsic height reference + tall reference, lime fill diff --git a/layout/reftests/backgrounds/vector/empty/ref-wide-empty.html b/layout/reftests/backgrounds/vector/empty/ref-wide-empty.html new file mode 100644 index 000000000000..3b4b2da95ed8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/ref-wide-empty.html @@ -0,0 +1,16 @@ + + + + wide reference, empty + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/ref-wide-lime.html b/layout/reftests/backgrounds/vector/empty/ref-wide-lime.html new file mode 100644 index 000000000000..374af7cd297b --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/ref-wide-lime.html @@ -0,0 +1,23 @@ + + + + wide reference, empty + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/reftest.list b/layout/reftests/backgrounds/vector/empty/reftest.list new file mode 100644 index 000000000000..8cacdc1e469b --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/reftest.list @@ -0,0 +1,30 @@ +== tall--contain--height.html ref-tall-empty.html +== tall--contain--width.html ref-tall-empty.html +== wide--contain--height.html ref-wide-empty.html +== wide--contain--width.html ref-wide-empty.html + +# Either OS X 32-bit or 10.5, judging from imprecise Tinderbox results, renders +# these tests as empty boxes, not filled boxes. We don't really care about this +# extreme edge case (the test exists more to test for safety against division by +# zero), so there is no bug has been filed to fix it, although a patch would +# probably be accepted. +random-if(cocoaWidget) == tall--cover--height.html ref-tall-lime.html +random-if(cocoaWidget) == tall--cover--width.html ref-tall-lime.html +random-if(cocoaWidget) == wide--cover--height.html ref-wide-lime.html +random-if(cocoaWidget) == wide--cover--width.html ref-wide-lime.html + +== zero-height-ratio-contain.html ref-tall-empty.html +== zero-height-ratio-cover.html ref-tall-empty.html +== zero-height-ratio-auto-auto.html ref-tall-empty.html +== zero-height-ratio-auto-5px.html ref-tall-empty.html +== zero-height-ratio-5px-auto.html ref-tall-empty.html +== zero-width-ratio-contain.html ref-tall-empty.html +== zero-width-ratio-cover.html ref-tall-empty.html +== zero-width-ratio-auto-auto.html ref-tall-empty.html +== zero-width-ratio-auto-5px.html ref-tall-empty.html +== zero-width-ratio-5px-auto.html ref-tall-empty.html +== zero-ratio-no-dimensions-contain.html ref-tall-empty.html +== zero-ratio-no-dimensions-cover.html ref-tall-empty.html +== zero-ratio-no-dimensions-auto-5px.html ref-tall-empty.html +== zero-ratio-no-dimensions-5px-auto.html ref-tall-empty.html +== zero-ratio-no-dimensions-auto-auto.html ref-tall-empty.html diff --git a/layout/reftests/backgrounds/vector/empty/tall--contain--height.html b/layout/reftests/backgrounds/vector/empty/tall--contain--height.html new file mode 100644 index 000000000000..bb2dcb05575c --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/tall--contain--height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-omitted-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/tall--contain--width.html b/layout/reftests/backgrounds/vector/empty/tall--contain--width.html new file mode 100644 index 000000000000..a22105a6a889 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/tall--contain--width.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-nonpercent-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/tall--cover--height.html b/layout/reftests/backgrounds/vector/empty/tall--cover--height.html new file mode 100644 index 000000000000..ce81f0da0c62 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/tall--cover--height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for nonpercent-width-omitted-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/tall--cover--width.html b/layout/reftests/backgrounds/vector/empty/tall--cover--width.html new file mode 100644 index 000000000000..abb63fa171b0 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/tall--cover--width.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-nonpercent-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/wide--contain--height.html b/layout/reftests/backgrounds/vector/empty/wide--contain--height.html new file mode 100644 index 000000000000..f3f24b0b7688 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/wide--contain--height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-omitted-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/wide--contain--width.html b/layout/reftests/backgrounds/vector/empty/wide--contain--width.html new file mode 100644 index 000000000000..3174da88cdc8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/wide--contain--width.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-nonpercent-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/wide--cover--height.html b/layout/reftests/backgrounds/vector/empty/wide--cover--height.html new file mode 100644 index 000000000000..da02d304d952 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/wide--cover--height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-omitted-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/wide--cover--width.html b/layout/reftests/backgrounds/vector/empty/wide--cover--width.html new file mode 100644 index 000000000000..0842c4b9e22f --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/wide--cover--width.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-nonpercent-height-extreme-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-height-ratio-5px-auto.html b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-5px-auto.html new file mode 100644 index 000000000000..deca83568120 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-5px-auto.html @@ -0,0 +1,25 @@ + + + + zero height ratio, 5px auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-5px.html b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-5px.html new file mode 100644 index 000000000000..03f3f3795280 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-5px.html @@ -0,0 +1,25 @@ + + + + zero height ratio, auto 5px + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-auto.html b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-auto.html new file mode 100644 index 000000000000..4ccc47b29a4a --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-auto-auto.html @@ -0,0 +1,25 @@ + + + + zero height ratio, auto auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-height-ratio-contain.html b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-contain.html new file mode 100644 index 000000000000..89132ea0c0ea --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-contain.html @@ -0,0 +1,25 @@ + + + + zero height ratio, contain + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-height-ratio-cover.html b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-cover.html new file mode 100644 index 000000000000..e1c0f060d56d --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-height-ratio-cover.html @@ -0,0 +1,25 @@ + + + + zero height ratio, cover + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-5px-auto.html b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-5px-auto.html new file mode 100644 index 000000000000..3b47bb47d0e2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-5px-auto.html @@ -0,0 +1,25 @@ + + + + zero ratio, no dimensions, 5px auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-5px.html b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-5px.html new file mode 100644 index 000000000000..2ebf838b1871 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-5px.html @@ -0,0 +1,25 @@ + + + + zero ratio, no dimensions, auto 5px + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-auto.html b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-auto.html new file mode 100644 index 000000000000..f0ab1277353d --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-auto-auto.html @@ -0,0 +1,25 @@ + + + + zero ratio, no dimensions, auto auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-contain.html b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-contain.html new file mode 100644 index 000000000000..0890e1be3f3d --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-contain.html @@ -0,0 +1,25 @@ + + + + zero ratio, no dimensions, contain + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-cover.html b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-cover.html new file mode 100644 index 000000000000..de54313f2dbe --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-ratio-no-dimensions-cover.html @@ -0,0 +1,25 @@ + + + + zero ratio, no dimensions, cover + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-width-ratio-5px-auto.html b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-5px-auto.html new file mode 100644 index 000000000000..522be29d0d36 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-5px-auto.html @@ -0,0 +1,25 @@ + + + + zero height ratio, 5px auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-5px.html b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-5px.html new file mode 100644 index 000000000000..a3f50e579cc3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-5px.html @@ -0,0 +1,25 @@ + + + + zero height ratio, auto 5px + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-auto.html b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-auto.html new file mode 100644 index 000000000000..a85595d684b4 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-auto-auto.html @@ -0,0 +1,25 @@ + + + + zero width ratio, auto auto + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-width-ratio-contain.html b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-contain.html new file mode 100644 index 000000000000..3dc3a39baf9d --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-contain.html @@ -0,0 +1,25 @@ + + + + zero width ratio, contain + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/empty/zero-width-ratio-cover.html b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-cover.html new file mode 100644 index 000000000000..5a16de943073 --- /dev/null +++ b/layout/reftests/backgrounds/vector/empty/zero-width-ratio-cover.html @@ -0,0 +1,25 @@ + + + + zero width ratio, cover + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height-viewbox.svg b/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height-viewbox.svg new file mode 100644 index 000000000000..9014ad5bf616 --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with non-percent width, non-percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height.svg b/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height.svg new file mode 100644 index 000000000000..60f9e724e094 --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-nonpercent-height.svg @@ -0,0 +1,10 @@ + + + Image with non-percentage dimensions + + + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height-viewbox.svg b/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height-viewbox.svg new file mode 100644 index 000000000000..8c794b61394f --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with non-percent width, omitted height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height.svg b/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height.svg new file mode 100644 index 000000000000..b506e625db28 --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-omitted-height.svg @@ -0,0 +1,10 @@ + + + Image with non-percent width, omitted height + + + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-percent-height-viewbox.svg b/layout/reftests/backgrounds/vector/nonpercent-width-percent-height-viewbox.svg new file mode 100644 index 000000000000..3a114ccc548b --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-percent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with non-percent width, percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/nonpercent-width-percent-height.svg b/layout/reftests/backgrounds/vector/nonpercent-width-percent-height.svg new file mode 100644 index 000000000000..398291e3b7fe --- /dev/null +++ b/layout/reftests/backgrounds/vector/nonpercent-width-percent-height.svg @@ -0,0 +1,10 @@ + + + Image with non-percent width, percent height + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height-viewbox.svg b/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height-viewbox.svg new file mode 100644 index 000000000000..ebf4d94ec4af --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with omitted width, non-percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height.svg b/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height.svg new file mode 100644 index 000000000000..b6985ad0100d --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-nonpercent-height.svg @@ -0,0 +1,10 @@ + + + Image with omitted width, non-percent height + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-omitted-height-viewbox.svg b/layout/reftests/backgrounds/vector/omitted-width-omitted-height-viewbox.svg new file mode 100644 index 000000000000..bcea95cdc992 --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-omitted-height-viewbox.svg @@ -0,0 +1,11 @@ + + + Image with omitted width, omitted height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-omitted-height.svg b/layout/reftests/backgrounds/vector/omitted-width-omitted-height.svg new file mode 100644 index 000000000000..d086213878a5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-omitted-height.svg @@ -0,0 +1,9 @@ + + + Image with omitted width, omitted height + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-percent-height-viewbox.svg b/layout/reftests/backgrounds/vector/omitted-width-percent-height-viewbox.svg new file mode 100644 index 000000000000..265c26a9a8ce --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-percent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with omitted width, percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/omitted-width-percent-height.svg b/layout/reftests/backgrounds/vector/omitted-width-percent-height.svg new file mode 100644 index 000000000000..b44560175d37 --- /dev/null +++ b/layout/reftests/backgrounds/vector/omitted-width-percent-height.svg @@ -0,0 +1,10 @@ + + + Image with omitted width, percent height + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-nonpercent-height-viewbox.svg b/layout/reftests/backgrounds/vector/percent-width-nonpercent-height-viewbox.svg new file mode 100644 index 000000000000..645c4c024489 --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-nonpercent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with percent width, non-percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-nonpercent-height.svg b/layout/reftests/backgrounds/vector/percent-width-nonpercent-height.svg new file mode 100644 index 000000000000..e7331150199c --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-nonpercent-height.svg @@ -0,0 +1,10 @@ + + + Image with percent width, non-percent height + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-omitted-height-viewbox.svg b/layout/reftests/backgrounds/vector/percent-width-omitted-height-viewbox.svg new file mode 100644 index 000000000000..ef0a4676781e --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-omitted-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with percent width, omitted height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-omitted-height.svg b/layout/reftests/backgrounds/vector/percent-width-omitted-height.svg new file mode 100644 index 000000000000..76e9cef3c676 --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-omitted-height.svg @@ -0,0 +1,10 @@ + + + Image with percent width, omitted height + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-percent-height-viewbox.svg b/layout/reftests/backgrounds/vector/percent-width-percent-height-viewbox.svg new file mode 100644 index 000000000000..be23fe2d2d3d --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-percent-height-viewbox.svg @@ -0,0 +1,12 @@ + + + Image with percent width, percent height, viewbox + + + diff --git a/layout/reftests/backgrounds/vector/percent-width-percent-height.svg b/layout/reftests/backgrounds/vector/percent-width-percent-height.svg new file mode 100644 index 000000000000..db197fb304c6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/percent-width-percent-height.svg @@ -0,0 +1,10 @@ + + + Image with percent width, percent height + + + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime192x384-aqua192x384.html b/layout/reftests/backgrounds/vector/ref-tall-lime192x384-aqua192x384.html new file mode 100644 index 000000000000..2d3e3ac956b7 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime192x384-aqua192x384.html @@ -0,0 +1,26 @@ + + + + tall reference, 192x384 lime, 192x384 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime256x16-aqua256x16.html b/layout/reftests/backgrounds/vector/ref-tall-lime256x16-aqua256x16.html new file mode 100644 index 000000000000..2afc9afec7e6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime256x16-aqua256x16.html @@ -0,0 +1,26 @@ + + + + tall reference, 256x16 lime, 256x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime256x384-aqua256x384.html b/layout/reftests/backgrounds/vector/ref-tall-lime256x384-aqua256x384.html new file mode 100644 index 000000000000..d02ee7a43419 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime256x384-aqua256x384.html @@ -0,0 +1,26 @@ + + + + tall reference, 256x384 lime, 256x384 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime256x512-aqua256x256.html b/layout/reftests/backgrounds/vector/ref-tall-lime256x512-aqua256x256.html new file mode 100644 index 000000000000..9000149fd056 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime256x512-aqua256x256.html @@ -0,0 +1,26 @@ + + + + tall reference, 256x512 lime, 256x256 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime256x768.html b/layout/reftests/backgrounds/vector/ref-tall-lime256x768.html new file mode 100644 index 000000000000..9be420474215 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime256x768.html @@ -0,0 +1,17 @@ + + + + tall reference, 256x512 lime, 256x256 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime2x16-aqua2x16.html b/layout/reftests/backgrounds/vector/ref-tall-lime2x16-aqua2x16.html new file mode 100644 index 000000000000..45ddc0135ce1 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime2x16-aqua2x16.html @@ -0,0 +1,26 @@ + + + + tall reference, 2x16 lime, 2x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime32x128-aqua32x128.html b/layout/reftests/backgrounds/vector/ref-tall-lime32x128-aqua32x128.html new file mode 100644 index 000000000000..e5e5d74511a8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime32x128-aqua32x128.html @@ -0,0 +1,26 @@ + + + + tall reference, 32x128 lime, 32x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime32x16-aqua32x16.html b/layout/reftests/backgrounds/vector/ref-tall-lime32x16-aqua32x16.html new file mode 100644 index 000000000000..281842b10351 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime32x16-aqua32x16.html @@ -0,0 +1,26 @@ + + + + tall reference, 32x16 lime, 32x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime32x256-aqua32x256.html b/layout/reftests/backgrounds/vector/ref-tall-lime32x256-aqua32x256.html new file mode 100644 index 000000000000..db464f75e833 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime32x256-aqua32x256.html @@ -0,0 +1,26 @@ + + + + tall reference, 32x256 lime, 32x256 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime32x384-aqua32x384.html b/layout/reftests/backgrounds/vector/ref-tall-lime32x384-aqua32x384.html new file mode 100644 index 000000000000..13adefe5a19e --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime32x384-aqua32x384.html @@ -0,0 +1,26 @@ + + + + tall reference, 32x384 lime, 32x384 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime32x64-aqua32x64.html b/layout/reftests/backgrounds/vector/ref-tall-lime32x64-aqua32x64.html new file mode 100644 index 000000000000..386ade56d755 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime32x64-aqua32x64.html @@ -0,0 +1,26 @@ + + + + tall reference, 32x64 lime, 32x64 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime48x384-aqua48x384.html b/layout/reftests/backgrounds/vector/ref-tall-lime48x384-aqua48x384.html new file mode 100644 index 000000000000..71a762785c56 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime48x384-aqua48x384.html @@ -0,0 +1,26 @@ + + + + tall reference, 48x384 lime, 48x384 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime4x16-aqua4x16.html b/layout/reftests/backgrounds/vector/ref-tall-lime4x16-aqua4x16.html new file mode 100644 index 000000000000..7e4de850b29c --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime4x16-aqua4x16.html @@ -0,0 +1,26 @@ + + + + tall reference, 4x16 lime, 4x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime8x16-aqua8x16.html b/layout/reftests/backgrounds/vector/ref-tall-lime8x16-aqua8x16.html new file mode 100644 index 000000000000..6d6af250d005 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime8x16-aqua8x16.html @@ -0,0 +1,26 @@ + + + + tall reference, 8x16 lime, 8x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime8x32-aqua8x32.html b/layout/reftests/backgrounds/vector/ref-tall-lime8x32-aqua8x32.html new file mode 100644 index 000000000000..55deb8cb0946 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime8x32-aqua8x32.html @@ -0,0 +1,26 @@ + + + + tall reference, 8x32 lime, 8x32 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime8x384-aqua8x384.html b/layout/reftests/backgrounds/vector/ref-tall-lime8x384-aqua8x384.html new file mode 100644 index 000000000000..1479ecab518f --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime8x384-aqua8x384.html @@ -0,0 +1,26 @@ + + + + tall reference, 8x384 lime, 8x384 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-tall-lime8x64-aqua8x64.html b/layout/reftests/backgrounds/vector/ref-tall-lime8x64-aqua8x64.html new file mode 100644 index 000000000000..0bfabeb36b10 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-tall-lime8x64-aqua8x64.html @@ -0,0 +1,26 @@ + + + + tall reference, 8x64 lime, 8x64 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime12x128-aqua12x128.html b/layout/reftests/backgrounds/vector/ref-wide-lime12x128-aqua12x128.html new file mode 100644 index 000000000000..a653822f01ab --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime12x128-aqua12x128.html @@ -0,0 +1,26 @@ + + + + wide reference, 12x128 lime, 12x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime12x16-aqua12x16.html b/layout/reftests/backgrounds/vector/ref-wide-lime12x16-aqua12x16.html new file mode 100644 index 000000000000..1c26d0f4828d --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime12x16-aqua12x16.html @@ -0,0 +1,26 @@ + + + + wide reference, 12x16 lime, 12x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime12x24-aqua12x24.html b/layout/reftests/backgrounds/vector/ref-wide-lime12x24-aqua12x24.html new file mode 100644 index 000000000000..a7dbea4820be --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime12x24-aqua12x24.html @@ -0,0 +1,26 @@ + + + + wide reference, 12x24 lime, 12x24 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime12x96-aqua12x96.html b/layout/reftests/backgrounds/vector/ref-wide-lime12x96-aqua12x96.html new file mode 100644 index 000000000000..e368aea015c0 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime12x96-aqua12x96.html @@ -0,0 +1,26 @@ + + + + wide reference, 12x96 lime, 12x96 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime16x128-aqua16x128.html b/layout/reftests/backgrounds/vector/ref-wide-lime16x128-aqua16x128.html new file mode 100644 index 000000000000..f160fbdba2ac --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime16x128-aqua16x128.html @@ -0,0 +1,26 @@ + + + + wide reference, 16x128 lime, 16x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime2x16-aqua2x16.html b/layout/reftests/backgrounds/vector/ref-wide-lime2x16-aqua2x16.html new file mode 100644 index 000000000000..cb8ad1a5bdcc --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime2x16-aqua2x16.html @@ -0,0 +1,26 @@ + + + + wide reference, 2x16 lime, 2x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime64x128-aqua64x128.html b/layout/reftests/backgrounds/vector/ref-wide-lime64x128-aqua64x128.html new file mode 100644 index 000000000000..fd275f1418d5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime64x128-aqua64x128.html @@ -0,0 +1,26 @@ + + + + wide reference, 64x128 lime, 64x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime768x128-aqua768x128.html b/layout/reftests/backgrounds/vector/ref-wide-lime768x128-aqua768x128.html new file mode 100644 index 000000000000..93eb90b8a826 --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime768x128-aqua768x128.html @@ -0,0 +1,26 @@ + + + + wide reference, 768x128 lime, 768x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime768x16-aqua768x16.html b/layout/reftests/backgrounds/vector/ref-wide-lime768x16-aqua768x16.html new file mode 100644 index 000000000000..247062c09cdc --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime768x16-aqua768x16.html @@ -0,0 +1,26 @@ + + + + wide reference, 768x16 lime, 768x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/background-size-no-intrinsic-width-image-ref.html b/layout/reftests/backgrounds/vector/ref-wide-lime768x256.html similarity index 59% rename from layout/reftests/backgrounds/background-size-no-intrinsic-width-image-ref.html rename to layout/reftests/backgrounds/vector/ref-wide-lime768x256.html index a01539de7411..35e00726d92d 100644 --- a/layout/reftests/backgrounds/background-size-no-intrinsic-width-image-ref.html +++ b/layout/reftests/backgrounds/vector/ref-wide-lime768x256.html @@ -1,18 +1,19 @@ - background-size: 32px auto; for image with no intrinsic size reference + wide reference, 768x256 lime diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime8x128-aqua8x128.html b/layout/reftests/backgrounds/vector/ref-wide-lime8x128-aqua8x128.html new file mode 100644 index 000000000000..e0ffc6c2a98f --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime8x128-aqua8x128.html @@ -0,0 +1,26 @@ + + + + wide reference, 8x128 lime, 8x128 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime8x16-aqua8x16.html b/layout/reftests/backgrounds/vector/ref-wide-lime8x16-aqua8x16.html new file mode 100644 index 000000000000..eb3b2b6e4e6a --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime8x16-aqua8x16.html @@ -0,0 +1,26 @@ + + + + wide reference, 8x16 lime, 8x16 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/ref-wide-lime8x64-aqua8x64.html b/layout/reftests/backgrounds/vector/ref-wide-lime8x64-aqua8x64.html new file mode 100644 index 000000000000..1aeb39eaaaad --- /dev/null +++ b/layout/reftests/backgrounds/vector/ref-wide-lime8x64-aqua8x64.html @@ -0,0 +1,26 @@ + + + + wide reference, 8x64 lime, 8x64 aqua + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/reftest.list b/layout/reftests/backgrounds/vector/reftest.list new file mode 100644 index 000000000000..6b9fe45f97ea --- /dev/null +++ b/layout/reftests/backgrounds/vector/reftest.list @@ -0,0 +1,208 @@ +include empty/reftest.list + +################################################################################ +# For reference (although the wide--32px-auto* tests/names were changed to +# avoid viewBox-directed scaling to make the scaled height less than the wide- +# tests height): +# +# for ORIENTATION in tall wide; do for SIZE in 32px-auto auto-32px auto contain cover; do for VIMAGE in *.svg; do cat template.html | sed -e "s/SIZE/$(echo $SIZE | sed -e 's/-/ /')/g" | sed -e "s/VIMAGE/$VIMAGE/g" | sed -e "s/TALLWIDE/$ORIENTATION/g" | sed -e "s/ORIENTATION/$(if [ "$ORIENTATION" = "tall" ]; then echo 'width: 256px; height: 768px'; else echo 'width: 768px; height: 256px'; fi)/g" > $ORIENTATION--$SIZE--$(echo $VIMAGE | sed -e 's/.svg//').html; echo "== $ORIENTATION--$SIZE--$(echo $VIMAGE | sed -e 's/.svg//').html ###" >> reftest.list; done; echo >> reftest.list; done; done +# +################################################################################ + +== tall--32px-auto--nonpercent-width-nonpercent-height.html ref-tall-lime32x64-aqua32x64.html +== tall--32px-auto--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime32x64-aqua32x64.html +== tall--32px-auto--nonpercent-width-omitted-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--nonpercent-width-omitted-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--nonpercent-width-percent-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--nonpercent-width-percent-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--omitted-width-nonpercent-height.html ref-tall-lime32x16-aqua32x16.html +== tall--32px-auto--omitted-width-nonpercent-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--omitted-width-omitted-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--omitted-width-omitted-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--omitted-width-percent-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--omitted-width-percent-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--percent-width-nonpercent-height.html ref-tall-lime32x16-aqua32x16.html +== tall--32px-auto--percent-width-nonpercent-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--percent-width-omitted-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--percent-width-omitted-height-viewbox.html ref-tall-lime32x256-aqua32x256.html +== tall--32px-auto--percent-width-percent-height.html ref-tall-lime32x384-aqua32x384.html +== tall--32px-auto--percent-width-percent-height-viewbox.html ref-tall-lime32x256-aqua32x256.html + +== tall--auto-32px--nonpercent-width-nonpercent-height.html ref-tall-lime8x16-aqua8x16.html +== tall--auto-32px--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime8x16-aqua8x16.html +== tall--auto-32px--nonpercent-width-omitted-height.html ref-tall-lime8x16-aqua8x16.html +== tall--auto-32px--nonpercent-width-omitted-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--nonpercent-width-percent-height.html ref-tall-lime8x16-aqua8x16.html +== tall--auto-32px--nonpercent-width-percent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--omitted-width-nonpercent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--omitted-width-nonpercent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--omitted-width-omitted-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--omitted-width-omitted-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--omitted-width-percent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--omitted-width-percent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--percent-width-nonpercent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--percent-width-nonpercent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--percent-width-omitted-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--percent-width-omitted-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto-32px--percent-width-percent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto-32px--percent-width-percent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html + +== tall--auto--nonpercent-width-nonpercent-height.html ref-tall-lime8x16-aqua8x16.html +== tall--auto--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime8x16-aqua8x16.html +== tall--auto--nonpercent-width-omitted-height.html ref-tall-lime8x384-aqua8x384.html +== tall--auto--nonpercent-width-omitted-height-viewbox.html ref-tall-lime8x64-aqua8x64.html +== tall--auto--nonpercent-width-percent-height.html ref-tall-lime8x384-aqua8x384.html +== tall--auto--nonpercent-width-percent-height-viewbox.html ref-tall-lime8x64-aqua8x64.html +== tall--auto--omitted-width-nonpercent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto--omitted-width-nonpercent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto--omitted-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--auto--omitted-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--auto--omitted-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--auto--omitted-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--auto--percent-width-nonpercent-height.html ref-tall-lime256x16-aqua256x16.html +== tall--auto--percent-width-nonpercent-height-viewbox.html ref-tall-lime2x16-aqua2x16.html +== tall--auto--percent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--auto--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--auto--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--auto--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html + +== tall--contain--nonpercent-width-nonpercent-height.html ref-tall-lime192x384-aqua192x384.html +== tall--contain--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime192x384-aqua192x384.html +== tall--contain--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--nonpercent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--nonpercent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--omitted-width-nonpercent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--omitted-width-nonpercent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--omitted-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--omitted-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--omitted-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--omitted-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--percent-width-nonpercent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--percent-width-nonpercent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--percent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html +== tall--contain--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html + +# We smear the background image when scaling it in these two tests... +fails == tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html +fails == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html + +# ...but we don't in identical tests with image-rendering: -moz-crisp-edges. +== tall--cover--nonpercent-width-nonpercent-height--crisp.html ref-tall-lime256x512-aqua256x256.html +== tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html ref-tall-lime256x512-aqua256x256.html + +== tall--cover--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--nonpercent-width-omitted-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--nonpercent-width-percent-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--omitted-width-nonpercent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--omitted-width-nonpercent-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--omitted-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--omitted-width-omitted-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--omitted-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--omitted-width-percent-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--percent-width-nonpercent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--percent-width-nonpercent-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--percent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--percent-width-omitted-height-viewbox.html ref-tall-lime256x768.html +== tall--cover--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html +== tall--cover--percent-width-percent-height-viewbox.html ref-tall-lime256x768.html + +== wide--12px-auto--nonpercent-width-nonpercent-height.html ref-wide-lime12x24-aqua12x24.html +== wide--12px-auto--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime12x24-aqua12x24.html +== wide--12px-auto--nonpercent-width-omitted-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--nonpercent-width-omitted-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--nonpercent-width-percent-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--nonpercent-width-percent-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--omitted-width-nonpercent-height.html ref-wide-lime12x16-aqua12x16.html +== wide--12px-auto--omitted-width-nonpercent-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--omitted-width-omitted-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--omitted-width-omitted-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--omitted-width-percent-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--omitted-width-percent-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--percent-width-nonpercent-height.html ref-wide-lime12x16-aqua12x16.html +== wide--12px-auto--percent-width-nonpercent-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--percent-width-omitted-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--percent-width-omitted-height-viewbox.html ref-wide-lime12x96-aqua12x96.html +== wide--12px-auto--percent-width-percent-height.html ref-wide-lime12x128-aqua12x128.html +== wide--12px-auto--percent-width-percent-height-viewbox.html ref-wide-lime12x96-aqua12x96.html + +== wide--auto-32px--nonpercent-width-nonpercent-height.html ref-wide-lime8x16-aqua8x16.html +== wide--auto-32px--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime8x16-aqua8x16.html +== wide--auto-32px--nonpercent-width-omitted-height.html ref-wide-lime8x16-aqua8x16.html +== wide--auto-32px--nonpercent-width-omitted-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--nonpercent-width-percent-height.html ref-wide-lime8x16-aqua8x16.html +== wide--auto-32px--nonpercent-width-percent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--omitted-width-nonpercent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--omitted-width-nonpercent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--omitted-width-omitted-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--omitted-width-omitted-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--omitted-width-percent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--omitted-width-percent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--percent-width-nonpercent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--percent-width-nonpercent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--percent-width-omitted-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--percent-width-omitted-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto-32px--percent-width-percent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto-32px--percent-width-percent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html + +== wide--auto--nonpercent-width-nonpercent-height.html ref-wide-lime8x16-aqua8x16.html +== wide--auto--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime8x16-aqua8x16.html +== wide--auto--nonpercent-width-omitted-height.html ref-wide-lime8x128-aqua8x128.html +== wide--auto--nonpercent-width-omitted-height-viewbox.html ref-wide-lime8x64-aqua8x64.html +== wide--auto--nonpercent-width-percent-height.html ref-wide-lime8x128-aqua8x128.html +== wide--auto--nonpercent-width-percent-height-viewbox.html ref-wide-lime8x64-aqua8x64.html +== wide--auto--omitted-width-nonpercent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto--omitted-width-nonpercent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto--omitted-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--auto--omitted-width-omitted-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--auto--omitted-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--auto--omitted-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--auto--percent-width-nonpercent-height.html ref-wide-lime768x16-aqua768x16.html +== wide--auto--percent-width-nonpercent-height-viewbox.html ref-wide-lime2x16-aqua2x16.html +== wide--auto--percent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--auto--percent-width-omitted-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--auto--percent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--auto--percent-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html + +== wide--contain--nonpercent-width-nonpercent-height.html ref-wide-lime64x128-aqua64x128.html +== wide--contain--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime64x128-aqua64x128.html +== wide--contain--nonpercent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--nonpercent-width-omitted-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--nonpercent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--nonpercent-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--omitted-width-nonpercent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--omitted-width-nonpercent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--omitted-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--omitted-width-omitted-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--omitted-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--omitted-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--percent-width-nonpercent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--percent-width-nonpercent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--percent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--percent-width-omitted-height-viewbox.html ref-wide-lime16x128-aqua16x128.html +== wide--contain--percent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--contain--percent-width-percent-height-viewbox.html ref-wide-lime16x128-aqua16x128.html + +== wide--cover--nonpercent-width-nonpercent-height.html ref-wide-lime768x256.html +== wide--cover--nonpercent-width-nonpercent-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--nonpercent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--nonpercent-width-omitted-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--nonpercent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--nonpercent-width-percent-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--omitted-width-nonpercent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--omitted-width-nonpercent-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--omitted-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--omitted-width-omitted-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--omitted-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--omitted-width-percent-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--percent-width-nonpercent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--percent-width-nonpercent-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--percent-width-omitted-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--percent-width-omitted-height-viewbox.html ref-wide-lime768x256.html +== wide--cover--percent-width-percent-height.html ref-wide-lime768x128-aqua768x128.html +== wide--cover--percent-width-percent-height-viewbox.html ref-wide-lime768x256.html + +== diagonal-percentage-vector-background.html diagonal-percentage-vector-background-ref.html diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..fd9803a8f8b8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..ba3c8aa77a9a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..e53db7f30dd6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/background-size-no-intrinsic-height-image.html b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height.html similarity index 56% rename from layout/reftests/backgrounds/background-size-no-intrinsic-height-image.html rename to layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height.html index 37cb3e1908cf..b0f5e401f11f 100644 --- a/layout/reftests/backgrounds/background-size-no-intrinsic-height-image.html +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-omitted-height.html @@ -1,19 +1,19 @@ - background-size: 32px auto; for image with no intrinsic height + tall background-size: 32px auto; for nonpercent-width-omitted-height.svg + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..e54a2ad9e70c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..2d8f074cf71c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..ec67fec894d3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..afe09a4b4c3e --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height.html new file mode 100644 index 000000000000..e2756de0e87c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..2530adf68c5c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height.html new file mode 100644 index 000000000000..6545549bd3f2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..d325e918f6d3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..feb0a9c6534b --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..6d5ade6fb778 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height.html new file mode 100644 index 000000000000..07e228f26242 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..e99bd8686d7a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height.html new file mode 100644 index 000000000000..816f27c505b6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--32px-auto--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: 32px auto; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..642fbd80a646 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..3b24eafce9b6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..a0024d6c897b --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..a2d38f55697d --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..f8100cf25bdc --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..4fcc6e9e5ee8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..cc02ddc44ae6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..f5ac5ed3327e --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..8615658f5805 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height.html new file mode 100644 index 000000000000..5329f2942309 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..03cff2b40ef4 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height.html new file mode 100644 index 000000000000..a6fc1642c5bd --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..50bfb2a93a08 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..94867ccf41b6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..8eb5d1c31ed3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height.html new file mode 100644 index 000000000000..779823ced817 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..7b0353c77059 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height.html new file mode 100644 index 000000000000..85624cccab92 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..43c3e578b3d6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..27828843011c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..b32858e2b7b3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/background-size-no-intrinsic-width-image.html b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height.html similarity index 57% rename from layout/reftests/backgrounds/background-size-no-intrinsic-width-image.html rename to layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height.html index 63f7c1ce6b4f..163ba23798ac 100644 --- a/layout/reftests/backgrounds/background-size-no-intrinsic-width-image.html +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-omitted-height.html @@ -1,19 +1,19 @@ - background-size: auto 32px; for image with no intrinsic width + tall background-size: auto 32px; for nonpercent-width-omitted-height.svg + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..d31b011afd12 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..33d9adbc25fe --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..b80f160bdad4 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..6dc6b7ebae13 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height.html new file mode 100644 index 000000000000..324d1560692f --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..43db64598dd5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height.html new file mode 100644 index 000000000000..c2381d4a549a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..3276604e3042 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..2adf7504c3ea --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..006ce5f00af0 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height.html new file mode 100644 index 000000000000..989b882025ad --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..e3398c2e0a65 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height.html new file mode 100644 index 000000000000..f95ba17bb301 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--auto-32px--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: auto 32px; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..468921cdf89c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..8b24b746e45c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..aeed514e2f9e --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..8b4ed6b70340 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..e188128d66cd --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..9ed2cae43dc1 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..ed53090a6c69 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..2f9015cb2497 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..06041b5bbc53 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height.html new file mode 100644 index 000000000000..cc6e2060d266 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..b693b34fa46a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height.html new file mode 100644 index 000000000000..e48a325f998b --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..b54ffa1c056a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..119333a637bb --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..0bcdf9560711 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height.html new file mode 100644 index 000000000000..97bde9099cd3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..f85cb97bc390 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height.html new file mode 100644 index 000000000000..69e064f86d1e --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--contain--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: contain; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height--crisp.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height--crisp.html new file mode 100644 index 000000000000..89cf5d2e3af5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height--crisp.html @@ -0,0 +1,26 @@ + + + + tall background-size: cover; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html new file mode 100644 index 000000000000..eb82a5eca94c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html @@ -0,0 +1,26 @@ + + + + tall background-size: cover; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..ceceac79f81f --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,26 @@ + + + + tall background-size: cover; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..9621f927a217 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-nonpercent-height.html @@ -0,0 +1,26 @@ + + + + tall background-size: cover; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..81c668b485cf --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..0d34345eeba2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..4d2ffda40a0c --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..a825bd043177 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..cc10f7b30826 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..b4d89f205688 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..cc4a89a73f91 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height.html new file mode 100644 index 000000000000..a70ef2a94046 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..8dc68eda654a --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height.html new file mode 100644 index 000000000000..e458d793c48b --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..578dc64a707e --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..1cf3e32e50de --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..dd88cd725062 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height.html new file mode 100644 index 000000000000..6d670bd5975b --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..7eeb5d77d1e4 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height.html new file mode 100644 index 000000000000..4cd646f26ff8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/tall--cover--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + tall background-size: cover; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/template.html b/layout/reftests/backgrounds/vector/template.html new file mode 100644 index 000000000000..2095fa5b91c0 --- /dev/null +++ b/layout/reftests/backgrounds/vector/template.html @@ -0,0 +1,25 @@ + + + + TALLWIDE background-size: SIZE; for VIMAGE + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..2c3dc6ac642f --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..1b7a505dc10e --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..22d869e60cbb --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..e308e2847261 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..56f25a844ba5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..8d6a5bf6f773 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..922fa01f2e40 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..5cf09ad3c199 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..ea4fa44e2522 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height.html new file mode 100644 index 000000000000..3491823e0f61 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..f56553929a5b --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height.html new file mode 100644 index 000000000000..b47f649e47bd --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..bccb98911d79 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..7b82f76d6600 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..77271f5b1780 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height.html new file mode 100644 index 000000000000..90c041a6221a --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..d85f8b62772a --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height.html new file mode 100644 index 000000000000..5a68b62f40cf --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--12px-auto--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: 12px auto; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..3ee97db8da5c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..b5d8528cc3ea --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..8f75558fcad2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..9510108528b3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..9a03af227d44 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..f2e1ee513b4a --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..5f1198755be1 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..a77164041fde --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..eceed7cf72dc --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height.html new file mode 100644 index 000000000000..b5806aecefe7 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..9fd2c8b219b6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height.html new file mode 100644 index 000000000000..c12cf0b5cbf9 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..bd20673f9dc3 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..cc022be78426 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..6e9a23dd47d2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height.html new file mode 100644 index 000000000000..026b56dc9c47 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..17de29617169 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height.html new file mode 100644 index 000000000000..865903615190 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..6e9b2292387c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..3d4390fe58cf --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..3d563176b8e6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..bc42ca57d19f --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..d919ccbc0049 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..624244d0112f --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..49e711949c90 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..21f1387e7192 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..bccb50ae0c02 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height.html new file mode 100644 index 000000000000..45ccc789628b --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..3cefcd5627b2 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height.html new file mode 100644 index 000000000000..8911767c16da --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..844d8bc7a1bc --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..f474a2054cc5 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..98c6359f5d4d --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height.html new file mode 100644 index 000000000000..5e6fc7c4bd6b --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..cb0575a74340 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height.html new file mode 100644 index 000000000000..b283f45bca5c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--auto-32px--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: auto 32px; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..d0362bbae008 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..adf3c7138fc1 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..65778f3e4eb0 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..d001546c8293 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..723582d9f0d8 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..c320e3ea5366 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..a557eae6355c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..2ffac114ad3c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..4137c62988fa --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height.html new file mode 100644 index 000000000000..8bec681b31bf --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..8473a3b9c5f6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height.html new file mode 100644 index 000000000000..a5c1f5124129 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..9c633e329f9d --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..e16a2e04edec --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..cb0e29705648 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height.html new file mode 100644 index 000000000000..32928022f7cf --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..dc001b48e617 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height.html new file mode 100644 index 000000000000..71b994caf7b7 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--contain--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: contain; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..1847bb5025ba --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height.html new file mode 100644 index 000000000000..d46e8b2b2475 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..4a5deb581d18 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height.html new file mode 100644 index 000000000000..de1113a2824e --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..c82a4f244fe6 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height.html new file mode 100644 index 000000000000..3e249bd2b022 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--nonpercent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for nonpercent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..e4d314cf307f --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height.html new file mode 100644 index 000000000000..80093281e52b --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..ac328e312909 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height.html new file mode 100644 index 000000000000..6142fc6d2c6c --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height-viewbox.html new file mode 100644 index 000000000000..4327d45ef179 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height.html new file mode 100644 index 000000000000..39a9ef1cfea7 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--omitted-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for omitted-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height-viewbox.html new file mode 100644 index 000000000000..6d77007859f1 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-nonpercent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height.html new file mode 100644 index 000000000000..7e566e5cf3af --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-nonpercent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-nonpercent-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height-viewbox.html new file mode 100644 index 000000000000..4fc993851d53 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-omitted-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height.html new file mode 100644 index 000000000000..66a6af9375db --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-omitted-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-omitted-height.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height-viewbox.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height-viewbox.html new file mode 100644 index 000000000000..6422102a4038 --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height-viewbox.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-percent-height-viewbox.svg + + + +
+ + diff --git a/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height.html b/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height.html new file mode 100644 index 000000000000..98efa4dae72d --- /dev/null +++ b/layout/reftests/backgrounds/vector/wide--cover--percent-width-percent-height.html @@ -0,0 +1,25 @@ + + + + wide background-size: cover; for percent-width-percent-height.svg + + + +
+ + diff --git a/layout/reftests/bugs/538909-1-ref.html b/layout/reftests/bugs/538909-1-ref.html index 9443c177f952..325e75455f2a 100644 --- a/layout/reftests/bugs/538909-1-ref.html +++ b/layout/reftests/bugs/538909-1-ref.html @@ -5,8 +5,7 @@ div { width: 260px; height: 260px; - background-size: 100px; - background-size: 100px; + background-size: 100px 100px; background-position: -20px -20px; background-image: -moz-linear-gradient(left top, yellow, blue); background-image: linear-gradient(left top, yellow, blue); diff --git a/layout/reftests/image-element/gradient-html-07b.html b/layout/reftests/image-element/gradient-html-07b.html index e317a48e48c8..1114cc7b296b 100644 --- a/layout/reftests/image-element/gradient-html-07b.html +++ b/layout/reftests/image-element/gradient-html-07b.html @@ -7,6 +7,6 @@ -
+
diff --git a/layout/reftests/mathml/munderover-empty-scripts-ref.html b/layout/reftests/mathml/munderover-empty-scripts-ref.html new file mode 100644 index 000000000000..0f53959dd1bc --- /dev/null +++ b/layout/reftests/mathml/munderover-empty-scripts-ref.html @@ -0,0 +1,34 @@ + + + Test munderover with empty scripts + + + +

munder / munderover with empty overscript: + + + AAA + bbb + + +

+ +

mover / munderover with empty underscript: + + + AAA + + bbb + +

+ +

mrow / munder with empty scripts: + + + AAA + + + +

+ + diff --git a/layout/reftests/mathml/munderover-empty-scripts.html b/layout/reftests/mathml/munderover-empty-scripts.html new file mode 100644 index 000000000000..c76a485863ae --- /dev/null +++ b/layout/reftests/mathml/munderover-empty-scripts.html @@ -0,0 +1,31 @@ + + + Test munderover with empty scripts + + + +

munder / munderover with empty overscript: + + + AAA + bbb + +

+ +

mover / munderover with empty underscript: + + + AAA + bbb + +

+ +

mrow / munder with empty scripts: + + + AAA + +

+ + + diff --git a/layout/reftests/mathml/reftest.list b/layout/reftests/mathml/reftest.list index d12bf3880f03..6659315d456f 100644 --- a/layout/reftests/mathml/reftest.list +++ b/layout/reftests/mathml/reftest.list @@ -76,3 +76,4 @@ fails == mstyle-5.xhtml mstyle-5-ref.xhtml # See bug 569125#c29 == mfrac-linethickness-1.xhtml mfrac-linethickness-1-ref.xhtml == mathml-negativespace.html mathml-negativespace-ref.html != link-1.xhtml link-ref.xhtml +== munderover-empty-scripts.html munderover-empty-scripts-ref.html diff --git a/layout/reftests/native-theme/676387-1-ref.xul b/layout/reftests/native-theme/676387-1-ref.xul new file mode 100644 index 000000000000..e532708823c5 --- /dev/null +++ b/layout/reftests/native-theme/676387-1-ref.xul @@ -0,0 +1,6 @@ + + + +