<commit_before>/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "gluonobjectfactory.h"
#include "gluonobject.h"
#include "component.h"
#include "asset.h"

#include <QtCore/QDebug>
#include <QDir>
#include <QApplication>
#include <QPluginLoader>

using namespace Gluon;

template<> GluonObjectFactory* KSingleton<GluonObjectFactory>::m_instance = 0;

void
GluonObjectFactory::registerObjectType(GluonObject * newObjectType)
{
    if(newObjectType)
    {
        qDebug() << "Registering object type" << newObjectType->metaObject()->className();
        objectTypes[newObjectType->metaObject()->className()] = newObjectType;
    }
}

GluonObject *
GluonObjectFactory::instantiateObjectByName(const QString& objectTypeName)
{
    QString fullObjectTypeName = QString("Gluon::") + objectTypeName;
    if(objectTypes.find(fullObjectTypeName) != objectTypes.end())
    {
        return objectTypes.value(fullObjectTypeName)->instantiate();
    }
    return 0;
}

void
GluonObjectFactory::loadPlugins()
{
    QList<QDir> pluginDirs;

    QDir pluginDir(QApplication::applicationDirPath());

#if defined(Q_OS_WIN)
    if (pluginDir.dirName().tolower() == "debug" || pluginDir.dirName().tolower() == "release")
        pluginDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginDir.dirName() == "MacOS")
    {
        pluginDir.cdUp();
        pluginDir.cdUp();
        pluginDir.cdUp();
    }
#endif
    if(pluginDir.cd("plugins"))
        pluginDirs.append(pluginDir);

    if(pluginDir.cd("/usr/lib/gluon"))
        pluginDirs.append(pluginDir);

    // Always look in the current dir
    pluginDirs.append(QDir::current());

    if(pluginDir.cd(QDir::homePath() + "/gluonplugins"))
        pluginDirs.append(pluginDir);

    qDebug() << "Number of plugin locations:" << pluginDirs.count();
    foreach(const QDir &theDir, pluginDirs)
    {
        qDebug() << "Looking for pluggable components in:" << theDir.absolutePath();
        qDebug() << "Found" << (theDir.count() - 2) << "potential plugins. Attempting to load:";

        foreach (QString fileName, theDir.entryList(QDir::Files))
        {
            QPluginLoader loader(theDir.absoluteFilePath(fileName));
            if(Component* loaded = qobject_cast<Component*>(loader.instance()))
                m_pluggedComponents.append(loaded);
            else if(Asset* loaded = qobject_cast<Asset*>(loader.instance()))
                m_pluggedAssets.append(loaded);
            else
                qDebug() << loader.errorString();
        }
    }
}

#include "gluonobjectfactory.moc"
<commit_msg>Add support for fully qualified names in the factory's instantiate by name function<commit_after>/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "gluonobjectfactory.h"
#include "gluonobject.h"
#include "component.h"
#include "asset.h"

#include <QtCore/QDebug>
#include <QDir>
#include <QApplication>
#include <QPluginLoader>

using namespace Gluon;

template<> GluonObjectFactory* KSingleton<GluonObjectFactory>::m_instance = 0;

void
GluonObjectFactory::registerObjectType(GluonObject * newObjectType)
{
    if(newObjectType)
    {
        qDebug() << "Registering object type" << newObjectType->metaObject()->className();
        objectTypes[newObjectType->metaObject()->className()] = newObjectType;
    }
}

GluonObject *
GluonObjectFactory::instantiateObjectByName(const QString& objectTypeName)
{
    QString fullObjectTypeName(objectTypeName);
    if(!objectTypeName.contains("::"))
         fullObjectTypeName = QString("Gluon::") + fullObjectTypeName;
    if(objectTypes.find(fullObjectTypeName) != objectTypes.end())
    {
        return objectTypes.value(fullObjectTypeName)->instantiate();
    }
    return 0;
}

void
GluonObjectFactory::loadPlugins()
{
    QList<QDir> pluginDirs;

    QDir pluginDir(QApplication::applicationDirPath());

#if defined(Q_OS_WIN)
    if (pluginDir.dirName().tolower() == "debug" || pluginDir.dirName().tolower() == "release")
        pluginDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginDir.dirName() == "MacOS")
    {
        pluginDir.cdUp();
        pluginDir.cdUp();
        pluginDir.cdUp();
    }
#endif
    if(pluginDir.cd("plugins"))
        pluginDirs.append(pluginDir);

    if(pluginDir.cd("/usr/lib/gluon"))
        pluginDirs.append(pluginDir);

    // Always look in the current dir
    pluginDirs.append(QDir::current());

    if(pluginDir.cd(QDir::homePath() + "/gluonplugins"))
        pluginDirs.append(pluginDir);

    qDebug() << "Number of plugin locations:" << pluginDirs.count();
    foreach(const QDir &theDir, pluginDirs)
    {
        qDebug() << "Looking for pluggable components in:" << theDir.absolutePath();
        qDebug() << "Found" << (theDir.count() - 2) << "potential plugins. Attempting to load:";

        foreach (QString fileName, theDir.entryList(QDir::Files))
        {
            QPluginLoader loader(theDir.absoluteFilePath(fileName));
            if(Component* loaded = qobject_cast<Component*>(loader.instance()))
                m_pluggedComponents.append(loaded);
            else if(Asset* loaded = qobject_cast<Asset*>(loader.instance()))
                m_pluggedAssets.append(loaded);
            else
                qDebug() << loader.errorString();
        }
    }
}

#include "gluonobjectfactory.moc"
<|endoftext|>


<commit_before>/***********************************************************************************************************************
 * Copyright (C) 2016 Andrew Zonenberg and contributors                                                                *
 *                                                                                *
 * This program 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 program 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 program; if not, you may   *
 * find one here:                                                                                *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/

#include "gp4prog.h"

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Device I/O

/* For use with the following systemtap script and the vendor tool (run as `stap -g silego.stp`):

function getstr:string(buf:long, off:long, cnt:long, pad:long) %{
  const char hex[] = "0123456789abcdef";
  uint8_t *buf = (*(uint8_t **)STAP_ARG_buf) + 0x10 + STAP_ARG_off;
  int i;
  char *out = STAP_RETVALUE;
  int remain = MAXSTRINGLEN;
  for(i = 0; i < STAP_ARG_cnt - STAP_ARG_off; i++) {
    const char byte[3] = { hex[buf[i] >> 4], hex[buf[i] & 0xf] };
    strlcpy (out, byte, remain);
    out += 2; remain -= 2;
    if(STAP_ARG_pad && (i == 0 || i == 1 || i == 2 || i == 3)) {
      strlcpy(out, "_", remain);
      out += 1; remain -= 1;
    }
  }
%}

global rbuf, rcnt, rtyp
probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice8dataReadER7QVectorIhE").
    call {
  rbuf = register("rsi")
  rcnt = register("rdx")
  rtyp = register("rcx")
}
probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice8dataReadER7QVectorIhE").
    return {
  printf("R%02x %s\n", rtyp, getstr(rbuf, 0, 64, 1));
}

probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice9dataWriteER7QVectorIhE").
    call {
  wbuf = register("rsi")
  wcnt = register("rdx")
  wtyp = register("rcx")
  printf("W%02x %s\n", wtyp, getstr(wbuf, 0, 64, 1));
}

*/
DataFrame::DataFrame(const char *ascii)
{
	uint8_t size;
	sscanf(ascii, "%02hhx_%02hhx_%02hhx_%02hhx_", &m_sequenceA, &m_type, &size, &m_sequenceB);
	for(size_t i=0; i<60; i++) {
		uint8_t byte;
		sscanf(ascii+12+i*2, "%02hhx", &byte);
		m_payload.push_back(byte);
	}
	if(size > 3)
		m_payload.resize(size - 3);
}

void DataFrame::Send(hdevice hdev)
{
	uint8_t data[64] = {};

	//Packet header
	data[0] = m_sequenceA;
	data[1] = m_type;
	if(m_payload.size() == 0)
		data[2] = 0x00;
	else
		data[2] = 3 + m_payload.size();
	data[3] = m_sequenceB;

	//Packet body
	for(size_t i=0; i<m_payload.size(); i++)
		data[4+i] = m_payload[i];

	LogVerbose("H→D: ");
	for(int i=0; i<64; i++) {
		LogVerbose("%02x", data[i] & 0xff);
		if(i < 4) LogVerbose("_");
	}
	LogVerbose("\n");

	SendInterruptTransfer(hdev, data, sizeof(data));
}

void DataFrame::Receive(hdevice hdev)
{
	uint8_t data[64];

	ReceiveInterruptTransfer(hdev, data, sizeof(data));

	LogVerbose("D→H: ");
	for(int i=0; i<64; i++) {
		LogVerbose("%02x", data[i] & 0xff);
		if(i < 4) LogVerbose("_");
	}
	LogVerbose("\n");

	//Packet header
	uint8_t size;
	m_sequenceA = data[0];
	m_type = data[1];
	if(data[2] == 0x00)
		size = 0;
	else if(data[2] > 3)
		size = data[2] - 3;
	else
		LogFatal("Unexpected size %d\n", data[2]);
	m_sequenceB = data[3];

	//Packet body
	m_payload.resize(size);
	for(size_t i=0; i<m_payload.size(); i++)
		m_payload[i] = data[4+i];
}

void DataFrame::Roundtrip(hdevice hdev, uint8_t ack_type)
{
	Send(hdev);

	// Receive an acknowledgement frame
	DataFrame ack_frame;
	ack_frame.Receive(hdev);

	// Compare the two frames.
	// Received frame will usually have length 0x3f; it is unimportant.
	// Received frame will sometimes have the same sequence number B, sometimes not. It is unimportant.
	if(!(m_sequenceA == ack_frame.m_sequenceA &&
	     ack_type == ack_frame.m_type &&
	     m_payload.size() <= ack_frame.m_payload.size() &&
	     std::equal(m_payload.begin(), m_payload.end(),
	                ack_frame.m_payload.begin()))) {
		LogFatal("Unexpected acknowledgement frame\n");
	}
}

void DataFrame::Roundtrip(hdevice hdev)
{
	Roundtrip(hdev, m_type);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Device I/O

void SwitchMode(hdevice hdev)
{
	uint8_t data[64] = {};
	data[60] = 0x09;
	SendInterruptTransfer(hdev, data, sizeof(data));
}

void SetPart(hdevice hdev, SilegoPart part)
{
	DataFrame frame(DataFrame::SET_PART);
	frame.push_back((uint8_t)part);
	frame.push_back(0x00);
	frame.push_back(0x00);
	frame.push_back(0x00);
	frame.Roundtrip(hdev);
}

void SetStatusLED(hdevice hdev, bool status)
{
	DataFrame frame(DataFrame::SET_STATUS_LED);
	frame.push_back(status);
	frame.Roundtrip(hdev);
}

void SetIOConfig(hdevice hdev, IOConfig& config)
{
	DataFrame frame(DataFrame::CONFIG_IO);

	//Test point config data
	for(unsigned int i=2; i<=20; i++)
	{
		unsigned int cfg = config.driverConfigs[i];
		frame.push_back(cfg >> 8);
		frame.push_back(cfg & 0xff);

		//skip TP11 since that's ground, no config for it
		if(i == 10)
			i++;
	}

	//7 unknown bytes, leave zero for now
	for(size_t i=0; i<7; i++)
		frame.push_back(0);

	//Expansion connector
	uint8_t exp[3] = {0};
	uint8_t expansionBitMap[21][2] =
	{
		{0, 0x00},		//unused
		{1, 0x01},		//Vdd

		{2, 0x04},		//TP2
		{2, 0x01},		//TP3
		{2, 0x10},		//TP4
		{2, 0x40},		//TP5
		{0, 0x01},		//TP6
		{0, 0x04},		//TP7
		{0, 0x10},		//TP8
		{0, 0x40},		//TP9
		{0, 0x80},		//TP10

		{0, 0x20},		//TP12
		{2, 0x08},		//TP13
		{2, 0x02},		//TP14
		{1, 0x80},		//TP15
		{2, 0x20},		//TP16
		{0, 0x02},		//TP17
		{1, 0x20},		//TP18
		{1, 0x08},		//TP19
		{2, 0x08}		//TP20
	};
	for(unsigned int i=1; i<21; i++)
	{
		if(config.expansionEnabled[i])
			exp[expansionBitMap[i][0]] = expansionBitMap[i][1];
	}
	for(size_t i=0; i<3; i++)
		frame.push_back(exp[i]);

	//LEDs from TP3 ... TP15
	unsigned int tpbase = 3;
	for(int i=0; i<3; i++)
	{
		uint8_t ledcfg = 0;
		for(int j=0; j<4; j++)
		{
			uint8_t bitmask = 1 << j;
			uint8_t tpnum = tpbase + j;

			if(config.ledEnabled[tpnum])
				ledcfg |= bitmask;
			if(config.ledInverted[tpnum])
				ledcfg |= (bitmask << 4);
		}
		frame.push_back(ledcfg);

		//Bump pointers. skip TP11 as it's not implemented in the hardware (ground)
		tpbase += 4;
		if(i == 1)
			tpbase ++;
	}

	//LEDs from TP16 ... TP20
	uint8_t leden = 0;
	uint8_t ledinv = 0;
	for(int i=0; i<5; i++)
	{
		uint8_t tpnum = 16 + i;
		uint8_t bitmask = 1 << i;

		if(config.ledEnabled[tpnum])
			leden |= bitmask;
		if(config.ledInverted[tpnum])
			ledinv |= bitmask;
	}
	frame.push_back(leden);
	frame.push_back(ledinv);

	//Always constant, meaning unknown
	frame.push_back(0x1);
	frame.push_back(0x0);
	frame.push_back(0x0);

	//Done, send it
	frame.Send(hdev);
}

//ch1 = Vdd, CH2...20 = TP2...20
//TODO: more than just a dummy placeholder
void ConfigureSiggen(hdevice hdev, uint8_t channel, double voltage)
{
	DataFrame frame(DataFrame::CONFIG_SIGGEN);

	uint16_t raw_voltage = voltage / 1.362;

	frame.push_back(2);					//signal generator
	frame.push_back(channel);			//channel number
	frame.push_back(1);					//hold at start value before starting
	frame.push_back(0);					//repeat waveform forever
	frame.push_back(1);					//end state: keep last state
	frame.push_back(raw_voltage >> 8);	//voltage
	frame.push_back(raw_voltage & 0xff);
	// frame.push_back(0);					//ramp delay
	// frame.push_back(0);
	// frame.push_back(0);					//integral step part
	// frame.push_back(0);
	// frame.push_back(0);					//step sign and fractional step part
	// frame.push_back(0);

	frame.Roundtrip(hdev);
}

void SetSiggenStatus(hdevice hdev, unsigned int chan, unsigned int status)
{
	DataFrame frame(DataFrame::ENABLE_SIGGEN);

	for(unsigned int i=1; i<=19; i++)
	{
		if(i == chan)					//apply our status
			frame.push_back(status);

		else
			frame.push_back(SIGGEN_NOP);	//no change
	}

	frame.Send(hdev);
}

void LoadBitstream(hdevice hdev, std::vector<uint8_t> bitstream)
{
	DataFrame frame(DataFrame::WRITE_BITSTREAM_SRAM);
	frame.push_back(0x80);
	frame.push_back(0x00);
	frame.push_back(0x00);

	uint16_t cycles = bitstream.size() * 8 + 34;
	frame.push_back(cycles >> 8);
	frame.push_back(cycles & 0xff);

	frame.m_sequenceB = (bitstream.size() + 3) / 60;

	for(size_t i = 0; i < bitstream.size(); i++) {
		frame.push_back(bitstream[i]);

		if(frame.IsFull()) {
			frame.Roundtrip(hdev, DataFrame::WRITE_BITSTREAM_SRAM_ACK1);
			frame = frame.Next();
		}
	}

	if(!frame.IsEmpty())
		frame.Roundtrip(hdev, DataFrame::WRITE_BITSTREAM_SRAM_ACK2);
}
<commit_msg>gp4prog: fix expansion connector configuration typo.<commit_after>/***********************************************************************************************************************
 * Copyright (C) 2016 Andrew Zonenberg and contributors                                                                *
 *                                                                                *
 * This program 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 program 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 program; if not, you may   *
 * find one here:                                                                                *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/

#include "gp4prog.h"

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Device I/O

/* For use with the following systemtap script and the vendor tool (run as `stap -g silego.stp`):

function getstr:string(buf:long, off:long, cnt:long, pad:long) %{
  const char hex[] = "0123456789abcdef";
  uint8_t *buf = (*(uint8_t **)STAP_ARG_buf) + 0x10 + STAP_ARG_off;
  int i;
  char *out = STAP_RETVALUE;
  int remain = MAXSTRINGLEN;
  for(i = 0; i < STAP_ARG_cnt - STAP_ARG_off; i++) {
    const char byte[3] = { hex[buf[i] >> 4], hex[buf[i] & 0xf] };
    strlcpy (out, byte, remain);
    out += 2; remain -= 2;
    if(STAP_ARG_pad && (i == 0 || i == 1 || i == 2 || i == 3)) {
      strlcpy(out, "_", remain);
      out += 1; remain -= 1;
    }
  }
%}

global rbuf, rcnt, rtyp
probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice8dataReadER7QVectorIhE").
    call {
  rbuf = register("rsi")
  rcnt = register("rdx")
  rtyp = register("rcx")
}
probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice8dataReadER7QVectorIhE").
    return {
  printf("R%02x %s\n", rtyp, getstr(rbuf, 0, 64, 1));
}

probe process("/usr/lib/libSilegoUSB-2.0.so.1").
    function("_ZN9USBDevice9dataWriteER7QVectorIhE").
    call {
  wbuf = register("rsi")
  wcnt = register("rdx")
  wtyp = register("rcx")
  printf("W%02x %s\n", wtyp, getstr(wbuf, 0, 64, 1));
}

*/
DataFrame::DataFrame(const char *ascii)
{
	uint8_t size;
	sscanf(ascii, "%02hhx_%02hhx_%02hhx_%02hhx_", &m_sequenceA, &m_type, &size, &m_sequenceB);
	for(size_t i=0; i<60; i++) {
		uint8_t byte;
		sscanf(ascii+12+i*2, "%02hhx", &byte);
		m_payload.push_back(byte);
	}
	if(size > 3)
		m_payload.resize(size - 3);
}

void DataFrame::Send(hdevice hdev)
{
	uint8_t data[64] = {};

	//Packet header
	data[0] = m_sequenceA;
	data[1] = m_type;
	if(m_payload.size() == 0)
		data[2] = 0x00;
	else
		data[2] = 3 + m_payload.size();
	data[3] = m_sequenceB;

	//Packet body
	for(size_t i=0; i<m_payload.size(); i++)
		data[4+i] = m_payload[i];

	LogVerbose("H→D: ");
	for(int i=0; i<64; i++) {
		LogVerbose("%02x", data[i] & 0xff);
		if(i < 4) LogVerbose("_");
	}
	LogVerbose("\n");

	SendInterruptTransfer(hdev, data, sizeof(data));
}

void DataFrame::Receive(hdevice hdev)
{
	uint8_t data[64];

	ReceiveInterruptTransfer(hdev, data, sizeof(data));

	LogVerbose("D→H: ");
	for(int i=0; i<64; i++) {
		LogVerbose("%02x", data[i] & 0xff);
		if(i < 4) LogVerbose("_");
	}
	LogVerbose("\n");

	//Packet header
	uint8_t size;
	m_sequenceA = data[0];
	m_type = data[1];
	if(data[2] == 0x00)
		size = 0;
	else if(data[2] > 3)
		size = data[2] - 3;
	else
		LogFatal("Unexpected size %d\n", data[2]);
	m_sequenceB = data[3];

	//Packet body
	m_payload.resize(size);
	for(size_t i=0; i<m_payload.size(); i++)
		m_payload[i] = data[4+i];
}

void DataFrame::Roundtrip(hdevice hdev, uint8_t ack_type)
{
	Send(hdev);

	// Receive an acknowledgement frame
	DataFrame ack_frame;
	ack_frame.Receive(hdev);

	// Compare the two frames.
	// Received frame will usually have length 0x3f; it is unimportant.
	// Received frame will sometimes have the same sequence number B, sometimes not. It is unimportant.
	if(!(m_sequenceA == ack_frame.m_sequenceA &&
	     ack_type == ack_frame.m_type &&
	     m_payload.size() <= ack_frame.m_payload.size() &&
	     std::equal(m_payload.begin(), m_payload.end(),
	                ack_frame.m_payload.begin()))) {
		LogFatal("Unexpected acknowledgement frame\n");
	}
}

void DataFrame::Roundtrip(hdevice hdev)
{
	Roundtrip(hdev, m_type);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Device I/O

void SwitchMode(hdevice hdev)
{
	uint8_t data[64] = {};
	data[60] = 0x09;
	SendInterruptTransfer(hdev, data, sizeof(data));
}

void SetPart(hdevice hdev, SilegoPart part)
{
	DataFrame frame(DataFrame::SET_PART);
	frame.push_back((uint8_t)part);
	frame.push_back(0x00);
	frame.push_back(0x00);
	frame.push_back(0x00);
	frame.Roundtrip(hdev);
}

void SetStatusLED(hdevice hdev, bool status)
{
	DataFrame frame(DataFrame::SET_STATUS_LED);
	frame.push_back(status);
	frame.Roundtrip(hdev);
}

void SetIOConfig(hdevice hdev, IOConfig& config)
{
	DataFrame frame(DataFrame::CONFIG_IO);

	//Test point config data
	for(unsigned int i=2; i<=20; i++)
	{
		unsigned int cfg = config.driverConfigs[i];
		frame.push_back(cfg >> 8);
		frame.push_back(cfg & 0xff);

		//skip TP11 since that's ground, no config for it
		if(i == 10)
			i++;
	}

	//7 unknown bytes, leave zero for now
	for(size_t i=0; i<7; i++)
		frame.push_back(0);

	//Expansion connector
	uint8_t exp[3] = {0};
	uint8_t expansionBitMap[21][2] =
	{
		{0, 0x00},		//unused
		{1, 0x01},		//Vdd

		{2, 0x04},		//TP2
		{2, 0x01},		//TP3
		{2, 0x10},		//TP4
		{2, 0x40},		//TP5
		{0, 0x01},		//TP6
		{0, 0x04},		//TP7
		{0, 0x10},		//TP8
		{0, 0x40},		//TP9
		{0, 0x80},		//TP10

		{0, 0x20},		//TP12
		{2, 0x08},		//TP13
		{2, 0x02},		//TP14
		{1, 0x80},		//TP15
		{2, 0x20},		//TP16
		{0, 0x02},		//TP17
		{1, 0x20},		//TP18
		{1, 0x08},		//TP19
		{2, 0x08}		//TP20
	};
	for(unsigned int i=1; i<21; i++)
	{
		if(config.expansionEnabled[i])
			exp[expansionBitMap[i][0]] |= expansionBitMap[i][1];
	}
	for(size_t i=0; i<3; i++)
		frame.push_back(exp[i]);

	//LEDs from TP3 ... TP15
	unsigned int tpbase = 3;
	for(int i=0; i<3; i++)
	{
		uint8_t ledcfg = 0;
		for(int j=0; j<4; j++)
		{
			uint8_t bitmask = 1 << j;
			uint8_t tpnum = tpbase + j;

			if(config.ledEnabled[tpnum])
				ledcfg |= bitmask;
			if(config.ledInverted[tpnum])
				ledcfg |= (bitmask << 4);
		}
		frame.push_back(ledcfg);

		//Bump pointers. skip TP11 as it's not implemented in the hardware (ground)
		tpbase += 4;
		if(i == 1)
			tpbase ++;
	}

	//LEDs from TP16 ... TP20
	uint8_t leden = 0;
	uint8_t ledinv = 0;
	for(int i=0; i<5; i++)
	{
		uint8_t tpnum = 16 + i;
		uint8_t bitmask = 1 << i;

		if(config.ledEnabled[tpnum])
			leden |= bitmask;
		if(config.ledInverted[tpnum])
			ledinv |= bitmask;
	}
	frame.push_back(leden);
	frame.push_back(ledinv);

	//Always constant, meaning unknown
	frame.push_back(0x1);
	frame.push_back(0x0);
	frame.push_back(0x0);

	//Done, send it
	frame.Send(hdev);
}

//ch1 = Vdd, CH2...20 = TP2...20
//TODO: more than just a dummy placeholder
void ConfigureSiggen(hdevice hdev, uint8_t channel, double voltage)
{
	DataFrame frame(DataFrame::CONFIG_SIGGEN);

	uint16_t raw_voltage = voltage / 1.362;

	frame.push_back(2);					//signal generator
	frame.push_back(channel);			//channel number
	frame.push_back(1);					//hold at start value before starting
	frame.push_back(0);					//repeat waveform forever
	frame.push_back(1);					//end state: keep last state
	frame.push_back(raw_voltage >> 8);	//voltage
	frame.push_back(raw_voltage & 0xff);
	// frame.push_back(0);					//ramp delay
	// frame.push_back(0);
	// frame.push_back(0);					//integral step part
	// frame.push_back(0);
	// frame.push_back(0);					//step sign and fractional step part
	// frame.push_back(0);

	frame.Roundtrip(hdev);
}

void SetSiggenStatus(hdevice hdev, unsigned int chan, unsigned int status)
{
	DataFrame frame(DataFrame::ENABLE_SIGGEN);

	for(unsigned int i=1; i<=19; i++)
	{
		if(i == chan)					//apply our status
			frame.push_back(status);

		else
			frame.push_back(SIGGEN_NOP);	//no change
	}

	frame.Send(hdev);
}

void LoadBitstream(hdevice hdev, std::vector<uint8_t> bitstream)
{
	DataFrame frame(DataFrame::WRITE_BITSTREAM_SRAM);
	frame.push_back(0x80);
	frame.push_back(0x00);
	frame.push_back(0x00);

	uint16_t cycles = bitstream.size() * 8 + 34;
	frame.push_back(cycles >> 8);
	frame.push_back(cycles & 0xff);

	frame.m_sequenceB = (bitstream.size() + 3) / 60;

	for(size_t i = 0; i < bitstream.size(); i++) {
		frame.push_back(bitstream[i]);

		if(frame.IsFull()) {
			frame.Roundtrip(hdev, DataFrame::WRITE_BITSTREAM_SRAM_ACK1);
			frame = frame.Next();
		}
	}

	if(!frame.IsEmpty())
		frame.Roundtrip(hdev, DataFrame::WRITE_BITSTREAM_SRAM_ACK2);
}
<|endoftext|>


<commit_before>

#include "Timestamp.h"

namespace Vq {

}
<commit_msg>Added empty impl<commit_after>

#include "Timestamp.h"

namespace Vq {

Timestamp::Timestamp( const TimeVal &timeVal ) {

}

Timestamp::Timestamp( const Timestamp &other ) {

}

Timestamp::Timestamp( Timestamp &&other ) {

}

Timestamp & Timestamp::operator = ( const Timestamp &other ) {

}

Timestamp & Timestamp::operator = ( const Timestamp &&other ) {

}

bool Timestamp::operator == ( const Timestamp &other ) {

}

bool Timestamp::operator != ( const Timestamp &other ) {

}

bool Timestamp::operator >  ( const Timestamp &other ) {

}

bool Timestamp::operator >= ( const Timestamp &other ) {

}

bool Timestamp::operator <  ( const Timestamp &other ) {

}

bool Timestamp::operator <= ( const Timestamp &other ) {

}

Timestamp Timestamp::operator + ( const Timestamp &other ) {

}

Timestamp Timestamp::operator - ( const Timestamp &other ) {

}

Timestamp & Timestamp::operator += ( const Timestamp &other ) {

}

Timestamp & Timestamp::operator -= ( const Timestamp &other ) {

}

Timestamp::TimeVal Timestamp::toUTCMicroSec() const  {

}

Timestamp::TimeVal Timestamp::toPosixMicroSec() const  {

}

Timestamp Timestamp::now() {

}

Timestamp Timestamp::fromPosixEpoch( const std::time_t &time ) {

}

Timestamp Timestamp::fromUTCTime( const TimeVal &utc ) {

}

}
<|endoftext|>


<commit_before>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "GrVkSampler.h"

#include "GrVkGpu.h"

static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
        GrSamplerState::WrapMode wrapMode) {
    switch (wrapMode) {
        case GrSamplerState::WrapMode::kClamp:
            return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
        case GrSamplerState::WrapMode::kRepeat:
            return VK_SAMPLER_ADDRESS_MODE_REPEAT;
        case GrSamplerState::WrapMode::kMirrorRepeat:
            return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
    }
    SK_ABORT("Unknown wrap mode.");
    return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
}

GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrSamplerState& samplerState,
                                 uint32_t maxMipLevel) {
    static VkFilter vkMinFilterModes[] = {
        VK_FILTER_NEAREST,
        VK_FILTER_LINEAR,
        VK_FILTER_LINEAR
    };
    static VkFilter vkMagFilterModes[] = {
        VK_FILTER_NEAREST,
        VK_FILTER_LINEAR,
        VK_FILTER_LINEAR
    };

    VkSamplerCreateInfo createInfo;
    memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
    createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    createInfo.pNext = 0;
    createInfo.flags = 0;
    createInfo.magFilter = vkMagFilterModes[static_cast<int>(samplerState.filter())];
    createInfo.minFilter = vkMinFilterModes[static_cast<int>(samplerState.filter())];
    createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    createInfo.addressModeU = wrap_mode_to_vk_sampler_address(samplerState.wrapModeX());
    createInfo.addressModeV = wrap_mode_to_vk_sampler_address(samplerState.wrapModeY());
    createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; // Shouldn't matter
    createInfo.mipLodBias = 0.0f;
    createInfo.anisotropyEnable = VK_FALSE;
    createInfo.maxAnisotropy = 1.0f;
    createInfo.compareEnable = VK_FALSE;
    createInfo.compareOp = VK_COMPARE_OP_NEVER;
    // Vulkan doesn't have a direct mapping of GL's nearest or linear filters for minFilter since
    // there is always a mipmapMode. To get the same effect as GL we can set minLod = maxLod = 0.0.
    // This works since our min and mag filters are the same (this forces us to use mag on the 0
    // level mip). If the filters weren't the same we could set min = 0 and max = 0.25 to force
    // the minFilter on mip level 0.
    createInfo.minLod = 0.0f;
    bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0;
    createInfo.maxLod = !useMipMaps ? 0.0f : (float)(maxMipLevel);
    createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    createInfo.unnormalizedCoordinates = VK_FALSE;

    VkSampler sampler;
    GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateSampler(gpu->device(),
                                                          &createInfo,
                                                          nullptr,
                                                          &sampler));

    return new GrVkSampler(sampler, GenerateKey(samplerState, maxMipLevel));
}

void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
    SkASSERT(fSampler);
    GR_VK_CALL(gpu->vkInterface(), DestroySampler(gpu->device(), fSampler, nullptr));
}

uint16_t GrVkSampler::GenerateKey(const GrSamplerState& samplerState, uint32_t maxMipLevel) {
    const int kTileModeXShift = 2;
    const int kTileModeYShift = 4;
    const int kMipLevelShift = 6;

    uint16_t key = static_cast<uint16_t>(samplerState.filter());

    SkASSERT(static_cast<int>(samplerState.filter()) <= 3);
    key |= (static_cast<uint16_t>(samplerState.wrapModeX()) << kTileModeXShift);

    GR_STATIC_ASSERT(SkShader::kTileModeCount <= 4);
    key |= (static_cast<uint16_t>(samplerState.wrapModeY()) << kTileModeYShift);

    SkASSERT(maxMipLevel < 1024);
    key |= (maxMipLevel << kMipLevelShift);

    return key;
}
<commit_msg>Fix wrap mode asserts in GrVkSampler::GenerateKey<commit_after>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "GrVkSampler.h"

#include "GrVkGpu.h"

static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
        GrSamplerState::WrapMode wrapMode) {
    switch (wrapMode) {
        case GrSamplerState::WrapMode::kClamp:
            return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
        case GrSamplerState::WrapMode::kRepeat:
            return VK_SAMPLER_ADDRESS_MODE_REPEAT;
        case GrSamplerState::WrapMode::kMirrorRepeat:
            return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
    }
    SK_ABORT("Unknown wrap mode.");
    return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
}

GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrSamplerState& samplerState,
                                 uint32_t maxMipLevel) {
    static VkFilter vkMinFilterModes[] = {
        VK_FILTER_NEAREST,
        VK_FILTER_LINEAR,
        VK_FILTER_LINEAR
    };
    static VkFilter vkMagFilterModes[] = {
        VK_FILTER_NEAREST,
        VK_FILTER_LINEAR,
        VK_FILTER_LINEAR
    };

    VkSamplerCreateInfo createInfo;
    memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
    createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    createInfo.pNext = 0;
    createInfo.flags = 0;
    createInfo.magFilter = vkMagFilterModes[static_cast<int>(samplerState.filter())];
    createInfo.minFilter = vkMinFilterModes[static_cast<int>(samplerState.filter())];
    createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    createInfo.addressModeU = wrap_mode_to_vk_sampler_address(samplerState.wrapModeX());
    createInfo.addressModeV = wrap_mode_to_vk_sampler_address(samplerState.wrapModeY());
    createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; // Shouldn't matter
    createInfo.mipLodBias = 0.0f;
    createInfo.anisotropyEnable = VK_FALSE;
    createInfo.maxAnisotropy = 1.0f;
    createInfo.compareEnable = VK_FALSE;
    createInfo.compareOp = VK_COMPARE_OP_NEVER;
    // Vulkan doesn't have a direct mapping of GL's nearest or linear filters for minFilter since
    // there is always a mipmapMode. To get the same effect as GL we can set minLod = maxLod = 0.0.
    // This works since our min and mag filters are the same (this forces us to use mag on the 0
    // level mip). If the filters weren't the same we could set min = 0 and max = 0.25 to force
    // the minFilter on mip level 0.
    createInfo.minLod = 0.0f;
    bool useMipMaps = GrSamplerState::Filter::kMipMap == samplerState.filter() && maxMipLevel > 0;
    createInfo.maxLod = !useMipMaps ? 0.0f : (float)(maxMipLevel);
    createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    createInfo.unnormalizedCoordinates = VK_FALSE;

    VkSampler sampler;
    GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateSampler(gpu->device(),
                                                          &createInfo,
                                                          nullptr,
                                                          &sampler));

    return new GrVkSampler(sampler, GenerateKey(samplerState, maxMipLevel));
}

void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
    SkASSERT(fSampler);
    GR_VK_CALL(gpu->vkInterface(), DestroySampler(gpu->device(), fSampler, nullptr));
}

uint16_t GrVkSampler::GenerateKey(const GrSamplerState& samplerState, uint32_t maxMipLevel) {
    const int kTileModeXShift = 2;
    const int kTileModeYShift = 4;
    const int kMipLevelShift = 6;

    SkASSERT(static_cast<int>(samplerState.filter()) <= 3);
    uint16_t key = static_cast<uint16_t>(samplerState.filter());

    SkASSERT(static_cast<int>(samplerState.wrapModeX()) <= 4);
    key |= (static_cast<uint16_t>(samplerState.wrapModeX()) << kTileModeXShift);

    SkASSERT(static_cast<int>(samplerState.wrapModeY()) <= 4);
    key |= (static_cast<uint16_t>(samplerState.wrapModeY()) << kTileModeYShift);

    SkASSERT(maxMipLevel < 1024);
    key |= (maxMipLevel << kMipLevelShift);

    return key;
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  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 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, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "OGLHelper.h"

#ifdef __APPLE__
#include "AppleGLHelper.h"
#endif

#include "../base/Logger.h"
#include "../base/Exception.h"

#ifndef _WIN32
#include <dlfcn.h>
#endif

#include <assert.h>
#include <iostream>
#include <sstream>

using namespace std;

namespace avg {

namespace glproc {
    PFNGLGENBUFFERSPROC GenBuffers;
    PFNGLBUFFERDATAPROC BufferData;
    PFNGLDELETEBUFFERSPROC DeleteBuffers;
    PFNGLBINDBUFFERPROC BindBuffer;
    PFNGLMAPBUFFERPROC MapBuffer;
    PFNGLUNMAPBUFFERPROC UnmapBuffer;
    PFNGLGETBUFFERSUBDATAPROC GetBufferSubData;

    PFNGLCREATESHADEROBJECTARBPROC CreateShaderObject;
    PFNGLSHADERSOURCEARBPROC ShaderSource;
    PFNGLCOMPILESHADERARBPROC CompileShader;
    PFNGLCREATEPROGRAMOBJECTARBPROC CreateProgramObject;
    PFNGLATTACHOBJECTARBPROC AttachObject;
    PFNGLLINKPROGRAMARBPROC LinkProgram;
    PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameteriv;
    PFNGLGETINFOLOGARBPROC GetInfoLog;
    PFNGLUSEPROGRAMOBJECTARBPROC UseProgramObject;
    PFNGLGETUNIFORMLOCATIONARBPROC GetUniformLocation;
    PFNGLUNIFORM1IARBPROC Uniform1i;
    PFNGLUNIFORM1FARBPROC Uniform1f;
    PFNGLUNIFORM1FVARBPROC Uniform1fv;
    PFNGLBLENDEQUATIONPROC BlendEquation;
    PFNGLACTIVETEXTUREPROC ActiveTexture;
    PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC CheckFramebufferStatus;
    PFNGLGENFRAMEBUFFERSEXTPROC GenFramebuffers;
    PFNGLBINDFRAMEBUFFEREXTPROC BindFramebuffer;
    PFNGLFRAMEBUFFERTEXTURE2DEXTPROC FramebufferTexture2D;
    PFNGLDELETEFRAMEBUFFERSEXTPROC DeleteFramebuffers;
#ifdef linux
    PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
    PFNGLXWAITVIDEOSYNCSGIPROC WaitVideoSyncSGI;
#endif
#ifdef _WIN32
    PFNWGLEXTSWAPCONTROLPROC SwapIntervalEXT;
#endif

    void * s_hGLLib = 0;
}

void OGLErrorCheck(int avgcode, const string & where)
{
    GLenum err = glGetError();
    if (err != GL_NO_ERROR) {
        stringstream s;
        s << "OpenGL error in " << where <<": " << gluErrorString(err)
            << " (#" << err << ") ";
        AVG_TRACE(Logger::ERROR, s.str());
        if (err != GL_INVALID_OPERATION) {
            OGLErrorCheck(avgcode, "  --");
        }
        throw Exception(avgcode, s.str());
    }
}

#ifdef _WIN32
void winOGLErrorCheck(bool bOK, const string & where)
{
    if (!bOK) {
        char szErr[512];
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, where+":"+
                + szErr);
    }
}
#endif

bool queryOGLExtension(char *extName)
{
    /*
    ** Search for extName in the extensions string. Use of strstr()
    ** is not sufficient because extension names can be prefixes of
    ** other extension names. Could use strtok() but the constant
    ** string returned by glGetString might be in read-only memory.
    */
    char *p;
    size_t extNameLen = strlen(extName);

    p = (char *)glGetString(GL_EXTENSIONS);
//    cout << "OpenGL extensions string: " << p << endl;
    if (NULL == p) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get OpenGL extension string.");
    }

    char * end = p + strlen(p);

    while (p < end) {
        size_t n = strcspn(p, " ");
        if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
            return true;
        }
        p += (n + 1);
    }
    return false;
}

bool queryGLXExtension(char *extName) {
#if (defined __APPLE__) || (defined _WIN32)
    return false;
#else
    int extNameLen = strlen(extName);

    Display * display = XOpenDisplay(0);
    char * p = (char *)glXQueryExtensionsString(display, DefaultScreen(display));
    if (NULL == p) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get GLX extension string.");
    }
//    cout << "GLX extensions string: " << p << endl;

    char * end = p + strlen(p);

    while (p < end) {
        int n = strcspn(p, " ");
        if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
            return true;
        }
        p += (n + 1);
    }
    return false;
#endif
}

void getGLVersion(int & major, int& minor)
{
    const char* pVersion = (const char*)glGetString(GL_VERSION);
    sscanf(pVersion, "%d.%d", &major, &minor);
}

void getGLShadingLanguageVersion(int & major, int& minor)
{
    const char* pVersion = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
    sscanf(pVersion, "%d.%d", &major, &minor);
}

void invalidGLCall()
{
    // Use this to cause core dump so we have the stack.
//    printf("%s");
    throw Exception(AVG_ERR_VIDEO_GENERAL, "Illegal gl entry point called.");
    // Cause core dump.
}

void loadGLLibrary()
{
#ifdef _WIN32
    const char * pszFName = "OPENGL32.DLL";
    char szErr[512];

    glproc::s_hGLLib = (void *)LoadLibrary(pszFName);

    if (glproc::s_hGLLib == 0) {
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
                + szErr);
    }
#else
#ifdef __APPLE__
    const char * pszFName = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
#else
    const char * pszFName = "libGL.so.1";
#endif
    glproc::s_hGLLib = dlopen(pszFName, RTLD_NOW);
    if (glproc::s_hGLLib == 0) {
        const char * pszErr = (char *)dlerror();
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
                + pszErr);
    }
#endif
}

GLfunction getProcAddress(const string& sName)
{
    assert(glproc::s_hGLLib);
#ifdef _WIN32
	GLfunction pProc = (GLfunction)wglGetProcAddress(sName.c_str());
    if (!pProc) {
	    char szErr[512];
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("wglGetProcAddress failed: ") + szErr);
    }

#else
    GLfunction pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName.c_str());
    if (!pProc) {
        // If the name didn't work, try using an underscore :-).
        string sName_ = string("_")+sName;
        pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName_.c_str());
    }
#endif
    return(pProc);
}

GLfunction getFuzzyProcAddress(const char * psz)
{
    GLfunction pProc = getProcAddress(psz);
    if (!pProc) {
        string s = string(psz)+"EXT";
        pProc = getProcAddress(s);
    }
    if (!pProc) {
        string s = string(psz)+"ARB";
        pProc = getProcAddress(s);
    }
    if (!pProc) {
        pProc = invalidGLCall;
//        AVG_TRACE(Logger::WARNING, "Couldn't initialize pointer to " << psz);
    } else {
//        AVG_TRACE(Logger::WARNING, "Pointer to " << psz << " initialized.");
    }
    return pProc;
}
#ifdef linux
GLfunction getglXProcAddress(const char * psz)
{
    GLfunction pProc = (GLfunction)glXGetProcAddress((const GLubyte *)psz);
    //GLfunction pProc = (GLfunction)glXGetProcAddressARB((const GLubyte *)psz);
    if (!pProc) {
        pProc = invalidGLCall;
    }
    return pProc;
}
#endif

#ifdef _WIN32
GLfunction getwglProcAddress(const char * psz)
{
    GLfunction pProc = (GLfunction)wglGetProcAddress((LPCSTR)psz);
    if (!pProc) {
        pProc = invalidGLCall;
    }
    return pProc;
}
#endif

namespace glproc {

    void init() {
        static bool s_bInitialized = false;
        if (s_bInitialized) {
            return;
        }
        s_bInitialized = true;
        loadGLLibrary();
#ifdef __APPLE__
        OSStatus err = aglInitEntryPoints();
        if (noErr != err) {
            AVG_TRACE(Logger::ERROR,
                    "Couldn't initialize Apple OpenGL entry points.");
        }
#endif
        GenBuffers = (PFNGLGENBUFFERSPROC)getFuzzyProcAddress("glGenBuffers");
        BufferData = (PFNGLBUFFERDATAPROC)getFuzzyProcAddress("glBufferData");
        DeleteBuffers = (PFNGLDELETEBUFFERSPROC)getFuzzyProcAddress("glDeleteBuffers");
        BindBuffer = (PFNGLBINDBUFFERPROC)getFuzzyProcAddress("glBindBuffer");
        MapBuffer = (PFNGLMAPBUFFERPROC)getFuzzyProcAddress("glMapBuffer");
        UnmapBuffer = (PFNGLUNMAPBUFFERPROC)getFuzzyProcAddress("glUnmapBuffer");
        GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)getFuzzyProcAddress("glGetBufferSubData");

        CreateShaderObject = (PFNGLCREATESHADEROBJECTARBPROC)
                getFuzzyProcAddress("glCreateShaderObject");
        ShaderSource = (PFNGLSHADERSOURCEARBPROC)
                getFuzzyProcAddress("glShaderSource");
        CompileShader = (PFNGLCOMPILESHADERARBPROC)
                getFuzzyProcAddress("glCompileShader");
        CreateProgramObject = (PFNGLCREATEPROGRAMOBJECTARBPROC)
                getFuzzyProcAddress("glCreateProgramObject");
        AttachObject = (PFNGLATTACHOBJECTARBPROC)
                getFuzzyProcAddress("glAttachObject");
        LinkProgram = (PFNGLLINKPROGRAMARBPROC)getFuzzyProcAddress("glLinkProgram");
        GetObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)
                getFuzzyProcAddress("glGetObjectParameteriv");
        GetInfoLog = (PFNGLGETINFOLOGARBPROC)getFuzzyProcAddress("glGetInfoLog");
        UseProgramObject =(PFNGLUSEPROGRAMOBJECTARBPROC)
                getFuzzyProcAddress("glUseProgramObject");
        GetUniformLocation = (PFNGLGETUNIFORMLOCATIONARBPROC)
                getFuzzyProcAddress("glGetUniformLocation");
        Uniform1i = (PFNGLUNIFORM1IARBPROC)getFuzzyProcAddress("glUniform1i");
        Uniform1f = (PFNGLUNIFORM1FARBPROC)getFuzzyProcAddress("glUniform1f");
        Uniform1fv = (PFNGLUNIFORM1FVARBPROC)getFuzzyProcAddress("glUniform1fv");
        BlendEquation = (PFNGLBLENDEQUATIONPROC)getFuzzyProcAddress("glBlendEquation");
        ActiveTexture = (PFNGLACTIVETEXTUREPROC)getFuzzyProcAddress("glActiveTexture");
        CheckFramebufferStatus =
                (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)getFuzzyProcAddress("glCheckFramebufferStatus");
        GenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)getFuzzyProcAddress("glGenFramebuffers");
        BindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)getFuzzyProcAddress("glBindFramebuffer");
        FramebufferTexture2D =
                (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)getFuzzyProcAddress("glFramebufferTexture2D");
        DeleteFramebuffers =
                (PFNGLDELETEFRAMEBUFFERSEXTPROC)getFuzzyProcAddress("glDeleteFramebuffers");
#ifdef linux
        SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)getglXProcAddress("glXSwapIntervalSGI");
        WaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)getglXProcAddress("glXWaitVideoSyncSGI");
#endif

#ifdef _WIN32
        SwapIntervalEXT = (PFNWGLEXTSWAPCONTROLPROC) getwglProcAddress("wglSwapIntervalEXT");
#endif
    }
}

}
<commit_msg>Fixed windows crash on older systems.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2006 Ulrich von Zadow
//
//  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 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, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "OGLHelper.h"

#ifdef __APPLE__
#include "AppleGLHelper.h"
#endif

#include "../base/Logger.h"
#include "../base/Exception.h"

#ifndef _WIN32
#include <dlfcn.h>
#endif

#include <assert.h>
#include <iostream>
#include <sstream>

using namespace std;

namespace avg {

namespace glproc {
    PFNGLGENBUFFERSPROC GenBuffers;
    PFNGLBUFFERDATAPROC BufferData;
    PFNGLDELETEBUFFERSPROC DeleteBuffers;
    PFNGLBINDBUFFERPROC BindBuffer;
    PFNGLMAPBUFFERPROC MapBuffer;
    PFNGLUNMAPBUFFERPROC UnmapBuffer;
    PFNGLGETBUFFERSUBDATAPROC GetBufferSubData;

    PFNGLCREATESHADEROBJECTARBPROC CreateShaderObject;
    PFNGLSHADERSOURCEARBPROC ShaderSource;
    PFNGLCOMPILESHADERARBPROC CompileShader;
    PFNGLCREATEPROGRAMOBJECTARBPROC CreateProgramObject;
    PFNGLATTACHOBJECTARBPROC AttachObject;
    PFNGLLINKPROGRAMARBPROC LinkProgram;
    PFNGLGETOBJECTPARAMETERIVARBPROC GetObjectParameteriv;
    PFNGLGETINFOLOGARBPROC GetInfoLog;
    PFNGLUSEPROGRAMOBJECTARBPROC UseProgramObject;
    PFNGLGETUNIFORMLOCATIONARBPROC GetUniformLocation;
    PFNGLUNIFORM1IARBPROC Uniform1i;
    PFNGLUNIFORM1FARBPROC Uniform1f;
    PFNGLUNIFORM1FVARBPROC Uniform1fv;
    PFNGLBLENDEQUATIONPROC BlendEquation;
    PFNGLACTIVETEXTUREPROC ActiveTexture;
    PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC CheckFramebufferStatus;
    PFNGLGENFRAMEBUFFERSEXTPROC GenFramebuffers;
    PFNGLBINDFRAMEBUFFEREXTPROC BindFramebuffer;
    PFNGLFRAMEBUFFERTEXTURE2DEXTPROC FramebufferTexture2D;
    PFNGLDELETEFRAMEBUFFERSEXTPROC DeleteFramebuffers;
#ifdef linux
    PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
    PFNGLXWAITVIDEOSYNCSGIPROC WaitVideoSyncSGI;
#endif
#ifdef _WIN32
    PFNWGLEXTSWAPCONTROLPROC SwapIntervalEXT;
#endif

    void * s_hGLLib = 0;
}

void OGLErrorCheck(int avgcode, const string & where)
{
    GLenum err = glGetError();
    if (err != GL_NO_ERROR) {
        stringstream s;
        s << "OpenGL error in " << where <<": " << gluErrorString(err)
            << " (#" << err << ") ";
        AVG_TRACE(Logger::ERROR, s.str());
        if (err != GL_INVALID_OPERATION) {
            OGLErrorCheck(avgcode, "  --");
        }
        throw Exception(avgcode, s.str());
    }
}

#ifdef _WIN32
void winOGLErrorCheck(bool bOK, const string & where)
{
    if (!bOK) {
        char szErr[512];
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, where+":"+
                + szErr);
    }
}
#endif

bool queryOGLExtension(char *extName)
{
    /*
    ** Search for extName in the extensions string. Use of strstr()
    ** is not sufficient because extension names can be prefixes of
    ** other extension names. Could use strtok() but the constant
    ** string returned by glGetString might be in read-only memory.
    */
    char *p;
    size_t extNameLen = strlen(extName);

    p = (char *)glGetString(GL_EXTENSIONS);
//    cout << "OpenGL extensions string: " << p << endl;
    if (NULL == p) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get OpenGL extension string.");
    }

    char * end = p + strlen(p);

    while (p < end) {
        size_t n = strcspn(p, " ");
        if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
            return true;
        }
        p += (n + 1);
    }
    return false;
}

bool queryGLXExtension(char *extName) {
#if (defined __APPLE__) || (defined _WIN32)
    return false;
#else
    int extNameLen = strlen(extName);

    Display * display = XOpenDisplay(0);
    char * p = (char *)glXQueryExtensionsString(display, DefaultScreen(display));
    if (NULL == p) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "Couldn't get GLX extension string.");
    }
//    cout << "GLX extensions string: " << p << endl;

    char * end = p + strlen(p);

    while (p < end) {
        int n = strcspn(p, " ");
        if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
            return true;
        }
        p += (n + 1);
    }
    return false;
#endif
}

void getGLVersion(int & major, int& minor)
{
    const char* pVersion = (const char*)glGetString(GL_VERSION);
    sscanf(pVersion, "%d.%d", &major, &minor);
}

void getGLShadingLanguageVersion(int & major, int& minor)
{
    const char* pVersion = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
    sscanf(pVersion, "%d.%d", &major, &minor);
}

void invalidGLCall()
{
    // Use this to cause core dump so we have the stack.
//    printf("%s");
    throw Exception(AVG_ERR_VIDEO_GENERAL, "Illegal gl entry point called.");
    // Cause core dump.
}

void loadGLLibrary()
{
#ifdef _WIN32
    const char * pszFName = "OPENGL32.DLL";
    char szErr[512];

    glproc::s_hGLLib = (void *)LoadLibrary(pszFName);

    if (glproc::s_hGLLib == 0) {
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
                + szErr);
    }
#else
#ifdef __APPLE__
    const char * pszFName = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
#else
    const char * pszFName = "libGL.so.1";
#endif
    glproc::s_hGLLib = dlopen(pszFName, RTLD_NOW);
    if (glproc::s_hGLLib == 0) {
        const char * pszErr = (char *)dlerror();
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("Loading ") + pszFName + "failed: "
                + pszErr);
    }
#endif
}

GLfunction getProcAddress(const string& sName)
{
    assert(glproc::s_hGLLib);
#ifdef _WIN32
	GLfunction pProc = (GLfunction)wglGetProcAddress(sName.c_str());
/*
    if (!pProc) {
	    char szErr[512];
        FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM),
                0, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                szErr, 512, 0);
        throw Exception(AVG_ERR_VIDEO_GENERAL, string("wglGetProcAddress("+sName+") failed: ") + szErr);
    }
*/
#else
    GLfunction pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName.c_str());
    if (!pProc) {
        // If the name didn't work, try using an underscore :-).
        string sName_ = string("_")+sName;
        pProc = (GLfunction)dlsym(glproc::s_hGLLib, sName_.c_str());
    }
#endif
    return(pProc);
}

GLfunction getFuzzyProcAddress(const char * psz)
{
    GLfunction pProc = getProcAddress(psz);
    if (!pProc) {
        string s = string(psz)+"EXT";
        pProc = getProcAddress(s);
    }
    if (!pProc) {
        string s = string(psz)+"ARB";
        pProc = getProcAddress(s);
    }
    if (!pProc) {
        pProc = invalidGLCall;
//        AVG_TRACE(Logger::WARNING, "Couldn't initialize pointer to " << psz);
    } else {
//        AVG_TRACE(Logger::WARNING, "Pointer to " << psz << " initialized.");
    }
    return pProc;
}
#ifdef linux
GLfunction getglXProcAddress(const char * psz)
{
    GLfunction pProc = (GLfunction)glXGetProcAddress((const GLubyte *)psz);
    //GLfunction pProc = (GLfunction)glXGetProcAddressARB((const GLubyte *)psz);
    if (!pProc) {
        pProc = invalidGLCall;
    }
    return pProc;
}
#endif

#ifdef _WIN32
GLfunction getwglProcAddress(const char * psz)
{
    GLfunction pProc = (GLfunction)wglGetProcAddress((LPCSTR)psz);
    if (!pProc) {
        pProc = invalidGLCall;
    }
    return pProc;
}
#endif

namespace glproc {

    void init() {
        static bool s_bInitialized = false;
        if (s_bInitialized) {
            return;
        }
        s_bInitialized = true;
        loadGLLibrary();
#ifdef __APPLE__
        OSStatus err = aglInitEntryPoints();
        if (noErr != err) {
            AVG_TRACE(Logger::ERROR,
                    "Couldn't initialize Apple OpenGL entry points.");
        }
#endif
        GenBuffers = (PFNGLGENBUFFERSPROC)getFuzzyProcAddress("glGenBuffers");
        BufferData = (PFNGLBUFFERDATAPROC)getFuzzyProcAddress("glBufferData");
        DeleteBuffers = (PFNGLDELETEBUFFERSPROC)getFuzzyProcAddress("glDeleteBuffers");
        BindBuffer = (PFNGLBINDBUFFERPROC)getFuzzyProcAddress("glBindBuffer");
        MapBuffer = (PFNGLMAPBUFFERPROC)getFuzzyProcAddress("glMapBuffer");
        UnmapBuffer = (PFNGLUNMAPBUFFERPROC)getFuzzyProcAddress("glUnmapBuffer");
        GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)getFuzzyProcAddress("glGetBufferSubData");

        CreateShaderObject = (PFNGLCREATESHADEROBJECTARBPROC)
                getFuzzyProcAddress("glCreateShaderObject");
        ShaderSource = (PFNGLSHADERSOURCEARBPROC)
                getFuzzyProcAddress("glShaderSource");
        CompileShader = (PFNGLCOMPILESHADERARBPROC)
                getFuzzyProcAddress("glCompileShader");
        CreateProgramObject = (PFNGLCREATEPROGRAMOBJECTARBPROC)
                getFuzzyProcAddress("glCreateProgramObject");
        AttachObject = (PFNGLATTACHOBJECTARBPROC)
                getFuzzyProcAddress("glAttachObject");
        LinkProgram = (PFNGLLINKPROGRAMARBPROC)getFuzzyProcAddress("glLinkProgram");
        GetObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)
                getFuzzyProcAddress("glGetObjectParameteriv");
        GetInfoLog = (PFNGLGETINFOLOGARBPROC)getFuzzyProcAddress("glGetInfoLog");
        UseProgramObject =(PFNGLUSEPROGRAMOBJECTARBPROC)
                getFuzzyProcAddress("glUseProgramObject");
        GetUniformLocation = (PFNGLGETUNIFORMLOCATIONARBPROC)
                getFuzzyProcAddress("glGetUniformLocation");
        Uniform1i = (PFNGLUNIFORM1IARBPROC)getFuzzyProcAddress("glUniform1i");
        Uniform1f = (PFNGLUNIFORM1FARBPROC)getFuzzyProcAddress("glUniform1f");
        Uniform1fv = (PFNGLUNIFORM1FVARBPROC)getFuzzyProcAddress("glUniform1fv");
        BlendEquation = (PFNGLBLENDEQUATIONPROC)getFuzzyProcAddress("glBlendEquation");
        ActiveTexture = (PFNGLACTIVETEXTUREPROC)getFuzzyProcAddress("glActiveTexture");
        CheckFramebufferStatus =
                (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)getFuzzyProcAddress("glCheckFramebufferStatus");
        GenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)getFuzzyProcAddress("glGenFramebuffers");
        BindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)getFuzzyProcAddress("glBindFramebuffer");
        FramebufferTexture2D =
                (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)getFuzzyProcAddress("glFramebufferTexture2D");
        DeleteFramebuffers =
                (PFNGLDELETEFRAMEBUFFERSEXTPROC)getFuzzyProcAddress("glDeleteFramebuffers");
#ifdef linux
        SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)getglXProcAddress("glXSwapIntervalSGI");
        WaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)getglXProcAddress("glXWaitVideoSyncSGI");
#endif

#ifdef _WIN32
        SwapIntervalEXT = (PFNWGLEXTSWAPCONTROLPROC) getwglProcAddress("wglSwapIntervalEXT");
#endif
    }
}

}
<|endoftext|>


<commit_before>//
//  AppleDSK.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 27/04/2018.
//  Copyright 2018 Thomas Harte. All rights reserved.
//

#include "AppleDSK.hpp"

#include "../../Track/PCMTrack.hpp"
#include "../../Track/TrackSerialiser.hpp"
#include "../../Encodings/AppleGCR/Encoder.hpp"
#include "../../Encodings/AppleGCR/SegmentParser.hpp"

using namespace Storage::Disk;

namespace {
	const int number_of_tracks = 35;
	const int bytes_per_sector = 256;
}

AppleDSK::AppleDSK(const std::string &file_name) :
	file_(file_name) {
	if(file_.stats().st_size % (number_of_tracks*bytes_per_sector)) throw Error::InvalidFormat;

	sectors_per_track_ = static_cast<int>(file_.stats().st_size / (number_of_tracks*bytes_per_sector));
	if(sectors_per_track_ != 13 && sectors_per_track_ != 16) throw Error::InvalidFormat;

	// Check whether this is a Pro DOS disk by inspecting the filename.
	if(sectors_per_track_ == 16) {
		size_t string_index = file_name.size()-1;
		while(file_name[string_index] != '.') {
			if(file_name[string_index] == 'p') {
				is_prodos_ = true;
				break;
			}
			--string_index;
		}
	}
}

HeadPosition AppleDSK::get_maximum_head_position() {
	return HeadPosition(number_of_tracks);
}

bool AppleDSK::get_is_read_only() {
	return file_.get_is_known_read_only();
}

long AppleDSK::file_offset(Track::Address address) {
	return address.position.as_int() * bytes_per_sector * sectors_per_track_;
}

size_t AppleDSK::logical_sector_for_physical_sector(size_t physical) {
	// DOS and Pro DOS interleave sectors on disk, and they're represented in a disk
	// image in physical order rather than logical.
	if(physical == 15) return 15;
	return (physical * (is_prodos_ ? 8 : 7)) % 15;
}

std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
	std::vector<uint8_t> track_data;
	{
		std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
		file_.seek(file_offset(address), SEEK_SET);
		track_data = file_.read(static_cast<size_t>(bytes_per_sector * sectors_per_track_));
	}

	Storage::Disk::PCMSegment segment;
	const uint8_t track = static_cast<uint8_t>(address.position.as_int());

	// In either case below, the code aims for exactly 50,000 bits per track.
	if(sectors_per_track_ == 16) {
		// Write the sectors.
		for(uint8_t c = 0; c < 16; ++c) {
			segment += Encodings::AppleGCR::six_and_two_sync(10);
			segment += Encodings::AppleGCR::header(254, track, c);
			segment += Encodings::AppleGCR::six_and_two_sync(10);
			segment += Encodings::AppleGCR::six_and_two_data(&track_data[logical_sector_for_physical_sector(c) * 256]);
		}

		// Pad if necessary.
		if(segment.number_of_bits < 50000) {
			segment += Encodings::AppleGCR::six_and_two_sync((50000 - segment.number_of_bits) / 10);
		}
	} else {
		// TODO: 5 and 3, 13-sector format. If DSK actually supports it?
	}

	return std::make_shared<PCMTrack>(segment);
}

void AppleDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
	std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
	for(const auto &pair: tracks) {
		// Decode the track.
		auto sector_map = Storage::Encodings::AppleGCR::sectors_from_segment(
			Storage::Disk::track_serialisation(*pair.second, Storage::Time(1, 50000)));

		// Rearrange sectors into Apple DOS or Pro-DOS order.
		std::vector<uint8_t> track_contents(static_cast<size_t>(bytes_per_sector * sectors_per_track_));
		for(const auto &sector_pair: sector_map) {
			const size_t target_address = logical_sector_for_physical_sector(sector_pair.second.address.sector);
			memcpy(&track_contents[target_address*256], sector_pair.second.data.data(), bytes_per_sector);
		}

		// Store for later.
		tracks_by_address[pair.first] = std::move(track_contents);
	}

	std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
	for(const auto &pair: tracks_by_address) {
		file_.seek(file_offset(pair.first), SEEK_SET);
		file_.write(pair.second);
	}
}
<commit_msg>Adds missing import for `memcpy`.<commit_after>//
//  AppleDSK.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 27/04/2018.
//  Copyright 2018 Thomas Harte. All rights reserved.
//

#include "AppleDSK.hpp"

#include "../../Track/PCMTrack.hpp"
#include "../../Track/TrackSerialiser.hpp"
#include "../../Encodings/AppleGCR/Encoder.hpp"
#include "../../Encodings/AppleGCR/SegmentParser.hpp"

#include <cstring>

using namespace Storage::Disk;

namespace {
	const int number_of_tracks = 35;
	const int bytes_per_sector = 256;
}

AppleDSK::AppleDSK(const std::string &file_name) :
	file_(file_name) {
	if(file_.stats().st_size % (number_of_tracks*bytes_per_sector)) throw Error::InvalidFormat;

	sectors_per_track_ = static_cast<int>(file_.stats().st_size / (number_of_tracks*bytes_per_sector));
	if(sectors_per_track_ != 13 && sectors_per_track_ != 16) throw Error::InvalidFormat;

	// Check whether this is a Pro DOS disk by inspecting the filename.
	if(sectors_per_track_ == 16) {
		size_t string_index = file_name.size()-1;
		while(file_name[string_index] != '.') {
			if(file_name[string_index] == 'p') {
				is_prodos_ = true;
				break;
			}
			--string_index;
		}
	}
}

HeadPosition AppleDSK::get_maximum_head_position() {
	return HeadPosition(number_of_tracks);
}

bool AppleDSK::get_is_read_only() {
	return file_.get_is_known_read_only();
}

long AppleDSK::file_offset(Track::Address address) {
	return address.position.as_int() * bytes_per_sector * sectors_per_track_;
}

size_t AppleDSK::logical_sector_for_physical_sector(size_t physical) {
	// DOS and Pro DOS interleave sectors on disk, and they're represented in a disk
	// image in physical order rather than logical.
	if(physical == 15) return 15;
	return (physical * (is_prodos_ ? 8 : 7)) % 15;
}

std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
	std::vector<uint8_t> track_data;
	{
		std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
		file_.seek(file_offset(address), SEEK_SET);
		track_data = file_.read(static_cast<size_t>(bytes_per_sector * sectors_per_track_));
	}

	Storage::Disk::PCMSegment segment;
	const uint8_t track = static_cast<uint8_t>(address.position.as_int());

	// In either case below, the code aims for exactly 50,000 bits per track.
	if(sectors_per_track_ == 16) {
		// Write the sectors.
		for(uint8_t c = 0; c < 16; ++c) {
			segment += Encodings::AppleGCR::six_and_two_sync(10);
			segment += Encodings::AppleGCR::header(254, track, c);
			segment += Encodings::AppleGCR::six_and_two_sync(10);
			segment += Encodings::AppleGCR::six_and_two_data(&track_data[logical_sector_for_physical_sector(c) * 256]);
		}

		// Pad if necessary.
		if(segment.number_of_bits < 50000) {
			segment += Encodings::AppleGCR::six_and_two_sync((50000 - segment.number_of_bits) / 10);
		}
	} else {
		// TODO: 5 and 3, 13-sector format. If DSK actually supports it?
	}

	return std::make_shared<PCMTrack>(segment);
}

void AppleDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
	std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
	for(const auto &pair: tracks) {
		// Decode the track.
		auto sector_map = Storage::Encodings::AppleGCR::sectors_from_segment(
			Storage::Disk::track_serialisation(*pair.second, Storage::Time(1, 50000)));

		// Rearrange sectors into Apple DOS or Pro-DOS order.
		std::vector<uint8_t> track_contents(static_cast<size_t>(bytes_per_sector * sectors_per_track_));
		for(const auto &sector_pair: sector_map) {
			const size_t target_address = logical_sector_for_physical_sector(sector_pair.second.address.sector);
			memcpy(&track_contents[target_address*256], sector_pair.second.data.data(), bytes_per_sector);
		}

		// Store for later.
		tracks_by_address[pair.first] = std::move(track_contents);
	}

	std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
	for(const auto &pair: tracks_by_address) {
		file_.seek(file_offset(pair.first), SEEK_SET);
		file_.write(pair.second);
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fwkbase.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2005-06-17 10:12:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_FWKBASE_HXX
#define INCLUDED_JVMFWK_FWKBASE_HXX
#include "rtl/ustring.hxx"
#include "libxmlutil.hxx"
namespace jfw
{

class VendorSettings
{
    rtl::OUString m_xmlDocVendorSettingsFileUrl;
    CXmlDocPtr m_xmlDocVendorSettings;
    CXPathContextPtr m_xmlPathContextVendorSettings;

public:
    VendorSettings();

    /** Gets all plugin library URLs with the corresponding vendor name.

    It uses the /javaSelection/plugins/library element from the javavendors.xml
    to locate the library.
    Is is verified that the plug-in exist. If a plug-in does not exist then an
    exception is thrown containing the error JFW_E_CONFIGURATION
    */
    std::vector<PluginLibrary> getPluginData();

    /* returns the file URL to the plugin.
     */
    rtl::OUString getPluginLibrary(const rtl::OUString& sVendor);

    VersionInfo getVersionInformation(const rtl::OUString & sVendor);

    std::vector<rtl::OUString> getSupportedVendors();
};

/* The class offers functions to retrieve verified bootstrap parameters.
 */
namespace  BootParams
{

/* Gets the file URL to the JRE which has been determined by the
   bootstrap parameter UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME.

   In direct mode either of them must be set. If not an exception is thrown.
*/
rtl::OUString getJREHome();

::std::vector<rtl::OString> getVMParameters();

rtl::OUString getUserData();

rtl::OUString getSharedData();

/* returns the file URL to the vendor settings xml file.
 */
rtl::OUString getVendorSettings();

/* User the parameter UNO_JAVA_JFW_CLASSPATH and UNO_JAVA_JFW_ENV_CLASSPATH
   to compose a classpath
 */
rtl::OString getClasspath();

rtl::OUString getClasspathUrls();

} //end namespace

/** Get the file URL to the javasettings.xml
        If the file does not exist yet, then an
        empty string is returned.

        @throws FrameworkException
    */
//rtl::OUString getUserSettingsURL();

enum JFW_MODE
{
    JFW_MODE_APPLICATION,

    JFW_MODE_DIRECT
};

JFW_MODE getMode();

/** creates the -Djava.class.path option with the complete classpath.
    If param mode is JFW_MODE_ENV_SIMPLE then the param javaSettings is ignored.
 */
rtl::OString makeClassPathOption(CNodeJava & javaSettings);

/** Get the system path to the javasettings.xml
    Converts the URL returned from getUserSettingsURL to a
    Systempath. An empty string is returned if the file
    does not exist.
   @throws FrameworkException
 */
rtl::OString getUserSettingsPath();

/* returns the system path to the file where the
   user data is to be stored.
*/
rtl::OString getUserSettingsStoreLocation();

/** Returns the system path of the share settings file.
    Returns a valid string or throws an exception.
   @throws FrameworkException
 */
rtl::OString getSharedSettingsPath();

/* Determines the application base which is either the BaseInstallation
   (see getBaseInstallation) or the directory where the executable is resides.

   This function always returns a URL or throws an exception.
*/
rtl::OUString getApplicationBase();

/* returns a valid string or throws an exception.
   @throws FrameworkException
 */
rtl::OString getVendorSettingsPath();

rtl::OUString buildClassPathFromDirectory(const rtl::OUString & relPath);

/** Called from writeJavaInfoData. It sets the process identifier. When
java is to be started, then the current id is compared to the one set by
this function. If they are identical then the Java was selected in the
same process. If that Java needs a prepared environment, such as a
LD_LIBRARY_PATH, then it must not be started in this process.
*/
void setJavaSelected();

/** Determines if the currently selected Java was set in this process.

    @see setProcessId()
 */
bool wasJavaSelectedInSameProcess();
/* Only for application mode.
 */
rtl::OUString getApplicationClassPath();
}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.6); FILE MERGED 2005/09/05 17:12:28 rt 1.4.6.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fwkbase.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:35:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#if !defined INCLUDED_JVMFWK_FWKBASE_HXX
#define INCLUDED_JVMFWK_FWKBASE_HXX
#include "rtl/ustring.hxx"
#include "libxmlutil.hxx"
namespace jfw
{

class VendorSettings
{
    rtl::OUString m_xmlDocVendorSettingsFileUrl;
    CXmlDocPtr m_xmlDocVendorSettings;
    CXPathContextPtr m_xmlPathContextVendorSettings;

public:
    VendorSettings();

    /** Gets all plugin library URLs with the corresponding vendor name.

    It uses the /javaSelection/plugins/library element from the javavendors.xml
    to locate the library.
    Is is verified that the plug-in exist. If a plug-in does not exist then an
    exception is thrown containing the error JFW_E_CONFIGURATION
    */
    std::vector<PluginLibrary> getPluginData();

    /* returns the file URL to the plugin.
     */
    rtl::OUString getPluginLibrary(const rtl::OUString& sVendor);

    VersionInfo getVersionInformation(const rtl::OUString & sVendor);

    std::vector<rtl::OUString> getSupportedVendors();
};

/* The class offers functions to retrieve verified bootstrap parameters.
 */
namespace  BootParams
{

/* Gets the file URL to the JRE which has been determined by the
   bootstrap parameter UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME.

   In direct mode either of them must be set. If not an exception is thrown.
*/
rtl::OUString getJREHome();

::std::vector<rtl::OString> getVMParameters();

rtl::OUString getUserData();

rtl::OUString getSharedData();

/* returns the file URL to the vendor settings xml file.
 */
rtl::OUString getVendorSettings();

/* User the parameter UNO_JAVA_JFW_CLASSPATH and UNO_JAVA_JFW_ENV_CLASSPATH
   to compose a classpath
 */
rtl::OString getClasspath();

rtl::OUString getClasspathUrls();

} //end namespace

/** Get the file URL to the javasettings.xml
        If the file does not exist yet, then an
        empty string is returned.

        @throws FrameworkException
    */
//rtl::OUString getUserSettingsURL();

enum JFW_MODE
{
    JFW_MODE_APPLICATION,

    JFW_MODE_DIRECT
};

JFW_MODE getMode();

/** creates the -Djava.class.path option with the complete classpath.
    If param mode is JFW_MODE_ENV_SIMPLE then the param javaSettings is ignored.
 */
rtl::OString makeClassPathOption(CNodeJava & javaSettings);

/** Get the system path to the javasettings.xml
    Converts the URL returned from getUserSettingsURL to a
    Systempath. An empty string is returned if the file
    does not exist.
   @throws FrameworkException
 */
rtl::OString getUserSettingsPath();

/* returns the system path to the file where the
   user data is to be stored.
*/
rtl::OString getUserSettingsStoreLocation();

/** Returns the system path of the share settings file.
    Returns a valid string or throws an exception.
   @throws FrameworkException
 */
rtl::OString getSharedSettingsPath();

/* Determines the application base which is either the BaseInstallation
   (see getBaseInstallation) or the directory where the executable is resides.

   This function always returns a URL or throws an exception.
*/
rtl::OUString getApplicationBase();

/* returns a valid string or throws an exception.
   @throws FrameworkException
 */
rtl::OString getVendorSettingsPath();

rtl::OUString buildClassPathFromDirectory(const rtl::OUString & relPath);

/** Called from writeJavaInfoData. It sets the process identifier. When
java is to be started, then the current id is compared to the one set by
this function. If they are identical then the Java was selected in the
same process. If that Java needs a prepared environment, such as a
LD_LIBRARY_PATH, then it must not be started in this process.
*/
void setJavaSelected();

/** Determines if the currently selected Java was set in this process.

    @see setProcessId()
 */
bool wasJavaSelectedInSameProcess();
/* Only for application mode.
 */
rtl::OUString getApplicationClassPath();
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Stephen Williams (steve@icarus.com)
 * Copyright CERN 2013 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include  "pform.h"
# include  "PPackage.h"
# include  "parse_misc.h"
# include  "parse_api.h"
# include  <map>
# include  <sstream>
# include  "ivl_assert.h"

using namespace std;

/*
 * This is a map of packages that have been defined.
 */
map<perm_string,PPackage*> pform_packages;

static PPackage*pform_cur_package = 0;

void pform_start_package_declaration(const struct vlltype&loc, const char*name)
{
      ivl_assert(loc, pform_cur_package == 0);

      perm_string use_name = lex_strings.make(name);
      PPackage*pkg_scope = pform_push_package_scope(loc, use_name);
      FILE_NAME(pkg_scope, loc);
      pform_cur_package = pkg_scope;
}

void pform_end_package_declaration(const struct vlltype&loc)
{
      ivl_assert(loc, pform_cur_package);
      perm_string use_name = pform_cur_package->pscope_name();

      map<perm_string,PPackage*>::const_iterator test = pform_packages.find(use_name);
      if (test != pform_packages.end()) {
	    ostringstream msg;
	    msg << "Package " << use_name << " was already declared here: "
		<< test->second->get_fileline() << ends;
	    VLerror(msg.str().c_str());
      } else {
	    pform_packages[use_name] = pform_cur_package;
      }

      pform_packages[use_name] = pform_cur_package;
      pform_cur_package = 0;
      pform_pop_scope();
}

/*
 * Do the import early, during processing. This requires that the
 * package is declared in pform ahead of time (it is) and that we can
 * simply transfer definitions to the current scope (we can).
 */
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
{
      perm_string use_name = lex_strings.make(pkg_name);
      map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
      if (pcur == pform_packages.end()) {
	    ostringstream msg;
	    msg << "Package " << pkg_name << " not found." << ends;
	    VLerror(msg.str().c_str());
	    return;
      }

      perm_string use_ident;
      if (ident) use_ident = lex_strings.make(ident);

      PPackage*pkg = pcur->second;
      LexicalScope*scope = pform_peek_scope();

      for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
		 ; cur != pkg->parameters.end() ; ++cur) {

	    scope->parameters[cur->first] = cur->second;
      }
}
<commit_msg>Support import if single items.<commit_after>/*
 * Copyright (c) 2012 Stephen Williams (steve@icarus.com)
 * Copyright CERN 2013 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include  "pform.h"
# include  "PPackage.h"
# include  "parse_misc.h"
# include  "parse_api.h"
# include  <map>
# include  <sstream>
# include  "ivl_assert.h"

using namespace std;

/*
 * This is a map of packages that have been defined.
 */
map<perm_string,PPackage*> pform_packages;

static PPackage*pform_cur_package = 0;

void pform_start_package_declaration(const struct vlltype&loc, const char*name)
{
      ivl_assert(loc, pform_cur_package == 0);

      perm_string use_name = lex_strings.make(name);
      PPackage*pkg_scope = pform_push_package_scope(loc, use_name);
      FILE_NAME(pkg_scope, loc);
      pform_cur_package = pkg_scope;
}

void pform_end_package_declaration(const struct vlltype&loc)
{
      ivl_assert(loc, pform_cur_package);
      perm_string use_name = pform_cur_package->pscope_name();

      map<perm_string,PPackage*>::const_iterator test = pform_packages.find(use_name);
      if (test != pform_packages.end()) {
	    ostringstream msg;
	    msg << "Package " << use_name << " was already declared here: "
		<< test->second->get_fileline() << ends;
	    VLerror(msg.str().c_str());
      } else {
	    pform_packages[use_name] = pform_cur_package;
      }

      pform_packages[use_name] = pform_cur_package;
      pform_cur_package = 0;
      pform_pop_scope();
}

/*
 * Do the import early, during processing. This requires that the
 * package is declared in pform ahead of time (it is) and that we can
 * simply transfer definitions to the current scope (we can).
 */
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
{
      perm_string use_name = lex_strings.make(pkg_name);
      map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
      if (pcur == pform_packages.end()) {
	    ostringstream msg;
	    msg << "Package " << pkg_name << " not found." << ends;
	    VLerror(msg.str().c_str());
	    return;
      }

      PPackage*pkg = pcur->second;
      LexicalScope*scope = pform_peek_scope();

      if (ident) {
	    perm_string use_ident = lex_strings.make(ident);

	    map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
		  = pkg->parameters.find(use_ident);
	    if (cur == pkg->parameters.end()) {
		  ostringstream msg;
		  msg << "Symbol " << use_ident
		      << " not found in package " << pcur->first << "." << ends;
		  VLerror(msg.str().c_str());
		  return;
	    }

	    scope->parameters[cur->first] = cur->second;

      } else {

	      // Handle the pkg::* case by importing everything from
	      // the package.
	    for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
		       ; cur != pkg->parameters.end() ; ++cur) {

		  scope->parameters[cur->first] = cur->second;
	    }
      }
}
<|endoftext|>


<commit_before>#include <io/network/address.h>
#include <io/network/socketBase.h>
#include <logging.h>
#include <cstring>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#elif !defined(EMSCRIPTEN)
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <errno.h>
#endif

namespace sp {
namespace io {
namespace network {

Address::Address()
{
}

Address::Address(const string& hostname)
{
    SocketBase::initSocketLib();
#ifndef EMSCRIPTEN
    struct addrinfo* result;
    if (::getaddrinfo(hostname.c_str(), nullptr, nullptr, &result))
        return;

    for(struct addrinfo* data=result; data != nullptr; data=data->ai_next)
    {
        if (data->ai_family != AF_INET && data->ai_family != AF_INET6)
            continue;

        char buffer[128];
        ::getnameinfo(data->ai_addr, static_cast<socklen_t>(data->ai_addrlen), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);

        addr_info.emplace_back(data->ai_family, buffer, data->ai_addr, data->ai_addrlen);
    }
    ::freeaddrinfo(result);
#endif
}

Address::Address(std::list<AddrInfo>&& addr_info)
: addr_info(std::forward<std::list<AddrInfo>>(addr_info))
{
}

std::vector<string> Address::getHumanReadable() const
{
    std::vector<string> result;
    for(const auto& info : addr_info)
        result.push_back(info.human_readable);
    return result;
}

bool Address::operator==(const Address& other) const
{
    if (addr_info.size() != other.addr_info.size())
        return false;

    for(auto my_info : addr_info)
    {
        bool found = false;
        for(auto other_info : other.addr_info)
        {
            if (my_info.family == other_info.family && my_info.addr == other_info.addr)
            {
                found = true;
                break;
            }
        }
        if (!found)
            return false;
    }
    return true;
}

Address Address::getLocalAddress()
{
    SocketBase::initSocketLib();

    std::list<AddrInfo> addr_info;

#ifdef _WIN32
    char buffer[128];

    PIP_ADAPTER_ADDRESSES addresses;
    ULONG table_size = 0;
    GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, nullptr, &table_size);
    if (table_size > 0)
    {
        addresses = static_cast<PIP_ADAPTER_ADDRESSES>(calloc(table_size, 1));
        if (GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, addresses, &table_size) == NO_ERROR)
        {
            for(PIP_ADAPTER_ADDRESSES address = addresses; address; address = address->Next)
            {
                if (address->OperStatus != IfOperStatusUp)
                    continue;

                for (PIP_ADAPTER_UNICAST_ADDRESS ua = address->FirstUnicastAddress; ua != nullptr; ua = ua->Next)
                {
                    ::getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength, buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                    if (ua->Address.iSockaddrLength == sizeof(sockaddr_in))
                        addr_info.emplace_back(AF_INET, buffer, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
                    if (ua->Address.iSockaddrLength == sizeof(sockaddr_in6))
                        addr_info.emplace_back(AF_INET6, buffer, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
                }
            }
        }
        free(addresses);
    }
#elif (!defined(__ANDROID_API__) || (__ANDROID_API__ >= 24)) && !defined(EMSCRIPTEN)
    char buffer[128];

    struct ifaddrs* addrs;
    if (!::getifaddrs(&addrs))
    {
        for(struct ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next)
        {
            if ((addr->ifa_flags & IFF_LOOPBACK) || !(addr->ifa_flags & IFF_UP))
            {
                continue;
            }
            if (addr->ifa_addr->sa_family == AF_INET)
            {
                ::getnameinfo(addr->ifa_addr, sizeof(struct sockaddr_in), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                addr_info.emplace_back(addr->ifa_addr->sa_family, buffer, addr->ifa_addr, sizeof(struct sockaddr_in));
            }
            if (addr->ifa_addr->sa_family == AF_INET6)
            {
                ::getnameinfo(addr->ifa_addr, sizeof(struct sockaddr_in6), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                addr_info.emplace_back(addr->ifa_addr->sa_family, buffer, addr->ifa_addr, sizeof(struct sockaddr_in6));
            }
        }
        freeifaddrs(addrs);
    }
#else
    LOG(Warning, "No method to get local IP address.");
#endif
    addr_info.sort([](const AddrInfo& a, const AddrInfo& b)
    {
        if (a.family == b.family)
            return memcmp(a.addr.data(), b.addr.data(), std::min(a.addr.size(), b.addr.size())) <= 0;
        return (a.family - b.family) <= 0;
    });

    return Address(std::move(addr_info));
}

Address::AddrInfo::AddrInfo(int family, const string& human_readable, const void* addr, size_t addrlen)
: family(family), human_readable(human_readable), addr(static_cast<const uint8_t *>(addr), static_cast<const uint8_t*>(addr) + addrlen)
{
}

Address::AddrInfo::~AddrInfo()
{
}

}//namespace network
}//namespace io
}//namespace sp
<commit_msg>Prevent the crash from #209<commit_after>#include <io/network/address.h>
#include <io/network/socketBase.h>
#include <logging.h>
#include <cstring>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#elif !defined(EMSCRIPTEN)
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <errno.h>
#endif

namespace sp {
namespace io {
namespace network {

Address::Address()
{
}

Address::Address(const string& hostname)
{
    SocketBase::initSocketLib();
#ifndef EMSCRIPTEN
    struct addrinfo* result;
    if (::getaddrinfo(hostname.c_str(), nullptr, nullptr, &result))
        return;

    for(struct addrinfo* data=result; data != nullptr; data=data->ai_next)
    {
        if (data->ai_family != AF_INET && data->ai_family != AF_INET6)
            continue;

        char buffer[128];
        ::getnameinfo(data->ai_addr, static_cast<socklen_t>(data->ai_addrlen), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);

        addr_info.emplace_back(data->ai_family, buffer, data->ai_addr, data->ai_addrlen);
    }
    ::freeaddrinfo(result);
#endif
}

Address::Address(std::list<AddrInfo>&& addr_info)
: addr_info(std::forward<std::list<AddrInfo>>(addr_info))
{
}

std::vector<string> Address::getHumanReadable() const
{
    std::vector<string> result;
    for(const auto& info : addr_info)
        result.push_back(info.human_readable);
    return result;
}

bool Address::operator==(const Address& other) const
{
    if (addr_info.size() != other.addr_info.size())
        return false;

    for(auto my_info : addr_info)
    {
        bool found = false;
        for(auto other_info : other.addr_info)
        {
            if (my_info.family == other_info.family && my_info.addr == other_info.addr)
            {
                found = true;
                break;
            }
        }
        if (!found)
            return false;
    }
    return true;
}

Address Address::getLocalAddress()
{
    SocketBase::initSocketLib();

    std::list<AddrInfo> addr_info;

#ifdef _WIN32
    char buffer[128];

    PIP_ADAPTER_ADDRESSES addresses;
    ULONG table_size = 0;
    GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, nullptr, &table_size);
    if (table_size > 0)
    {
        addresses = static_cast<PIP_ADAPTER_ADDRESSES>(calloc(table_size, 1));
        if (GetAdaptersAddresses(AF_UNSPEC, 0, nullptr, addresses, &table_size) == NO_ERROR)
        {
            for(PIP_ADAPTER_ADDRESSES address = addresses; address; address = address->Next)
            {
                if (address->OperStatus != IfOperStatusUp)
                    continue;

                for (PIP_ADAPTER_UNICAST_ADDRESS ua = address->FirstUnicastAddress; ua != nullptr; ua = ua->Next)
                {
                    ::getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength, buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                    if (ua->Address.iSockaddrLength == sizeof(sockaddr_in))
                        addr_info.emplace_back(AF_INET, buffer, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
                    if (ua->Address.iSockaddrLength == sizeof(sockaddr_in6))
                        addr_info.emplace_back(AF_INET6, buffer, ua->Address.lpSockaddr, ua->Address.iSockaddrLength);
                }
            }
        }
        free(addresses);
    }
#elif (!defined(__ANDROID_API__) || (__ANDROID_API__ >= 24)) && !defined(EMSCRIPTEN)
    char buffer[128];

    struct ifaddrs* addrs;
    if (!::getifaddrs(&addrs))
    {
        for(struct ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next)
        {
            if ((addr->ifa_flags & IFF_LOOPBACK) || !(addr->ifa_flags & IFF_UP))
            {
                continue;
            }
            if (addr->ifa_addr == nullptr)
            {
                continue;
            }
            if (addr->ifa_addr->sa_family == AF_INET)
            {
                ::getnameinfo(addr->ifa_addr, sizeof(struct sockaddr_in), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                addr_info.emplace_back(addr->ifa_addr->sa_family, buffer, addr->ifa_addr, sizeof(struct sockaddr_in));
            }
            if (addr->ifa_addr->sa_family == AF_INET6)
            {
                ::getnameinfo(addr->ifa_addr, sizeof(struct sockaddr_in6), buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
                addr_info.emplace_back(addr->ifa_addr->sa_family, buffer, addr->ifa_addr, sizeof(struct sockaddr_in6));
            }
        }
        freeifaddrs(addrs);
    }
#else
    LOG(Warning, "No method to get local IP address.");
#endif
    addr_info.sort([](const AddrInfo& a, const AddrInfo& b)
    {
        if (a.family == b.family)
            return memcmp(a.addr.data(), b.addr.data(), std::min(a.addr.size(), b.addr.size())) <= 0;
        return (a.family - b.family) <= 0;
    });

    return Address(std::move(addr_info));
}

Address::AddrInfo::AddrInfo(int family, const string& human_readable, const void* addr, size_t addrlen)
: family(family), human_readable(human_readable), addr(static_cast<const uint8_t *>(addr), static_cast<const uint8_t*>(addr) + addrlen)
{
}

Address::AddrInfo::~AddrInfo()
{
}

}//namespace network
}//namespace io
}//namespace sp
<|endoftext|>