<commit_before>//
// Created by pavel on 12.04.16.
//

#include <iostream>
#include <stdexcept>

#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IR/PassManager.h>
#include <llvm/Support/raw_ostream.h>

using namespace std;
using namespace llvm;

Module *makeModule();

int main(int argc, char *argv[]) {
    try {

        Module *module = makeModule();

        module->dump();

        verifyModule(*module);

        ModulePassManager mpm;
        // mpm.addPass(createPrintModul);
        mpm.run(*module);

    } catch (const exception &e) {
        cerr << e.what() << endl;
    }
}

Module *makeModule() {
    LLVMContext &context = getGlobalContext();
    Module *module = new Module("MainModule", context);

    Constant *function = module->getOrInsertFunction("mul_add",
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     nullptr);

    Function *mul_add = cast<Function>(function);
    mul_add->setCallingConv(CallingConv::C);

    Function::arg_iterator args = mul_add->arg_begin();

    Value *x = args.getNodePtrUnchecked();
    x->setName("x");
    args++;

    Value *y = args.getNodePtrUnchecked();
    y->setName("y");
    args++;

    Value *z = args.getNodePtrUnchecked();
    z->setName("z");
    args++;

    BasicBlock *block = BasicBlock::Create(context, "block", mul_add);

    IRBuilder<> builder(block);

    Value *tmp = builder.CreateBinOp(BinaryOperator::Mul, x, y, "tmp");
    Value *tmp2 = builder.CreateBinOp(BinaryOperator::Add, tmp, z, "tmp2");

    builder.CreateRet(tmp2);

    return module;
}<commit_msg>поправил ксилофон<commit_after>//
// Created by pavel on 12.04.16.
//

#include <iostream>
#include <stdexcept>

#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IR/PassManager.h>
#include <llvm/Support/raw_ostream.h>

using namespace std;
using namespace llvm;

Module *makeModule();

int main(int argc, char *argv[]) {
    try {

        Module *module = makeModule();

        module->dump();

        verifyModule(*module);

        ModulePassManager mpm;
        // mpm.addPass(createPrintModul);
        mpm.run(*module);

    } catch (const exception &e) {
        cerr << e.what() << endl;
    }
}

Module *makeModule() {
    LLVMContext &context = getGlobalContext();
    Module *module = new Module("MainModule", context);

    Constant *function = module->getOrInsertFunction("mul_add",
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     IntegerType::get(context, 32),
                                                     nullptr);

    Function *mul_add = cast<Function>(function);
    mul_add->setCallingConv(CallingConv::C);

    Function::arg_iterator args = mul_add->arg_begin();

    Value *x = &*args++;
    x->setName("x");

    Value *y = &*args++;
    y->setName("y");

    Value *z = &*args++;
    z->setName("z");

    BasicBlock *block = BasicBlock::Create(context, "block", mul_add);

    IRBuilder<> builder(block);

    Value *tmp = builder.CreateBinOp(BinaryOperator::Mul, x, y, "tmp");
    Value *tmp2 = builder.CreateBinOp(BinaryOperator::Add, tmp, z, "tmp2");

    builder.CreateRet(tmp2);

    return module;
}<|endoftext|>


<commit_before>#include <TVirtualMC.h>
#include <TDatabasePDG.h>
#include <TParticle.h>

#include "AliGenReaderHepMC.h"
#include "AliRun.h"
#include "AliStack.h"
#include "AliGenHepMCEventHeader.h"

#include "HepMC/IO_BaseClass.h"
#include "HepMC/GenEvent.h"
#include "HepMC/IO_GenEvent.h"

ClassImp(AliGenReaderHepMC)

AliGenReaderHepMC::AliGenReaderHepMC():fEventsHandle(0), fGenEvent(0), fParticleArray(0), fParticleIterator(0), fGenEventHeader(0) {;}

AliGenReaderHepMC::AliGenReaderHepMC(const AliGenReaderHepMC &reader)
   :AliGenReader(reader), fEventsHandle(0), fGenEvent(0), fParticleArray(0), fParticleIterator(0), fGenEventHeader(0) {reader.Copy(*this);}

AliGenReaderHepMC& AliGenReaderHepMC::operator=(const  AliGenReaderHepMC& rhs)
{
   // Assignment operator
   rhs.Copy(*this);
   return *this;
}

AliGenReaderHepMC::~AliGenReaderHepMC(){ delete fEventsHandle; delete fGenEvent; delete fParticleArray; delete fParticleIterator;} // not deleting fGenEventHeader as it is returned out

void AliGenReaderHepMC::Copy(TObject&) const
{
   //
   // Copy
   //
   Fatal("Copy","Not implemented!\n");
}

void AliGenReaderHepMC::Init()
{
   // check if file exists, using FILE to avoid (the otherwise faster) POSIX dependencies
   if (FILE *file = fopen(fFileName,"r"))  {
      printf("File %s opened \n", fFileName);
      fclose(file);
   } else {
      printf("Couldn't open input file: %s \n", fFileName);
   }
   // Initialisation
   fEventsHandle = new HepMC::IO_GenEvent(fFileName, std::ios::in);
   fParticleArray = new TClonesArray("TParticle");
   fParticleIterator = new TIter(fParticleArray);
}

Int_t AliGenReaderHepMC::NextEvent()
{
   // Read the next event
   if ((fGenEvent = fEventsHandle->read_next_event())) {
      THepMCParser::ParseGenEvent2TCloneArray(fGenEvent,fParticleArray,false);
      fParticleIterator->Reset();
      THepMCParser::HeavyIonHeader_t heavyIonHeader;
      THepMCParser::PdfHeader_t pdfHeader;
      THepMCParser::ParseGenEvent2HeaderStructs(fGenEvent,heavyIonHeader,pdfHeader,true,true);
      fGenEventHeader = new AliGenHepMCEventHeader(
            heavyIonHeader.Ncoll_hard,
            heavyIonHeader.Npart_proj,
            heavyIonHeader.Npart_targ,
            heavyIonHeader.Ncoll,
            heavyIonHeader.spectator_neutrons,
            heavyIonHeader.spectator_protons,
            heavyIonHeader.N_Nwounded_collisions,
            heavyIonHeader.Nwounded_N_collisions,
            heavyIonHeader.Nwounded_Nwounded_collisions,
            heavyIonHeader.impact_parameter,
            heavyIonHeader.event_plane_angle,
            heavyIonHeader.eccentricity,
            heavyIonHeader.sigma_inel_NN,
            pdfHeader.id1,
            pdfHeader.id2,
            pdfHeader.pdf_id1,
            pdfHeader.pdf_id2,
            pdfHeader.x1,
            pdfHeader.x2,
            pdfHeader.scalePDF,
            pdfHeader.pdf1,
            pdfHeader.pdf2
      );
      printf("Parsed event with %d particles.\n", fGenEvent->particles_size());
      return fGenEvent->particles_size();
   }
   printf("No more events in the file.\n");
   return 0;
}

TParticle* AliGenReaderHepMC::NextParticle()
{
   // Read next particle
   TParticle * particle = (TParticle*)fParticleIterator->Next();
   if (particle && particle->GetStatusCode()==1) {
      particle->SetBit(kTransportBit);
   }
   return particle;
}

void AliGenReaderHepMC::RewindEvent()
{
   fParticleIterator->Reset();
}
<commit_msg>Fixed minor memory leak.<commit_after>#include <TVirtualMC.h>
#include <TDatabasePDG.h>
#include <TParticle.h>

#include "AliGenReaderHepMC.h"
#include "AliRun.h"
#include "AliStack.h"
#include "AliGenHepMCEventHeader.h"

#include "HepMC/IO_BaseClass.h"
#include "HepMC/GenEvent.h"
#include "HepMC/IO_GenEvent.h"

ClassImp(AliGenReaderHepMC)

AliGenReaderHepMC::AliGenReaderHepMC():fEventsHandle(0), fGenEvent(0), fParticleArray(0), fParticleIterator(0), fGenEventHeader(0) {;}

AliGenReaderHepMC::AliGenReaderHepMC(const AliGenReaderHepMC &reader)
   :AliGenReader(reader), fEventsHandle(0), fGenEvent(0), fParticleArray(0), fParticleIterator(0), fGenEventHeader(0) {reader.Copy(*this);}

AliGenReaderHepMC& AliGenReaderHepMC::operator=(const  AliGenReaderHepMC& rhs)
{
   // Assignment operator
   rhs.Copy(*this);
   return *this;
}

AliGenReaderHepMC::~AliGenReaderHepMC(){ delete fEventsHandle; delete fGenEvent; delete fParticleArray; delete fParticleIterator;} // not deleting fGenEventHeader as it is returned out

void AliGenReaderHepMC::Copy(TObject&) const
{
   //
   // Copy
   //
   Fatal("Copy","Not implemented!\n");
}

void AliGenReaderHepMC::Init()
{
   // check if file exists, using FILE to avoid (the otherwise faster) POSIX dependencies
   if (FILE *file = fopen(fFileName,"r"))  {
      printf("File %s opened \n", fFileName);
      fclose(file);
   } else {
      printf("Couldn't open input file: %s \n", fFileName);
   }
   // Initialisation
   fEventsHandle = new HepMC::IO_GenEvent(fFileName, std::ios::in);
   fParticleArray = new TClonesArray("TParticle");
   fParticleIterator = new TIter(fParticleArray);
}

Int_t AliGenReaderHepMC::NextEvent()
{
   // Clean memory
   if (fGenEvent) delete fGenEvent;
   // Read the next event
   if ((fGenEvent = fEventsHandle->read_next_event())) {
      THepMCParser::ParseGenEvent2TCloneArray(fGenEvent,fParticleArray,false);
      fParticleIterator->Reset();
      THepMCParser::HeavyIonHeader_t heavyIonHeader;
      THepMCParser::PdfHeader_t pdfHeader;
      THepMCParser::ParseGenEvent2HeaderStructs(fGenEvent,heavyIonHeader,pdfHeader,true,true);
      fGenEventHeader = new AliGenHepMCEventHeader(
            heavyIonHeader.Ncoll_hard,
            heavyIonHeader.Npart_proj,
            heavyIonHeader.Npart_targ,
            heavyIonHeader.Ncoll,
            heavyIonHeader.spectator_neutrons,
            heavyIonHeader.spectator_protons,
            heavyIonHeader.N_Nwounded_collisions,
            heavyIonHeader.Nwounded_N_collisions,
            heavyIonHeader.Nwounded_Nwounded_collisions,
            heavyIonHeader.impact_parameter,
            heavyIonHeader.event_plane_angle,
            heavyIonHeader.eccentricity,
            heavyIonHeader.sigma_inel_NN,
            pdfHeader.id1,
            pdfHeader.id2,
            pdfHeader.pdf_id1,
            pdfHeader.pdf_id2,
            pdfHeader.x1,
            pdfHeader.x2,
            pdfHeader.scalePDF,
            pdfHeader.pdf1,
            pdfHeader.pdf2
      );
      printf("Parsed event with %d particles.\n", fGenEvent->particles_size());
      return fGenEvent->particles_size();
   }
   printf("No more events in the file.\n");
   return 0;
}

TParticle* AliGenReaderHepMC::NextParticle()
{
   // Read next particle
   TParticle * particle = (TParticle*)fParticleIterator->Next();
   if (particle && particle->GetStatusCode()==1) {
      particle->SetBit(kTransportBit);
   }
   return particle;
}

void AliGenReaderHepMC::RewindEvent()
{
   fParticleIterator->Reset();
}
<|endoftext|>


<commit_before>/**
 * I2CFlexel.cpp - I2C Flexel base class implementation
 *
 * Note: I2C-FLEXEL name is (c) http://www.web4robot.com
 *
 * Author:     Korney Czukowski (https://github.com/czukowski)
 * Copyright:  (c) 2012 Korney Czukowski
 * License:    MIT License
 */

#include "I2CFlexel.h"
#include "I2CIncludes.h"

namespace I2CFlexel
{
	void I2CFlexel::setWire(IWire& wire)
	{
		connector = &wire;
	}

	void I2CFlexel::beginCommand(byte command)
	{
		connector->beginTransmission(I2C_FLEXEL_ADDRESS);
		connector->write(I2C_FLEXEL_PREFIX);
		connector->write(command);
	}

	void I2CFlexel::sendCommandParameter(byte parameter)
	{
		connector->write(parameter);
	}

	void I2CFlexel::sendCommandParameters(byte* parameters, uint8_t count)
	{
		for (uint8_t i = 0; i < count; i++)
		{
			connector->write(parameters[i]);
		}
	}

	void I2CFlexel::endCommand()
	{
		connector->endTransmission();
	}

	void I2CFlexel::requestByte()
	{
		requestBytes(1);
	}

	void I2CFlexel::requestBytes(uint8_t count)
	{
		connector->requestFrom( (uint8_t) I2C_FLEXEL_ADDRESS, count);
	}

	byte I2CFlexel::readByte()
	{
		return (byte) connector->read();
	}

	void I2CFlexel::readBytes(byte* arr, uint8_t size)
	{
		byte *p = arr;
		for (int i = 0; i < size; i++)
		{
			*p++ = readByte();
		}
		*p = 0;
	}

	// Clock functions

	void I2CFlexel::getTime(byte* time)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_TIME);
		endCommand();
		requestBytes(3);
		readBytes(time, 3);
	}
	DateTime I2CFlexel::getTime()
	{
		byte time[3];
		getTime(time);
		return DateTime(bcdToDec(time[0]), bcdToDec(time[1]), bcdToDec(time[2]));
	}

	void I2CFlexel::getDate(byte *date)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_DATE);
		endCommand();
		requestBytes(4);
		readBytes(date, 4);
	}
	DateTime I2CFlexel::getDate()
	{
		byte date[4];
		getDate(date);
		return DateTime(bcdToDec(date[0]), bcdToDec(date[1]), bcdToDec(date[2]), bcdToDec(date[3]));
	}

	void I2CFlexel::getTimeAndDate(byte* timeAndDate)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_TIME_AND_DATE);
		endCommand();
		requestBytes(7);
		readBytes(timeAndDate, 7);
	}
	DateTime I2CFlexel::getTimeAndDate()
	{
		byte timeAndDate[7];
		getTimeAndDate(timeAndDate);
		return DateTime(
			bcdToDec(timeAndDate[0]), bcdToDec(timeAndDate[1]), bcdToDec(timeAndDate[2]), bcdToDec(timeAndDate[3]),
			bcdToDec(timeAndDate[4]), bcdToDec(timeAndDate[5]), bcdToDec(timeAndDate[6])
		);
	}

	void I2CFlexel::setTime(byte sec, byte min, byte hour)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_TIME);
		sendCommandParameter(sec);
		sendCommandParameter(min);
		sendCommandParameter(hour);
		endCommand();
	}
	void I2CFlexel::setTime(const DateTime &time)
	{
		setTime(decToBcd(time.seconds), decToBcd(time.minutes), decToBcd(time.hours));
	}

	void I2CFlexel::setDate(byte wday, byte day, byte month, byte year)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_DATE);
		sendCommandParameter(wday);
		sendCommandParameter(day);
		sendCommandParameter(month);
		sendCommandParameter(year);
		endCommand();
	}
	void I2CFlexel::setDate(const DateTime &date)
	{
		setDate(decToBcd(date.weekDay), decToBcd(date.day), decToBcd(date.month), decToBcd(date.year));
	}

	void I2CFlexel::setTimeAndDate(byte sec, byte min, byte hour, byte wday, byte day, byte month, byte year)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_TIME_AND_DATE);
		sendCommandParameter(sec);
		sendCommandParameter(min);
		sendCommandParameter(hour);
		sendCommandParameter(wday);
		sendCommandParameter(day);
		sendCommandParameter(month);
		sendCommandParameter(year);
		endCommand();
	}
	void I2CFlexel::setTimeAndDate(const DateTime &timeAndDate)
	{
		setTimeAndDate(
			decToBcd(timeAndDate.seconds), decToBcd(timeAndDate.minutes), decToBcd(timeAndDate.hours), decToBcd(timeAndDate.weekDay),
			decToBcd(timeAndDate.day), decToBcd(timeAndDate.month), decToBcd(timeAndDate.year)
		);
	}

	// Misc command functions

	byte I2CFlexel::getFirmwareVersion()
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_FIRMWARE_VERSION);
		endCommand();
		requestByte();
		return readByte();
	}

	void I2CFlexel::setHighPowerPin(const HighPowerPin &pin)
	{
		setHighPowerPin( (byte) pin);
	}
	void I2CFlexel::setHighPowerPin(byte pin)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_HIGH_POWER_PIN);
		sendCommandParameter(pin);
		endCommand();
	}

	void I2CFlexel::clearHighPowerPin(const HighPowerPin &pin)
	{
		clearHighPowerPin( (byte) pin);
	}
	void I2CFlexel::clearHighPowerPin(byte pin)
	{
		beginCommand(I2C_FLEXEL_COMMAND_CLEAR_HIGH_POWER_PIN);
		sendCommandParameter(pin);
		endCommand();
	}

	void I2CFlexel::setPwmForHighPowerPin(const HighPowerPin &pin, byte pwmValue)
	{
		setPwmForHighPowerPin( (byte) pin, pwmValue);
	}
	void I2CFlexel::setPwmForHighPowerPin(byte pin, byte pwmValue)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_PWM_FOR_HIGH_POWER_PIN);
		sendCommandParameter(pwmValue);
		endCommand();
	}

	void I2CFlexel::setServoMotorPosition(const ServoPin &pin, byte msb, byte lsb)
	{
		// TODO: improve this
		setServoMotorPosition( (byte) pin, msb, lsb);
	}
	void I2CFlexel::setServoMotorPosition(byte pin, byte msb, byte lsb)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_SERVO_MOTOR_POSITION);
		sendCommandParameter(pin);
		sendCommandParameter(msb);
		sendCommandParameter(lsb);
		endCommand();
	}

	void I2CFlexel::setPwmForDcMotor(const DcMotor &motor, const MotorDirection &direction, byte pwmValue)
	{
		setPwmForDcMotor(( (byte) (motor << 2) + (byte) direction), pwmValue);
	}
	void I2CFlexel::setPwmForDcMotor(byte motorAndPosition, byte pwmValue)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_PWM_FOR_DC_MOTOR);
		sendCommandParameter(motorAndPosition);
		sendCommandParameter(pwmValue);
		endCommand();
	}

	uint16_t I2CFlexel::getAnalogInputValue(const AnalogInputPin &pin)
	{
		byte analog[2];
		getAnalogInputValue( (byte) pin, analog);
		return (uint16_t) ((analog[0] << 8) + analog[1]);
	}
	void I2CFlexel::getAnalogInputValue(byte pin, byte* analog)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_ANALOG_INPUT_VALUE);
		sendCommandParameter(pin);
		endCommand();
		requestBytes(2);
		readBytes(analog, 2);
	}

	void I2CFlexel::setBuzzerTime(uint16_t ms)
	{
		setBuzzerTime( (byte) floor(ms / buzzerMsPerCount));
	}
	void I2CFlexel::setBuzzerTime(byte count)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_BUZZER_TIME);
		sendCommandParameter(count);
		endCommand();
	}

	// Input functions

	void I2CFlexel::setKeypadMode(const KeypadMode &mode)
	{
		setKeypadMode(mode);
		keypadMode = mode;
	}
	void I2CFlexel::setKeypadMode(byte mode)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_KEYPAD_MODE);
		sendCommandParameter(mode);
		endCommand();
	}

	byte I2CFlexel::readKeypad()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_KEYPAD);
	}

	byte I2CFlexel::readButtons()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_BUTTONS);
	}

	byte I2CFlexel::readPS2Keypad()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_PS2_KEYPAD);
	}

	byte I2CFlexel::readKey(byte command)
	{
		beginCommand(command);
		endCommand();
		requestByte();
		return readByte();
	}
	byte I2CFlexel::readKey()
	{
		return readKey(readKeypadCommandBase + keypadMode);
	}

	// LCD functions

	void I2CFlexel::setLcdBacklightBrightness(byte brightness)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_BACKLIGHT_BRIGHTNESS);
		sendCommandParameter(brightness);
		endCommand();
	}

	void I2CFlexel::setLcdContrast(byte contrast)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_CONTRAST);
		sendCommandParameter(contrast);
		endCommand();
	}

	void I2CFlexel::turnOnDisplay()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_DISPLAY);
		endCommand();
	}

	void I2CFlexel::turnOffDisplay()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_DISPLAY);
		endCommand();
	}

	void I2CFlexel::setLcdCursorPosition(byte row, byte column)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_CURSOR_POSITION);
		sendCommandParameter(min(I2C_FLEXEL_LCD_MAX_ROWS_COUNT - 1, row));
		sendCommandParameter(min(I2C_FLEXEL_LCD_MAX_COLS_COUNT - 1, column));
		endCommand();
	}

	void I2CFlexel::homeCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_HOME_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOnUnderlineCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_UNDERLINE_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOffUnderlineCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_UNDERLINE_CURSOR);
		endCommand();
	}

	void I2CFlexel::moveCursorLeftOneSpace()
	{
		beginCommand(I2C_FLEXEL_COMMAND_MOVE_CURSOR_LEFT_ONE_SPACE);
		endCommand();
	}

	void I2CFlexel::moveCursorRightOneSpace()
	{
		beginCommand(I2C_FLEXEL_COMMAND_MOVE_CURSOR_RIGHT_ONE_SPACE);
		endCommand();
	}

	void I2CFlexel::turnOnBlinkingCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_BLINKING_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOffBlinkingCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_BLINKING_CURSOR);
		endCommand();
	}

	void I2CFlexel::clearLcdScreen()
	{
		beginCommand(I2C_FLEXEL_COMMAND_CLEAR_LCD_SCREEN);
		endCommand();
	}

	void I2CFlexel::printStringOnLcd(byte* str, uint8_t length)
	{
		beginCommand(I2C_FLEXEL_COMMAND_PRINT_STRING_ON_LCD);
		sendCommandParameter(length);
		sendCommandParameters(str, length);
		endCommand();
	}

	void I2CFlexel::loadLcdCustomCharacters(byte addr, byte* bitmap)
	{
		beginCommand(I2C_FLEXEL_COMMAND_LOAD_LCD_CUSTOM_CHARACTERS);
		sendCommandParameter(addr);
		sendCommandParameters(bitmap, I2C_FLEXEL_LCD_CHAR_ROWS_COUNT);
		endCommand();
	}
}<commit_msg>Added missing parameter send<commit_after>/**
 * I2CFlexel.cpp - I2C Flexel base class implementation
 *
 * Note: I2C-FLEXEL name is (c) http://www.web4robot.com
 *
 * Author:     Korney Czukowski (https://github.com/czukowski)
 * Copyright:  (c) 2012 Korney Czukowski
 * License:    MIT License
 */

#include "I2CFlexel.h"
#include "I2CIncludes.h"

namespace I2CFlexel
{
	void I2CFlexel::setWire(IWire& wire)
	{
		connector = &wire;
	}

	void I2CFlexel::beginCommand(byte command)
	{
		connector->beginTransmission(I2C_FLEXEL_ADDRESS);
		connector->write(I2C_FLEXEL_PREFIX);
		connector->write(command);
	}

	void I2CFlexel::sendCommandParameter(byte parameter)
	{
		connector->write(parameter);
	}

	void I2CFlexel::sendCommandParameters(byte* parameters, uint8_t count)
	{
		for (uint8_t i = 0; i < count; i++)
		{
			connector->write(parameters[i]);
		}
	}

	void I2CFlexel::endCommand()
	{
		connector->endTransmission();
	}

	void I2CFlexel::requestByte()
	{
		requestBytes(1);
	}

	void I2CFlexel::requestBytes(uint8_t count)
	{
		connector->requestFrom( (uint8_t) I2C_FLEXEL_ADDRESS, count);
	}

	byte I2CFlexel::readByte()
	{
		return (byte) connector->read();
	}

	void I2CFlexel::readBytes(byte* arr, uint8_t size)
	{
		byte *p = arr;
		for (int i = 0; i < size; i++)
		{
			*p++ = readByte();
		}
		*p = 0;
	}

	// Clock functions

	void I2CFlexel::getTime(byte* time)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_TIME);
		endCommand();
		requestBytes(3);
		readBytes(time, 3);
	}
	DateTime I2CFlexel::getTime()
	{
		byte time[3];
		getTime(time);
		return DateTime(bcdToDec(time[0]), bcdToDec(time[1]), bcdToDec(time[2]));
	}

	void I2CFlexel::getDate(byte *date)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_DATE);
		endCommand();
		requestBytes(4);
		readBytes(date, 4);
	}
	DateTime I2CFlexel::getDate()
	{
		byte date[4];
		getDate(date);
		return DateTime(bcdToDec(date[0]), bcdToDec(date[1]), bcdToDec(date[2]), bcdToDec(date[3]));
	}

	void I2CFlexel::getTimeAndDate(byte* timeAndDate)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_TIME_AND_DATE);
		endCommand();
		requestBytes(7);
		readBytes(timeAndDate, 7);
	}
	DateTime I2CFlexel::getTimeAndDate()
	{
		byte timeAndDate[7];
		getTimeAndDate(timeAndDate);
		return DateTime(
			bcdToDec(timeAndDate[0]), bcdToDec(timeAndDate[1]), bcdToDec(timeAndDate[2]), bcdToDec(timeAndDate[3]),
			bcdToDec(timeAndDate[4]), bcdToDec(timeAndDate[5]), bcdToDec(timeAndDate[6])
		);
	}

	void I2CFlexel::setTime(byte sec, byte min, byte hour)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_TIME);
		sendCommandParameter(sec);
		sendCommandParameter(min);
		sendCommandParameter(hour);
		endCommand();
	}
	void I2CFlexel::setTime(const DateTime &time)
	{
		setTime(decToBcd(time.seconds), decToBcd(time.minutes), decToBcd(time.hours));
	}

	void I2CFlexel::setDate(byte wday, byte day, byte month, byte year)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_DATE);
		sendCommandParameter(wday);
		sendCommandParameter(day);
		sendCommandParameter(month);
		sendCommandParameter(year);
		endCommand();
	}
	void I2CFlexel::setDate(const DateTime &date)
	{
		setDate(decToBcd(date.weekDay), decToBcd(date.day), decToBcd(date.month), decToBcd(date.year));
	}

	void I2CFlexel::setTimeAndDate(byte sec, byte min, byte hour, byte wday, byte day, byte month, byte year)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_TIME_AND_DATE);
		sendCommandParameter(sec);
		sendCommandParameter(min);
		sendCommandParameter(hour);
		sendCommandParameter(wday);
		sendCommandParameter(day);
		sendCommandParameter(month);
		sendCommandParameter(year);
		endCommand();
	}
	void I2CFlexel::setTimeAndDate(const DateTime &timeAndDate)
	{
		setTimeAndDate(
			decToBcd(timeAndDate.seconds), decToBcd(timeAndDate.minutes), decToBcd(timeAndDate.hours), decToBcd(timeAndDate.weekDay),
			decToBcd(timeAndDate.day), decToBcd(timeAndDate.month), decToBcd(timeAndDate.year)
		);
	}

	// Misc command functions

	byte I2CFlexel::getFirmwareVersion()
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_FIRMWARE_VERSION);
		endCommand();
		requestByte();
		return readByte();
	}

	void I2CFlexel::setHighPowerPin(const HighPowerPin &pin)
	{
		setHighPowerPin( (byte) pin);
	}
	void I2CFlexel::setHighPowerPin(byte pin)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_HIGH_POWER_PIN);
		sendCommandParameter(pin);
		endCommand();
	}

	void I2CFlexel::clearHighPowerPin(const HighPowerPin &pin)
	{
		clearHighPowerPin( (byte) pin);
	}
	void I2CFlexel::clearHighPowerPin(byte pin)
	{
		beginCommand(I2C_FLEXEL_COMMAND_CLEAR_HIGH_POWER_PIN);
		sendCommandParameter(pin);
		endCommand();
	}

	void I2CFlexel::setPwmForHighPowerPin(const HighPowerPin &pin, byte pwmValue)
	{
		setPwmForHighPowerPin( (byte) pin, pwmValue);
	}
	void I2CFlexel::setPwmForHighPowerPin(byte pin, byte pwmValue)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_PWM_FOR_HIGH_POWER_PIN);
		sendCommandParameter(pin);
		sendCommandParameter(pwmValue);
		endCommand();
	}

	void I2CFlexel::setServoMotorPosition(const ServoPin &pin, byte msb, byte lsb)
	{
		// TODO: improve this
		setServoMotorPosition( (byte) pin, msb, lsb);
	}
	void I2CFlexel::setServoMotorPosition(byte pin, byte msb, byte lsb)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_SERVO_MOTOR_POSITION);
		sendCommandParameter(pin);
		sendCommandParameter(msb);
		sendCommandParameter(lsb);
		endCommand();
	}

	void I2CFlexel::setPwmForDcMotor(const DcMotor &motor, const MotorDirection &direction, byte pwmValue)
	{
		setPwmForDcMotor(( (byte) (motor << 2) + (byte) direction), pwmValue);
	}
	void I2CFlexel::setPwmForDcMotor(byte motorAndPosition, byte pwmValue)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_PWM_FOR_DC_MOTOR);
		sendCommandParameter(motorAndPosition);
		sendCommandParameter(pwmValue);
		endCommand();
	}

	uint16_t I2CFlexel::getAnalogInputValue(const AnalogInputPin &pin)
	{
		byte analog[2];
		getAnalogInputValue( (byte) pin, analog);
		return (uint16_t) ((analog[0] << 8) + analog[1]);
	}
	void I2CFlexel::getAnalogInputValue(byte pin, byte* analog)
	{
		beginCommand(I2C_FLEXEL_COMMAND_GET_ANALOG_INPUT_VALUE);
		sendCommandParameter(pin);
		endCommand();
		requestBytes(2);
		readBytes(analog, 2);
	}

	void I2CFlexel::setBuzzerTime(uint16_t ms)
	{
		setBuzzerTime( (byte) floor(ms / buzzerMsPerCount));
	}
	void I2CFlexel::setBuzzerTime(byte count)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_BUZZER_TIME);
		sendCommandParameter(count);
		endCommand();
	}

	// Input functions

	void I2CFlexel::setKeypadMode(const KeypadMode &mode)
	{
		setKeypadMode(mode);
		keypadMode = mode;
	}
	void I2CFlexel::setKeypadMode(byte mode)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_KEYPAD_MODE);
		sendCommandParameter(mode);
		endCommand();
	}

	byte I2CFlexel::readKeypad()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_KEYPAD);
	}

	byte I2CFlexel::readButtons()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_BUTTONS);
	}

	byte I2CFlexel::readPS2Keypad()
	{
		return readKey(I2C_FLEXEL_COMMAND_READ_PS2_KEYPAD);
	}

	byte I2CFlexel::readKey(byte command)
	{
		beginCommand(command);
		endCommand();
		requestByte();
		return readByte();
	}
	byte I2CFlexel::readKey()
	{
		return readKey(readKeypadCommandBase + keypadMode);
	}

	// LCD functions

	void I2CFlexel::setLcdBacklightBrightness(byte brightness)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_BACKLIGHT_BRIGHTNESS);
		sendCommandParameter(brightness);
		endCommand();
	}

	void I2CFlexel::setLcdContrast(byte contrast)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_CONTRAST);
		sendCommandParameter(contrast);
		endCommand();
	}

	void I2CFlexel::turnOnDisplay()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_DISPLAY);
		endCommand();
	}

	void I2CFlexel::turnOffDisplay()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_DISPLAY);
		endCommand();
	}

	void I2CFlexel::setLcdCursorPosition(byte row, byte column)
	{
		beginCommand(I2C_FLEXEL_COMMAND_SET_LCD_CURSOR_POSITION);
		sendCommandParameter(min(I2C_FLEXEL_LCD_MAX_ROWS_COUNT - 1, row));
		sendCommandParameter(min(I2C_FLEXEL_LCD_MAX_COLS_COUNT - 1, column));
		endCommand();
	}

	void I2CFlexel::homeCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_HOME_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOnUnderlineCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_UNDERLINE_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOffUnderlineCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_UNDERLINE_CURSOR);
		endCommand();
	}

	void I2CFlexel::moveCursorLeftOneSpace()
	{
		beginCommand(I2C_FLEXEL_COMMAND_MOVE_CURSOR_LEFT_ONE_SPACE);
		endCommand();
	}

	void I2CFlexel::moveCursorRightOneSpace()
	{
		beginCommand(I2C_FLEXEL_COMMAND_MOVE_CURSOR_RIGHT_ONE_SPACE);
		endCommand();
	}

	void I2CFlexel::turnOnBlinkingCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_ON_BLINKING_CURSOR);
		endCommand();
	}

	void I2CFlexel::turnOffBlinkingCursor()
	{
		beginCommand(I2C_FLEXEL_COMMAND_TURN_OFF_BLINKING_CURSOR);
		endCommand();
	}

	void I2CFlexel::clearLcdScreen()
	{
		beginCommand(I2C_FLEXEL_COMMAND_CLEAR_LCD_SCREEN);
		endCommand();
	}

	void I2CFlexel::printStringOnLcd(byte* str, uint8_t length)
	{
		beginCommand(I2C_FLEXEL_COMMAND_PRINT_STRING_ON_LCD);
		sendCommandParameter(length);
		sendCommandParameters(str, length);
		endCommand();
	}

	void I2CFlexel::loadLcdCustomCharacters(byte addr, byte* bitmap)
	{
		beginCommand(I2C_FLEXEL_COMMAND_LOAD_LCD_CUSTOM_CHARACTERS);
		sendCommandParameter(addr);
		sendCommandParameters(bitmap, I2C_FLEXEL_LCD_CHAR_ROWS_COUNT);
		endCommand();
	}
}<|endoftext|>


<commit_before>#include <lambda/pylambda_worker.hpp>
#include <cppipc/server/comm_server.hpp>
#include <lambda/pylambda.hpp>
#include <shmipc/shmipc.hpp>
#include <lambda/graph_pylambda.hpp>
#include <logger/logger.hpp>
#include <process/process_util.hpp>
#include <util/try_finally.hpp>

namespace graphlab { namespace lambda {

/** The main function to be called from the python ctypes library to
 *  create a pylambda worker process.
 *
 *  Different error routes produce different error codes of 101 and
 *  above.
 */
int EXPORT pylambda_worker_main(const std::string& root_path,
                                const std::string& server_address, int loglevel) {

  /** Set up the debug configuration.
   *
   *  By default, all LOG_ERROR and LOG_FATAL messages are sent to
   *  stderr, and all messages above loglevel are sent to stdout.
   *
   *  If GRAPHLAB_LAMBDA_WORKER_LOG_FILE is set and is non-empty, then
   *  all log messages are sent to the file instead of the stdout and
   *  stderr.  In this case, the only errors logged to stderr/stdout
   *  concern opening the log file.
   *
   *  If GRAPHLAB_LAMBDA_WORKER_DEBUG_MODE is set, then the default
   *  log level is set to LOG_DEBUG.  If a log file is set, then all
   *  log messages are sent there, otherwise they are sent to stderr.
   */
  boost::optional<std::string> debug_mode_str = graphlab::getenv_str("GRAPHLAB_LAMBDA_WORKER_DEBUG_MODE");
  boost::optional<std::string> debug_mode_file_str = graphlab::getenv_str("GRAPHLAB_LAMBDA_WORKER_LOG_FILE");

  std::string log_file_string = debug_mode_file_str ? *debug_mode_file_str :  "";
  bool log_to_file = (!log_file_string.empty());

  bool debug_mode = (bool)(debug_mode_str);

  global_logger().set_log_level(loglevel);
  global_logger().set_log_to_console(true);

  // Logging using the LOG_DEBUG_WITH_PID macro requires this_pid to be set.
  size_t this_pid = get_my_pid();
  global_logger().set_pid(this_pid);

  // Set up the logging to file if needed.
  if(log_to_file) {
    // Set up the logging to the file, with any errors being fully logged.
    global_logger().set_log_to_console(true, true);
    global_logger().set_log_file(log_file_string);
    LOG_DEBUG_WITH_PID("Logging lambda worker logs to " << log_file_string);
    global_logger().set_log_to_console(false);
  }

  // Now, set the log mode for debug
  if(debug_mode) {
    global_logger().set_log_level(LOG_DEBUG);
    if(!log_to_file) {
      // Set logging to console, with everything logged to stderr.
      global_logger().set_log_to_console(true, true);
    }
  }

  // Log the basic information about parameters.
  size_t parent_pid = get_parent_pid();

  LOG_DEBUG_WITH_PID("root_path = '" << root_path << "'");
  LOG_DEBUG_WITH_PID("server_address = '" << server_address << "'");
  LOG_DEBUG_WITH_PID("parend pid = " << parent_pid);

  size_t _last_line = __LINE__;
#define __TRACK do { _last_line = __LINE__; } while(0)
  try {

    LOG_DEBUG_WITH_PID("Library function entered successfully.");

    if(server_address == "debug") {
      logstream(LOG_INFO) << "Exiting dry run." << std::endl;
      return 1;
    }

    __TRACK; boost::optional<std::string> disable_shm = graphlab::getenv_str("GRAPHLAB_DISABLE_LAMBDA_SHM");
    bool use_shm = true;
    if(disable_shm && *disable_shm == "1") {
      use_shm = false;
      __TRACK; LOG_DEBUG_WITH_PID("shm disabled.");
    }

    __TRACK; graphlab::shmipc::server shm_comm_server;
    __TRACK; bool has_shm = use_shm ? shm_comm_server.bind() : false;

    __TRACK; LOG_DEBUG_WITH_PID("shm_comm_server bind: has_shm=" << has_shm);

    // construct the server
    __TRACK; cppipc::comm_server server(std::vector<std::string>(), "", server_address);

    __TRACK; server.register_type<graphlab::lambda::lambda_evaluator_interface>([&](){
        if (has_shm) {
          __TRACK; auto n = new graphlab::lambda::pylambda_evaluator(&shm_comm_server);
          __TRACK; LOG_DEBUG_WITH_PID("creation of pylambda_evaluator with SHM complete.");
          __TRACK; return n;
        } else {
          __TRACK; auto n = new graphlab::lambda::pylambda_evaluator();
          __TRACK; LOG_DEBUG_WITH_PID("creation of pylambda_evaluator without SHM complete.");
          __TRACK; return n;
        }
      });

    __TRACK; server.register_type<graphlab::lambda::graph_lambda_evaluator_interface>([&](){
        __TRACK; auto n = new graphlab::lambda::graph_pylambda_evaluator();
        __TRACK; LOG_DEBUG_WITH_PID("creation of graph_pylambda_evaluator complete.");
        __TRACK; return n;
      });

    __TRACK; LOG_DEBUG_WITH_PID("Starting server.");
    __TRACK; server.start();

    __TRACK; wait_for_parent_exit(parent_pid);

    return 0;

    /** Any exceptions happening?  If so, propegate back what's going
     *  on through the error codes.
     */
  } catch (const std::string& error) {
    logstream(LOG_ERROR) << "Internal PyLambda Error: " << error
                         << "; last successful line =" << _last_line  << std::endl;
    return _last_line;
  } catch (const std::exception& error) {
    logstream(LOG_ERROR) << "PyLambda C++ Error: " << error.what()
                         << "; last successful line =" << _last_line << std::endl;
    return _last_line;
  } catch (...) {
    logstream(LOG_ERROR) << "Unknown PyLambda Error"
                         << "; last successful line =" << _last_line << std::endl;
    return _last_line;
  }
}

}}

<commit_msg>Add further try-catch aronud SHM bind to attempt to catch shm errors.<commit_after>#include <lambda/pylambda_worker.hpp>
#include <cppipc/server/comm_server.hpp>
#include <lambda/pylambda.hpp>
#include <shmipc/shmipc.hpp>
#include <lambda/graph_pylambda.hpp>
#include <logger/logger.hpp>
#include <process/process_util.hpp>
#include <util/try_finally.hpp>

namespace graphlab { namespace lambda {

/** The main function to be called from the python ctypes library to
 *  create a pylambda worker process.
 *
 *  Different error routes produce different error codes of 101 and
 *  above.
 */
int EXPORT pylambda_worker_main(const std::string& root_path,
                                const std::string& server_address, int loglevel) {

  /** Set up the debug configuration.
   *
   *  By default, all LOG_ERROR and LOG_FATAL messages are sent to
   *  stderr, and all messages above loglevel are sent to stdout.
   *
   *  If GRAPHLAB_LAMBDA_WORKER_LOG_FILE is set and is non-empty, then
   *  all log messages are sent to the file instead of the stdout and
   *  stderr.  In this case, the only errors logged to stderr/stdout
   *  concern opening the log file.
   *
   *  If GRAPHLAB_LAMBDA_WORKER_DEBUG_MODE is set, then the default
   *  log level is set to LOG_DEBUG.  If a log file is set, then all
   *  log messages are sent there, otherwise they are sent to stderr.
   */
  boost::optional<std::string> debug_mode_str = graphlab::getenv_str("GRAPHLAB_LAMBDA_WORKER_DEBUG_MODE");
  boost::optional<std::string> debug_mode_file_str = graphlab::getenv_str("GRAPHLAB_LAMBDA_WORKER_LOG_FILE");

  std::string log_file_string = debug_mode_file_str ? *debug_mode_file_str :  "";
  bool log_to_file = (!log_file_string.empty());

  bool debug_mode = (bool)(debug_mode_str);

  global_logger().set_log_level(loglevel);
  global_logger().set_log_to_console(true);

  // Logging using the LOG_DEBUG_WITH_PID macro requires this_pid to be set.
  size_t this_pid = get_my_pid();
  global_logger().set_pid(this_pid);

  // Set up the logging to file if needed.
  if(log_to_file) {
    // Set up the logging to the file, with any errors being fully logged.
    global_logger().set_log_to_console(true, true);
    global_logger().set_log_file(log_file_string);
    LOG_DEBUG_WITH_PID("Logging lambda worker logs to " << log_file_string);
    global_logger().set_log_to_console(false);
  }

  // Now, set the log mode for debug
  if(debug_mode) {
    global_logger().set_log_level(LOG_DEBUG);
    if(!log_to_file) {
      // Set logging to console, with everything logged to stderr.
      global_logger().set_log_to_console(true, true);
    }
  }

  // Log the basic information about parameters.
  size_t parent_pid = get_parent_pid();

  LOG_DEBUG_WITH_PID("root_path = '" << root_path << "'");
  LOG_DEBUG_WITH_PID("server_address = '" << server_address << "'");
  LOG_DEBUG_WITH_PID("parend pid = " << parent_pid);

  size_t _last_line = __LINE__;
#define __TRACK do { _last_line = __LINE__; } while(0)
  try {

    LOG_DEBUG_WITH_PID("Library function entered successfully.");

    if(server_address == "debug") {
      logstream(LOG_INFO) << "Exiting dry run." << std::endl;
      return 1;
    }

    __TRACK; boost::optional<std::string> disable_shm = graphlab::getenv_str("GRAPHLAB_DISABLE_LAMBDA_SHM");
    bool use_shm = true;
    if(disable_shm && *disable_shm == "1") {
      use_shm = false;
      __TRACK; LOG_DEBUG_WITH_PID("shm disabled.");
    }

    __TRACK; graphlab::shmipc::server shm_comm_server;
    bool has_shm = false;

    try {
      __TRACK; has_shm = use_shm ? shm_comm_server.bind() : false;
    } catch (const std::string& error) {
      logstream(LOG_ERROR) << "Internal PyLambda Error binding SHM server: "
                           << error << "; disabling SHM." << std::endl;
      has_shm = false;
    } catch (const std::exception& error) {
      logstream(LOG_ERROR) << "Internal PyLambda Error binding SHM server: "
                           << error.what() << "; disabling SHM." << std::endl;
      has_shm = false;
    } catch (...) {
      logstream(LOG_ERROR) << "Unknown internal PyLambda Error binding SHM server; disabling SHM."
                           << std::endl;
      has_shm = false;
    }

    __TRACK; LOG_DEBUG_WITH_PID("shm_comm_server bind: has_shm=" << has_shm);

    // construct the server
    __TRACK; cppipc::comm_server server(std::vector<std::string>(), "", server_address);

    __TRACK; server.register_type<graphlab::lambda::lambda_evaluator_interface>([&](){
        if (has_shm) {
          __TRACK; auto n = new graphlab::lambda::pylambda_evaluator(&shm_comm_server);
          __TRACK; LOG_DEBUG_WITH_PID("creation of pylambda_evaluator with SHM complete.");
          __TRACK; return n;
        } else {
          __TRACK; auto n = new graphlab::lambda::pylambda_evaluator();
          __TRACK; LOG_DEBUG_WITH_PID("creation of pylambda_evaluator without SHM complete.");
          __TRACK; return n;
        }
      });

    __TRACK; server.register_type<graphlab::lambda::graph_lambda_evaluator_interface>([&](){
        __TRACK; auto n = new graphlab::lambda::graph_pylambda_evaluator();
        __TRACK; LOG_DEBUG_WITH_PID("creation of graph_pylambda_evaluator complete.");
        __TRACK; return n;
      });

    __TRACK; LOG_DEBUG_WITH_PID("Starting server.");
    __TRACK; server.start();

    __TRACK; wait_for_parent_exit(parent_pid);

    return 0;

    /** Any exceptions happening?  If so, propegate back what's going
     *  on through the error codes.
     */
  } catch (const std::string& error) {
    logstream(LOG_ERROR) << "Internal PyLambda Error: " << error
                         << "; last successful line =" << _last_line  << std::endl;
    return _last_line;
  } catch (const std::exception& error) {
    logstream(LOG_ERROR) << "PyLambda C++ Error: " << error.what()
                         << "; last successful line =" << _last_line << std::endl;
    return _last_line;
  } catch (...) {
    logstream(LOG_ERROR) << "Unknown PyLambda Error"
                         << "; last successful line =" << _last_line << std::endl;
    return _last_line;
  }
}

}}

<|endoftext|>


<commit_before>#include "optionsParser.h"

/***************************************************************************************
    Parse the command line to retrieve the options
    as seen in http://seqan.readthedocs.org/en/seqan-v2.0.0/Tutorial/ParsingCommandLineArguments.html
***************************************************************************************/
seqan::ArgumentParser::ParseResult
parseCommandLine(AlphaOptions &options, int argc, char const **argv)
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("ovgraphbuild");
    // Set short description, version, and date.
    seqan::setShortDescription(parser, "Build a read overlap graph from a mapping file");
    seqan::setVersion(parser, "1.0.0");
    seqan::setDate(parser, "February 2016");

    // Define Options -- Section Input Files
    seqan::addSection(parser, "Input");
    seqan::addOption(parser, seqan::ArgParseOption( "r", "reference", "Reference fasta file.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    seqan::addOption(parser, seqan::ArgParseOption( "p", "pairwise", "Reference pairwise alignment file, fasta format.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    seqan::addOption(parser, seqan::ArgParseOption( "s", "sam", "SAM/BAM input file.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    // Define Options -- Section Output Files
    seqan::addSection(parser, "Output");
    seqan::addOption(parser, seqan::ArgParseOption( "o", "output_basename", "Output files basename.",
        seqan::ArgParseArgument::STRING, "BASENAME"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "asqg", "Output overlap graph in ASQG format."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "csv", "Output overlap graph in 2 CSV files (nodes and edges)."));
    // Define Options -- Section Parameters
    seqan::addSection(parser, "Parameters");
    seqan::addOption(parser, seqan::ArgParseOption( "", "min_ref_pairwise_pid", "Minimum percent id for the ref pairwise alignments.",
        seqan::ArgParseArgument::DOUBLE, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "m", "min_overlap", "Minimum overlap size.",
        seqan::ArgParseArgument::INTEGER, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "i", "id_threshold", "Sequence identity to keep an overlap between [0.0:1.0].",
        seqan::ArgParseArgument::DOUBLE, "ID"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "min_trail_matches", "Minimum trailing matches needed to anchor the pairwise overlaps (correction).",
        seqan::ArgParseArgument::INTEGER, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "no_indel", "Indels are not allowed in reads overlap."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "multi_ref", "Turn on multi-ref algorithm."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "illumina", "Optimize the parameters for illumina sequencing."));

    // Define Options -- Section Misc.
    seqan::addSection(parser, "Misc.");
    seqan::addOption(parser, seqan::ArgParseOption( "v", "verbose", "Turn on verbose output."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "debug", "Turn on debug infos."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "test", "Turn on test infos."));

    // Set required options
    setRequired(parser, "reference");
//    setRequired(parser, "pairwise");
    setRequired(parser, "sam");

    // Set format restrictions
    seqan::setValidValues(parser, "reference", "fasta fa");
    seqan::setValidValues(parser, "pairwise", "fasta fa");
    seqan::setValidValues(parser, "sam", "sam bam");

    // Set default values
    seqan::setDefaultValue(parser, "output_basename", "ovgraphbuild_output");

    seqan::setDefaultValue(parser, "min_ref_pairwise_pid", 90);
    seqan::setDefaultValue(parser, "min_overlap", 50);
    seqan::setDefaultValue(parser, "id_threshold", 1);
    seqan::setDefaultValue(parser, "min_trail_matches", 3);

    // Parse command line
    auto res = seqan::parse(parser, argc, argv);

    // Only extract  options if the program will continue after parseCommandLine()
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

    // Extract and print the options.
    seqan::getOptionValue(options.myRefFastaFile, parser, "reference");
    seqan::getOptionValue(options.myRefPairwiseAlignFile, parser, "pairwise");
    seqan::getOptionValue(options.mySamFile, parser, "sam");

    seqan::getOptionValue(options.outputBasename, parser, "output_basename");
//    options.outputASQG = seqan::isSet(parser, "asqg");
    options.outputASQG = true;
//    options.outputCSV = seqan::isSet(parser, "csv");
    options.outputCSV = true;

    seqan::getOptionValue(options.minRefPairwisePercentId, parser, "min_ref_pairwise_pid");
    seqan::getOptionValue(options.minOverlapLength, parser, "min_overlap");
    seqan::getOptionValue(options.idRateThreshold, parser, "id_threshold");
    seqan::getOptionValue(options.minNumTrailingMatches, parser, "min_trail_matches");
    options.noIndel = seqan::isSet(parser, "no_indel");
    options.multiRef = seqan::isSet(parser, "multi_ref");

    if (seqan::isSet(parser, "illumina"))
    {
        options.noIndel = true;
    }

    options.verbose = seqan::isSet(parser, "verbose");
    options.debug = seqan::isSet(parser, "debug");
    options.test = seqan::isSet(parser, "test");

    // TO DO: Add parameters check (e.g. 0 <= pid <= 100)

    return seqan::ArgumentParser::PARSE_OK;
}

/***************************************************************************************
    Print all the debug and verbose info at the start of the program, after
    arguments parsing
***************************************************************************************/
int printStartingDebugAndVerboseInfo(AlphaOptions &options)
{
    if (options.debug)
    {
        std::cout << "DEBUG: Currently in file: " << __FILE__
                  << " Function: " << __FUNCTION__ << "()" << "\n" << "\n";

        std::cout << "DEBUG: size of bool      = " << sizeof(bool) << "\n"
                  << "DEBUG: size of char      = " << sizeof(char) << "\n"
                  << "DEBUG: size of short     = " << sizeof(short) << "\n"
                  << "DEBUG: size of int       = " << sizeof(int) << "\n"
                  << "DEBUG: size of int8_t    = " << sizeof(int8_t) << "\n"
                  << "DEBUG: size of int16_t   = " << sizeof(int16_t) << "\n"
                  << "DEBUG: size of int32_t   = " << sizeof(int32_t) << "\n"
                  << "DEBUG: size of int64_t   = " << sizeof(int64_t) << "\n"
                  << "DEBUG: size of long      = " << sizeof(long) << "\n"
                  << "DEBUG: size of long long = " << sizeof(long long) << "\n"
                  << "DEBUG: size of float     = " << sizeof(float) << "\n"
                  << "DEBUG: size of double    = " << sizeof(double) << "\n"
                  << "DEBUG: size of char*             = " << sizeof(char*) << "\n"
                  << "DEBUG: size of std::string       = " << sizeof(std::string) << "\n"
                  << "DEBUG: size of seqan::CharString = " << sizeof(seqan::CharString)
                  << "\n" << "\n";
    }

    if (options.verbose)
    {
        std::cout << "PARAM: References:         \t" << options.myRefFastaFile << "\n"
                  << "PARAM: Pairwise:           \t" << options.myRefPairwiseAlignFile << "\n"
                  << "PARAM: Sam file:           \t" << options.mySamFile << "\n"
                  << "PARAM: Output basename:    \t" << options.outputBasename << "\n"
                  << "PARAM: ASQG output:        \t" << options.outputASQG << "\n"
                  << "PARAM: CSV output:         \t" << options.outputCSV << "\n"
                  << "PARAM: Min Ref Pairw. pid: \t" << options.minRefPairwisePercentId << "\n"
                  << "PARAM: Min Overlap:        \t" << options.minOverlapLength << "\n"
                  << "PARAM: Id Threshold:       \t" << options.idRateThreshold << "\n"
                  << "PARAM: NoIndel:            \t" << options.noIndel << "\n"
                  << "PARAM: MultiRef:           \t" << options.multiRef << "\n"
                  << "PARAM: Debug:              \t" << options.debug << "\n"
                  << "PARAM: Verbose:            \t" << options.verbose << "\n"
                  << "PARAM: Test:               \t" << options.test << "\n" << "\n";
    }

    return 0;
}

/***************************************************************************************
    Main procedure
***************************************************************************************/
int getOptions(AlphaOptions &options, int argc, char const **argv)
{
    // Parse the command line.
    auto res = parseCommandLine(options, argc, argv);

    // If parsing was not successful then exit with code 1 if there were errors.
    // Otherwise, exit with code 0 (e.g. help was printed).
    if (res != seqan::ArgumentParser::PARSE_OK)
    {
        return res == seqan::ArgumentParser::PARSE_ERROR;
    }

    std::cout << "\n";

    printStartingDebugAndVerboseInfo(options);

    return 0;
}
<commit_msg>Reactivated --asqg --csv options<commit_after>#include "optionsParser.h"

/***************************************************************************************
    Parse the command line to retrieve the options
    as seen in http://seqan.readthedocs.org/en/seqan-v2.0.0/Tutorial/ParsingCommandLineArguments.html
***************************************************************************************/
seqan::ArgumentParser::ParseResult
parseCommandLine(AlphaOptions &options, int argc, char const **argv)
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("ovgraphbuild");
    // Set short description, version, and date.
    seqan::setShortDescription(parser, "Build a read overlap graph from a mapping file");
    seqan::setVersion(parser, "1.0.0");
    seqan::setDate(parser, "February 2016");

    // Define Options -- Section Input Files
    seqan::addSection(parser, "Input");
    seqan::addOption(parser, seqan::ArgParseOption( "r", "reference", "Reference fasta file.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    seqan::addOption(parser, seqan::ArgParseOption( "p", "pairwise", "Reference pairwise alignment file, fasta format.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    seqan::addOption(parser, seqan::ArgParseOption( "s", "sam", "SAM/BAM input file.",
        seqan::ArgParseArgument::INPUT_FILE, "IN_FILE"));
    // Define Options -- Section Output Files
    seqan::addSection(parser, "Output");
    seqan::addOption(parser, seqan::ArgParseOption( "o", "output_basename", "Output files basename.",
        seqan::ArgParseArgument::STRING, "BASENAME"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "asqg", "Output overlap graph in ASQG format."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "csv", "Output overlap graph in 2 CSV files (nodes and edges)."));
    // Define Options -- Section Parameters
    seqan::addSection(parser, "Parameters");
    seqan::addOption(parser, seqan::ArgParseOption( "", "min_ref_pairwise_pid", "Minimum percent id for the ref pairwise alignments.",
        seqan::ArgParseArgument::DOUBLE, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "m", "min_overlap", "Minimum overlap size.",
        seqan::ArgParseArgument::INTEGER, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "i", "id_threshold", "Sequence identity to keep an overlap between [0.0:1.0].",
        seqan::ArgParseArgument::DOUBLE, "ID"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "min_trail_matches", "Minimum trailing matches needed to anchor the pairwise overlaps (correction).",
        seqan::ArgParseArgument::INTEGER, "MIN"));
    seqan::addOption(parser, seqan::ArgParseOption( "", "no_indel", "Indels are not allowed in reads overlap."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "multi_ref", "Turn on multi-ref algorithm."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "illumina", "Optimize the parameters for illumina sequencing."));

    // Define Options -- Section Misc.
    seqan::addSection(parser, "Misc.");
    seqan::addOption(parser, seqan::ArgParseOption( "v", "verbose", "Turn on verbose output."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "debug", "Turn on debug infos."));
    seqan::addOption(parser, seqan::ArgParseOption( "", "test", "Turn on test infos."));

    // Set required options
    setRequired(parser, "reference");
//    setRequired(parser, "pairwise");
    setRequired(parser, "sam");

    // Set format restrictions
    seqan::setValidValues(parser, "reference", "fasta fa");
    seqan::setValidValues(parser, "pairwise", "fasta fa");
    seqan::setValidValues(parser, "sam", "sam bam");

    // Set default values
    seqan::setDefaultValue(parser, "output_basename", "ovgraphbuild_output");

    seqan::setDefaultValue(parser, "min_ref_pairwise_pid", 90);
    seqan::setDefaultValue(parser, "min_overlap", 50);
    seqan::setDefaultValue(parser, "id_threshold", 1);
    seqan::setDefaultValue(parser, "min_trail_matches", 3);

    // Parse command line
    auto res = seqan::parse(parser, argc, argv);

    // Only extract  options if the program will continue after parseCommandLine()
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

    // Extract and print the options.
    seqan::getOptionValue(options.myRefFastaFile, parser, "reference");
    seqan::getOptionValue(options.myRefPairwiseAlignFile, parser, "pairwise");
    seqan::getOptionValue(options.mySamFile, parser, "sam");

    seqan::getOptionValue(options.outputBasename, parser, "output_basename");
    options.outputASQG = seqan::isSet(parser, "asqg");
//    options.outputASQG = true;
    options.outputCSV = seqan::isSet(parser, "csv");
//    options.outputCSV = true;

    seqan::getOptionValue(options.minRefPairwisePercentId, parser, "min_ref_pairwise_pid");
    seqan::getOptionValue(options.minOverlapLength, parser, "min_overlap");
    seqan::getOptionValue(options.idRateThreshold, parser, "id_threshold");
    seqan::getOptionValue(options.minNumTrailingMatches, parser, "min_trail_matches");
    options.noIndel = seqan::isSet(parser, "no_indel");
    options.multiRef = seqan::isSet(parser, "multi_ref");

    if (seqan::isSet(parser, "illumina"))
    {
        options.noIndel = true;
    }

    options.verbose = seqan::isSet(parser, "verbose");
    options.debug = seqan::isSet(parser, "debug");
    options.test = seqan::isSet(parser, "test");

    // TO DO: Add parameters check (e.g. 0 <= pid <= 100)

    return seqan::ArgumentParser::PARSE_OK;
}

/***************************************************************************************
    Print all the debug and verbose info at the start of the program, after
    arguments parsing
***************************************************************************************/
int printStartingDebugAndVerboseInfo(AlphaOptions &options)
{
    if (options.debug)
    {
        std::cout << "DEBUG: Currently in file: " << __FILE__
                  << " Function: " << __FUNCTION__ << "()" << "\n" << "\n";

        std::cout << "DEBUG: size of bool      = " << sizeof(bool) << "\n"
                  << "DEBUG: size of char      = " << sizeof(char) << "\n"
                  << "DEBUG: size of short     = " << sizeof(short) << "\n"
                  << "DEBUG: size of int       = " << sizeof(int) << "\n"
                  << "DEBUG: size of int8_t    = " << sizeof(int8_t) << "\n"
                  << "DEBUG: size of int16_t   = " << sizeof(int16_t) << "\n"
                  << "DEBUG: size of int32_t   = " << sizeof(int32_t) << "\n"
                  << "DEBUG: size of int64_t   = " << sizeof(int64_t) << "\n"
                  << "DEBUG: size of long      = " << sizeof(long) << "\n"
                  << "DEBUG: size of long long = " << sizeof(long long) << "\n"
                  << "DEBUG: size of float     = " << sizeof(float) << "\n"
                  << "DEBUG: size of double    = " << sizeof(double) << "\n"
                  << "DEBUG: size of char*             = " << sizeof(char*) << "\n"
                  << "DEBUG: size of std::string       = " << sizeof(std::string) << "\n"
                  << "DEBUG: size of seqan::CharString = " << sizeof(seqan::CharString)
                  << "\n" << "\n";
    }

    if (options.verbose)
    {
        std::cout << "PARAM: References:         \t" << options.myRefFastaFile << "\n"
                  << "PARAM: Pairwise:           \t" << options.myRefPairwiseAlignFile << "\n"
                  << "PARAM: Sam file:           \t" << options.mySamFile << "\n"
                  << "PARAM: Output basename:    \t" << options.outputBasename << "\n"
                  << "PARAM: ASQG output:        \t" << options.outputASQG << "\n"
                  << "PARAM: CSV output:         \t" << options.outputCSV << "\n"
                  << "PARAM: Min Ref Pairw. pid: \t" << options.minRefPairwisePercentId << "\n"
                  << "PARAM: Min Overlap:        \t" << options.minOverlapLength << "\n"
                  << "PARAM: Id Threshold:       \t" << options.idRateThreshold << "\n"
                  << "PARAM: NoIndel:            \t" << options.noIndel << "\n"
                  << "PARAM: MultiRef:           \t" << options.multiRef << "\n"
                  << "PARAM: Debug:              \t" << options.debug << "\n"
                  << "PARAM: Verbose:            \t" << options.verbose << "\n"
                  << "PARAM: Test:               \t" << options.test << "\n" << "\n";
    }

    return 0;
}

/***************************************************************************************
    Main procedure
***************************************************************************************/
int getOptions(AlphaOptions &options, int argc, char const **argv)
{
    // Parse the command line.
    auto res = parseCommandLine(options, argc, argv);

    // If parsing was not successful then exit with code 1 if there were errors.
    // Otherwise, exit with code 0 (e.g. help was printed).
    if (res != seqan::ArgumentParser::PARSE_OK)
    {
        return res == seqan::ArgumentParser::PARSE_ERROR;
    }

    std::cout << "\n";

    printStartingDebugAndVerboseInfo(options);

    return 0;
}
<|endoftext|>


<commit_before>#include "System.h"
#include "SDL_ttf.h"
#include <string.h>

struct_textfile *sub_LoadTextFile(FManNode *file)
{
    mfile *f = mfopen(file);

    if (f == NULL)
        return NULL;

    m_wide_to_utf8(f);

    int sz = f->size;

    struct_textfile *tmp = new(struct_textfile);

    tmp->buffer = (char *)calloc(sz+1,1);

    memcpy(tmp->buffer,f->buf,f->size);
    mfclose(f);

    int linescount=0;

    for (int i=0; i<sz; i++)
        if (tmp->buffer[i] == 0x0A)
            linescount ++;

    tmp->count = linescount;

    tmp->subs   = (char **)calloc(linescount,sizeof(char *));

    linescount=0;
    int i=0;
    char *curline=NULL;

    while (i<sz)
    {
        curline = tmp->buffer+i;

        while (i<sz)
        {
            if (tmp->buffer[i] == 0xA || tmp->buffer[i] == 0xD)
                break;
            i++;
        }

        if (tmp->buffer[i] == 0xD)
        {
            if (tmp->buffer[i+1] == 0xA)//windows
            {
                tmp->buffer[i] = 0;
                tmp->buffer[i+1] = 0;
                i+=2;
            }
            else //macOS
            {
                tmp->buffer[i] = 0;
                i++;
            }
        }
        else if (tmp->buffer[i] == 0xA) //unix
        {
            tmp->buffer[i] = 0;
            i++;
        }

        if (linescount<tmp->count)
            tmp->subs[linescount]   = curline;

        linescount++;
    }

    return tmp;
}

void sub_DeleteTextFile(struct_textfile *txt)
{
    free(txt->buffer);
    free(txt->subs);
    delete txt;
}

struct_subtitles *sub_LoadSubtitles(char *filename)
{

    char buf[FILE_LN_BUF];
    char *str1; // without left spaces, paramname
    char *str2 = NULL; // params

    int subscount=0;

    struct_subtitles *tmp;

    FManNode *fil = FindInBinTree(filename);
    if (fil == NULL)
        return NULL;

    tmp = new(struct_subtitles);

    tmp->currentsub = -1;
    tmp->SubRect = NULL;
    tmp->subscount = 0;

    mfile *f = mfopen(fil);
    while (!mfeof(f))
    {
        mfgets(buf,FILE_LN_BUF,f);
        str1 = TrimLeft(buf);

        int32_t t_len = strlen(str1);
        for (int i=0; i<t_len; i++)
            if (str1[i] == ':')
            {
                str1[i] = 0x0;
                str2 = str1+i+1;
                break;
            }
        for (int i=strlen(str2)-1; i>=0; i--)
            if (str2[i] == '~' || str2[i]==0x0A || str2[i]==0x0D)
                str2[i] = 0x0;

        if (strCMP(str1,"Initialization") == 0)
        {
            ;
        }
        else if (strCMP(str1,"Rectangle") == 0)
        {
            int x;
            int y;
            int x2;
            int y2;
            sscanf(str2,"%d %d %d %d",&x,&y,&x2,&y2);
            tmp->SubRect = Rend_CreateSubRect(x + GAMESCREEN_X + SUB_CORRECT_HORIZ + GAMESCREEN_FLAT_X,
                                              y + GAMESCREEN_Y + SUB_CORRECT_VERT,
                                              x2-x+1,
                                              y2-y+1);
        }
        else if (strCMP(str1,"TextFile") == 0)
        {
            FManNode *fil2 = FindInBinTree(str2);
            if (fil2 == NULL)
            {
                delete tmp;
                return NULL;
            }

            tmp->txt = sub_LoadTextFile(fil2);
            tmp->subs = (struct_one_subtitle *)calloc(tmp->txt->count,sizeof(struct_one_subtitle));
            subscount = tmp->txt->count;
        }
        else//it's must be sub info
        {
            int st;
            int en;
            int sb;
            if ( sscanf(str2,"(%d,%d)=%d",&st,&en,&sb) == 3)
            {
                if (subscount == 0 || sb > subscount)
                {
                    printf("Error in subs %s\n",filename);
                    exit(-1);
                }
                tmp->subs[tmp->subscount].start = st;
                tmp->subs[tmp->subscount].stop  = en;
                tmp->subs[tmp->subscount].sub  = sb;

                tmp->subscount++;
            }

        }

    }
    mfclose(f);

    return tmp;
}

void sub_ProcessSub(struct_subtitles *sub,int subtime)
{
    int j=-1;
    for (int i=0; i<sub->subscount; i++)
        if (subtime >= sub->subs[i].start &&
                subtime <= sub->subs[i].stop)
        {
            j=i;
            break;
        }

    if (j == -1 && sub->currentsub!= -1)
    {
        SDL_FillRect(sub->SubRect->img,NULL,SDL_MapRGBA(sub->SubRect->img->format,0,0,0,255));
        sub->currentsub = -1;
    }

    if (j!=-1 && j!=sub->currentsub)
    {
        char *sss;
        sss = sub->txt->subs[sub->subs[j].sub];
        if (sss != NULL)
            if (strlen(sss) > 0)
            {
                SDL_FillRect(sub->SubRect->img,NULL,SDL_MapRGBA(sub->SubRect->img->format,0,0,0,255));
                txt_DrawTxtInOneLine(sss,sub->SubRect->img);
            }

        sub->currentsub = j;
    }
}

void sub_DeleteSub(struct_subtitles *sub)
{
    Rend_DeleteSubRect(sub->SubRect);

    sub_DeleteTextFile(sub->txt);
    free(sub->subs);
    delete sub;
}
<commit_msg>Fixed memory leak in subtitles with empty lines<commit_after>#include "System.h"
#include "SDL_ttf.h"
#include <string.h>

struct_textfile *sub_LoadTextFile(FManNode *file)
{
    mfile *f = mfopen(file);

    if (f == NULL)
        return NULL;

    m_wide_to_utf8(f);

    int sz = f->size;

    struct_textfile *tmp = new(struct_textfile);

    tmp->buffer = (char *)calloc(sz+1,1);

    memcpy(tmp->buffer,f->buf,f->size);
    mfclose(f);

    int linescount=0;

    for (int i=0; i<sz; i++)
        if (tmp->buffer[i] == 0x0A)
            linescount ++;

    tmp->count = linescount;

    tmp->subs   = (char **)calloc(linescount,sizeof(char *));

    linescount=0;
    int i=0;
    char *curline=NULL;

    while (i<sz)
    {
        curline = tmp->buffer+i;

        while (i<sz)
        {
            if (tmp->buffer[i] == 0xA || tmp->buffer[i] == 0xD)
                break;
            i++;
        }

        if (tmp->buffer[i] == 0xD)
        {
            if (tmp->buffer[i+1] == 0xA)//windows
            {
                tmp->buffer[i] = 0;
                tmp->buffer[i+1] = 0;
                i+=2;
            }
            else //macOS
            {
                tmp->buffer[i] = 0;
                i++;
            }
        }
        else if (tmp->buffer[i] == 0xA) //unix
        {
            tmp->buffer[i] = 0;
            i++;
        }

        if (linescount<tmp->count)
            tmp->subs[linescount]   = curline;

        linescount++;
    }

    return tmp;
}

void sub_DeleteTextFile(struct_textfile *txt)
{
    free(txt->buffer);
    free(txt->subs);
    delete txt;
}

struct_subtitles *sub_LoadSubtitles(char *filename)
{

    char buf[FILE_LN_BUF];
    char *str1; // without left spaces, paramname
    char *str2 = NULL; // params

    int subscount=0;

    struct_subtitles *tmp;

    FManNode *fil = FindInBinTree(filename);
    if (fil == NULL)
        return NULL;

    tmp = new(struct_subtitles);

    tmp->currentsub = -1;
    tmp->SubRect = NULL;
    tmp->subscount = 0;

    mfile *f = mfopen(fil);
    while (!mfeof(f))
    {
        mfgets(buf,FILE_LN_BUF,f);
        str1 = TrimLeft(buf);

        str2 = NULL;

        int32_t t_len = strlen(str1);

        for (int i=0; i<t_len; i++)
            if (str1[i] == ':')
            {
                str1[i] = 0x0;
                str2 = str1+i+1;
                break;
            }

        if (str2 != NULL)
        {
            for (int i=strlen(str2)-1; i>=0; i--)
                if (str2[i] == '~' || str2[i]==0x0A || str2[i]==0x0D)
                    str2[i] = 0x0;

            if (strCMP(str1,"Initialization") == 0)
            {
                ;
            }
            else if (strCMP(str1,"Rectangle") == 0)
            {
                int x;
                int y;
                int x2;
                int y2;
                sscanf(str2,"%d %d %d %d",&x,&y,&x2,&y2);
                tmp->SubRect = Rend_CreateSubRect(x + GAMESCREEN_X + SUB_CORRECT_HORIZ + GAMESCREEN_FLAT_X,
                                                  y + GAMESCREEN_Y + SUB_CORRECT_VERT,
                                                  x2-x+1,
                                                  y2-y+1);
            }
            else if (strCMP(str1,"TextFile") == 0)
            {
                FManNode *fil2 = FindInBinTree(str2);
                if (fil2 == NULL)
                {
                    delete tmp;
                    return NULL;
                }

                tmp->txt = sub_LoadTextFile(fil2);
                tmp->subs = (struct_one_subtitle *)calloc(tmp->txt->count,sizeof(struct_one_subtitle));
                subscount = tmp->txt->count;
            }
            else//it's must be sub info
            {
                int st;
                int en;
                int sb;
                if ( sscanf(str2,"(%d,%d)=%d",&st,&en,&sb) == 3)
                {
                    if (subscount == 0 || sb > subscount)
                    {
                        printf("Error in subs %s\n",filename);
                        exit(-1);
                    }
                    tmp->subs[tmp->subscount].start = st;
                    tmp->subs[tmp->subscount].stop  = en;
                    tmp->subs[tmp->subscount].sub  = sb;

                    tmp->subscount++;
                }

            }
        }

    }
    mfclose(f);

    return tmp;
}

void sub_ProcessSub(struct_subtitles *sub,int subtime)
{
    int j=-1;
    for (int i=0; i<sub->subscount; i++)
        if (subtime >= sub->subs[i].start &&
                subtime <= sub->subs[i].stop)
        {
            j=i;
            break;
        }

    if (j == -1 && sub->currentsub!= -1)
    {
        SDL_FillRect(sub->SubRect->img,NULL,SDL_MapRGBA(sub->SubRect->img->format,0,0,0,255));
        sub->currentsub = -1;
    }

    if (j!=-1 && j!=sub->currentsub)
    {
        char *sss;
        sss = sub->txt->subs[sub->subs[j].sub];
        if (sss != NULL)
            if (strlen(sss) > 0)
            {
                SDL_FillRect(sub->SubRect->img,NULL,SDL_MapRGBA(sub->SubRect->img->format,0,0,0,255));
                txt_DrawTxtInOneLine(sss,sub->SubRect->img);
            }

        sub->currentsub = j;
    }
}

void sub_DeleteSub(struct_subtitles *sub)
{
    Rend_DeleteSubRect(sub->SubRect);

    sub_DeleteTextFile(sub->txt);
    free(sub->subs);
    delete sub;
}
<|endoftext|>


<commit_before>#include "utils/md5-fix/md5-fix.h"
#include <QCryptographicHash>
#include <QDir>
#include <QDirIterator>
#include <QMessageBox>
#include <QSettings>
#include <ui_md5-fix.h>
#include "functions.h"
#include "helpers.h"
#include "logger.h"
#include "models/profile.h"

Md5Fix::Md5Fix(Profile *profile, QWidget *parent)
	: QDialog(parent), ui(new Ui::Md5Fix), m_profile(profile)
{
	ui->setupUi(this);

	QSettings *settings = profile->getSettings();
	ui->lineFolder->setText(settings->value("Save/path").toString());
	ui->lineFilename->setText(settings->value("Save/filename").toString());
	ui->lineSuffixes->setText(getExternalLogFilesSuffixes(profile->getSettings()).join(", "));
	ui->progressBar->hide();

	m_worker = new Md5FixWorker();
	m_worker->moveToThread(&m_thread);
	connect(&m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
	connect(this, &Md5Fix::startWorker, m_worker, &Md5FixWorker::doWork);
	connect(m_worker, &Md5FixWorker::maximumSet, this, &Md5Fix::workerMaximumSet);
	connect(m_worker, &Md5FixWorker::valueSet, this, &Md5Fix::workerValueSet);
	connect(m_worker, &Md5FixWorker::md5Calculated, this, &Md5Fix::workerMd5Calculated);
	connect(m_worker, &Md5FixWorker::finished, this, &Md5Fix::workerFinished);

	m_thread.start();

	resize(size().width(), 0);
}

Md5Fix::~Md5Fix()
{
	delete ui;

	m_thread.quit();
	m_thread.wait();

	m_worker->deleteLater();
}

void Md5Fix::cancel()
{
	emit rejected();
	close();
}

void Md5Fix::workerMaximumSet(int max)
{
	if (max > 0) {
		ui->progressBar->setValue(0);
		ui->progressBar->setMaximum(max);
		ui->progressBar->show();
	}
}

void Md5Fix::workerValueSet(int value)
{
	ui->progressBar->setValue(value);
}

void Md5Fix::workerMd5Calculated(const QString &md5, const QString &path)
{
	m_profile->addMd5(md5, path);
}

void Md5Fix::workerFinished(int loadedCount)
{
	// Hide progress bar
	ui->progressBar->hide();
	ui->progressBar->setValue(0);
	ui->progressBar->setMaximum(0);

	ui->buttonStart->setEnabled(true);

	m_profile->sync();

	QMessageBox::information(this, tr("Finished"), tr("%n MD5(s) loaded", "", loadedCount));
}

void Md5Fix::start()
{
	ui->buttonStart->setEnabled(false);

	// Check that directory exists
	QString dir = fixFilename("", ui->lineFolder->text());
	if (!QDir(dir).exists()) {
		error(this, tr("This folder does not exist."));
		ui->buttonStart->setEnabled(true);
		return;
	}

	// Make sure the input is valid
	bool force = ui->radioForce->isChecked();
	if (!force && !ui->lineFilename->text().contains("%md5%")) {
		error(this, tr("If you want to get the MD5 from the filename, you have to include the %md5% token in it."));
		ui->buttonStart->setEnabled(true);
		return;
	}

	// Suffixes
	QStringList suffixes = ui->lineSuffixes->text().split(',');
	for (QString &suffix : suffixes) {
		suffix = suffix.trimmed();
	}

	emit startWorker(dir, ui->lineFilename->text(), suffixes, force);
}
<commit_msg>Fix crash when closing MD5 list fixer<commit_after>#include "utils/md5-fix/md5-fix.h"
#include <QCryptographicHash>
#include <QDir>
#include <QDirIterator>
#include <QMessageBox>
#include <QSettings>
#include <ui_md5-fix.h>
#include "functions.h"
#include "helpers.h"
#include "logger.h"
#include "models/profile.h"

Md5Fix::Md5Fix(Profile *profile, QWidget *parent)
	: QDialog(parent), ui(new Ui::Md5Fix), m_profile(profile)
{
	ui->setupUi(this);

	QSettings *settings = profile->getSettings();
	ui->lineFolder->setText(settings->value("Save/path").toString());
	ui->lineFilename->setText(settings->value("Save/filename").toString());
	ui->lineSuffixes->setText(getExternalLogFilesSuffixes(profile->getSettings()).join(", "));
	ui->progressBar->hide();

	m_worker = new Md5FixWorker();
	m_worker->moveToThread(&m_thread);
	connect(&m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
	connect(this, &Md5Fix::startWorker, m_worker, &Md5FixWorker::doWork);
	connect(m_worker, &Md5FixWorker::maximumSet, this, &Md5Fix::workerMaximumSet);
	connect(m_worker, &Md5FixWorker::valueSet, this, &Md5Fix::workerValueSet);
	connect(m_worker, &Md5FixWorker::md5Calculated, this, &Md5Fix::workerMd5Calculated);
	connect(m_worker, &Md5FixWorker::finished, this, &Md5Fix::workerFinished);

	m_thread.start();

	resize(size().width(), 0);
}

Md5Fix::~Md5Fix()
{
	delete ui;

	m_thread.quit();
	m_thread.wait();
}

void Md5Fix::cancel()
{
	emit rejected();
	close();
}

void Md5Fix::workerMaximumSet(int max)
{
	if (max > 0) {
		ui->progressBar->setValue(0);
		ui->progressBar->setMaximum(max);
		ui->progressBar->show();
	}
}

void Md5Fix::workerValueSet(int value)
{
	ui->progressBar->setValue(value);
}

void Md5Fix::workerMd5Calculated(const QString &md5, const QString &path)
{
	m_profile->addMd5(md5, path);
}

void Md5Fix::workerFinished(int loadedCount)
{
	// Hide progress bar
	ui->progressBar->hide();
	ui->progressBar->setValue(0);
	ui->progressBar->setMaximum(0);

	ui->buttonStart->setEnabled(true);

	m_profile->sync();

	QMessageBox::information(this, tr("Finished"), tr("%n MD5(s) loaded", "", loadedCount));
}

void Md5Fix::start()
{
	ui->buttonStart->setEnabled(false);

	// Check that directory exists
	QString dir = fixFilename("", ui->lineFolder->text());
	if (!QDir(dir).exists()) {
		error(this, tr("This folder does not exist."));
		ui->buttonStart->setEnabled(true);
		return;
	}

	// Make sure the input is valid
	bool force = ui->radioForce->isChecked();
	if (!force && !ui->lineFilename->text().contains("%md5%")) {
		error(this, tr("If you want to get the MD5 from the filename, you have to include the %md5% token in it."));
		ui->buttonStart->setEnabled(true);
		return;
	}

	// Suffixes
	QStringList suffixes = ui->lineSuffixes->text().split(',');
	for (QString &suffix : suffixes) {
		suffix = suffix.trimmed();
	}

	emit startWorker(dir, ui->lineFilename->text(), suffixes, force);
}
<|endoftext|>


<commit_before>/*
 * tensortrackwidget.cpp
 *
 *  Created on: 26.01.2013
 *      Author: Ralph
 */
#include <QtGui/QPushButton>
#include <QtGui/QProgressBar>

#include "sliderwithedit.h"
#include "sliderwitheditint.h"
#include "selectwithlabel.h"

#include "../../algos/track.h"
#include "../../data/datasets/dataset.h"
#include "../../data/datasets/datasetFibers.h"
#include "../../data/datasets/datasetTensor.h"

#include "tensortrackwidget.h"

TensorTrackWidget::TensorTrackWidget( Dataset* ds, QList<QVariant> &dsl, QWidget* parent ) :
    m_progress( 0 )
{
    m_tracker = new Track( dynamic_cast<DatasetTensor*>( ds ) );
    connect( m_tracker, SIGNAL( progress() ), this, SLOT( slotProgress() ), Qt::QueuedConnection );
    connect( m_tracker, SIGNAL( finished() ), this, SLOT( slotFinished() ) );

    m_layout = new QVBoxLayout();
/*
    SelectWithLabel* sel = new SelectWithLabel( QString( "optional: mask (not yet implemented)" ), 1 );
    sel->insertItem( 0, QString("none") );
    for ( int k = 0; k < dsl.size(); ++k )
    {
        if ( dsl[k]->properties()->get( FNPROP_TYPE ).toInt() == FNDT_NIFTI_SCALAR )
        {
            sel->insertItem( k+1, dsl[k]->properties()->get( FNPROP_NAME ).toString() );
        }
    }
    m_layout->addWidget( sel );

    SelectWithLabel* sel2 = new SelectWithLabel( QString( "optional: roi (not yet implemented)" ), 1 );
    sel2->insertItem( 0, QString("none") );
    for ( int k = 0; k < dsl.size(); ++k )
    {
        if ( dsl[k]->properties()->get( FNPROP_TYPE ).toInt() == FNDT_NIFTI_SCALAR )
        {
            sel2->insertItem( k+1, dsl[k]->properties()->get( FNPROP_NAME ).toString() );
        }
    }
    m_layout->addWidget( sel2 );
*/
    QHBoxLayout* hLayout = new QHBoxLayout();
    m_startButton = new QPushButton( tr("Start") );
    connect( m_startButton, SIGNAL( clicked() ), this, SLOT( start() ) );

    SliderWithEdit* minFA = new SliderWithEdit( QString("min FA for Start Voxels") );
    minFA->setMin( 0.01f );
    minFA->setMax( 1.0f );
    minFA->setValue( 0.2f );
    m_layout->addWidget( minFA );
    connect( minFA, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setMinStartFA( float, int) ) );

    SliderWithEdit* stopFA = new SliderWithEdit( QString("min FA to keep tracking") );
    stopFA->setMin( 0.01f );
    stopFA->setMax( 1.0f );
    stopFA->setValue( 0.2f );
    m_layout->addWidget( stopFA );
    connect( stopFA, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setMinFA( float, int) ) );

    SliderWithEditInt* minLength = new SliderWithEditInt( QString("min length to keep fibers") );
    minLength->setMin( 1 );
    minLength->setMax( 200 );
    minLength->setValue( 10 );
    m_layout->addWidget( minLength );
    connect( minLength, SIGNAL( valueChanged( int, int) ), m_tracker, SLOT( setMinLength( int, int) ) );

    SliderWithEdit* setSize = new SliderWithEdit( QString("step size") );
    setSize->setMin( 0.01f );
    setSize->setMax( 2.0f );
    setSize->setValue( 1.0f );
    m_layout->addWidget( setSize );
    connect( setSize, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setStepSize( float, int) ) );

    SliderWithEdit* smoothness = new SliderWithEdit( QString("smoothness") );
    smoothness->setMin( 0.0f );
    smoothness->setMax( 1.0f );
    smoothness->setValue( 0.0f );
    m_layout->addWidget( smoothness );
    connect( smoothness, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setSmoothness( float, int) ) );

    int numVoxels = ds->properties()->get( FNPROP_NX ).toInt() * ds->properties()->get( FNPROP_NY ).toInt() * ds->properties()->get( FNPROP_NZ ).toInt();

    m_progressBar = new QProgressBar( this );
    m_progressBar->setValue( 0 );
    m_progressBar->setMaximum( numVoxels );
    m_progressBar->hide();

    m_layout->addWidget( m_progressBar );

    hLayout->addStretch();
    hLayout->addWidget( m_startButton );

    m_layout->addLayout( hLayout );

    m_layout->addStretch();
    setLayout( m_layout );

}

TensorTrackWidget::~TensorTrackWidget()
{
}

QList<Dataset*> TensorTrackWidget::getFibs()
{
    QList<Dataset*> l;
    DatasetFibers* fibs = new DatasetFibers( m_tracker->getFibs() );
    l.push_back( fibs );
    return l;
}

void TensorTrackWidget::start()
{
    qDebug() << "tensor track widget start";
    m_startButton->hide();
    m_progressBar->show();
    m_tracker->startTracking();
}

void TensorTrackWidget::slotProgress()
{
    m_progressBar->setValue( m_progressBar->value() + 100 );
}

void TensorTrackWidget::slotFinished()
{
    emit( finished() );
}
<commit_msg>fix linux compilation<commit_after>/*
 * tensortrackwidget.cpp
 *
 *  Created on: 26.01.2013
 *      Author: Ralph
 */
#include <QtGui/QPushButton>
#include <QtGui/QProgressBar>

#include "sliderwithedit.h"
#include "sliderwitheditint.h"
#include "selectwithlabel.h"

#include "../../algos/track.h"
#include "../../data/datasets/dataset.h"
#include "../../data/datasets/datasetfibers.h"
#include "../../data/datasets/datasettensor.h"

#include "tensortrackwidget.h"

TensorTrackWidget::TensorTrackWidget( Dataset* ds, QList<QVariant> &dsl, QWidget* parent ) :
    m_progress( 0 )
{
    m_tracker = new Track( dynamic_cast<DatasetTensor*>( ds ) );
    connect( m_tracker, SIGNAL( progress() ), this, SLOT( slotProgress() ), Qt::QueuedConnection );
    connect( m_tracker, SIGNAL( finished() ), this, SLOT( slotFinished() ) );

    m_layout = new QVBoxLayout();
/*
    SelectWithLabel* sel = new SelectWithLabel( QString( "optional: mask (not yet implemented)" ), 1 );
    sel->insertItem( 0, QString("none") );
    for ( int k = 0; k < dsl.size(); ++k )
    {
        if ( dsl[k]->properties()->get( FNPROP_TYPE ).toInt() == FNDT_NIFTI_SCALAR )
        {
            sel->insertItem( k+1, dsl[k]->properties()->get( FNPROP_NAME ).toString() );
        }
    }
    m_layout->addWidget( sel );

    SelectWithLabel* sel2 = new SelectWithLabel( QString( "optional: roi (not yet implemented)" ), 1 );
    sel2->insertItem( 0, QString("none") );
    for ( int k = 0; k < dsl.size(); ++k )
    {
        if ( dsl[k]->properties()->get( FNPROP_TYPE ).toInt() == FNDT_NIFTI_SCALAR )
        {
            sel2->insertItem( k+1, dsl[k]->properties()->get( FNPROP_NAME ).toString() );
        }
    }
    m_layout->addWidget( sel2 );
*/
    QHBoxLayout* hLayout = new QHBoxLayout();
    m_startButton = new QPushButton( tr("Start") );
    connect( m_startButton, SIGNAL( clicked() ), this, SLOT( start() ) );

    SliderWithEdit* minFA = new SliderWithEdit( QString("min FA for Start Voxels") );
    minFA->setMin( 0.01f );
    minFA->setMax( 1.0f );
    minFA->setValue( 0.2f );
    m_layout->addWidget( minFA );
    connect( minFA, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setMinStartFA( float, int) ) );

    SliderWithEdit* stopFA = new SliderWithEdit( QString("min FA to keep tracking") );
    stopFA->setMin( 0.01f );
    stopFA->setMax( 1.0f );
    stopFA->setValue( 0.2f );
    m_layout->addWidget( stopFA );
    connect( stopFA, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setMinFA( float, int) ) );

    SliderWithEditInt* minLength = new SliderWithEditInt( QString("min length to keep fibers") );
    minLength->setMin( 1 );
    minLength->setMax( 200 );
    minLength->setValue( 10 );
    m_layout->addWidget( minLength );
    connect( minLength, SIGNAL( valueChanged( int, int) ), m_tracker, SLOT( setMinLength( int, int) ) );

    SliderWithEdit* setSize = new SliderWithEdit( QString("step size") );
    setSize->setMin( 0.01f );
    setSize->setMax( 2.0f );
    setSize->setValue( 1.0f );
    m_layout->addWidget( setSize );
    connect( setSize, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setStepSize( float, int) ) );

    SliderWithEdit* smoothness = new SliderWithEdit( QString("smoothness") );
    smoothness->setMin( 0.0f );
    smoothness->setMax( 1.0f );
    smoothness->setValue( 0.0f );
    m_layout->addWidget( smoothness );
    connect( smoothness, SIGNAL( valueChanged( float, int) ), m_tracker, SLOT( setSmoothness( float, int) ) );

    int numVoxels = ds->properties()->get( FNPROP_NX ).toInt() * ds->properties()->get( FNPROP_NY ).toInt() * ds->properties()->get( FNPROP_NZ ).toInt();

    m_progressBar = new QProgressBar( this );
    m_progressBar->setValue( 0 );
    m_progressBar->setMaximum( numVoxels );
    m_progressBar->hide();

    m_layout->addWidget( m_progressBar );

    hLayout->addStretch();
    hLayout->addWidget( m_startButton );

    m_layout->addLayout( hLayout );

    m_layout->addStretch();
    setLayout( m_layout );

}

TensorTrackWidget::~TensorTrackWidget()
{
}

QList<Dataset*> TensorTrackWidget::getFibs()
{
    QList<Dataset*> l;
    DatasetFibers* fibs = new DatasetFibers( m_tracker->getFibs() );
    l.push_back( fibs );
    return l;
}

void TensorTrackWidget::start()
{
    qDebug() << "tensor track widget start";
    m_startButton->hide();
    m_progressBar->show();
    m_tracker->startTracking();
}

void TensorTrackWidget::slotProgress()
{
    m_progressBar->setValue( m_progressBar->value() + 100 );
}

void TensorTrackWidget::slotFinished()
{
    emit( finished() );
}
<|endoftext|>


<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_STORAGE_ARCHIVE_HPP
#define OUZEL_STORAGE_ARCHIVE_HPP

#include <cstdint>
#include <fstream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "utils/Utils.hpp"

namespace ouzel
{
    namespace storage
    {
        class Archive final
        {
        public:
            Archive() = default;

            explicit Archive(const std::string& path):
                file{path, std::ios::binary}
            {
                constexpr std::uint32_t CENTRAL_DIRECTORY = 0x02014B50;
                constexpr std::uint32_t HEADER_SIGNATURE = 0x04034B50;

                for (;;)
                {
                    std::uint8_t signature[4];
                    file.read(reinterpret_cast<char*>(signature), sizeof(signature));

                    if (decodeLittleEndian<std::uint32_t>(signature) == CENTRAL_DIRECTORY)
                        break;

                    if (decodeLittleEndian<std::uint32_t>(signature) != HEADER_SIGNATURE)
                        throw std::runtime_error("Bad signature");

                    std::uint8_t version[2];

                    file.read(reinterpret_cast<char*>(version), sizeof(version));

                    std::uint16_t flags;

                    file.read(reinterpret_cast<char*>(&flags), sizeof(flags));

                    std::uint16_t compression;
                    file.read(reinterpret_cast<char*>(&compression), sizeof(compression));

                    if (compression != 0x00)
                        throw std::runtime_error("Unsupported compression");

                    file.seekg(4, std::ios::cur); // skip modification time
                    file.seekg(4, std::ios::cur); // skip CRC-32

                    std::uint8_t compressedSize[4];
                    file.read(reinterpret_cast<char*>(compressedSize), sizeof(compressedSize));

                    std::uint8_t uncompressedSize[4];
                    file.read(reinterpret_cast<char*>(uncompressedSize), sizeof(uncompressedSize));

                    std::uint8_t fileNameLength[2];
                    file.read(reinterpret_cast<char*>(fileNameLength), sizeof(fileNameLength));

                    std::uint8_t extraFieldLength[2];
                    file.read(reinterpret_cast<char*>(extraFieldLength), sizeof(extraFieldLength));

                    std::vector<char> name(decodeLittleEndian<std::uint16_t>(fileNameLength) + 1);

                    file.read(name.data(), decodeLittleEndian<std::uint16_t>(fileNameLength));

                    name[decodeLittleEndian<std::uint16_t>(fileNameLength)] = '\0';

                    Entry& entry = entries[name.data()];
                    entry.size = decodeLittleEndian<std::uint32_t>(uncompressedSize);

                    file.seekg(decodeLittleEndian<std::uint16_t>(extraFieldLength), std::ios::cur); // skip extra field

                    entry.offset = file.tellg();

                    file.seekg(static_cast<std::streamoff>(decodeLittleEndian<std::uint32_t>(uncompressedSize)),
                               std::ios::cur); // skip uncompressed size
                }
            }

            std::vector<std::uint8_t> readFile(const std::string& filename)
            {
                std::vector<std::uint8_t> data;

                auto i = entries.find(filename);

                if (i == entries.end())
                    throw std::runtime_error("File " + filename + " does not exist");

                file.seekg(i->second.offset, std::ios::beg);

                data.resize(i->second.size);

                file.read(reinterpret_cast<char*>(data.data()), static_cast<std::streamsize>(i->second.size));

                return data;
            }

            bool fileExists(const std::string& filename) const
            {
                return entries.find(filename) != entries.end();
            }

        private:
            std::ifstream file;

            struct Entry final
            {
                std::streamoff offset;
                std::size_t size;
            };

            std::map<std::string, Entry> entries;
        };
    } // namespace storage
} // namespace ouzel

#endif // OUZEL_STORAGE_ARCHIVE_HPP
<commit_msg>Always read bytes from zip<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_STORAGE_ARCHIVE_HPP
#define OUZEL_STORAGE_ARCHIVE_HPP

#include <cstdint>
#include <fstream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "utils/Utils.hpp"

namespace ouzel
{
    namespace storage
    {
        class Archive final
        {
        public:
            Archive() = default;

            explicit Archive(const std::string& path):
                file{path, std::ios::binary}
            {
                constexpr std::uint32_t CENTRAL_DIRECTORY = 0x02014B50;
                constexpr std::uint32_t HEADER_SIGNATURE = 0x04034B50;

                for (;;)
                {
                    std::uint8_t signature[4];
                    file.read(reinterpret_cast<char*>(signature), sizeof(signature));

                    if (decodeLittleEndian<std::uint32_t>(signature) == CENTRAL_DIRECTORY)
                        break;

                    if (decodeLittleEndian<std::uint32_t>(signature) != HEADER_SIGNATURE)
                        throw std::runtime_error("Bad signature");

                    std::uint8_t version[2];
                    file.read(reinterpret_cast<char*>(version), sizeof(version));

                    std::uint8_t flags[2];
                    file.read(reinterpret_cast<char*>(&flags), sizeof(flags));

                    std::uint8_t compression[2];
                    file.read(reinterpret_cast<char*>(&compression), sizeof(compression));

                    if (decodeLittleEndian<std::uint16_t>(compression) != 0x00)
                        throw std::runtime_error("Unsupported compression");

                    file.seekg(4, std::ios::cur); // skip modification time
                    file.seekg(4, std::ios::cur); // skip CRC-32

                    std::uint8_t compressedSize[4];
                    file.read(reinterpret_cast<char*>(compressedSize), sizeof(compressedSize));

                    std::uint8_t uncompressedSize[4];
                    file.read(reinterpret_cast<char*>(uncompressedSize), sizeof(uncompressedSize));

                    std::uint8_t fileNameLength[2];
                    file.read(reinterpret_cast<char*>(fileNameLength), sizeof(fileNameLength));

                    std::uint8_t extraFieldLength[2];
                    file.read(reinterpret_cast<char*>(extraFieldLength), sizeof(extraFieldLength));

                    std::vector<char> name(decodeLittleEndian<std::uint16_t>(fileNameLength) + 1);

                    file.read(name.data(), decodeLittleEndian<std::uint16_t>(fileNameLength));

                    name[decodeLittleEndian<std::uint16_t>(fileNameLength)] = '\0';

                    Entry& entry = entries[name.data()];
                    entry.size = decodeLittleEndian<std::uint32_t>(uncompressedSize);

                    file.seekg(decodeLittleEndian<std::uint16_t>(extraFieldLength), std::ios::cur); // skip extra field

                    entry.offset = file.tellg();

                    file.seekg(static_cast<std::streamoff>(decodeLittleEndian<std::uint32_t>(uncompressedSize)),
                               std::ios::cur); // skip uncompressed size
                }
            }

            std::vector<std::uint8_t> readFile(const std::string& filename)
            {
                std::vector<std::uint8_t> data;

                auto i = entries.find(filename);

                if (i == entries.end())
                    throw std::runtime_error("File " + filename + " does not exist");

                file.seekg(i->second.offset, std::ios::beg);

                data.resize(i->second.size);

                file.read(reinterpret_cast<char*>(data.data()), static_cast<std::streamsize>(i->second.size));

                return data;
            }

            bool fileExists(const std::string& filename) const
            {
                return entries.find(filename) != entries.end();
            }

        private:
            std::ifstream file;

            struct Entry final
            {
                std::streamoff offset;
                std::size_t size;
            };

            std::map<std::string, Entry> entries;
        };
    } // namespace storage
} // namespace ouzel

#endif // OUZEL_STORAGE_ARCHIVE_HPP
<|endoftext|>