<commit_before>//
// Name:		SceneGraphDlg.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
	#pragma implementation "SceneGraphDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wx/treectrl.h"
#include "wx/image.h"

#include "vtlib/vtlib.h"
#include "vtlib/core/Engine.h"
#include "vtui/wxString2.h"
#include "SceneGraphDlg.h"

#include <typeinfo>
using namespace std;

#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)
#  include "icon1.xpm"
#  include "icon2.xpm"
#  include "icon3.xpm"
#  include "icon4.xpm"
#  include "icon5.xpm"
#  include "icon6.xpm"
#  include "icon7.xpm"
#  include "icon8.xpm"
#  include "icon9.xpm"
#  include "icon10.xpm"
#endif

/////////////////////////////

class MyTreeItemData : public wxTreeItemData
{
public:
	MyTreeItemData(vtNodeBase *pNode, vtEngine *pEngine)
	{
		m_pNode = pNode;
		m_pEngine = pEngine;
	}
	vtNodeBase *m_pNode;
	vtEngine *m_pEngine;
};

// WDR: class implementations

//----------------------------------------------------------------------------
// SceneGraphDlg
//----------------------------------------------------------------------------

// WDR: event table for SceneGraphDlg

BEGIN_EVENT_TABLE(SceneGraphDlg,wxDialog)
	EVT_INIT_DIALOG (SceneGraphDlg::OnInitDialog)
	EVT_TREE_SEL_CHANGED( ID_SCENETREE, SceneGraphDlg::OnTreeSelChanged )
	EVT_CHECKBOX( ID_ENABLED, SceneGraphDlg::OnEnabled )
	EVT_BUTTON( ID_ZOOMTO, SceneGraphDlg::OnZoomTo )
	EVT_BUTTON( ID_REFRESH, SceneGraphDlg::OnRefresh )
END_EVENT_TABLE()

SceneGraphDlg::SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
	wxDialog( parent, id, title, position, size, style )
{
	SceneGraphFunc( this, TRUE );

	m_pZoomTo = GetZoomto();
	m_pEnabled = GetEnabled();
	m_pTree = GetScenetree();

	m_pZoomTo->Enable(false);

	m_imageListNormal = NULL;
	CreateImageList(16);
}

SceneGraphDlg::~SceneGraphDlg()
{
	delete m_imageListNormal;
}

///////////

void SceneGraphDlg::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}
	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	wxIcon icons[10];
	icons[0] = wxICON(icon1);
	icons[1] = wxICON(icon2);
	icons[2] = wxICON(icon3);
	icons[3] = wxICON(icon4);
	icons[4] = wxICON(icon5);
	icons[5] = wxICON(icon6);
	icons[6] = wxICON(icon7);
	icons[7] = wxICON(icon8);
	icons[8] = wxICON(icon9);
	icons[9] = wxICON(icon10);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
	}
	m_pTree->SetImageList(m_imageListNormal);
}

void SceneGraphDlg::RefreshTreeContents()
{
	vtScene* scene = vtGetScene();
	if (!scene)
		return;

	// start with a blank slate
	m_pTree->DeleteAllItems();

	// Fill in the tree with nodes
	m_bFirst = true;
	vtNode *pRoot = scene->GetRoot();
	if (pRoot) AddNodeItemsRecursively(wxTreeItemId(), pRoot, 0);

	wxTreeItemId hRoot = m_pTree->GetRootItem();
	wxTreeItemId hEngRoot = m_pTree->AppendItem(hRoot, _("Engines"), 7, 7);

	vtEngine *pEngine = scene->GetRootEngine();
	if (pEngine) AddEnginesRecursively(hEngRoot, pEngine, 0);
	m_pTree->Expand(hEngRoot);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;
}

void SceneGraphDlg::AddNodeItemsRecursively(wxTreeItemId hParentItem,
										vtNodeBase *pNode, int depth)
{
	wxString str;
	int nImage;
	wxTreeItemId hNewItem;

	if (!pNode) return;

	if (dynamic_cast<vtLight*>(pNode))
	{
		str = _("Light");
		nImage = 4;
	}
	else if (dynamic_cast<vtGeom*>(pNode))
	{
		str = _("Geometry");
		nImage = 2;
	}
	else if (dynamic_cast<vtLOD*>(pNode))
	{
		str = _T("LOD");
		nImage = 5;
	}
	else if (dynamic_cast<vtTransform*>(pNode))
	{
		str = _T("XForm");
		nImage = 9;
	}
	else if (dynamic_cast<vtGroupBase*>(pNode))
	{
		// must be just a group for grouping's sake
		str = _("Group");
		nImage = 3;
	}
	else
	{
		// must be something else
		str = _("Other");
		nImage = 8;
	}
	if (pNode->GetName2())
	{
		str += _T(" \"");
		str += wxString::FromAscii(pNode->GetName2());
		str += _T("\"");
	}

	if (m_bFirst)
	{
		hNewItem = m_pTree->AddRoot(str);
		m_bFirst = false;
	}
	else
		hNewItem = m_pTree->AppendItem(hParentItem, str, nImage, nImage);

	const std::type_info &t1 = typeid(*pNode);
	if (t1 == typeid(vtGeom))
	{
		vtGeom *pGeom = dynamic_cast<vtGeom*>(pNode);
		int num_mesh = pGeom->GetNumMeshes();
		wxTreeItemId	hGeomItem;

		for (int i = 0; i < num_mesh; i++)
		{
			vtMesh *pMesh = pGeom->GetMesh(i);
			if (pMesh)
			{
				int iNumPrim = pMesh->GetNumPrims();
				int iNumVert = pMesh->GetNumVertices();

				GLenum pt = pMesh->GetPrimType();
				const char *mtype="";
				switch (pt)
				{
				case GL_POINTS: mtype = "Points"; break;
				case GL_LINES: mtype = "Lines"; break;
				case GL_LINE_LOOP: mtype = "LineLoop"; break;
				case GL_LINE_STRIP: mtype = "LineStrip"; break;
				case GL_TRIANGLES: mtype = "Triangles"; break;
				case GL_TRIANGLE_STRIP: mtype = "TriStrip"; break;
				case GL_TRIANGLE_FAN: mtype = "TriFan"; break;
				case GL_QUADS: mtype = "Quads"; break;
				case GL_QUAD_STRIP: mtype = "QuadStrip"; break;
				case GL_POLYGON: mtype = "Polygon"; break;
				}
				str.Printf(_("Mesh %d, %hs, %d verts, %d prims"), i, mtype, iNumVert, iNumPrim);
				hGeomItem = m_pTree->AppendItem(hNewItem, str, 6, 6);
			}
			else
				hGeomItem = m_pTree->AppendItem(hNewItem, _("Text Mesh"), 6, 6);
		}
	}

	m_pTree->SetItemData(hNewItem, new MyTreeItemData(pNode, NULL));

	wxTreeItemId hSubItem;
	vtGroupBase *pGroup = dynamic_cast<vtGroupBase*>(pNode);
	if (pGroup)
	{
		int num_children = pGroup->GetNumChildren();
		if (num_children > 200)
		{
			str.Printf(_("(%d children)"), num_children);
			hSubItem = m_pTree->AppendItem(hNewItem, str, 8, 8);
		}
		else
		{
			for (int i = 0; i < num_children; i++)
			{
				vtNode *pChild = pGroup->GetChild(i);
				if (pChild)
					AddNodeItemsRecursively(hNewItem, pChild, depth+1);
				else
					hSubItem = m_pTree->AppendItem(hNewItem, _("(internal node)"), 8, 8);
			}
		}
	}
	// expand a bit so that the tree is initially partially exposed
	if (depth < 2)
		m_pTree->Expand(hNewItem);
}

void SceneGraphDlg::AddEnginesRecursively(wxTreeItemId hParentItem,
										vtEngine *pEng, int depth)
{
	wxTreeItemId hNewItem;

	if (!pEng) return;

	wxString2 str = pEng->GetName2();
	if (str == "")
		str = "unnamed";

	int targets = pEng->NumTargets();
	vtTarget *target = pEng->GetTarget();
	if (target)
	{
		str += _T(" -> ");
		vtNodeBase *node = dynamic_cast<vtNodeBase*>(target);
		if (node)
		{
			str += _T("\"");
			str += wxString::FromAscii(node->GetName2());
			str += _T("\"");
		}
		else
			str += _("(non-node)");
	}
	if (targets > 1)
	{
		wxString2 plus;
		plus.Printf(_(" (%d targets total)"), targets);
		str += plus;
	}

	hNewItem = m_pTree->AppendItem(hParentItem, str, 1, 1);
	m_pTree->SetItemData(hNewItem, new MyTreeItemData(NULL, pEng));

	for (unsigned int i = 0; i < pEng->NumChildren(); i++)
	{
		vtEngine *pChild = pEng->GetChild(i);
		AddEnginesRecursively(hNewItem, pChild, depth+1);
	}

	// always expand engines
	m_pTree->Expand(hNewItem);
}

// WDR: handler implementations for SceneGraphDlg

void SceneGraphDlg::OnRefresh( wxCommandEvent &event )
{
	RefreshTreeContents();
}

void SceneGraphDlg::OnZoomTo( wxCommandEvent &event )
{
	if (m_pSelectedNode)
	{
		FSphere sph;
		m_pSelectedNode->GetBoundSphere(sph, true);	// global bounds

		// a bit back to make sure whole volume of bounding sphere is in view
		vtCamera *pCam = vtGetScene()->GetCamera();
		float smallest = min(pCam->GetFOV(), pCam->GetVertFOV());
		float alpha = smallest / 2.0f;
		float distance = sph.radius / tanf(alpha);
		sph.radius = distance;

		pCam->ZoomToSphere(sph);
	}
}

void SceneGraphDlg::OnEnabled( wxCommandEvent &event )
{
	if (m_pSelectedEngine)
		m_pSelectedEngine->SetEnabled(m_pEnabled->GetValue());
	if (m_pSelectedNode)
		m_pSelectedNode->SetEnabled(m_pEnabled->GetValue());
}

void SceneGraphDlg::OnTreeSelChanged( wxTreeEvent &event )
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)m_pTree->GetItemData(item);

	m_pEnabled->Enable(data != NULL);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;

	if (data && data->m_pEngine)
	{
		m_pSelectedEngine = data->m_pEngine;
		m_pEnabled->SetValue(m_pSelectedEngine->GetEnabled());
	}
	if (data && data->m_pNode)
	{
		m_pSelectedNode = data->m_pNode;
		m_pEnabled->SetValue(m_pSelectedNode->GetEnabled());
		m_pZoomTo->Enable(true);
	}
	else
		m_pZoomTo->Enable(false);
}

void SceneGraphDlg::OnInitDialog(wxInitDialogEvent& event)
{
	RefreshTreeContents();

	wxWindow::OnInitDialog(event);
}

<commit_msg>unicode build fix<commit_after>//
// Name:		SceneGraphDlg.cpp
//
// Copyright (c) 2001-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
	#pragma implementation "SceneGraphDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wx/treectrl.h"
#include "wx/image.h"

#include "vtlib/vtlib.h"
#include "vtlib/core/Engine.h"
#include "vtui/wxString2.h"
#include "SceneGraphDlg.h"

#include <typeinfo>
using namespace std;

#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)
#  include "icon1.xpm"
#  include "icon2.xpm"
#  include "icon3.xpm"
#  include "icon4.xpm"
#  include "icon5.xpm"
#  include "icon6.xpm"
#  include "icon7.xpm"
#  include "icon8.xpm"
#  include "icon9.xpm"
#  include "icon10.xpm"
#endif

/////////////////////////////

class MyTreeItemData : public wxTreeItemData
{
public:
	MyTreeItemData(vtNodeBase *pNode, vtEngine *pEngine)
	{
		m_pNode = pNode;
		m_pEngine = pEngine;
	}
	vtNodeBase *m_pNode;
	vtEngine *m_pEngine;
};

// WDR: class implementations

//----------------------------------------------------------------------------
// SceneGraphDlg
//----------------------------------------------------------------------------

// WDR: event table for SceneGraphDlg

BEGIN_EVENT_TABLE(SceneGraphDlg,wxDialog)
	EVT_INIT_DIALOG (SceneGraphDlg::OnInitDialog)
	EVT_TREE_SEL_CHANGED( ID_SCENETREE, SceneGraphDlg::OnTreeSelChanged )
	EVT_CHECKBOX( ID_ENABLED, SceneGraphDlg::OnEnabled )
	EVT_BUTTON( ID_ZOOMTO, SceneGraphDlg::OnZoomTo )
	EVT_BUTTON( ID_REFRESH, SceneGraphDlg::OnRefresh )
END_EVENT_TABLE()

SceneGraphDlg::SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
	wxDialog( parent, id, title, position, size, style )
{
	SceneGraphFunc( this, TRUE );

	m_pZoomTo = GetZoomto();
	m_pEnabled = GetEnabled();
	m_pTree = GetScenetree();

	m_pZoomTo->Enable(false);

	m_imageListNormal = NULL;
	CreateImageList(16);
}

SceneGraphDlg::~SceneGraphDlg()
{
	delete m_imageListNormal;
}

///////////

void SceneGraphDlg::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}
	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	wxIcon icons[10];
	icons[0] = wxICON(icon1);
	icons[1] = wxICON(icon2);
	icons[2] = wxICON(icon3);
	icons[3] = wxICON(icon4);
	icons[4] = wxICON(icon5);
	icons[5] = wxICON(icon6);
	icons[6] = wxICON(icon7);
	icons[7] = wxICON(icon8);
	icons[8] = wxICON(icon9);
	icons[9] = wxICON(icon10);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
	}
	m_pTree->SetImageList(m_imageListNormal);
}

void SceneGraphDlg::RefreshTreeContents()
{
	vtScene* scene = vtGetScene();
	if (!scene)
		return;

	// start with a blank slate
	m_pTree->DeleteAllItems();

	// Fill in the tree with nodes
	m_bFirst = true;
	vtNode *pRoot = scene->GetRoot();
	if (pRoot) AddNodeItemsRecursively(wxTreeItemId(), pRoot, 0);

	wxTreeItemId hRoot = m_pTree->GetRootItem();
	wxTreeItemId hEngRoot = m_pTree->AppendItem(hRoot, _("Engines"), 7, 7);

	vtEngine *pEngine = scene->GetRootEngine();
	if (pEngine) AddEnginesRecursively(hEngRoot, pEngine, 0);
	m_pTree->Expand(hEngRoot);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;
}

void SceneGraphDlg::AddNodeItemsRecursively(wxTreeItemId hParentItem,
										vtNodeBase *pNode, int depth)
{
	wxString str;
	int nImage;
	wxTreeItemId hNewItem;

	if (!pNode) return;

	if (dynamic_cast<vtLight*>(pNode))
	{
		str = _("Light");
		nImage = 4;
	}
	else if (dynamic_cast<vtGeom*>(pNode))
	{
		str = _("Geometry");
		nImage = 2;
	}
	else if (dynamic_cast<vtLOD*>(pNode))
	{
		str = _T("LOD");
		nImage = 5;
	}
	else if (dynamic_cast<vtTransform*>(pNode))
	{
		str = _T("XForm");
		nImage = 9;
	}
	else if (dynamic_cast<vtGroupBase*>(pNode))
	{
		// must be just a group for grouping's sake
		str = _("Group");
		nImage = 3;
	}
	else
	{
		// must be something else
		str = _("Other");
		nImage = 8;
	}
	if (pNode->GetName2())
	{
		str += _T(" \"");
		str += wxString::FromAscii(pNode->GetName2());
		str += _T("\"");
	}

	if (m_bFirst)
	{
		hNewItem = m_pTree->AddRoot(str);
		m_bFirst = false;
	}
	else
		hNewItem = m_pTree->AppendItem(hParentItem, str, nImage, nImage);

	const std::type_info &t1 = typeid(*pNode);
	if (t1 == typeid(vtGeom))
	{
		vtGeom *pGeom = dynamic_cast<vtGeom*>(pNode);
		int num_mesh = pGeom->GetNumMeshes();
		wxTreeItemId	hGeomItem;

		for (int i = 0; i < num_mesh; i++)
		{
			vtMesh *pMesh = pGeom->GetMesh(i);
			if (pMesh)
			{
				int iNumPrim = pMesh->GetNumPrims();
				int iNumVert = pMesh->GetNumVertices();

				GLenum pt = pMesh->GetPrimType();
				const char *mtype="";
				switch (pt)
				{
				case GL_POINTS: mtype = "Points"; break;
				case GL_LINES: mtype = "Lines"; break;
				case GL_LINE_LOOP: mtype = "LineLoop"; break;
				case GL_LINE_STRIP: mtype = "LineStrip"; break;
				case GL_TRIANGLES: mtype = "Triangles"; break;
				case GL_TRIANGLE_STRIP: mtype = "TriStrip"; break;
				case GL_TRIANGLE_FAN: mtype = "TriFan"; break;
				case GL_QUADS: mtype = "Quads"; break;
				case GL_QUAD_STRIP: mtype = "QuadStrip"; break;
				case GL_POLYGON: mtype = "Polygon"; break;
				}
				str.Printf(_("Mesh %d, %hs, %d verts, %d prims"), i, mtype, iNumVert, iNumPrim);
				hGeomItem = m_pTree->AppendItem(hNewItem, str, 6, 6);
			}
			else
				hGeomItem = m_pTree->AppendItem(hNewItem, _("Text Mesh"), 6, 6);
		}
	}

	m_pTree->SetItemData(hNewItem, new MyTreeItemData(pNode, NULL));

	wxTreeItemId hSubItem;
	vtGroupBase *pGroup = dynamic_cast<vtGroupBase*>(pNode);
	if (pGroup)
	{
		int num_children = pGroup->GetNumChildren();
		if (num_children > 200)
		{
			str.Printf(_("(%d children)"), num_children);
			hSubItem = m_pTree->AppendItem(hNewItem, str, 8, 8);
		}
		else
		{
			for (int i = 0; i < num_children; i++)
			{
				vtNode *pChild = pGroup->GetChild(i);
				if (pChild)
					AddNodeItemsRecursively(hNewItem, pChild, depth+1);
				else
					hSubItem = m_pTree->AppendItem(hNewItem, _("(internal node)"), 8, 8);
			}
		}
	}
	// expand a bit so that the tree is initially partially exposed
	if (depth < 2)
		m_pTree->Expand(hNewItem);
}

void SceneGraphDlg::AddEnginesRecursively(wxTreeItemId hParentItem,
										vtEngine *pEng, int depth)
{
	wxTreeItemId hNewItem;

	if (!pEng) return;

	wxString2 str = pEng->GetName2();
	if (str == wxString2(""))
		str = "unnamed";

	int targets = pEng->NumTargets();
	vtTarget *target = pEng->GetTarget();
	if (target)
	{
		str += _T(" -> ");
		vtNodeBase *node = dynamic_cast<vtNodeBase*>(target);
		if (node)
		{
			str += _T("\"");
			str += wxString::FromAscii(node->GetName2());
			str += _T("\"");
		}
		else
			str += _("(non-node)");
	}
	if (targets > 1)
	{
		wxString2 plus;
		plus.Printf(_(" (%d targets total)"), targets);
		str += plus;
	}

	hNewItem = m_pTree->AppendItem(hParentItem, str, 1, 1);
	m_pTree->SetItemData(hNewItem, new MyTreeItemData(NULL, pEng));

	for (unsigned int i = 0; i < pEng->NumChildren(); i++)
	{
		vtEngine *pChild = pEng->GetChild(i);
		AddEnginesRecursively(hNewItem, pChild, depth+1);
	}

	// always expand engines
	m_pTree->Expand(hNewItem);
}

// WDR: handler implementations for SceneGraphDlg

void SceneGraphDlg::OnRefresh( wxCommandEvent &event )
{
	RefreshTreeContents();
}

void SceneGraphDlg::OnZoomTo( wxCommandEvent &event )
{
	if (m_pSelectedNode)
	{
		FSphere sph;
		m_pSelectedNode->GetBoundSphere(sph, true);	// global bounds

		// a bit back to make sure whole volume of bounding sphere is in view
		vtCamera *pCam = vtGetScene()->GetCamera();
		float smallest = min(pCam->GetFOV(), pCam->GetVertFOV());
		float alpha = smallest / 2.0f;
		float distance = sph.radius / tanf(alpha);
		sph.radius = distance;

		pCam->ZoomToSphere(sph);
	}
}

void SceneGraphDlg::OnEnabled( wxCommandEvent &event )
{
	if (m_pSelectedEngine)
		m_pSelectedEngine->SetEnabled(m_pEnabled->GetValue());
	if (m_pSelectedNode)
		m_pSelectedNode->SetEnabled(m_pEnabled->GetValue());
}

void SceneGraphDlg::OnTreeSelChanged( wxTreeEvent &event )
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)m_pTree->GetItemData(item);

	m_pEnabled->Enable(data != NULL);

	m_pSelectedEngine = NULL;
	m_pSelectedNode = NULL;

	if (data && data->m_pEngine)
	{
		m_pSelectedEngine = data->m_pEngine;
		m_pEnabled->SetValue(m_pSelectedEngine->GetEnabled());
	}
	if (data && data->m_pNode)
	{
		m_pSelectedNode = data->m_pNode;
		m_pEnabled->SetValue(m_pSelectedNode->GetEnabled());
		m_pZoomTo->Enable(true);
	}
	else
		m_pZoomTo->Enable(false);
}

void SceneGraphDlg::OnInitDialog(wxInitDialogEvent& event)
{
	RefreshTreeContents();

	wxWindow::OnInitDialog(event);
}

<|endoftext|>


<commit_before>/*
  MAX1464 library for Arduino
  Copyright (C) 2016 Giacomo Mazzamuto <gmazzamuto@gmail.com>

  This library 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.

  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, see <http://www.gnu.org/licenses/>.
*/

#include "MAX1464.h"

MAX1464::MAX1464(int chipSelect) :
    AbstractMAX1464(chipSelect)
{
    settings = SPISettings(4000000, LSBFIRST, SPI_MODE0);
}

void MAX1464::begin()
{
    SPI.begin();
    enable4WireModeDataTransfer();
}

void MAX1464::byteShiftOut(uint8_t b)
{
#ifdef SERIALDEBUG
    if(debugMsg == NULL)
        debugMsg = "";
    Serial.println(debugMsg);
    debugMsg = NULL;
#endif
    SPI.beginTransaction(settings);
    digitalWrite(_chipSelect, LOW);
    SPI.transfer(b);
    digitalWrite(_chipSelect, HIGH);
    SPI.endTransaction();
}

uint16_t MAX1464::wordShiftIn()
{
    uint16_t w = 0;
    SPI.beginTransaction(settings);
    digitalWrite(_chipSelect, LOW);
    w = SPI.transfer16(0x0000);

    digitalWrite(_chipSelect, HIGH);
    SPI.endTransaction();

    // reverse bits
    uint8_t newVal = 0;
    if (w & 0x1) newVal |= 0x8000;
    if (w & 0x2) newVal |= 0x4000;
    if (w & 0x4) newVal |= 0x2000;
    if (w & 0x8) newVal |= 0x1000;
    if (w & 0x10) newVal |= 0x800;
    if (w & 0x20) newVal |= 0x400;
    if (w & 0x40) newVal |= 0x200;
    if (w & 0x80) newVal |= 0x100;
    if (w & 0x100) newVal |= 0x80;
    if (w & 0x200) newVal |= 0x40;
    if (w & 0x400) newVal |= 0x20;
    if (w & 0x800) newVal |= 0x10;
    if (w & 0x1000) newVal |= 0x8;
    if (w & 0x2000) newVal |= 0x4;
    if (w & 0x4000) newVal |= 0x2;
    if (w & 0x8000) newVal |= 0x1;

    return newVal;
}
<commit_msg>MAX1464: fix bug in byteShiftOut (wrong 8 bit type)<commit_after>/*
  MAX1464 library for Arduino
  Copyright (C) 2016 Giacomo Mazzamuto <gmazzamuto@gmail.com>

  This library 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.

  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, see <http://www.gnu.org/licenses/>.
*/

#include "MAX1464.h"

MAX1464::MAX1464(int chipSelect) :
    AbstractMAX1464(chipSelect)
{
    settings = SPISettings(4000000, LSBFIRST, SPI_MODE0);
}

void MAX1464::begin()
{
    SPI.begin();
    enable4WireModeDataTransfer();
}

void MAX1464::byteShiftOut(uint8_t b)
{
#ifdef SERIALDEBUG
    if(debugMsg == NULL)
        debugMsg = "";
    Serial.println(debugMsg);
    debugMsg = NULL;
#endif
    SPI.beginTransaction(settings);
    digitalWrite(_chipSelect, LOW);
    SPI.transfer(b);
    digitalWrite(_chipSelect, HIGH);
    SPI.endTransaction();
}

uint16_t MAX1464::wordShiftIn()
{
    uint16_t w = 0;
    SPI.beginTransaction(settings);
    digitalWrite(_chipSelect, LOW);

    w = SPI.transfer16(0x0000);

    digitalWrite(_chipSelect, HIGH);
    SPI.endTransaction();

    // reverse bits
    uint16_t newVal = 0;
    if (w & 0x1) newVal |= 0x8000;
    if (w & 0x2) newVal |= 0x4000;
    if (w & 0x4) newVal |= 0x2000;
    if (w & 0x8) newVal |= 0x1000;
    if (w & 0x10) newVal |= 0x800;
    if (w & 0x20) newVal |= 0x400;
    if (w & 0x40) newVal |= 0x200;
    if (w & 0x80) newVal |= 0x100;
    if (w & 0x100) newVal |= 0x80;
    if (w & 0x200) newVal |= 0x40;
    if (w & 0x400) newVal |= 0x20;
    if (w & 0x800) newVal |= 0x10;
    if (w & 0x1000) newVal |= 0x8;
    if (w & 0x2000) newVal |= 0x4;
    if (w & 0x4000) newVal |= 0x2;
    if (w & 0x8000) newVal |= 0x1;

    return newVal;
}
<|endoftext|>


<commit_before>#include "Ubidots.h"
/**
 * Constructor.
 */
Ubidots::Ubidots(char* token, char* dsName) {
    _token = token;
    currentValue = 0;
    val = (Value *)malloc(MAX_VALUES*sizeof(Value));
    _dsName = dsName;
}
/**
 * This function is to get value from the Ubidots API
 * @arg id the id where you will get the data
 * @return num the data that you get from the Ubidots API
 */
float Ubidots::getValueWithDatasource(char* dsName, char* idName) {
  float num;
  int i = 0;
  char* allData = (char *) malloc(sizeof(char) * 300);
  String response;
  uint8_t bodyPosinit;
  sprintf(allData, "Particle|LV|%s|%s:%s|end", _token, _dsName, idName);
  while (!_client.connected() && i < 6) {
        i++;
        _client.connect(SERVER, PORT);
    }
    if (_client.connected()) {  // Connect to the server
#ifdef DEBUG_UBIDOTS
        Serial.println("Client connected");
        Serial.println(allData);
#endif
        _client.println(allData);
        _client.flush();
    }
    i = 50000;
    while (!_client.available()|| i == 0) {
        i--;
    }
    while (_client.available()) {
        char c = _client.read();
        response += c;
    }
    bodyPosinit = 3 + response.indexOf("OK|");
    response = response.substring(bodyPosinit);
    num = response.toFloat();
    currentValue = 0;
    _client.stop();
    free(allData);
    _client.stop();
    return num;
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, double value) {
  add(variable_id, value, NULL);
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, double value, char *ctext1) {
  (val+currentValue)->idName = variable_id;
  (val+currentValue)->idValue = value;
  (val+currentValue)->contextOne = ctext1;
  currentValue++;
  if (currentValue > MAX_VALUES) {
        Serial.println(F("You are sending more than 10 consecutives variables, you just could send 5 variables. Then other variables will be deleted!"));
        currentValue = MAX_VALUES;
  }
}
/**
 * Send all data of all variables that you saved
 * @reutrn true upon success, false upon error.
 */
bool Ubidots::sendAll() {
    int i;
    char* allData = (char *) malloc(sizeof(char) * 700);
    sprintf(allData, "Particle|POST|%s|%s=>", _token, _dsName);
    for (i = 0; i < currentValue; ) {
        sprintf(allData, "%s%s:%f", allData, (val + i)->idName, (val + i)->idValue);
        if ((val + i)->contextOne != NULL) {
            sprintf(allData, "%s$%s", allData, (val + i)->contextOne);
        }
        i++;
        if (i < currentValue) {
            sprintf(allData, "%s,", allData);
        }
    }
    sprintf(allData, "%s|end", allData);
#ifdef DEBUG_UBIDOTS
    Serial.println(allData);
#endif
    while (!_client.connected() && i < 6) {
        i++;
        _client.connect(SERVER, PORT);
    }
    if (_client.connected()) {        // Connect to the server
#ifdef DEBUG_UBIDOTS
        Serial.println("Client connected");
#endif
        _client.println(allData);
        _client.flush();
    }
    i = 50000;
    while (!_client.available() || i == 0) {
        i--;
    }
    while (_client.available()) {
        char c = _client.read();
#ifdef DEBUG_UBIDOTS
        Serial.write(c);
#endif
    }
    currentValue = 0;
    _client.stop();
    free(allData);
    return true;
}
<commit_msg>changed the version and the message of maximum variables<commit_after>#include "Ubidots.h"
/**
 * Constructor.
 */
Ubidots::Ubidots(char* token, char* dsName) {
    _token = token;
    currentValue = 0;
    val = (Value *)malloc(MAX_VALUES*sizeof(Value));
    _dsName = dsName;
}
/**
 * This function is to get value from the Ubidots API
 * @arg id the id where you will get the data
 * @return num the data that you get from the Ubidots API
 */
float Ubidots::getValueWithDatasource(char* dsName, char* idName) {
  float num;
  int i = 0;
  char* allData = (char *) malloc(sizeof(char) * 300);
  String response;
  uint8_t bodyPosinit;
  sprintf(allData, "Particle|LV|%s|%s:%s|end", _token, _dsName, idName);
  while (!_client.connected() && i < 6) {
        i++;
        _client.connect(SERVER, PORT);
    }
    if (_client.connected()) {  // Connect to the server
#ifdef DEBUG_UBIDOTS
        Serial.println("Client connected");
        Serial.println(allData);
#endif
        _client.println(allData);
        _client.flush();
    }
    i = 50000;
    while (!_client.available()|| i == 0) {
        i--;
    }
    while (_client.available()) {
        char c = _client.read();
        response += c;
    }
    bodyPosinit = 3 + response.indexOf("OK|");
    response = response.substring(bodyPosinit);
    num = response.toFloat();
    currentValue = 0;
    _client.stop();
    free(allData);
    _client.stop();
    return num;
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, double value) {
  add(variable_id, value, NULL);
}
/**
 * Add a value of variable to save
 * @arg variable_id variable id to save in a struct
 * @arg value variable value to save in a struct
 */
void Ubidots::add(char *variable_id, double value, char *ctext1) {
  (val+currentValue)->idName = variable_id;
  (val+currentValue)->idValue = value;
  (val+currentValue)->contextOne = ctext1;
  currentValue++;
  if (currentValue > MAX_VALUES) {
        Serial.println(F("You are sending more than the maximum of consecutive variables"));
        currentValue = MAX_VALUES;
  }
}
/**
 * Send all data of all variables that you saved
 * @reutrn true upon success, false upon error.
 */
bool Ubidots::sendAll() {
    int i;
    char* allData = (char *) malloc(sizeof(char) * 700);
    sprintf(allData, "Particle/1.0|POST|%s|%s=>", _token, _dsName);
    for (i = 0; i < currentValue; ) {
        sprintf(allData, "%s%s:%f", allData, (val + i)->idName, (val + i)->idValue);
        if ((val + i)->contextOne != NULL) {
            sprintf(allData, "%s$%s", allData, (val + i)->contextOne);
        }
        i++;
        if (i < currentValue) {
            sprintf(allData, "%s,", allData);
        }
    }
    sprintf(allData, "%s|end", allData);
#ifdef DEBUG_UBIDOTS
    Serial.println(allData);
#endif
    while (!_client.connected() && i < 6) {
        i++;
        _client.connect(SERVER, PORT);
    }
    if (_client.connected()) {        // Connect to the server
#ifdef DEBUG_UBIDOTS
        Serial.println("Client connected");
#endif
        _client.println(allData);
        _client.flush();
    }
    i = 50000;
    while (!_client.available() || i == 0) {
        i--;
    }
    while (_client.available()) {
        char c = _client.read();
#ifdef DEBUG_UBIDOTS
        Serial.write(c);
#endif
    }
    currentValue = 0;
    _client.stop();
    free(allData);
    return true;
}
<|endoftext|>


<commit_before>// FILE: dataperf.cpp
//
// DESCRIPTION:
//
//   Compare relative performance of data types in SystemC
//   by creating long loops and performing arithmetic.
//
// LICENSE:
//
//   Copyright 2014 David C Black
//
//   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
//
//   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.

#include "require_cxx11.h"
#include <cstdint>
#include <cmath>
#include <cassert>
#include <systemc>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <ctime>
#include <string>
#include <cstddef>

using namespace std;
using namespace sc_dt;

namespace {
  chrono::time_point<chrono::system_clock> start, current;
  chrono::duration<double> elapsed_seconds;
  time_t end_time;
  size_t loop_count = 1e8;
}

template<typename T>
void truncate(T& val)
{
  val = T(uint32_t(val)); // Truncate to 32 bits
}

template<>
void truncate<sc_bigint<32>>(sc_bigint<32>& val)
{
}

template<typename T>
void dataperf(void)
{
  cout << "Testing " << typeid(T).name() << " with loop_count=" << loop_count << " " << flush;
  T result =          1;
  T A      = 1103515245; // Linear congruential constants for 32 bit pseudo-random of max length
  T C      =      12345; // result = (A*result + C) & 0xFFFF_FFFF

  start = chrono::system_clock::now();
  for (size_t loop=loop_count; loop!=0; --loop)
  {
    result = A * result + C;     // Computation
    truncate<T>(result);
  }
  cout << "result=" << fixed << setprecision(0) << result << " " << flush; // Ensure compiler doesn't optimize loop out
  current = chrono::system_clock::now();
  elapsed_seconds = current - start;
  end_time = chrono::system_clock::to_time_t(current);
  cout << "elapsed time " << setprecision(6) << elapsed_seconds.count() << "s" << endl;
}

int sc_main(int argc, char* argv[])
{
  for (int i=1; i<argc; ++i) { // Process command-line
    string arg(argv[i]);
    if (arg.length()>1 and string("-help").find(arg) == 0) {
      cout
        << "SYNOPSIS\n"
        << "  " << argv[0] << " [LOOP_COUNT]\n"
        << "EXAMPLES\n"
        << "  " << argv[0] << "1e7\n"
        << endl
        ;
      return 0;
    } else if (arg.find_first_not_of("0123456789e") == string::npos) {
      istringstream is(arg);
      double d;
      is >> d;
      loop_count = d;
      assert(loop_count != 0);
    }//endif
  }

  dataperf<int32_t>();
  dataperf<sc_int<32>>();
  dataperf<sc_bigint<32>>();
  dataperf<double>();
  dataperf<sc_fixed_fast<32,32>>();
  dataperf<sc_fixed<32,32>>();

  cout << "\nCompleted all tests" << endl;
  return 0;
}

//End of file
<commit_msg>formatting<commit_after>// FILE: dataperf.cpp
//
// DESCRIPTION:
//
//   Compare relative performance of data types in SystemC
//   by creating long loops and performing operations on the data.
//
// LICENSE:
//
//   Copyright 2014,2015 David C Black
//
//   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
//
//   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.

#include "require_cxx11.h"
#include <cstdint>
#include <cmath>
#include <cassert>
#include <systemc>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <ctime>
#include <string>
#include <cstddef>

using namespace std;
using namespace sc_dt;

namespace {
  chrono::time_point<chrono::system_clock> start, current;
  chrono::duration<double> elapsed_seconds;
  time_t end_time;
  size_t loop_count = 1e8;
}

template<typename T>
void truncate(T& val)
{
  val = T(uint32_t(val)); // Truncate to 32 bits
}

template<>
void truncate<sc_bigint<32>>(sc_bigint<32>& val)
{
}

template<typename T>
void arithperf(void)
{
  cout << "Testing arithmetic " << typeid(T).name() << " occupies " << sizeof(T) << " bytes with loop_count=" << loop_count << " " << flush;
  T result =          1;
  T A      = 1103515245; // Linear congruential constants for 32 bit pseudo-random of max length
  T C      =      12345; // result = (A*result + C) & 0xFFFF_FFFF

  start = chrono::system_clock::now();
  for (size_t loop=loop_count; loop!=0; --loop)
  {
    // Compute
    result = A * result + C;
    truncate<T>(result);
  }
  cout << "result=" << fixed << setprecision(0) << result << " " << flush; // Ensure compiler doesn't optimize loop out
  current = chrono::system_clock::now();
  elapsed_seconds = current - start;
  end_time = chrono::system_clock::to_time_t(current);
  cout << "elapsed time " << setprecision(6) << elapsed_seconds.count() << "s" << endl;
}

template<typename T>
void logicperf(void)
{
  cout << "Testing logic " << typeid(T).name() << " occupies " << sizeof(T) << " bytes with loop_count=" << loop_count << " " << flush;
  size_t tbits = 8*sizeof(T);
  size_t rbits = 17;
  size_t lbits = tbits - rbits;
  T val    =          1;
  T A      = 1103515245; // Linear congruential constants for 32 bit pseudo-random of max length
  T C      =      12345; // val    = (A^ror(val,rbits) ^ C) & 0xFFFF_FFFF
  T rhs, lhs;

  start = chrono::system_clock::now();
  for (size_t loop=loop_count; loop!=0; --loop)
  {
    // Compute
    rhs = (val >> rbits);
    lhs = ((rhs << rbits)^val);
    val = A ^ ((lhs<<lbits)|rhs) ^ C;
  }
  cout << "result=" << fixed << setprecision(0) << val << " " << flush; // Ensure compiler doesn't optimize loop out
  current = chrono::system_clock::now();
  elapsed_seconds = current - start;
  end_time = chrono::system_clock::to_time_t(current);
  cout << "elapsed time " << setprecision(6) << elapsed_seconds.count() << "s" << endl;
}

int sc_main(int argc, char* argv[])
{
  for (int i=1; i<argc; ++i) { // Process command-line
    string arg(argv[i]);
    if (arg.length()>1 and string("-help").find(arg) == 0) {
      cout
        << "SYNOPSIS\n"
        << "  " << argv[0] << " [LOOP_COUNT]\n"
        << "EXAMPLES\n"
        << "  " << argv[0] << "1e7\n"
        << endl
        ;
      return 0;
    } else if (arg.find_first_not_of("0123456789e") == string::npos) {
      istringstream is(arg);
      double d;
      is >> d;
      loop_count = d;
      assert(loop_count != 0);
    }//endif
  }

  arithperf<int32_t>();
  arithperf<sc_int<32>>();
  arithperf<sc_bigint<32>>();
  arithperf<double>();
  arithperf<sc_fixed_fast<32,32>>();
  arithperf<sc_fixed<32,32>>();

  cout << endl;

  logicperf<int32_t>();
  logicperf<sc_int<32>>();
  logicperf<sc_bigint<32>>();
  logicperf<sc_lv<32>>();
  logicperf<sc_bv<32>>();

  cout << "\nCompleted all tests" << endl;
  return 0;
}

//End of file
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Facebook, Inc.
 *
 * 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
 *
 * 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.
 */

#include "MacAddress.h"

#include "folly/Exception.h"
#include "folly/IPAddressV6.h"

using std::invalid_argument;
using std::string;

namespace folly {

const MacAddress MacAddress::BROADCAST{Endian::big(0xffffffffffffU)};
const MacAddress MacAddress::ZERO;

MacAddress::MacAddress(StringPiece str) {
  memset(&bytes_, 0, 8);
  parse(str);
}

MacAddress MacAddress::createMulticast(IPAddressV6 v6addr) {
  // This method should only be used for multicast addresses.
  DCHECK(v6addr.isMulticast());

  uint8_t bytes[SIZE];
  bytes[0] = 0x33;
  bytes[1] = 0x33;
  memcpy(bytes + 2, v6addr.bytes() + 12, 4);
  return fromBinary(ByteRange(bytes, SIZE));
}

string MacAddress::toString() const {
  static const char hexValues[] = "0123456789abcdef";
  string result;
  result.resize(17);
  result[0] = hexValues[getByte(0) >> 4];
  result[1] = hexValues[getByte(0) & 0xf];
  result[2] = ':';
  result[3] = hexValues[getByte(1) >> 4];
  result[4] = hexValues[getByte(1) & 0xf];
  result[5] = ':';
  result[6] = hexValues[getByte(2) >> 4];
  result[7] = hexValues[getByte(2) & 0xf];
  result[8] = ':';
  result[9] = hexValues[getByte(3) >> 4];
  result[10] = hexValues[getByte(3) & 0xf];
  result[11] = ':';
  result[12] = hexValues[getByte(4) >> 4];
  result[13] = hexValues[getByte(4) & 0xf];
  result[14] = ':';
  result[15] = hexValues[getByte(5) >> 4];
  result[16] = hexValues[getByte(5) & 0xf];
  return result;
}

void MacAddress::parse(StringPiece str) {
  // Helper function to convert a single hex char into an integer
  auto unhex = [](char c) -> int {
    return c >= '0' && c <= '9' ? c - '0' :
           c >= 'A' && c <= 'F' ? c - 'A' + 10 :
           c >= 'a' && c <= 'f' ? c - 'a' + 10 :
           -1;
  };
  auto isSeparatorChar = [](char c) {
    return c == ':' || c == '-';
  };

  uint8_t parsed[SIZE];
  auto p = str.begin();
  for (unsigned int byteIndex = 0; byteIndex < SIZE; ++byteIndex) {
    if (p == str.end()) {
      throw invalid_argument(to<string>("invalid MAC address \"", str,
                                        "\": not enough digits"));
    }

    // Skip over ':' or '-' separators between bytes
    if (byteIndex != 0 && isSeparatorChar(*p)) {
      ++p;
      if (p == str.end()) {
        throw invalid_argument(to<string>("invalid MAC address \"", str,
                                          "\": not enough digits"));
      }
    }

    // Parse the upper nibble
    int upper = unhex(*p);
    if (upper < 0) {
      throw invalid_argument(to<string>("invalid MAC address \"", str,
                                        "\": contains non-hex digit"));
    }
    ++p;

    // Parse the lower nibble
    int lower;
    if (p == str.end()) {
      lower = upper;
      upper = 0;
    } else {
      lower = unhex(*p);
      if (lower < 0) {
        // Also accept ':', '-', or '\0', to handle the case where one
        // of the bytes was represented by just a single digit.
        if (isSeparatorChar(*p)) {
          lower = upper;
          upper = 0;
        } else {
          throw invalid_argument(to<string>("invalid MAC address \"", str,
                                            "\": contains non-hex digit"));
        }
      }
      ++p;
    }

    // Update parsed with the newly parsed byte
    parsed[byteIndex] = ((upper << 4) | lower);
  }

  if (p != str.end()) {
    // String is too long to be a MAC address
    throw invalid_argument(to<string>("invalid MAC address \"", str,
                                      "\": found trailing characters"));
  }

  // Only update now that we have successfully parsed the entire
  // string.  This way we remain unchanged on error.
  setFromBinary(ByteRange(parsed, SIZE));
}

void MacAddress::setFromBinary(ByteRange value) {
  if (value.size() != SIZE) {
    throw invalid_argument(to<string>("MAC address must be 6 bytes "
                                      "long, got ", value.size()));
  }
  memcpy(bytes_ + 2, value.begin(), SIZE);
}

std::ostream& operator<<(std::ostream& os, MacAddress address) {
  os << address.toString();
  return os;
}

} // folly
<commit_msg>Be explicit about what we're passing to Endian::big<commit_after>/*
 * Copyright 2014 Facebook, Inc.
 *
 * 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
 *
 * 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.
 */

#include "MacAddress.h"

#include "folly/Exception.h"
#include "folly/IPAddressV6.h"

using std::invalid_argument;
using std::string;

namespace folly {

const MacAddress MacAddress::BROADCAST{Endian::big(uint64_t(0xffffffffffffU))};
const MacAddress MacAddress::ZERO;

MacAddress::MacAddress(StringPiece str) {
  memset(&bytes_, 0, 8);
  parse(str);
}

MacAddress MacAddress::createMulticast(IPAddressV6 v6addr) {
  // This method should only be used for multicast addresses.
  DCHECK(v6addr.isMulticast());

  uint8_t bytes[SIZE];
  bytes[0] = 0x33;
  bytes[1] = 0x33;
  memcpy(bytes + 2, v6addr.bytes() + 12, 4);
  return fromBinary(ByteRange(bytes, SIZE));
}

string MacAddress::toString() const {
  static const char hexValues[] = "0123456789abcdef";
  string result;
  result.resize(17);
  result[0] = hexValues[getByte(0) >> 4];
  result[1] = hexValues[getByte(0) & 0xf];
  result[2] = ':';
  result[3] = hexValues[getByte(1) >> 4];
  result[4] = hexValues[getByte(1) & 0xf];
  result[5] = ':';
  result[6] = hexValues[getByte(2) >> 4];
  result[7] = hexValues[getByte(2) & 0xf];
  result[8] = ':';
  result[9] = hexValues[getByte(3) >> 4];
  result[10] = hexValues[getByte(3) & 0xf];
  result[11] = ':';
  result[12] = hexValues[getByte(4) >> 4];
  result[13] = hexValues[getByte(4) & 0xf];
  result[14] = ':';
  result[15] = hexValues[getByte(5) >> 4];
  result[16] = hexValues[getByte(5) & 0xf];
  return result;
}

void MacAddress::parse(StringPiece str) {
  // Helper function to convert a single hex char into an integer
  auto unhex = [](char c) -> int {
    return c >= '0' && c <= '9' ? c - '0' :
           c >= 'A' && c <= 'F' ? c - 'A' + 10 :
           c >= 'a' && c <= 'f' ? c - 'a' + 10 :
           -1;
  };
  auto isSeparatorChar = [](char c) {
    return c == ':' || c == '-';
  };

  uint8_t parsed[SIZE];
  auto p = str.begin();
  for (unsigned int byteIndex = 0; byteIndex < SIZE; ++byteIndex) {
    if (p == str.end()) {
      throw invalid_argument(to<string>("invalid MAC address \"", str,
                                        "\": not enough digits"));
    }

    // Skip over ':' or '-' separators between bytes
    if (byteIndex != 0 && isSeparatorChar(*p)) {
      ++p;
      if (p == str.end()) {
        throw invalid_argument(to<string>("invalid MAC address \"", str,
                                          "\": not enough digits"));
      }
    }

    // Parse the upper nibble
    int upper = unhex(*p);
    if (upper < 0) {
      throw invalid_argument(to<string>("invalid MAC address \"", str,
                                        "\": contains non-hex digit"));
    }
    ++p;

    // Parse the lower nibble
    int lower;
    if (p == str.end()) {
      lower = upper;
      upper = 0;
    } else {
      lower = unhex(*p);
      if (lower < 0) {
        // Also accept ':', '-', or '\0', to handle the case where one
        // of the bytes was represented by just a single digit.
        if (isSeparatorChar(*p)) {
          lower = upper;
          upper = 0;
        } else {
          throw invalid_argument(to<string>("invalid MAC address \"", str,
                                            "\": contains non-hex digit"));
        }
      }
      ++p;
    }

    // Update parsed with the newly parsed byte
    parsed[byteIndex] = ((upper << 4) | lower);
  }

  if (p != str.end()) {
    // String is too long to be a MAC address
    throw invalid_argument(to<string>("invalid MAC address \"", str,
                                      "\": found trailing characters"));
  }

  // Only update now that we have successfully parsed the entire
  // string.  This way we remain unchanged on error.
  setFromBinary(ByteRange(parsed, SIZE));
}

void MacAddress::setFromBinary(ByteRange value) {
  if (value.size() != SIZE) {
    throw invalid_argument(to<string>("MAC address must be 6 bytes "
                                      "long, got ", value.size()));
  }
  memcpy(bytes_ + 2, value.begin(), SIZE);
}

std::ostream& operator<<(std::ostream& os, MacAddress address) {
  os << address.toString();
  return os;
}

} // folly
<|endoftext|>


<commit_before>/* ___                                                        _            ___            __ _                       ___   _
  / _ \_ __ ___   ___ ___  ___ ___  __ _ _ __ ___   ___ _ __ | |_ ___     / _ \_ __ __ _ / _(_) ___ ___             / _ \ /_\
 / /_)/ '__/ _ \ / __/ _ \/ __/ __|/ _` | '_ ` _ \ / _ \ '_ \| __/ _ \   / /_\/ '__/ _` | |_| |/ __/ _ \   _____   / /_\///_\\
/ ___/| | | (_) | (_|  __/\__ \__ \ (_| | | | | | |  __/ | | | || (_) | / /_\\| | | (_| |  _| | (_| (_) | |_____| / /_\\/  _  \
\/    |_|  \___/ \___\___||___/___/\__,_|_| |_| |_|\___|_| |_|\__\___/  \____/|_|  \__,_|_| |_|\___\___/          \____/\_/ \_/
								Unisinos 2016 - Vinicius Pegorini Arnhold e Reni Steffenon
*/

#pragma once

#include <Windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include  <stdio.h>
#include <stdlib.h>
#include "Image.h"
#include "PTMReader.h"
#include <iostream>
#include "Layer.h"
#include "Animation.h"

#pragma warning( disable : 4244)//Conversao sempre estara no range

using namespace std;

vector<Layer *> layers;
vector<Animation *> animations;
Image *scene, *backup;
char *zBuffer, *zBuffer2;

//Sprites
int numSpritesLargura = 4;
int numSpritesAltura = 4;
int widthSprites = 0;
int heightSprites = 0;

int xSprite = 0;
int ySprite = 0;

Image imagem;
Image sprite;

void updateScene(int value) {

	Image impressao = imagem.clone();

	widthSprites = floor(sprite.getWidth() / numSpritesLargura);
	heightSprites = floor(sprite.getHeight() / numSpritesAltura);

	Image personagem1(64, 64);

	sprite.subImage(&personagem1, xSprite*widthSprites, ySprite*heightSprites);

	impressao.plot(personagem1, 50, 50);

	if (ySprite == numSpritesAltura - 1 && xSprite == numSpritesLargura - 1) {
		ySprite = 0;
		xSprite = 0;
	}
	else if (xSprite == numSpritesLargura - 1) {
		xSprite = 0;
		ySprite++;
	}
	else {
		xSprite++;
	}

	cout << xSprite << " " << ySprite << endl << widthSprites << " " << heightSprites << endl;

	glClearColor(0.0, 0.0, 0.0, 0.0);
	glDrawPixels(impressao.getWidth(), impressao.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE,
		impressao.getPixels());
	glFlush();

	glutTimerFunc(500, updateScene, 1);
}

void display(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glDrawPixels(imagem.getWidth(), imagem.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE,
		imagem.getPixels());
	glFlush();
}

void keyboard(int key, int x, int y) {
	switch (key)
	{
	case GLUT_KEY_RIGHT:
		for each (Layer* layer in layers)
		{
			layer->scroll(true);
		}
		break;
	case GLUT_KEY_LEFT:
		for each (Layer* layer in layers)
		{
			layer->scroll(false);
		}
		break;
	default:
		break;
	}
}

void init(void)
{
	/*  select clearing (background) color       */
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	/*  initialize viewing values  */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

	/*
		1) carregar imagens das camadas
	*/
	PTMReader leitorFundo = PTMReader();
	leitorFundo.ler("C:\\Users\Administrador\Documents\ProcessamentoGrafico\Imagens\montanhas.ptm");
	imagem = leitorFundo.getImage();

	/*
		2) Inicializar Layers, para cada layer da cena
	*/
	Layer cena1 = Layer(0,0);
	cena1.setBackground(&imagem);
	/*
		3) Carregar animaes objetos do jogo
	*/
		PTMReader leitorPersonagem = PTMReader();
		leitorPersonagem.ler("C:\\Users\Administrador\Documents\ProcessamentoGrafico\Imagens\T-rex.ptm");
		sprite = leitorPersonagem.getImage();
		GameObject personagemDireita = GameObject();
		GameObject personagemEsquerda = GameObject();
		Animation animacaoPersonagemDireita = Animation();
		Animation animacaoPersonagemEsquerda = Animation();
		for (int x = 0; x < sprite.getHeight()+1; x += 242) {
			for (int y = 0; y < sprite.getWidth()/2+1; y += 126) {
				if (x = 242) {
					Image aux = Image(242, 126);
					Image *p = &aux;
					sprite.subImage(p, x, y);
					animacaoPersonagemDireita.addFrame(&aux);
					delete p;
				}
				else {
					Image aux = Image(242, 126);
					Image *p = &aux;
					sprite.subImage(p, x, y);
					animacaoPersonagemEsquerda.addFrame(&aux);
					delete p;
				}
			}
		}
		personagemDireita.setSprite(animacaoPersonagemDireita);
		personagemEsquerda.setSprite(animacaoPersonagemEsquerda);

	/*
		4) Inicializar scene, backup, zBuffer e zBuffer2

	*/
		scene = &imagem;
		Image imagemBackup = imagem;
		backup = &imagemBackup;
		int tamanhox = scene->getHeight();
		char buffer[1600*900];
		char buffer2[1600*900];
		//zBuffer = &buffer;
		//zBuffer2 = &buffer2;

}
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	init();
	glutInitWindowSize(imagem.getWidth(), imagem.getHeight());
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Processamento Grafico - GA");
	glutDisplayFunc(display);
	updateScene(1);
	glutMainLoop();
	return 0;   /* ISO C requires main to return int. */

	//TODO Deletar Ponteiros Criados
}<commit_msg>Fix NullPointers<commit_after>/* ___                                                        _            ___            __ _                       ___   _
  / _ \_ __ ___   ___ ___  ___ ___  __ _ _ __ ___   ___ _ __ | |_ ___     / _ \_ __ __ _ / _(_) ___ ___             / _ \ /_\
 / /_)/ '__/ _ \ / __/ _ \/ __/ __|/ _` | '_ ` _ \ / _ \ '_ \| __/ _ \   / /_\/ '__/ _` | |_| |/ __/ _ \   _____   / /_\///_\\
/ ___/| | | (_) | (_|  __/\__ \__ \ (_| | | | | | |  __/ | | | || (_) | / /_\\| | | (_| |  _| | (_| (_) | |_____| / /_\\/  _  \
\/    |_|  \___/ \___\___||___/___/\__,_|_| |_| |_|\___|_| |_|\__\___/  \____/|_|  \__,_|_| |_|\___\___/          \____/\_/ \_/
								Unisinos 2016 - Vinicius Pegorini Arnhold e Reni Steffenon
*/

#pragma once

#include <Windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include  <stdio.h>
#include <stdlib.h>
#include "Image.h"
#include "PTMReader.h"
#include <iostream>
#include "Layer.h"
#include "Animation.h"

#pragma warning( disable : 4244)//Conversao sempre estara no range

using namespace std;

vector<Layer *> layers;
vector<Animation *> animations;
Image *scene, *backup;
char *zBuffer, *zBuffer2;

//Sprites
int numSpritesLargura = 4;
int numSpritesAltura = 4;
int widthSprites = 0;
int heightSprites = 0;

int xSprite = 0;
int ySprite = 0;

Image imagem;
Image sprite;

void updateScene(int value) {

	Image impressao = imagem.clone();

	widthSprites = floor(sprite.getWidth() / numSpritesLargura);
	heightSprites = floor(sprite.getHeight() / numSpritesAltura);

	Image personagem1(64, 64);

	sprite.subImage(&personagem1, xSprite*widthSprites, ySprite*heightSprites);

	impressao.plot(personagem1, 50, 50);

	if (ySprite == numSpritesAltura - 1 && xSprite == numSpritesLargura - 1) {
		ySprite = 0;
		xSprite = 0;
	}
	else if (xSprite == numSpritesLargura - 1) {
		xSprite = 0;
		ySprite++;
	}
	else {
		xSprite++;
	}

	cout << xSprite << " " << ySprite << endl << widthSprites << " " << heightSprites << endl;

	glClearColor(0.0, 0.0, 0.0, 0.0);
	glDrawPixels(impressao.getWidth(), impressao.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE,
		impressao.getPixels());
	glFlush();

	glutTimerFunc(500, updateScene, 1);
}

void display(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glDrawPixels(imagem.getWidth(), imagem.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE,
		imagem.getPixels());
	glFlush();
}

void keyboard(int key, int x, int y) {
	switch (key)
	{
	case GLUT_KEY_RIGHT:
		for each (Layer* layer in layers)
		{
			layer->scroll(true);
		}
		break;
	case GLUT_KEY_LEFT:
		for each (Layer* layer in layers)
		{
			layer->scroll(false);
		}
		break;
	default:
		break;
	}
}

void init(void)
{
	/*  select clearing (background) color       */
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	/*  initialize viewing values  */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

	/*
		1) carregar imagens das camadas
	*/
	PTMReader leitorFundo = PTMReader();
	leitorFundo.ler("C:\\Users\Administrador\Documents\ProcessamentoGrafico\Imagens\montanhas.ptm");
	imagem = leitorFundo.getImage();

	/*
		2) Inicializar Layers, para cada layer da cena
	*/
	Layer cena1 = Layer(0,0);
	cena1.setBackground(&imagem);
	/*
		3) Carregar anima��es objetos do jogo
	*/
		PTMReader leitorPersonagem = PTMReader();
		leitorPersonagem.ler("C:\\Users\Administrador\Documents\ProcessamentoGrafico\Imagens\T-rex.ptm");
		sprite = leitorPersonagem.getImage();
		GameObject personagemDireita = GameObject();
		GameObject personagemEsquerda = GameObject();
		Animation animacaoPersonagemDireita = Animation();
		Animation animacaoPersonagemEsquerda = Animation();
		for (int x = 0; x < sprite.getHeight()+1; x += 242) {
			for (int y = 0; y < sprite.getWidth()/2+1; y += 126) {
				if (x = 242) {
					Image aux = Image(242, 126);
					Image *p = &aux;
					sprite.subImage(p, x, y);
					animacaoPersonagemDireita.addFrame(&aux);
					delete p;
				}
				else {
					Image aux = Image(242, 126);
					Image *p = &aux;
					sprite.subImage(p, x, y);
					animacaoPersonagemEsquerda.addFrame(&aux);
					delete p;
				}
			}
		}
		personagemDireita.setSprite(animacaoPersonagemDireita);
		personagemEsquerda.setSprite(animacaoPersonagemEsquerda);

	/*
		4) Inicializar scene, backup, zBuffer e zBuffer2

	*/
		scene = &imagem;
		Image imagemBackup = imagem;
		backup = &imagemBackup;
		int tamanhox = scene->getHeight();
		char buffer[1600*900];
		char buffer2[1600*900];
		zBuffer2 = buffer2;
		zBuffer = buffer;

}
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	init();
	glutInitWindowSize(imagem.getWidth(), imagem.getHeight());
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Processamento Grafico - GA");
	glutDisplayFunc(display);
	updateScene(1);
	glutMainLoop();
	return 0;   /* ISO C requires main to return int. */

	//TODO Deletar Ponteiros Criados
}<|endoftext|>


<commit_before>//
// Created by Per Lange Laursen on 08/03/16.
//

#include "Pathfinding.h"

void Pathfinding::addState(int x1, int y1, std::string roadName, int x2, int y2) {
    Heureka::Point point1(x1, y1);
    Heureka::State temp1;
    temp1.point = point1;
    temp1.distanceFromStart = std::numeric_limits<double>::max();
    temp1.heuristic_distance = std::numeric_limits<double>::max();

    Heureka::Point point2(x2, y2);
    Heureka::State temp2;
    temp2.point = point2;
    temp2.distanceFromStart = std::numeric_limits<double>::max();
    temp2.heuristic_distance = std::numeric_limits<double>::max();

    int index1 = checkIfStateExists(temp1);
    int index2 = checkIfStateExists(temp2);
    states[index1].neighbors.push_back(std::make_pair(index2, roadName));
}

void Pathfinding::aStar(Heureka::State start, Heureka::State goal) {
    start.distanceFromStart = 0;
    start.heuristic_distance = start.point.calcEuclideanDistance(goal.point);
    openSet.push_back(start);
    double tempDistanceFromStart;
    std::list<Heureka::State>::iterator iterator;

    while (!openSet.empty()) {
        std::sort(openSet.begin(), openSet.end());
        Heureka::State current = openSet.front();
        if (current == goal) {
            reconstructPath(goal);
            openSet.clear();
            break;
        }
        openSet.pop_front();
        for(std::pair<int, std::string> neighbor : current.neighbors) {
            if (states[neighbor.first].visited) {
                continue;
            }
            tempDistanceFromStart = current.distanceFromStart +
                    current.point.calcEuclideanDistance(states[neighbor.first].point);
            if (tempDistanceFromStart >= states[neighbor.first].distanceFromStart) {
                continue;
            }
            states[neighbor.first].cameFrom = getIndex(current);
            states[neighbor.first].distanceFromStart = tempDistanceFromStart;
            states[neighbor.first].heuristic_distance = states[neighbor.first].point.calcEuclideanDistance(goal.point);
            iterator = std::find(openSet.begin(), openSet.end(), states[neighbor.first]);
            if(iterator != openSet.end()) {
                (*iterator).cameFrom = states[neighbor.first].cameFrom;
                (*iterator).distanceFromStart = states[neighbor.first].distanceFromStart;
                (*iterator).heuristic_distance = states[neighbor.first].heuristic_distance;
            } else {
                openSet.push_front(states[neighbor.first]);
            }
        }
    }
}

void Pathfinding::reconstructPath(Heureka::State goal) {
    std::vector<std::string> path;
    int currentIndex = getIndex(goal);
    std::vector<std::pair<int, std::string>>::iterator iterator;
    while (currentIndex != -1) {
        iterator = std::find_if(goal.neighbors.begin(), goal.neighbors.end(),
                                [](const std::pair<int, std::string>& element) {
                                    return element.first == goal.cameFrom;
                                });
        currentIndex = (*iterator).first;
        path.insert(path.begin(), (*iterator).second);
    }
    std::copy(path.begin(), path.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}

int Pathfinding::checkIfStateExists(Heureka::State state) {
    bool inSet = false;
    int i = 0;
    for(Heureka::State s : states) {
        if(state == s) {
            inSet = true;
        }
    }
    if(!inSet) {
        states.push_back(state);
        i = (int) (states.size() - 1);
    }
    return i;
}

void Pathfinding::aStar(int startIndex, int goalIndex) {
    Heureka::State start = states[startIndex];
    Heureka::State goal = states[goalIndex];
    aStar(start, goal);
}

int Pathfinding::getIndex(Heureka::State s) {
    int i = 0;
    for(auto state : states) {
        if (state == s) return i;
        ++i;
    }
    return -1;
}

<commit_msg>AStar ready for testing + code cleanup<commit_after>//
// Created by Per Lange Laursen on 08/03/16.
//

#include "Pathfinding.h"

void Pathfinding::addState(int x1, int y1, std::string roadName, int x2, int y2) {
    Heureka::Point point1(x1, y1);
    Heureka::State temp1;
    temp1.point = point1;
    temp1.distanceFromStart = std::numeric_limits<double>::max();
    temp1.heuristic_distance = std::numeric_limits<double>::max();
    states.push_back(temp1);

    Heureka::Point point2(x2, y2);
    Heureka::State temp2;
    temp2.point = point2;
    temp2.distanceFromStart = std::numeric_limits<double>::max();
    temp2.heuristic_distance = std::numeric_limits<double>::max();
    states.push_back(temp2);

    int index1 = checkIfStateExists(temp1);
    int index2 = checkIfStateExists(temp2);
    states[index1].neighbors.push_back(std::make_pair(index2, roadName));
}

void Pathfinding::aStar(Heureka::State start, Heureka::State goal) {
    start.distanceFromStart = 0;
    start.heuristic_distance = start.point.calcEuclideanDistance(goal.point);
    openSet.push_back(start);
    double tempDistanceFromStart;
    std::list<Heureka::State>::iterator iterator;

    while (!openSet.empty()) {
        std::sort(openSet.begin(), openSet.end());
        Heureka::State current = openSet.front();
        if (current == goal) {
            reconstructPath(goal);
            openSet.clear();
            break;
        }
        openSet.pop_front();
        for(std::pair<int, std::string> neighbor : current.neighbors) {
            if (states[neighbor.first].visited) {
                continue;
            }
            tempDistanceFromStart = current.distanceFromStart +
                    current.point.calcEuclideanDistance(states[neighbor.first].point);
            if (tempDistanceFromStart >= states[neighbor.first].distanceFromStart) {
                continue;
            }
            states[neighbor.first].cameFrom = getIndex(current);
            states[neighbor.first].distanceFromStart = tempDistanceFromStart;
            states[neighbor.first].heuristic_distance = states[neighbor.first].point.calcEuclideanDistance(goal.point);
            iterator = std::find(openSet.begin(), openSet.end(), states[neighbor.first]);
            if(iterator != openSet.end()) {
                (*iterator).cameFrom = states[neighbor.first].cameFrom;
                (*iterator).distanceFromStart = states[neighbor.first].distanceFromStart;
                (*iterator).heuristic_distance = states[neighbor.first].heuristic_distance;
            } else {
                openSet.push_front(states[neighbor.first]);
            }
        }
    }
}

void Pathfinding::reconstructPath(Heureka::State goal) {
    std::vector<std::string> path;
    int currentIndex = getIndex(goal);
    std::vector<std::pair<int, std::string>>::iterator iterator;
    while (currentIndex != -1) {
        iterator = std::find_if(goal.neighbors.begin(), goal.neighbors.end(),
                                [](const std::pair<int, std::string>& element) {
                                    return element.first == goal.cameFrom;
                                });
        currentIndex = (*iterator).first;
        path.insert(path.begin(), (*iterator).second);
    }
    std::copy(path.begin(), path.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}

int Pathfinding::checkIfStateExists(Heureka::State state) {
    bool inSet = false;
    int i = 0;
    for(Heureka::State s : states) {
        if(state == s) {
            inSet = true;
        }
    }
    if(!inSet) {
        states.push_back(state);
        i = (int) (states.size() - 1);
    }
    return i;
}

void Pathfinding::aStar(int startIndex, int goalIndex) {
    Heureka::State start = states[startIndex];
    Heureka::State goal = states[goalIndex];
    aStar(start, goal);
}

int Pathfinding::getIndex(Heureka::State s) {
    int i = 0;
    for(auto state : states) {
        if (state == s) return i;
        ++i;
    }
    return -1;
}

<|endoftext|>


<commit_before>//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// CodeEmitterGen uses the descriptions of instructions and their fields to
// construct an automated code emitter: a function that, given a MachineInstr,
// returns the (currently, 32-bit unsigned) value of the instruction.
//
//===----------------------------------------------------------------------===//

#include "CodeEmitterGen.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "Support/Debug.h"
using namespace llvm;

void CodeEmitterGen::run(std::ostream &o) {
  CodeGenTarget Target;
  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");

  EmitSourceFileHeader("Machine Code Emitter", o);

  std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";

  //const std::string &Namespace = Inst->getValue("Namespace")->getName();
  o << "unsigned " << Target.getName() << "CodeEmitter::"
    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
    << "  unsigned Value = 0;\n"
    << "  DEBUG(std::cerr << MI);\n"
    << "  switch (MI.getOpcode()) {\n";
  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
       I != E; ++I) {
    Record *R = *I;
    o << "    case " << Namespace << R->getName() << ": {\n"
      << "      DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";

    BitsInit *BI = R->getValueAsBitsInit("Inst");

    unsigned Value = 0;
    const std::vector<RecordVal> &Vals = R->getValues();

    DEBUG(o << "      // prefilling: ");
    // Start by filling in fixed values...
    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
        Value |= B->getValue() << (e-i-1);
        DEBUG(o << B->getValue());
      } else {
        DEBUG(o << "0");
      }
    }
    DEBUG(o << "\n");

    DEBUG(o << "      // " << *R->getValue("Inst") << "\n");
    o << "      Value = " << Value << "U;\n\n";

    // Loop over all of the fields in the instruction determining which are the
    // operands to the instruction.
    //
    unsigned op = 0;
    std::map<std::string, unsigned> OpOrder;
    std::map<std::string, bool> OpContinuous;
    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
      if (!Vals[i].getPrefix() &&  !Vals[i].getValue()->isComplete()) {
        // Is the operand continuous? If so, we can just mask and OR it in
        // instead of doing it bit-by-bit, saving a lot in runtime cost.
        const BitsInit *InstInit = BI;
        int beginBitInVar = -1, endBitInVar = -1;
        int beginBitInInst = -1, endBitInInst = -1;
        bool continuous = true;

        for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
          if (VarBitInit *VBI =
              dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              // only process the current variable
              if (VI->getName() != Vals[i].getName())
                continue;

              if (beginBitInVar == -1)
                beginBitInVar = VBI->getBitNum();

              if (endBitInVar == -1)
                endBitInVar = VBI->getBitNum();
              else {
                if (endBitInVar == (int)VBI->getBitNum() + 1)
                  endBitInVar = VBI->getBitNum();
                else {
                  continuous = false;
                  break;
                }
              }

              if (beginBitInInst == -1)
                beginBitInInst = bit;
              if (endBitInInst == -1)
                endBitInInst = bit;
              else {
                if (endBitInInst == bit + 1)
                  endBitInInst = bit;
                else {
                  continuous = false;
                  break;
                }
              }

              // maintain same distance between bits in field and bits in
              // instruction. if the relative distances stay the same
              // throughout,
              if (beginBitInVar - (int)VBI->getBitNum() !=
                  beginBitInInst - bit) {
                continuous = false;
                break;
              }
            }
          }
        }

        // If we have found no bit in "Inst" which comes from this field, then
        // this is not an operand!!
        if (beginBitInInst != -1) {
          o << "      // op" << op << ": " << Vals[i].getName() << "\n"
            << "      int64_t op" << op
            <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
          //<< "   MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
          OpOrder[Vals[i].getName()] = op++;

          DEBUG(o << "      // Var: begin = " << beginBitInVar
                  << ", end = " << endBitInVar
                  << "; Inst: begin = " << beginBitInInst
                  << ", end = " << endBitInInst << "\n");

          if (continuous) {
            DEBUG(o << "      // continuous: op" << OpOrder[Vals[i].getName()]
                    << "\n");

            // Mask off the right bits
            // Low mask (ie. shift, if necessary)
            assert(endBitInVar >= 0 && "Negative shift amount in masking!");
            if (endBitInVar != 0) {
              o << "      op" << OpOrder[Vals[i].getName()]
                << " >>= " << endBitInVar << ";\n";
              beginBitInVar -= endBitInVar;
              endBitInVar = 0;
            }

            // High mask
            o << "      op" << OpOrder[Vals[i].getName()]
              << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";

            // Shift the value to the correct place (according to place in inst)
            assert(endBitInInst >= 0 && "Negative shift amount!");
            if (endBitInInst != 0)
              o << "      op" << OpOrder[Vals[i].getName()]
              << " <<= " << endBitInInst << ";\n";

            // Just OR in the result
            o << "      Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
          }

          // otherwise, will be taken care of in the loop below using this
          // value:
          OpContinuous[Vals[i].getName()] = continuous;
        }
      }
    }

    for (unsigned f = 0, e = Vals.size(); f != e; ++f) {
      if (Vals[f].getPrefix()) {
        BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();

        // Scan through the field looking for bit initializers of the current
        // variable...
        for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
          Init *I = FieldInitializer->getBit(i);
          if (BitInit *BI = dynamic_cast<BitInit*>(I)) {
            DEBUG(o << "      // bit init: f: " << f << ", i: " << i << "\n");
          } else if (UnsetInit *UI = dynamic_cast<UnsetInit*>(I)) {
            DEBUG(o << "      // unset init: f: " << f << ", i: " << i << "\n");
          } else if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(I)) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              // If the bits of the field are laid out consecutively in the
              // instruction, then instead of separately ORing in bits, just
              // mask and shift the entire field for efficiency.
              if (OpContinuous[VI->getName()]) {
                // already taken care of in the loop above, thus there is no
                // need to individually OR in the bits

                // for debugging, output the regular version anyway, commented
                DEBUG(o << "      // Value |= getValueBit(op"
                        << OpOrder[VI->getName()] << ", " << VBI->getBitNum()
                        << ")" << " << " << i << ";\n");
              } else {
                o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
                  << ", " << VBI->getBitNum()
                  << ")" << " << " << i << ";\n";
              }
            } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
              // FIXME: implement this!
              o << "FIELD INIT not implemented yet!\n";
            } else {
              o << "Error: UNIMPLEMENTED\n";
            }
          }
        }
      }
    }

    o << "      break;\n"
      << "    }\n";
  }

  o << "  default:\n"
    << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
    << "    abort();\n"
    << "  }\n"
    << "  return Value;\n"
    << "}\n";

  EmitSourceFileTail(o);
}
<commit_msg>Deleted commented-out code as we now get namespace directly, add comments<commit_after>//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// CodeEmitterGen uses the descriptions of instructions and their fields to
// construct an automated code emitter: a function that, given a MachineInstr,
// returns the (currently, 32-bit unsigned) value of the instruction.
//
//===----------------------------------------------------------------------===//

#include "CodeEmitterGen.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "Support/Debug.h"
using namespace llvm;

void CodeEmitterGen::run(std::ostream &o) {
  CodeGenTarget Target;
  std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");

  EmitSourceFileHeader("Machine Code Emitter", o);
  std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::";

  // Emit function declaration
  o << "unsigned " << Target.getName() << "CodeEmitter::"
    << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
    << "  unsigned Value = 0;\n"
    << "  DEBUG(std::cerr << MI);\n"
    << "  switch (MI.getOpcode()) {\n";

  // Emit a case statement for each opcode
  for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
       I != E; ++I) {
    Record *R = *I;
    o << "    case " << Namespace << R->getName() << ": {\n"
      << "      DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";

    BitsInit *BI = R->getValueAsBitsInit("Inst");

    unsigned Value = 0;
    const std::vector<RecordVal> &Vals = R->getValues();

    DEBUG(o << "      // prefilling: ");
    // Start by filling in fixed values...
    for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
        Value |= B->getValue() << (e-i-1);
        DEBUG(o << B->getValue());
      } else {
        DEBUG(o << "0");
      }
    }
    DEBUG(o << "\n");

    DEBUG(o << "      // " << *R->getValue("Inst") << "\n");
    o << "      Value = " << Value << "U;\n\n";

    // Loop over all of the fields in the instruction determining which are the
    // operands to the instruction.
    //
    unsigned op = 0;
    std::map<std::string, unsigned> OpOrder;
    std::map<std::string, bool> OpContinuous;
    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
      if (!Vals[i].getPrefix() &&  !Vals[i].getValue()->isComplete()) {
        // Is the operand continuous? If so, we can just mask and OR it in
        // instead of doing it bit-by-bit, saving a lot in runtime cost.
        const BitsInit *InstInit = BI;
        int beginBitInVar = -1, endBitInVar = -1;
        int beginBitInInst = -1, endBitInInst = -1;
        bool continuous = true;

        for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
          if (VarBitInit *VBI =
              dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              // only process the current variable
              if (VI->getName() != Vals[i].getName())
                continue;

              if (beginBitInVar == -1)
                beginBitInVar = VBI->getBitNum();

              if (endBitInVar == -1)
                endBitInVar = VBI->getBitNum();
              else {
                if (endBitInVar == (int)VBI->getBitNum() + 1)
                  endBitInVar = VBI->getBitNum();
                else {
                  continuous = false;
                  break;
                }
              }

              if (beginBitInInst == -1)
                beginBitInInst = bit;
              if (endBitInInst == -1)
                endBitInInst = bit;
              else {
                if (endBitInInst == bit + 1)
                  endBitInInst = bit;
                else {
                  continuous = false;
                  break;
                }
              }

              // maintain same distance between bits in field and bits in
              // instruction. if the relative distances stay the same
              // throughout,
              if (beginBitInVar - (int)VBI->getBitNum() !=
                  beginBitInInst - bit) {
                continuous = false;
                break;
              }
            }
          }
        }

        // If we have found no bit in "Inst" which comes from this field, then
        // this is not an operand!!
        if (beginBitInInst != -1) {
          o << "      // op" << op << ": " << Vals[i].getName() << "\n"
            << "      int64_t op" << op
            <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
          //<< "   MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
          OpOrder[Vals[i].getName()] = op++;

          DEBUG(o << "      // Var: begin = " << beginBitInVar
                  << ", end = " << endBitInVar
                  << "; Inst: begin = " << beginBitInInst
                  << ", end = " << endBitInInst << "\n");

          if (continuous) {
            DEBUG(o << "      // continuous: op" << OpOrder[Vals[i].getName()]
                    << "\n");

            // Mask off the right bits
            // Low mask (ie. shift, if necessary)
            assert(endBitInVar >= 0 && "Negative shift amount in masking!");
            if (endBitInVar != 0) {
              o << "      op" << OpOrder[Vals[i].getName()]
                << " >>= " << endBitInVar << ";\n";
              beginBitInVar -= endBitInVar;
              endBitInVar = 0;
            }

            // High mask
            o << "      op" << OpOrder[Vals[i].getName()]
              << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";

            // Shift the value to the correct place (according to place in inst)
            assert(endBitInInst >= 0 && "Negative shift amount!");
            if (endBitInInst != 0)
              o << "      op" << OpOrder[Vals[i].getName()]
              << " <<= " << endBitInInst << ";\n";

            // Just OR in the result
            o << "      Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
          }

          // otherwise, will be taken care of in the loop below using this
          // value:
          OpContinuous[Vals[i].getName()] = continuous;
        }
      }
    }

    for (unsigned f = 0, e = Vals.size(); f != e; ++f) {
      if (Vals[f].getPrefix()) {
        BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();

        // Scan through the field looking for bit initializers of the current
        // variable...
        for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
          Init *I = FieldInitializer->getBit(i);
          if (BitInit *BI = dynamic_cast<BitInit*>(I)) {
            DEBUG(o << "      // bit init: f: " << f << ", i: " << i << "\n");
          } else if (UnsetInit *UI = dynamic_cast<UnsetInit*>(I)) {
            DEBUG(o << "      // unset init: f: " << f << ", i: " << i << "\n");
          } else if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(I)) {
            TypedInit *TI = VBI->getVariable();
            if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
              // If the bits of the field are laid out consecutively in the
              // instruction, then instead of separately ORing in bits, just
              // mask and shift the entire field for efficiency.
              if (OpContinuous[VI->getName()]) {
                // already taken care of in the loop above, thus there is no
                // need to individually OR in the bits

                // for debugging, output the regular version anyway, commented
                DEBUG(o << "      // Value |= getValueBit(op"
                        << OpOrder[VI->getName()] << ", " << VBI->getBitNum()
                        << ")" << " << " << i << ";\n");
              } else {
                o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
                  << ", " << VBI->getBitNum()
                  << ")" << " << " << i << ";\n";
              }
            } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
              // FIXME: implement this!
              o << "FIELD INIT not implemented yet!\n";
            } else {
              o << "Error: UNIMPLEMENTED\n";
            }
          }
        }
      }
    }

    o << "      break;\n"
      << "    }\n";
  }

  o << "  default:\n"
    << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
    << "    abort();\n"
    << "  }\n"
    << "  return Value;\n"
    << "}\n";

  EmitSourceFileTail(o);
}
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetCmdParser.cpp
 */

#include "JPetCmdParser.h"
#include <iostream>
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../JPetLoggerInclude.h"
#include "../JPetScopeConfigParser/JPetScopeConfigParser.h"
#include <stdexcept>

JPetCmdParser::JPetCmdParser(): fOptionsDescriptions("Allowed options")
{
  fOptionsDescriptions.add_options()
  ("help,h", "Displays this help message.")
  ("type,t", po::value<std::string>()->required()->implicit_value(""), "Type of file: hld, zip, root or scope.")
  ("file,f", po::value< std::vector<std::string> >()->required()->multitoken(), "File(s) to open.")
  ("outputPath,o", po::value<std::string>(), "Location to which the outputFiles will be saved.")
  ("range,r", po::value< std::vector<int> >()->multitoken()->default_value({ -1, -1}, ""), "Range of events to process e.g. -r 1 1000 .")
  ("param,p", po::value<std::string>(), "xml file with TRB settings used by the unpacker program.")
  ("runId,i", po::value<int>(), "Run id.")
  ("progressBar,b", "Progress bar.")
  ("localDB,l", po::value<std::string>(), "The file to use as the parameter database.")
  ("localDBCreate,L", po::value<std::string>(), "File name to which the parameter database will be saved.");
}

JPetCmdParser::~JPetCmdParser()
{
  /**/
}

std::vector<JPetOptions> JPetCmdParser::parseAndGenerateOptions(int argc, const char** argv)
{
  po::variables_map variablesMap;
  if (argc == 1) {
    ERROR("No options provided.");
    std::cerr << getOptionsDescription() << "\n";
    throw std::invalid_argument("No options provided.");
  }

  po::store(po::parse_command_line(argc, argv, fOptionsDescriptions), variablesMap);

  /* print out help */
  if (variablesMap.count("help")) {
    std::cout << getOptionsDescription() << "\n";
    exit(0);
  }
  po::notify(variablesMap);
  if (!areCorrectOptions(variablesMap)) {
    throw std::invalid_argument("Wrong user options provided! Check the log!");
  }

  return generateOptions(variablesMap);
}

bool JPetCmdParser::areCorrectOptions(const po::variables_map& variablesMap) const
{
  /* Parse range of events */
  if (variablesMap.count("range")) {
    if (variablesMap["range"].as< std::vector<int> >().size() != 2) {
      ERROR("Wrong number of bounds in range.");
      std::cerr << "Wrong number of bounds in range: " << variablesMap["range"].as< std::vector<int> >().size() << std::endl;
      return false;
    }
    if (
      variablesMap["range"].as< std::vector<int> >()[0]
      > variablesMap["range"].as< std::vector<int> >()[1]) {
      ERROR("Wrong range of events.");
      std::cerr << "Wrong range of events." << std::endl;
      return false;
    }
  }

  if (!isCorrectFileType(getFileType(variablesMap))) {
    ERROR("Wrong type of file.");
    std::cerr << "Wrong type of file: " << getFileType(variablesMap) << std::endl;
    std::cerr << "Possible options: hld, root or scope" << std::endl;
    return false;
  }

  if (isRunNumberSet(variablesMap)) {
    int l_runId = variablesMap["runId"].as<int>();

    if (l_runId <= 0) {
      ERROR("Run id must be a number larger than 0.");
      std::cerr << "Run id must be a number larger than 0." << l_runId << std::endl;
      return false;
    }
  }

  if (isProgressBarSet(variablesMap)) {
    int l_progressBar = variablesMap["progressBar"].as<int>();

    if (l_progressBar != 0 && l_progressBar != 1) {
      ERROR("Wrong parameter of progressbar.");
      std::cerr << "Wrong parameter of progressbar: " << l_progressBar << std::endl;
      return false;
    }
  }

  if (isLocalDBSet(variablesMap)) {
    std::string localDBName = getLocalDBName(variablesMap);
    if ( !JPetCommonTools::ifFileExisting(localDBName) ) {
      ERROR("File : " + localDBName + " does not exist.");
      std::cerr << "File : " << localDBName << " does not exist" << std::endl;
      return false;
    }
  }

  std::vector<std::string> fileNames(variablesMap["file"].as< std::vector<std::string> >());
  for (unsigned int i = 0; i < fileNames.size(); i++) {
    if ( ! JPetCommonTools::ifFileExisting(fileNames[i]) ) {
      std::string fileName = fileNames[i];
      ERROR("File : " + fileName + " does not exist.");
      std::cerr << "File : " << fileNames[i] << " does not exist" << std::endl;
      return false;
    }
  }

  /// The run number option is neclegted if the input file is set as "scope"
  if (isRunNumberSet(variablesMap)) {
    if (getFileType(variablesMap) == "scope") {
      WARNING("Run number was specified but the input file type is a scope!\n The run number will be ignored!");
    }
  }

  /// Check if output path exists
  if (isOutputPath(variablesMap)) {
      auto dir = getOutputPath(variablesMap);
      if (!JPetCommonTools::isDirectory(dir)) {
        ERROR("Output directory : " + dir + " does not exist.");
        std::cerr << "Output directory: " << dir << " does not exist" << std::endl;
        return false;
      }
  }
  return true;
}

std::vector<JPetOptions> JPetCmdParser::generateOptions(const po::variables_map& optsMap) const
{
  std::map<std::string, std::string> options = JPetOptions::getDefaultOptions();
  auto fileType = getFileType(optsMap);
  if (isCorrectFileType(fileType)) {
    options.at("inputFileType") = fileType;
  }
  if (isOutputPath(optsMap)) {
    options.at("outputPath") = JPetCommonTools::appendSlashToPathIfAbsent(getOutputPath(optsMap));
  }
  if (isRunNumberSet(optsMap)) {
    options.at("runId") = std::to_string(getRunNumber(optsMap));
  }
  if (isProgressBarSet(optsMap)) {
    options.at("progressBar") = "true";
  }
  if (isLocalDBSet(optsMap)) {
    options["localDB"] = getLocalDBName(optsMap);
  }
  if (isLocalDBCreateSet(optsMap)) {
    options["localDBCreate"] = getLocalDBCreateName(optsMap);
  }
  auto firstEvent  = getLowerEventBound(optsMap);
  auto lastEvent  = getHigherEventBound(optsMap);
  if (firstEvent >= 0) options.at("firstEvent") = std::to_string(firstEvent);
  if (lastEvent >= 0) options.at("lastEvent") = std::to_string(lastEvent);

  auto files = getFileNames(optsMap);
  std::vector<JPetOptions>  optionContainer;
  /// In case of scope there is one special input file
  /// which is a json config file which must be parsed.
  /// Based on its content the set of input directories are generated.
  /// The input directories contain data files.
  /// The config input file name also should be stored in a special option field.
  if (fileType == "scope") {
    assert(files.size() == 1); /// there should be only file which is config.
    auto configFileName = files.front();
    options.at("scopeConfigFile") =  configFileName;
    JPetScopeConfigParser scopeConfigParser;
    /// The scope module must use a fake input file name which will be used to
    /// produce the correct output file names by the following modules.
    /// At the same time, the input directory with true input files must be
    /// also added. The container of pairs <directory, fileName> is generated
    /// based on the content of the configuration file.
    JPetScopeConfigParser::DirFileContainer dirsAndFiles = scopeConfigParser.getInputDirectoriesAndFakeInputFiles(configFileName);
    for (auto dirAndFile : dirsAndFiles) {
      options.at("scopeInputDirectory") = dirAndFile.first;
      options.at("inputFile") = dirAndFile.second;
      optionContainer.push_back(JPetOptions(options));
    }
  } else {
    /// for every single input file we create separate JPetOptions
    for (auto file : files) {
      options.at("inputFile") = file;
      optionContainer.push_back(JPetOptions(options));
    }
  }
  return optionContainer;
}

//#endif /* __CINT__ */
<commit_msg>Added zip phrase to function in JPetCmdParser<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetCmdParser.cpp
 */

#include "JPetCmdParser.h"
#include <iostream>
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../JPetLoggerInclude.h"
#include "../JPetScopeConfigParser/JPetScopeConfigParser.h"
#include <stdexcept>

JPetCmdParser::JPetCmdParser(): fOptionsDescriptions("Allowed options")
{
  fOptionsDescriptions.add_options()
  ("help,h", "Displays this help message.")
  ("type,t", po::value<std::string>()->required()->implicit_value(""), "Type of file: hld, zip, root or scope.")
  ("file,f", po::value< std::vector<std::string> >()->required()->multitoken(), "File(s) to open.")
  ("outputPath,o", po::value<std::string>(), "Location to which the outputFiles will be saved.")
  ("range,r", po::value< std::vector<int> >()->multitoken()->default_value({ -1, -1}, ""), "Range of events to process e.g. -r 1 1000 .")
  ("param,p", po::value<std::string>(), "xml file with TRB settings used by the unpacker program.")
  ("runId,i", po::value<int>(), "Run id.")
  ("progressBar,b", "Progress bar.")
  ("localDB,l", po::value<std::string>(), "The file to use as the parameter database.")
  ("localDBCreate,L", po::value<std::string>(), "File name to which the parameter database will be saved.");
}

JPetCmdParser::~JPetCmdParser()
{
  /**/
}

std::vector<JPetOptions> JPetCmdParser::parseAndGenerateOptions(int argc, const char** argv)
{
  po::variables_map variablesMap;
  if (argc == 1) {
    ERROR("No options provided.");
    std::cerr << getOptionsDescription() << "\n";
    throw std::invalid_argument("No options provided.");
  }

  po::store(po::parse_command_line(argc, argv, fOptionsDescriptions), variablesMap);

  /* print out help */
  if (variablesMap.count("help")) {
    std::cout << getOptionsDescription() << "\n";
    exit(0);
  }
  po::notify(variablesMap);
  if (!areCorrectOptions(variablesMap)) {
    throw std::invalid_argument("Wrong user options provided! Check the log!");
  }

  return generateOptions(variablesMap);
}

bool JPetCmdParser::areCorrectOptions(const po::variables_map& variablesMap) const
{
  /* Parse range of events */
  if (variablesMap.count("range")) {
    if (variablesMap["range"].as< std::vector<int> >().size() != 2) {
      ERROR("Wrong number of bounds in range.");
      std::cerr << "Wrong number of bounds in range: " << variablesMap["range"].as< std::vector<int> >().size() << std::endl;
      return false;
    }
    if (
      variablesMap["range"].as< std::vector<int> >()[0]
      > variablesMap["range"].as< std::vector<int> >()[1]) {
      ERROR("Wrong range of events.");
      std::cerr << "Wrong range of events." << std::endl;
      return false;
    }
  }

  if (!isCorrectFileType(getFileType(variablesMap))) {
    ERROR("Wrong type of file.");
    std::cerr << "Wrong type of file: " << getFileType(variablesMap) << std::endl;
    std::cerr << "Possible options: hld, zip, root or scope" << std::endl;
    return false;
  }

  if (isRunNumberSet(variablesMap)) {
    int l_runId = variablesMap["runId"].as<int>();

    if (l_runId <= 0) {
      ERROR("Run id must be a number larger than 0.");
      std::cerr << "Run id must be a number larger than 0." << l_runId << std::endl;
      return false;
    }
  }

  if (isProgressBarSet(variablesMap)) {
    int l_progressBar = variablesMap["progressBar"].as<int>();

    if (l_progressBar != 0 && l_progressBar != 1) {
      ERROR("Wrong parameter of progressbar.");
      std::cerr << "Wrong parameter of progressbar: " << l_progressBar << std::endl;
      return false;
    }
  }

  if (isLocalDBSet(variablesMap)) {
    std::string localDBName = getLocalDBName(variablesMap);
    if ( !JPetCommonTools::ifFileExisting(localDBName) ) {
      ERROR("File : " + localDBName + " does not exist.");
      std::cerr << "File : " << localDBName << " does not exist" << std::endl;
      return false;
    }
  }

  std::vector<std::string> fileNames(variablesMap["file"].as< std::vector<std::string> >());
  for (unsigned int i = 0; i < fileNames.size(); i++) {
    if ( ! JPetCommonTools::ifFileExisting(fileNames[i]) ) {
      std::string fileName = fileNames[i];
      ERROR("File : " + fileName + " does not exist.");
      std::cerr << "File : " << fileNames[i] << " does not exist" << std::endl;
      return false;
    }
  }

  /// The run number option is neclegted if the input file is set as "scope"
  if (isRunNumberSet(variablesMap)) {
    if (getFileType(variablesMap) == "scope") {
      WARNING("Run number was specified but the input file type is a scope!\n The run number will be ignored!");
    }
  }

  /// Check if output path exists
  if (isOutputPath(variablesMap)) {
      auto dir = getOutputPath(variablesMap);
      if (!JPetCommonTools::isDirectory(dir)) {
        ERROR("Output directory : " + dir + " does not exist.");
        std::cerr << "Output directory: " << dir << " does not exist" << std::endl;
        return false;
      }
  }
  return true;
}

std::vector<JPetOptions> JPetCmdParser::generateOptions(const po::variables_map& optsMap) const
{
  std::map<std::string, std::string> options = JPetOptions::getDefaultOptions();
  auto fileType = getFileType(optsMap);
  if (isCorrectFileType(fileType)) {
    options.at("inputFileType") = fileType;
  }
  if (isOutputPath(optsMap)) {
    options.at("outputPath") = JPetCommonTools::appendSlashToPathIfAbsent(getOutputPath(optsMap));
  }
  if (isRunNumberSet(optsMap)) {
    options.at("runId") = std::to_string(getRunNumber(optsMap));
  }
  if (isProgressBarSet(optsMap)) {
    options.at("progressBar") = "true";
  }
  if (isLocalDBSet(optsMap)) {
    options["localDB"] = getLocalDBName(optsMap);
  }
  if (isLocalDBCreateSet(optsMap)) {
    options["localDBCreate"] = getLocalDBCreateName(optsMap);
  }
  auto firstEvent  = getLowerEventBound(optsMap);
  auto lastEvent  = getHigherEventBound(optsMap);
  if (firstEvent >= 0) options.at("firstEvent") = std::to_string(firstEvent);
  if (lastEvent >= 0) options.at("lastEvent") = std::to_string(lastEvent);

  auto files = getFileNames(optsMap);
  std::vector<JPetOptions>  optionContainer;
  /// In case of scope there is one special input file
  /// which is a json config file which must be parsed.
  /// Based on its content the set of input directories are generated.
  /// The input directories contain data files.
  /// The config input file name also should be stored in a special option field.
  if (fileType == "scope") {
    assert(files.size() == 1); /// there should be only file which is config.
    auto configFileName = files.front();
    options.at("scopeConfigFile") =  configFileName;
    JPetScopeConfigParser scopeConfigParser;
    /// The scope module must use a fake input file name which will be used to
    /// produce the correct output file names by the following modules.
    /// At the same time, the input directory with true input files must be
    /// also added. The container of pairs <directory, fileName> is generated
    /// based on the content of the configuration file.
    JPetScopeConfigParser::DirFileContainer dirsAndFiles = scopeConfigParser.getInputDirectoriesAndFakeInputFiles(configFileName);
    for (auto dirAndFile : dirsAndFiles) {
      options.at("scopeInputDirectory") = dirAndFile.first;
      options.at("inputFile") = dirAndFile.second;
      optionContainer.push_back(JPetOptions(options));
    }
  } else {
    /// for every single input file we create separate JPetOptions
    for (auto file : files) {
      options.at("inputFile") = file;
      optionContainer.push_back(JPetOptions(options));
    }
  }
  return optionContainer;
}

//#endif /* __CINT__ */
<|endoftext|>