<commit_before>#include <Shifty.h>

Shifty::Shifty() {
}

void Shifty::setBitCount(int bitCount) {
  this->bitCount = bitCount;
  this->byteCount = bitCount/8;
  for(int i = 0; i < this->byteCount; i++) {
    this->writeBuffer[i] = 0;
    this->dataModes[i] = 0;
    this->readBuffer[i] = 0;
  }
}

void Shifty::setPins(int dataPin, int clockPin, int latchPin, int readPin) {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(readPin, INPUT);
  this->dataPin = dataPin;
  this->clockPin = clockPin;
  this->latchPin = latchPin;
  if(readPin != -1) {
    this->readPin = readPin;
  }
}

void Shifty::setPins(int dataPin, int clockPin, int latchPin) {
  setPins(dataPin, clockPin, latchPin, -1);
}

void Shifty::batchWriteBegin() {
  batchWriteMode = true;
}

void Shifty::writeBit(int bitnum, bool value) {
  if(batchWriteMode) {
    writeBitSoft(bitnum, value);
  } else {
    writeBitHard(bitnum, value);
  }
}

void Shifty::batchWriteEnd() {
  writeAllBits();
  batchWriteMode = false;
}

void Shifty::batchReadBegin() {
  batchReadMode = true;
  readAllBits();
}

bool Shifty::readBit(int bitnum) {
  if(batchReadMode) {
    readBitSoft(bitnum);
  } else {
    readBitHard(bitnum);
  }
}

void Shifty::batchReadEnd() {
  batchReadMode = false;
}

void Shifty::bitMode(int bitnum, bool mode) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;
  byte b = this->dataModes[bytenum];
  bitSet(b, offset);
  this->dataModes[bytenum] = b;
}

void Shifty::writeBitSoft(int bitnum, bool value) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;
  byte b = this->writeBuffer[bytenum];
  bitWrite(b, offset, value);
  this->writeBuffer[bytenum] = b;
}

void Shifty::writeBitHard(int bitnum, bool value) {
  writeBitSoft(bitnum, value);
  writeAllBits();
}

void Shifty::writeAllBits() {
  digitalWrite(latchPin, LOW);
  digitalWrite(clockPin, LOW);
  for(int i = 0; i < this->byteCount; i++) {
    shiftOut(dataPin, clockPin, MSBFIRST, this->writeBuffer[i]);
  }
  digitalWrite(latchPin, HIGH);
}

bool Shifty::readBitSoft(int bitnum) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;

  return bitRead(this->readBuffer[bytenum], offset);
}

bool Shifty::readBitHard(int bitnum) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;

  // To read the bit, set all output pins except the pin we are looking at to 0
  for(int i = 0; i < this->byteCount; i++) {
    byte mask = this->dataModes[i];
    byte outb = this->writeBuffer[i];
    for(int j = 0; j < 8; j++) {
      if(bitRead(mask, j)) {
        if(i == bytenum && j == bitnum) {
          bitSet(outb, j);
        } else {
          bitClear(outb, j);
        }
      }
    }
  }

  // Flush
  writeAllBits();

  // Get our data pin
  bool value = digitalRead(this->readPin);

  // Set the cached value
  byte cacheb = this->readBuffer[bytenum];
  bitWrite(cacheb, offset, value);
  this->readBuffer[bytenum] = cacheb;
}

void Shifty::readAllBits() {
  for(int i = 0; i < this->byteCount; i++) {
    byte mask = this->dataModes[i];
    byte outb = this->writeBuffer[i];
    byte inb = 0;
    for(int j = 0; j < 8; j++) {
      if(bitRead(mask, j)) {
        readBitHard(i * 8 + j);
      }
    }
  }
}
<commit_msg>Fixed bugs in reading bits<commit_after>#include <Shifty.h>

Shifty::Shifty() {
}

void Shifty::setBitCount(int bitCount) {
  this->bitCount = bitCount;
  this->byteCount = bitCount/8;
  for(int i = 0; i < this->byteCount; i++) {
    this->writeBuffer[i] = 0;
    this->dataModes[i] = 0;
    this->readBuffer[i] = 0;
  }
}

void Shifty::setPins(int dataPin, int clockPin, int latchPin, int readPin) {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(readPin, INPUT);
  this->dataPin = dataPin;
  this->clockPin = clockPin;
  this->latchPin = latchPin;
  if(readPin != -1) {
    this->readPin = readPin;
  }
}

void Shifty::setPins(int dataPin, int clockPin, int latchPin) {
  setPins(dataPin, clockPin, latchPin, -1);
}

void Shifty::batchWriteBegin() {
  batchWriteMode = true;
}

void Shifty::writeBit(int bitnum, bool value) {
  if(batchWriteMode) {
    writeBitSoft(bitnum, value);
  } else {
    writeBitHard(bitnum, value);
  }
}

void Shifty::batchWriteEnd() {
  writeAllBits();
  batchWriteMode = false;
}

void Shifty::batchReadBegin() {
  batchReadMode = true;
  readAllBits();
}

bool Shifty::readBit(int bitnum) {
  if(batchReadMode) {
    return readBitSoft(bitnum);
  } else {
    return readBitHard(bitnum);
  }
}

void Shifty::batchReadEnd() {
  batchReadMode = false;
}

void Shifty::bitMode(int bitnum, bool mode) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;
  byte b = this->dataModes[bytenum];
  bitSet(b, offset);
  this->dataModes[bytenum] = b;
}

void Shifty::writeBitSoft(int bitnum, bool value) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;
  byte b = this->writeBuffer[bytenum];
  bitWrite(b, offset, value);
  this->writeBuffer[bytenum] = b;
}

void Shifty::writeBitHard(int bitnum, bool value) {
  writeBitSoft(bitnum, value);
  writeAllBits();
}

void Shifty::writeAllBits() {
  digitalWrite(latchPin, LOW);
  digitalWrite(clockPin, LOW);
  for(int i = 0; i < this->byteCount; i++) {
    shiftOut(dataPin, clockPin, MSBFIRST, this->writeBuffer[i]);
  }
  digitalWrite(latchPin, HIGH);
}

bool Shifty::readBitSoft(int bitnum) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;

  return bitRead(this->readBuffer[bytenum], offset);
}

bool Shifty::readBitHard(int bitnum) {
  int bytenum = bitnum / 8;
  int offset = bitnum % 8;

  // To read the bit, set all output pins except the pin we are looking at to 0
  for(int i = 0; i < this->byteCount; i++) {
    byte mask = this->dataModes[i];
    byte outb = this->writeBuffer[i];
    for(int j = 0; j < 8; j++) {
      if(bitRead(mask, j)) {
        if(i == bytenum && j == bitnum) {
          bitSet(outb, j);
        } else {
          bitClear(outb, j);
        }
      }
    }
  }

  // Flush
  writeAllBits();

  // Get our data pin
  bool value = digitalRead(this->readPin);

  // Set the cached value
  byte cacheb = this->readBuffer[bytenum];
  bitWrite(cacheb, offset, value);
  this->readBuffer[bytenum] = cacheb;

  return value;
}

void Shifty::readAllBits() {
  for(int i = 0; i < this->byteCount; i++) {
    byte mask = this->dataModes[i];
    byte outb = this->writeBuffer[i];
    byte inb = 0;
    for(int j = 0; j < 8; j++) {
      if(bitRead(mask, j)) {
        readBitHard(i * 8 + j);
      }
    }
  }
}
<|endoftext|>


<commit_before>
/*
 *  Stream.hpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

#ifndef SFEMOVIE_STREAM_HPP
#define SFEMOVIE_STREAM_HPP

#include "Macros.hpp"
#include "Timer.hpp"
#include <list>
#include <memory>
#include <SFML/System.hpp>
#include <sfeMovie/Movie.hpp>

extern "C"
{
#include <libavformat/avformat.h>
}

namespace sfe
{
    class Stream : public Timer::Observer
    {
    public:
        struct DataSource
        {
            virtual void requestMoreData(Stream& starvingStream) = 0;
            virtual void resetEndOfFileStatus() = 0;
        };

        /** @return a textual description of the given FFmpeg stream
         */
        static std::string AVStreamDescription(AVStream* stream);

        /** Create a stream from the given FFmpeg stream
         *
         * At the end of the constructor, the stream is guaranteed
         * to have all of its fields set and the decoder loaded
         *
         * @param stream the FFmpeg stream
         * @param dataSource the encoded data provider for this stream
         */
        Stream(AVFormatContext*& formatCtx, AVStream*& stream, DataSource& dataSource, std::shared_ptr<Timer> timer);

        /** Default destructor
         */
        virtual ~Stream();

        /** Connect this stream against the reference timer to receive playback events; this allows this
         * stream to be played
         */
        void connect();

        /** Disconnect this stream from the reference timer ; this disables this stream
         */
        void disconnect();

        /** Called by the demuxer to provide the stream with encoded data
         *
         * @return packet the encoded data usable by this stream
         */
        virtual void pushEncodedData(AVPacket* packet);

        /** Reinsert an AVPacket at the beginning of the queue
         *
         * This is used for packets that contain several frames, but whose next frames
         * cannot be decoded yet. These packets are repushed to be decoded when possible.
         *
         * @param packet the packet to re-insert at the beginning of the queue
         */
        virtual void prependEncodedData(AVPacket* packet);

        /** Return the oldest encoded data that was pushed to this stream
         *
         * If no packet is stored when this method is called, it will ask the
         * data source to feed this stream first
         *
         * @return the oldest encoded data, or nullptr if no data could be read from the media
         */
        virtual AVPacket* popEncodedData();

        /** Empty the encoded data queue, destroy all the packets and flush the decoding pipeline
         */
        virtual void flushBuffers();

        /** Used by the demuxer to know if this stream should be fed with more data
         *
         * The default implementation returns true if the packet list contains less than 10 packets
         *
         * @return true if the demuxer should give more data to this stream, false otherwise
         */
        virtual bool needsMoreData() const;

        /** Get the stream kind (either audio, video or subtitle stream)
         *
         * @return the kind of stream represented by this stream
         */
        virtual MediaType getStreamKind() const;

        /** Give the stream's status
         *
         * @return The stream's status (Playing, Paused or Stopped)
         */
        Status getStatus() const;

        /** Return the stream's language code
         *
         * @return the language code of the stream as ISO 639-2 format
         */
        std::string getLanguage() const;

        /** Compute the stream position in the media, by possibly fetching a packet
         */
        sf::Time computePosition();

        /** @return a textual description of the current stream
         */
        std::string description() const;

        /** Update the current stream's status and eventually decode frames
         */
        virtual void update() = 0;

        /** @return true if the given packet is for the current stream
         */
        bool canUsePacket(AVPacket* packet) const;

        /** @return true if this stream never requests packets and let
         * itself be fed, false otherwise. Default implementation always
         * returns false
         */
        virtual bool isPassive() const;
    protected:
        // Timer::Observer interface
        void didPlay(const Timer& timer, Status previousStatus) override;
        void didPause(const Timer& timer, Status previousStatus) override;
        void didStop(const Timer& timer, Status previousStatus) override;

        /** @return true if any raw packet for the current stream is queued
         */
        bool hasPackets();

        void setStatus(Status status);

        AVFormatContext* & m_formatCtx;
        AVStream*& m_stream;

        DataSource& m_dataSource;
        std::shared_ptr<Timer> m_timer;
        AVCodec* m_codec;
        int m_streamID;
        std::string m_language;
        std::list <AVPacket*> m_packetList;
        Status m_status;
        sf::Mutex m_readerMutex;
    };
}

#endif
<commit_msg>#6 Added API for fast-forwarding streams (must be implemented ; will break build for now)<commit_after>
/*
 *  Stream.hpp
 *  sfeMovie project
 *
 *  Copyright (C) 2010-2014 Lucas Soltic
 *  lucas.soltic@orange.fr
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

#ifndef SFEMOVIE_STREAM_HPP
#define SFEMOVIE_STREAM_HPP

#include "Macros.hpp"
#include "Timer.hpp"
#include <list>
#include <memory>
#include <SFML/System.hpp>
#include <sfeMovie/Movie.hpp>

extern "C"
{
#include <libavformat/avformat.h>
}

namespace sfe
{
    class Stream : public Timer::Observer
    {
    public:
        struct DataSource
        {
            virtual void requestMoreData(Stream& starvingStream) = 0;
            virtual void resetEndOfFileStatus() = 0;
        };

        /** @return a textual description of the given FFmpeg stream
         */
        static std::string AVStreamDescription(AVStream* stream);

        /** Create a stream from the given FFmpeg stream
         *
         * At the end of the constructor, the stream is guaranteed
         * to have all of its fields set and the decoder loaded
         *
         * @param stream the FFmpeg stream
         * @param dataSource the encoded data provider for this stream
         */
        Stream(AVFormatContext*& formatCtx, AVStream*& stream, DataSource& dataSource, std::shared_ptr<Timer> timer);

        /** Default destructor
         */
        virtual ~Stream();

        /** Connect this stream against the reference timer to receive playback events; this allows this
         * stream to be played
         */
        void connect();

        /** Disconnect this stream from the reference timer ; this disables this stream
         */
        void disconnect();

        /** Called by the demuxer to provide the stream with encoded data
         *
         * @return packet the encoded data usable by this stream
         */
        virtual void pushEncodedData(AVPacket* packet);

        /** Reinsert an AVPacket at the beginning of the queue
         *
         * This is used for packets that contain several frames, but whose next frames
         * cannot be decoded yet. These packets are repushed to be decoded when possible.
         *
         * @param packet the packet to re-insert at the beginning of the queue
         */
        virtual void prependEncodedData(AVPacket* packet);

        /** Return the oldest encoded data that was pushed to this stream
         *
         * If no packet is stored when this method is called, it will ask the
         * data source to feed this stream first
         *
         * @return the oldest encoded data, or nullptr if no data could be read from the media
         */
        virtual AVPacket* popEncodedData();

        /** Empty the encoded data queue, destroy all the packets and flush the decoding pipeline
         */
        virtual void flushBuffers();

        /** Used by the demuxer to know if this stream should be fed with more data
         *
         * The default implementation returns true if the packet list contains less than 10 packets
         *
         * @return true if the demuxer should give more data to this stream, false otherwise
         */
        virtual bool needsMoreData() const;

        /** Get the stream kind (either audio, video or subtitle stream)
         *
         * @return the kind of stream represented by this stream
         */
        virtual MediaType getStreamKind() const;

        /** Give the stream's status
         *
         * @return The stream's status (Playing, Paused or Stopped)
         */
        Status getStatus() const;

        /** Return the stream's language code
         *
         * @return the language code of the stream as ISO 639-2 format
         */
        std::string getLanguage() const;

        /** Compute the stream position in the media, by possibly fetching a packet
         */
        sf::Time computePosition();

        /** Discard the data not needed to start playback at the given position
         *
         * Every single bit of unneeded data must be discarded as streams synchronization accuracy will
         * depend on this
         *
         * @param targetPosition the position for which the stream is expected to be ready to play
         */
        virtual void fastForward(sf::Time targetPosition) = 0;

        /** @return a textual description of the current stream
         */
        std::string description() const;

        /** Update the current stream's status and eventually decode frames
         */
        virtual void update() = 0;

        /** @return true if the given packet is for the current stream
         */
        bool canUsePacket(AVPacket* packet) const;

        /** @return true if this stream never requests packets and let
         * itself be fed, false otherwise. Default implementation always
         * returns false
         */
        virtual bool isPassive() const;
    protected:
        // Timer::Observer interface
        void didPlay(const Timer& timer, Status previousStatus) override;
        void didPause(const Timer& timer, Status previousStatus) override;
        void didStop(const Timer& timer, Status previousStatus) override;

        /** @return true if any raw packet for the current stream is queued
         */
        bool hasPackets();

        void setStatus(Status status);

        AVFormatContext* & m_formatCtx;
        AVStream*& m_stream;

        DataSource& m_dataSource;
        std::shared_ptr<Timer> m_timer;
        AVCodec* m_codec;
        int m_streamID;
        std::string m_language;
        std::list <AVPacket*> m_packetList;
        Status m_status;
        sf::Mutex m_readerMutex;
    };
}

#endif
<|endoftext|>


<commit_before>#include "ExecutionEngine.h"

#include <chrono>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>

#pragma GCC diagnostic pop

#include "Runtime.h"
#include "Memory.h"
#include "Stack.h"
#include "Type.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	if (auto cachedExec = Cache::findExec(key))
	{
		return run(*cachedExec, _data, _env);
	}

	auto module = Compiler({}).compile(_code);
	return run(std::move(module), _data, _env, _code);
}

ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code)
{
	auto module = _module.get(); // Keep ownership of the module in _module

	llvm::sys::PrintStackTraceOnErrorSignal();
	static const auto program = "EVM JIT";
	llvm::PrettyStackTraceProgram X(1, &program);

	auto&& context = llvm::getGlobalContext();

	llvm::InitializeNativeTarget();
	llvm::InitializeNativeTargetAsmPrinter();
	llvm::InitializeNativeTargetAsmParser();

	std::string errorMsg;
	llvm::EngineBuilder builder(module);
	//builder.setMArch(MArch);
	//builder.setMCPU(MCPU);
	//builder.setMAttrs(MAttrs);
	//builder.setRelocationModel(RelocModel);
	//builder.setCodeModel(CMModel);
	builder.setErrorStr(&errorMsg);
	builder.setEngineKind(llvm::EngineKind::JIT);
	builder.setUseMCJIT(true);
	builder.setMCJITMemoryManager(new llvm::SectionMemoryManager());
	builder.setOptLevel(llvm::CodeGenOpt::None);

	auto triple = llvm::Triple(llvm::sys::getProcessTriple());
	if (triple.getOS() == llvm::Triple::OSType::Win32)
		triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);    // MCJIT does not support COFF format
	module->setTargetTriple(triple.str());

	ExecBundle exec;
	exec.engine.reset(builder.create());
	if (!exec.engine)
		return ReturnCode::LLVMConfigError;
	_module.release();  // Successfully created llvm::ExecutionEngine takes ownership of the module

	auto finalizationStartTime = std::chrono::high_resolution_clock::now();
	exec.engine->finalizeObject();
	auto finalizationEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	exec.entryFunc = module->getFunction("main");
	if (!exec.entryFunc)
		return ReturnCode::LLVMLinkError;

	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	auto& cachedExec = Cache::registerExec(key, std::move(exec));
	auto returnCode = run(cachedExec, _data, _env);

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms ";
	//clog(JIT) << "Max stack size: " << Stack::maxStackSize;

	clog(JIT) << "\n";

	return returnCode;
}

ReturnCode ExecutionEngine::run(ExecBundle const& _exec, RuntimeData* _data, Env* _env)
{
	ReturnCode returnCode;
	Runtime runtime(_data, _env);

	auto r = setjmp(runtime.getJmpBuf());
	if (r == 0)
	{
		auto result = _exec.engine->runFunction(_exec.entryFunc, {{}, llvm::GenericValue(&runtime)});
		returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
	}
	else
		returnCode = static_cast<ReturnCode>(r);

	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();

		auto&& log = clog(JIT);
		log << "RETURN [ ";
		for (auto it = returnData.begin(), end = returnData.end(); it != end; ++it)
			log << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
		log << "]";
	}
	else
		clog(JIT) << "RETURN " << (int)returnCode;

	return returnCode;
}

}
}
}
<commit_msg>Change the way entry function is called.<commit_after>#include "ExecutionEngine.h"

#include <chrono>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>

#pragma GCC diagnostic pop

#include "Runtime.h"
#include "Memory.h"
#include "Stack.h"
#include "Type.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	if (auto cachedExec = Cache::findExec(key))
	{
		return run(*cachedExec, _data, _env);
	}

	auto module = Compiler({}).compile(_code);
	return run(std::move(module), _data, _env, _code);
}

ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code)
{
	auto module = _module.get(); // Keep ownership of the module in _module

	llvm::sys::PrintStackTraceOnErrorSignal();
	static const auto program = "EVM JIT";
	llvm::PrettyStackTraceProgram X(1, &program);

	auto&& context = llvm::getGlobalContext();

	llvm::InitializeNativeTarget();
	llvm::InitializeNativeTargetAsmPrinter();
	llvm::InitializeNativeTargetAsmParser();

	std::string errorMsg;
	llvm::EngineBuilder builder(module);
	//builder.setMArch(MArch);
	//builder.setMCPU(MCPU);
	//builder.setMAttrs(MAttrs);
	//builder.setRelocationModel(RelocModel);
	//builder.setCodeModel(CMModel);
	builder.setErrorStr(&errorMsg);
	builder.setEngineKind(llvm::EngineKind::JIT);
	builder.setUseMCJIT(true);
	builder.setMCJITMemoryManager(new llvm::SectionMemoryManager());
	builder.setOptLevel(llvm::CodeGenOpt::None);

	auto triple = llvm::Triple(llvm::sys::getProcessTriple());
	if (triple.getOS() == llvm::Triple::OSType::Win32)
		triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);    // MCJIT does not support COFF format
	module->setTargetTriple(triple.str());

	ExecBundle exec;
	exec.engine.reset(builder.create());
	if (!exec.engine)
		return ReturnCode::LLVMConfigError;
	_module.release();  // Successfully created llvm::ExecutionEngine takes ownership of the module

	auto finalizationStartTime = std::chrono::high_resolution_clock::now();
	exec.engine->finalizeObject();
	auto finalizationEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	exec.entryFunc = module->getFunction("main");
	if (!exec.entryFunc)
		return ReturnCode::LLVMLinkError;

	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	auto& cachedExec = Cache::registerExec(key, std::move(exec));
	auto returnCode = run(cachedExec, _data, _env);

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms ";
	//clog(JIT) << "Max stack size: " << Stack::maxStackSize;

	clog(JIT) << "\n";

	return returnCode;
}

ReturnCode ExecutionEngine::run(ExecBundle const& _exec, RuntimeData* _data, Env* _env)
{
	ReturnCode returnCode;
	Runtime runtime(_data, _env);

	std::vector<llvm::GenericValue> args{{}, llvm::GenericValue(&runtime)};
	llvm::GenericValue result;

	typedef ReturnCode(*EntryFuncPtr)(int, Runtime*);

	auto entryFuncVoidPtr = _exec.engine->getPointerToFunction(_exec.entryFunc);
	auto entryFuncPtr = static_cast<EntryFuncPtr>(entryFuncVoidPtr);

	auto r = setjmp(runtime.getJmpBuf());
	if (r == 0)
	{
		returnCode = entryFuncPtr(0, &runtime);
	}
	else
		returnCode = static_cast<ReturnCode>(r);

	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();

		auto&& log = clog(JIT);
		log << "RETURN [ ";
		for (auto it = returnData.begin(), end = returnData.end(); it != end; ++it)
			log << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
		log << "]";
	}
	else
		clog(JIT) << "RETURN " << (int)returnCode;

	return returnCode;
}

}
}
}
<|endoftext|>


<commit_before>#ifndef RDB_PROTOCOL_CHANGEFEED_HPP_
#define RDB_PROTOCOL_CHANGEFEED_HPP_

#include <deque>
#include <exception>
#include <map>

#include "errors.hpp"

#include <boost/variant.hpp>

#include "concurrency/rwlock.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "protocol_api.hpp"
#include "repli_timestamp.hpp"
#include "rpc/connectivity/connectivity.hpp"
#include "rpc/mailbox/typed.hpp"
#include "rpc/serialize_macros.hpp"

class auto_drainer_t;
class base_namespace_repo_t;
class mailbox_manager_t;
struct rdb_modification_report_t;

namespace ql {

class base_exc_t;
class batcher_t;
class changefeed_t;
class datum_stream_t;
class datum_t;
class env_t;
class table_t;

namespace changefeed {

struct msg_t {
    struct change_t {
        change_t();
        explicit change_t(counted_t<const datum_t> _old_val,
                          counted_t<const datum_t> _new_val);
        ~change_t();
        counted_t<const datum_t> old_val, new_val;
        RDB_DECLARE_ME_SERIALIZABLE;
    };
    struct stop_t { RDB_DECLARE_ME_SERIALIZABLE; };

    msg_t() { }
    msg_t(msg_t &&msg);
    msg_t(const msg_t &msg) = default;
    explicit msg_t(stop_t &&op);
    explicit msg_t(change_t &&op);

    // Starts with STOP to avoid doing work for default initialization.
    boost::variant<stop_t, change_t> op;

    RDB_DECLARE_ME_SERIALIZABLE;
};

class feed_t;
struct stamped_msg_t;

// The `client_t` exists on the machine handling the changefeed query, in the
// `rdb_context_t`.  When a query subscribes to the changes on a table, it
// should call `new_feed`.  The `client_t` will give it back a stream of rows.
// The `client_t` does this by maintaining an internal map from table UUIDs to
// `feed_t`s.  (It does this so that there is at most one `feed_t` per <table,
// client> pair, to prevent redundant cluster messages.)  The actual logic for
// subscribing to a changefeed server and distributing writes to streams can be
// found in the `feed_t` class.
class client_t : public home_thread_mixin_t {
public:
    typedef mailbox_addr_t<void(stamped_msg_t)> addr_t;
    client_t(mailbox_manager_t *_manager);
    ~client_t();
    // Throws QL exceptions.
    counted_t<datum_stream_t> new_feed(const counted_t<table_t> &tbl, env_t *env);
    void maybe_remove_feed(const uuid_u &uuid);
    scoped_ptr_t<feed_t> detach_feed(const uuid_u &uuid);
private:
    friend class sub_t;
    mailbox_manager_t *const manager;
    std::map<uuid_u, scoped_ptr_t<feed_t> > feeds;
    // This lock manages access to the `feeds` map.  The `feeds` map needs to be
    // read whenever `new_feed` is called, and needs to be written to whenever
    // `new_feed` is called with a table not already in the `feeds` map, or
    // whenever `maybe_remove_feed` or `detach_feed` is called.
    rwlock_t feeds_lock;
    auto_drainer_t drainer;
};

// There is one `server_t` per `store_t`, and it is used to send changes that
// occur on that `store_t` to any subscribed `feed_t`s contained in a
// `client_t`.
class server_t {
public:
    typedef mailbox_addr_t<void(client_t::addr_t)> addr_t;
    server_t(mailbox_manager_t *_manager);
    void add_client(const client_t::addr_t &addr);
    void send_all(msg_t msg);
    addr_t get_stop_addr();
    uint64_t get_stamp(const client_t::addr_t &addr);
    uuid_u get_uuid();
private:
    void stop_mailbox_cb(client_t::addr_t addr);
    void add_client_cb(signal_t *stopped, client_t::addr_t addr);

    // The UUID of the server, used so that `feed_t`s can order changefeed
    // messages on a per-server basis (and drop changefeed messages from before
    // their own creation timestamp on a per-server basis).
    const uuid_u uuid;
    mailbox_manager_t *const manager;

    struct client_info_t {
        scoped_ptr_t<cond_t> cond;
        uint64_t stamp;
    };
    std::map<client_t::addr_t, client_info_t> clients;
    rwlock_t clients_lock;

    mailbox_t<void(client_t::addr_t)> stop_mailbox;
    auto_drainer_t drainer;
};

} // namespace changefeed
} // namespace ql

#endif // RDB_PROTOCOL_CHANGEFEED_HPP_
<commit_msg>Added comments.<commit_after>#ifndef RDB_PROTOCOL_CHANGEFEED_HPP_
#define RDB_PROTOCOL_CHANGEFEED_HPP_

#include <deque>
#include <exception>
#include <map>

#include "errors.hpp"

#include <boost/variant.hpp>

#include "concurrency/rwlock.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "protocol_api.hpp"
#include "repli_timestamp.hpp"
#include "rpc/connectivity/connectivity.hpp"
#include "rpc/mailbox/typed.hpp"
#include "rpc/serialize_macros.hpp"

class auto_drainer_t;
class base_namespace_repo_t;
class mailbox_manager_t;
struct rdb_modification_report_t;

namespace ql {

class base_exc_t;
class batcher_t;
class changefeed_t;
class datum_stream_t;
class datum_t;
class env_t;
class table_t;

namespace changefeed {

struct msg_t {
    struct change_t {
        change_t();
        explicit change_t(counted_t<const datum_t> _old_val,
                          counted_t<const datum_t> _new_val);
        ~change_t();
        counted_t<const datum_t> old_val, new_val;
        RDB_DECLARE_ME_SERIALIZABLE;
    };
    struct stop_t { RDB_DECLARE_ME_SERIALIZABLE; };

    msg_t() { }
    msg_t(msg_t &&msg);
    msg_t(const msg_t &msg) = default;
    explicit msg_t(stop_t &&op);
    explicit msg_t(change_t &&op);

    // Starts with STOP to avoid doing work for default initialization.
    boost::variant<stop_t, change_t> op;

    RDB_DECLARE_ME_SERIALIZABLE;
};

class feed_t;
struct stamped_msg_t;

// The `client_t` exists on the machine handling the changefeed query, in the
// `rdb_context_t`.  When a query subscribes to the changes on a table, it
// should call `new_feed`.  The `client_t` will give it back a stream of rows.
// The `client_t` does this by maintaining an internal map from table UUIDs to
// `feed_t`s.  (It does this so that there is at most one `feed_t` per <table,
// client> pair, to prevent redundant cluster messages.)  The actual logic for
// subscribing to a changefeed server and distributing writes to streams can be
// found in the `feed_t` class.
class client_t : public home_thread_mixin_t {
public:
    typedef mailbox_addr_t<void(stamped_msg_t)> addr_t;
    client_t(mailbox_manager_t *_manager);
    ~client_t();
    // Throws QL exceptions.
    counted_t<datum_stream_t> new_feed(const counted_t<table_t> &tbl, env_t *env);
    void maybe_remove_feed(const uuid_u &uuid);
    scoped_ptr_t<feed_t> detach_feed(const uuid_u &uuid);
private:
    friend class sub_t;
    mailbox_manager_t *const manager;
    std::map<uuid_u, scoped_ptr_t<feed_t> > feeds;
    // This lock manages access to the `feeds` map.  The `feeds` map needs to be
    // read whenever `new_feed` is called, and needs to be written to whenever
    // `new_feed` is called with a table not already in the `feeds` map, or
    // whenever `maybe_remove_feed` or `detach_feed` is called.
    rwlock_t feeds_lock;
    auto_drainer_t drainer;
};

// There is one `server_t` per `store_t`, and it is used to send changes that
// occur on that `store_t` to any subscribed `feed_t`s contained in a
// `client_t`.
class server_t {
public:
    typedef mailbox_addr_t<void(client_t::addr_t)> addr_t;
    server_t(mailbox_manager_t *_manager);
    void add_client(const client_t::addr_t &addr);
    void send_all(msg_t msg);
    addr_t get_stop_addr();
    uint64_t get_stamp(const client_t::addr_t &addr);
    uuid_u get_uuid();
private:
    void stop_mailbox_cb(client_t::addr_t addr);
    void add_client_cb(signal_t *stopped, client_t::addr_t addr);

    // The UUID of the server, used so that `feed_t`s can order changefeed
    // messages on a per-server basis (and drop changefeed messages from before
    // their own creation timestamp on a per-server basis).
    const uuid_u uuid;
    mailbox_manager_t *const manager;

    struct client_info_t {
        scoped_ptr_t<cond_t> cond;
        uint64_t stamp;
    };
    std::map<client_t::addr_t, client_info_t> clients;
    // Controls access to `clients`.  A `server_t` needs to read `clients` when:
    // * `send_all` is called
    // * `get_tamp` is called
    // And needs to write to clients when:
    // * `add_client` is called
    // * A message is received at `stop_mailbox` unsubscribing a client
    // A lock is needed because e.g. `send_all` calls `send`, which can block,
    // while looping over `clients`, and we need to make sure the map doesn't
    // change under it.
    rwlock_t clients_lock;

    mailbox_t<void(client_t::addr_t)> stop_mailbox;
    auto_drainer_t drainer;
};

} // namespace changefeed
} // namespace ql

#endif // RDB_PROTOCOL_CHANGEFEED_HPP_
<|endoftext|>


<commit_before>#ifndef RDB_PROTOCOL_CHANGEFEED_HPP_
#define RDB_PROTOCOL_CHANGEFEED_HPP_

#include <deque>
#include <exception>
#include <map>

#include "errors.hpp"

#include <boost/variant.hpp>

#include "concurrency/rwlock.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "protocol_api.hpp"
#include "repli_timestamp.hpp"
#include "rpc/connectivity/connectivity.hpp"
#include "rpc/mailbox/typed.hpp"
#include "rpc/serialize_macros.hpp"

class auto_drainer_t;
class base_namespace_repo_t;
class mailbox_manager_t;
struct rdb_modification_report_t;

namespace ql {

class base_exc_t;
class batcher_t;
class changefeed_t;
class datum_stream_t;
class datum_t;
class env_t;
class table_t;

namespace changefeed {

struct msg_t {
    struct change_t {
        change_t();
        explicit change_t(counted_t<const datum_t> _old_val,
                          counted_t<const datum_t> _new_val);
        ~change_t();
        counted_t<const datum_t> old_val, new_val;
        RDB_DECLARE_ME_SERIALIZABLE;
    };
    struct stop_t { RDB_DECLARE_ME_SERIALIZABLE; };

    msg_t() { }
    msg_t(msg_t &&msg);
    msg_t(const msg_t &msg) = default;
    explicit msg_t(stop_t &&op);
    explicit msg_t(change_t &&op);

    // Starts with STOP to avoid doing work for default initialization.
    boost::variant<stop_t, change_t> op;

    RDB_DECLARE_ME_SERIALIZABLE;
};

class feed_t;
struct stamped_msg_t;

// The `client_t` exists on the machine handling the changefeed query, in the
// `rdb_context_t`.  When a query subscribes to the changes on a table, it
// should call `new_feed`.  The `client_t` will give it back a stream of rows.
// The `client_t` does this by maintaining an internal map from table UUIDs to
// `feed_t`s.  (It does this so that there is at most one `feed_t` per <table,
// client> pair, to prevent redundant cluster messages.)  The actual logic for
// subscribing to a changefeed server and distributing writes to streams can be
// found in the `feed_t` class.
class client_t : public home_thread_mixin_t {
public:
    typedef mailbox_addr_t<void(stamped_msg_t)> addr_t;
    client_t(mailbox_manager_t *_manager);
    ~client_t();
    // Throws QL exceptions.
    counted_t<datum_stream_t> new_feed(const counted_t<table_t> &tbl, env_t *env);
    void maybe_remove_feed(const uuid_u &uuid);
    scoped_ptr_t<feed_t> detach_feed(const uuid_u &uuid);
private:
    friend class sub_t;
    mailbox_manager_t *manager;
    std::map<uuid_u, scoped_ptr_t<feed_t> > feeds;
    // This lock manages access to the `feeds` map.  The `feeds` map needs to be
    // read whenever `new_feed` is called, and needs to be written to whenever
    // `new_feed` is called with a table not already in the `feeds` map, or
    // whenever `maybe_remove_feed` or `detach_feed` is called.
    rwlock_t feeds_lock;
    auto_drainer_t drainer;
};

class server_t {
public:
    typedef mailbox_addr_t<void(client_t::addr_t)> addr_t;
    server_t(mailbox_manager_t *_manager);
    void add_client(const client_t::addr_t &addr);
    void send_all(msg_t msg);
    addr_t get_stop_addr();
    uint64_t get_stamp(const client_t::addr_t &addr);
    uuid_u get_uuid();
private:
    void stop_mailbox_cb(client_t::addr_t addr);
    void add_client_cb(signal_t *stopped, client_t::addr_t addr);

    uuid_u uuid;
    mailbox_manager_t *manager;

    struct client_info_t {
        scoped_ptr_t<cond_t> cond;
        uint64_t stamp;
    };
    std::map<client_t::addr_t, client_info_t> clients;
    rwlock_t clients_lock;

    mailbox_t<void(client_t::addr_t)> stop_mailbox;
    auto_drainer_t drainer;
};

} // namespace changefeed
} // namespace ql

#endif // RDB_PROTOCOL_CHANGEFEED_HPP_
<commit_msg>Added comments.<commit_after>#ifndef RDB_PROTOCOL_CHANGEFEED_HPP_
#define RDB_PROTOCOL_CHANGEFEED_HPP_

#include <deque>
#include <exception>
#include <map>

#include "errors.hpp"

#include <boost/variant.hpp>

#include "concurrency/rwlock.hpp"
#include "containers/counted.hpp"
#include "containers/scoped.hpp"
#include "protocol_api.hpp"
#include "repli_timestamp.hpp"
#include "rpc/connectivity/connectivity.hpp"
#include "rpc/mailbox/typed.hpp"
#include "rpc/serialize_macros.hpp"

class auto_drainer_t;
class base_namespace_repo_t;
class mailbox_manager_t;
struct rdb_modification_report_t;

namespace ql {

class base_exc_t;
class batcher_t;
class changefeed_t;
class datum_stream_t;
class datum_t;
class env_t;
class table_t;

namespace changefeed {

struct msg_t {
    struct change_t {
        change_t();
        explicit change_t(counted_t<const datum_t> _old_val,
                          counted_t<const datum_t> _new_val);
        ~change_t();
        counted_t<const datum_t> old_val, new_val;
        RDB_DECLARE_ME_SERIALIZABLE;
    };
    struct stop_t { RDB_DECLARE_ME_SERIALIZABLE; };

    msg_t() { }
    msg_t(msg_t &&msg);
    msg_t(const msg_t &msg) = default;
    explicit msg_t(stop_t &&op);
    explicit msg_t(change_t &&op);

    // Starts with STOP to avoid doing work for default initialization.
    boost::variant<stop_t, change_t> op;

    RDB_DECLARE_ME_SERIALIZABLE;
};

class feed_t;
struct stamped_msg_t;

// The `client_t` exists on the machine handling the changefeed query, in the
// `rdb_context_t`.  When a query subscribes to the changes on a table, it
// should call `new_feed`.  The `client_t` will give it back a stream of rows.
// The `client_t` does this by maintaining an internal map from table UUIDs to
// `feed_t`s.  (It does this so that there is at most one `feed_t` per <table,
// client> pair, to prevent redundant cluster messages.)  The actual logic for
// subscribing to a changefeed server and distributing writes to streams can be
// found in the `feed_t` class.
class client_t : public home_thread_mixin_t {
public:
    typedef mailbox_addr_t<void(stamped_msg_t)> addr_t;
    client_t(mailbox_manager_t *_manager);
    ~client_t();
    // Throws QL exceptions.
    counted_t<datum_stream_t> new_feed(const counted_t<table_t> &tbl, env_t *env);
    void maybe_remove_feed(const uuid_u &uuid);
    scoped_ptr_t<feed_t> detach_feed(const uuid_u &uuid);
private:
    friend class sub_t;
    mailbox_manager_t *manager;
    std::map<uuid_u, scoped_ptr_t<feed_t> > feeds;
    // This lock manages access to the `feeds` map.  The `feeds` map needs to be
    // read whenever `new_feed` is called, and needs to be written to whenever
    // `new_feed` is called with a table not already in the `feeds` map, or
    // whenever `maybe_remove_feed` or `detach_feed` is called.
    rwlock_t feeds_lock;
    auto_drainer_t drainer;
};

// There is one `server_t` per `store_t`, and it is used to send changes that
// occur on that `store_t` to any subscribed `feed_t`s contained in a
// `client_t`.
class server_t {
public:
    typedef mailbox_addr_t<void(client_t::addr_t)> addr_t;
    server_t(mailbox_manager_t *_manager);
    void add_client(const client_t::addr_t &addr);
    void send_all(msg_t msg);
    addr_t get_stop_addr();
    uint64_t get_stamp(const client_t::addr_t &addr);
    uuid_u get_uuid();
private:
    void stop_mailbox_cb(client_t::addr_t addr);
    void add_client_cb(signal_t *stopped, client_t::addr_t addr);

    uuid_u uuid;
    mailbox_manager_t *manager;

    struct client_info_t {
        scoped_ptr_t<cond_t> cond;
        uint64_t stamp;
    };
    std::map<client_t::addr_t, client_info_t> clients;
    rwlock_t clients_lock;

    mailbox_t<void(client_t::addr_t)> stop_mailbox;
    auto_drainer_t drainer;
};

} // namespace changefeed
} // namespace ql

#endif // RDB_PROTOCOL_CHANGEFEED_HPP_
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/qvariant.h>
#include <QtCore/qdebug.h>
#include <QtGui/qwidget.h>

#include "s60mediaplayerservice.h"
#include "s60mediaplayercontrol.h"
#include "s60videoplayersession.h"
#include "s60audioplayersession.h"
#include "s60mediametadataprovider.h"
#include "s60mediarecognizer.h"
#include "s60videowidgetcontrol.h"
#include "s60videowindowcontrol.h"
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
#include "s60videorenderer.h"
#endif
#include "s60mediaplayeraudioendpointselector.h"
#include "s60medianetworkaccesscontrol.h"
#include "s60mediastreamcontrol.h"

#include <qmediaplaylistnavigator.h>
#include <qmediaplaylist.h>

S60MediaPlayerService::S60MediaPlayerService(QObject *parent)
    : QMediaService(parent)
    , m_control(NULL)
    , m_videoPlayerSession(NULL)
    , m_audioPlayerSession(NULL)
    , m_metaData(NULL)
    , m_audioEndpointSelector(NULL)
    , m_streamControl(NULL)
    , m_networkAccessControl(NULL)
    , m_videoOutput(NULL)
{
    m_control = new S60MediaPlayerControl(*this, this);
    m_metaData = new S60MediaMetaDataProvider(m_control, this);
    m_audioEndpointSelector = new S60MediaPlayerAudioEndpointSelector(m_control, this);
    m_streamControl = new S60MediaStreamControl(m_control, this);
    m_networkAccessControl =  new S60MediaNetworkAccessControl(this);
}

S60MediaPlayerService::~S60MediaPlayerService()
{
}

QMediaControl *S60MediaPlayerService::requestControl(const char *name)
{
    if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
        return m_control;

    if (qstrcmp(name, QMediaNetworkAccessControl_iid) == 0)
        return m_networkAccessControl;

    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
        return m_metaData;

    if (qstrcmp(name, QAudioEndpointSelector_iid) == 0)
        return m_audioEndpointSelector;

    if (qstrcmp(name, QMediaStreamsControl_iid) == 0)
        return m_streamControl;

    if (!m_videoOutput) {
        if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
            m_videoOutput = new S60VideoWidgetControl(this);
        }
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
        else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
            m_videoOutput = new S60VideoRenderer(this);
        }
#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
        else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
            m_videoOutput = new S60VideoWindowControl(this);
        }

        if (m_videoOutput) {
            m_control->setVideoOutput(m_videoOutput);
            return m_videoOutput;
        }
    }else {
        if (qstrcmp(name, QVideoWidgetControl_iid) == 0 ||
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
            qstrcmp(name, QVideoRendererControl_iid) == 0 ||
#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
            qstrcmp(name, QVideoWindowControl_iid) == 0){
            return m_videoOutput;
        }
    }
    return 0;
}

void S60MediaPlayerService::releaseControl(QMediaControl *control)
{
    if (control == m_videoOutput) {
        m_videoOutput = 0;
        m_control->setVideoOutput(m_videoOutput);
    }
}

S60MediaPlayerSession* S60MediaPlayerService::PlayerSession()
{
    QUrl url = m_control->media().canonicalUrl();

    if (url.isEmpty() == true) {
        return NULL;
    }

    QScopedPointer<S60MediaRecognizer> mediaRecognizer(new S60MediaRecognizer);
    S60MediaRecognizer::MediaType mediaType = mediaRecognizer->mediaType(url);
    mediaRecognizer.reset();

    switch (mediaType) {
    case S60MediaRecognizer::Video:
    case S60MediaRecognizer::Url:
        {
        m_control->setMediaType(S60MediaSettings::Video);
        return VideoPlayerSession();
        }
    case S60MediaRecognizer::Audio:
        {
        m_control->setMediaType(S60MediaSettings::Audio);
        return AudioPlayerSession();
        }
    default:
        m_control->setMediaType(S60MediaSettings::Unknown);
        break;
    }

    return NULL;
}

S60MediaPlayerSession* S60MediaPlayerService::VideoPlayerSession()
{
    if (!m_videoPlayerSession) {
        m_videoPlayerSession = new S60VideoPlayerSession(this, m_networkAccessControl);

        connect(m_videoPlayerSession, SIGNAL(positionChanged(qint64)),
                m_control, SIGNAL(positionChanged(qint64)));
        connect(m_videoPlayerSession, SIGNAL(playbackRateChanged(qreal)),
                m_control, SIGNAL(playbackRateChanged(qreal)));
        connect(m_videoPlayerSession, SIGNAL(volumeChanged(int)),
                m_control, SIGNAL(volumeChanged(int)));
        connect(m_videoPlayerSession, SIGNAL(mutedChanged(bool)),
                m_control, SIGNAL(mutedChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(durationChanged(qint64)),
                m_control, SIGNAL(durationChanged(qint64)));
        connect(m_videoPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
                m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
        connect(m_videoPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
                m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
        connect(m_videoPlayerSession,SIGNAL(bufferStatusChanged(int)),
                m_control, SIGNAL(bufferStatusChanged(int)));
        connect(m_videoPlayerSession, SIGNAL(videoAvailableChanged(bool)),
                m_control, SIGNAL(videoAvailableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(audioAvailableChanged(bool)),
                m_control, SIGNAL(audioAvailableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(seekableChanged(bool)),
                m_control, SIGNAL(seekableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
                m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
        connect(m_videoPlayerSession, SIGNAL(error(int, const QString &)),
                m_control, SIGNAL(error(int, const QString &)));
        connect(m_videoPlayerSession, SIGNAL(metaDataChanged()),
                m_metaData, SIGNAL(metaDataChanged()));
        connect(m_videoPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
                m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
        connect(m_videoPlayerSession, SIGNAL(mediaChanged()),
                m_streamControl, SLOT(handleStreamsChanged()));
        connect(m_videoPlayerSession, SIGNAL(accessPointChanged(int)),
                m_networkAccessControl, SLOT(accessPointChanged(int)));
    }

        m_videoPlayerSession->setVolume(m_control->mediaControlSettings().volume());
        m_videoPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
        m_videoPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());

    }
    return m_videoPlayerSession;
}

S60MediaPlayerSession* S60MediaPlayerService::AudioPlayerSession()
{
    if (!m_audioPlayerSession) {
        m_audioPlayerSession = new S60AudioPlayerSession(this);

        connect(m_audioPlayerSession, SIGNAL(positionChanged(qint64)),
                m_control, SIGNAL(positionChanged(qint64)));
        connect(m_audioPlayerSession, SIGNAL(playbackRateChanged(qreal)),
                m_control, SIGNAL(playbackRateChanged(qreal)));
        connect(m_audioPlayerSession, SIGNAL(volumeChanged(int)),
                m_control, SIGNAL(volumeChanged(int)));
        connect(m_audioPlayerSession, SIGNAL(mutedChanged(bool)),
                m_control, SIGNAL(mutedChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(durationChanged(qint64)),
                m_control, SIGNAL(durationChanged(qint64)));
        connect(m_audioPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
                m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
        connect(m_audioPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
                m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
        connect(m_audioPlayerSession,SIGNAL(bufferStatusChanged(int)),
                m_control, SIGNAL(bufferStatusChanged(int)));
        connect(m_audioPlayerSession, SIGNAL(videoAvailableChanged(bool)),
                m_control, SIGNAL(videoAvailableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(audioAvailableChanged(bool)),
                m_control, SIGNAL(audioAvailableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(seekableChanged(bool)),
                m_control, SIGNAL(seekableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
                m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
        connect(m_audioPlayerSession, SIGNAL(error(int, const QString &)),
                m_control, SIGNAL(error(int, const QString &)));
        connect(m_audioPlayerSession, SIGNAL(metaDataChanged()),
                m_metaData, SIGNAL(metaDataChanged()));
        connect(m_audioPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
                m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
        connect(m_audioPlayerSession, SIGNAL(mediaChanged()),
                m_streamControl, SLOT(handleStreamsChanged()));

        m_audioPlayerSession->setVolume(m_control->mediaControlSettings().volume());
        m_audioPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
        m_audioPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());
    }
    return m_audioPlayerSession;
}
<commit_msg>make Symbian mediaplayer plugin compile<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/qvariant.h>
#include <QtCore/qdebug.h>
#include <QtGui/qwidget.h>

#include "s60mediaplayerservice.h"
#include "s60mediaplayercontrol.h"
#include "s60videoplayersession.h"
#include "s60audioplayersession.h"
#include "s60mediametadataprovider.h"
#include "s60mediarecognizer.h"
#include "s60videowidgetcontrol.h"
#include "s60videowindowcontrol.h"
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
#include "s60videorenderer.h"
#endif
#include "s60mediaplayeraudioendpointselector.h"
#include "s60medianetworkaccesscontrol.h"
#include "s60mediastreamcontrol.h"

#include <qmediaplaylistnavigator.h>
#include <qmediaplaylist.h>

S60MediaPlayerService::S60MediaPlayerService(QObject *parent)
    : QMediaService(parent)
    , m_control(NULL)
    , m_videoPlayerSession(NULL)
    , m_audioPlayerSession(NULL)
    , m_metaData(NULL)
    , m_audioEndpointSelector(NULL)
    , m_streamControl(NULL)
    , m_networkAccessControl(NULL)
    , m_videoOutput(NULL)
{
    m_control = new S60MediaPlayerControl(*this, this);
    m_metaData = new S60MediaMetaDataProvider(m_control, this);
    m_audioEndpointSelector = new S60MediaPlayerAudioEndpointSelector(m_control, this);
    m_streamControl = new S60MediaStreamControl(m_control, this);
    m_networkAccessControl =  new S60MediaNetworkAccessControl(this);
}

S60MediaPlayerService::~S60MediaPlayerService()
{
}

QMediaControl *S60MediaPlayerService::requestControl(const char *name)
{
    if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
        return m_control;

    if (qstrcmp(name, QMediaNetworkAccessControl_iid) == 0)
        return m_networkAccessControl;

    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
        return m_metaData;

    if (qstrcmp(name, QAudioEndpointSelector_iid) == 0)
        return m_audioEndpointSelector;

    if (qstrcmp(name, QMediaStreamsControl_iid) == 0)
        return m_streamControl;

    if (!m_videoOutput) {
        if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
            m_videoOutput = new S60VideoWidgetControl(this);
        }
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
        else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
            m_videoOutput = new S60VideoRenderer(this);
        }
#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
        else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
            m_videoOutput = new S60VideoWindowControl(this);
        }

        if (m_videoOutput) {
            m_control->setVideoOutput(m_videoOutput);
            return m_videoOutput;
        }
    }else {
        if (qstrcmp(name, QVideoWidgetControl_iid) == 0 ||
#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
            qstrcmp(name, QVideoRendererControl_iid) == 0 ||
#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
            qstrcmp(name, QVideoWindowControl_iid) == 0){
            return m_videoOutput;
        }
    }
    return 0;
}

void S60MediaPlayerService::releaseControl(QMediaControl *control)
{
    if (control == m_videoOutput) {
        m_videoOutput = 0;
        m_control->setVideoOutput(m_videoOutput);
    }
}

S60MediaPlayerSession* S60MediaPlayerService::PlayerSession()
{
    QUrl url = m_control->media().canonicalUrl();

    if (url.isEmpty() == true) {
        return NULL;
    }

    QScopedPointer<S60MediaRecognizer> mediaRecognizer(new S60MediaRecognizer);
    S60MediaRecognizer::MediaType mediaType = mediaRecognizer->mediaType(url);
    mediaRecognizer.reset();

    switch (mediaType) {
    case S60MediaRecognizer::Video:
    case S60MediaRecognizer::Url:
        {
        m_control->setMediaType(S60MediaSettings::Video);
        return VideoPlayerSession();
        }
    case S60MediaRecognizer::Audio:
        {
        m_control->setMediaType(S60MediaSettings::Audio);
        return AudioPlayerSession();
        }
    default:
        m_control->setMediaType(S60MediaSettings::Unknown);
        break;
    }

    return NULL;
}

S60MediaPlayerSession* S60MediaPlayerService::VideoPlayerSession()
{
    if (!m_videoPlayerSession) {
        m_videoPlayerSession = new S60VideoPlayerSession(this, m_networkAccessControl);

        connect(m_videoPlayerSession, SIGNAL(positionChanged(qint64)),
                m_control, SIGNAL(positionChanged(qint64)));
        connect(m_videoPlayerSession, SIGNAL(playbackRateChanged(qreal)),
                m_control, SIGNAL(playbackRateChanged(qreal)));
        connect(m_videoPlayerSession, SIGNAL(volumeChanged(int)),
                m_control, SIGNAL(volumeChanged(int)));
        connect(m_videoPlayerSession, SIGNAL(mutedChanged(bool)),
                m_control, SIGNAL(mutedChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(durationChanged(qint64)),
                m_control, SIGNAL(durationChanged(qint64)));
        connect(m_videoPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
                m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
        connect(m_videoPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
                m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
        connect(m_videoPlayerSession,SIGNAL(bufferStatusChanged(int)),
                m_control, SIGNAL(bufferStatusChanged(int)));
        connect(m_videoPlayerSession, SIGNAL(videoAvailableChanged(bool)),
                m_control, SIGNAL(videoAvailableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(audioAvailableChanged(bool)),
                m_control, SIGNAL(audioAvailableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(seekableChanged(bool)),
                m_control, SIGNAL(seekableChanged(bool)));
        connect(m_videoPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
                m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
        connect(m_videoPlayerSession, SIGNAL(error(int, const QString &)),
                m_control, SIGNAL(error(int, const QString &)));
        connect(m_videoPlayerSession, SIGNAL(metaDataChanged()),
                m_metaData, SIGNAL(metaDataChanged()));
        connect(m_videoPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
                m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
        connect(m_videoPlayerSession, SIGNAL(mediaChanged()),
                m_streamControl, SLOT(handleStreamsChanged()));
        connect(m_videoPlayerSession, SIGNAL(accessPointChanged(int)),
                m_networkAccessControl, SLOT(accessPointChanged(int)));

        m_videoPlayerSession->setVolume(m_control->mediaControlSettings().volume());
        m_videoPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
        m_videoPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());

    }
    return m_videoPlayerSession;
}

S60MediaPlayerSession* S60MediaPlayerService::AudioPlayerSession()
{
    if (!m_audioPlayerSession) {
        m_audioPlayerSession = new S60AudioPlayerSession(this);

        connect(m_audioPlayerSession, SIGNAL(positionChanged(qint64)),
                m_control, SIGNAL(positionChanged(qint64)));
        connect(m_audioPlayerSession, SIGNAL(playbackRateChanged(qreal)),
                m_control, SIGNAL(playbackRateChanged(qreal)));
        connect(m_audioPlayerSession, SIGNAL(volumeChanged(int)),
                m_control, SIGNAL(volumeChanged(int)));
        connect(m_audioPlayerSession, SIGNAL(mutedChanged(bool)),
                m_control, SIGNAL(mutedChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(durationChanged(qint64)),
                m_control, SIGNAL(durationChanged(qint64)));
        connect(m_audioPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
                m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
        connect(m_audioPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
                m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
        connect(m_audioPlayerSession,SIGNAL(bufferStatusChanged(int)),
                m_control, SIGNAL(bufferStatusChanged(int)));
        connect(m_audioPlayerSession, SIGNAL(videoAvailableChanged(bool)),
                m_control, SIGNAL(videoAvailableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(audioAvailableChanged(bool)),
                m_control, SIGNAL(audioAvailableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(seekableChanged(bool)),
                m_control, SIGNAL(seekableChanged(bool)));
        connect(m_audioPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
                m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
        connect(m_audioPlayerSession, SIGNAL(error(int, const QString &)),
                m_control, SIGNAL(error(int, const QString &)));
        connect(m_audioPlayerSession, SIGNAL(metaDataChanged()),
                m_metaData, SIGNAL(metaDataChanged()));
        connect(m_audioPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
                m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
        connect(m_audioPlayerSession, SIGNAL(mediaChanged()),
                m_streamControl, SLOT(handleStreamsChanged()));

        m_audioPlayerSession->setVolume(m_control->mediaControlSettings().volume());
        m_audioPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
        m_audioPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());
    }
    return m_audioPlayerSession;
}
<|endoftext|>


<commit_before>/* Copyright 2017 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "pioneerKit/blocks/pioneerBlocksFactory.h"

using namespace pioneer::blocks;

qReal::interpretation::Block *PioneerBlocksFactory::produceBlock(const qReal::Id &element)
{
	Q_UNUSED(element);
	return nullptr;
}

qReal::IdList PioneerBlocksFactory::providedBlocks() const
{
	return {
			id("GeoTakeoff")
			, id("GeoLanding")
			, id("GoToPoint")
			, id("PioneerPrint")
			, id("PioneerSystem")
			, id("PioneerLed")
			, id("PioneerMagnet")
			, id("PioneerYaw")
	};
}

qReal::IdList PioneerBlocksFactory::blocksToDisable() const
{
	return {
	};
}

qReal::IdList PioneerBlocksFactory::blocksToHide() const
{
	return {
			id("Function")
			, id("FiBlock")
			, id("SwitchBlock")
			, id("Loop")
			, id("Subprogram")
			, id("Fork")
			, id("Join")
			, id("KillThread")

			, id("SendMessageThreads")

			, id("ReceiveMessageThreads")

			, id("PrintText")
			, id("ClearScreen")
			, id("MarkerDown")
			, id("MarkerUp")
	};
}
<commit_msg>Added EndIf block<commit_after>/* Copyright 2017 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "pioneerKit/blocks/pioneerBlocksFactory.h"

using namespace pioneer::blocks;

qReal::interpretation::Block *PioneerBlocksFactory::produceBlock(const qReal::Id &element)
{
	Q_UNUSED(element);
	return nullptr;
}

qReal::IdList PioneerBlocksFactory::providedBlocks() const
{
	return {
			id("GeoTakeoff")
			, id("GeoLanding")
			, id("GoToPoint")
			, id("PioneerPrint")
			, id("PioneerSystem")
			, id("PioneerLed")
			, id("PioneerMagnet")
			, id("PioneerYaw")
	};
}

qReal::IdList PioneerBlocksFactory::blocksToDisable() const
{
	return {
	};
}

qReal::IdList PioneerBlocksFactory::blocksToHide() const
{
	return {
			id("Function")
			, id("SwitchBlock")
			, id("Loop")
			, id("Subprogram")
			, id("Fork")
			, id("Join")
			, id("KillThread")

			, id("SendMessageThreads")

			, id("ReceiveMessageThreads")

			, id("PrintText")
			, id("ClearScreen")
			, id("MarkerDown")
			, id("MarkerUp")
	};
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 neurodata (http://neurodata.io/)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of knor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef USE_NUMA
#include <numa.h>
#endif

#include "base_kmeans_thread.hpp"
#include "exception.hpp"
#include "util.hpp"

#define VERBOSE 0
#define INVALID_THD_ID -1

namespace kpmeans {

void base_kmeans_thread::destroy_numa_mem() {
    if (!preallocd_data) {
#ifdef USE_NUMA
    numa_free(local_data, get_data_size());
#else
    delete [] local_data;
#endif
    }
}

void base_kmeans_thread::join() {
    void* join_status;
    int rc = pthread_join(hw_thd, &join_status);
    if (rc)
        throw base::thread_exception("pthread_join()", rc);

    thd_id = INVALID_THD_ID;
}

// Once the algorithm ends we should deallocate the memory we moved
void base_kmeans_thread::close_file_handle() {
    int rc = fclose(f);
    if (rc)
        throw base::io_exception("fclose() failed!", rc);

#if VERBOSE
#ifndef BIND
    printf("Thread %u closing the file handle.\n",thd_id);
#endif
#endif
    f = NULL;
}

// Move data ~equally to all nodes
void base_kmeans_thread::numa_alloc_mem() {
    kpmbase::assert_msg(f, "File handle invalid, can only alloc once!");
    size_t blob_size = get_data_size();
#ifdef USE_NUMA
    local_data = static_cast<double*>(numa_alloc_onnode(blob_size, node_id));
#else
    local_data = new double [blob_size/sizeof(double)];
#endif
    fseek(f, start_rid*ncol*sizeof(double), SEEK_SET); // start position
#ifdef NDEBUG
    size_t nread = fread(local_data, blob_size, 1, f);
    nread = nread; // Silence compiler warning
#else
    assert(fread(local_data, blob_size, 1, f) == 1);
#endif
    close_file_handle();
}

void base_kmeans_thread::set_local_data_ptr(double* data, bool offset) {
    if (offset)
        local_data = &(data[start_rid*ncol]); // Grab your offset
    else
        local_data = data;
}

base_kmeans_thread::~base_kmeans_thread() {
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    pthread_mutexattr_destroy(&mutex_attr);

    if (f)
        close_file_handle();
#if VERBOSE
#ifndef BIND
    printf("Thread %u being destroyed\n", thd_id);
#endif
#endif
    if (thd_id != INVALID_THD_ID)
        join();
}

void base_kmeans_thread::bind2node_id() {
#ifdef USE_NUMA
    struct bitmask *bmp = numa_allocate_nodemask();
    numa_bitmask_setbit(bmp, node_id);
    numa_bind(bmp);
    numa_free_nodemask(bmp);
#endif
    // No NUMA? Do nothing
}
} // End namespace kpmeans
<commit_msg>warn: silence compiler<commit_after>/*
 * Copyright 2016 neurodata (http://neurodata.io/)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of knor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef USE_NUMA
#include <numa.h>
#endif

#include "base_kmeans_thread.hpp"
#include "exception.hpp"
#include "util.hpp"

#define VERBOSE 0
#define INVALID_THD_ID -1

namespace kpmeans {

void base_kmeans_thread::destroy_numa_mem() {
    if (!preallocd_data) {
#ifdef USE_NUMA
    numa_free(local_data, get_data_size());
#else
    delete [] local_data;
#endif
    }
}

void base_kmeans_thread::join() {
    void* join_status;
    int rc = pthread_join(hw_thd, &join_status);
    if (rc)
        throw base::thread_exception("pthread_join()", rc);

    thd_id = INVALID_THD_ID;
}

// Once the algorithm ends we should deallocate the memory we moved
void base_kmeans_thread::close_file_handle() {
    int rc = fclose(f);
    if (rc)
        throw base::io_exception("fclose() failed!", rc);

#if VERBOSE
#ifndef BIND
    printf("Thread %u closing the file handle.\n",thd_id);
#endif
#endif
    f = NULL;
}

// Move data ~equally to all nodes
void base_kmeans_thread::numa_alloc_mem() {
    kpmbase::assert_msg(f, "File handle invalid, can only alloc once!");
    size_t blob_size = get_data_size();
#ifdef USE_NUMA
    local_data = static_cast<double*>(numa_alloc_onnode(blob_size, node_id));
#else
    local_data = new double [blob_size/sizeof(double)];
#endif
    fseek(f, start_rid*ncol*sizeof(double), SEEK_SET); // start position
#ifdef NDEBUG
    size_t nread = fread(local_data, blob_size, 1, f);
    nread = nread + 1 - 1; // Silence compiler warning
#else
    assert(fread(local_data, blob_size, 1, f) == 1);
#endif
    close_file_handle();
}

void base_kmeans_thread::set_local_data_ptr(double* data, bool offset) {
    if (offset)
        local_data = &(data[start_rid*ncol]); // Grab your offset
    else
        local_data = data;
}

base_kmeans_thread::~base_kmeans_thread() {
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    pthread_mutexattr_destroy(&mutex_attr);

    if (f)
        close_file_handle();
#if VERBOSE
#ifndef BIND
    printf("Thread %u being destroyed\n", thd_id);
#endif
#endif
    if (thd_id != INVALID_THD_ID)
        join();
}

void base_kmeans_thread::bind2node_id() {
#ifdef USE_NUMA
    struct bitmask *bmp = numa_allocate_nodemask();
    numa_bitmask_setbit(bmp, node_id);
    numa_bind(bmp);
    numa_free_nodemask(bmp);
#endif
    // No NUMA? Do nothing
}
} // End namespace kpmeans
<|endoftext|>


<commit_before>#include "test_driver.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#include <windows.h>
#else
#include <dirent.h>
#endif

namespace ONNX_NAMESPACE {
namespace testing {
bool FileExists(const std::string& filename) {
#ifdef _WIN32
  if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(filename.c_str())) {
    return false;
  }
#else
  struct stat stats;
  if (lstat(filename.c_str(), &stats) != 0 || !S_ISREG(stats.st_mode)) {
    return false;
  }
#endif
  return true;
}

void TestDriver::SetDefaultDir(const std::string& s) {
  default_dir_ = s;
}

/**
 *	It is possible that case_dir is not a dir.
 *	But it does not affect the result.
 */
void TestDriver::FetchSingleTestCase(const std::string& case_dir) {
  std::string model_name = case_dir;
  model_name += "model.onnx";
  if (FileExists(model_name)) {
    UnsolvedTestCase test_case;
    test_case.model_filename_ = model_name;
    test_case.model_dirname_ = case_dir;
    for (int case_count = 0;; case_count++) {
      std::vector<std::string> input_filenames, output_filenames;
      std::string input_name, output_name;
      std::string case_dirname = case_dir;
      case_dirname += "test_data_set_" + ONNX_NAMESPACE::to_string(case_count);
      input_name = case_dirname + "/input_" + "0" + ".pb";
      output_name = case_dirname + "/output_" + "0" + ".pb";
      if (!FileExists(output_name) && !FileExists(input_name)) {
        break;
      }

      for (int data_count = 0;; data_count++) {
        input_name = case_dirname + "/input_" +
            ONNX_NAMESPACE::to_string(data_count) + ".pb";
        output_name = case_dirname + "/output_" +
            ONNX_NAMESPACE::to_string(data_count) + ".pb";
        const bool input_exists = FileExists(input_name);
        const bool output_exists = FileExists(output_name);
        if (!output_exists && !input_exists) {
          break;
        }
        if (input_exists) {
          input_filenames.emplace_back(std::move(input_name));
        }
        if (output_exists) {
          output_filenames.emplace_back(std::move(output_name));
        }
      }
      UnsolvedTestData test_data(input_filenames, output_filenames);
      test_case.test_data_.emplace_back(std::move(test_data));
    }
    testcases_.emplace_back(std::move(test_case));
  }
}

bool TestDriver::FetchAllTestCases(const std::string& target) {
  std::string target_dir = target;
  if (target_dir == "") {
    target_dir = default_dir_;
  }
  if (target_dir[target_dir.size() - 1] == '/') {
    target_dir.erase(target_dir.size() - 1, 1);
  }
#ifdef _WIN32
  _finddata_t file;
  intptr_t lf;
  if ((lf = _findfirst(target_dir.c_str(), &file)) == -1) {
    std::cerr << "Error: cannot open directory " << target_dir
              << " when fetching test data: " << strerror(errno) << std::endl;
    return false;
  } else {
    try {
      do {
        std::string entry_dname = file.name;
        if (entry_dname != "." && entry_dname != "..") {
          entry_dname = target_dir + "/" + entry_dname + "/";
          FetchSingleTestCase(entry_dname);
        }
      } while (_findnext(lf, &file) == 0);
    } catch (const std::exception& e) {
      std::cerr << "Error occured while reading directory. " << e.what()
                << std::endl;
      _findclose(lf);
      throw;
    }
    _findclose(lf);
  }
#else
  DIR* directory;
  try {
    directory = opendir(target_dir.c_str());
    if (directory == NULL) {
      std::cerr << "Error: cannot open directory " << target_dir
                << " when fetching test data: " << strerror(errno) << std::endl;
      return false;
    }
    while (true) {
      errno = 0;
      struct dirent* entry = readdir(directory);
      if (entry == NULL) {
        if (errno != 0) {
          std::cerr << "Error: cannot read directory " << target_dir
                    << " when fetching test data: " << strerror(errno)
                    << std::endl;
          return -1;
        } else {
          break;
        }
      }
      std::string entry_dname = entry->d_name;
      if (entry_dname != "." && entry_dname != "..") {
        entry_dname = target_dir + "/" + entry_dname + "/";
        FetchSingleTestCase(entry_dname);
      }
    }
  } catch (const std::exception& e) {
    if (directory != NULL) {
      if (closedir(directory) != 0) {
        std::cerr << "Warning: failed to close directory " << target_dir
                  << " when fetching test data: " << strerror(errno)
                  << std::endl;
      }
    }
    std::cerr << "Error: exception occured: " << e.what() << std::endl;
    throw;
  }
  if (directory != NULL) {
    if (closedir(directory) != 0) {
      std::cerr << "Warning: failed to close directory " << target_dir
                << " when fetching test data: " << strerror(errno) << std::endl;
      return false;
    }
  }
#endif
return true;
}

std::vector<UnsolvedTestCase> GetTestCase(const std::string& location) {
  TestDriver test_driver;
  test_driver.FetchAllTestCases(location);
  return test_driver.testcases_;
}

void LoadSingleFile(const std::string& filename, std::string& filedata) {
  FILE* fp;
  if ((fp = fopen(filename.c_str(), "r")) != NULL) {
    try {
      int fsize;
      char buff[1024] = {0};
      do {
        fsize = fread(buff, sizeof(char), 1024, fp);
        filedata += std::string(buff, buff + fsize);
      } while (fsize == 1024);
    } catch (const std::exception& e) {
      fclose(fp);
      throw;
    }
    fclose(fp);
  } else {
    std::cerr << "Warning: failed to open file: " << filename << std::endl;
  }
}

ResolvedTestCase LoadSingleTestCase(const UnsolvedTestCase& t) {
  ResolvedTestCase st;
  std::string raw_model;
  LoadSingleFile(t.model_filename_, raw_model);
  ONNX_NAMESPACE::ParseProtoFromBytes(
      &st.model_, raw_model.c_str(), raw_model.size());

  for (auto& test_data : t.test_data_) {
    ResolvedTestData proto_test_data;

    for (auto& input_file : test_data.input_filenames_) {
      std::string input_data;
      LoadSingleFile(input_file, input_data);
      ONNX_NAMESPACE::TensorProto input_proto;
      ONNX_NAMESPACE::ParseProtoFromBytes(
          &input_proto, input_data.c_str(), input_data.size());
      proto_test_data.inputs_.emplace_back(std::move(input_proto));
    }
    for (auto& output_file : test_data.output_filenames_) {
      std::string output_data = "";
      LoadSingleFile(output_file, output_data);
      ONNX_NAMESPACE::TensorProto output_proto;
      ONNX_NAMESPACE::ParseProtoFromBytes(
          &output_proto, output_data.c_str(), output_data.size());
      proto_test_data.outputs_.emplace_back(std::move(output_proto));
    }
  }
  return st;
}

std::vector<ResolvedTestCase> LoadAllTestCases(const std::string& location) {
  std::vector<UnsolvedTestCase> t = GetTestCase(location);
  return LoadAllTestCases(t);
}

std::vector<ResolvedTestCase> LoadAllTestCases(
    const std::vector<UnsolvedTestCase>& t) {
  std::vector<ResolvedTestCase> st;
  for (const auto& i : t) {
    st.push_back(LoadSingleTestCase(i));
  }
  return st;
}

} // namespace testing
} // namespace ONNX_NAMESPACE
<commit_msg>fix the bug of loading model input/output proto (#1477)<commit_after>#include "test_driver.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#include <windows.h>
#else
#include <dirent.h>
#endif

namespace ONNX_NAMESPACE {
namespace testing {
bool FileExists(const std::string& filename) {
#ifdef _WIN32
  if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(filename.c_str())) {
    return false;
  }
#else
  struct stat stats;
  if (lstat(filename.c_str(), &stats) != 0 || !S_ISREG(stats.st_mode)) {
    return false;
  }
#endif
  return true;
}

void TestDriver::SetDefaultDir(const std::string& s) {
  default_dir_ = s;
}

/**
 *	It is possible that case_dir is not a dir.
 *	But it does not affect the result.
 */
void TestDriver::FetchSingleTestCase(const std::string& case_dir) {
  std::string model_name = case_dir;
  model_name += "model.onnx";
  if (FileExists(model_name)) {
    UnsolvedTestCase test_case;
    test_case.model_filename_ = model_name;
    test_case.model_dirname_ = case_dir;
    for (int case_count = 0;; case_count++) {
      std::vector<std::string> input_filenames, output_filenames;
      std::string input_name, output_name;
      std::string case_dirname = case_dir;
      case_dirname += "test_data_set_" + ONNX_NAMESPACE::to_string(case_count);
      input_name = case_dirname + "/input_" + "0" + ".pb";
      output_name = case_dirname + "/output_" + "0" + ".pb";
      if (!FileExists(output_name) && !FileExists(input_name)) {
        break;
      }

      for (int data_count = 0;; data_count++) {
        input_name = case_dirname + "/input_" +
            ONNX_NAMESPACE::to_string(data_count) + ".pb";
        output_name = case_dirname + "/output_" +
            ONNX_NAMESPACE::to_string(data_count) + ".pb";
        const bool input_exists = FileExists(input_name);
        const bool output_exists = FileExists(output_name);
        if (!output_exists && !input_exists) {
          break;
        }
        if (input_exists) {
          input_filenames.emplace_back(std::move(input_name));
        }
        if (output_exists) {
          output_filenames.emplace_back(std::move(output_name));
        }
      }
      UnsolvedTestData test_data(input_filenames, output_filenames);
      test_case.test_data_.emplace_back(std::move(test_data));
    }
    testcases_.emplace_back(std::move(test_case));
  }
}

bool TestDriver::FetchAllTestCases(const std::string& target) {
  std::string target_dir = target;
  if (target_dir == "") {
    target_dir = default_dir_;
  }
  if (target_dir[target_dir.size() - 1] == '/') {
    target_dir.erase(target_dir.size() - 1, 1);
  }
#ifdef _WIN32
  _finddata_t file;
  intptr_t lf;
  if ((lf = _findfirst(target_dir.c_str(), &file)) == -1) {
    std::cerr << "Error: cannot open directory " << target_dir
              << " when fetching test data: " << strerror(errno) << std::endl;
    return false;
  } else {
    try {
      do {
        std::string entry_dname = file.name;
        if (entry_dname != "." && entry_dname != "..") {
          entry_dname = target_dir + "/" + entry_dname + "/";
          FetchSingleTestCase(entry_dname);
        }
      } while (_findnext(lf, &file) == 0);
    } catch (const std::exception& e) {
      std::cerr << "Error occured while reading directory. " << e.what()
                << std::endl;
      _findclose(lf);
      throw;
    }
    _findclose(lf);
  }
#else
  DIR* directory;
  try {
    directory = opendir(target_dir.c_str());
    if (directory == NULL) {
      std::cerr << "Error: cannot open directory " << target_dir
                << " when fetching test data: " << strerror(errno) << std::endl;
      return false;
    }
    while (true) {
      errno = 0;
      struct dirent* entry = readdir(directory);
      if (entry == NULL) {
        if (errno != 0) {
          std::cerr << "Error: cannot read directory " << target_dir
                    << " when fetching test data: " << strerror(errno)
                    << std::endl;
          return -1;
        } else {
          break;
        }
      }
      std::string entry_dname = entry->d_name;
      if (entry_dname != "." && entry_dname != "..") {
        entry_dname = target_dir + "/" + entry_dname + "/";
        FetchSingleTestCase(entry_dname);
      }
    }
  } catch (const std::exception& e) {
    if (directory != NULL) {
      if (closedir(directory) != 0) {
        std::cerr << "Warning: failed to close directory " << target_dir
                  << " when fetching test data: " << strerror(errno)
                  << std::endl;
      }
    }
    std::cerr << "Error: exception occured: " << e.what() << std::endl;
    throw;
  }
  if (directory != NULL) {
    if (closedir(directory) != 0) {
      std::cerr << "Warning: failed to close directory " << target_dir
                << " when fetching test data: " << strerror(errno) << std::endl;
      return false;
    }
  }
#endif
return true;
}

std::vector<UnsolvedTestCase> GetTestCase(const std::string& location) {
  TestDriver test_driver;
  test_driver.FetchAllTestCases(location);
  return test_driver.testcases_;
}

void LoadSingleFile(const std::string& filename, std::string& filedata) {
  FILE* fp;
  if ((fp = fopen(filename.c_str(), "r")) != NULL) {
    try {
      int fsize;
      char buff[1024] = {0};
      do {
        fsize = fread(buff, sizeof(char), 1024, fp);
        filedata += std::string(buff, buff + fsize);
      } while (fsize == 1024);
    } catch (const std::exception& e) {
      fclose(fp);
      throw;
    }
    fclose(fp);
  } else {
    std::cerr << "Warning: failed to open file: " << filename << std::endl;
  }
}

ResolvedTestCase LoadSingleTestCase(const UnsolvedTestCase& t) {
  ResolvedTestCase st;
  std::string raw_model;
  LoadSingleFile(t.model_filename_, raw_model);
  ONNX_NAMESPACE::ParseProtoFromBytes(
      &st.model_, raw_model.c_str(), raw_model.size());

  for (auto& test_data : t.test_data_) {
    ResolvedTestData proto_test_data;

    for (auto& input_file : test_data.input_filenames_) {
      std::string input_data;
      LoadSingleFile(input_file, input_data);
      ONNX_NAMESPACE::TensorProto input_proto;
      ONNX_NAMESPACE::ParseProtoFromBytes(
          &input_proto, input_data.c_str(), input_data.size());
      proto_test_data.inputs_.emplace_back(std::move(input_proto));
    }
    for (auto& output_file : test_data.output_filenames_) {
      std::string output_data = "";
      LoadSingleFile(output_file, output_data);
      ONNX_NAMESPACE::TensorProto output_proto;
      ONNX_NAMESPACE::ParseProtoFromBytes(
          &output_proto, output_data.c_str(), output_data.size());
      proto_test_data.outputs_.emplace_back(std::move(output_proto));
    }
    st.proto_test_data_.emplace_back(std::move(proto_test_data));
  }
  return st;
}

std::vector<ResolvedTestCase> LoadAllTestCases(const std::string& location) {
  std::vector<UnsolvedTestCase> t = GetTestCase(location);
  return LoadAllTestCases(t);
}

std::vector<ResolvedTestCase> LoadAllTestCases(
    const std::vector<UnsolvedTestCase>& t) {
  std::vector<ResolvedTestCase> st;
  for (const auto& i : t) {
    st.push_back(LoadSingleTestCase(i));
  }
  return st;
}

} // namespace testing
} // namespace ONNX_NAMESPACE
<|endoftext|>


<commit_before>#include <jni.h>
#include <sstream>
#include <string>
#include <stdio.h>

#include <android/log.h>

#include "utils.cpp"
#include "amanda.cpp"

extern "C" {

// Process a frame
JNIEXPORT jboolean JNICALL
Java_com_danycabrera_signcoach_LearnActivity_processFrame(JNIEnv *env, jobject instance,
																	jlong iAddr1, jlong iAddr2, jchar c) {

	// Prepare source and destination image pointers
	Mat *src = (Mat *) iAddr1;
	Mat *dst = (Mat *) iAddr2;
	flip(*src, *src, 1);
	//__android_log_print(ANDROID_LOG_ERROR, "MyLogs", "GlobalN address: %p", &globalN);

	//cropImage(*src, *dst);

	return checkIfCorrect(*src, c);
}

// Assigns values to configuration globals
JNIEXPORT void JNICALL
Java_com_danycabrera_signcoach_MainActivity_initGlobals(JNIEnv *env, jobject instance,
																   jstring externalStoragePath) {

	sign_cascade_folder = jstring2string(env, externalStoragePath) + "/signcoach/data/";
	__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "sign_cascade_folder: %s", sign_cascade_folder.c_str());

	FILE* file = fopen("/sdcard/textTest.txt","w+");
	if (file == NULL) {
		__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "Error fopen: %d (%s)", errno, strerror(errno));
	} else {
		__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "File open!");
	}
	fputs("hello, world\n", file);
	fclose(file);
}

}<commit_msg>added things that dany said to add<commit_after>#include <jni.h>
#include <sstream>
#include <string>
#include <stdio.h>

#include <android/log.h>

#include "utils.cpp"
#include "amanda.cpp"

extern "C" {

// Process a frame
JNIEXPORT jboolean JNICALL
Java_com_danycabrera_signcoach_LearnActivity_processFrame(JNIEnv *env, jobject instance,
																	jlong iAddr1, jlong iAddr2, jchar c) {

	// Prepare source and destination image pointers
	Mat *src = (Mat *) iAddr1;
	Mat *dst = (Mat *) iAddr2;
	//
	// flip(*src, *src, 1);
	//__android_log_print(ANDROID_LOG_ERROR, "MyLogs", "GlobalN address: %p", &globalN);
	fixRotation(*src, *dst, 1);
	//cropImage(*src, *dst);

	return checkIfCorrect(*src, c);
}

// Assigns values to configuration globals
JNIEXPORT void JNICALL
Java_com_danycabrera_signcoach_MainActivity_initGlobals(JNIEnv *env, jobject instance,
																   jstring externalStoragePath) {

	sign_cascade_folder = jstring2string(env, externalStoragePath) + "/signcoach/data/";
	__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "sign_cascade_folder: %s", sign_cascade_folder.c_str());

	FILE* file = fopen("/sdcard/textTest.txt","w+");
	if (file == NULL) {
		__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "Error fopen: %d (%s)", errno, strerror(errno));
	} else {
		__android_log_print(ANDROID_LOG_ERROR, "initGlobals", "File open!");
	}
	fputs("hello, world\n", file);
	fclose(file);
}

}<|endoftext|>