<commit_before>//
//  ex9_32.cpp
//  Exercise 9.32
//
//  Created by pezy on 12/3/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  @Brief  Assuming vi is a container of ints that includes even and odd values,
//          predict the behavior of the following loop.
//          After you've analyzed this loop, write a program to test whether your expectations were correct.
//  @Answer "infinite loop". Casue the `++iter` out of the `while` loop. But even through add brackets it is still infinite loop.
//          Fixed following.

#include <iostream>
#include <vector>

using std::vector; using std::cout; using std::endl;

int main()
{
    vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
    auto iter = vi.begin();
    while (iter != vi.end())
    {
        if (*iter % 2)
            iter = vi.insert(iter, *iter++);
        ++iter;
    }

    for (auto i : vi)
        cout << i << " ";

    return 0;
}

<commit_msg>fixed #136<commit_after>//
//  ex9_32.cpp
//  Exercise 9.32
//
//  Created by pezy on 12/3/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  @Brief  Assuming vi is a container of ints that includes even and odd values,
//          predict the behavior of the following loop.
//          After you've analyzed this loop, write a program to test whether your expectations were correct.
//
//			iter = vi.begin();
//			while (iter != vi.end())
//				if (*iter % 2)
//					iter = vi.insert(iter, *iter);
//				++iter;
//
//  @Answer "infinite loop". Casue the `++iter` out of the `while` loop. But even through add brackets it is still infinite loop.
//          Fixed following.

#include <iostream>
using std::cout; using std::endl;

#include <vector>
using std::vector;

int main()
{
	vector<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = vi.begin();
	while (iter != vi.end()) {
		if (*iter % 2) {
			iter = vi.insert(iter, *iter);
			++iter;
		}
		++iter;
	}

	for (auto i : vi)
		cout << i << " ";

	return 0;
}

<|endoftext|>


<commit_before>#include "Octree.h"
#include <algorithm>
#include <fstream>
#include <iostream>

void Octree::build(const int depth, const int full_layer,
	const int npt, const float* bbmin, const float* bbmax,
	const float* pts, const float* normals, const int* labels)
{
	// init
	full_layer_ = full_layer < 1 ? 1 : full_layer;
	depth_ = full_layer < depth ? depth : full_layer;
	set_bbox(bbmin, bbmax);
	children_.clear();
	children_.resize(depth + 1);
	keys_.clear();
	keys_.resize(depth + 1);

	// preprocess, get key and sort
	vector<uint32> node_keys, sorted_idx;
	vector<float> weights;
	processing_points(node_keys, sorted_idx, weights, pts, npt);

	// get unique key
	vector<uint32> unique_idx;
	unique_key(node_keys, unique_idx);

	// build tree
	// build layer 0 to full_layer_depth_
	for (int curr_depth = 0; curr_depth <= full_layer_; curr_depth++)
	{
		vector<int>& children = children_[curr_depth];
		vector<uint32>& keys = keys_[curr_depth];

		int n = 1 << 3 * curr_depth;
		keys.resize(n, -1); children.resize(n, -1);
		for (int i = 0; i < n; i++)
		{
			keys[i] = i;

			if (curr_depth != full_layer_)
			{
				children[i] = i;
			}
		}

	}
	// build layers
	for (int curr_depth = depth_; curr_depth > full_layer_; --curr_depth)
	{
		// compute parent key, i.e. keys of layer (curr_depth -1)
		int n = node_keys.size();
		vector<uint32> parent_keys(n);
		#pragma omp parallel for
		for (int i = 0; i < n; i++)
		{
			parent_keys[i] = node_keys[i] >> 3;
		}

		// compute unique parent key
		vector<uint32> parent_pidx;
		unique_key(parent_keys, parent_pidx);

		// augment children keys and create nodes
		int np = parent_keys.size();
		int nch = np << 3;
		vector<int>& children = children_[curr_depth];
		vector<uint32>& keys = keys_[curr_depth];

		children.resize(nch, -1);
		keys.resize(nch, 0);

		for (int i = 0; i < nch; i++)
		{
			int j = i >> 3;
			keys[i] = (parent_keys[j] << 3) | (i % 8);
		}

		// compute base address for each node
		vector<uint32> addr(nch);
		for (int i = 0; i < np; i++)
		{
			for (uint32 j = parent_pidx[i]; j < parent_pidx[i + 1]; j++)
			{
				addr[j] = i << 3;
			}
		}

		// set children pointer and parent pointer
		#pragma omp parallel for
		for (int i = 0; i < n; i++)
		{
			// address
			uint32 k = (node_keys[i] & 7u) | addr[i];

			// set children pointer for layer curr_depth
			children[k] = i;
		}

		// save data and prepare for the following iteration
		node_keys.swap(parent_keys);
	}
	// set the children for the layer full_layer_depth_
	// Now the node_keys are the key for full_layer
	if (depth_ > full_layer_)
	{
		for (int i = 0; i < node_keys.size(); i++)
		{
			uint32 j = node_keys[i];
			children_[full_layer_][j] = i;
		}
	}

	// splat normal (according to Ps, Ns, pnum, pidx)
 	splat_normal(normals, weights, sorted_idx, unique_idx, children_[depth_]);
	if(labels != nullptr)
		splat_label(labels, weights, sorted_idx, unique_idx, children_[depth_]);
 }

bool Octree::save(std::string& filename)
{
	std::ofstream outfile(filename, std::ios::binary);
	if (!outfile) return false;

	vector<int> node_num;
	for (auto& keys : keys_)
	{
		node_num.push_back(keys.size());
	}

	vector<int> node_num_accu(depth_ + 2, 0);
	for (int i = 1; i < depth_ + 2; ++i)
	{
		node_num_accu[i] = node_num_accu[i - 1] + node_num[i - 1];
	}
	int total_node_num = node_num_accu[depth_ + 1];
	int final_node_num = node_num[depth_];

	// calc key
	std::vector<int> key(total_node_num), children(total_node_num);
	int idx = 0;
	for (int d = 0; d <= depth_; ++d)
	{
		vector<uint32>& keys = keys_[d];
		for (int i =0; i < keys.size(); ++i)
		{
			// calc point
			uint32 k = keys[i], pt[3];
			compute_pt(pt, k, d);

			// compress
			unsigned char* ptr = reinterpret_cast<unsigned char*>(&key[idx]);
			ptr[0] = static_cast<unsigned char>(pt[0]);
			ptr[1] = static_cast<unsigned char>(pt[1]);
			ptr[2] = static_cast<unsigned char>(pt[2]);
			ptr[3] = static_cast<unsigned char>(d);

			// children
			children[idx] = children_[d][i];

			// update index
			idx++;
		}
	}

	// write
	outfile.write((char*)&total_node_num, sizeof(int));
	outfile.write((char*)&final_node_num, sizeof(int));
	outfile.write((char*)&depth_, sizeof(int));
	outfile.write((char*)&full_layer_, sizeof(int));
	outfile.write((char*)node_num.data(), sizeof(int)*(depth_ + 1));
	outfile.write((char*)node_num_accu.data(), sizeof(int)*(depth_ + 2));
	outfile.write((char*)key.data(), sizeof(int)*total_node_num);
	outfile.write((char*)children.data(), sizeof(int)*total_node_num);
	outfile.write((char*)data_.data(), sizeof(float) * 3 * final_node_num);
	if (!label_.empty())
	{
		outfile.write((char*)label_.data(), label_.size()*sizeof(int));
	}
	outfile.close();

	return true;
}

void Octree::set_bbox(const float* bbmin, const float* bbmax)
{
	float center[3];
	scale_ = -1.0e20;
	for (int i = 0; i < 3; ++i)
	{
		float dis = bbmax[i] - bbmin[i];
		if (dis > scale_) scale_ = dis;
		center[i] = (bbmin[i] + bbmax[i])*0.5;
	}

	// set the bounding box and place the object in the center
	float radius = scale_ * 0.5;
	for (int i = 0; i < 3; ++i)
	{
		bbmax_[i] = center[i] + radius;
		bbmin_[i] = center[i] - radius;
	}
}

void Octree::processing_points(vector<uint32>& sorted_keys,
	vector<uint32>& sorted_idx,	vector<float>& weights,
	const float* pts, const int npt)
{
	sorted_keys.resize(npt);
	sorted_idx.resize(npt);
	weights.resize(npt);
	vector<uint64> code(npt);
	const float mul = float(1 << depth_) / scale_;
	#pragma omp parallel for
	for (int i = 0; i < npt; i++)
	{
		// normalize coordinate
		uint32 pt[3];
		weights[i] = 1.0f;
		for (int j = 0; j < 3; j++)
		{
			float tmp = (pts[i * 3 + j] - bbmin_[j]) * mul;
			pt[j] = tmp;
			weights[i] *= bspline(float(pt[j]) + 0.5f - tmp);
		}

		// calc key
		uint32 key;
		compute_key(key, pt, depth_);

		// generate code
		uint32* ptr = (uint32*)(&code[i]);
		ptr[0] = i;
		ptr[1] = key;
	}

	// sort all sample points
	std::sort(code.begin(), code.end());

	// unpack the code
	#pragma omp parallel for
	for (int i = 0; i < npt; i++)
	{
		uint32* ptr = (uint32*)(&code[i]);
		sorted_idx[i] = ptr[0];
		sorted_keys[i] = ptr[1];
	}
}

void Octree::unique_key(vector<uint32>& keys, vector<uint32>& idx)
{
	// init
	idx.clear();
	idx.push_back(0);

	// unique
	int n = keys.size(), j = 1;
	for (int i = 1; i < n; i++)
	{
		if (keys[i] != keys[i - 1])
		{
			idx.push_back(i);
			keys[j++] = keys[i];
		}
	}

	keys.resize(j);
	idx.push_back(n);
}

inline void Octree::compute_key(uint32& key, const uint32* pt, const int depth)
{
	key = 0;
	for (int i = 0; i < depth; i++)
	{
		uint32 mask = 1u << i;
		for (int j = 0; j < 3; j++)
		{
			key |= (pt[j] & mask) << (2 * i + 2 - j);
		}
	}
}

inline void Octree::compute_pt(uint32* pt, const uint32& key, const int depth)
{
	// init
	for (int i = 0; i < 3; pt[i++] = 0u);

	// convert
	for (int i = 0; i < depth; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			// bit mask
			uint32 mask = 1u << (3 * i + 2 - j);
			// put the bit to position i
			pt[j] |= (key & mask) >> (2 * i + 2 - j);
		}
	}
}

inline float Octree::bspline(float x)
{
	if (x < -1.5f)
	{
		return 0;
	}
	else if (x < -0.5f)
	{
		return 0.5f * (x + 1.5f) * (x + 1.5f);
	}
	else if ( x < 0.5f)
	{
		return 0.75f - x * x;
	}
	else if (x <= 1.5f)
	{
		return 0.5f * (x - 1.5f) * (x - 1.5f);
	}
	else
	{
		return 0;
	}
}

void Octree::splat_normal(const float* normals, const vector<float>& weights,
	const vector<uint32>& sorted_idx, const vector<uint32>& unique_idx,
	const vector<int>& children)
{
	int n = children.size();
	data_.resize(3 * n);
	#pragma omp parallel for
	for (int i = 0; i < n; i++)
	{
		int t = children[i];
		vector<float> Nw(3, 0.0);
		if (t != -1)
		{
			for (int j = unique_idx[t]; j < unique_idx[t + 1]; j++)
			{
				int h = sorted_idx[j];
				Nw[0] += weights[h] * normals[3 * h];
				Nw[1] += weights[h] * normals[3 * h + 1];
				Nw[2] += weights[h] * normals[3 * h + 2];
			}

			float len = sqrt(Nw[0] * Nw[0] + Nw[1] * Nw[1] + Nw[2] * Nw[2]);
			if (len < ESP) len = ESP;

			Nw[0] /= len;
			Nw[1] /= len;
			Nw[2] /= len;
		}

		data_[i] = Nw[0];
		data_[n + i] = Nw[1];
		data_[2 * n + i] = Nw[2];
	}
}

void Octree::splat_label(const int* labels, const vector<float>& weights,
	const vector<uint32>& sorted_idx, const vector<uint32>& unique_idx,
	const vector<int>& children)
{
	int n = children_.size();
	int nl = *std::max_element(labels, labels + n) + 1;

	label_.clear();
	label_.resize(n, -1);
	#pragma omp parallel for
	for (int i = 0; i < n; i++)
	{
		int t = children[i];
		if (t == -1) continue;
		vector<float> Lw(nl, 0);

		for (int j = unique_idx[t]; j < unique_idx[t + 1]; j++)
		{
			int h = sorted_idx[j];
			Lw[labels[h]] += weights[h];
		}

		label_[i] = 0;
		float v = Lw[0];
		for (int j = 1; j < nl; ++j)
		{
			if (Lw[j] > v)
			{
				v = Lw[j];
				label_[i] = j;
			}
		}
	}
}
<commit_msg>Remove the BUG in the Octree::splat_label<commit_after>#include "Octree.h"
#include <algorithm>
#include <fstream>
#include <iostream>

void Octree::build(const int depth, const int full_layer,
	const int npt, const float* bbmin, const float* bbmax,
	const float* pts, const float* normals, const int* labels)
{
	// init
	full_layer_ = full_layer < 1 ? 1 : full_layer;
	depth_ = full_layer < depth ? depth : full_layer;
	set_bbox(bbmin, bbmax);
	children_.clear();
	children_.resize(depth + 1);
	keys_.clear();
	keys_.resize(depth + 1);

	// preprocess, get key and sort
	vector<uint32> node_keys, sorted_idx;
	vector<float> weights;
	processing_points(node_keys, sorted_idx, weights, pts, npt);

	// get unique key
	vector<uint32> unique_idx;
	unique_key(node_keys, unique_idx);

	// build tree
	// build layer 0 to full_layer_depth_
	for (int curr_depth = 0; curr_depth <= full_layer_; curr_depth++)
	{
		vector<int>& children = children_[curr_depth];
		vector<uint32>& keys = keys_[curr_depth];

		int n = 1 << 3 * curr_depth;
		keys.resize(n, -1); children.resize(n, -1);
		for (int i = 0; i < n; i++)
		{
			keys[i] = i;

			if (curr_depth != full_layer_)
			{
				children[i] = i;
			}
		}

	}
	// build layers
	for (int curr_depth = depth_; curr_depth > full_layer_; --curr_depth)
	{
		// compute parent key, i.e. keys of layer (curr_depth -1)
		int n = node_keys.size();
		vector<uint32> parent_keys(n);
		#pragma omp parallel for
		for (int i = 0; i < n; i++)
		{
			parent_keys[i] = node_keys[i] >> 3;
		}

		// compute unique parent key
		vector<uint32> parent_pidx;
		unique_key(parent_keys, parent_pidx);

		// augment children keys and create nodes
		int np = parent_keys.size();
		int nch = np << 3;
		vector<int>& children = children_[curr_depth];
		vector<uint32>& keys = keys_[curr_depth];

		children.resize(nch, -1);
		keys.resize(nch, 0);

		for (int i = 0; i < nch; i++)
		{
			int j = i >> 3;
			keys[i] = (parent_keys[j] << 3) | (i % 8);
		}

		// compute base address for each node
		vector<uint32> addr(nch);
		for (int i = 0; i < np; i++)
		{
			for (uint32 j = parent_pidx[i]; j < parent_pidx[i + 1]; j++)
			{
				addr[j] = i << 3;
			}
		}

		// set children pointer and parent pointer
		#pragma omp parallel for
		for (int i = 0; i < n; i++)
		{
			// address
			uint32 k = (node_keys[i] & 7u) | addr[i];

			// set children pointer for layer curr_depth
			children[k] = i;
		}

		// save data and prepare for the following iteration
		node_keys.swap(parent_keys);
	}
	// set the children for the layer full_layer_depth_
	// Now the node_keys are the key for full_layer
	if (depth_ > full_layer_)
	{
		for (int i = 0; i < node_keys.size(); i++)
		{
			uint32 j = node_keys[i];
			children_[full_layer_][j] = i;
		}
	}

	// splat normal (according to Ps, Ns, pnum, pidx)
 	splat_normal(normals, weights, sorted_idx, unique_idx, children_[depth_]);
	if(labels != nullptr)
		splat_label(labels, weights, sorted_idx, unique_idx, children_[depth_]);
 }

bool Octree::save(std::string& filename)
{
	std::ofstream outfile(filename, std::ios::binary);
	if (!outfile) return false;

	vector<int> node_num;
	for (auto& keys : keys_)
	{
		node_num.push_back(keys.size());
	}

	vector<int> node_num_accu(depth_ + 2, 0);
	for (int i = 1; i < depth_ + 2; ++i)
	{
		node_num_accu[i] = node_num_accu[i - 1] + node_num[i - 1];
	}
	int total_node_num = node_num_accu[depth_ + 1];
	int final_node_num = node_num[depth_];

	// calc key
	std::vector<int> key(total_node_num), children(total_node_num);
	int idx = 0;
	for (int d = 0; d <= depth_; ++d)
	{
		vector<uint32>& keys = keys_[d];
		for (int i =0; i < keys.size(); ++i)
		{
			// calc point
			uint32 k = keys[i], pt[3];
			compute_pt(pt, k, d);

			// compress
			unsigned char* ptr = reinterpret_cast<unsigned char*>(&key[idx]);
			ptr[0] = static_cast<unsigned char>(pt[0]);
			ptr[1] = static_cast<unsigned char>(pt[1]);
			ptr[2] = static_cast<unsigned char>(pt[2]);
			ptr[3] = static_cast<unsigned char>(d);

			// children
			children[idx] = children_[d][i];

			// update index
			idx++;
		}
	}

	// write
	outfile.write((char*)&total_node_num, sizeof(int));
	outfile.write((char*)&final_node_num, sizeof(int));
	outfile.write((char*)&depth_, sizeof(int));
	outfile.write((char*)&full_layer_, sizeof(int));
	outfile.write((char*)node_num.data(), sizeof(int)*(depth_ + 1));
	outfile.write((char*)node_num_accu.data(), sizeof(int)*(depth_ + 2));
	outfile.write((char*)key.data(), sizeof(int)*total_node_num);
	outfile.write((char*)children.data(), sizeof(int)*total_node_num);
	outfile.write((char*)data_.data(), sizeof(float) * 3 * final_node_num);
	if (!label_.empty())
	{
		outfile.write((char*)label_.data(), label_.size()*sizeof(int));
	}
	outfile.close();

	return true;
}

void Octree::set_bbox(const float* bbmin, const float* bbmax)
{
	float center[3];
	scale_ = -1.0e20;
	for (int i = 0; i < 3; ++i)
	{
		float dis = bbmax[i] - bbmin[i];
		if (dis > scale_) scale_ = dis;
		center[i] = (bbmin[i] + bbmax[i])*0.5;
	}

	// set the bounding box and place the object in the center
	float radius = scale_ * 0.5;
	for (int i = 0; i < 3; ++i)
	{
		bbmax_[i] = center[i] + radius;
		bbmin_[i] = center[i] - radius;
	}
}

void Octree::processing_points(vector<uint32>& sorted_keys,
	vector<uint32>& sorted_idx,	vector<float>& weights,
	const float* pts, const int npt)
{
	sorted_keys.resize(npt);
	sorted_idx.resize(npt);
	weights.resize(npt);
	vector<uint64> code(npt);
	const float mul = float(1 << depth_) / scale_;
	#pragma omp parallel for
	for (int i = 0; i < npt; i++)
	{
		// normalize coordinate
		uint32 pt[3];
		weights[i] = 1.0f;
		for (int j = 0; j < 3; j++)
		{
			float tmp = (pts[i * 3 + j] - bbmin_[j]) * mul;
			pt[j] = tmp;
			weights[i] *= bspline(float(pt[j]) + 0.5f - tmp);
		}

		// calc key
		uint32 key;
		compute_key(key, pt, depth_);

		// generate code
		uint32* ptr = (uint32*)(&code[i]);
		ptr[0] = i;
		ptr[1] = key;
	}

	// sort all sample points
	std::sort(code.begin(), code.end());

	// unpack the code
	#pragma omp parallel for
	for (int i = 0; i < npt; i++)
	{
		uint32* ptr = (uint32*)(&code[i]);
		sorted_idx[i] = ptr[0];
		sorted_keys[i] = ptr[1];
	}
}

void Octree::unique_key(vector<uint32>& keys, vector<uint32>& idx)
{
	// init
	idx.clear();
	idx.push_back(0);

	// unique
	int n = keys.size(), j = 1;
	for (int i = 1; i < n; i++)
	{
		if (keys[i] != keys[i - 1])
		{
			idx.push_back(i);
			keys[j++] = keys[i];
		}
	}

	keys.resize(j);
	idx.push_back(n);
}

inline void Octree::compute_key(uint32& key, const uint32* pt, const int depth)
{
	key = 0;
	for (int i = 0; i < depth; i++)
	{
		uint32 mask = 1u << i;
		for (int j = 0; j < 3; j++)
		{
			key |= (pt[j] & mask) << (2 * i + 2 - j);
		}
	}
}

inline void Octree::compute_pt(uint32* pt, const uint32& key, const int depth)
{
	// init
	for (int i = 0; i < 3; pt[i++] = 0u);

	// convert
	for (int i = 0; i < depth; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			// bit mask
			uint32 mask = 1u << (3 * i + 2 - j);
			// put the bit to position i
			pt[j] |= (key & mask) >> (2 * i + 2 - j);
		}
	}
}

inline float Octree::bspline(float x)
{
	if (x < -1.5f)
	{
		return 0;
	}
	else if (x < -0.5f)
	{
		return 0.5f * (x + 1.5f) * (x + 1.5f);
	}
	else if ( x < 0.5f)
	{
		return 0.75f - x * x;
	}
	else if (x <= 1.5f)
	{
		return 0.5f * (x - 1.5f) * (x - 1.5f);
	}
	else
	{
		return 0;
	}
}

void Octree::splat_normal(const float* normals, const vector<float>& weights,
	const vector<uint32>& sorted_idx, const vector<uint32>& unique_idx,
	const vector<int>& children)
{
	int n = children.size();
	data_.resize(3 * n);
	#pragma omp parallel for
	for (int i = 0; i < n; i++)
	{
		int t = children[i];
		vector<float> Nw(3, 0.0);
		if (t != -1)
		{
			for (int j = unique_idx[t]; j < unique_idx[t + 1]; j++)
			{
				int h = sorted_idx[j];
				Nw[0] += weights[h] * normals[3 * h];
				Nw[1] += weights[h] * normals[3 * h + 1];
				Nw[2] += weights[h] * normals[3 * h + 2];
			}

			float len = sqrt(Nw[0] * Nw[0] + Nw[1] * Nw[1] + Nw[2] * Nw[2]);
			if (len < ESP) len = ESP;

			Nw[0] /= len;
			Nw[1] /= len;
			Nw[2] /= len;
		}

		data_[i] = Nw[0];
		data_[n + i] = Nw[1];
		data_[2 * n + i] = Nw[2];
	}
}

void Octree::splat_label(const int* labels, const vector<float>& weights,
	const vector<uint32>& sorted_idx, const vector<uint32>& unique_idx,
	const vector<int>& children)
{
	int n = children.size();
	int nl = *std::max_element(labels, labels + n) + 1;

	label_.clear();
	label_.resize(n, -1);
	#pragma omp parallel for
	for (int i = 0; i < n; i++)
	{
		int t = children[i];
		if (t == -1) continue;
		vector<float> Lw(nl, 0);

		for (int j = unique_idx[t]; j < unique_idx[t + 1]; j++)
		{
			int h = sorted_idx[j];
			Lw[labels[h]] += weights[h];
		}

		label_[i] = 0;
		float v = Lw[0];
		for (int j = 1; j < nl; ++j)
		{
			if (Lw[j] > v)
			{
				v = Lw[j];
				label_[i] = j;
			}
		}
	}
}
<|endoftext|>


<commit_before>#include "auto/DriveCommand.h"

DriveCommand::DriveCommand(Drive* drive, double distance) {
	drive_ = drive;
	distanceGoal_ = distance;
	//set constanst for tuning here
	leftPid_ = new Pid(.1, 0, 0);
	leftPid_->SetGoal(distanceGoal_);
	rightPid_ = new Pid(.1, 0, 0);
	rightPid_->SetGoal(distanceGoal_);
	distanceGoal_ = distance;
}

void DriveCommand::Initialize() {
	drive_->ResetEncoders();
}

bool DriveCommand::Run() {
	double currLeftDist = drive_->GetLeftEncoderDistance();
	double currRightDist = drive_->GetRightEncoderDistance();
	//if goal reached, return true so current command can be popped off queue
	if(currLeftDist == distanceGoal_ && currRightDist == distanceGoal_) {
		return true;
	}
	//get PID feedback and send back to motors
	double leftPwr = leftPid_->Update(currLeftDist);
	double rightPwr = rightPid_->Update(currRightDist);
	drive_->SetLinearPower(leftPwr, rightPwr);
	//indicates that goal is not reached
	return false;
}

DriveCommand::~DriveCommand() {
	delete leftPid_;
	delete rightPid_;
	delete drive_;
}
<commit_msg>Style fixes<commit_after>#include "auto/DriveCommand.h"

DriveCommand::DriveCommand(Drive* drive, double distance) {
  drive_ = drive;
  distanceGoal_ = distance;
  // set constants for tuning here
  leftPid_ = new Pid(.1, 0, 0);
  leftPid_->SetGoal(distanceGoal_);
  rightPid_ = new Pid(.1, 0, 0);
  rightPid_->SetGoal(distanceGoal_);
  distanceGoal_ = distance;
}

void DriveCommand::Initialize() {
  drive_->ResetEncoders();
}

bool DriveCommand::Run() {
  double currLeftDist = drive_->GetLeftEncoderDistance();
  double currRightDist = drive_->GetRightEncoderDistance();
  // if goal reached, return true so current command can be popped off queue
  if(currLeftDist == distanceGoal_ && currRightDist == distanceGoal_) {
    return true;
  }
  // get PID feedback and send back to motors
  double leftPwr = leftPid_->Update(currLeftDist);
  double rightPwr = rightPid_->Update(currRightDist);
  drive_->SetLinearPower(leftPwr, rightPwr);
  // indicates that goal is not reached
  return false;
}

DriveCommand::~DriveCommand() {
  delete leftPid_;
  delete rightPid_;
  delete drive_;
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#include "itkProcessObject.h"
#include "itkSmartPointerForwardReference.txx"
#include "itkRealTimeClock.h"
#include "itkTemporalDataObject.h"

// Manual instantiation is necessary to prevent link errors
template class itk::SmartPointerForwardReference< itk::ProcessObject >;

namespace itk
{

//----------------------------------------------------------------------------
TemporalDataObject::TemporalDataObject()
  : m_LargestPossibleTemporalRegion(),
    m_RequestedTemporalRegion(),
    m_BufferedTemporalRegion(),
    m_TemporalUnit(Frame)
{
  m_DataObjectBuffer = BufferType::New();
}

//----------------------------------------------------------------------------
TemporalDataObject
::~TemporalDataObject()
{}

//----------------------------------------------------------------------------
const TemporalDataObject::TemporalRegionType
TemporalDataObject
::GetUnbufferedRequestedTemporalRegion()
{
  // Get the start and end of the buffered and requested temporal regions
  unsigned long reqStart = m_RequestedTemporalRegion.GetFrameStart();
  unsigned long reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
                          m_RequestedTemporalRegion.GetFrameDuration() - 1;
  unsigned long bufStart = m_BufferedTemporalRegion.GetFrameStart();
  unsigned long bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
                          m_BufferedTemporalRegion.GetFrameDuration() - 1;

  //DEBUG
  std::cout << "req start: " << reqStart << " req end: " << reqEnd << std::endl;
  std::cout << "buf start: " << bufStart << " buf end: " << bufEnd << std::endl;

  // Handle case with unbuffered frames at beginning and end
  if (reqStart < bufStart && reqEnd > bufEnd)
    {
    itkDebugMacro(<< "Unbuffered frames at beginning and end. Returning entire "
                  << "requested region as unbuffered");
    return this->m_RequestedTemporalRegion;
    }

  // Handle case with unbuffered frames at end -- TODO: FIX FOR REAL TIME!!!!!
  else if(reqEnd > bufEnd)
    {
    TemporalRegionType out;
    out.SetFrameStart(bufEnd + 1);
    out.SetFrameDuration(reqEnd - bufEnd);
    return out;
    }

  // Handle case with unbuffered frames at beginning -- TODO: FIX FOR REAL TIME!!!!!
  else if(reqStart < bufStart)
    {
    TemporalRegionType out;
    out.SetFrameStart(reqStart);
    out.SetFrameDuration(bufStart - reqStart);
    return out;
    }

  // Otherwise, nothing unbuffered
  else
    {
    TemporalRegionType out;
    out.SetFrameStart(0);
    out.SetFrameDuration(0);
    return out;
    }

}

//----------------------------------------------------------------------------
void
TemporalDataObject
::SetRequestedRegionToLargestPossibleRegion()
{
  this->SetRequestedTemporalRegion( this->GetLargestPossibleTemporalRegion() );
}

//----------------------------------------------------------------------------
bool
TemporalDataObject
::RequestedRegionIsOutsideOfTheBufferedRegion()
{
  bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() <
    m_BufferedTemporalRegion.GetFrameStart();
  frameFlag |= m_RequestedTemporalRegion.GetFrameDuration() >
    m_BufferedTemporalRegion.GetFrameDuration();
  bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() <
    m_BufferedTemporalRegion.GetRealStart();
  realTimeFlag |= m_RequestedTemporalRegion.GetRealDuration() >
    m_BufferedTemporalRegion.GetRealDuration();
  switch( m_TemporalUnit )
    {
    case Frame:
      {
      return frameFlag;
      }
    case RealTime:
      {
      return realTimeFlag;
      }
    case FrameAndRealTime:
      {
      return frameFlag || realTimeFlag;
      }
    default:
      itkExceptionMacro( << "itk::TemporalDataObject::"
                         << "RequestedRegionIsOutsideOfTheBufferedRegion() "
                         << "Invalid Temporal Unit" );
      return true;
    }
}

//----------------------------------------------------------------------------
bool
TemporalDataObject
::VerifyRequestedRegion()
{
  bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() >=
    m_LargestPossibleTemporalRegion.GetFrameStart();
  frameFlag &= m_RequestedTemporalRegion.GetFrameDuration() <=
    m_LargestPossibleTemporalRegion.GetFrameDuration();
  bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() >=
    m_LargestPossibleTemporalRegion.GetRealStart();
  realTimeFlag &= m_RequestedTemporalRegion.GetRealDuration() <=
    m_LargestPossibleTemporalRegion.GetRealDuration();
  switch( m_TemporalUnit )
    {
    case Frame:
      {
      return frameFlag;
      }
    case RealTime:
      {
      return realTimeFlag;
      }
    case FrameAndRealTime:
      {
      return frameFlag && realTimeFlag;
      }
    default:
      itkExceptionMacro( << "itk::TemporalDataObject::VerifyRequestedRegion() "
                         << "Invalid Temporal Unit" );
      return false;
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::CopyInformation(const DataObject *data)
{
  // Standard call to the superclass' method
  Superclass::CopyInformation(data);

  const TemporalDataObject* temporalData;
  temporalData = dynamic_cast< const TemporalDataObject* >( data );

  if ( temporalData )
    {
    // Copy the meta data for this data type
    this->SetLargestPossibleTemporalRegion(
      temporalData->GetLargestPossibleTemporalRegion() );
    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->CopyInformation(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject::CopyInformation() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::Graft(const DataObject *data)
{
  const TemporalDataObject* temporalData;

  temporalData = dynamic_cast< const TemporalDataObject* >( data );

  if( temporalData )
    {
    // Copy the meta-information
    this->CopyInformation( temporalData );

    this->SetBufferedTemporalRegion(
      temporalData->GetBufferedTemporalRegion() );
    this->SetRequestedTemporalRegion(
      temporalData->GetRequestedTemporalRegion() );

    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->Graft(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject::Graft() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::SetRequestedRegion(DataObject *data)
{
  TemporalDataObject *temporalData;

  temporalData = dynamic_cast< TemporalDataObject * >( data );

  if ( temporalData )
    {
    // only copy the RequestedTemporalRegion if the parameter object is
    // a temporal data object
    this->SetRequestedTemporalRegion(
      temporalData->GetRequestedTemporalRegion() );
    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->SetRequestedRegion(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject:SetRequestedRegion() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "Data Object Buffer: " << m_DataObjectBuffer.GetPointer()
     << std::endl;
  os << indent << "LargestPossibleTemporalRegion: " << std::endl;
  this->GetLargestPossibleTemporalRegion().Print( os,
                                                  indent.GetNextIndent() );

  os << indent << "BufferedTemporalRegion: " << std::endl;
  this->GetBufferedTemporalRegion().Print( os, indent.GetNextIndent() );

  os << indent << "RequestedTemporalRegion: " << std::endl;
  this->GetRequestedTemporalRegion().Print( os, indent.GetNextIndent() );
}

} // end namespace itk
<commit_msg>ENH: Fix calculations for unbuffered region<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
/*=========================================================================
 *
 *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
 *
 *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 *
 *  For complete copyright, license and disclaimer of warranty information
 *  please refer to the NOTICE file at the top of the ITK source tree.
 *
 *=========================================================================*/
#include "itkProcessObject.h"
#include "itkSmartPointerForwardReference.txx"
#include "itkRealTimeClock.h"
#include "itkTemporalDataObject.h"

// Manual instantiation is necessary to prevent link errors
template class itk::SmartPointerForwardReference< itk::ProcessObject >;

namespace itk
{

//----------------------------------------------------------------------------
TemporalDataObject::TemporalDataObject()
  : m_LargestPossibleTemporalRegion(),
    m_RequestedTemporalRegion(),
    m_BufferedTemporalRegion(),
    m_TemporalUnit(Frame)
{
  m_DataObjectBuffer = BufferType::New();
}

//----------------------------------------------------------------------------
TemporalDataObject
::~TemporalDataObject()
{}

//----------------------------------------------------------------------------
const TemporalDataObject::TemporalRegionType
TemporalDataObject
::GetUnbufferedRequestedTemporalRegion()
{
  // If nothing is buffered or nothing is requested, just return the entire request
  if (m_BufferedTemporalRegion.GetFrameDuration() == 0 ||
      m_RequestedTemporalRegion.GetFrameDuration() == 0)
    {
    return m_RequestedTemporalRegion;
    }

  // Get the start and end of the buffered and requested temporal regions
  unsigned long reqStart = m_RequestedTemporalRegion.GetFrameStart();
  unsigned long reqEnd = m_RequestedTemporalRegion.GetFrameStart() +
                          m_RequestedTemporalRegion.GetFrameDuration() - 1;

  unsigned long bufStart = m_BufferedTemporalRegion.GetFrameStart();
  unsigned long bufEnd = m_BufferedTemporalRegion.GetFrameStart() +
                          m_BufferedTemporalRegion.GetFrameDuration() - 1;

  // If the request starts after the buffered region, return the whole request
  if (reqStart > bufEnd)
    {
    return m_RequestedTemporalRegion;
    }

  // Handle case with unbuffered frames at beginning and end
  if (reqStart < bufStart && reqEnd > bufEnd)
    {
    itkDebugMacro(<< "Unbuffered frames at beginning and end. Returning entire "
                  << "requested region as unbuffered");
    return this->m_RequestedTemporalRegion;
    }

  // Handle case with unbuffered frames at end -- TODO: FIX FOR REAL TIME!!!!!
  else if(reqEnd > bufEnd)
    {
    TemporalRegionType out;
    out.SetFrameStart(bufEnd + 1);
    out.SetFrameDuration(reqEnd - bufEnd);
    return out;
    }

  // Handle case with unbuffered frames at beginning -- TODO: FIX FOR REAL TIME!!!!!
  else if(reqStart < bufStart)
    {
    TemporalRegionType out;
    out.SetFrameStart(reqStart);
    out.SetFrameDuration(bufStart - reqStart);
    return out;
    }

  // Otherwise, nothing unbuffered
  else
    {
    TemporalRegionType out;
    out.SetFrameStart(0);
    out.SetFrameDuration(0);
    return out;
    }

}

//----------------------------------------------------------------------------
void
TemporalDataObject
::SetRequestedRegionToLargestPossibleRegion()
{
  this->SetRequestedTemporalRegion( this->GetLargestPossibleTemporalRegion() );
}

//----------------------------------------------------------------------------
bool
TemporalDataObject
::RequestedRegionIsOutsideOfTheBufferedRegion()
{
  bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() <
    m_BufferedTemporalRegion.GetFrameStart();
  frameFlag |= m_RequestedTemporalRegion.GetFrameDuration() >
    m_BufferedTemporalRegion.GetFrameDuration();
  bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() <
    m_BufferedTemporalRegion.GetRealStart();
  realTimeFlag |= m_RequestedTemporalRegion.GetRealDuration() >
    m_BufferedTemporalRegion.GetRealDuration();
  switch( m_TemporalUnit )
    {
    case Frame:
      {
      return frameFlag;
      }
    case RealTime:
      {
      return realTimeFlag;
      }
    case FrameAndRealTime:
      {
      return frameFlag || realTimeFlag;
      }
    default:
      itkExceptionMacro( << "itk::TemporalDataObject::"
                         << "RequestedRegionIsOutsideOfTheBufferedRegion() "
                         << "Invalid Temporal Unit" );
      return true;
    }
}

//----------------------------------------------------------------------------
bool
TemporalDataObject
::VerifyRequestedRegion()
{
  bool frameFlag = m_RequestedTemporalRegion.GetFrameStart() >=
    m_LargestPossibleTemporalRegion.GetFrameStart();
  frameFlag &= m_RequestedTemporalRegion.GetFrameDuration() <=
    m_LargestPossibleTemporalRegion.GetFrameDuration();
  bool realTimeFlag = m_RequestedTemporalRegion.GetRealStart() >=
    m_LargestPossibleTemporalRegion.GetRealStart();
  realTimeFlag &= m_RequestedTemporalRegion.GetRealDuration() <=
    m_LargestPossibleTemporalRegion.GetRealDuration();
  switch( m_TemporalUnit )
    {
    case Frame:
      {
      return frameFlag;
      }
    case RealTime:
      {
      return realTimeFlag;
      }
    case FrameAndRealTime:
      {
      return frameFlag && realTimeFlag;
      }
    default:
      itkExceptionMacro( << "itk::TemporalDataObject::VerifyRequestedRegion() "
                         << "Invalid Temporal Unit" );
      return false;
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::CopyInformation(const DataObject *data)
{
  // Standard call to the superclass' method
  Superclass::CopyInformation(data);

  const TemporalDataObject* temporalData;
  temporalData = dynamic_cast< const TemporalDataObject* >( data );

  if ( temporalData )
    {
    // Copy the meta data for this data type
    this->SetLargestPossibleTemporalRegion(
      temporalData->GetLargestPossibleTemporalRegion() );
    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->CopyInformation(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject::CopyInformation() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::Graft(const DataObject *data)
{
  const TemporalDataObject* temporalData;

  temporalData = dynamic_cast< const TemporalDataObject* >( data );

  if( temporalData )
    {
    // Copy the meta-information
    this->CopyInformation( temporalData );

    this->SetBufferedTemporalRegion(
      temporalData->GetBufferedTemporalRegion() );
    this->SetRequestedTemporalRegion(
      temporalData->GetRequestedTemporalRegion() );

    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->Graft(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject::Graft() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::SetRequestedRegion(DataObject *data)
{
  TemporalDataObject *temporalData;

  temporalData = dynamic_cast< TemporalDataObject * >( data );

  if ( temporalData )
    {
    // only copy the RequestedTemporalRegion if the parameter object is
    // a temporal data object
    this->SetRequestedTemporalRegion(
      temporalData->GetRequestedTemporalRegion() );
    for( unsigned int i = 0;
         i < this->m_DataObjectBuffer->GetNumberOfBuffers();
         ++i )
      {
      if( this->m_DataObjectBuffer->BufferIsFull(i) )
        {
        m_DataObjectBuffer->GetBufferContents(i)->SetRequestedRegion(
          temporalData->m_DataObjectBuffer->GetBufferContents(i) );
        }
      }
    }
  else
    {
    // pointer could not be cast back down
    itkExceptionMacro( << "itk::TemporalDataObject:SetRequestedRegion() "
                       << "cannot cast " << typeid( data ).name() << " to "
                       << typeid( const TemporalDataObject* ).name() );
    }
}

//----------------------------------------------------------------------------
void
TemporalDataObject
::PrintSelf(std::ostream & os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "Data Object Buffer: " << m_DataObjectBuffer.GetPointer()
     << std::endl;
  os << indent << "LargestPossibleTemporalRegion: " << std::endl;
  this->GetLargestPossibleTemporalRegion().Print( os,
                                                  indent.GetNextIndent() );

  os << indent << "BufferedTemporalRegion: " << std::endl;
  this->GetBufferedTemporalRegion().Print( os, indent.GetNextIndent() );

  os << indent << "RequestedTemporalRegion: " << std::endl;
  this->GetRequestedTemporalRegion().Print( os, indent.GetNextIndent() );
}

} // end namespace itk
<|endoftext|>


<commit_before>#include <string>

#include <config/config.h>
#include <config/config_class.h>
#include <config/config_object.h>
#include <config/config_type.h>
#include <config/config_value.h>

Config::Config(void)
: log_("/config"),
  class_map_(),
  object_map_()
{ }

Config::~Config()
{
	ASSERT(class_map_.empty());
	ASSERT(object_map_.empty());
}

bool
Config::activate(const std::string& oname)
{
	if (object_map_.find(oname) == object_map_.end()) {
		ERROR(log_) << "Object (" << oname << ") can not be activated as it does not exist.";
		return (false);
	}

	ConfigObject *co = object_map_[oname];
	ConfigClass *cc = co->class_;

	return (cc->activate(co));
}

bool
Config::create(const std::string& cname, const std::string& oname)
{
	if (class_map_.find(cname) == class_map_.end()) {
		ERROR(log_) << "Class (" << cname << ") not present.";
		return (false);
	}
	if (object_map_.find(oname) != object_map_.end()) {
		ERROR(log_) << "Refusing to create object (" << oname << ") twice.";
		return (false);
	}

	ConfigClass *cc = class_map_[cname];
	ConfigObject *co = new ConfigObject(this, cc);

	object_map_[oname] = co;

	return (true);
}

bool
Config::set(const std::string& oname, const std::string& mname,
	    const std::string& vstr)
{
	if (object_map_.find(oname) == object_map_.end()) {
		ERROR(log_) << "Can not set member value on object (" << oname << ") that does not exist.";
		return (false);
	}

	ConfigObject *co = object_map_[oname];
	ConfigClass *cc = co->class_;

	ConfigType *ct = cc->member(mname);
	if (ct == NULL) {
		ERROR(log_) << "No such member (" << mname << ") in object (" << oname << ")";
		return (false);
	}

	ConfigValue *cv = new ConfigValue(this, ct, vstr);
	if (!ct->set(cv, vstr)) {
		delete cv;
		return (false);
	}
	cc->set(co, mname, cv);

	return (true);
}

void
Config::import(const std::string& cname, ConfigClass *cc)
{
	if (class_map_.find(cname) != class_map_.end())
		return;

	class_map_[cname] = cc;
}
<commit_msg>Add untested reference resolution code.<commit_after>#include <string>

#include <config/config.h>
#include <config/config_class.h>
#include <config/config_object.h>
#include <config/config_type.h>
#include <config/config_value.h>

Config::Config(void)
: log_("/config"),
  class_map_(),
  object_map_()
{ }

Config::~Config()
{
	ASSERT(class_map_.empty());
	ASSERT(object_map_.empty());
}

bool
Config::activate(const std::string& oname)
{
	if (object_map_.find(oname) == object_map_.end()) {
		ERROR(log_) << "Object (" << oname << ") can not be activated as it does not exist.";
		return (false);
	}

	ConfigObject *co = object_map_[oname];
	ConfigClass *cc = co->class_;

	return (cc->activate(co));
}

bool
Config::create(const std::string& cname, const std::string& oname)
{
	if (class_map_.find(cname) == class_map_.end()) {
		ERROR(log_) << "Class (" << cname << ") not present.";
		return (false);
	}
	if (object_map_.find(oname) != object_map_.end()) {
		ERROR(log_) << "Refusing to create object (" << oname << ") twice.";
		return (false);
	}

	ConfigClass *cc = class_map_[cname];
	ConfigObject *co = new ConfigObject(this, cc);

	object_map_[oname] = co;

	return (true);
}

bool
Config::set(const std::string& oname, const std::string& mname,
	    const std::string& vstr)
{
	if (object_map_.find(oname) == object_map_.end()) {
		ERROR(log_) << "Can not set member value on object (" << oname << ") that does not exist.";
		return (false);
	}

	ConfigObject *co = object_map_[oname];
	ConfigClass *cc = co->class_;

	ConfigType *ct = cc->member(mname);
	if (ct == NULL) {
		ERROR(log_) << "No such member (" << mname << ") in object (" << oname << ")";
		return (false);
	}

	if (vstr[0] == '$') {
		std::string::const_iterator dot;

		dot = std::find(vstr.begin(), vstr.end(), '.');

		std::string ooname(vstr.begin() + 1, dot);
		std::string omname(dot, vstr.end());

		if (ooname == "" || omname == "") {
			ERROR(log_) << "Refernece to invalid object (" << ooname << ") or member (" << omname << ") by name.";
			return (false);
		}

		if (object_map_.find(ooname) == object_map_.end()) {
			ERROR(log_) << "Reference to non-existant object (" << ooname << ")";
			return (false);
		}

		ConfigObject *oco = object_map_[ooname];
		ConfigClass *occ = oco->class_;

		ConfigType *oct = occ->member(mname);
		if (oct == NULL) {
			ERROR(log_) << "Reference to non-existant member (" << omname << ") in object (" << ooname << ")";
			return (false);
		}

		ConfigValue *ocv = oco->members_[omname];
		if (ocv == NULL) {
			ERROR(log_) << "Reference to uninitialized member (" << omname << ") in object (" << ooname << ")";
			return (false);
		}

		return (set(oname, mname, ocv->string_));
	}

	ConfigValue *cv = new ConfigValue(this, ct, vstr);
	if (!ct->set(cv, vstr)) {
		delete cv;
		return (false);
	}
	cc->set(co, mname, cv);

	return (true);
}

void
Config::import(const std::string& cname, ConfigClass *cc)
{
	if (class_map_.find(cname) != class_map_.end())
		return;

	class_map_[cname] = cc;
}
<|endoftext|>


<commit_before>/***********************************************************************
 load_jpeg.cpp - Example showing how to insert BLOB data into the
	database from a file.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2009 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS.txt file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "cmdline.h"
#include "images.h"
#include "printdata.h"

#include <fstream>

using namespace std;
using namespace mysqlpp;

// This is just an implementation detail for the example.  Skip down to
// main() for the concept this example is trying to demonstrate.
static bool
is_jpeg(const char* img_data)
{
	const unsigned char* idp =
			reinterpret_cast<const unsigned char*>(img_data);
	return (idp[0] == 0xFF) && (idp[1] == 0xD8) &&
			((memcmp(idp + 6, "JFIF", 4) == 0) ||
			 (memcmp(idp + 6, "Exif", 4) == 0));
}

// Another implementation detail.  Skip to main().
static bool
load_jpeg_file(const mysqlpp::examples::CommandLine& cmdline,
		images& img, string& img_name)
{
	if (cmdline.extra_args().size() == 0) {
		// Nothing for us to do here.  Caller will insert NULL BLOB.
		return true;
	}

	// Got a file's name on the command line, so open it.
	img_name = cmdline.extra_args()[0];
	ifstream img_file(img_name.c_str(), ios::ate | ios::binary);
	if (img_file) {
		// File opened, so try to slurp its contents into RAM.  The key
		// thing to get from this function is that we're storing the
		// binary data in a mysqlpp::sql_blob value, which we assign from
		// a C++ string (stringstream::str()), thus not truncating the
		// string at the first embedded null character.
		stringstream sstr;
		sstr << img_file.rdbuf();
		img.data.data = sstr.str();

		// Check JPEG data for sanity
		if (img.data.data.size() > 10) {
			// The following triple 'data' sure does look foolish,
			// doesn't it?  Sorry, we're not trying to be obscure here,
			// it's just a coincidence of naming.  Right-to-left, what
			// we have here is:
			//
			// 1. A call to mysqlpp::sql_blob::data() (mirroring C++'s
			//    std::string:data() interface) to get the raw C data
			//    pointer without null-terminating it first.
			// 2. Access to the mysqlpp::sql_blob object through its
			//    mysqlpp::Null<> wrapper, which lets us have a "NULL
			//    JPEG" in the DB when the file doesn't exist.
			// 3. Access to the JPEG BLOB column, images.data.
			if (is_jpeg(img.data.data.data())) {
				return true;
			}
			else {
				cerr << '"' << img_file << "\" isn't a JPEG!" << endl;
			}
		}
		else {
			cerr << "File is too short to be a JPEG!" << endl;
		}
	}

	cmdline.print_usage("[jpeg_file]");
	return false;
}

int
main(int argc, char *argv[])
{
	// Get database access parameters from command line
	mysqlpp::examples::CommandLine cmdline(argc, argv);
	if (!cmdline) {
		return 1;
	}

	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::examples::db_name,
				cmdline.server(), cmdline.user(), cmdline.pass());

		// Load the file named on the command line
		images img(mysqlpp::null, mysqlpp::null);
		string img_name("NULL");
		if (load_jpeg_file(cmdline, img, img_name)) {
			// Insert image data or SQL NULL into the images.data BLOB
			// column.  The key here is that we're holding the raw
			// binary data in a mysqlpp::sql_blob, which avoids data
			// conversion problems that can lead to treating BLOB data
			// as C strings, thus causing null-truncation.  The fact
			// that we're using SSQLS here is a side issue, simply
			// demonstrating that mysqlpp::Null<mysqlpp::sql_blob> is
			// now legal in SSQLS, as of MySQL++ 3.0.7.
			Query query = con.query();
			query.insert(img);
			SimpleResult res = query.execute();

			// Report successful insertion
			cout << "Inserted \"" << img_name <<
					"\" into images table, " << img.data.data.size() <<
					" bytes, ID " << res.insert_id() << endl;
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
<commit_msg>Yet another load_jpeg example simplification<commit_after>/***********************************************************************
 load_jpeg.cpp - Example showing how to insert BLOB data into the
	database from a file.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2009 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS.txt file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "cmdline.h"
#include "images.h"
#include "printdata.h"

#include <fstream>

using namespace std;
using namespace mysqlpp;

// This is just an implementation detail for the example.  Skip down to
// main() for the concept this example is trying to demonstrate.
static bool
is_jpeg(const char* img_data)
{
	const unsigned char* idp =
			reinterpret_cast<const unsigned char*>(img_data);
	return (idp[0] == 0xFF) && (idp[1] == 0xD8) &&
			((memcmp(idp + 6, "JFIF", 4) == 0) ||
			 (memcmp(idp + 6, "Exif", 4) == 0));
}

// Another implementation detail.  Skip to main().
static bool
load_jpeg_file(const mysqlpp::examples::CommandLine& cmdline,
		images& img, string& img_name)
{
	if (cmdline.extra_args().size() == 0) {
		// Nothing for us to do here.  Caller will insert NULL BLOB.
		return true;
	}

	// Got a file's name on the command line, so open it.
	img_name = cmdline.extra_args()[0];
	ifstream img_file(img_name.c_str(), ios::ate | ios::binary);
	if (img_file) {
		// File opened, so try to slurp its contents into RAM.  The key
		// thing to get from this function is that we're storing the
		// binary data in a mysqlpp::sql_blob value, which we assign from
		// a C++ string (stringstream::str()), thus not truncating the
		// string at the first embedded null character.
		stringstream sstr;
		sstr << img_file.rdbuf();
		img.data.data = sstr.str();

		// Check JPEG data for sanity.
		//
		// All these 'data's sure do look foolish, don't they?  Sorry,
		// we're not trying to be obscure here, it's just a coincidence
		// of naming.  The triple 'data' in the is_jpeg() call breaks
		// down like this:
		//
		// 1. We're accessing to the JPEG BLOB column, images.data.
		// 2. We then dig down to the mysqlpp::sql_blob object through
		//    its mysqlpp::Null<> wrapper, which we need to allow a
		//    "NULL JPEG" in the DB when the file doesn't exist.
		// 3. Finally, we need to pass a raw, unterminated char buffer
		//    pointer to is_jpeg(), which mysqlpp::sql_blob::data()
		//    returns, mirroring the C++'s std::string interface.
		if ((img.data.data.size() > 10) &&
				is_jpeg(img.data.data.data())) {
			return true;
		}
		else {
			cerr << '"' << img_file << "\" isn't a JPEG file!" << endl;
		}
	}

	cmdline.print_usage("[jpeg_file]");
	return false;
}

int
main(int argc, char *argv[])
{
	// Get database access parameters from command line
	mysqlpp::examples::CommandLine cmdline(argc, argv);
	if (!cmdline) {
		return 1;
	}

	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::examples::db_name,
				cmdline.server(), cmdline.user(), cmdline.pass());

		// Load the file named on the command line
		images img(mysqlpp::null, mysqlpp::null);
		string img_name("NULL");
		if (load_jpeg_file(cmdline, img, img_name)) {
			// Insert image data or SQL NULL into the images.data BLOB
			// column.  The key here is that we're holding the raw
			// binary data in a mysqlpp::sql_blob, which avoids data
			// conversion problems that can lead to treating BLOB data
			// as C strings, thus causing null-truncation.  The fact
			// that we're using SSQLS here is a side issue, simply
			// demonstrating that mysqlpp::Null<mysqlpp::sql_blob> is
			// now legal in SSQLS, as of MySQL++ 3.0.7.
			Query query = con.query();
			query.insert(img);
			SimpleResult res = query.execute();

			// Report successful insertion
			cout << "Inserted \"" << img_name <<
					"\" into images table, " << img.data.data.size() <<
					" bytes, ID " << res.insert_id() << endl;
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "../uvc.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#include <sstream>

#include <linux/uvcvideo.h>
#include <linux/videodev2.h>
#include <linux/usb/video.h>

namespace rsimpl
{
    namespace uvc
    {
        struct context
        {
            // TODO: V4L2-specific information

            context() {} // TODO: Init
            ~context() {} // TODO: Cleanup
        };

        struct subdevice
        {
            // TODO: Stream-specific information
            std::string name;
            uint16_t camIndex;

            std::function<void(const void * frame)> callback;
        };

        struct device
        {
            const std::shared_ptr<context> parent;

            // TODO: Device-specific information
            std::vector<subdevice> subdevices;

            uint32_t serialNumber;

            device(std::shared_ptr<context> parent) : parent(parent) {} // TODO: Init
            ~device() {} // TODO: Cleanup
        };

        ////////////
        // device //
        ////////////

        int get_vendor_id(const device & device) { return 0; }
        int get_product_id(const device & device) { return 0; }

        void init_controls(device & device, int subdevice, const guid & xu_guid) {}
        void get_control(const device & device, int subdevice, uint8_t ctrl, void * data, int len) {}
        void set_control(device & device, int subdevice, uint8_t ctrl, void * data, int len) {}

        void claim_interface(device & device, const guid & interface_guid, int interface_number) {}
        void bulk_transfer(device & device, unsigned char endpoint, void * data, int length, int *actual_length, unsigned int timeout) {}

        void set_subdevice_mode(device & device, int subdevice_index, int width, int height, uint32_t fourcc, int fps, std::function<void(const void * frame)> callback) {}
        void start_streaming(device & device, int num_transfer_bufs) {}
        void stop_streaming(device & device) {}

        void set_pu_control(device & device, int subdevice, rs_option option, int value) {}
        int get_pu_control(const device & device, int subdevice, rs_option option) { return 0; }

        /////////////
        // context //
        /////////////

        std::shared_ptr<context> create_context()
        {
            return std::make_shared<context>();
        }

        std::vector<std::shared_ptr<device>> query_devices(std::shared_ptr<context> context)
        {

            std::vector<std::shared_ptr<device>> devices;

            auto make_subdevice = [&](char * name, uint16_t & indexDepth, uint16_t & indexIR, uint16_t & indexRGB)
            {
                auto subdev = std::make_shared<subdevice>();
                if (strcmp(name, "Intel(R) RealSense(TM) 3D Camera (R200) Depth") == 0)
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexDepth++;
                }
                else if (strcmp(name, "Intel(R) RealSense(TM) 3D Camera (R200) Left-Right") == 0)
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexIR++;
                }
                else if (strcmp(name, "Intel(R) RealSense(TM) 3D Camera (R200) RGB") == 0)
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexRGB++;
                }
                return subdev;
            };

            try
            {
                std::stringstream ss;
                std::string strTmpDev;
                std::string strTmpInt;

                struct stat vstat;
                char buf[64] = {0};
                int fd = 0;
                int ret = 0;
                char * nl = NULL;

                uint16_t indexDepth = 0;
                uint16_t indexIR = 0;
                uint16_t indexRGB = 0;

                for (int i = 0; i < 64; ++i)
                {
                    ss.str("");
                    ss << "/dev/video" << i;

                    strTmpDev = ss.str();
                    if (stat(strTmpDev.c_str(), &vstat) < 0 || !S_ISCHR(vstat.st_mode))
                        break;

                    ss.str("");
                    ss << "/sys/class/video4linux/video" << i << "/device/interface";
                    strTmpInt = ss.str();

                    fd = open(strTmpInt.c_str(), O_RDONLY);
                    if (fd < 0)
                        continue;

                    ret = read(fd, buf, sizeof(buf));
                    close(fd);
                    if (ret < 0)
                        continue;

                    buf[63] = 0;

                    nl = strchr(buf, '\n');
                    if (!nl)
                        continue;

                    *nl = '\0';

                    if (strncmp(buf, "DS4", 3) == 0 || strncmp(buf, "Intel(R) RealSense(TM) 3D Camera (R200)", 39) == 0)
                    {
                        devices.subdevices.push_back(make_subdevice(buf, indexDepth, indexIR, indexRGB));
                    }
                }
            }
            catch (...)
            {
                throw std::runtime_error("failed to enumerate list of devices");
            }

            return devices;
        }
    }
}
<commit_msg>use strings instead of strcmp<commit_after>#include "../uvc.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#include <sstream>

#include <linux/uvcvideo.h>
#include <linux/videodev2.h>
#include <linux/usb/video.h>

namespace rsimpl
{
    namespace uvc
    {
        struct context
        {
            // TODO: V4L2-specific information

            context() {} // TODO: Init
            ~context() {} // TODO: Cleanup
        };

        struct subdevice
        {
            // TODO: Stream-specific information
            std::string name;
            uint16_t camIndex;

            std::function<void(const void * frame)> callback;
        };

        struct device
        {
            const std::shared_ptr<context> parent;

            // TODO: Device-specific information
            std::vector<subdevice> subdevices;

            uint32_t serialNumber;

            device(std::shared_ptr<context> parent) : parent(parent) {} // TODO: Init
            ~device() {} // TODO: Cleanup
        };

        ////////////
        // device //
        ////////////

        int get_vendor_id(const device & device) { return 0; }
        int get_product_id(const device & device) { return 0; }

        void init_controls(device & device, int subdevice, const guid & xu_guid) {}
        void get_control(const device & device, int subdevice, uint8_t ctrl, void * data, int len) {}
        void set_control(device & device, int subdevice, uint8_t ctrl, void * data, int len) {}

        void claim_interface(device & device, const guid & interface_guid, int interface_number) {}
        void bulk_transfer(device & device, unsigned char endpoint, void * data, int length, int *actual_length, unsigned int timeout) {}

        void set_subdevice_mode(device & device, int subdevice_index, int width, int height, uint32_t fourcc, int fps, std::function<void(const void * frame)> callback) {}
        void start_streaming(device & device, int num_transfer_bufs) {}
        void stop_streaming(device & device) {}

        void set_pu_control(device & device, int subdevice, rs_option option, int value) {}
        int get_pu_control(const device & device, int subdevice, rs_option option) { return 0; }

        /////////////
        // context //
        /////////////

        std::shared_ptr<context> create_context()
        {
            return std::make_shared<context>();
        }

        std::vector<std::shared_ptr<device>> query_devices(std::shared_ptr<context> context)
        {
            std::vector<std::shared_ptr<device>> devices;

            auto make_subdevice = [&](char * name, uint16_t & indexDepth, uint16_t & indexIR, uint16_t & indexRGB)
            {
                auto subdev = std::make_shared<subdevice>();
                if (std::string(name) == "Intel(R) RealSense(TM) 3D Camera (R200) Depth"))
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexDepth++;
                }
                else if (std::string(name) == "Intel(R) RealSense(TM) 3D Camera (R200) Left-Right"))
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexIR++;
                }
                else if (std::string(name) == "Intel(R) RealSense(TM) 3D Camera (R200) RGB"))
                {
                    subdev.name = std::string(name);
                    subdev.camIndex = indexRGB++;
                }
                return subdev;
            };

            try
            {
                std::stringstream ss;
                std::string strTmpDev;
                std::string strTmpInt;

                struct stat vstat;
                char buf[64] = {0};
                int fd = 0;
                int ret = 0;
                char * nl = NULL;

                uint16_t indexDepth = 0;
                uint16_t indexIR = 0;
                uint16_t indexRGB = 0;

                for (int i = 0; i < 64; ++i)
                {
                    ss.str("");
                    ss << "/dev/video" << i;

                    strTmpDev = ss.str();
                    if (stat(strTmpDev.c_str(), &vstat) < 0 || !S_ISCHR(vstat.st_mode))
                        break;

                    ss.str("");
                    ss << "/sys/class/video4linux/video" << i << "/device/interface";
                    strTmpInt = ss.str();

                    fd = open(strTmpInt.c_str(), O_RDONLY);
                    if (fd < 0)
                        continue;

                    ret = read(fd, buf, sizeof(buf));
                    close(fd);
                    if (ret < 0)
                        continue;

                    buf[63] = 0;

                    nl = strchr(buf, '\n');
                    if (!nl)
                        continue;

                    *nl = '\0';

                    if (strncmp(buf, "DS4", 3) || strncmp(buf, "Intel(R) RealSense(TM) 3D Camera (R200)", 39) == 0)
                    {
                        devices.subdevices.push_back(make_subdevice(buf, indexDepth, indexIR, indexRGB));
                    }
                }
            }
            catch (...)
            {
                throw std::runtime_error("failed to enumerate list of devices");
            }

            return devices;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, History) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  host_resolver()->AddRule("www.a.com", "127.0.0.1");
  host_resolver()->AddRule("www.b.com", "127.0.0.1");
  StartHTTPServer();

  ASSERT_TRUE(RunExtensionTest("history")) << message_;
}
<commit_msg>Disable flaky test.  See http://crbug.com/26296 BUG=26296 TEST=none Review URL: http://codereview.chromium.org/346021<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

// Flaky, http://crbug.com/26296.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_History) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  host_resolver()->AddRule("www.a.com", "127.0.0.1");
  host_resolver()->AddRule("www.b.com", "127.0.0.1");
  StartHTTPServer();

  ASSERT_TRUE(RunExtensionTest("history")) << message_;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/format_macros.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/notification_service.h"

#if defined(TOOLKIT_GTK)
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#endif

namespace {

string16 AutocompleteResultAsString(const AutocompleteResult& result) {
  std::string output(base::StringPrintf("{%" PRIuS "} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::string provider_name = match.provider->name();
    output.append(base::StringPrintf("[\"%s\" by \"%s\"] ",
                                     UTF16ToUTF8(match.contents).c_str(),
                                     provider_name.c_str()));
  }
  return UTF8ToUTF16(output);
}

}  // namespace

class OmniboxApiTest : public ExtensionApiTest {
 protected:
  LocationBar* GetLocationBar(Browser* browser) const {
    return browser->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController(Browser* browser) const {
    return GetLocationBar(browser)->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }

  void WaitForTemplateURLServiceToLoad() {
    ui_test_utils::WindowedNotificationObserver loaded_observer(
        chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
        content::NotificationService::AllSources());
    TemplateURLService* model =
        TemplateURLServiceFactory::GetForProfile(browser()->profile());
    model->Load();
    if (!model->loaded())
      loaded_observer.Wait();
  }

  // TODO(phajdan.jr): Get rid of this wait-in-a-loop pattern.
  void WaitForAutocompleteDone(AutocompleteController* controller) {
    while (!controller->done()) {
      ui_test_utils::WindowedNotificationObserver ready_observer(
          chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
          content::Source<AutocompleteController>(controller));
      ready_observer.Wait();
    }
  }
};

IN_PROC_BROWSER_TEST_F(OmniboxApiTest, Basic) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
      browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(browser());
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(browser());

  // Test that our extension's keyword is suggested to us when we partially type
  // it.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keywor"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(string16(), location_bar->GetInputString());
    EXPECT_EQ(string16(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

    // First result should be to search for what was typed, second should be to
    // enter "extension keyword" mode.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);

    match = result.match_at(1);
    ASSERT_TRUE(match.template_url);
    EXPECT_TRUE(match.template_url->IsExtensionKeyword());
    EXPECT_EQ(ASCIIToUTF16("keyword"), match.template_url->keyword());
  }

  // Test that our extension can send suggestions back to us.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword suggestio"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());

    // First result should be to invoke the keyword with what we typed, 2-4
    // should be to invoke with suggestions from the extension, and the last
    // should be to search for what we typed.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);

    ASSERT_TRUE(result.match_at(0).template_url);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestio"),
              result.match_at(0).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion1"),
              result.match_at(1).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion2"),
              result.match_at(2).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion3"),
              result.match_at(3).fill_into_edit);

    string16 description =
        ASCIIToUTF16("Description with style: <match>, [dim], (url till end)");
    EXPECT_EQ(description, result.match_at(1).contents);
    ASSERT_EQ(6u, result.match_at(1).contents_class.size());

    EXPECT_EQ(0u,
              result.match_at(1).contents_class[0].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[0].style);

    EXPECT_EQ(description.find('<'),
              result.match_at(1).contents_class[1].offset);
    EXPECT_EQ(ACMatchClassification::MATCH,
              result.match_at(1).contents_class[1].style);

    EXPECT_EQ(description.find('>') + 1u,
              result.match_at(1).contents_class[2].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[2].style);

    EXPECT_EQ(description.find('['),
              result.match_at(1).contents_class[3].offset);
    EXPECT_EQ(ACMatchClassification::DIM,
              result.match_at(1).contents_class[3].style);

    EXPECT_EQ(description.find(']') + 1u,
              result.match_at(1).contents_class[4].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[4].style);

    EXPECT_EQ(description.find('('),
              result.match_at(1).contents_class[5].offset);
    EXPECT_EQ(ACMatchClassification::URL,
              result.match_at(1).contents_class[5].style);

    AutocompleteMatch match = result.match_at(4);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    ResultCatcher catcher;
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword command"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);
    location_bar->AcceptInput();
    EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  }
}

// Tests that the autocomplete popup doesn't reopen after accepting input for
// a given query.
// http://crbug.com/88552
IN_PROC_BROWSER_TEST_F(OmniboxApiTest, PopupStaysClosed) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
    browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(browser());
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(browser());
  AutocompletePopupModel* popup_model =
      GetLocationBar(browser())->location_entry()->model()->popup_model();

  // Input a keyword query and wait for suggestions from the extension.
  autocomplete_controller->Start(
      ASCIIToUTF16("keyword comman"), string16(), true, false, true,
      AutocompleteInput::ALL_MATCHES);
  WaitForAutocompleteDone(autocomplete_controller);
  EXPECT_TRUE(autocomplete_controller->done());
  EXPECT_TRUE(popup_model->IsOpen());

  // Quickly type another query and accept it before getting suggestions back
  // for the query. The popup will close after accepting input - ensure that it
  // does not reopen when the extension returns its suggestions.
  ResultCatcher catcher;
  autocomplete_controller->Start(
      ASCIIToUTF16("keyword command"), string16(), true, false, true,
      AutocompleteInput::ALL_MATCHES);
  location_bar->AcceptInput();
  WaitForAutocompleteDone(autocomplete_controller);
  EXPECT_TRUE(autocomplete_controller->done());
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  EXPECT_FALSE(popup_model->IsOpen());
}

// Tests that we get suggestions from and send input to the incognito context
// of an incognito split mode extension.
// http://crbug.com/100927
IN_PROC_BROWSER_TEST_F(OmniboxApiTest, IncognitoSplitMode) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
    browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ResultCatcher catcher_incognito;
  catcher_incognito.RestrictToProfile(
      browser()->profile()->GetOffTheRecordProfile());

  ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_;

  // Open an incognito window and wait for the incognito extension process to
  // respond.
  Browser* incognito_browser = CreateIncognitoBrowser();
  ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message();

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(incognito_browser);
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(incognito_browser);

  // Test that we get the incognito-specific suggestions.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword suggestio"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());

    // First result should be to invoke the keyword with what we typed, 2-4
    // should be to invoke with suggestions from the extension, and the last
    // should be to search for what we typed.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);
    ASSERT_TRUE(result.match_at(0).template_url);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion3 incognito"),
              result.match_at(3).fill_into_edit);
  }

  // Test that our input is sent to the incognito context. The test will do a
  // text comparison and succeed only if "command incognito" is sent to the
  // incognito context.
  {
    ResultCatcher catcher;
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword command incognito"), string16(),
        true, false, true, AutocompleteInput::ALL_MATCHES);
    location_bar->AcceptInput();
    EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  }
}
<commit_msg>Disable OmniboxApiTest.IncognitoSplitMode. It fails flakily on Linux.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/format_macros.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/notification_service.h"

#if defined(TOOLKIT_GTK)
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#endif

namespace {

string16 AutocompleteResultAsString(const AutocompleteResult& result) {
  std::string output(base::StringPrintf("{%" PRIuS "} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::string provider_name = match.provider->name();
    output.append(base::StringPrintf("[\"%s\" by \"%s\"] ",
                                     UTF16ToUTF8(match.contents).c_str(),
                                     provider_name.c_str()));
  }
  return UTF8ToUTF16(output);
}

}  // namespace

class OmniboxApiTest : public ExtensionApiTest {
 protected:
  LocationBar* GetLocationBar(Browser* browser) const {
    return browser->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController(Browser* browser) const {
    return GetLocationBar(browser)->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }

  void WaitForTemplateURLServiceToLoad() {
    ui_test_utils::WindowedNotificationObserver loaded_observer(
        chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
        content::NotificationService::AllSources());
    TemplateURLService* model =
        TemplateURLServiceFactory::GetForProfile(browser()->profile());
    model->Load();
    if (!model->loaded())
      loaded_observer.Wait();
  }

  // TODO(phajdan.jr): Get rid of this wait-in-a-loop pattern.
  void WaitForAutocompleteDone(AutocompleteController* controller) {
    while (!controller->done()) {
      ui_test_utils::WindowedNotificationObserver ready_observer(
          chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
          content::Source<AutocompleteController>(controller));
      ready_observer.Wait();
    }
  }
};

IN_PROC_BROWSER_TEST_F(OmniboxApiTest, Basic) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
      browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(browser());
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(browser());

  // Test that our extension's keyword is suggested to us when we partially type
  // it.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keywor"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(string16(), location_bar->GetInputString());
    EXPECT_EQ(string16(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

    // First result should be to search for what was typed, second should be to
    // enter "extension keyword" mode.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(2U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);

    match = result.match_at(1);
    ASSERT_TRUE(match.template_url);
    EXPECT_TRUE(match.template_url->IsExtensionKeyword());
    EXPECT_EQ(ASCIIToUTF16("keyword"), match.template_url->keyword());
  }

  // Test that our extension can send suggestions back to us.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword suggestio"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());

    // First result should be to invoke the keyword with what we typed, 2-4
    // should be to invoke with suggestions from the extension, and the last
    // should be to search for what we typed.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);

    ASSERT_TRUE(result.match_at(0).template_url);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestio"),
              result.match_at(0).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion1"),
              result.match_at(1).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion2"),
              result.match_at(2).fill_into_edit);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion3"),
              result.match_at(3).fill_into_edit);

    string16 description =
        ASCIIToUTF16("Description with style: <match>, [dim], (url till end)");
    EXPECT_EQ(description, result.match_at(1).contents);
    ASSERT_EQ(6u, result.match_at(1).contents_class.size());

    EXPECT_EQ(0u,
              result.match_at(1).contents_class[0].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[0].style);

    EXPECT_EQ(description.find('<'),
              result.match_at(1).contents_class[1].offset);
    EXPECT_EQ(ACMatchClassification::MATCH,
              result.match_at(1).contents_class[1].style);

    EXPECT_EQ(description.find('>') + 1u,
              result.match_at(1).contents_class[2].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[2].style);

    EXPECT_EQ(description.find('['),
              result.match_at(1).contents_class[3].offset);
    EXPECT_EQ(ACMatchClassification::DIM,
              result.match_at(1).contents_class[3].style);

    EXPECT_EQ(description.find(']') + 1u,
              result.match_at(1).contents_class[4].offset);
    EXPECT_EQ(ACMatchClassification::NONE,
              result.match_at(1).contents_class[4].style);

    EXPECT_EQ(description.find('('),
              result.match_at(1).contents_class[5].offset);
    EXPECT_EQ(ACMatchClassification::URL,
              result.match_at(1).contents_class[5].style);

    AutocompleteMatch match = result.match_at(4);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    ResultCatcher catcher;
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword command"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);
    location_bar->AcceptInput();
    EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  }
}

// Tests that the autocomplete popup doesn't reopen after accepting input for
// a given query.
// http://crbug.com/88552
IN_PROC_BROWSER_TEST_F(OmniboxApiTest, PopupStaysClosed) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
    browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ASSERT_TRUE(RunExtensionTest("omnibox")) << message_;

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(browser());
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(browser());
  AutocompletePopupModel* popup_model =
      GetLocationBar(browser())->location_entry()->model()->popup_model();

  // Input a keyword query and wait for suggestions from the extension.
  autocomplete_controller->Start(
      ASCIIToUTF16("keyword comman"), string16(), true, false, true,
      AutocompleteInput::ALL_MATCHES);
  WaitForAutocompleteDone(autocomplete_controller);
  EXPECT_TRUE(autocomplete_controller->done());
  EXPECT_TRUE(popup_model->IsOpen());

  // Quickly type another query and accept it before getting suggestions back
  // for the query. The popup will close after accepting input - ensure that it
  // does not reopen when the extension returns its suggestions.
  ResultCatcher catcher;
  autocomplete_controller->Start(
      ASCIIToUTF16("keyword command"), string16(), true, false, true,
      AutocompleteInput::ALL_MATCHES);
  location_bar->AcceptInput();
  WaitForAutocompleteDone(autocomplete_controller);
  EXPECT_TRUE(autocomplete_controller->done());
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  EXPECT_FALSE(popup_model->IsOpen());
}

// Tests that we get suggestions from and send input to the incognito context
// of an incognito split mode extension.
// http://crbug.com/100927
// Test flaky on linux: http://crbug.com/101219
IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) {
#if defined(TOOLKIT_GTK)
  // Disable the timer because, on Lucid at least, it triggers resize/move
  // behavior in the browser window, which dismisses the autocomplete popup
  // before the results can be read.
  static_cast<BrowserWindowGtk*>(
    browser()->window())->DisableDebounceTimerForTests(true);
#endif

  ResultCatcher catcher_incognito;
  catcher_incognito.RestrictToProfile(
      browser()->profile()->GetOffTheRecordProfile());

  ASSERT_TRUE(RunExtensionTestIncognito("omnibox")) << message_;

  // Open an incognito window and wait for the incognito extension process to
  // respond.
  Browser* incognito_browser = CreateIncognitoBrowser();
  ASSERT_TRUE(catcher_incognito.GetNextResult()) << catcher_incognito.message();

  // The results depend on the TemplateURLService being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  WaitForTemplateURLServiceToLoad();

  LocationBar* location_bar = GetLocationBar(incognito_browser);
  AutocompleteController* autocomplete_controller =
      GetAutocompleteController(incognito_browser);

  // Test that we get the incognito-specific suggestions.
  {
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword suggestio"), string16(), true, false, true,
        AutocompleteInput::ALL_MATCHES);

    WaitForAutocompleteDone(autocomplete_controller);
    EXPECT_TRUE(autocomplete_controller->done());

    // First result should be to invoke the keyword with what we typed, 2-4
    // should be to invoke with suggestions from the extension, and the last
    // should be to search for what we typed.
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(5U, result.size()) << AutocompleteResultAsString(result);
    ASSERT_TRUE(result.match_at(0).template_url);
    EXPECT_EQ(ASCIIToUTF16("keyword suggestion3 incognito"),
              result.match_at(3).fill_into_edit);
  }

  // Test that our input is sent to the incognito context. The test will do a
  // text comparison and succeed only if "command incognito" is sent to the
  // incognito context.
  {
    ResultCatcher catcher;
    autocomplete_controller->Start(
        ASCIIToUTF16("keyword command incognito"), string16(),
        true, false, true, AutocompleteInput::ALL_MATCHES);
    location_bar->AcceptInput();
    EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
  }
}
<|endoftext|>