Пример #1
0
    // Thread-safe and non-blocking (may block if node needs to be allocated
    // from the operating system). Returns false if the freelist is not able to
    // allocate a new deque node.
    // Complexity: O(Processes)
    bool push_right(T const& data)
    {
        // Allocate the new node which we will be inserting.
        node* n = alloc_node(0, 0, data);

        if (n == 0)
            return false;

        // Loop until we insert successfully.
        while (true)
        {
            // Load the anchor.
            anchor_pair lrs = anchor_.lrs();

            // Check if the deque is empty.
            // FIXME: Should we check both pointers here?
            if (lrs.get_right_ptr() == 0)
            {
                // If the deque is empty, we simply install a new anchor which
                // points to the new node as both its leftmost and rightmost
                // element.
                if (anchor_.cas(lrs, anchor_pair(n, n,
                        lrs.get_left_tag(), lrs.get_right_tag() + 1)))
                    return true;
            }

            // Check if the deque is stable.
            else if (lrs.get_left_tag() == stable)
            {
                // Make the left pointer on our new node refer to the current
                // rightmost node.
                n->left.store(node_pointer(lrs.get_right_ptr()));

                // Now we want to make the anchor point to our new node as the
                // leftmost node. We change the state to lpush as the deque
                // will become unstable if this operation succeeds.
                anchor_pair new_anchor(lrs.get_left_ptr(), n,
                    rpush, lrs.get_right_tag() + 1);

                if (anchor_.cas(lrs, new_anchor))
                {
                    stabilize_right(new_anchor);
                    return true;
                }
            }

            // The deque must be unstable, so we have to stabilize it before
            // we can continue.
            else // lrs.s() != stable
                stabilize(lrs);
        }
    }
Пример #2
0
void
TextSelection::SetText (const char *text)
{
#define CONTENT_START (0)
#define CONTENT_END ((guint32)-1)

	if (anchor.GetParent() == NULL || moving.GetParent() == NULL)
		// if either are null we're going nowhere fast...
		return;

	ClearSelection ();

	// at this point the selection is empty and anchor == moving
	if (text && *text) {
		if (anchor.GetParent()->Is (Type::RUN)) {
			const char *run_text = ((Run*)anchor.GetParent())->GetText();
			if (run_text == NULL)
				run_text = "\0";

			char *new_text = (char*)g_malloc0 (strlen (run_text) + strlen (text) + 1);

			if (strlen (text) < (size_t) anchor.ResolveLocation ()){
				// #339RT enters here
				g_free (new_text);
				new_text = g_strdup ("BUGBUGBUG");
			} else {
				strncpy (new_text, run_text, anchor.ResolveLocation());
				strcpy (new_text + anchor.ResolveLocation(), text);
				strncpy (new_text + anchor.ResolveLocation() + strlen(text), run_text + anchor.ResolveLocation(), strlen (run_text) - anchor.ResolveLocation());
			}

			((Run*)anchor.GetParent())->SetText (new_text);

			if (moving.GetLocation() > strlen (new_text)) {
				anchor = TextPointer (anchor.GetParent(), CONTENT_END, anchor.GetLogicalDirection());
				moving = TextPointer (anchor.GetParent(), CONTENT_END, anchor.GetLogicalDirection());
			}
			else {
				TextPointer new_anchor (anchor.GetParent(), anchor.ResolveLocation () + strlen (text), anchor.GetLogicalDirection());
				moving = TextPointer (anchor.GetParent(), anchor.ResolveLocation () + strlen (text), anchor.GetLogicalDirection());
				anchor = new_anchor;
			}

			g_free (new_text);

			if (anchor.CompareTo_np (moving) < 0) {
				start = anchor;
				end = moving;
			}
			else {
				start = moving;
				end = anchor;
			}
		}
		else {
			IDocumentNode *node = anchor.GetParentNode();
			DependencyObjectCollection *children = node->GetDocumentChildren();

			if (!children) {
				// this can happen when anchor is in an InlineUIContainer.
				printf ("NIEX TextSelection.SetText for anchor == InlineUIContainer.\n");
				return;
			}

			Run *r = MoonUnmanagedFactory::CreateRun ();
			r->SetText (text);

			if (children->Is(Type::BLOCK_COLLECTION)) {
				// the node takes Blocks as children, so we need to create a Paragraph first.
				Paragraph *p = MoonUnmanagedFactory::CreateParagraph();
				children->Insert (anchor.GetLocation(), Value (p));
				children = p->GetInlines();
				children->Add (Value (r));
				p->unref ();
			}
			else {
				children->Insert (anchor.GetLocation(), Value (r));
			}

			anchor = TextPointer (r, CONTENT_END, anchor.GetLogicalDirection());
			moving = TextPointer (r, CONTENT_END, anchor.GetLogicalDirection());
			r->unref ();

			if (anchor.CompareTo_np (moving) < 0) {
				start = anchor;
				end = moving;
			}
			else {
				start = moving;
				end = anchor;
			}
		}
	}

	g_free (this->text);
	this->text = NULL;
}