Exemplo n.º 1
0
 inline bool move_next_leaf()
 {
     if (has_more() && current_node().is_leaf)
         skip_subtree();
     while (has_more() && !current_node().is_leaf)
         expand();
     return has_more();
 }
Exemplo n.º 2
0
/**
 * Clear the stack back to a table context: "the UA must, while the current
 * node is not a table element or an html element, pop elements from the stack
 * of open elements."
 */
static inline void clear_stack_table_context(hubbub_treebuilder *treebuilder)
{
	hubbub_ns ns;
	element_type type = current_node(treebuilder);
	void *node;

	while (type != TABLE && type != HTML) {
		element_stack_pop(treebuilder, &ns, &type, &node);

		treebuilder->tree_handler->unref_node(
				treebuilder->tree_handler->ctx,
				node);

		type = current_node(treebuilder);
	}
}
/**
 * Append text to the current node, inserting into the last child of the
 * current node, iff it's a Text node.
 *
 * \param treebuilder  The treebuilder instance
 * \param string       The string to append
 * \return HUBBUB_OK on success, appropriate error otherwise
 */
hubbub_error append_text(hubbub_treebuilder *treebuilder,
		const hubbub_string *string)
{
	element_type type = current_node(treebuilder);
	hubbub_error error = HUBBUB_OK;
	void *appended;

	if (treebuilder->context.in_table_foster &&
			(type == TABLE || type == TBODY || type == TFOOT ||
			type == THEAD || type == TR)) {
		error = aa_insert_into_foster_parent_new(treebuilder,
				HUBBUB_TOKEN_CHARACTER,
				&appended);
	} else {
		error = treebuilder->tree_handler->append_child_new(
				treebuilder->tree_handler->ctx,
				treebuilder->context.element_stack[
					treebuilder->context.current_node].node,
				HUBBUB_TOKEN_CHARACTER, &appended);
	}

	if (error != HUBBUB_OK) {
		return error;
	}

	error = treebuilder->tree_handler->set_value(
			treebuilder->tree_handler->ctx,
			appended,
			string);

	return error;
}
/**
 * Process a comment token, appending it to the given parent
 *
 * \param treebuilder  The treebuilder instance
 * \param token        The comment token
 * \param parent       The node to append to
 * \return HUBBUB_OK on success, appropriate error otherwise
 */
hubbub_error process_comment_append(hubbub_treebuilder *treebuilder,
		const hubbub_token *token, void *parent)
{
	hubbub_error error = HUBBUB_OK;
	element_type type = current_node(treebuilder);
	void *appended;

	if (treebuilder->context.in_table_foster &&
			(type == TABLE || type == TBODY || type == TFOOT ||
			type == THEAD || type == TR)) {
		error = aa_insert_into_foster_parent_new(treebuilder,
				HUBBUB_TOKEN_COMMENT,
				&appended);
	} else {
		error = treebuilder->tree_handler->append_child_new(
				treebuilder->tree_handler->ctx,
				parent, HUBBUB_TOKEN_COMMENT, &appended);
	}

	if (error != HUBBUB_OK) {
		return error;
	}

	error = treebuilder->tree_handler->set_value(
			treebuilder->tree_handler->ctx,
			appended,
			&token->data.comment);

	if (error != HUBBUB_OK) {
		return error;
	}

	return error;
}
Exemplo n.º 5
0
/**
 * Clear the stack back to a table row context.
 *
 * \param treebuilder	The treebuilder instance
 */
static void table_clear_stack(hubbub_treebuilder *treebuilder)
{
	element_type cur_node = current_node(treebuilder);

	while (cur_node != TR && cur_node != HTML) {
		hubbub_ns ns;
		element_type type;
		void *node;

		element_stack_pop(treebuilder, &ns, &type, &node);

		treebuilder->tree_handler->unref_node(
				treebuilder->tree_handler->ctx,
				node);

		cur_node = current_node(treebuilder);
	}

	return;
}
Exemplo n.º 6
0
	void direct_upwards(sooty::const_parseme_ptr_ref starting_node, F func)
	{
		if (starting_node->parent.expired())
			return;

		parseme_ptr current_node(starting_node->parent);
		while (current_node)
		{
			state::Enum r = func(current_node);
			if (r == state::stop)
				break;

			current_node = current_node->parent.lock();
		}
	}
TEST_F(MDSMetaDataStoreTest, successful_construction)
{
    be::BackendTestSetup::WithRandomNamespace wrns("",
                                                   cm_);

    const vd::MDSNodeConfigs ncfgs{ mds_manager_->server_configs()[0].node_config };
    const vd::MDSMetaDataBackendConfig cfg(ncfgs,
                                           vd::ApplyRelocationsToSlaves::T);

    auto mdstore(std::make_unique<vd::MDSMetaDataStore>(cfg,
                                                        cm_->newBackendInterface(wrns.ns()),
                                                        mdstore_home(),
                                                        1024));

    EXPECT_EQ(ncfgs[0],
              mdstore->current_node());
    EXPECT_TRUE(ncfgs == mdstore->get_config().node_configs());
}
Exemplo n.º 8
0
    static bool BreathFirstSearch( FuncWeight func_weight, std::shared_ptr< NodeType > node_src ){
	std::queue< std::shared_ptr< NodeType > > queue_vertex;
	node_src->_node_colour = graph_node_generic_colour::GREY;
	node_src->_relaxed_weight = 0;
	queue_vertex.push( node_src );
	while( !queue_vertex.empty() ){
	    std::shared_ptr< NodeType > current_node( queue_vertex.front() );
	    queue_vertex.pop();
	    int id_current_node = current_node->_id;
	    for( auto & adjacent : current_node->_desc ){
//		if( graph_node_generic_colour::WHITE == adjacent->_node_colour ){
		    adjacent->_node_colour = graph_node_generic_colour::GREY;
		    if( Relax( current_node, adjacent, func_weight ) ){
			queue_vertex.push( adjacent ); //if relaxed, descendents of adjacent node needs to be updated
		    }
//		}
	    }
//	    current_node->_node_colour = graph_node_generic_colour::BLACK;
	}
	return true;
    }
Exemplo n.º 9
0
    static bool BreathFirstSearchMaxFlowUnitLengthEdge( std::map< std::pair< std::shared_ptr< NodeType >, std::shared_ptr< NodeType > >, int> capacitymap, std::map< std::pair< std::shared_ptr< NodeType >, std::shared_ptr< NodeType > >, int> & flowmap, std::shared_ptr< NodeType > node_src, std::shared_ptr< NodeType > node_dest ){
	node_dest->_pred = nullptr;
	node_src->_pred = nullptr;
	std::queue< std::shared_ptr< NodeType > > queue_vertex;
	std::set< std::shared_ptr< NodeType > > travelled_nodes;
	queue_vertex.push( node_src );
	travelled_nodes.insert( node_src );
	while( !queue_vertex.empty() ){
	    std::shared_ptr< NodeType > current_node( queue_vertex.front() );
	    queue_vertex.pop();
	    for( auto & adjacent : current_node->_desc ){
		auto it_capacity = capacitymap.find( std::make_pair( current_node, adjacent ) );
		int capacity = 0;
		if( capacitymap.end() != it_capacity ){
		    capacity = it_capacity->second;
		}
		auto it_flow = flowmap.find( std::make_pair( current_node, adjacent ) );
		int flow = 0;
		if( flowmap.end() != it_flow ){
		    flow = it_flow->second;
		}
		if( adjacent != node_src &&
		    travelled_nodes.end() == travelled_nodes.find( adjacent ) &&
		    capacity > flow ) //relaxation
		{
		    travelled_nodes.insert( adjacent );
		    adjacent->_pred = current_node;
		    queue_vertex.push( adjacent );
		}
	    }
	}
	if( nullptr == node_dest->_pred ){
	    return false;
	}
	return true;
    }
/**
 * Create element and insert it into the DOM,
 * potentially pushing it on the stack
 *
 * \param treebuilder  The treebuilder instance
 * \param tag          The element to insert
 * \param push         Whether to push the element onto the stack
 * \return HUBBUB_OK on success, appropriate error otherwise.
 */
hubbub_error insert_element(hubbub_treebuilder *treebuilder,
		const hubbub_tag *tag, bool push)
{
	element_type type = current_node(treebuilder);
	hubbub_error error;
	void *appended;

	if (treebuilder->context.in_table_foster &&
			(type == TABLE || type == TBODY || type == TFOOT ||
			type == THEAD || type == TR)) {
		error = aa_insert_into_foster_parent_new(treebuilder,
				HUBBUB_TOKEN_START_TAG,
				&appended);
	} else {
		error = treebuilder->tree_handler->append_child_new(
				treebuilder->tree_handler->ctx,
				treebuilder->context.element_stack[
					treebuilder->context.current_node].node,
				HUBBUB_TOKEN_START_TAG, &appended);
	}

	if (error != HUBBUB_OK)
		return error;

	error = treebuilder->tree_handler->set_name(
			treebuilder->tree_handler->ctx,
			appended,
			&tag->name);

	if (error != HUBBUB_OK)
		return error;

	error = treebuilder->tree_handler->add_attributes(
			treebuilder->tree_handler->ctx,
                        appended,
			tag->attributes,
			tag->n_attributes);

	if (error != HUBBUB_OK)
		return error;

	type = element_type_from_name(treebuilder, &tag->name);
	if (treebuilder->context.form_element != NULL &&
			is_form_associated(type)) {
		/* Consideration of @form is left to the client */
		error = treebuilder->tree_handler->form_associate(
				treebuilder->tree_handler->ctx,
				treebuilder->context.form_element,
				appended);
		if (error != HUBBUB_OK) {
			remove_node_from_dom(treebuilder, appended);

			return error;
		}
	}

	if (push) {
		error = element_stack_push(treebuilder,
				tag->ns, type, appended);
		if (error != HUBBUB_OK) {
			remove_node_from_dom(treebuilder, appended);

			return error;
		}
	}

	return HUBBUB_OK;
}
/**
 * Reconstruct the list of active formatting elements
 *
 * \param treebuilder  Treebuilder instance containing list
 * \return HUBBUB_OK on success, appropriate error otherwise.
 */
hubbub_error reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
{
	hubbub_error error = HUBBUB_OK;
	formatting_list_entry *entry, *initial_entry;
	uint32_t sp = treebuilder->context.current_node;

	if (treebuilder->context.formatting_list == NULL)
		return HUBBUB_OK;

	entry = treebuilder->context.formatting_list_end;

	/* Assumption: HTML and TABLE elements are not inserted into the list */
	if (is_scoping_element(entry->details.type) || entry->stack_index != 0)
		return HUBBUB_OK;

	while (entry->prev != NULL) {
		entry = entry->prev;

		if (is_scoping_element(entry->details.type) ||
				entry->stack_index != 0) {
			entry = entry->next;
			break;
		}
	}

	/* Save initial entry for later */
	initial_entry = entry;

	/* Process formatting list entries, cloning nodes and
	 * inserting them into the DOM and element stack */
	while (entry != NULL) {
		void *clone, *appended;
		bool foster;
		element_type type = current_node(treebuilder);

		error = treebuilder->tree_handler->clone_node(
				treebuilder->tree_handler->ctx,
				entry->details.node,
				false,
				&clone);
		if (error != HUBBUB_OK)
			goto cleanup;

		foster = treebuilder->context.in_table_foster &&
				(type == TABLE || type == TBODY ||
					type == TFOOT || type == THEAD ||
					type == TR);

		if (foster) {
			error = aa_insert_into_foster_parent(treebuilder,
					clone, &appended);
		} else {
			error = treebuilder->tree_handler->append_child(
					treebuilder->tree_handler->ctx,
					treebuilder->context.element_stack[
					treebuilder->context.current_node].node,
					clone,
					&appended);
		}

		if (error != HUBBUB_OK)
			goto cleanup;

		error = element_stack_push(treebuilder, entry->details.ns,
				entry->details.type, appended);
		if (error != HUBBUB_OK) {
			remove_node_from_dom(treebuilder, appended);

			goto cleanup;
		}

		entry = entry->next;
	}

	/* Now, replace the formatting list entries */
	for (entry = initial_entry; entry != NULL; entry = entry->next) {
		void *node;
		hubbub_ns prev_ns;
		element_type prev_type;
		void *prev_node;
		uint32_t prev_stack_index;

		node = treebuilder->context.element_stack[++sp].node;

		error = formatting_list_replace(treebuilder, entry,
				entry->details.ns, entry->details.type,
				node, sp,
				&prev_ns, &prev_type, &prev_node,
				&prev_stack_index);
		/* Cannot fail. Ensure this. */
		assert(error == HUBBUB_OK);
	}

	return HUBBUB_OK;

cleanup:
	/* An error occurred while cloning nodes and inserting them.
	 * We must restore the state on entry here. */
	while (treebuilder->context.current_node > sp) {
		hubbub_ns ns;
		element_type type;
		void *node;

		element_stack_pop(treebuilder, &ns, &type, &node);

		remove_node_from_dom(treebuilder, node);
	}

	return error;
}