<commit_before>#include "DFA.h"
#include "Edge.h"
#include "Vertex.h"
#include <string>
#include <stack>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
template <class T>
class LinkStack;

//ʽջ
template <class T>
class StackNode
{
	friend class LinkStack<T>;
private:
	T data;
	StackNode<T> *next;
	StackNode(T item = 0, StackNode<T> *p = NULL)
	{
		data = item;
		next = p;
	}
};

// ʽջ
template <class T>
class LinkStack
{
private:
	StackNode<T> *top;
public:
	LinkStack();
	~LinkStack();
	bool IsEmpty();
	int Length();
	void Push(const T &item);
	T Pop();
	T GetTop();
	void Clear();
};
//幹캯
template <class T>
LinkStack<T>::LinkStack()
{
	top = NULL;
}

//
template <class T>
LinkStack<T>::~LinkStack()
{
	Clear();
}
//жջǷΪ
template <class T>
bool LinkStack<T>::IsEmpty()
{
	return(!top);
}
//ջĳ
template <class T>
int LinkStack<T>::Length()
{
	StackNode<T> *temp = new StackNode<T>();
	temp = top;
	int length = 0;
	while (temp)
	{
		temp = temp->next;
		length++;
	}
	return length;
}
//ѹջ
template <class T>
void LinkStack<T>::Push(const T &item)
{
	top = new StackNode<T>(item, top);
}
// (ջ)
template <class T>
T LinkStack<T>::Pop()
{
	if (!IsEmpty())
	{
		StackNode<T> *temp = top;
		top = top->next;
		T value = temp->data;
		delete temp;
		return value;
	}
	else
	{
		cout << "Stack is Empty" << endl;
		exit(1);
	}
}
//ȡջ
template<class T>
T LinkStack<T>::GetTop()
{
	if (!IsEmpty())
		return top->data;
	else
	{
		cout << "The Stack is Empty" << endl;
		exit(1);
	}
}
//ջ
template<class T>
void LinkStack<T>::Clear()
{
	StackNode<T> *temp = new StackNode<T>();
	while (top)
	{
		temp = top;
		top = top->next;
		delete temp;
	}
}
/*
		DFA
*/
//DFA캯
DFA::DFA()
{
	Regex = new char[128];
	RegexPost = new char[128];
	EdgeNum = new char[128];
	EdgeNumber = 0;
	DFAStatesNumber = 0;
	NFAStatesNumber = 0;
	DtranNumber = 0;
	NFATable = new AdjacentTable();
	DFATable = new AdjacentTable();
}
//DFA
DFA::~DFA()
{
	delete[] Regex;
	delete[] RegexPost;
	//delete[] Edge;
	//delete[] AcceptStates;
	//NFATable->Clear();
	//DFATable->clear();
}
//ȡ
void DFA::InputRegex()
{
	cout << " ʽ" << endl;
	cin >> Regex;
}
//"."
void DFA::InsertNode()
{
	int i = 0,j, len = strlen(Regex);
	int length = len;
	len--;
	while (len--)
	{
		if (((Regex[i] != '(' && Regex[i] != '.' && Regex[i] != '|')
			|| Regex[i] == ')'|| Regex[i] == '*')
			&& (Regex[i + 1] != ')' && Regex[i + 1] != '.' && Regex[i + 1] != '|' && Regex[i + 1] != '*'))
		{
			for (j =length; j >i;j--)
			{
				Regex[j+1] = Regex[j];
			}
			Regex[i + 1] = '.';
			length++;
			Regex[length] = '\0';
			i++;
		}
		i++;
	}
	cout << endl;
	cout << "     " << endl;
	cout<<Regex << endl;
	cout << "ַȣ" <<length<<endl;
}
//жȼ
int DFA::Precedence(char symbol)
{
	int priority;
	switch (symbol)
	{
	case '|':priority = 1; break;
	case '.':priority = 2; break;
	case '*':priority = 3; break;
	default:priority = 0; break;
	}
	return priority;
}
//ʽתΪ沨ʽ
void DFA::RegextoPost()
{
	int i = 0, j = 0;
	char ch, cl;
	strcpy(RegexPost, "\0");
	LinkStack<char> *Value = new LinkStack<char>();
	Value->Clear();
	ch = Regex[i];
	Value->Push('#');
	ch = Regex[i];
	while (ch != '\0')
	{
		if (ch == '(')
		{
			Value->Push(ch);
			ch = Regex[++i];
		}
		else if (ch == ')')
		{
			while (Value->GetTop() != '(')
			{
				RegexPost[j++] = Value->Pop();
			}
			Value->Pop();
			ch = Regex[++i];
		}
		else if ((ch == '|') || (ch == '*') || (ch == '.'))
		{
			cl = Value->GetTop();
			while (Precedence(cl) >= Precedence(ch))
			{
				RegexPost[j++] = cl;
				Value->Pop();
				cl = Value->GetTop();
			}
			Value->Push(ch);
			ch = Regex[++i];
		}
		else
		{
			RegexPost[j++] = ch;
			ch = Regex[++i];
		}
	}
	ch = Value->Pop();
	while ((ch == '|') || (ch == '*') || (ch == '.'))
	{
		RegexPost[j++] = ch;
		ch = Value->Pop();
	}
	RegexPost[j] = '\0';
	Value->Clear();
	cout << "\nڶ: תΪ׺ʽ\n"
		<< RegexPost << "\n"
		<< "ַ: " << strlen(RegexPost)
		<< "\n\n------------------------" << endl;
}
//ɨ沨ʽгַĿ
void DFA::GetEdgeNumber()
{
	int i = 0, j;
	EdgeNumber = 0;
	while (RegexPost[i] != '\0')
	{
		if (RegexPost[i] == '.' || RegexPost[i] == '|' || RegexPost[i] == '*')
		{
			i++;
			continue;
		}
		for (j = 0; j < EdgeNumber; j++)
		{
			if (RegexPost[i] == EdgeNum[j])
				break;
		}
		if (j == EdgeNumber)
		{
			EdgeNum[EdgeNumber] = RegexPost[i];
			EdgeNumber++;
		}
		i++;
	}
	EdgeNum[EdgeNumber] = '\0';
	cout << "\n: ȡַ\n";
	for (i = 0; i<EdgeNumber; i++)
	{
		cout << EdgeNum[i] << ' ';
	}
	cout << "\nַ: " << EdgeNumber
		<< "\n\n------------------------" << endl;
}

//Thompson취NFA
void DFA::Thompson()
{
	int i, j;
	char ch;
	int s1, s2;
	LinkStack<int >*States = new LinkStack<int >();
	States->Clear();
	if (strlen(RegexPost) < 1)
	{
		cout << "No Regex Expression Find" << endl;
		exit(1);
	}
	i = 1; j = 0;
	ch = RegexPost[j];
	while (ch != '\0')
	{
		if (ch == '.')
		{
			s2 = States->Pop();
			int Ex1 = States->Pop();
			int Ex2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertEdgeByValue(Ex2, Ex1, '~');
			States->Push(s1);
			States->Push(s2);
		}
		else if (ch == '*')
		{
			s2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, i + 1, '~');
			NFATable->InsertEdgeByValue(s2, s1, '~');
			NFATable->InsertEdgeByValue(i, s1, '~');
			NFATable->InsertEdgeByValue(s2, i + 1, '~');
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		else if (ch == '|')
		{
			s2 = States->Pop();
			int temp1 = States->Pop();
			int temp2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, s1, '~');
			NFATable->InsertEdgeByValue(i, temp1, '~');
			NFATable->InsertEdgeByValue(temp2, i + 1, '~');
			NFATable->InsertEdgeByValue(s2, i + 1, '~');
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		else
		{
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, i + 1, ch);
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		j++;
		ch = RegexPost[j];
	}
	s2 = States->Pop();
	s1 = States->Pop();
	NFAStatesNumber = s2 + 1;
}
void SetNFANodeAll(int (*A)[100])
{
	for (int i = 0; i < 101;i++)
	for (int j = 0; j < 101; j++)
		A[i][j] = 0;
}
//Ӽ취 NFADFA
void DFA::NFAtoDFA()
{
	int states, update=0;
	int VertexNode[1001];
	queue<int > DFAStates;//DFA״̬
	queue<int >NFANode;//NFA״̬Ӽ
	int NFANodeAll[100][100];
	SetNFANodeAll(NFANodeAll);
	DFAStates.push(1);
	int Pointer = 0;
	for (int i = 0; i < NFATable->numOfVertexs; i++)
		VertexNode[i] = 0;//һ飬洢Ƿʹ
	states = DFAStates.front();//DFA״̬еĵһ
	update = states;
	/*
		1״̬ʼҳλ
	*/
	for (int i = 0; i < EdgeNumber; i++)
	{
		char weight = EdgeNum[i];
		Vertex *P = new Vertex;
		P = NFATable->StartVertex;
		for (int j = 0; j < states; j++)
			P = P->Next;
		if (P->Out->Link == NULL)
		{
			if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
				NFANode.push(P->Out->position);
			VertexNode[P->Out->position] = 1;
		}
		while (P->Out->Link != NULL)
		{
			if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
				NFANode.push(P->Out->position);
			VertexNode[P->Out->position] = 1;
		}
		if (NFANode.empty())
			break;
		states++;
		while (!NFANode.empty())
		{
			int Visual = NFANode.front();
			NFANode.pop();
			NFANodeAll[states][Pointer] = Visual;
			Pointer++;
			P = NFATable->StartVertex;
			for (int j = 0; j < Visual; j++)
				P = P->Next;
			if (P->Out&&P->Out->Link == NULL)
			{
				if (P->Out->weight == '~'&&VertexNode[P->Out->position] == 0)//ûбʹ
					NFANode.push(P->Out->position);
				VertexNode[P->Out->position] = 1;
			}
			else if (P->Out)
			{
				if (P->Out->weight == '~'&&VertexNode[P->Out->position] == 0)//ûбʹ
					NFANode.push(P->Out->position);
				VertexNode[P->Out->position] = 1;
				Edge *LinkNode= P->Out->Link;
				while (LinkNode!= NULL)
				{
					if (LinkNode->weight == '~'&&VertexNode[LinkNode->position] == 0)
						NFANode.push(LinkNode->position);
					VertexNode[P->Out->position] = 1;
					LinkNode = LinkNode->Link;
				}
			}
		}
		DFATable->InsertEdgeByValue(1, states, EdgeNum[i]);
	}
	update = states - update;
	NFAStatesNumber = 1;
	/*
		1״̬óNFA״̬ȥ
	*/
	while (update != 0)
	{
		VertexNode[1001] = { 0 };
		for (int j = 0; j < EdgeNumber; j++)
		{
			int i = 0;
			char weight = EdgeNum[j];
			while (NFANodeAll[NFAStatesNumber][i] != 0)
			{
				Vertex *P = new Vertex;
				P = NFATable->StartVertex;
				for (int i = 0; i < NFANodeAll[NFAStatesNumber][i]; i++)
					P = P->Next;
				if (P->Out->Link == NULL)
				{
					if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
						NFANode.push(P->Out->position);
					VertexNode[P->Out->position] = 1;
				}

			}
		}
	}

}<commit_msg>update<commit_after>#include "DFA.h"
#include "Edge.h"
#include "Vertex.h"
#include <string>
#include <stack>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
template <class T>
class LinkStack;

//ʽջ
template <class T>
class StackNode
{
	friend class LinkStack<T>;
private:
	T data;
	StackNode<T> *next;
	StackNode(T item = 0, StackNode<T> *p = NULL)
	{
		data = item;
		next = p;
	}
};

// ʽջ
template <class T>
class LinkStack
{
private:
	StackNode<T> *top;
public:
	LinkStack();
	~LinkStack();
	bool IsEmpty();
	int Length();
	void Push(const T &item);
	T Pop();
	T GetTop();
	void Clear();
};
//幹캯
template <class T>
LinkStack<T>::LinkStack()
{
	top = NULL;
}

//
template <class T>
LinkStack<T>::~LinkStack()
{
	Clear();
}
//жջǷΪ
template <class T>
bool LinkStack<T>::IsEmpty()
{
	return(!top);
}
//ջĳ
template <class T>
int LinkStack<T>::Length()
{
	StackNode<T> *temp = new StackNode<T>();
	temp = top;
	int length = 0;
	while (temp)
	{
		temp = temp->next;
		length++;
	}
	return length;
}
//ѹջ
template <class T>
void LinkStack<T>::Push(const T &item)
{
	top = new StackNode<T>(item, top);
}
// (ջ)
template <class T>
T LinkStack<T>::Pop()
{
	if (!IsEmpty())
	{
		StackNode<T> *temp = top;
		top = top->next;
		T value = temp->data;
		delete temp;
		return value;
	}
	else
	{
		cout << "Stack is Empty" << endl;
		exit(1);
	}
}
//ȡջ
template<class T>
T LinkStack<T>::GetTop()
{
	if (!IsEmpty())
		return top->data;
	else
	{
		cout << "The Stack is Empty" << endl;
		exit(1);
	}
}
//ջ
template<class T>
void LinkStack<T>::Clear()
{
	StackNode<T> *temp = new StackNode<T>();
	while (top)
	{
		temp = top;
		top = top->next;
		delete temp;
	}
}
/*
		DFA
*/
//DFA캯
DFA::DFA()
{
	Regex = new char[128];
	RegexPost = new char[128];
	EdgeNum = new char[128];
	EdgeNumber = 0;
	DFAStatesNumber = 0;
	NFAStatesNumber = 0;
	DtranNumber = 0;
	NFATable = new AdjacentTable();
	DFATable = new AdjacentTable();
}
//DFA
DFA::~DFA()
{
	delete[] Regex;
	delete[] RegexPost;
	//delete[] Edge;
	//delete[] AcceptStates;
	//NFATable->Clear();
	//DFATable->clear();
}
//ȡ
void DFA::InputRegex()
{
	cout << " ʽ" << endl;
	cin >> Regex;
}
//"."
void DFA::InsertNode()
{
	int i = 0,j, len = strlen(Regex);
	int length = len;
	len--;
	while (len--)
	{
		if (((Regex[i] != '(' && Regex[i] != '.' && Regex[i] != '|')
			|| Regex[i] == ')'|| Regex[i] == '*')
			&& (Regex[i + 1] != ')' && Regex[i + 1] != '.' && Regex[i + 1] != '|' && Regex[i + 1] != '*'))
		{
			for (j =length; j >i;j--)
			{
				Regex[j+1] = Regex[j];
			}
			Regex[i + 1] = '.';
			length++;
			Regex[length] = '\0';
			i++;
		}
		i++;
	}
	cout << endl;
	cout << "     " << endl;
	cout<<Regex << endl;
	cout << "ַȣ" <<length<<endl;
}
//жȼ
int DFA::Precedence(char symbol)
{
	int priority;
	switch (symbol)
	{
	case '|':priority = 1; break;
	case '.':priority = 2; break;
	case '*':priority = 3; break;
	default:priority = 0; break;
	}
	return priority;
}
//ʽתΪ沨ʽ
void DFA::RegextoPost()
{
	int i = 0, j = 0;
	char ch, cl;
	strcpy(RegexPost, "\0");
	LinkStack<char> *Value = new LinkStack<char>();
	Value->Clear();
	ch = Regex[i];
	Value->Push('#');
	ch = Regex[i];
	while (ch != '\0')
	{
		if (ch == '(')
		{
			Value->Push(ch);
			ch = Regex[++i];
		}
		else if (ch == ')')
		{
			while (Value->GetTop() != '(')
			{
				RegexPost[j++] = Value->Pop();
			}
			Value->Pop();
			ch = Regex[++i];
		}
		else if ((ch == '|') || (ch == '*') || (ch == '.'))
		{
			cl = Value->GetTop();
			while (Precedence(cl) >= Precedence(ch))
			{
				RegexPost[j++] = cl;
				Value->Pop();
				cl = Value->GetTop();
			}
			Value->Push(ch);
			ch = Regex[++i];
		}
		else
		{
			RegexPost[j++] = ch;
			ch = Regex[++i];
		}
	}
	ch = Value->Pop();
	while ((ch == '|') || (ch == '*') || (ch == '.'))
	{
		RegexPost[j++] = ch;
		ch = Value->Pop();
	}
	RegexPost[j] = '\0';
	Value->Clear();
	cout << "\nڶ: תΪ׺ʽ\n"
		<< RegexPost << "\n"
		<< "ַ: " << strlen(RegexPost)
		<< "\n\n------------------------" << endl;
}
//ɨ沨ʽгַĿ
void DFA::GetEdgeNumber()
{
	int i = 0, j;
	EdgeNumber = 0;
	while (RegexPost[i] != '\0')
	{
		if (RegexPost[i] == '.' || RegexPost[i] == '|' || RegexPost[i] == '*')
		{
			i++;
			continue;
		}
		for (j = 0; j < EdgeNumber; j++)
		{
			if (RegexPost[i] == EdgeNum[j])
				break;
		}
		if (j == EdgeNumber)
		{
			EdgeNum[EdgeNumber] = RegexPost[i];
			EdgeNumber++;
		}
		i++;
	}
	EdgeNum[EdgeNumber] = '\0';
	cout << "\n: ȡַ\n";
	for (i = 0; i<EdgeNumber; i++)
	{
		cout << EdgeNum[i] << ' ';
	}
	cout << "\nַ: " << EdgeNumber
		<< "\n\n------------------------" << endl;
}

//Thompson취NFA
void DFA::Thompson()
{
	int i, j;
	char ch;
	int s1, s2;
	LinkStack<int >*States = new LinkStack<int >();
	States->Clear();
	if (strlen(RegexPost) < 1)
	{
		cout << "No Regex Expression Find" << endl;
		exit(1);
	}
	i = 1; j = 0;
	ch = RegexPost[j];
	while (ch != '\0')
	{
		if (ch == '.')
		{
			s2 = States->Pop();
			int Ex1 = States->Pop();
			int Ex2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertEdgeByValue(Ex2, Ex1, '~');
			States->Push(s1);
			States->Push(s2);
		}
		else if (ch == '*')
		{
			s2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, i + 1, '~');
			NFATable->InsertEdgeByValue(s2, s1, '~');
			NFATable->InsertEdgeByValue(i, s1, '~');
			NFATable->InsertEdgeByValue(s2, i + 1, '~');
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		else if (ch == '|')
		{
			s2 = States->Pop();
			int temp1 = States->Pop();
			int temp2 = States->Pop();
			s1 = States->Pop();
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, s1, '~');
			NFATable->InsertEdgeByValue(i, temp1, '~');
			NFATable->InsertEdgeByValue(temp2, i + 1, '~');
			NFATable->InsertEdgeByValue(s2, i + 1, '~');
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		else
		{
			NFATable->InsertVertex(i);
			NFATable->InsertVertex(i + 1);
			NFATable->InsertEdgeByValue(i, i + 1, ch);
			s1 = i;
			s2 = i + 1;
			States->Push(s1);
			States->Push(s2);
			i += 2;
		}
		j++;
		ch = RegexPost[j];
	}
	s2 = States->Pop();
	s1 = States->Pop();
	NFAStatesNumber = s2 + 1;
}
void SetNFANodeAll(int (*A)[100])
{
	for (int i = 0; i < 101;i++)
	for (int j = 0; j < 101; j++)
		A[i][j] = 0;
}
//Ӽ취 NFADFA
void DFA::NFAtoDFA()
{
	int states, update=0;
	int VertexNode[1001];
	queue<int > DFAStates;//DFA״̬
	queue<int >NFANode;//NFA״̬Ӽ
	int NFANodeAll[100][100];
	SetNFANodeAll(NFANodeAll);
	DFAStates.push(1);
	int Pointer = 0;
	for (int i = 0; i < NFATable->numOfVertexs; i++)
		VertexNode[i] = 0;//һ飬洢Ƿʹ
	states = DFAStates.front();//DFA״̬еĵһ
	update = states;
	/*
		1״̬ʼҳλ
	*/
	for (int i = 0; i < EdgeNumber; i++)
	{
		char weight = EdgeNum[i];
		Vertex *P = new Vertex;
		P = NFATable->StartVertex;
		for (int j = 0; j < states; j++)
			P = P->Next;
		if (P->Out->Link == NULL)
		{
			if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
				NFANode.push(P->Out->position);
			VertexNode[P->Out->position] = 1;
		}
		while (P->Out->Link != NULL)
		{
			if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
				NFANode.push(P->Out->position);
			VertexNode[P->Out->position] = 1;
		}
		if (NFANode.empty())
			break;
		states++;
		while (!NFANode.empty())
		{
			int Visual = NFANode.front();
			NFANode.pop();
			NFANodeAll[states][Pointer] = Visual;
			Pointer++;
			P = NFATable->StartVertex;
			for (int j = 0; j < Visual; j++)
				P = P->Next;
			if (P->Out&&P->Out->Link == NULL)
			{
				if (P->Out->weight == '~'&&VertexNode[P->Out->position] == 0)//ûбʹ
					NFANode.push(P->Out->position);
				VertexNode[P->Out->position] = 1;
			}
			else if (P->Out)
			{
				if (P->Out->weight == '~'&&VertexNode[P->Out->position] == 0)//ûбʹ
					NFANode.push(P->Out->position);
				VertexNode[P->Out->position] = 1;
				Edge *LinkNode= P->Out->Link;
				while (LinkNode!= NULL)
				{
					if (LinkNode->weight == '~'&&VertexNode[LinkNode->position] == 0)
						NFANode.push(LinkNode->position);
					VertexNode[P->Out->position] = 1;
					LinkNode = LinkNode->Link;
				}
			}
		}
		DFATable->InsertEdgeByValue(1, states, EdgeNum[i]);
	}
	update = states - update;
	NFAStatesNumber = 1;
	/*
		1״̬óNFA״̬ȥ
	*/
	while (update != 0)
	{
		VertexNode[1001] = { 0 };
		for (int j = 0; j < EdgeNumber; j++)
		{
			int i = 0;
			char weight = EdgeNum[j];
			while (NFANodeAll[NFAStatesNumber][i] != 0)
			{
				Vertex *P = new Vertex;
				P = NFATable->StartVertex;
				for (int i = 0; i < NFANodeAll[NFAStatesNumber][i]; i++)
					P = P->Next;
				if (P->Out->Link == NULL)
				{
					if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
						NFANode.push(P->Out->position);
					VertexNode[P->Out->position] = 1;
				}
				while (P->Out->Link != NULL)
				{
					if (P->Out->weight == weight&&VertexNode[P->Out->position] == 0)//ûбʹ
						NFANode.push(P->Out->position);
					VertexNode[P->Out->position] = 1;
				}
				if (NFANode.empty())
					break;
				states++;
				update++;
				while (!NFANode.empty())
				{

				}

			}
		}
	}

}<|endoftext|>


<commit_before>#include "fast++.hpp"
#include <phypp/core/main.hpp>

const char* fastpp_version = "1.0";

const constexpr uint_t grid_id::z;
const constexpr uint_t grid_id::av;
const constexpr uint_t grid_id::age;
const constexpr uint_t grid_id::metal;
const constexpr uint_t grid_id::custom;

const constexpr uint_t prop_id::scale;
const constexpr uint_t prop_id::spec_scale;
const constexpr uint_t prop_id::mass;
const constexpr uint_t prop_id::sfr;
const constexpr uint_t prop_id::ssfr;
const constexpr uint_t prop_id::ldust;
const constexpr uint_t prop_id::lion;
const constexpr uint_t prop_id::mform;
const constexpr uint_t prop_id::custom;

int phypp_main(int argc, char* argv[]) {
    std::string param_file = (argc >= 2 ? argv[1] : "fast.param");

    // Read input data
    options_t opts;
    input_state_t input;
    if (!read_input(opts, input, param_file)) {
        return 1;
    }

    // Initialize the grid
    output_state_t output;
    gridder_t gridder(opts, input, output);
    if (!gridder.check_options()) {
        return 1;
    }

    if (opts.make_seds.empty()) {
        // Initizalize the fitter
        fitter_t fitter(opts, input, gridder, output);

        // Build/read the grid and fit galaxies
        if (!gridder.build_and_send(fitter)) {
            return 1;
        }

        // Compile results
        fitter.find_best_fits();

        // Write output to disk
        write_output(opts, input, gridder, output);
    } else {
        // Write SEDs if asked
        gridder.write_seds();
    }

    return 0;
}
<commit_msg>Changed version number to 1.1<commit_after>#include "fast++.hpp"
#include <phypp/core/main.hpp>

const char* fastpp_version = "1.1";

const constexpr uint_t grid_id::z;
const constexpr uint_t grid_id::av;
const constexpr uint_t grid_id::age;
const constexpr uint_t grid_id::metal;
const constexpr uint_t grid_id::custom;

const constexpr uint_t prop_id::scale;
const constexpr uint_t prop_id::spec_scale;
const constexpr uint_t prop_id::mass;
const constexpr uint_t prop_id::sfr;
const constexpr uint_t prop_id::ssfr;
const constexpr uint_t prop_id::ldust;
const constexpr uint_t prop_id::lion;
const constexpr uint_t prop_id::mform;
const constexpr uint_t prop_id::custom;

int phypp_main(int argc, char* argv[]) {
    std::string param_file = (argc >= 2 ? argv[1] : "fast.param");

    // Read input data
    options_t opts;
    input_state_t input;
    if (!read_input(opts, input, param_file)) {
        return 1;
    }

    // Initialize the grid
    output_state_t output;
    gridder_t gridder(opts, input, output);
    if (!gridder.check_options()) {
        return 1;
    }

    if (opts.make_seds.empty()) {
        // Initizalize the fitter
        fitter_t fitter(opts, input, gridder, output);

        // Build/read the grid and fit galaxies
        if (!gridder.build_and_send(fitter)) {
            return 1;
        }

        // Compile results
        fitter.find_best_fits();

        // Write output to disk
        write_output(opts, input, gridder, output);
    } else {
        // Write SEDs if asked
        gridder.write_seds();
    }

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tbx_ww.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2004-07-06 12:26:23 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SD_TBX_WW_HXX
#define _SD_TBX_WW_HXX

#ifndef _SDRESID_HXX
#include <sdresid.hxx>
#endif

#ifndef _SFXTBXMGR_HXX //autogen
#include <sfx2/tbxmgr.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

//------------------------------------------------------------------------

/*
class SdPopupWindowTbx : public SfxPopupWindow
{
private:
    SfxToolBoxManager   aTbx;
    SdResId             aSdResIdWin;
    SdResId             aSdResIdTbx;
    WindowAlign         eTbxAlign;
    Link                aSelectLink;

    DECL_LINK( TbxSelectHdl, ToolBox * );

public:
    SdPopupWindowTbx( USHORT nId, WindowAlign eAlign,
                      SdResId aRIdWin, SdResId aRIdTbx, SfxBindings& rBindings );
    ~SdPopupWindowTbx();

    virtual SfxPopupWindow* Clone() const;

    virtual void PopupModeEnd();

    void         StartSelection() { aTbx.GetToolBox().StartSelection(); }
    void         Update();

private:

    // Adapt the toolbox to whether CTL is active or not.  If CTL is not
    //    active then all toolbox items that describe CTL specific shapes are
    //    deleted from it and its size is re-calculated.
    void AdaptToCTL (void);
};
*/
//------------------------------------------------------------------------

class SdTbxControl : public SfxToolBoxControl
{
private:
    BOOL    IsCheckable( USHORT nSId );

public:
            SFX_DECL_TOOLBOX_CONTROL();

            SdTbxControl(USHORT nSlotId, USHORT nId, ToolBox& rTbx );
            ~SdTbxControl() {}

    virtual SfxPopupWindowType  GetPopupWindowType() const;
    virtual SfxPopupWindow*     CreatePopupWindow();
    virtual void StateChanged( USHORT nSId, SfxItemState eState,
                                const SfxPoolItem* pState );
};

#endif      // _SD_TBX_WW_HXX

<commit_msg>INTEGRATION: CWS fwkbugfix04 (1.4.190); FILE MERGED 2004/12/15 12:06:59 mba 1.4.190.1: obsolete sfx headers removed<commit_after>/*************************************************************************
 *
 *  $RCSfile: tbx_ww.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-18 15:18:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SD_TBX_WW_HXX
#define _SD_TBX_WW_HXX

#ifndef _SDRESID_HXX
#include <sdresid.hxx>
#endif

#ifndef _SFXTBXCTRL_HXX //autogen
#include <sfx2/tbxctrl.hxx>
#endif

//------------------------------------------------------------------------

/*
class SdPopupWindowTbx : public SfxPopupWindow
{
private:
    SfxToolBoxManager   aTbx;
    SdResId             aSdResIdWin;
    SdResId             aSdResIdTbx;
    WindowAlign         eTbxAlign;
    Link                aSelectLink;

    DECL_LINK( TbxSelectHdl, ToolBox * );

public:
    SdPopupWindowTbx( USHORT nId, WindowAlign eAlign,
                      SdResId aRIdWin, SdResId aRIdTbx, SfxBindings& rBindings );
    ~SdPopupWindowTbx();

    virtual SfxPopupWindow* Clone() const;

    virtual void PopupModeEnd();

    void         StartSelection() { aTbx.GetToolBox().StartSelection(); }
    void         Update();

private:

    // Adapt the toolbox to whether CTL is active or not.  If CTL is not
    //    active then all toolbox items that describe CTL specific shapes are
    //    deleted from it and its size is re-calculated.
    void AdaptToCTL (void);
};
*/
//------------------------------------------------------------------------

class SdTbxControl : public SfxToolBoxControl
{
private:
    BOOL    IsCheckable( USHORT nSId );

public:
            SFX_DECL_TOOLBOX_CONTROL();

            SdTbxControl(USHORT nSlotId, USHORT nId, ToolBox& rTbx );
            ~SdTbxControl() {}

    virtual SfxPopupWindowType  GetPopupWindowType() const;
    virtual SfxPopupWindow*     CreatePopupWindow();
    virtual void StateChanged( USHORT nSId, SfxItemState eState,
                                const SfxPoolItem* pState );
};

#endif      // _SD_TBX_WW_HXX

<|endoftext|>


<commit_before>// Ewmh.hh for fluxbox
// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen<at>fluxbox.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Ewmh.hh,v 1.16 2004/01/21 09:37:04 fluxgen Exp $

#include "AtomHandler.hh"

#include <X11/Xatom.h>
#include <vector>
#include <map>

/// Implementes Extended Window Manager Hints ( http://www.freedesktop.org/Standards/wm-spec )
class Ewmh:public AtomHandler {
public:

    Ewmh();
    ~Ewmh();
    void initForScreen(BScreen &screen);
    void setupFrame(FluxboxWindow &win);
    void setupClient(WinClient &winclient);

    void updateFocusedWindow(BScreen &screen, Window win);
    void updateClientList(BScreen &screen);
    void updateWorkspaceNames(BScreen &screen);
    void updateCurrentWorkspace(BScreen &screen);
    void updateWorkspaceCount(BScreen &screen);
    void updateViewPort(BScreen &screen);
    void updateGeometry(BScreen &screen);
    void updateWorkarea(BScreen &screen);

    void updateState(FluxboxWindow &win);
    void updateLayer(FluxboxWindow &win);
    void updateHints(FluxboxWindow &win);
    void updateWorkspace(FluxboxWindow &win);

    bool checkClientMessage(const XClientMessageEvent &ce,
                            BScreen * screen, WinClient * const winclient);

    bool propertyNotify(WinClient &winclient, Atom the_property);
    void updateFrameClose(FluxboxWindow &win);

    //ignore this one
    void updateClientClose(WinClient &winclient) {}

    void setFullscreen(FluxboxWindow &win, bool value);

private:

    typedef struct WindowState {
        WindowState(int x, int y, unsigned int width, unsigned int height, int layer, unsigned int decor);
        int x, y, layer;
        unsigned int width, height, decor;
    } WindowState;

    enum { STATE_REMOVE = 0, STATE_ADD = 1, STATE_TOGGLE = 2};

    void setState(FluxboxWindow &win, Atom state, bool value);
    void toggleState(FluxboxWindow &win, Atom state);
    void createAtoms();
    void updateStrut(WinClient &winclient);

    // root window properties
    Atom m_net_supported, m_net_client_list, m_net_client_list_stacking,
        m_net_number_of_desktops, m_net_desktop_geometry, m_net_desktop_viewport,
        m_net_current_desktop, m_net_desktop_names, m_net_active_window, m_net_workarea,
        m_net_supporting_wm_check, m_net_virtual_roots, m_net_moveresize_window;

    // root window messages
    Atom m_net_close_window, m_net_wm_moveresize;

    // application window properties
    Atom m_net_properties, m_net_wm_name, m_net_wm_desktop,
        // types
        m_net_wm_window_type,
        m_net_wm_window_type_dock,

        // states
        m_net_wm_state, m_net_wm_state_sticky, m_net_wm_state_shaded,
	m_net_wm_state_maximized_horz, m_net_wm_state_maximized_vert,
        m_net_wm_state_fullscreen,
        m_net_wm_state_hidden,
        m_net_wm_state_skip_taskbar,
        m_net_wm_state_below,
        m_net_wm_state_above,

        m_net_wm_strut, m_net_wm_icon_geometry, m_net_wm_icon, m_net_wm_pid,
        m_net_wm_handled_icons;

    // application protocols
    Atom m_net_wm_ping;

    std::vector<Window> m_windows;
    typedef std::map<FluxboxWindow *, WindowState *> SavedState;
    SavedState m_savedstate;

    WindowState *getState(FluxboxWindow &win);
    void clearState(FluxboxWindow &win);
    void saveState(FluxboxWindow &win, WindowState *state);

};
<commit_msg>minor updates<commit_after>// Ewmh.hh for fluxbox
// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen<at>fluxbox.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Ewmh.hh,v 1.17 2004/01/21 15:42:35 fluxgen Exp $

#include "AtomHandler.hh"

#include <X11/Xatom.h>
#include <vector>
#include <map>

/// Implementes Extended Window Manager Hints ( http://www.freedesktop.org/Standards/wm-spec )
class Ewmh:public AtomHandler {
public:

    Ewmh();
    ~Ewmh();
    void initForScreen(BScreen &screen);
    void setupFrame(FluxboxWindow &win);
    void setupClient(WinClient &winclient);

    void updateFocusedWindow(BScreen &screen, Window win);
    void updateClientList(BScreen &screen);
    void updateWorkspaceNames(BScreen &screen);
    void updateCurrentWorkspace(BScreen &screen);
    void updateWorkspaceCount(BScreen &screen);
    void updateViewPort(BScreen &screen);
    void updateGeometry(BScreen &screen);
    void updateWorkarea(BScreen &screen);

    void updateState(FluxboxWindow &win);
    void updateLayer(FluxboxWindow &win);
    void updateHints(FluxboxWindow &win);
    void updateWorkspace(FluxboxWindow &win);

    bool checkClientMessage(const XClientMessageEvent &ce,
                            BScreen * screen, WinClient * const winclient);

    bool propertyNotify(WinClient &winclient, Atom the_property);
    void updateFrameClose(FluxboxWindow &win);

    //ignore this one
    void updateClientClose(WinClient &winclient) {}

    void setFullscreen(FluxboxWindow &win, bool value);

private:

    typedef struct WindowState {
        WindowState(int x, int y, unsigned int width, unsigned int height, int layer, unsigned int decor);
        int x, y, layer;
        unsigned int width, height, decor;
    } WindowState;

    enum { STATE_REMOVE = 0, STATE_ADD = 1, STATE_TOGGLE = 2};

    void setState(FluxboxWindow &win, Atom state, bool value);
    void toggleState(FluxboxWindow &win, Atom state);
    void createAtoms();
    void updateStrut(WinClient &winclient);
    void setupState(FluxboxWindow &win);

    // root window properties
    Atom m_net_supported, m_net_client_list, m_net_client_list_stacking,
        m_net_number_of_desktops, m_net_desktop_geometry, m_net_desktop_viewport,
        m_net_current_desktop, m_net_desktop_names, m_net_active_window, m_net_workarea,
        m_net_supporting_wm_check, m_net_virtual_roots, m_net_moveresize_window;

    // root window messages
    Atom m_net_close_window, m_net_wm_moveresize;

    // application window properties
    Atom m_net_properties, m_net_wm_name, m_net_wm_desktop,
        // types
        m_net_wm_window_type,
        m_net_wm_window_type_dock,

        // states
        m_net_wm_state, m_net_wm_state_sticky, m_net_wm_state_shaded,
	m_net_wm_state_maximized_horz, m_net_wm_state_maximized_vert,
        m_net_wm_state_fullscreen,
        m_net_wm_state_hidden,
        m_net_wm_state_skip_taskbar,
        m_net_wm_state_below,
        m_net_wm_state_above,

        m_net_wm_strut, m_net_wm_icon_geometry, m_net_wm_icon, m_net_wm_pid,
        m_net_wm_handled_icons;

    // application protocols
    Atom m_net_wm_ping;

    std::vector<Window> m_windows;
    typedef std::map<FluxboxWindow *, WindowState *> SavedState;
    SavedState m_savedstate;

    WindowState *getState(FluxboxWindow &win);
    void clearState(FluxboxWindow &win);
    void saveState(FluxboxWindow &win, WindowState *state);

};
<|endoftext|>


<commit_before>//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries.
//===----------------------------------------------------------------------===//

#include "sanitizer_common.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_stacktrace.h"
#include "sanitizer_stacktrace_printer.h"
#include "sanitizer_symbolizer.h"

namespace __sanitizer {

void StackTrace::Print() const {
  if (trace == nullptr || size == 0) {
    Printf("    <empty stack>\n\n");
    return;
  }
  InternalScopedString frame_desc(GetPageSizeCached() * 2);
  uptr frame_num = 0;
  for (uptr i = 0; i < size && trace[i]; i++) {
    // PCs in stack traces are actually the return addresses, that is,
    // addresses of the next instructions after the call.
    uptr pc = GetPreviousInstructionPc(trace[i]);
    SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
    CHECK(frames);
    for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
      frame_desc.clear();
      RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
                  cur->info, common_flags()->symbolize_vs_style,
                  common_flags()->strip_path_prefix);
      Printf("%s\n", frame_desc.data());
    }
    frames->ClearAll();
  }
  // Always print a trailing empty line after stack trace.
  Printf("\n");
}

void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
                                uptr stack_top, uptr stack_bottom,
                                bool request_fast_unwind) {
  top_frame_bp = (max_depth > 0) ? bp : 0;
  // Avoid doing any work for small max_depth.
  if (max_depth == 0) {
    size = 0;
    return;
  }
  if (max_depth == 1) {
    size = 1;
    trace_buffer[0] = pc;
    return;
  }
  if (!WillUseFastUnwind(request_fast_unwind)) {
    if (context)
      SlowUnwindStackWithContext(pc, context, max_depth);
    else
      SlowUnwindStack(pc, max_depth);
  } else {
    FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);
  }
}

}  // namespace __sanitizer
<commit_msg>[sanitizer] add #ifdefs around slow unwinder to fix OS X debug build<commit_after>//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries.
//===----------------------------------------------------------------------===//

#include "sanitizer_common.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_stacktrace.h"
#include "sanitizer_stacktrace_printer.h"
#include "sanitizer_symbolizer.h"

namespace __sanitizer {

void StackTrace::Print() const {
  if (trace == nullptr || size == 0) {
    Printf("    <empty stack>\n\n");
    return;
  }
  InternalScopedString frame_desc(GetPageSizeCached() * 2);
  uptr frame_num = 0;
  for (uptr i = 0; i < size && trace[i]; i++) {
    // PCs in stack traces are actually the return addresses, that is,
    // addresses of the next instructions after the call.
    uptr pc = GetPreviousInstructionPc(trace[i]);
    SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(pc);
    CHECK(frames);
    for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
      frame_desc.clear();
      RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
                  cur->info, common_flags()->symbolize_vs_style,
                  common_flags()->strip_path_prefix);
      Printf("%s\n", frame_desc.data());
    }
    frames->ClearAll();
  }
  // Always print a trailing empty line after stack trace.
  Printf("\n");
}

void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
                                uptr stack_top, uptr stack_bottom,
                                bool request_fast_unwind) {
  top_frame_bp = (max_depth > 0) ? bp : 0;
  // Avoid doing any work for small max_depth.
  if (max_depth == 0) {
    size = 0;
    return;
  }
  if (max_depth == 1) {
    size = 1;
    trace_buffer[0] = pc;
    return;
  }
  if (!WillUseFastUnwind(request_fast_unwind)) {
#if SANITIZER_CAN_SLOW_UNWIND
    if (context)
      SlowUnwindStackWithContext(pc, context, max_depth);
    else
      SlowUnwindStack(pc, max_depth);
#else
    UNREACHABLE("slow unwind requested but not available");
#endif
  } else {
    FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);
  }
}

}  // namespace __sanitizer
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: precompiled_slideshow.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 08:22:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "precompiled_slideshow.hxx"

<commit_msg>INTEGRATION: CWS changefileheader (1.2.92); FILE MERGED 2008/03/31 14:00:12 rt 1.2.92.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: precompiled_slideshow.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "precompiled_slideshow.hxx"

<|endoftext|>


<commit_before>/**
 * @file FixedPriorityQueue_test.cpp
 * @brief Unit tests for the FixedPriorityQueue class.
 * @author Dominique LaSalle <dominique@solidlake.com>
 * Copyright 2017, Solid Lake LLC
 * @version 1
 * @date 2017-10-20
 */

#include "UnitTest.hpp"
#include "FixedPriorityQueue.hpp"

namespace sl
{

UNITTEST(FixedPriortyQueue, AddPopInOrder)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    int const num = pq.pop();
    testEqual(num, i);
  }
}

UNITTEST(FixedPriortyQueue, AddPeek)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  testEqual(pq.peek(), 0);
}

UNITTEST(FixedPriortyQueue, AddMax)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  testEqual(pq.max(), 1.0);
}

UNITTEST(FixedPriortyQueue, AddContains)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.add(1.0/(i+1), i);
    }
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      testTrue(pq.contains(i));
    } else {
      testFalse(pq.contains(i));
    }
  }

}

UNITTEST(FixedPriortyQueue, AddUpdate)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.update(i, i);
    }
  }

  // verify top element
  testEqual(pq.max(), 9);
  testEqual(pq.peek(), 9);

  float lastPriority = pq.max();
  for (int i = 0; i < 10; ++i) {
    float const newPriority = pq.max();
    int const x = pq.pop();

    // verify we're getting them in order
    testLessOrEqual(newPriority, lastPriority);

    // verify we have the right priority
    if (x % 3 == 0) {
      testEqual(newPriority, x);
    } else {
      testEqual(newPriority, static_cast<float>(1.0/(x+1)));
    }

    lastPriority = newPriority;
  }
}

UNITTEST(FixedPriortyQueue, AddPopReverseOrder)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(i/10.0, i);
  }

  for (int i = 10; i > 0;) {
    --i;
    int const num = pq.pop();
    testEqual(num, i);
  }
}

UNITTEST(FixedPriortyQueue, AddRemoveContains)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.remove(i);
    }
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      testFalse(pq.contains(i));
    } else {
      testTrue(pq.contains(i));
    }
  }
}

UNITTEST(FixedPriortyQueue, Clear)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  // remove a couple
  pq.pop();
  pq.pop();

  pq.clear();
  testEqual(0u, pq.size());

  // verify that it is empty
  for (int i = 0; i < 10; ++i) {
    testFalse(pq.contains(i));
  }

  // test that we can re-use the priorty queue again
  for (int i = 0; i < 10; ++i) {
    pq.add(i/10.0, i);
  }

  for (int i = 10; i > 0;) {
    --i;
    int const num = pq.pop();
    testEqual(num, i);
  }
}

}
<commit_msg>Add unit tests<commit_after>/**
 * @file FixedPriorityQueue_test.cpp
 * @brief Unit tests for the FixedPriorityQueue class.
 * @author Dominique LaSalle <dominique@solidlake.com>
 * Copyright 2017, Solid Lake LLC
 * @version 1
 * @date 2017-10-20
 */

#include "UnitTest.hpp"
#include "FixedPriorityQueue.hpp"

namespace sl
{

UNITTEST(FixedPriortyQueue, AddPopInOrder)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    int const num = pq.pop();
    testEqual(num, i);
  }
}

UNITTEST(FixedPriortyQueue, AddPeek)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  testEqual(pq.peek(), 0);
}

UNITTEST(FixedPriortyQueue, AddMax)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  testEqual(pq.max(), 1.0);
}

UNITTEST(FixedPriortyQueue, AddContains)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.add(1.0/(i+1), i);
    }
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      testTrue(pq.contains(i));
    } else {
      testFalse(pq.contains(i));
    }
  }

}

UNITTEST(FixedPriortyQueue, AddUpdate)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.update(i, i);
    }
  }

  // verify top element
  testEqual(pq.max(), 9);
  testEqual(pq.peek(), 9);

  float lastPriority = pq.max();
  for (int i = 0; i < 10; ++i) {
    float const newPriority = pq.max();
    int const x = pq.pop();

    // verify we're getting them in order
    testLessOrEqual(newPriority, lastPriority);

    // verify we have the right priority
    if (x % 3 == 0) {
      testEqual(newPriority, x);
    } else {
      testEqual(newPriority, static_cast<float>(1.0/(x+1)));
    }

    lastPriority = newPriority;
  }
}

UNITTEST(FixedPriortyQueue, UpdateByDelta)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(i, i);
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.updateByDelta(i, i);
    }
  }

  // verify top element
  testEqual(pq.max(), 18);
  testEqual(pq.peek(), 9);

  float lastPriority = pq.max();
  for (int i = 0; i < 10; ++i) {
    float const newPriority = pq.max();
    int const x = pq.pop();

    // verify we're getting them in order
    testLessOrEqual(newPriority, lastPriority);

    // verify we have the right priority
    if (x % 3 == 0) {
      testEqual(newPriority, static_cast<float>(x*2));
    } else {
      testEqual(newPriority, static_cast<float>(x));
    }

    lastPriority = newPriority;
  }
}

UNITTEST(FixedPriortyQueue, AddPopReverseOrder)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(i/10.0, i);
  }

  for (int i = 10; i > 0;) {
    --i;
    int const num = pq.pop();
    testEqual(num, i);
  }
}

UNITTEST(FixedPriortyQueue, AddRemoveContains)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      pq.remove(i);
    }
  }

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      testFalse(pq.contains(i));
    } else {
      testTrue(pq.contains(i));
    }
  }
}

UNITTEST(FixedPriortyQueue, Clear)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  // remove a couple
  pq.pop();
  pq.pop();

  pq.clear();
  testEqual(0u, pq.size());

  // verify that it is empty
  for (int i = 0; i < 10; ++i) {
    testFalse(pq.contains(i));
  }

  // test that we can re-use the priorty queue again
  for (int i = 0; i < 10; ++i) {
    pq.add(i/10.0, i);
  }

  for (int i = 10; i > 0;) {
    --i;
    int const num = pq.pop();
    testEqual(num, i);
  }
}

UNITTEST(FixedPriorityQueue, RemainingAll)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 10; ++i) {
    pq.add(1.0/(i+1), i);
  }

  size_t count = 0;
  for (int const i : pq.remaining()) {
    ++count;
    testTrue(pq.contains(i));
  }

  testEqual(count, pq.size());
}

UNITTEST(FixedPriorityQueue, RemainingHalf)
{
  FixedPriorityQueue<float, int> pq(10);

  for (int i = 0; i < 7; ++i) {
    pq.add(1.0/(i+1), i);
  }

  pq.pop();
  pq.pop();

  size_t count = 0;
  for (int const i : pq.remaining()) {
    ++count;
    testTrue(pq.contains(i));
  }

  testEqual(count, pq.size());
}

}
<|endoftext|>


<commit_before>/*
 * Copyright 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

//
// For reference, see https://developers.google.com/protocol-buffers/docs/encoding#varints
//

#include "bytes.hh"

#include <cstdint>

using vint_size_type = bytes::size_type;

struct unsigned_vint final {
    using value_type = uint64_t;

    struct deserialized_type final {
        value_type value;
        vint_size_type size;
    };

    static vint_size_type serialized_size(value_type) noexcept;

    static vint_size_type serialize(value_type, bytes::iterator out);

    static deserialized_type deserialize(bytes_view v);
};

struct signed_vint final {
    using value_type = int64_t;

    struct deserialized_type final {
        value_type value;
        vint_size_type size;
    };

    static vint_size_type serialized_size(value_type) noexcept;

    static vint_size_type serialize(value_type, bytes::iterator out);

    static deserialized_type deserialize(bytes_view v);
};
<commit_msg>core: add #pragma once to vint-serialization.hh<commit_after>/*
 * Copyright 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

//
// For reference, see https://developers.google.com/protocol-buffers/docs/encoding#varints
//

#pragma once

#include "bytes.hh"

#include <cstdint>

using vint_size_type = bytes::size_type;

struct unsigned_vint final {
    using value_type = uint64_t;

    struct deserialized_type final {
        value_type value;
        vint_size_type size;
    };

    static vint_size_type serialized_size(value_type) noexcept;

    static vint_size_type serialize(value_type, bytes::iterator out);

    static deserialized_type deserialize(bytes_view v);
};

struct signed_vint final {
    using value_type = int64_t;

    struct deserialized_type final {
        value_type value;
        vint_size_type size;
    };

    static vint_size_type serialized_size(value_type) noexcept;

    static vint_size_type serialize(value_type, bytes::iterator out);

    static deserialized_type deserialize(bytes_view v);
};
<|endoftext|>


<commit_before>/*-
 * Copyright (c) 2005-2008 Benjamin Close <Benjamin.Close@clearchain.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string.h>

#ifdef WIN32
	#include <strstream>
#else /* UNIX */
	#include <iostream>
	#include <unistd.h>
	#include <sys/socket.h>
	#include <fcntl.h>
	#include <errno.h>
#endif

#include "Socket.h"

namespace wcl {

/**
 * For Win32 winsock needs to be initialised before
 * we can use the subsystem. This is done in the first constructor call to
 * Socket. But we need to know if it's been done or not
 */
#ifdef WIN32
static bool win32init = false;
static WORD sockVersion = MAKEWORD(1,1); // We'd like Winsock version 1.1
static WSADATA wsaData;
#endif

/**
 * Constructor, create a socket which has not yet got a file descriptor
 * allocated to it. This can only be called by subclasses to its the sub classes
 * responsibility to create the socket.
 */
Socket::Socket()
{
    this->sockfd = -1;
    memset( &this->address, 0, sizeof( this->address ));

#ifdef WIN32
	if(!win32init){
		WSAStartup(sockVersion, &wsaData);
		win32init=true;
	}
#endif

#if defined(__linux) || defined(MACOSX)
	/* Block the SIGPIPE signal to avoid it being sent when a read on a closed socket happens */
	sigset_t mask;

	/* Initialise the signal mask */
	sigemptyset(&mask);

	/* Add the new signal to the mask */
	sigaddset(&mask, SIGPIPE);

	/* Set the new signal to be blocked */
	sigprocmask(SIG_BLOCK, &mask, NULL);
#endif
}

/**
 * Destructor, this closes the socket if its open
 */
Socket::~Socket()
{
    if ( this->isValid()){
	this->close();
    }
}

/**
 * Close the socket if it is open
 */
void Socket::close()
{
    if ( this->isValid()){
#ifdef WIN32
	::closesocket( this->sockfd );
#else
	::close( this->sockfd );
#endif
	this->sockfd = -1;
    }
}

/**
 * Indicate if the socket object is valid.
 * This is a lightweight call that checks class internals only
 *
 * @return true if the socket object is valid, false if it is not
 */
bool Socket::isValid() const
{
    return (this->sockfd != -1);
}

/**
 * Bind the socket to a given port on any address of the local host
 *
 * @param port The port to bind the socket to
 * @return true if the bind was successful, false if socket was invalid or the bind failed
 */
bool Socket::bind( const unsigned port )
{
    if ( !this->isValid()){
	return false;
    }

    this->address.sin_family = AF_INET;
    this->address.sin_addr.s_addr = INADDR_ANY;
    this->address.sin_port = htons ( port );

    if ( ::bind ( this->sockfd, (struct sockaddr *)&this->address, sizeof(this->address)) == -1 ){
	return false;
    }

    return true;
}

/**
 * Attempt to read data from a socket into a buffer. This method
 * will read data and return as soon as it can. It will not block until
 * the given size has been read. If you want this functionality use readuntil.
 * If the remote socket is closed a SocketException is thrown.
 *
 * @param buffer The buffer to read into
 * @param size The size of the buffer
 * @return The amount of data read if all ok, -1 on a read error, not caused
 *         by the close of a socket, 0 on a graceful close Note, the amount
 *        of data actually read may not match what you requested. This function
 *        will return as soon as some data has been read
 * @throws SocketException if the remote end has forcable closed the socket
 */
ssize_t Socket::read ( void *buffer, size_t size )
{

    if ( !isValid()){
	return -1;
    }

#ifdef WIN32
    ssize_t retval = ::recv(this->sockfd, (char*)buffer, size, 0x0);
    if( retval == SOCKET_ERROR ){
	throw new SocketException(this);
    }
    return retval;
#else
    ssize_t retval = ::read(this->sockfd, buffer, size );
    if ( retval == -1 ){
	throw new SocketException(this);
    }
    return retval;
#endif
}

/**
 * Attempt to read data from a socket into a buffer. This method
 * will block until the requested size has been read. If you don't want
 * the socket to block, (even if it's nonblocking) use read. Please note
 * if using this on a blocking socket, it will act like a busy loop thrashing.
 *
 * @param buffer The buffer to read into
 * @param size The amount of data to read, the buffer msut be at least this size
 * @throws SocketException if the remote end has forcable closed the socket
 */
void Socket::readUntil ( void *buffer, size_t size )
{
    ssize_t amount;

    while( size > 0 ){
	amount = this->read( buffer, size );

	// We just can't increment a void * pointer as we don't know what it is
	// pointing too. However, we know that ::read returns in bytes so we
	// cast to a type which can be validly incremented
	buffer = amount + (uint8_t *)buffer;
    }
}

/**
 * Attempt to write size characters from buffer to the socket.
 * This method throws an exception if the remote end has forcable closed
 * the socket.
 *
 * @param buffer The buffer containing the data to write
 * @param size The amount of characters to write, the buffer must be this big
 * @return The amount of charaters written
 * @throws SockcetException if the remote peer has forced the socket * closed
 */
ssize_t Socket::write( const void *buffer, size_t size )
{
    if ( !isValid()){
	return -1;
    }

#ifdef WIN32
    ssize_t retval = ::send(this->sockfd, (const char *)buffer, size, 0x0);
    if ( retval == SOCKET_ERROR ){
	throw new SocketException(this);
    }
    return retval;
#else
    ssize_t retval =  ::write( this->sockfd, buffer, size );
    if ( retval == -1 ){
	throw new SocketException(this);
    }
    return retval;
#endif
}

/**
 * Write the given string to the socket.
 *
 * @param string The string to write
 * @return -1 on failure, or the number of bytes written otherwise
 */
ssize_t Socket::write( const std::string &string )
{
    return this->write( string.c_str(), string.size());
}

/**
 * Set the blocking mode of this socket.
 * The blocking mode of a socket indicates whether read / accept / write calls will
 * block. Win32 does not support non blocking sockets without a HWND hence this library doesnt
 *
 * @param mode The mode to set this socket too
 * @return true if the call was successful, false otherwise
 */
bool Socket::setBlockingMode( const BlockingMode mode)
{
    int flags;

    if ( !isValid()){
	return false;
    }

#ifdef WIN32
	/**
         * Windows does non blocking very, very differently.
	 * hence we don't support it. We return false to indicate this.
	 */
	return false;

#else /* UNIX */
    // In order to set the blocking flag, we must be careful not
    // to stop on any other flags that have been set. Hence
    // we obtain all the flags and adjust the blocking flag only
    flags = ::fcntl(this->sockfd, F_GETFL, 0 /* ALLFLAGS */);

    switch( mode ) {
	case BLOCKING:
	    flags &=~O_NONBLOCK;
	    if ( ::fcntl( this->sockfd, F_SETFL, flags ) == 0 ){
		return true;
	    }
	    break;
	case NONBLOCKING:
	    flags |= O_NONBLOCK;
	    if ( ::fcntl( this->sockfd, F_SETFL, flags ) == 0 ){
		return true;
	    }
	    break;
    }

    return false;
#endif
}

/**
 * Obtain whether the socket is set to blocking or non blocking mode.
 * Note: A windows socket will always be blocking
 *
 * @return BLOCKING or NONBLOCKING depending on the socket state, if the socket has not been setup
 *         then it is in the default state of BLOCKING.
 */
Socket::BlockingMode Socket::getBlockingMode() const
{
#ifdef WIN32
	return BLOCKING;

#else /* UNIX */
    if ( !isValid() || ::fcntl( this->sockfd, F_GETFL, O_NONBLOCK) == 0 ){
		return BLOCKING;
    }
    return NONBLOCKING;
#endif
}

/**
 * Return the file descriptor associated with this socket
 *
 * @return the socket descriptor, -1 if its in error
 */
int Socket::operator *() const
{
    return this->sockfd;
}

/*==============================================================================
 *
 *  SocketException Class Methods
 *
 *=============================================================================*/

/**
 * Construct a socket exception with the specified reason
 *
 * @param reason The reason the exception occurred
 */
SocketException::SocketException( const Socket *s )
{
    this->sockid = **s;

#ifdef WIN32
    this->errornumber  = WSAGetLastError();
#else
    this->errornumber  = errno; /* errno defined in errno.h */
#endif
}

SocketException::~SocketException()
{}

int SocketException::getCause() const
{
	return this->errornumber;
}

/**
 * Obtain the reason why the socket exception was
 * thrown
 *
 * @return The reason this socket exception occurred
 */
const std::string SocketException::getReason() const
{
#ifdef WIN32
    std::strstream s;
    s << "Winsock Errno:";
    s << this->errornumber;
    s << std::ends;
    return s.str();
#else
    return strerror( this->errornumber );
#endif
}

} // namespace wcl
<commit_msg>network: Decrement the amount of bytes read correctly in readuntil<commit_after>/*-
 * Copyright (c) 2005-2008 Benjamin Close <Benjamin.Close@clearchain.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string.h>

#ifdef WIN32
	#include <strstream>
#else /* UNIX */
	#include <iostream>
	#include <unistd.h>
	#include <sys/socket.h>
	#include <fcntl.h>
	#include <errno.h>
#endif

#include "Socket.h"

namespace wcl {

/**
 * For Win32 winsock needs to be initialised before
 * we can use the subsystem. This is done in the first constructor call to
 * Socket. But we need to know if it's been done or not
 */
#ifdef WIN32
static bool win32init = false;
static WORD sockVersion = MAKEWORD(1,1); // We'd like Winsock version 1.1
static WSADATA wsaData;
#endif

/**
 * Constructor, create a socket which has not yet got a file descriptor
 * allocated to it. This can only be called by subclasses to its the sub classes
 * responsibility to create the socket.
 */
Socket::Socket()
{
    this->sockfd = -1;
    memset( &this->address, 0, sizeof( this->address ));

#ifdef WIN32
	if(!win32init){
		WSAStartup(sockVersion, &wsaData);
		win32init=true;
	}
#endif

#if defined(__linux) || defined(MACOSX)
	/* Block the SIGPIPE signal to avoid it being sent when a read on a closed socket happens */
	sigset_t mask;

	/* Initialise the signal mask */
	sigemptyset(&mask);

	/* Add the new signal to the mask */
	sigaddset(&mask, SIGPIPE);

	/* Set the new signal to be blocked */
	sigprocmask(SIG_BLOCK, &mask, NULL);
#endif
}

/**
 * Destructor, this closes the socket if its open
 */
Socket::~Socket()
{
    if ( this->isValid()){
	this->close();
    }
}

/**
 * Close the socket if it is open
 */
void Socket::close()
{
    if ( this->isValid()){
#ifdef WIN32
	::closesocket( this->sockfd );
#else
	::close( this->sockfd );
#endif
	this->sockfd = -1;
    }
}

/**
 * Indicate if the socket object is valid.
 * This is a lightweight call that checks class internals only
 *
 * @return true if the socket object is valid, false if it is not
 */
bool Socket::isValid() const
{
    return (this->sockfd != -1);
}

/**
 * Bind the socket to a given port on any address of the local host
 *
 * @param port The port to bind the socket to
 * @return true if the bind was successful, false if socket was invalid or the bind failed
 */
bool Socket::bind( const unsigned port )
{
    if ( !this->isValid()){
	return false;
    }

    this->address.sin_family = AF_INET;
    this->address.sin_addr.s_addr = INADDR_ANY;
    this->address.sin_port = htons ( port );

    if ( ::bind ( this->sockfd, (struct sockaddr *)&this->address, sizeof(this->address)) == -1 ){
	return false;
    }

    return true;
}

/**
 * Attempt to read data from a socket into a buffer. This method
 * will read data and return as soon as it can. It will not block until
 * the given size has been read. If you want this functionality use readuntil.
 * If the remote socket is closed a SocketException is thrown.
 *
 * @param buffer The buffer to read into
 * @param size The size of the buffer
 * @return The amount of data read if all ok, -1 on a read error, not caused
 *         by the close of a socket, 0 on a graceful close Note, the amount
 *        of data actually read may not match what you requested. This function
 *        will return as soon as some data has been read
 * @throws SocketException if the remote end has forcable closed the socket
 */
ssize_t Socket::read ( void *buffer, size_t size )
{

    if ( !isValid()){
	return -1;
    }

#ifdef WIN32
    ssize_t retval = ::recv(this->sockfd, (char*)buffer, size, 0x0);
    if( retval == SOCKET_ERROR ){
	throw new SocketException(this);
    }
    return retval;
#else
    ssize_t retval = ::read(this->sockfd, buffer, size );
    if ( retval == -1 ){
	throw new SocketException(this);
    }
    return retval;
#endif
}

/**
 * Attempt to read data from a socket into a buffer. This method
 * will block until the requested size has been read. If you don't want
 * the socket to block, (even if it's nonblocking) use read. Please note
 * if using this on a blocking socket, it will act like a busy loop thrashing.
 *
 * @param buffer The buffer to read into
 * @param size The amount of data to read, the buffer msut be at least this size
 * @throws SocketException if the remote end has forcable closed the socket
 */
void Socket::readUntil ( void *buffer, size_t size )
{
    ssize_t amount;

    while( size > 0 ){
	amount = this->read( buffer, size );

	// We just can't increment a void * pointer as we don't know what it is
	// pointing too. However, we know that ::read returns in bytes so we
	// cast to a type which can be validly incremented
	buffer = amount + (uint8_t *)buffer;
	size-=amount;
    }
}

/**
 * Attempt to write size characters from buffer to the socket.
 * This method throws an exception if the remote end has forcable closed
 * the socket.
 *
 * @param buffer The buffer containing the data to write
 * @param size The amount of characters to write, the buffer must be this big
 * @return The amount of charaters written
 * @throws SockcetException if the remote peer has forced the socket * closed
 */
ssize_t Socket::write( const void *buffer, size_t size )
{
    if ( !isValid()){
	return -1;
    }

#ifdef WIN32
    ssize_t retval = ::send(this->sockfd, (const char *)buffer, size, 0x0);
    if ( retval == SOCKET_ERROR ){
	throw new SocketException(this);
    }
    return retval;
#else
    ssize_t retval =  ::write( this->sockfd, buffer, size );
    if ( retval == -1 ){
	throw new SocketException(this);
    }
    return retval;
#endif
}

/**
 * Write the given string to the socket.
 *
 * @param string The string to write
 * @return -1 on failure, or the number of bytes written otherwise
 */
ssize_t Socket::write( const std::string &string )
{
    return this->write( string.c_str(), string.size());
}

/**
 * Set the blocking mode of this socket.
 * The blocking mode of a socket indicates whether read / accept / write calls will
 * block. Win32 does not support non blocking sockets without a HWND hence this library doesnt
 *
 * @param mode The mode to set this socket too
 * @return true if the call was successful, false otherwise
 */
bool Socket::setBlockingMode( const BlockingMode mode)
{
    int flags;

    if ( !isValid()){
	return false;
    }

#ifdef WIN32
	/**
         * Windows does non blocking very, very differently.
	 * hence we don't support it. We return false to indicate this.
	 */
	return false;

#else /* UNIX */
    // In order to set the blocking flag, we must be careful not
    // to stop on any other flags that have been set. Hence
    // we obtain all the flags and adjust the blocking flag only
    flags = ::fcntl(this->sockfd, F_GETFL, 0 /* ALLFLAGS */);

    switch( mode ) {
	case BLOCKING:
	    flags &=~O_NONBLOCK;
	    if ( ::fcntl( this->sockfd, F_SETFL, flags ) == 0 ){
		return true;
	    }
	    break;
	case NONBLOCKING:
	    flags |= O_NONBLOCK;
	    if ( ::fcntl( this->sockfd, F_SETFL, flags ) == 0 ){
		return true;
	    }
	    break;
    }

    return false;
#endif
}

/**
 * Obtain whether the socket is set to blocking or non blocking mode.
 * Note: A windows socket will always be blocking
 *
 * @return BLOCKING or NONBLOCKING depending on the socket state, if the socket has not been setup
 *         then it is in the default state of BLOCKING.
 */
Socket::BlockingMode Socket::getBlockingMode() const
{
#ifdef WIN32
	return BLOCKING;

#else /* UNIX */
    if ( !isValid() || ::fcntl( this->sockfd, F_GETFL, O_NONBLOCK) == 0 ){
		return BLOCKING;
    }
    return NONBLOCKING;
#endif
}

/**
 * Return the file descriptor associated with this socket
 *
 * @return the socket descriptor, -1 if its in error
 */
int Socket::operator *() const
{
    return this->sockfd;
}

/*==============================================================================
 *
 *  SocketException Class Methods
 *
 *=============================================================================*/

/**
 * Construct a socket exception with the specified reason
 *
 * @param reason The reason the exception occurred
 */
SocketException::SocketException( const Socket *s )
{
    this->sockid = **s;

#ifdef WIN32
    this->errornumber  = WSAGetLastError();
#else
    this->errornumber  = errno; /* errno defined in errno.h */
#endif
}

SocketException::~SocketException()
{}

int SocketException::getCause() const
{
	return this->errornumber;
}

/**
 * Obtain the reason why the socket exception was
 * thrown
 *
 * @return The reason this socket exception occurred
 */
const std::string SocketException::getReason() const
{
#ifdef WIN32
    std::strstream s;
    s << "Winsock Errno:";
    s << this->errornumber;
    s << std::ends;
    return s.str();
#else
    return strerror( this->errornumber );
#endif
}

} // namespace wcl
<|endoftext|>