bool nsSelectionState::IsEqual(nsSelectionState *aSelState) { NS_ENSURE_TRUE(aSelState, PR_FALSE); PRUint32 i, myCount = mArray.Length(), itsCount = aSelState->mArray.Length(); if (myCount != itsCount) return PR_FALSE; if (myCount < 1) return PR_FALSE; for (i=0; i<myCount; i++) { nsCOMPtr<nsIDOMRange> myRange, itsRange; mArray[i].GetRange(address_of(myRange)); aSelState->mArray[i].GetRange(address_of(itsRange)); NS_ENSURE_TRUE(myRange && itsRange, PR_FALSE); PRInt16 compResult; nsresult rv; rv = myRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START, itsRange, &compResult); if (NS_FAILED(rv) || compResult) return PR_FALSE; rv = myRange->CompareBoundaryPoints(nsIDOMRange::END_TO_END, itsRange, &compResult); if (NS_FAILED(rv) || compResult) return PR_FALSE; } // if we got here, they are equal return PR_TRUE; }
bool Flasher_::is_erased(PageID page) { volatile const Data *const startp = reinterpret_cast<volatile const Data *>(address_of(page)); volatile const Data *const stopp = reinterpret_cast<volatile const Data *>(address_of(page + 1)); // Cycle through the whole page and check for default set bits for (volatile const Data *datap = startp; datap < stopp; ++datap) { if (*datap != ERASED_WORD) return false; } return true; }
nsresult nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult) { // we only need to execute the stuff below if we are a plaintext editor. // html editors have a different mechanism for putting in mozBR's // (because there are a bunch more places you have to worry about it in html) if (!IsPlaintextEditor()) { return NS_OK; } // if we are at the end of the document, we need to insert // a special mozBR following the normal br, and then set the // selection to stick to the mozBR. PRInt32 selOffset; nsCOMPtr<nsIDOMNode> selNode; nsresult res; res = mEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); // confirm we are at end of document if (selOffset == 0) return NS_OK; // can't be after a br if we are at offset 0 nsIDOMElement *rootElem = mEditor->GetRoot(); nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem); NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER); if (selNode != root) return NS_OK; // must be inside text node or somewhere other than end of root nsCOMPtr<nsIDOMNode> temp = mEditor->GetChildAt(selNode, selOffset); if (temp) return NS_OK; // can't be at end if there is a node after us. nsCOMPtr<nsIDOMNode> nearNode = mEditor->GetChildAt(selNode, selOffset-1); if (nearNode && nsTextEditUtils::IsBreak(nearNode) && !nsTextEditUtils::IsMozBR(nearNode)) { nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection)); // need to insert special moz BR. Why? Because if we don't // the user will see no new line for the break. Also, things // like table cells won't grow in height. nsCOMPtr<nsIDOMNode> brNode; res = CreateMozBR(selNode, selOffset, address_of(brNode)); NS_ENSURE_SUCCESS(res, res); res = nsEditor::GetNodeLocation(brNode, address_of(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); selPrivate->SetInterlinePosition(PR_TRUE); res = aSelection->Collapse(selNode, selOffset); NS_ENSURE_SUCCESS(res, res); } return res; }
nsresult TextEditRules::CreateBRInternal(nsIDOMNode* inParent, int32_t inOffset, bool aMozBR, nsIDOMNode** outBRNode) { NS_ENSURE_TRUE(inParent, NS_ERROR_NULL_POINTER); nsCOMPtr<nsIDOMNode> brNode; NS_ENSURE_STATE(mTextEditor); nsresult rv = mTextEditor->CreateBR(inParent, inOffset, address_of(brNode)); NS_ENSURE_SUCCESS(rv, rv); // give it special moz attr nsCOMPtr<Element> brElem = do_QueryInterface(brNode); if (aMozBR && brElem) { rv = mTextEditor->SetAttribute(brElem, nsGkAtoms::type, NS_LITERAL_STRING("_moz")); NS_ENSURE_SUCCESS(rv, rv); } if (outBRNode) { brNode.forget(outBRNode); } return NS_OK; }
nsresult nsTextEditRules::CreateTrailingBRIfNeeded() { // but only if we aren't a single line edit field if (IsSingleLineEditor()) return NS_OK; nsIDOMNode *body = mEditor->GetRoot(); NS_ENSURE_TRUE(body, NS_ERROR_NULL_POINTER); nsCOMPtr<nsIDOMNode> lastChild; nsresult res = body->GetLastChild(getter_AddRefs(lastChild)); // assuming CreateBogusNodeIfNeeded() has been called first NS_ENSURE_SUCCESS(res, res); NS_ENSURE_TRUE(lastChild, NS_ERROR_NULL_POINTER); if (!nsTextEditUtils::IsBreak(lastChild)) { nsAutoTxnsConserveSelection dontSpazMySelection(mEditor); PRUint32 rootLen; res = mEditor->GetLengthOfDOMNode(body, rootLen); NS_ENSURE_SUCCESS(res, res); nsCOMPtr<nsIDOMNode> unused; res = CreateMozBR(body, rootLen, address_of(unused)); } return res; }
int Flasher_::compare(PageID page, volatile const Data *bufp) { R2P_ASSERT(is_aligned(const_cast<const Data *>(bufp))); volatile const Data *const flashp = reinterpret_cast<volatile const Data *>(address_of(page)); bool identical = true; for (size_t pos = 0; pos < PAGE_SIZE / WORD_ALIGNMENT; ++pos) { if (flashp[pos] != bufp[pos]) { // Keep track if the buffer is identical to page -> mark not identical identical = false; // Not identical, and not erased, needs erase if (flashp[pos] != ERASED_WORD) return -1; } } // Page is not identical, but no page erase is needed to write if (!identical) return 1; // Page is identical. No write is needed return 0; }
nsresult nsTextEditRules::DidDeleteSelection(nsISelection *aSelection, nsIEditor::EDirection aCollapsedAction, nsresult aResult) { nsCOMPtr<nsIDOMNode> startNode; PRInt32 startOffset; nsresult res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset); if (NS_FAILED(res)) return res; if (!startNode) return NS_ERROR_FAILURE; // delete empty text nodes at selection if (mEditor->IsTextNode(startNode)) { nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(startNode); PRUint32 strLength; res = textNode->GetLength(&strLength); if (NS_FAILED(res)) return res; // are we in an empty text node? if (!strLength) { res = mEditor->DeleteNode(startNode); if (NS_FAILED(res)) return res; } } if (!mDidExplicitlySetInterline) { // We prevent the caret from sticking on the left of prior BR // (i.e. the end of previous line) after this deletion. Bug 92124 nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(aSelection); if (selPriv) res = selPriv->SetInterlinePosition(PR_TRUE); } return res; }
nsresult nsTextEditRules::CreateTrailingBRIfNeeded() { // but only if we aren't a single line edit field if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) return NS_OK; nsIDOMNode *body = mEditor->GetRoot(); if (!body) return NS_ERROR_NULL_POINTER; nsCOMPtr<nsIDOMNode> lastChild; nsresult res = body->GetLastChild(getter_AddRefs(lastChild)); // assuming CreateBogusNodeIfNeeded() has been called first if (NS_FAILED(res)) return res; if (!lastChild) return NS_ERROR_NULL_POINTER; if (!nsTextEditUtils::IsBreak(lastChild)) { nsAutoTxnsConserveSelection dontSpazMySelection(mEditor); PRUint32 rootLen; res = mEditor->GetLengthOfDOMNode(body, rootLen); if (NS_FAILED(res)) return res; nsCOMPtr<nsIDOMNode> unused; res = CreateMozBR(body, rootLen, address_of(unused)); } return res; }
void nsContentSubtreeIterator::Prev() { // Prev should be optimized to use the mStartNodes, just as Next // uses mEndNodes. if (mIsDone || !mCurNode) return; if (mCurNode == mFirst) { mIsDone = PR_TRUE; return; } nsINode *prevNode = PrevNode(GetDeepFirstChild(mCurNode, nsnull), nsnull); prevNode = GetDeepLastChild(prevNode, nsnull); GetTopAncestorInRange(prevNode, address_of(mCurNode)); // This shouldn't be needed, but since our selection code can put us // in a situation where mFirst is in generated content, we need this // to stop the iterator when we've walked past past the first node! mIsDone = mCurNode == nsnull; }
bool Flasher_::write(PageID page, volatile const Data *bufp) { R2P_ASSERT(is_aligned(const_cast<const Data *>(bufp))); if (!check_bounds(address_of(page), PAGE_SIZE, get_program_start(), get_program_length())) { return false; } volatile Data *const flashp = reinterpret_cast<volatile Data *>( reinterpret_cast<uintptr_t>(address_of(page)) ); chSysDisable(); // Unlock flash for write access if (!flash_unlock()) { flash_lock(); chSysEnable(); return false; } flash_busy_wait(); for (size_t pos = 0; pos < PAGE_SIZE / WORD_ALIGNMENT; ++pos) { // Enter flash programming mode FLASH->CR |= FLASH_CR_PG; // Write half-word to flash flashp[pos] = bufp[pos]; flash_busy_wait(); // Exit flash programming mode FLASH->CR &= ~FLASH_CR_PG; // Check for flash error if (flashp[pos] != bufp[pos]) { flash_lock(); chSysEnable(); return false; } } flash_lock(); chSysEnable(); return true; }
nsresult nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode) { if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc... NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER); PRUint32 i, count = mArray.Length(); if (!count) { return NS_OK; } nsCOMPtr<nsIDOMNode> parent; PRInt32 offset = 0; nsresult res = nsEditor::GetNodeLocation(aNode, address_of(parent), &offset); NS_ENSURE_SUCCESS(res, res); // check for range endpoints that are after aNode and in the same parent nsRangeStore *item; for (i=0; i<count; i++) { item = mArray[i]; NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER); if ((item->startNode.get() == parent) && (item->startOffset > offset)) item->startOffset--; if ((item->endNode.get() == parent) && (item->endOffset > offset)) item->endOffset--; // check for range endpoints that are in aNode if (item->startNode == aNode) { item->startNode = parent; item->startOffset = offset; } if (item->endNode == aNode) { item->endNode = parent; item->endOffset = offset; } // check for range endpoints that are in descendants of aNode nsCOMPtr<nsIDOMNode> oldStart; if (nsEditorUtils::IsDescendantOf(item->startNode, aNode)) { oldStart = item->startNode; // save for efficiency hack below. item->startNode = parent; item->startOffset = offset; } // avoid having to call IsDescendantOf() for common case of range startnode == range endnode. if ((item->endNode == oldStart) || nsEditorUtils::IsDescendantOf(item->endNode, aNode)) { item->endNode = parent; item->endOffset = offset; } } return NS_OK; }
bool Flasher_::read(PageID page, Data *bufp) { R2P_ASSERT(is_aligned(bufp)); memcpy(static_cast<void *>(bufp), reinterpret_cast<const void *>(address_of(page)), PAGE_SIZE); return true; }
planar_pixel_iterator& operator=(P* pix) { function_requires<PixelsCompatibleConcept<P,value_type> >(); static_transform(*pix,*this, address_of()); // PERFORMANCE_CHECK: Compare to this: //this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>(); //this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>(); //this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>(); return *this; }
bool nsSelectionState::IsCollapsed() { if (1 != mArray.Length()) return PR_FALSE; nsCOMPtr<nsIDOMRange> range; mArray[0].GetRange(address_of(range)); NS_ENSURE_TRUE(range, PR_FALSE); bool bIsCollapsed = false; range->GetCollapsed(&bIsCollapsed); return bIsCollapsed; }
nsresult nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode) { if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc... NS_ENSURE_TRUE(aOldRightNode && aNewLeftNode, NS_ERROR_NULL_POINTER); PRUint32 i, count = mArray.Length(); if (!count) { return NS_OK; } nsCOMPtr<nsIDOMNode> parent; PRInt32 offset; nsresult result = nsEditor::GetNodeLocation(aOldRightNode, address_of(parent), &offset); NS_ENSURE_SUCCESS(result, result); // first part is same as inserting aNewLeftnode result = SelAdjInsertNode(parent,offset-1); NS_ENSURE_SUCCESS(result, result); // next step is to check for range enpoints inside aOldRightNode nsRangeStore *item; for (i=0; i<count; i++) { item = mArray[i]; NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER); if (item->startNode.get() == aOldRightNode) { if (item->startOffset > aOffset) { item->startOffset -= aOffset; } else { item->startNode = aNewLeftNode; } } if (item->endNode.get() == aOldRightNode) { if (item->endOffset > aOffset) { item->endOffset -= aOffset; } else { item->endNode = aNewLeftNode; } } } return NS_OK; }
nsresult nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection) { // we only need to execute the stuff below if we are a plaintext editor. // html editors have a different mechanism for putting in mozBR's // (because there are a bunch more places you have to worry about it in html) if (!IsPlaintextEditor()) { return NS_OK; } // if we are at the end of the textarea, we need to set the // selection to stick to the mozBR at the end of the textarea. PRInt32 selOffset; nsCOMPtr<nsIDOMNode> selNode; nsresult res; res = mEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset); NS_ENSURE_SUCCESS(res, res); nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(selNode); if (!nodeAsText) return NS_OK; // nothing to do if we're not at a text node PRUint32 length; res = nodeAsText->GetLength(&length); NS_ENSURE_SUCCESS(res, res); // nothing to do if we're not at the end of the text node if (selOffset != PRInt32(length)) return NS_OK; nsCOMPtr<nsIDOMNode> parentNode; PRInt32 parentOffset; res = nsEditor::GetNodeLocation(selNode, address_of(parentNode), &parentOffset); NS_ENSURE_SUCCESS(res, res); nsIDOMElement *rootElem = mEditor->GetRoot(); nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem); NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER); if (parentNode != root) return NS_OK; nsCOMPtr<nsIDOMNode> nextNode = mEditor->GetChildAt(parentNode, parentOffset + 1); if (nextNode && nsTextEditUtils::IsMozBR(nextNode)) { res = aSelection->Collapse(parentNode, parentOffset + 1); NS_ENSURE_SUCCESS(res, res); } return res; }
nsresult TypeInState::UpdateSelState(nsISelection *aSelection) { if (!aSelection) return NS_ERROR_NULL_POINTER; PRBool isCollapsed = PR_FALSE; nsresult result = aSelection->GetIsCollapsed(&isCollapsed); if (NS_FAILED(result)) return result; if (isCollapsed) { result = nsEditor::GetStartNodeAndOffset(aSelection, address_of(mLastSelectionContainer), &mLastSelectionOffset); } return result; }
NS_IMETHODIMP TypeInState::NotifySelectionChanged(nsIDOMDocument *, nsISelection *aSelection, PRInt16) { // XXX: Selection currently generates bogus selection changed notifications // XXX: (bug 140303). It can notify us when the selection hasn't actually // XXX: changed, and it notifies us more than once for the same change. // XXX: // XXX: The following code attempts to work around the bogus notifications, // XXX: and should probably be removed once bug 140303 is fixed. // XXX: // XXX: This code temporarily fixes the problem where clicking the mouse in // XXX: the same location clears the type-in-state. if (aSelection) { PRBool isCollapsed = PR_FALSE; nsresult result = aSelection->GetIsCollapsed(&isCollapsed); if (NS_FAILED(result)) return result; if (isCollapsed) { nsCOMPtr<nsIDOMNode> selNode; PRInt32 selOffset = 0; result = nsEditor::GetStartNodeAndOffset(aSelection, address_of(selNode), &selOffset); if (NS_FAILED(result)) return result; if (selNode && selNode == mLastSelectionContainer && selOffset == mLastSelectionOffset) { // We got a bogus selection changed notification! return NS_OK; } mLastSelectionContainer = selNode; mLastSelectionOffset = selOffset; } else { mLastSelectionContainer = nsnull; mLastSelectionOffset = 0; } } Reset(); return NS_OK; }
int write_page(BTREE *bt, void *page) { int i; long l; l = address_of(bt, page); if (l < 0) return -1; fseek(bt->indfile, l, SEEK_SET); if (fwrite(page, PAGESIZE, 1, bt->indfile) != 1) { btree_errno = IND_WRITE; return -1; } return 0; }
bool Flasher_::flash_aligned(const Data *address, const Data *bufp, size_t buflen) { R2P_ASSERT(is_aligned(address)); R2P_ASSERT(is_aligned(bufp)); R2P_ASSERT(is_aligned(reinterpret_cast<const void *>(buflen))); bool writeback = false; // Process all given words while (buflen > 0) { PageID old_page = page; page = page_of(reinterpret_cast<const uint8_t *>(address)); ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(address) - reinterpret_cast<ptrdiff_t>(address_of(page)); size_t length = (PAGE_SIZE - offset); // Read back new page if page has changed if (old_page != page) { if (page_modified) { if (!write_if_needed(old_page, page_bufp)) return false; } if (!read(page, page_bufp)) return false; page_modified = false; } // Process no more bytes than remaining if (length > buflen) { length = buflen; } else { writeback = true; } // Copy buffer into page buffer and mark as tainted memcpy(&page_bufp[offset / WORD_ALIGNMENT], bufp, length); page_modified = true; buflen -= length; // Writeback buffer if needed if (writeback) { if (!write_if_needed(page, page_bufp)) return false; writeback = false; } } return true; }
bool Flasher_::erase(PageID page) { // Unlock flash for write access if (!flash_unlock()) return false; flash_busy_wait(); // Start deletion of page. FLASH->CR |= FLASH_CR_PER; FLASH->AR = reinterpret_cast<uint32_t>(address_of(page)); FLASH->CR |= FLASH_CR_STRT; flash_busy_wait(); // Page erase flag does not clear automatically. FLASH->CR &= !FLASH_CR_PER; flash_lock(); return is_erased(page); }
static inline already_AddRefed<nsIDOMNode> GetTextNode(nsISelection *selection, nsEditor *editor) { PRInt32 selOffset; nsCOMPtr<nsIDOMNode> selNode; nsresult res = editor->GetStartNodeAndOffset(selection, address_of(selNode), &selOffset); if (NS_FAILED(res)) return nsnull; if (!editor->IsTextNode(selNode)) { // Get an nsINode from the nsIDOMNode nsCOMPtr<nsINode> node = do_QueryInterface(selNode); // if node is null, return it to indicate there's no text if (!node) return nsnull; // This should be the root node, walk the tree looking for text nodes nsNodeIterator iter(node, nsIDOMNodeFilter::SHOW_TEXT, nsnull, PR_TRUE); while (!editor->IsTextNode(selNode)) { if (NS_FAILED(res = iter.NextNode(getter_AddRefs(selNode))) || !selNode) { return nsnull; } } } return selNode.forget(); }
planar_frame_iterator& operator= (P* pix) { /* TODO: It seems that the following statements are optimized away by GCC in some strange cases... */ boost::function_requires<FramesCompatibleConcept<P, value_type> >(); static_transform (*pix, *this, address_of ()); /* TODO: Performance compare to this: this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>(); this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>(); this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>(); */ return *this; }
uintptr_t alloc( unsigned int pages, unsigned int alignment ) { size_t i = 0; while( (i + _prev_idx) % alignment ) ++i; for( ; i < _num_pageframes; i += alignment ) { bool ok = true; for( unsigned int j = 0; j < pages; ++j ) { int idx = (_prev_idx + i + j) % _num_pageframes; if( status(idx) ) { ok = false; break; } } if( ok ) { int idx = (_prev_idx + i) % _num_pageframes; for( unsigned int j = 0; j < pages; ++j ) { status(idx + j) = 1; } _prev_idx = (idx + pages) % _num_pageframes; return address_of(idx); } } if( _fallback ) return _fallback->alloc( pages, alignment ); return 0; }
nsresult nsSelectionState::RestoreSelection(nsISelection *aSel) { NS_ENSURE_TRUE(aSel, NS_ERROR_NULL_POINTER); nsresult res; PRUint32 i, arrayCount = mArray.Length(); // clear out selection aSel->RemoveAllRanges(); // set the selection ranges anew for (i=0; i<arrayCount; i++) { nsCOMPtr<nsIDOMRange> range; mArray[i].GetRange(address_of(range)); NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED); res = aSel->AddRange(range); if(NS_FAILED(res)) return res; } return NS_OK; }
constexpr const int *return_param(int n) { // expected-note {{declared here}} return address_of(n); }
nsresult nsContentSubtreeIterator::Init(nsIDOMRange* aRange) { if (!aRange) return NS_ERROR_NULL_POINTER; mIsDone = PR_FALSE; mRange = aRange; // get the start node and offset, convert to nsINode nsCOMPtr<nsIDOMNode> commonParent; nsCOMPtr<nsIDOMNode> startParent; nsCOMPtr<nsIDOMNode> endParent; nsCOMPtr<nsINode> nStartP; nsCOMPtr<nsINode> nEndP; nsCOMPtr<nsINode> n; nsINode *firstCandidate = nsnull; nsINode *lastCandidate = nsnull; PRInt32 indx, startIndx, endIndx; // get common content parent if (NS_FAILED(aRange->GetCommonAncestorContainer(getter_AddRefs(commonParent))) || !commonParent) return NS_ERROR_FAILURE; mCommonParent = do_QueryInterface(commonParent); // get start content parent if (NS_FAILED(aRange->GetStartContainer(getter_AddRefs(startParent))) || !startParent) return NS_ERROR_FAILURE; nStartP = do_QueryInterface(startParent); aRange->GetStartOffset(&startIndx); // get end content parent if (NS_FAILED(aRange->GetEndContainer(getter_AddRefs(endParent))) || !endParent) return NS_ERROR_FAILURE; nEndP = do_QueryInterface(endParent); aRange->GetEndOffset(&endIndx); // short circuit when start node == end node if (startParent == endParent) { nsINode* nChild = nStartP->GetChildAt(0); if (!nChild) // no children, must be a text node or empty container { // all inside one text node - empty subtree iterator MakeEmpty(); return NS_OK; } else { if (startIndx == endIndx) // collapsed range { MakeEmpty(); return NS_OK; } } } // cache ancestors #if 0 nsContentUtils::GetAncestorsAndOffsets(startParent, startIndx, &mStartNodes, &mStartOffsets); #endif nsContentUtils::GetAncestorsAndOffsets(endParent, endIndx, &mEndNodes, &mEndOffsets); // find first node in range aRange->GetStartOffset(&indx); if (!nStartP->GetChildCount()) // no children, start at the node itself { n = nStartP; } else { nsINode* nChild = nStartP->GetChildAt(indx); if (!nChild) // offset after last child { n = nStartP; } else { firstCandidate = nChild; } } if (!firstCandidate) { // then firstCandidate is next node after cN firstCandidate = GetNextSibling(n, nsnull); if (!firstCandidate) { MakeEmpty(); return NS_OK; } } firstCandidate = GetDeepFirstChild(firstCandidate, nsnull); // confirm that this first possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. PRBool nodeBefore, nodeAfter; if (NS_FAILED(nsRange::CompareNodeToRange(firstCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; if (nodeBefore || nodeAfter) { MakeEmpty(); return NS_OK; } // cool, we have the first node in the range. Now we walk // up its ancestors to find the most senior that is still // in the range. That's the real first node. if (NS_FAILED(GetTopAncestorInRange(firstCandidate, address_of(mFirst)))) return NS_ERROR_FAILURE; // now to find the last node aRange->GetEndOffset(&indx); PRInt32 numChildren = nEndP->GetChildCount(); if (indx > numChildren) indx = numChildren; if (!indx) { n = nEndP; } else { if (!numChildren) // no children, must be a text node { n = nEndP; } else { lastCandidate = nEndP->GetChildAt(--indx); NS_ASSERTION(lastCandidate, "tree traversal trouble in nsContentSubtreeIterator::Init"); } } if (!lastCandidate) { // then lastCandidate is prev node before n lastCandidate = GetPrevSibling(n, nsnull); } lastCandidate = GetDeepLastChild(lastCandidate, nsnull); // confirm that this last possible contained node // is indeed contained. Else we have a range that // does not fully contain any node. if (NS_FAILED(nsRange::CompareNodeToRange(lastCandidate, aRange, &nodeBefore, &nodeAfter))) return NS_ERROR_FAILURE; if (nodeBefore || nodeAfter) { MakeEmpty(); return NS_OK; } // cool, we have the last node in the range. Now we walk // up its ancestors to find the most senior that is still // in the range. That's the real first node. if (NS_FAILED(GetTopAncestorInRange(lastCandidate, address_of(mLast)))) return NS_ERROR_FAILURE; mCurNode = mFirst; return NS_OK; }
nsresult TextEditRules::WillInsertText(EditAction aAction, Selection* aSelection, bool* aCancel, bool* aHandled, const nsAString* inString, nsAString* outString, int32_t aMaxLength) { if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; } if (inString->IsEmpty() && aAction != EditAction::insertIMEText) { // HACK: this is a fix for bug 19395 // I can't outlaw all empty insertions // because IME transaction depend on them // There is more work to do to make the // world safe for IME. *aCancel = true; *aHandled = false; return NS_OK; } // initialize out param *aCancel = false; *aHandled = true; // handle docs with a max length // NOTE, this function copies inString into outString for us. bool truncated = false; nsresult rv = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength, &truncated); NS_ENSURE_SUCCESS(rv, rv); // If we're exceeding the maxlength when composing IME, we need to clean up // the composing text, so we shouldn't return early. if (truncated && outString->IsEmpty() && aAction != EditAction::insertIMEText) { *aCancel = true; return NS_OK; } uint32_t start = 0; uint32_t end = 0; // handle password field docs if (IsPasswordEditor()) { NS_ENSURE_STATE(mTextEditor); nsContentUtils::GetSelectionInTextControl(aSelection, mTextEditor->GetRoot(), start, end); } // if the selection isn't collapsed, delete it. bool bCollapsed; rv = aSelection->GetIsCollapsed(&bCollapsed); NS_ENSURE_SUCCESS(rv, rv); if (!bCollapsed) { NS_ENSURE_STATE(mTextEditor); rv = mTextEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip); NS_ENSURE_SUCCESS(rv, rv); } WillInsert(*aSelection, aCancel); // initialize out param // we want to ignore result of WillInsert() *aCancel = false; // handle password field data // this has the side effect of changing all the characters in aOutString // to the replacement character if (IsPasswordEditor() && aAction == EditAction::insertIMEText) { RemoveIMETextFromPWBuf(start, outString); } // People have lots of different ideas about what text fields // should do with multiline pastes. See bugs 21032, 23485, 23485, 50935. // The six possible options are: // 0. paste newlines intact // 1. paste up to the first newline (default) // 2. replace newlines with spaces // 3. strip newlines // 4. replace with commas // 5. strip newlines and surrounding whitespace // So find out what we're expected to do: if (IsSingleLineEditor()) { nsAutoString tString(*outString); NS_ENSURE_STATE(mTextEditor); HandleNewLines(tString, mTextEditor->mNewlineHandling); outString->Assign(tString); } if (IsPasswordEditor()) { // manage the password buffer mPasswordText.Insert(*outString, start); if (LookAndFeel::GetEchoPassword() && !DontEchoPassword()) { HideLastPWInput(); mLastStart = start; mLastLength = outString->Length(); if (mTimer) { mTimer->Cancel(); } else { mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); NS_ENSURE_SUCCESS(rv, rv); } mTimer->InitWithCallback(this, LookAndFeel::GetPasswordMaskDelay(), nsITimer::TYPE_ONE_SHOT); } else { FillBufWithPWChars(outString, outString->Length()); } } // get the (collapsed) selection location NS_ENSURE_STATE(aSelection->GetRangeAt(0)); nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartContainer(); int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset(); NS_ENSURE_STATE(selNode); // don't put text in places that can't have it NS_ENSURE_STATE(mTextEditor); if (!EditorBase::IsTextNode(selNode) && !mTextEditor->CanContainTag(*selNode, *nsGkAtoms::textTagName)) { return NS_ERROR_FAILURE; } // we need to get the doc NS_ENSURE_STATE(mTextEditor); nsCOMPtr<nsIDocument> doc = mTextEditor->GetDocument(); NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED); if (aAction == EditAction::insertIMEText) { NS_ENSURE_STATE(mTextEditor); // Find better insertion point to insert text. mTextEditor->FindBetterInsertionPoint(selNode, selOffset); // If there is one or more IME selections, its minimum offset should be // the insertion point. int32_t IMESelectionOffset = mTextEditor->GetIMESelectionStartOffsetIn(selNode); if (IMESelectionOffset >= 0) { selOffset = IMESelectionOffset; } rv = mTextEditor->InsertTextImpl(*outString, address_of(selNode), &selOffset, doc); NS_ENSURE_SUCCESS(rv, rv); } else { // aAction == EditAction::insertText; find where we are nsCOMPtr<nsINode> curNode = selNode; int32_t curOffset = selOffset; // don't change my selection in subtransactions NS_ENSURE_STATE(mTextEditor); AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor); rv = mTextEditor->InsertTextImpl(*outString, address_of(curNode), &curOffset, doc); NS_ENSURE_SUCCESS(rv, rv); if (curNode) { // Make the caret attach to the inserted text, unless this text ends with a LF, // in which case make the caret attach to the next line. bool endsWithLF = !outString->IsEmpty() && outString->Last() == nsCRT::LF; aSelection->SetInterlinePosition(endsWithLF); aSelection->Collapse(curNode, curOffset); } } ASSERT_PASSWORD_LENGTHS_EQUAL() return NS_OK; }
int insert_key(BTREE *bt, long page, KEY *key, ITEM *u, KEY **hkey) { PAGE_ADDRESS *p, *b; KEY *pk, *pkk, *vkey; long nx; int k, l, r, n; ITEM v; *hkey = NULL; if (page == BTREE_NULL) { u->next = page; u->child = 0; *hkey = (KEY *) malloc(bt->keysize); memcpy(*hkey, key, bt->realkeysize); return 0; } p = (PAGE_ADDRESS *) get_page(bt, page); pk = (KEY *) (p + 1); l = 0; r = p->nkeys-1; do { k = (l + r) / 2; pkk = nth_key(bt, p, k); if (bt->compare_key((void *) key, pkk) < 0) r = k - 1; else if (bt->compare_key((void *) key, pkk) > 0) l = k + 1; else break; } while (r >= l); if (r >= l) { if (p->s[k].size < 0) /* chave foi deletada */ { p->s[k].size = u->size; p->s[k].address = u->address; memcpy(nth_key(bt, p, k), key, bt->realkeysize); return 0; } btree_errno = DUP_KEY; return -1; /* chave jah existe */ } if (r < 0) nx = p->next0; else nx = p->s[r].next; v = *u; if ((k = insert_key(bt, nx, key, &v, &vkey)) < 0) return k; if (vkey == NULL) { if ( r < 0) { p->child0 += v.child; } else { p->s[r].child += v.child; } *u = v; write_page(bt, p); return 0; } p->s[r].child -= v.child; if (p->nkeys < bt->order) { for (k = p->nkeys; k > r+1; k--) { p->s[k] = p->s[k-1]; pkk = nth_key(bt, p, k); pk = nth_key(bt, p, k-1); memcpy(pkk, pk, bt->realkeysize); } memcpy(nth_key(bt, p, k), vkey, bt->realkeysize); p->s[k] = v; p->nkeys++; u->child = 1; free(vkey); write_page(bt, p); return 0; } b = (PAGE_ADDRESS *) new_page(bt); b->label = BTREE_LABEL; n = bt->order / 2 - 1; if (r <= n) { if (r != n) { *u = p->s[n]; *hkey = (KEY *) malloc(bt->keysize); memcpy(*hkey, nth_key(bt, p, n), bt->realkeysize); for (k = n ; k > r+1; k--) { p->s[k] = p->s[k-1]; pkk = nth_key(bt, p, k); pk = nth_key(bt, p, k-1); memcpy(pkk, pk, bt->realkeysize); } memcpy(nth_key(bt, p, k), vkey, bt->realkeysize); p->s[k] = v; free(vkey); } else { *u = v; *hkey = vkey; } n++; for (k = 0; k < n; k++) { b->s[k] = p->s[k+n]; memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n), bt->realkeysize); } } else { r = r - n - 1; *u = p->s[n+1]; *hkey = (KEY *) malloc(bt->keysize); memcpy(*hkey, nth_key(bt, p, n+1), bt->realkeysize); for (k = 0; k < r; k++) { b->s[k] = p->s[k+n+2]; memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n+2), bt->realkeysize); } memcpy(nth_key(bt, b, k), vkey, bt->realkeysize); b->s[k] = v; free(vkey); n++; for (k = r+1; k < n; k++) { b->s[k] = p->s[k+n]; memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n), bt->realkeysize); } } p->nkeys = b->nkeys = n; b->next0 = u->next; b->child0 = u->child; u->next = address_of(bt, b); u->child = n + b->child0; for (k = 0; k < n; k++) u->child += b->s[k].child; write_page(bt, p); write_page(bt, b); return 0; }
static lua_Number ljc_relational( lua_Number st, lua_Number sv , lua_Number tt, lua_Number tv , int op ) { assert( !( st == LUA_TNUMBER && tt == LUA_TNUMBER ) ); struct TValue s = { .t = st, .v = (union Value)sv }; struct TValue t = { .t = tt, .v = (union Value)tv }; switch( op ){ case REL_LT: return do_lt( &s, &t ); case REL_LEQ: return do_leq( &s, &t ); case REL_EQ: return do_eq( &s, &t ); default: assert( false ); } } typedef void (*arch_rel)( struct emitter*, struct machine* , operand, operand, label ); static void emit_relational( struct emitter *me, struct machine_ops *mop , struct frame* f , loperand s, loperand t , arch_rel ar, int op , bool expect ){ vreg_operand os = loperand_to_operand( f, s ), ot = loperand_to_operand( f, t ); unsigned int pc = me->ops->pc( me ) + 2; label l = LBL_PC( pc ); // determine if coercion is required operand tag = OP_TARGETREG( acquire_temp( mop, me, f->m ) ); mop->bor( me, f->m, tag, os.type, ot.type ); mop->beq( me, f->m, tag, OP_TARGETIMMED( 0 ), LBL_NEXT( 0 ) ); // do coercion mop->call_static_cfn( me, f, (uintptr_t)&ljc_relational , &tag, 5, os.type, os.value , ot.type, ot.value , OP_TARGETIMMED( op ) ); mop->beq( me, f->m, tag, OP_TARGETIMMED( expect ), l ); mop->b( me, f->m, LBL_NEXT( 1 ) ); // do primitive relational me->ops->label_local( me, 0 ); ar( me, f->m, os.value, ot.value, l ); me->ops->label_local( me, 1 ); release_temp( mop, me, f->m ); return; } void emit_jmp( struct emitter** mce, struct machine_ops* mop , struct frame *f , loperand a , int offset ){ assert( a.islocal ); // if not zero then any upvalues below the vreg need to be closed. if( a.index > 0 ){ vreg_operand op = vreg_to_operand( f, a.index + 1, true ); operand base = OP_TARGETREG( acquire_temp( mop, REF, f->m ) ); address_of( mop, REF, f->m, base, op.type ); mop->call_static_cfn( REF, f, (uintptr_t)&closure_close, NULL , 1 , base ); release_temp( mop, REF, f->m ); } unsigned int pc = (int)REF->ops->pc( REF ) + offset + 1; mop->b( REF, f->m, LBL_PC( pc ) ); }