<commit_before>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include "xyzfileformat.h"

#include <iomanip>
#include <iostream>

#include <chemkit/atom.h>
#include <chemkit/element.h>
#include <chemkit/foreach.h>
#include <chemkit/moleculefile.h>

XyzFileFormat::XyzFileFormat()
    : chemkit::MoleculeFileFormat("xyz")
{
}

XyzFileFormat::~XyzFileFormat()
{
}

bool XyzFileFormat::read(std::istream &input, chemkit::MoleculeFile *file)
{
    // atom count line
    int atomCount = 0;
    input >> atomCount;
    input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // comment line (unused)
    std::string commentLine;
    std::getline(input, commentLine);
    CHEMKIT_UNUSED(commentLine);

    // create molecule
    chemkit::Molecule *molecule = new chemkit::Molecule;

    // read atoms and coordinates
    for(int i = 0; i < atomCount; i++){
        std::string symbol;
        double x = 0;
        double y = 0;
        double z = 0;

        input >> symbol >> x >> y >> z;
        if(input.fail()){
            input.clear();
        }

        // add atom from symbol or atomic number
        chemkit::Atom *atom = 0;
        if(symbol.empty()){
            continue;
        }
        else if(std::isdigit(symbol.at(0))){
            int atomicNumber = boost::lexical_cast<int>(symbol);
            atom = molecule->addAtom(atomicNumber);
        }
        else{
            atom = molecule->addAtom(symbol);
        }

        // set atom position
        if(atom){
            atom->setPosition(x, y, z);
        }
    }

    // add molecule to file
    file->addMolecule(molecule);

    return true;
}

bool XyzFileFormat::write(const chemkit::MoleculeFile *file, std::ostream &output)
{
    chemkit::Molecule *molecule = file->molecule();
    if(!molecule){
        setErrorString("No molecule in file.");
        return false;
    }

    // atom count line
    output << molecule->atomCount() << "\n";

    // comment line
    output << "\n";

    // atoms and coordinates
    foreach(chemkit::Atom *atom, molecule->atoms()){
        output << std::showpoint
               << std::setw(3) << atom->symbol()
               << std::setw(15) << std::setprecision(5) << atom->x()
               << std::setw(15) << std::setprecision(5) << atom->y()
               << std::setw(15) << std::setprecision(5) << atom->z()
               << "\n";
    }

    return true;
}
<commit_msg>Replace std::isdigit() with isdigit()<commit_after>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include "xyzfileformat.h"

#include <iomanip>
#include <iostream>

#include <chemkit/atom.h>
#include <chemkit/element.h>
#include <chemkit/foreach.h>
#include <chemkit/moleculefile.h>

XyzFileFormat::XyzFileFormat()
    : chemkit::MoleculeFileFormat("xyz")
{
}

XyzFileFormat::~XyzFileFormat()
{
}

bool XyzFileFormat::read(std::istream &input, chemkit::MoleculeFile *file)
{
    // atom count line
    int atomCount = 0;
    input >> atomCount;
    input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // comment line (unused)
    std::string commentLine;
    std::getline(input, commentLine);
    CHEMKIT_UNUSED(commentLine);

    // create molecule
    chemkit::Molecule *molecule = new chemkit::Molecule;

    // read atoms and coordinates
    for(int i = 0; i < atomCount; i++){
        std::string symbol;
        double x = 0;
        double y = 0;
        double z = 0;

        input >> symbol >> x >> y >> z;
        if(input.fail()){
            input.clear();
        }

        // add atom from symbol or atomic number
        chemkit::Atom *atom = 0;
        if(symbol.empty()){
            continue;
        }
        else if(isdigit(symbol.at(0))){
            int atomicNumber = boost::lexical_cast<int>(symbol);
            atom = molecule->addAtom(atomicNumber);
        }
        else{
            atom = molecule->addAtom(symbol);
        }

        // set atom position
        if(atom){
            atom->setPosition(x, y, z);
        }
    }

    // add molecule to file
    file->addMolecule(molecule);

    return true;
}

bool XyzFileFormat::write(const chemkit::MoleculeFile *file, std::ostream &output)
{
    chemkit::Molecule *molecule = file->molecule();
    if(!molecule){
        setErrorString("No molecule in file.");
        return false;
    }

    // atom count line
    output << molecule->atomCount() << "\n";

    // comment line
    output << "\n";

    // atoms and coordinates
    foreach(chemkit::Atom *atom, molecule->atoms()){
        output << std::showpoint
               << std::setw(3) << atom->symbol()
               << std::setw(15) << std::setprecision(5) << atom->x()
               << std::setw(15) << std::setprecision(5) << atom->y()
               << std::setw(15) << std::setprecision(5) << atom->z()
               << "\n";
    }

    return true;
}
<|endoftext|>


<commit_before>#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <unistd.h>
#include <QtCore>
#include <stdexcept>

#include "hp34970hack.h"

// set DC voltage
// SENS:VOLT:DC ()
// 'SENS:VOLT:DC:RANG'+qs+', (@'+IntToStr(chan)+')';
// SENS:VOLT:DC:NPLC'+qs+', (@'+IntToStr(chan)+')'

/*
procedure THall.ResBtnClick(Sender: TObject);
var s:string;
    kod:integer;
    cur,volp,voln,Ra,Rb,Rs,pomr,t:double;
begin
 ResBtn.Enabled:=false; HallBtn.Enabled:=false;
 OpenChannel('209,210');
 // Convert'+#13+'Current to Number
 s:=EditCurr.Text; val(s,cur,kod);
 // Convert'+#13+'Thickness to Number
 s:=EditT.Text; val(s,t,kod);
 t:=t/10;
 cur:=cur/1000; str(cur:5:3,s);
 { --- Measure R_a --- }
 SetCurrent(s);
 CloseChannel('201,202'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=-ReadValue(101);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=-ReadValue(101);
 ApplyCurrent(False);
 OpenChannel('201');
 Ra:=(volp-voln)/2/cur*t; str(Ra:7:5,s);
 EditRa.Text:=s;
 { --- Measure R_b --- }
 str(cur:6:4,s);
 SetCurrent(s);
 CloseChannel('203,205'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(102);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(102);
 ApplyCurrent(False);
 OpenChannel('202,203,205');
 Rb:=(volp-voln)/2/cur*t; str(Rb:7:5,s);
 EditRb.Text:=s;
 { --- Calculate R_s --- }
 Rs:=SolveRs(Ra,Rb,kod);   //(Ra+Rb)/2; kod:=0;
 if not(kod=0) then ShowMessage('Failed on Calculating Rs');
 str(Rs:7:5,s);
 EditRs.Text:=s;
 { --- Measure Field --- }
 CloseChannel('209,210');
 SetCurrent('0.001'); KPausa(300);
 ApplyCurrent(true);
 KPausa(500);
 pomr:=ReadValue(114)*1000;
 pomr:=-30.588+sqrt(934.773+0.392163*pomr);
 ApplyCurrent(false);
 str(pomr:4:2,s);
 EditB.Text:=s;
 ResBtn.Enabled:=true; HallBtn.Enabled:=true;
end;

procedure THall.HallBtnClick(Sender: TObject);
var s:string;
    kod:integer;
    cur,volp,voln,Ra,Rb,Rs,pomr,t:double;
begin
 ResBtn.Enabled:=false; HallBtn.Enabled:=false;
 OpenChannel('209,210');
 // Convert'+#13+'Current to Number
 s:=EditCurr.Text; val(s,cur,kod);
 // Convert'+#13+'Thickness to Number
 s:=EditT.Text; val(s,t,kod);
 t:=t/10;
 cur:=cur/1000; str(cur:6:4,s);
 { --- Measure R_b --- }
 SetCurrent(s);
 CloseChannel('202,204'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(104);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(104);
 ApplyCurrent(False);
 OpenChannel('202,204');
 Rb:=(volp-voln)/2/cur*t;
 s:=Format('%6.3e',[Rb]);
 Delete(s,Length(s)-2,2);
 EditVb.Text:=s;
 { --- Measure R_a --- }
 str(cur:6:4,s);
 SetCurrent(s);
 CloseChannel('201,203,206'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(103);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(103);
 ApplyCurrent(False);
 OpenChannel('201,203,206');
 Ra:=(volp-voln)/2/cur*t;
 s:=Format('%6.3e',[Ra]);
 Delete(s,Length(s)-2,2);
 EditVa.Text:=s;
 { --- Measure Field --- }
 CloseChannel('209,210');
 SetCurrent('0.001'); KPausa(300);
 ApplyCurrent(true);
 KPausa(500);
 pomr:=ReadValue(114)*1000;
 pomr:=-30.588+sqrt(934.773+0.392163*pomr);
 ApplyCurrent(false);
 str(pomr:4:2,s);
 EditB.Text:=s;
 { --- Calculate V/B/I --- }
 Rs:=Ra/pomr*10000;
 s:=Format('%6.3e',[Rs]);
 Delete(s,Length(s)-2,2);
 EditUB.Text:=s;
 ResBtn.Enabled:=true; HallBtn.Enabled:=true;
end;
*/

HP34970Hack::Sense_t HP34970Hack::SenseVolt = "CONF:VOLT";
HP34970Hack::Sense_t HP34970Hack::SenseRes = "CONF:RES";

HP34970Hack::HP34970Hack() :
    QSerial()
{
    memset(HP34903ClosedChannels, 0, sizeof(HP34903ClosedChannels));
}

HP34970Hack::~HP34970Hack()
{
    close();
}

void HP34970Hack::close()
{
    QSerial::close();
}

QString HP34970Hack::formatCmd(const QString &cmd, const Channels_t &channels)
{
    if (!channels.size()) {
        return cmd;
    }

    QStringList ch;
    foreach(int channel, channels) {
        ch.append(QVariant(channel).toString());
    }

    QString format("%1 (@%2)");

    return format.arg(cmd).arg(ch.join(","));
}

void HP34970Hack::init()
{
    sendCmd("INIT", 2000000);
}

bool HP34970Hack::open(const QString &port)
{
    const long timeout = (10l * 1000000l) / 9600l;

    close();

    if (!QSerial::open(port, QSerial::Baude9600, 300000, timeout))
        return false;

    write("\n");
    sendCmd("*RST;*CLS", 500000);
    sendCmd("SYST:REM");

    return true;
}

QStringList HP34970Hack::read()
{
    QString s;
    QStringList data;

    s = sendQuery("READ?");
    data = s.split(",", QString::SkipEmptyParts);

    for (QStringList::iterator idata(data.begin()); idata != data.end(); ++idata) {
        *idata = idata->trimmed();
    }

    return data;
}

void HP34970Hack::sendCmd(const QString &cmd, long timeout)
{
    QString s;

    s = sendQuery(cmd, timeout);
    if (!s.isEmpty())
        throw new std::runtime_error("P34970hack::cmd response not empty.");
}

void HP34970Hack::sendCmd(const QString &cmd, const Channels_t &channels, long timeout)
{
    QString s;

    s = sendQuery(cmd, channels, timeout);
    if (!s.isEmpty())
        throw new std::runtime_error("P34970hack::cmd response not empty.");
}

QString HP34970Hack::sendQuery(const QString &cmd, long timeout)
{
    QString _cmd(cmd + ";*OPC?\n");
    write(_cmd);

    QString result(readLine(1024, timeout).trimmed());
    if (result == "1")
        return QString();
    if (result.endsWith(";1"))
        return result.left(result.size() - 2);

    throw new std::runtime_error("P34970hack::sendQuery failed read response.");
}

QString HP34970Hack::sendQuery(const QString &cmd, const Channels_t &channels, long timeout)
{
    QString _cmd(formatCmd(cmd, channels));

    return sendQuery(_cmd, timeout);
}

void HP34970Hack::setRoute(Channels_t closeChannels, int offs)
{
    Channels_t openChannels;
    Channels_t _closeChannels_;

    // channel = x + 1 + offs;
    ++offs;
    for (int x(0); x <= 19; ++x) {
        bool c(HP34903ClosedChannels[x]);
        Channel_t channel = x + offs;
        bool cw(closeChannels.count(channel));

        if (c && !cw) {
            openChannels.append(channel);
        } else
        if (!c && cw) {
            _closeChannels_.append(channel);
        }
    }

    if(!openChannels.isEmpty())
        sendCmd("ROUT:OPEN", openChannels);
    if (!closeChannels.isEmpty())
        sendCmd("ROUT:CLOS", _closeChannels_);
}

void HP34970Hack::setScan(Channels_t channels)
{
    QString cmd("ROUT:SCAN");

    cmd = formatCmd(cmd, channels).append(";:INIT");

    sendCmd(cmd);
}

void HP34970Hack::setSense(Sense_t sense, Channels_t channels)
{
    sendCmd(sense, channels);
}
<commit_msg>fix open/close channel chace for agilent<commit_after>#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <unistd.h>
#include <QtCore>
#include <stdexcept>

#include "hp34970hack.h"

// set DC voltage
// SENS:VOLT:DC ()
// 'SENS:VOLT:DC:RANG'+qs+', (@'+IntToStr(chan)+')';
// SENS:VOLT:DC:NPLC'+qs+', (@'+IntToStr(chan)+')'

/*
procedure THall.ResBtnClick(Sender: TObject);
var s:string;
    kod:integer;
    cur,volp,voln,Ra,Rb,Rs,pomr,t:double;
begin
 ResBtn.Enabled:=false; HallBtn.Enabled:=false;
 OpenChannel('209,210');
 // Convert'+#13+'Current to Number
 s:=EditCurr.Text; val(s,cur,kod);
 // Convert'+#13+'Thickness to Number
 s:=EditT.Text; val(s,t,kod);
 t:=t/10;
 cur:=cur/1000; str(cur:5:3,s);
 { --- Measure R_a --- }
 SetCurrent(s);
 CloseChannel('201,202'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=-ReadValue(101);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=-ReadValue(101);
 ApplyCurrent(False);
 OpenChannel('201');
 Ra:=(volp-voln)/2/cur*t; str(Ra:7:5,s);
 EditRa.Text:=s;
 { --- Measure R_b --- }
 str(cur:6:4,s);
 SetCurrent(s);
 CloseChannel('203,205'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(102);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(102);
 ApplyCurrent(False);
 OpenChannel('202,203,205');
 Rb:=(volp-voln)/2/cur*t; str(Rb:7:5,s);
 EditRb.Text:=s;
 { --- Calculate R_s --- }
 Rs:=SolveRs(Ra,Rb,kod);   //(Ra+Rb)/2; kod:=0;
 if not(kod=0) then ShowMessage('Failed on Calculating Rs');
 str(Rs:7:5,s);
 EditRs.Text:=s;
 { --- Measure Field --- }
 CloseChannel('209,210');
 SetCurrent('0.001'); KPausa(300);
 ApplyCurrent(true);
 KPausa(500);
 pomr:=ReadValue(114)*1000;
 pomr:=-30.588+sqrt(934.773+0.392163*pomr);
 ApplyCurrent(false);
 str(pomr:4:2,s);
 EditB.Text:=s;
 ResBtn.Enabled:=true; HallBtn.Enabled:=true;
end;

procedure THall.HallBtnClick(Sender: TObject);
var s:string;
    kod:integer;
    cur,volp,voln,Ra,Rb,Rs,pomr,t:double;
begin
 ResBtn.Enabled:=false; HallBtn.Enabled:=false;
 OpenChannel('209,210');
 // Convert'+#13+'Current to Number
 s:=EditCurr.Text; val(s,cur,kod);
 // Convert'+#13+'Thickness to Number
 s:=EditT.Text; val(s,t,kod);
 t:=t/10;
 cur:=cur/1000; str(cur:6:4,s);
 { --- Measure R_b --- }
 SetCurrent(s);
 CloseChannel('202,204'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(104);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(104);
 ApplyCurrent(False);
 OpenChannel('202,204');
 Rb:=(volp-voln)/2/cur*t;
 s:=Format('%6.3e',[Rb]);
 Delete(s,Length(s)-2,2);
 EditVb.Text:=s;
 { --- Measure R_a --- }
 str(cur:6:4,s);
 SetCurrent(s);
 CloseChannel('201,203,206'); KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 volp:=ReadValue(103);
 ApplyCurrent(False);
 str(-cur:6:4,s);
 SetCurrent(s);  KPausa(300);
 ApplyCurrent(True);
 KPausa(500);
 voln:=ReadValue(103);
 ApplyCurrent(False);
 OpenChannel('201,203,206');
 Ra:=(volp-voln)/2/cur*t;
 s:=Format('%6.3e',[Ra]);
 Delete(s,Length(s)-2,2);
 EditVa.Text:=s;
 { --- Measure Field --- }
 CloseChannel('209,210');
 SetCurrent('0.001'); KPausa(300);
 ApplyCurrent(true);
 KPausa(500);
 pomr:=ReadValue(114)*1000;
 pomr:=-30.588+sqrt(934.773+0.392163*pomr);
 ApplyCurrent(false);
 str(pomr:4:2,s);
 EditB.Text:=s;
 { --- Calculate V/B/I --- }
 Rs:=Ra/pomr*10000;
 s:=Format('%6.3e',[Rs]);
 Delete(s,Length(s)-2,2);
 EditUB.Text:=s;
 ResBtn.Enabled:=true; HallBtn.Enabled:=true;
end;
*/

HP34970Hack::Sense_t HP34970Hack::SenseVolt = "CONF:VOLT";
HP34970Hack::Sense_t HP34970Hack::SenseRes = "CONF:RES";

HP34970Hack::HP34970Hack() :
    QSerial()
{
    memset(HP34903ClosedChannels, 0, sizeof(HP34903ClosedChannels));
}

HP34970Hack::~HP34970Hack()
{
    close();
}

void HP34970Hack::close()
{
    QSerial::close();
}

QString HP34970Hack::formatCmd(const QString &cmd, const Channels_t &channels)
{
    if (!channels.size()) {
        return cmd;
    }

    QStringList ch;
    foreach(int channel, channels) {
        ch.append(QVariant(channel).toString());
    }

    QString format("%1 (@%2)");

    return format.arg(cmd).arg(ch.join(","));
}

void HP34970Hack::init()
{
    sendCmd("INIT", 2000000);
}

bool HP34970Hack::open(const QString &port)
{
    const long timeout = (10l * 1000000l) / 9600l;

    close();

    if (!QSerial::open(port, QSerial::Baude9600, 300000, timeout))
        return false;

    write("\n");
    sendCmd("*RST;*CLS", 500000);
    sendCmd("SYST:REM");

    return true;
}

QStringList HP34970Hack::read()
{
    QString s;
    QStringList data;

    s = sendQuery("READ?");
    data = s.split(",", QString::SkipEmptyParts);

    for (QStringList::iterator idata(data.begin()); idata != data.end(); ++idata) {
        *idata = idata->trimmed();
    }

    return data;
}

void HP34970Hack::sendCmd(const QString &cmd, long timeout)
{
    QString s;

    s = sendQuery(cmd, timeout);
    if (!s.isEmpty())
        throw new std::runtime_error("P34970hack::cmd response not empty.");
}

void HP34970Hack::sendCmd(const QString &cmd, const Channels_t &channels, long timeout)
{
    QString s;

    s = sendQuery(cmd, channels, timeout);
    if (!s.isEmpty())
        throw new std::runtime_error("P34970hack::cmd response not empty.");
}

QString HP34970Hack::sendQuery(const QString &cmd, long timeout)
{
    QString _cmd(cmd + ";*OPC?\n");
    write(_cmd);

    QString result(readLine(1024, timeout).trimmed());
    if (result == "1")
        return QString();
    if (result.endsWith(";1"))
        return result.left(result.size() - 2);

    throw new std::runtime_error("P34970hack::sendQuery failed read response.");
}

QString HP34970Hack::sendQuery(const QString &cmd, const Channels_t &channels, long timeout)
{
    QString _cmd(formatCmd(cmd, channels));

    return sendQuery(_cmd, timeout);
}

void HP34970Hack::setRoute(Channels_t closeChannels, int offs)
{
    Channels_t openChannels;
    Channels_t _closeChannels_;

    // channel = x + 1 + offs;
    ++offs;
    for (int x(0); x <= 19; ++x) {
        bool c(HP34903ClosedChannels[x]);
        Channel_t channel = x + offs;
        bool cw(closeChannels.count(channel));

        if (c && !cw) {
            openChannels.append(channel);
            HP34903ClosedChannels[x] = false;
        } else
        if (!c && cw) {
            _closeChannels_.append(channel);
            HP34903ClosedChannels[x] = true;
        }
    }

    if(!openChannels.isEmpty())
        sendCmd("ROUT:OPEN", openChannels);
    if (!closeChannels.isEmpty())
        sendCmd("ROUT:CLOS", _closeChannels_);
}

void HP34970Hack::setScan(Channels_t channels)
{
    QString cmd("ROUT:SCAN");

    cmd = formatCmd(cmd, channels).append(";:INIT");

    sendCmd(cmd);
}

void HP34970Hack::setSense(Sense_t sense, Channels_t channels)
{
    sendCmd(sense, channels);
}
<|endoftext|>


<commit_before>#include "Halide.h"
#include "wrapper_swap.h"
#include "tiramisu/utils.h"
#include <cstdlib>
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
#define NN 100
int main(int, char **)
{
   // Declare vector 1 and initialize it with 3
    Halide::Buffer<uint8_t> input1_buf(NN);
    init_buffer(input1_buf,(uint8_t)3);
   // Declare vector 2 and initialize it with 4
    Halide::Buffer<uint8_t> input2_buf(NN);
    init_buffer(input2_buf,(uint8_t)4);
   // REF C++ PROGRAM STARTS:
    auto start1 = std::chrono::high_resolution_clock::now();
   // expected1 = what we expect input1 to be after calling swap
    Halide::Buffer<uint8_t> expected1(NN);
    for (int i = 0; i < NN;i++) {
            expected1(i) = input2_buf(i);
    }
   // expected2 = what we expect input2 to be after calling swap
    Halide::Buffer<uint8_t> expected2(NN);
    for (int i = 0; i < NN; i++) {
            expected2(i) = input1_buf(i);
    }
    auto end1 = std::chrono::high_resolution_clock::now();
    auto  duration1 =duration_cast<microseconds>(end1 - start1);
   // REF C++ PROGRAM ENDS.
   // TIRAMISU PROGRAM STARTS:
    auto start2 = std::chrono::high_resolution_clock::now();
    swap(input1_buf.raw_buffer(), input2_buf.raw_buffer());
    auto end2 = std::chrono::high_resolution_clock::now();
    auto  duration2 =duration_cast<microseconds>(end2 - start2);
   // TIRAMISU PROGRAM ENDS.
   // printing REFERECE EXEC TIME:
    std::cout << "\n REF RESOLUTION TIME : " << duration1.count() << "microseconds";
   // printing TIRAMISU EXEC TIME:
    std::cout << "\n TIRAMISU RESOLUTION TIME : " << duration2.count() << "microseconds";
    printf("\n");
    compare_buffers("swap_input1", input1_buf, expected1);
    printf("\n");
    compare_buffers("swap_input2", input2_buf, expected2);
    printf("\n");
    return 0;
}
<commit_msg>Update wrapper_swap.cpp<commit_after>#include "Halide.h"
#include "wrapper_swap.h"
#include "tiramisu/utils.h"
#include <cstdlib>
#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

#define NN 100

int main(int, char **)
{
    // Declare vector 1 and initialize it with 3
    Halide::Buffer<uint8_t> input1_buf(NN);
    init_buffer(input1_buf,(uint8_t)3);

    // Declare vector 2 and initialize it with 4
    Halide::Buffer<uint8_t> input2_buf(NN);
    init_buffer(input2_buf,(uint8_t)4);

    // REF C++ PROGRAM STARTS:
    auto start1 = std::chrono::high_resolution_clock::now();

    // expected1 = what we expect input1 to be after calling swap
    Halide::Buffer<uint8_t> expected1(NN);
    for (int i = 0; i < NN;i++)
    {
            expected1(i) = input2_buf(i);
    }

    // expected2 = what we expect input2 to be after calling swap
    Halide::Buffer<uint8_t> expected2(NN);
    for (int i = 0; i < NN; i++)
    {
            expected2(i) = input1_buf(i);
    }

    auto end1 = std::chrono::high_resolution_clock::now();
    auto  duration1 =duration_cast<microseconds>(end1 - start1);

    // REF C++ PROGRAM ENDS.
    // TIRAMISU PROGRAM STARTS:
    auto start2 = std::chrono::high_resolution_clock::now();
    swap(input1_buf.raw_buffer(), input2_buf.raw_buffer());
    auto end2 = std::chrono::high_resolution_clock::now();
    auto  duration2 =duration_cast<microseconds>(end2 - start2);

    // TIRAMISU PROGRAM ENDS.
    // printing REFERECE EXEC TIME:
    std::cout << "\n REF RESOLUTION TIME : " << duration1.count() << "microseconds";

    // printing TIRAMISU EXEC TIME:
    std::cout << "\n TIRAMISU RESOLUTION TIME : " << duration2.count() << "microseconds";
    printf("\n");
    compare_buffers("swap_input1", input1_buf, expected1);
    printf("\n");
    compare_buffers("swap_input2", input2_buf, expected2);
    printf("\n");
    return 0;
}
<|endoftext|>


<commit_before>#include "config.h"

#include "http_client.h"
#include "exception.h"
#include <cinttypes>
#ifndef HAVE_LIBCURL
#include "buffered_socket.h"
#else
#include <cstring>
#endif

namespace arg3
{
    namespace net
    {

#ifdef HAVE_LIBCURL

        size_t curl_append_response_callback(void *ptr, size_t size, size_t nmemb, string *s)
        {
            if (s == NULL) return 0;

            const size_t new_len = size * nmemb;

            char buf[new_len + 1];

            memcpy(buf, ptr, size * nmemb);

            buf[new_len] = '\0';

            s->append(buf);

            return new_len;
        }
#endif

        http_client::http_client(const string &host) : scheme_(http::SCHEME), host_(host)
        {
            add_header("User-Agent", "libarg3net");
        }

        http_client::http_client()
        {
            add_header("User-Agent", "libarg3net");
        }

        http_client::~http_client()
        {
        }

        http_client::http_client(const http_client &other) : scheme_(other.scheme_), host_(other.host_),
            payload_(other.payload_), responseCode_(other.responseCode_),
            response_(other.response_), headers_(other.headers_)
        {
        }

        http_client::http_client(http_client &&other) : scheme_(std::move(other.scheme_)), host_(std::move(other.host_)),
            payload_(std::move(other.payload_)), responseCode_(other.responseCode_),
            response_(std::move(other.response_)), headers_(std::move(other.headers_))
        {
        }

        http_client &http_client::operator=(const http_client &other)
        {
            scheme_ = other.scheme_;
            host_ = other.host_;
            payload_ = other.payload_;
            responseCode_ = other.responseCode_;
            response_ = other.response_;
            headers_ = other.headers_;
            return *this;
        }

        http_client &http_client::operator=(http_client && other)
        {
            scheme_ = std::move(other.scheme_);
            host_ = std::move(other.host_);
            payload_ = std::move(other.payload_);
            responseCode_ = other.responseCode_;
            response_ = std::move(other.response_);
            headers_ = std::move(other.headers_);
            return *this;
        }

        http_client &http_client::add_header(const string &key, const string &value)
        {
            headers_[key] = value;
            return *this;
        }

        void http_client::remove_header(const string &key)
        {
            headers_.erase(key);
        }

        string http_client::header(const string &key)
        {
            return headers_[key];
        }

        string http_client::host() const
        {
            return host_;
        }

        int http_client::response_code() const
        {
            return responseCode_;
        }

        string http_client::payload() const
        {
            return payload_;
        }

        string http_client::response() const
        {
            return response_;
        }

        bool http_client::is_secure() const
        {
            return scheme_ == http::SECURE_SCHEME;
        }

        http_client &http_client::set_host(const string &host)
        {
            host_ = host;
            return *this;
        }

        http_client &http_client::set_secure(bool value)
        {
            scheme_ = value ? http::SECURE_SCHEME : http::SCHEME;
            return *this;
        }

        http_client &http_client::set_payload(const string &payload)
        {
            payload_ = payload;
            return *this;
        }

        http_client &http_client::request(http::method method, const string &path)
        {
            char buf[http::MAX_URL_LEN + 1];

            response_.clear();

            if (host_.empty())
                throw socket_exception("no host");

#ifdef HAVE_LIBCURL
            struct curl_slist *headers = NULL;

            CURL *curl_ = curl_easy_init();

            if (curl_ == NULL)
            {
                throw rest_exception("unable to initialize request");
            }

            if (path.empty())
                snprintf(buf, http::MAX_URL_LEN, "%s://%s", scheme_.c_str(), host_.c_str());
            else
                snprintf(buf, http::MAX_URL_LEN, "%s://%s/%s", scheme_.c_str(), host_.c_str(), path.c_str());

            curl_easy_setopt(curl_, CURLOPT_URL, buf);

            curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, curl_append_response_callback);

            switch (method)
            {
            case http::GET:
                curl_easy_setopt(curl_, CURLOPT_HTTPGET, 1L);
                break;
            case http::POST:
                curl_easy_setopt(curl_, CURLOPT_POST, 1L);
                if (!payload_.empty())
                {
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, payload_.c_str());
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, payload_.size());
                }
                break;
            case http::PUT:
                curl_easy_setopt(curl_, CURLOPT_PUT, 1L);
                if (!payload_.empty())
                {
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, payload_.c_str());
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, payload_.size());
                }
            case http::DELETE:
                curl_easy_setopt(curl_, CURLOPT_CUSTOMREQUEST, http::method_names[http::DELETE]);
                break;
            }

            for (auto & h : headers_)
            {
                snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());

                headers = curl_slist_append(headers, buf);
            }

            curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, headers);

            curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response_);

            CURLcode res = curl_easy_perform(curl_);

            if (res != CURLE_OK)
            {
                curl_easy_cleanup(curl_);

                throw rest_exception(curl_easy_strerror(res));
            }

            curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &responseCode_);

            curl_easy_cleanup(curl_);
#else
            buffered_socket sock;

            // create the socket based on hostname and port
            auto pos = host().find(':');

            if (is_secure())
                sock.set_secure(true);

            if (pos != string::npos)
            {
                string hostname = host().substr(0, pos);
                int port = stoi(host().substr(pos + 1));
                sock.connect(hostname, port);
            }
            else
            {
                sock.connect(host(), is_secure() ? http::DEFAULT_SECURE_PORT : http::DEFAULT_PORT);
            }

            // send the method and path

            if (path.empty())
                snprintf(buf, http::MAX_URL_LEN, http::REQUEST_HEADER, http::method_names[method], "/");
            else
                snprintf(buf, http::MAX_URL_LEN, http::REQUEST_HEADER, http::method_names[method], path.c_str());

            sock.writeln(buf);

            // specify the host
            snprintf(buf, http::MAX_URL_LEN, "Host: %s", host().c_str());

            sock.writeln(buf);

            // add the headers
            for (auto & h : headers_)
            {
                snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());

                sock.writeln(buf);
            }

            // if we have a payload, add the size
            if (!payload_.empty())
            {
                snprintf(buf, http::MAX_URL_LEN, "Content-Size: %zu", payload_.size());

                sock.writeln(buf);
            }

            // finish header
            sock.writeln();

            // add the payload
            if (!payload_.empty())
            {
                sock.writeln(payload_);
            }

            sock.write_from_buffer();

            sock.read_to_buffer();

            string line = sock.readln();

            if (sscanf(line.c_str(), http::RESPONSE_HEADER, &responseCode_, buf) == 2)
            {
                // parse out the rest of the header
                while (!line.empty())
                {
                    line = sock.readln();
                    response_ += line;
                }
                response_.clear();
            }
            else
            {
                // could be plain text
                response_ = line;
            }

            auto input = sock.input();

            if (!input.empty())
                response_.append(input.begin(), input.end());

            sock.close();
#endif
            return *this;
        }

        http_client &http_client::get(const string &path)
        {
            return request(http::GET, path);
        }

        http_client &http_client::post(const string &path)
        {
            return request(http::POST, path);
        }

        http_client &http_client::put(const string &path)
        {
            return request(http::PUT, path);
        }

        http_client &http_client::de1ete(const string &path)
        {
            return request(http::DELETE, path);
        }
    }
}
<commit_msg>fix issue in curl implementation<commit_after>#include "config.h"

#include "http_client.h"
#include "exception.h"
#include <cinttypes>
#ifndef HAVE_LIBCURL
#include "buffered_socket.h"
#else
#include <cstring>
#endif

namespace arg3
{
    namespace net
    {

#ifdef HAVE_LIBCURL

        size_t curl_append_response_callback(void *ptr, size_t size, size_t nmemb, string *s)
        {
            if (s == NULL) return 0;

            const size_t new_len = size * nmemb;

            char buf[new_len + 1];

            memcpy(buf, ptr, size * nmemb);

            buf[new_len] = '\0';

            s->append(buf);

            return new_len;
        }
#endif

        http_client::http_client(const string &host) : scheme_(http::SCHEME), host_(host)
        {
            add_header("User-Agent", "libarg3net");
        }

        http_client::http_client()
        {
            add_header("User-Agent", "libarg3net");
        }

        http_client::~http_client()
        {
        }

        http_client::http_client(const http_client &other) : scheme_(other.scheme_), host_(other.host_),
            payload_(other.payload_), responseCode_(other.responseCode_),
            response_(other.response_), headers_(other.headers_)
        {
        }

        http_client::http_client(http_client &&other) : scheme_(std::move(other.scheme_)), host_(std::move(other.host_)),
            payload_(std::move(other.payload_)), responseCode_(other.responseCode_),
            response_(std::move(other.response_)), headers_(std::move(other.headers_))
        {
        }

        http_client &http_client::operator=(const http_client &other)
        {
            scheme_ = other.scheme_;
            host_ = other.host_;
            payload_ = other.payload_;
            responseCode_ = other.responseCode_;
            response_ = other.response_;
            headers_ = other.headers_;
            return *this;
        }

        http_client &http_client::operator=(http_client && other)
        {
            scheme_ = std::move(other.scheme_);
            host_ = std::move(other.host_);
            payload_ = std::move(other.payload_);
            responseCode_ = other.responseCode_;
            response_ = std::move(other.response_);
            headers_ = std::move(other.headers_);
            return *this;
        }

        http_client &http_client::add_header(const string &key, const string &value)
        {
            headers_[key] = value;
            return *this;
        }

        void http_client::remove_header(const string &key)
        {
            headers_.erase(key);
        }

        string http_client::header(const string &key)
        {
            return headers_[key];
        }

        string http_client::host() const
        {
            return host_;
        }

        int http_client::response_code() const
        {
            return responseCode_;
        }

        string http_client::payload() const
        {
            return payload_;
        }

        string http_client::response() const
        {
            return response_;
        }

        bool http_client::is_secure() const
        {
            return scheme_ == http::SECURE_SCHEME;
        }

        http_client &http_client::set_host(const string &host)
        {
            host_ = host;
            return *this;
        }

        http_client &http_client::set_secure(bool value)
        {
            scheme_ = value ? http::SECURE_SCHEME : http::SCHEME;
            return *this;
        }

        http_client &http_client::set_payload(const string &payload)
        {
            payload_ = payload;
            return *this;
        }

        http_client &http_client::request(http::method method, const string &path)
        {
            char buf[http::MAX_URL_LEN + 1];

            response_.clear();

            if (host_.empty())
                throw socket_exception("no host");

#ifdef HAVE_LIBCURL
            struct curl_slist *headers = NULL;

            CURL *curl_ = curl_easy_init();

            if (curl_ == NULL)
            {
                throw rest_exception("unable to initialize request");
            }

            if (path.empty())
                snprintf(buf, http::MAX_URL_LEN, "%s://%s", scheme_.c_str(), host_.c_str());
            else if (path[0] == '/')
                snprintf(buf, http::MAX_URL_LEN, "%s://%s%s", scheme_.c_str(), host_.c_str(), path.c_str());
            else
                snprintf(buf, http::MAX_URL_LEN, "%s://%s/%s", scheme_.c_str(), host_.c_str(), path.c_str());

            curl_easy_setopt(curl_, CURLOPT_URL, buf);

            curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, curl_append_response_callback);

            switch (method)
            {
            case http::GET:
                curl_easy_setopt(curl_, CURLOPT_HTTPGET, 1L);
                break;
            case http::POST:
                curl_easy_setopt(curl_, CURLOPT_POST, 1L);
                if (!payload_.empty())
                {
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, payload_.c_str());
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, payload_.size());
                }
                break;
            case http::PUT:
                curl_easy_setopt(curl_, CURLOPT_PUT, 1L);
                if (!payload_.empty())
                {
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, payload_.c_str());
                    curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, payload_.size());
                }
            case http::DELETE:
                curl_easy_setopt(curl_, CURLOPT_CUSTOMREQUEST, http::method_names[http::DELETE]);
                break;
            }

            for (auto &h : headers_)
            {
                snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());

                headers = curl_slist_append(headers, buf);
            }

            curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, headers);

            curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response_);

            CURLcode res = curl_easy_perform(curl_);

            if (res != CURLE_OK)
            {
                curl_easy_cleanup(curl_);

                throw rest_exception(curl_easy_strerror(res));
            }

            curl_easy_getinfo (curl_, CURLINFO_RESPONSE_CODE, &responseCode_);

            curl_easy_cleanup(curl_);
#else
            buffered_socket sock;

            // create the socket based on hostname and port
            auto pos = host().find(':');

            if (is_secure())
                sock.set_secure(true);

            if (pos != string::npos)
            {
                string hostname = host().substr(0, pos);
                int port = stoi(host().substr(pos + 1));
                sock.connect(hostname, port);
            }
            else
            {
                sock.connect(host(), is_secure() ? http::DEFAULT_SECURE_PORT : http::DEFAULT_PORT);
            }

            // send the method and path

            if (path.empty())
                snprintf(buf, http::MAX_URL_LEN, http::REQUEST_HEADER, http::method_names[method], "/");
            else
                snprintf(buf, http::MAX_URL_LEN, http::REQUEST_HEADER, http::method_names[method], path.c_str());

            sock.writeln(buf);

            // specify the host
            snprintf(buf, http::MAX_URL_LEN, "Host: %s", host().c_str());

            sock.writeln(buf);

            // add the headers
            for (auto &h : headers_)
            {
                snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());

                sock.writeln(buf);
            }

            // if we have a payload, add the size
            if (!payload_.empty())
            {
                snprintf(buf, http::MAX_URL_LEN, "Content-Size: %zu", payload_.size());

                sock.writeln(buf);
            }

            // finish header
            sock.writeln();

            // add the payload
            if (!payload_.empty())
            {
                sock.writeln(payload_);
            }

            sock.write_from_buffer();

            sock.read_to_buffer();

            string line = sock.readln();

            if (sscanf(line.c_str(), http::RESPONSE_HEADER, &responseCode_, buf) == 2)
            {
                // parse out the rest of the header
                while (!line.empty())
                {
                    line = sock.readln();
                    response_ += line;
                }
                response_.clear();
            }
            else
            {
                // could be plain text
                response_ = line;
            }

            auto input = sock.input();

            if (!input.empty())
                response_.append(input.begin(), input.end());

            sock.close();
#endif
            return *this;
        }

        http_client &http_client::get(const string &path)
        {
            return request(http::GET, path);
        }

        http_client &http_client::post(const string &path)
        {
            return request(http::POST, path);
        }

        http_client &http_client::put(const string &path)
        {
            return request(http::PUT, path);
        }

        http_client &http_client::de1ete(const string &path)
        {
            return request(http::DELETE, path);
        }
    }
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#include <cctype>
#include <algorithm>
#include <stdlib.h>

#include "libtorrent/config.hpp"
#include "libtorrent/http_parser.hpp"
#include "libtorrent/assert.hpp"

using namespace libtorrent;

namespace
{
	char to_lower(char c) { return std::tolower(c); }
}

namespace libtorrent
{
	http_parser::http_parser()
		: m_recv_pos(0)
		, m_status_code(-1)
		, m_content_length(-1)
		, m_state(read_status)
		, m_recv_buffer(0, 0)
		, m_body_start_pos(0)
		, m_finished(false)
	{}

	boost::tuple<int, int> http_parser::incoming(
		buffer::const_interval recv_buffer, bool& error)
	{
		TORRENT_ASSERT(recv_buffer.left() >= m_recv_buffer.left());
		boost::tuple<int, int> ret(0, 0);
		int start_pos = m_recv_buffer.left();

		// early exit if there's nothing new in the receive buffer
		if (start_pos == recv_buffer.left()) return ret;
		m_recv_buffer = recv_buffer;

		if (m_state == error_state)
		{
			error = true;
			return ret;
		}

		char const* pos = recv_buffer.begin + m_recv_pos;
		if (m_state == read_status)
		{
			TORRENT_ASSERT(!m_finished);
			char const* newline = std::find(pos, recv_buffer.end, '\n');
			// if we don't have a full line yet, wait.
			if (newline == recv_buffer.end)
			{
				boost::get<1>(ret) += m_recv_buffer.left() - start_pos;
				return ret;
			}

			if (newline == pos)
			{
				m_state = error_state;
				error = true;
				return ret;
			}

			char const* line_end = newline;
			if (pos != line_end && *(line_end - 1) == '\r') --line_end;

			std::istringstream line(std::string(pos, line_end));
			++newline;
			int incoming = (int)std::distance(pos, newline);
			m_recv_pos += incoming;
			boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
			pos = newline;

			line >> m_protocol;
			if (m_protocol.substr(0, 5) == "HTTP/")
			{
				line >> m_status_code;
				std::getline(line, m_server_message);
			}
			else
			{
				m_method = m_protocol;
				std::transform(m_method.begin(), m_method.end(), m_method.begin(), &to_lower);
				m_protocol.clear();
				line >> m_path >> m_protocol;
				m_status_code = 0;
			}
			m_state = read_header;
			start_pos = pos - recv_buffer.begin;
		}

		if (m_state == read_header)
		{
			TORRENT_ASSERT(!m_finished);
			char const* newline = std::find(pos, recv_buffer.end, '\n');
			std::string line;

			while (newline != recv_buffer.end && m_state == read_header)
			{
				// if the LF character is preceeded by a CR
				// charachter, don't copy it into the line string.
				char const* line_end = newline;
				if (pos != line_end && *(line_end - 1) == '\r') --line_end;
				line.assign(pos, line_end);
				++newline;
				m_recv_pos += newline - pos;
				pos = newline;

				std::string::size_type separator = line.find(':');
				if (separator == std::string::npos)
				{
					// this means we got a blank line,
					// the header is finished and the body
					// starts.
					m_state = read_body;
					m_body_start_pos = m_recv_pos;
					break;
				}

				std::string name = line.substr(0, separator);
				std::transform(name.begin(), name.end(), name.begin(), &to_lower);
				++separator;
				// skip whitespace
				while (separator < line.size()
					&& (line[separator] == ' ' || line[separator] == '\t'))
					++separator;
				std::string value = line.substr(separator, std::string::npos);
				m_header.insert(std::make_pair(name, value));

				if (name == "content-length")
				{
#ifdef TORRENT_WINDOWS
					m_content_length = _atoi64(value.c_str());
#else
					m_content_length = atoll(value.c_str());
#endif
				}
				else if (name == "content-range")
				{
					std::stringstream range_str(value);
					char dummy;
					std::string bytes;
					size_type range_start, range_end;
					// apparently some web servers do not send the "bytes"
					// in their content-range
					if (value.find(' ') != std::string::npos)
						range_str >> bytes;
					range_str >> range_start >> dummy >> range_end;
					if (!range_str || range_end < range_start)
					{
						m_state = error_state;
						error = true;
						return ret;
					}
					// the http range is inclusive
					m_content_length = range_end - range_start + 1;
				}

				TORRENT_ASSERT(m_recv_pos <= (int)recv_buffer.left());
				newline = std::find(pos, recv_buffer.end, '\n');
			}
			boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
		}

		if (m_state == read_body)
		{
			int incoming = recv_buffer.end - pos;
			if (m_recv_pos - m_body_start_pos + incoming > m_content_length
				&& m_content_length >= 0)
				incoming = m_content_length - m_recv_pos + m_body_start_pos;

			TORRENT_ASSERT(incoming >= 0);
			m_recv_pos += incoming;
			boost::get<0>(ret) += incoming;

			if (m_content_length >= 0
				&& m_recv_pos - m_body_start_pos >= m_content_length)
			{
				m_finished = true;
			}
		}
		return ret;
	}

	buffer::const_interval http_parser::get_body() const
	{
		TORRENT_ASSERT(m_state == read_body);
		if (m_content_length >= 0)
			return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
				, m_recv_buffer.begin + (std::min)(size_type(m_recv_pos)
				, m_body_start_pos + m_content_length));
		else
			return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
				, m_recv_buffer.begin + m_recv_pos);
	}

	void http_parser::reset()
	{
		m_recv_pos = 0;
		m_body_start_pos = 0;
		m_status_code = -1;
		m_content_length = -1;
		m_finished = false;
		m_state = read_status;
		m_recv_buffer.begin = 0;
		m_recv_buffer.end = 0;
		m_header.clear();
	}

}

<commit_msg>fix to http_parser when used to parse requests instead of responses<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#include <cctype>
#include <algorithm>
#include <stdlib.h>

#include "libtorrent/config.hpp"
#include "libtorrent/http_parser.hpp"
#include "libtorrent/assert.hpp"

using namespace libtorrent;

namespace
{
	char to_lower(char c) { return std::tolower(c); }
}

namespace libtorrent
{
	http_parser::http_parser()
		: m_recv_pos(0)
		, m_status_code(-1)
		, m_content_length(-1)
		, m_state(read_status)
		, m_recv_buffer(0, 0)
		, m_body_start_pos(0)
		, m_finished(false)
	{}

	boost::tuple<int, int> http_parser::incoming(
		buffer::const_interval recv_buffer, bool& error)
	{
		TORRENT_ASSERT(recv_buffer.left() >= m_recv_buffer.left());
		boost::tuple<int, int> ret(0, 0);
		int start_pos = m_recv_buffer.left();

		// early exit if there's nothing new in the receive buffer
		if (start_pos == recv_buffer.left()) return ret;
		m_recv_buffer = recv_buffer;

		if (m_state == error_state)
		{
			error = true;
			return ret;
		}

		char const* pos = recv_buffer.begin + m_recv_pos;
		if (m_state == read_status)
		{
			TORRENT_ASSERT(!m_finished);
			char const* newline = std::find(pos, recv_buffer.end, '\n');
			// if we don't have a full line yet, wait.
			if (newline == recv_buffer.end)
			{
				boost::get<1>(ret) += m_recv_buffer.left() - start_pos;
				return ret;
			}

			if (newline == pos)
			{
				m_state = error_state;
				error = true;
				return ret;
			}

			char const* line_end = newline;
			if (pos != line_end && *(line_end - 1) == '\r') --line_end;

			std::istringstream line(std::string(pos, line_end));
			++newline;
			int incoming = (int)std::distance(pos, newline);
			m_recv_pos += incoming;
			boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
			pos = newline;

			line >> m_protocol;
			if (m_protocol.substr(0, 5) == "HTTP/")
			{
				line >> m_status_code;
				std::getline(line, m_server_message);
			}
			else
			{
				m_method = m_protocol;
				std::transform(m_method.begin(), m_method.end(), m_method.begin(), &to_lower);
				m_protocol.clear();
				line >> m_path >> m_protocol;
				m_status_code = 0;
			}
			m_state = read_header;
			start_pos = pos - recv_buffer.begin;
		}

		if (m_state == read_header)
		{
			TORRENT_ASSERT(!m_finished);
			char const* newline = std::find(pos, recv_buffer.end, '\n');
			std::string line;

			while (newline != recv_buffer.end && m_state == read_header)
			{
				// if the LF character is preceeded by a CR
				// charachter, don't copy it into the line string.
				char const* line_end = newline;
				if (pos != line_end && *(line_end - 1) == '\r') --line_end;
				line.assign(pos, line_end);
				++newline;
				m_recv_pos += newline - pos;
				pos = newline;

				std::string::size_type separator = line.find(':');
				if (separator == std::string::npos)
				{
					// this means we got a blank line,
					// the header is finished and the body
					// starts.
					m_state = read_body;
					// if this is a request (not a response)
					// we're done once we reach the end of the headers
					if (!m_method.empty()) m_finished = true;
					m_body_start_pos = m_recv_pos;
					break;
				}

				std::string name = line.substr(0, separator);
				std::transform(name.begin(), name.end(), name.begin(), &to_lower);
				++separator;
				// skip whitespace
				while (separator < line.size()
					&& (line[separator] == ' ' || line[separator] == '\t'))
					++separator;
				std::string value = line.substr(separator, std::string::npos);
				m_header.insert(std::make_pair(name, value));

				if (name == "content-length")
				{
#ifdef TORRENT_WINDOWS
					m_content_length = _atoi64(value.c_str());
#else
					m_content_length = atoll(value.c_str());
#endif
				}
				else if (name == "content-range")
				{
					std::stringstream range_str(value);
					char dummy;
					std::string bytes;
					size_type range_start, range_end;
					// apparently some web servers do not send the "bytes"
					// in their content-range
					if (value.find(' ') != std::string::npos)
						range_str >> bytes;
					range_str >> range_start >> dummy >> range_end;
					if (!range_str || range_end < range_start)
					{
						m_state = error_state;
						error = true;
						return ret;
					}
					// the http range is inclusive
					m_content_length = range_end - range_start + 1;
				}

				TORRENT_ASSERT(m_recv_pos <= (int)recv_buffer.left());
				newline = std::find(pos, recv_buffer.end, '\n');
			}
			boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
		}

		if (m_state == read_body)
		{
			int incoming = recv_buffer.end - pos;
			if (m_recv_pos - m_body_start_pos + incoming > m_content_length
				&& m_content_length >= 0)
				incoming = m_content_length - m_recv_pos + m_body_start_pos;

			TORRENT_ASSERT(incoming >= 0);
			m_recv_pos += incoming;
			boost::get<0>(ret) += incoming;

			if (m_content_length >= 0
				&& m_recv_pos - m_body_start_pos >= m_content_length)
			{
				m_finished = true;
			}
		}
		return ret;
	}

	buffer::const_interval http_parser::get_body() const
	{
		TORRENT_ASSERT(m_state == read_body);
		if (m_content_length >= 0)
			return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
				, m_recv_buffer.begin + (std::min)(size_type(m_recv_pos)
				, m_body_start_pos + m_content_length));
		else
			return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
				, m_recv_buffer.begin + m_recv_pos);
	}

	void http_parser::reset()
	{
		m_recv_pos = 0;
		m_body_start_pos = 0;
		m_status_code = -1;
		m_content_length = -1;
		m_finished = false;
		m_state = read_status;
		m_recv_buffer.begin = 0;
		m_recv_buffer.end = 0;
		m_header.clear();
	}

}

<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_gm.h"
#include "libmesh/quadrature_grid.h"
#include "libmesh/quadrature_jacobi.h"
#include "libmesh/quadrature_monomial.h"
#include "libmesh/quadrature_simpson.h"
#include "libmesh/quadrature_trap.h"
#include "libmesh/quadrature_gauss_lobatto.h"
#include "libmesh/string_to_enum.h"

namespace libMesh
{

//---------------------------------------------------------------
AutoPtr<QBase> QBase::build (const std::string &type,
                             const unsigned int _dim,
                             const Order _order)
{
  return QBase::build (Utility::string_to_enum<QuadratureType> (type),
                       _dim,
                       _order);
}

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
                            const unsigned int _dim,
                            const Order _order)
{
  switch (_qt)
    {

    case QCLOUGH:
      {
#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Clough quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QClough(_dim, _order));
        return ap;
      }

    case QGAUSS:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Gauss quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QGauss(_dim, _order));
        return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
        return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
        return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
        if (_order > THIRD)
          {
            libMesh::out << "WARNING: Simpson rule provides only" << std::endl
                         << " THIRD order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QSimpson(_dim));
        return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
        if (_order > FIRST)
          {
            libMesh::out << "WARNING: Trapezoidal rule provides only" << std::endl
                         << " FIRST order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QTrap(_dim));
        return ap;
      }

    case QGRID:
      {
        AutoPtr<QBase> ap(new QGrid(_dim, _order));
        return ap;
      }

    case QGRUNDMANN_MOLLER:
      {
        AutoPtr<QBase> ap(new QGrundmann_Moller(_dim, _order));
        return ap;
      }

    case QMONOMIAL:
      {
        AutoPtr<QBase> ap(new QMonomial(_dim, _order));
        return ap;
      }

    case QGAUSS_LOBATTO:
      {
        AutoPtr<QBase> ap(new QGaussLobatto(_dim, _order));
        return ap;
      }

    default:
      libmesh_error_msg("ERROR: Bad qt=" << _qt);
    }

  libmesh_error_msg("We'll never get here!");
  AutoPtr<QBase> ap(NULL);
  return ap;
}

} // namespace libMesh
<commit_msg>Add QCONICAL to the list of rules supported by QBase::build()<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

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

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_gm.h"
#include "libmesh/quadrature_grid.h"
#include "libmesh/quadrature_jacobi.h"
#include "libmesh/quadrature_monomial.h"
#include "libmesh/quadrature_simpson.h"
#include "libmesh/quadrature_trap.h"
#include "libmesh/quadrature_gauss_lobatto.h"
#include "libmesh/quadrature_conical.h"
#include "libmesh/string_to_enum.h"

namespace libMesh
{

//---------------------------------------------------------------
AutoPtr<QBase> QBase::build (const std::string &type,
                             const unsigned int _dim,
                             const Order _order)
{
  return QBase::build (Utility::string_to_enum<QuadratureType> (type),
                       _dim,
                       _order);
}

AutoPtr<QBase> QBase::build(const QuadratureType _qt,
                            const unsigned int _dim,
                            const Order _order)
{
  switch (_qt)
    {

    case QCLOUGH:
      {
#ifdef DEBUG
        if (_order > TWENTYTHIRD)
          {
            libMesh::out << "WARNING: Clough quadrature implemented" << std::endl
                         << " up to TWENTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QClough(_dim, _order));
        return ap;
      }

    case QGAUSS:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Gauss quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QGauss(_dim, _order));
        return ap;
      }

    case QJACOBI_1_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(1,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 1, 0));
        return ap;
      }

    case QJACOBI_2_0:
      {

#ifdef DEBUG
        if (_order > FORTYTHIRD)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " up to FORTYTHIRD order." << std::endl;
          }

        if (_dim > 1)
          {
            libMesh::out << "WARNING: Jacobi(2,0) quadrature implemented" << std::endl
                         << " in 1D only." << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QJacobi(_dim, _order, 2, 0));
        return ap;
      }

    case QSIMPSON:
      {

#ifdef DEBUG
        if (_order > THIRD)
          {
            libMesh::out << "WARNING: Simpson rule provides only" << std::endl
                         << " THIRD order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QSimpson(_dim));
        return ap;
      }

    case QTRAP:
      {

#ifdef DEBUG
        if (_order > FIRST)
          {
            libMesh::out << "WARNING: Trapezoidal rule provides only" << std::endl
                         << " FIRST order!" << std::endl;
          }
#endif

        AutoPtr<QBase> ap(new QTrap(_dim));
        return ap;
      }

    case QGRID:
      {
        AutoPtr<QBase> ap(new QGrid(_dim, _order));
        return ap;
      }

    case QGRUNDMANN_MOLLER:
      {
        AutoPtr<QBase> ap(new QGrundmann_Moller(_dim, _order));
        return ap;
      }

    case QMONOMIAL:
      {
        AutoPtr<QBase> ap(new QMonomial(_dim, _order));
        return ap;
      }

    case QGAUSS_LOBATTO:
      {
        AutoPtr<QBase> ap(new QGaussLobatto(_dim, _order));
        return ap;
      }

    case QCONICAL:
      {
        AutoPtr<QBase> ap(new QConical(_dim, _order));
        return ap;
      }

    default:
      libmesh_error_msg("ERROR: Bad qt=" << _qt);
    }

  libmesh_error_msg("We'll never get here!");
  AutoPtr<QBase> ap(NULL);
  return ap;
}

} // namespace libMesh
<|endoftext|>


<commit_before><commit_msg>coverity#1222234 Division or modulo by zero<commit_after><|endoftext|>


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

#include "Ruine.hpp"
#include "AssetService.hpp"
#include "Drawable.hpp"
#include "Group.hpp"
#include "Logger.hpp"
#include "OpenGLDataInstance.hpp"
#include "Pristine.hpp"
#include "Shape.hpp"
#include "TypesToOStream.hpp"
#include "WavefrontLoader.hpp"
#include "types.hpp"

#include <cmath>
#include <iostream>
#include <vector>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/matrix.hpp>

namespace Soleil {

  Ruine::Ruine(AssetService* assetService, SoundService* soundService,
               int viewportWidth, int viewportHeight)
    : assetService(assetService)
    , soundService(soundService)
    , viewportWidth(viewportWidth)
    , viewportHeight(viewportHeight)
  {
    OpenGLDataInstance::Initialize();
  }

  Ruine::~Ruine() {}

  static void renderSceneGraph(const Group& group, Soleil::Frame& frame)
  {
    /* This is not the most efficient way to Render a Scene Graph but it will
     * make the job for two elements. Let's optimize that afterward. */
    for (NodePtr node : group) {
      if (node->getName() == "lightBulb") {
        // auto currentTransformation = node->getTransformation();

        static float angle = 0;

        float     sinAngle = glm::sin(angle);
        glm::mat4 translation =
          glm::translate(glm::mat4(), glm::vec3(0.0f, 2.0f, 0.0f));
        glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(0.1));
        glm::mat4 rotation =
          glm::rotate(glm::mat4(), glm::mix(0.0f, 1.5f, sinAngle),
                      glm::vec3(0.0f, 0.0f, 1.0f));

        node->setTransformation(rotation * translation * scale);

        frame.pointLights[0].position =
          glm::vec3(rotation * glm::vec4(0.0f, 2.0f, 0.0f, 1.0f));

        angle += 0.01;

        // SOLEIL__LOGGER_DEBUG(toString("sin(", angle, ") = ", sinAngle));

        static float oldValue = 0.98f;

        if ((oldValue > 0.0f && oldValue < sinAngle) ||
            (oldValue < 0.0f && oldValue > sinAngle)) {
          SoundService::FireSound("woot.pcm", SoundProperties(100));
	  oldValue = -oldValue;
        }
      }

      auto drawable = std::dynamic_pointer_cast<Drawable>(node);
      if (drawable) {
        drawable->render(frame);
      }

      auto childGroup = std::dynamic_pointer_cast<Group>(node);
      if (childGroup) {
        renderSceneGraph(*childGroup, frame);
      }
    }
  }

  void Ruine::render(Timer time)
  {
#ifndef NDEBUG
    {
      /* --- Peformance log --- */
      static Timer      firstTime = time;
      static unsigned   frames    = 0;
      static const auto oneSec    = std::chrono::milliseconds(1000);

      frames++;
      if (time - firstTime > oneSec) {
        SOLEIL__LOGGER_DEBUG(toString("Time to draw previous frame: ",
                                      (time - firstTime) / frames),
                             " (FPS=", frames, ")");

        firstTime = time;
        frames    = 0;
      }
      /* ---------------------- */
      static Pristine FirstLoop;
      if (FirstLoop) {
        SOLEIL__LOGGER_DEBUG(toString("SIZEOF OpenGLData: ",
                                      sizeof(OpenGLDataInstance::Instance())));
      }
    }
#endif

    // static std::shared_ptr<Drawable> triangle;
    static Group group;
    static Frame frame;

    static Pristine FirstLoop;
    if (FirstLoop) {
      const std::string content = AssetService::LoadAsString("wallcube.obj");
      ShapePtr          shape   = WavefrontLoader::fromContent(content);
      ShapePtr          ball    = WavefrontLoader::fromContent(
        AssetService::LoadAsString("colored-ball.obj"));

      std::shared_ptr<Drawable> platform = std::make_shared<Drawable>(shape);
      std::shared_ptr<Group>    platformGroup = std::make_shared<Group>();
      // std::shared_ptr<Drawable> cube     = std::make_shared<Drawable>(shape);

      platform->setName("Platform");
      // cube->setName("Cube");
      platformGroup->setName("PlatformGroup");

      platform->setTransformation(
        glm::scale(glm::mat4(), glm::vec3(4.0f, 0.1f, 4.0f)));

      // platformGroup->addChild(cube);
      auto lightBulb = std::make_shared<Drawable>(ball);
      lightBulb->setName("lightBulb");
      lightBulb->setTransformation(
        glm::scale(glm::translate(glm::mat4(), glm::vec3(0.0f, 1.5f, 0.0f)),
                   glm::vec3(.30f)));

      auto littleCube = std::make_shared<Drawable>(shape);
      littleCube->setTransformation(
        glm::scale(glm::translate(glm::mat4(), glm::vec3(0.0f, 0.5f, 0.0f)),
                   glm::vec3(0.4)));

      platformGroup->addChild(littleCube);
      platformGroup->addChild(lightBulb);
      group.addChild(platform);
      group.addChild(platformGroup);

      SoundService::PlayMusic("fabulous.wav");

      frame.pointLights.push_back(PointLight());
    }

    glClearColor(0.0f, 0.3f, 0.7f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    static const glm::mat4 projection = glm::perspective(
      glm::radians(50.0f), (float)viewportWidth / (float)viewportHeight, 0.1f,
      50.0f);

    static float cameraRotationAngle = 0.8f;
    glm::vec3    cameraPosition =
      glm::vec3(glm::rotate(glm::mat4(), cameraRotationAngle,
                            glm::vec3(0.0f, 1.0f, 0.0f)) *
                glm::vec4(0.0f, 5.0f, 5.0f, 1.0f));
#if 0
    cameraRotationAngle += 0.0055f;
#endif

    glm::mat4 view =
      glm::lookAt(cameraPosition, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

    frame.time           = time;
    frame.cameraPosition = cameraPosition;
    frame.updateViewProjectionMatrices(view, projection);

    glEnable(GL_DEPTH_TEST);

    /* Way to render the scene-graph. Optimization may follow */
    renderSceneGraph(group, frame);

// Make it rotate on its own axis
#if 0
    static float angle = 0.55f;

    /* The cube is already centered */
    static const glm::mat4 translation;
    static const glm::mat4 inverseTranslation;

    glm::mat4 transformation =
      glm::rotate(inverseTranslation, angle, glm::vec3(0.0f, 1.0f, 0.0f)) *
      translation;

    angle += 0.1f;
    if (angle >= glm::two_pi<float>()) {
      SoundService::FireSound("woot.pcm", SoundProperties(100));
      angle = 0.0f;
    }

    group.setTransformation(transformation);
#endif
  }
} // Soleil
<commit_msg>Just to save scene with light moving away the cube<commit_after>/*
 * Copyright (C) 2017  Florian GOLESTIN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "Ruine.hpp"
#include "AssetService.hpp"
#include "Drawable.hpp"
#include "Group.hpp"
#include "Logger.hpp"
#include "OpenGLDataInstance.hpp"
#include "Pristine.hpp"
#include "Shape.hpp"
#include "TypesToOStream.hpp"
#include "WavefrontLoader.hpp"
#include "types.hpp"

#include <cmath>
#include <iostream>
#include <vector>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/matrix.hpp>

namespace Soleil {

  Ruine::Ruine(AssetService* assetService, SoundService* soundService,
               int viewportWidth, int viewportHeight)
    : assetService(assetService)
    , soundService(soundService)
    , viewportWidth(viewportWidth)
    , viewportHeight(viewportHeight)
  {
    OpenGLDataInstance::Initialize();
  }

  Ruine::~Ruine() {}

  static void renderSceneGraph(const Group& group, Soleil::Frame& frame)
  {
    /* This is not the most efficient way to Render a Scene Graph but it will
     * make the job for two elements. Let's optimize that afterward. */
    for (NodePtr node : group) {
      if (node->getName() == "lightBulb") {
        // auto currentTransformation = node->getTransformation();

        static float angle    = 0;
        const float  sinAngle = glm::sin(angle);

#if 0
        const glm::mat4 translation =
          glm::translate(glm::mat4(), glm::vec3(0.0f, 2.0f, 0.0f));
        const glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(0.1));
        const glm::mat4 rotation =
          glm::rotate(glm::mat4(), glm::mix(0.0f, 1.5f, sinAngle),
                      glm::vec3(0.0f, 0.0f, 1.0f));

        node->setTransformation(rotation * translation * scale);

        frame.pointLights[0].position =
          glm::vec3(rotation * glm::vec4(0.0f, 2.0f, 0.0f, 1.0f));

        // SOLEIL__LOGGER_DEBUG(toString("sin(", angle, ") = ", sinAngle));

        static float oldValue = 0.98f;

        if ((oldValue > 0.0f && oldValue < sinAngle) ||
            (oldValue < 0.0f && oldValue > sinAngle)) {
          SoundService::FireSound("woot.pcm", SoundProperties(100));
	  oldValue = -oldValue;
        }

#else
        const glm::vec3 position    = glm::vec3(glm::mix(1.5f, 2.5f, sinAngle), 0.5f, 0.0f);
        const glm::mat4 translation = glm::translate(glm::mat4(), position);
        const glm::mat4 scale       = glm::scale(glm::mat4(), glm::vec3(0.1f));

        node->setTransformation(translation * scale);
        frame.pointLights[0].position = position;

#endif

        angle += 0.01;
      }

      auto drawable = std::dynamic_pointer_cast<Drawable>(node);
      if (drawable) {
        drawable->render(frame);
      }

      auto childGroup = std::dynamic_pointer_cast<Group>(node);
      if (childGroup) {
        renderSceneGraph(*childGroup, frame);
      }
    }
  }

  void Ruine::render(Timer time)
  {
#ifndef NDEBUG
    {
      /* --- Peformance log --- */
      static Timer      firstTime = time;
      static unsigned   frames    = 0;
      static const auto oneSec    = std::chrono::milliseconds(1000);

      frames++;
      if (time - firstTime > oneSec) {
        SOLEIL__LOGGER_DEBUG(toString("Time to draw previous frame: ",
                                      (time - firstTime) / frames),
                             " (FPS=", frames, ")");

        firstTime = time;
        frames    = 0;
      }
      /* ---------------------- */
      static Pristine FirstLoop;
      if (FirstLoop) {
        SOLEIL__LOGGER_DEBUG(toString("SIZEOF OpenGLData: ",
                                      sizeof(OpenGLDataInstance::Instance())));
      }
    }
#endif

    // static std::shared_ptr<Drawable> triangle;
    static Group group;
    static Frame frame;

    static Pristine FirstLoop;
    if (FirstLoop) {
      const std::string content = AssetService::LoadAsString("wallcube.obj");
      ShapePtr          shape   = WavefrontLoader::fromContent(content);
      ShapePtr          ball    = WavefrontLoader::fromContent(
        AssetService::LoadAsString("colored-ball.obj"));

      std::shared_ptr<Drawable> platform = std::make_shared<Drawable>(shape);
      std::shared_ptr<Group>    platformGroup = std::make_shared<Group>();
      // std::shared_ptr<Drawable> cube     = std::make_shared<Drawable>(shape);

      platform->setName("Platform");
      // cube->setName("Cube");
      platformGroup->setName("PlatformGroup");

      platform->setTransformation(
        glm::scale(glm::mat4(), glm::vec3(4.0f, 0.1f, 4.0f)));

      // platformGroup->addChild(cube);
      auto lightBulb = std::make_shared<Drawable>(ball);
      lightBulb->setName("lightBulb");
      // lightBulb->setTransformation(
      //   glm::scale(glm::translate(glm::mat4(), glm::vec3(0.0f, 1.5f, 0.0f)),
      //              glm::vec3(.30f)));

      auto littleCube = std::make_shared<Drawable>(shape);
      littleCube->setTransformation(
        glm::scale(glm::translate(glm::mat4(), glm::vec3(0.0f, 0.5f, 0.0f)),
                   glm::vec3(0.4)));

      platformGroup->addChild(littleCube);
      platformGroup->addChild(lightBulb);
      // group.addChild(platform);
      group.addChild(platformGroup);

      SoundService::PlayMusic("fabulous.wav");

      frame.pointLights.push_back(PointLight());
    }

    glClearColor(0.0f, 0.3f, 0.7f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    static const glm::mat4 projection = glm::perspective(
      glm::radians(50.0f), (float)viewportWidth / (float)viewportHeight, 0.1f,
      50.0f);

    static float cameraRotationAngle = 0.8f;
    glm::vec3    cameraPosition =
      glm::vec3(glm::rotate(glm::mat4(), cameraRotationAngle,
                            glm::vec3(0.0f, 1.0f, 0.0f)) *
                glm::vec4(0.0f, 5.0f, 5.0f, 1.0f));
#if 0
    cameraRotationAngle += 0.0055f;
#endif

    glm::mat4 view =
      glm::lookAt(cameraPosition, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

    frame.time           = time;
    frame.cameraPosition = cameraPosition;
    frame.updateViewProjectionMatrices(view, projection);

    glEnable(GL_DEPTH_TEST);

    /* Way to render the scene-graph. Optimization may follow */
    renderSceneGraph(group, frame);

// Make it rotate on its own axis
#if 0
    static float angle = 0.55f;

    /* The cube is already centered */
    static const glm::mat4 translation;
    static const glm::mat4 inverseTranslation;

    glm::mat4 transformation =
      glm::rotate(inverseTranslation, angle, glm::vec3(0.0f, 1.0f, 0.0f)) *
      translation;

    angle += 0.1f;
    if (angle >= glm::two_pi<float>()) {
      SoundService::FireSound("woot.pcm", SoundProperties(100));
      angle = 0.0f;
    }

    group.setTransformation(transformation);
#endif
  }
} // Soleil
<|endoftext|>