<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if (!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
      /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
      /// For all but the first task,
      /// the input path must be changed if
      /// the output path argument -o was given, because the input
      /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }

  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    if (!createScopeTaskAndAddToTaskList()) {
      ERROR("Scope task not added correctly!!!");
      return false;
    }
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    unpackFile(inputFile, nevents);
  }
  //Assumption that only HLD files can be zipped!!!!!! - Sz.N.
  else if( inputFileType == JPetOptions::kZip){
    INFO( std::string("Unzipping file before unpacking") );
    if( !JPetCommonTools::unzipFile(inputFile) )
      ERROR( std::string("Problem with unpacking file: ") + inputFile );
    long long nevents = fOptions.getTotalEvents();
    INFO( std::string("Unpacking") );
    unpackFile( JPetCommonTools::stripFileNameSuffix( std::string(inputFile) ).c_str(), nevents);
  }

  if(fOptions.getInputFileType() == JPetOptions::kUndefinedFileType)
    ERROR( Form("Unknown file type provided for file: %s", fOptions.getInputFile()) );

  return true;
}

bool JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
    return false;
  }
  fTasks.push_front(module);
  return true;
}

void JPetTaskExecutor::unpackFile(const char* filename, const long long nevents)
{
    if (nevents > 0) {
      fUnpacker.setParams( filename, nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams( filename );
    }
    fUnpacker.exec();
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<commit_msg>Fix std namespace after Unpacker headers' cleanup<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if (!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
      /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
      /// For all but the first task,
      /// the input path must be changed if
      /// the output path argument -o was given, because the input
      /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(std::to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }

  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    if (!createScopeTaskAndAddToTaskList()) {
      ERROR("Scope task not added correctly!!!");
      return false;
    }
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    unpackFile(inputFile, nevents);
  }
  //Assumption that only HLD files can be zipped!!!!!! - Sz.N.
  else if( inputFileType == JPetOptions::kZip){
    INFO( std::string("Unzipping file before unpacking") );
    if( !JPetCommonTools::unzipFile(inputFile) )
      ERROR( std::string("Problem with unpacking file: ") + inputFile );
    long long nevents = fOptions.getTotalEvents();
    INFO( std::string("Unpacking") );
    unpackFile( JPetCommonTools::stripFileNameSuffix( std::string(inputFile) ).c_str(), nevents);
  }

  if(fOptions.getInputFileType() == JPetOptions::kUndefinedFileType)
    ERROR( Form("Unknown file type provided for file: %s", fOptions.getInputFile()) );

  return true;
}

bool JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
    return false;
  }
  fTasks.push_front(module);
  return true;
}

void JPetTaskExecutor::unpackFile(const char* filename, const long long nevents)
{
    if (nevents > 0) {
      fUnpacker.setParams( filename, nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams( filename );
    }
    fUnpacker.exec();
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/TestHarness.h"
#include "CppUTest/MemoryLeakAllocator.h"
#include "CppUTest/PlatformSpecificFunctions.h"

static char* checkedMalloc(size_t size)
{
	char* mem = (char*) PlatformSpecificMalloc(size);
	if (mem == 0)FAIL("malloc returned nul pointer");
	return mem;
}

MemoryLeakAllocator* MemoryLeakAllocator::currentNewAllocator = 0;
MemoryLeakAllocator* MemoryLeakAllocator::currentNewArrayAllocator = 0;
MemoryLeakAllocator* MemoryLeakAllocator::currentMallocAllocator = 0;

int MemoryLeakAllocator::isOfEqualType(MemoryLeakAllocator* allocator)
{
	return PlatformSpecificStrCmp(this->name(), allocator->name()) == 0;
}

void MemoryLeakAllocator::setCurrentNewAllocator(MemoryLeakAllocator* allocator)
{
	currentNewAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentNewAllocator()
{
	if (currentNewAllocator == 0)
		setCurrentNewAllocatorToDefault();
	return currentNewAllocator;
}

void MemoryLeakAllocator::setCurrentNewAllocatorToDefault()
{
	currentNewAllocator = StandardNewAllocator::defaultAllocator();
}

void MemoryLeakAllocator::setCurrentNewArrayAllocator(MemoryLeakAllocator* allocator)
{
	currentNewArrayAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentNewArrayAllocator()
{
	if (currentNewArrayAllocator == 0)
		setCurrentNewArrayAllocatorToDefault();
	return currentNewArrayAllocator;
}

void MemoryLeakAllocator::setCurrentNewArrayAllocatorToDefault()
{
	currentNewArrayAllocator = StandardNewArrayAllocator::defaultAllocator();
}

void MemoryLeakAllocator::setCurrentMallocAllocator(MemoryLeakAllocator* allocator)
{
	currentMallocAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentMallocAllocator()
{
	if (currentMallocAllocator == 0)
		setCurrentMallocAllocatorToDefault();
	return currentMallocAllocator;
}

void MemoryLeakAllocator::setCurrentMallocAllocatorToDefault()
{
	currentMallocAllocator = StandardMallocAllocator::defaultAllocator();
}

char* StandardMallocAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardMallocAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardMallocAllocator::name()
{
	return "Standard Malloc Allocator";
}

const char* StandardMallocAllocator::alloc_name()
{
	return "malloc";
}

const char* StandardMallocAllocator::free_name()
{
	return "free";
}

MemoryLeakAllocator* StandardMallocAllocator::defaultAllocator()
{
	static StandardMallocAllocator allocator;
	return &allocator;
}

char* StandardNewAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardNewAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardNewAllocator::name()
{
	return "Standard New Allocator";
}

const char* StandardNewAllocator::alloc_name()
{
	return "new";
}

const char* StandardNewAllocator::free_name()
{
	return "delete";
}

MemoryLeakAllocator* StandardNewAllocator::defaultAllocator()
{
	static StandardNewAllocator allocator;
	return &allocator;
}

char* StandardNewArrayAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardNewArrayAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardNewArrayAllocator::name()
{
	return "Standard New [] Allocator";
}

const char* StandardNewArrayAllocator::alloc_name()
{
	return "new []";
}

const char* StandardNewArrayAllocator::free_name()
{
	return "delete []";
}

MemoryLeakAllocator* StandardNewArrayAllocator::defaultAllocator()
{
	static StandardNewArrayAllocator allocator;
	return &allocator;
}
char* NullUnknownAllocator::alloc_memory(size_t size)
{
	return 0;
}

void NullUnknownAllocator::free_memory(char* memory)
{
}

const char* NullUnknownAllocator::name()
{
	return "Null Allocator";
}

const char* NullUnknownAllocator::alloc_name()
{
	return "unknown";
}

const char* NullUnknownAllocator::free_name()
{
	return "unknown";
}

MemoryLeakAllocator* NullUnknownAllocator::defaultAllocator()
{
	static NullUnknownAllocator allocator;
	return &allocator;
}
<commit_msg><commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/TestHarness.h"
#include "CppUTest/MemoryLeakAllocator.h"
#include "CppUTest/PlatformSpecificFunctions.h"

static char* checkedMalloc(size_t size)
{
	char* mem = (char*) PlatformSpecificMalloc(size);
	if (mem == 0)FAIL("malloc returned nul pointer");
	return mem;
}

MemoryLeakAllocator* MemoryLeakAllocator::currentNewAllocator = 0;
MemoryLeakAllocator* MemoryLeakAllocator::currentNewArrayAllocator = 0;
MemoryLeakAllocator* MemoryLeakAllocator::currentMallocAllocator = 0;

int MemoryLeakAllocator::isOfEqualType(MemoryLeakAllocator* allocator)
{
	return PlatformSpecificStrCmp(this->name(), allocator->name()) == 0;
}

void MemoryLeakAllocator::setCurrentNewAllocator(MemoryLeakAllocator* allocator)
{
	currentNewAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentNewAllocator()
{
	if (currentNewAllocator == 0)
		setCurrentNewAllocatorToDefault();
	return currentNewAllocator;
}

void MemoryLeakAllocator::setCurrentNewAllocatorToDefault()
{
	currentNewAllocator = StandardNewAllocator::defaultAllocator();
}

void MemoryLeakAllocator::setCurrentNewArrayAllocator(MemoryLeakAllocator* allocator)
{
	currentNewArrayAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentNewArrayAllocator()
{
	if (currentNewArrayAllocator == 0)
		setCurrentNewArrayAllocatorToDefault();
	return currentNewArrayAllocator;
}

void MemoryLeakAllocator::setCurrentNewArrayAllocatorToDefault()
{
	currentNewArrayAllocator = StandardNewArrayAllocator::defaultAllocator();
}

void MemoryLeakAllocator::setCurrentMallocAllocator(MemoryLeakAllocator* allocator)
{
	currentMallocAllocator = allocator;
}

MemoryLeakAllocator* MemoryLeakAllocator::getCurrentMallocAllocator()
{
	if (currentMallocAllocator == 0)
		setCurrentMallocAllocatorToDefault();
	return currentMallocAllocator;
}

void MemoryLeakAllocator::setCurrentMallocAllocatorToDefault()
{
	currentMallocAllocator = StandardMallocAllocator::defaultAllocator();
}

char* StandardMallocAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardMallocAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardMallocAllocator::name()
{
	return "Standard Malloc Allocator";
}

const char* StandardMallocAllocator::alloc_name()
{
	return "malloc";
}

const char* StandardMallocAllocator::free_name()
{
	return "free";
}

MemoryLeakAllocator* StandardMallocAllocator::defaultAllocator()
{
	static StandardMallocAllocator allocator;
	return &allocator;
}

char* StandardNewAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardNewAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardNewAllocator::name()
{
	return "Standard New Allocator";
}

const char* StandardNewAllocator::alloc_name()
{
	return "new";
}

const char* StandardNewAllocator::free_name()
{
	return "delete";
}

MemoryLeakAllocator* StandardNewAllocator::defaultAllocator()
{
	static StandardNewAllocator allocator;
	return &allocator;
}

char* StandardNewArrayAllocator::alloc_memory(size_t size)
{
	return checkedMalloc(size);
}

void StandardNewArrayAllocator::free_memory(char* memory)
{
	PlatformSpecificFree(memory);
}

const char* StandardNewArrayAllocator::name()
{
	return "Standard New [] Allocator";
}

const char* StandardNewArrayAllocator::alloc_name()
{
	return "new []";
}

const char* StandardNewArrayAllocator::free_name()
{
	return "delete []";
}

MemoryLeakAllocator* StandardNewArrayAllocator::defaultAllocator()
{
	static StandardNewArrayAllocator allocator;
	return &allocator;
}
char* NullUnknownAllocator::alloc_memory(size_t /*size*/)
{
	return 0;
}

void NullUnknownAllocator::free_memory(char* /*memory*/)
{
}

const char* NullUnknownAllocator::name()
{
	return "Null Allocator";
}

const char* NullUnknownAllocator::alloc_name()
{
	return "unknown";
}

const char* NullUnknownAllocator::free_name()
{
	return "unknown";
}

MemoryLeakAllocator* NullUnknownAllocator::defaultAllocator()
{
	static NullUnknownAllocator allocator;
	return &allocator;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <codecvt>
//#include <cstddef>
#include <locale>
#include <clocale>
#include <string>
#include <iomanip>
#include <ctime>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF-8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return (int)v2w.size();
    }

    wstring sample(int len) {
        int p=std::rand()%(text.size()-len);
        return text.substr(p,len);
    }
};

void currentDateTime(wstring& timestr) {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
    timestr=std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(buf);
}

int main(int argc, char *argv[]) {
#ifndef __APPLE__
    std::setlocale(LC_ALL, "");
#else
    setlocale(LC_ALL, "");
    std::wcout.imbue(std::locale("en_US.UTF-8"));
#endif
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << L"rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int T=96;

    int N=(int)txt.text.size() / (T+1);
    cerr << N << " Max datasets" << endl;
    MatrixN Xr(N,T);
    MatrixN yr(N,T);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N; i++) {
        wstring smp = txt.sample(T+1);
        chunk=smp.substr(0,T);
        chunky=smp.substr(1,T);
        for (int t=0; t<T; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
        }
        ++n;
    }

    int maxN = 100000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;
    if (n1+2*dn > n) {
        cerr << "Math doesn't work out." << endl;
    }

    cerr << n1 << " datasets, " << dn << " test-sets, " << dn << " validation-sets" << endl;

/*    MatrixN X(n1,T);
    MatrixN y(n1,T);
    MatrixN Xv(dn,T);
    MatrixN yv(dn,T);
    MatrixN Xt(dn,T);
    MatrixN yt(dn,T);
*/
    MatrixN X=Xr.block(0,0,n1,T);
    MatrixN y=yr.block(0,0,n1,T);
    MatrixN Xv=Xr.block(n1,0,dn,T);
    MatrixN yv=yr.block(n1,0,dn,T);
    MatrixN Xt=Xr.block(n1+dn,0,dn,T);
    MatrixN yt=yr.block(n1+dn,0,dn,T);

    unsigned int ctm=(unsigned int)std::time(0);
    std::srand(ctm);

    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlockOldStyle lb(R"({"name":"rnnreader","init":"orthonormal"})"_json);
    int VS=txt.vocsize();
    int H=128; // 400;
    int BS=128; // 96;
    //float clip=5.0;

    //int D=64;
    // CpParams cp0;
    // cp0.setPar("inputShape",vector<int>{T});
    // cp0.setPar("V",VS);
    // cp0.setPar("D",D);
    // cp0.setPar("clip",clip);
    // cp0.setPar("init",(string)"orthonormal");
    // lb.addLayer("WordEmbedding","WE0",cp0,{"input"});

    string rnntype="LSTM"; // or "RNN"
    cerr << "RNN-type: " << rnntype << endl;

    json j0;
    string oName{"OH0"};
    j0["inputShape"]=vector<int>{T};
    j0["V"]=VS;
    lb.addLayer("OneHot",oName,j0,{"input"});

    string nName;
    json j1;
    j1["inputShape"]=vector<int>{VS,T};
    j1["N"]=BS;
    j1["H"]=H;
    j1["forgetgateinitones"]=true;
    //j1["forgetbias"]=0.10;
    //j1["clip"]=clip;
    int layer_depth1=2; // 6;
    j1["H"]=H;
    for (auto l=0; l<layer_depth1; l++) {
        if (l>0) j1["inputShape"]=vector<int>{H,T};
        nName="lstm"+std::to_string(l);
        lb.addLayer(rnntype,nName,j1,{oName});
        oName=nName;
    }

    json j10;
    j10["inputShape"]=vector<int>{H,T};
    j10["M"]=VS;
    lb.addLayer("TemporalAffine","af1",j10,{oName});

    json j11;
    j11["inputShape"]=vector<int>{VS,T};
    cerr << "Adding softmax layer, inputShape: " << j11["inputShape"] << " VS: " << VS << " T: " << T << endl;
    lb.addLayer("TemporalSoftmax","sm1",j11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

    //json jc;
    //lb.getLayerConfiguration(jc);
    //cerr << jc.dump(4) << endl;

    // preseverstates no longer necessary for training!
    json jo(R"({"verbose":true,"shuffle":false,"preservestates":false,"notests":false,"nofragmentbatches":true})"_json);
    jo["lossfactor"]=1.0/(floatN)T;  // Allows to normalize the loss with T.
    //j_opt["inputShape"]=vector<int>{H,T};
    floatN dep=5.0; // 70.0;
    floatN sep=0.0;
    jo["epochs"]=(floatN)dep;
    jo["batch_size"]=BS;
    jo["lr_decay"] = 1.0;
    // XXX: regularization crashes the training.
    // jo["regularization"]=1.0e-5;
    // jo["regularization_decay"]=0.95;

    json j_opt(R"({"learning_rate": 1e-2})"_json);
    Optimizer *pOpt=optimizerFactory("Adam",j_opt);
    t_cppl OptimizerState{};

    json j_loss(R"({"name":"temporalsoftmax"})"_json);
    j_loss["inputShape"]=vector<int>{VS,T};
    Loss *pLoss=lossFactory("TemporalCrossEntropy",j_loss);

    for (int i=0; i<1000; i++) {
        jo["startepoch"]=(floatN)sep;
        t_cppl states;
        t_cppl statesv;
        states["y"] = new MatrixN(y);
        statesv["y"] = new MatrixN(yv);
        lb.train(X, &states, Xv, &statesv, pOpt, &OptimizerState, pLoss, jo);
        cppl_delete(&states);
        cppl_delete(&statesv);

        sep+=dep;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,T);

        MatrixN xg(1,T);
        for (int i=0; i<T; i++) {
            xg(0,i)=txt.w2v[instr[i]];
       }
        wstring sout{};
        Layer* plstm0=lb.layerMap["lstm0"];
        t_cppl statesg{};
        plstm0->genZeroStates(&statesg, 1);

        int g,t,v;
        for (g=0; g<300; g++) {
            t_cppl cache{};

            MatrixN probst=lb.forward(xg,&cache, &statesg);
            /* Wrong idea:
            // Forward generates the 'wrong' permutation of output. QUick-hack is abusing the 'cache' to get the permutation.
            if (cache.find("sm1-probst")==cache.end()) {
                cerr << "probst didn't make it, FATAL" << endl;
                exit(1);
            }
            MatrixN probst=*(cache["sm1-probst"]); // XXX check if temporal softmax uses redundant morpher!
            */
            MatrixN probsd=MatrixN(T,VS);
            for (t=0; t<T; t++) {
                for (v=0; v<VS; v++) {
                    probsd(t,v)=probst(0,t*VS+v);
                }
            }
            int li = -1;
            for (t=0; t<T; t++) {
                vector<floatN> probs(VS);
                vector<floatN> index(VS);
                for (v=0; v<VS; v++) {
                    probs[v]=probsd(t,v);
                    index[v]=v;
                }
                li=(int)index[randomChoice(index, probs)];
            }
            cppl_delete(&cache);

            for (int t=0; t<T-1; t++) {
                xg(0,t)=xg(0,t+1);
            }
            xg(0,T-1)=li;
            sout += txt.v2w[li];
        }
        wcout << "output: " << sout << endl;
        wstring timestr;
        currentDateTime(timestr);
        std::wofstream fl("rnnreader.txt", std::ios_base::app);
        fl << "---- " << timestr << ", ep:" << sep << " ---" << endl;
        fl << sout << endl;
        fl.close();
        cppl_delete(&statesg);
    }
    delete pOpt;
    cppl_delete(&OptimizerState);
    delete pLoss;
}
<commit_msg>cleaning<commit_after>#include <iostream>
#include <fstream>
#include <codecvt>
//#include <cstddef>
#include <locale>
#include <clocale>
#include <string>
#include <iomanip>
#include <ctime>

#include "cp-neural.h"

using std::wcout; using std::wstring;
using std::cerr; using std::vector;

class Text {
private:
    bool isinit=false;
    bool readDataFile(string inputfile) {
        std::wifstream txtfile(inputfile, std::ios::binary);
        if (!txtfile.is_open()) {
            return false;
        }
        txtfile.imbue(std::locale("en_US.UTF-8"));
        wstring ttext((std::istreambuf_iterator<wchar_t>(txtfile)),
                     std::istreambuf_iterator<wchar_t>());
        txtfile.close();
        text=ttext;
        filename=inputfile;
        return true;
    }
public:
    wstring text;
    string filename;
    std::map<wchar_t,int> freq;
    std::map<wchar_t,int> w2v;
    std::map<int,wchar_t> v2w;
    Text(string filename) {
        if (readDataFile(filename)) {
            for (auto wc : text) {
                freq[wc]++;
            }
            int it=0;
            for (auto wc : freq) {
                w2v[wc.first]=it;
                v2w[it]=wc.first;
                ++it;
            }
            isinit=true;
            cerr << "Freq:" << freq.size() << ", w2v:" << w2v.size() << ", v2w:" << v2w.size() << endl;
        }
    }
    ~Text() {

    }
    bool isInit() {
        return isinit;
    }
    int vocsize() {
        if (!isinit) return 0;
        return (int)v2w.size();
    }

    wstring sample(int len) {
        int p=std::rand()%(text.size()-len);
        return text.substr(p,len);
    }
};

void currentDateTime(wstring& timestr) {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
    timestr=std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(buf);
}

int main(int argc, char *argv[]) {
#ifndef __APPLE__
    std::setlocale(LC_ALL, "");
#else
    setlocale(LC_ALL, "");
    std::wcout.imbue(std::locale("en_US.UTF-8"));
#endif
    wcout << L"Rnn-Readär" << std::endl;

    bool allOk=true;
    if (argc!=2) {
        cerr << L"rnnreader <path-to-text-file>" << endl;
        exit(-1);
    }
    Text txt(argv[1]);
    if (!txt.isInit()) {
        cerr << "Cannot initialize Text object from inputfile: " << argv[1] << endl;
        exit(-1);
    }

    wcout << L"Text size: " << txt.text.size() << endl;

    wcout << L"Size of vocabulary:" << txt.freq.size() << std::endl;
/*    for (auto f : txt.freq) {
        int c=(int)f.first;
        wstring wc(1,f.first);
        wcout << wc << L"|" <<  wchar_t(f.first) << L"(0x" << std::hex << c << L")" ": " << std::dec <<  f.second << endl;
    }
*/
    Color::Modifier red(Color::FG_RED);
    Color::Modifier green(Color::FG_GREEN);
    Color::Modifier def(Color::FG_DEFAULT);

    int timeSteps=96;

    int N=(int)txt.text.size() / (timeSteps+1);
    cerr << N << " Max datasets" << endl;
    MatrixN Xr(N,timeSteps);
    MatrixN yr(N,timeSteps);

    wstring chunk,chunky;
    int n=0;
    for (int i=0; i<N; i++) {
        wstring smp = txt.sample(timeSteps+1);
        chunk=smp.substr(0,timeSteps);
        chunky=smp.substr(1,timeSteps);
        for (int t=0; t<timeSteps; t++) {
            Xr(i,t)=txt.w2v[chunk[t]];
            yr(i,t)=txt.w2v[chunky[t]];
        }
        ++n;
    }

    int maxN = 100000;
    if (n>maxN) n=maxN;
    int n1=n*0.9;
    int dn=(n-n1)/2;
    if (n1+2*dn > n) {
        cerr << "Math doesn't work out." << endl;
    }

    cerr << n1 << " datasets, " << dn << " test-sets, " << dn << " validation-sets" << endl;

    MatrixN X=Xr.block(0,0,n1,timeSteps);
    MatrixN y=yr.block(0,0,n1,timeSteps);
    MatrixN xVal=Xr.block(n1,0,dn,timeSteps);
    MatrixN yVal=yr.block(n1,0,dn,timeSteps);
    MatrixN xTest=Xr.block(n1+dn,0,dn,timeSteps);
    MatrixN yTest=yr.block(n1+dn,0,dn,timeSteps);

    unsigned int ctm=(unsigned int)std::time(0);
    std::srand(ctm);

    cpInitCompute("Rnnreader");
    registerLayers();

    LayerBlockOldStyle lb(R"({"name":"rnnreader","init":"orthonormal"})"_json);
    int vocabularySize=txt.vocsize();
    int H=128; // 400;
    int batchSize=128; // 96;
    //float clip=5.0;

    string rnntype="LSTM"; // or "RNN"
    cerr << "RNN-type: " << rnntype << endl;

    json j0;
    string oName{"OH0"};
    j0["inputShape"]=vector<int>{timeSteps};
    j0["V"]=vocabularySize;
    lb.addLayer("OneHot",oName,j0,{"input"});

    string nName;
    json j1;
    j1["inputShape"]=vector<int>{vocabularySize,timeSteps};
    j1["N"]=batchSize;
    j1["H"]=H;
    j1["forgetgateinitones"]=true;
    //j1["forgetbias"]=0.10;
    //j1["clip"]=clip;
    int layerDepth=8; // 6;
    j1["H"]=H;
    for (auto l=0; l<layerDepth; l++) {
        if (l>0) j1["inputShape"]=vector<int>{H,timeSteps};
        nName="lstm"+std::to_string(l);
        lb.addLayer(rnntype,nName,j1,{oName});
        oName=nName;
    }

    json j10;
    j10["inputShape"]=vector<int>{H,timeSteps};
    j10["M"]=vocabularySize;
    lb.addLayer("TemporalAffine","af1",j10,{oName});

    json j11;
    j11["inputShape"]=vector<int>{vocabularySize,timeSteps}; // currently inputShape of TempSoftmax MUST match inputShape of TemporalLoss
    lb.addLayer("TemporalSoftmax","sm1",j11,{"af1"});

    if (!lb.checkTopology(true)) {
        allOk=false;
        cerr << red << "Topology-check for LayerBlock: ERROR." << def << endl;
        exit(-1);
    } else {
        cerr << green << "Topology-check for LayerBlock: ok." << def << endl;
    }

    floatN episodes=5.0; // 70.0;
    floatN currentEpoch=0.0;

    json train_params(R"({"verbose":true,"shuffle":false,"notests":false,"nofragmentbatches":true})"_json);
    train_params["lossfactor"]=1.0/(floatN)timeSteps;  // Allows to normalize the loss with timeSteps.
    train_params["epochs"]=(floatN)episodes;
    train_params["batch_size"]=batchSize;
    train_params["lr_decay"] = 0.945; // every 40 epochs, lr = lr/10 (0.945^40 = 0.104)

    json j_opt(R"({"learning_rate": 1e-2})"_json);
    Optimizer *pOpt=optimizerFactory("Adam",j_opt);
    t_cppl OptimizerState{};

    json j_loss(R"({"name":"temporalsoftmax"})"_json);
    j_loss["inputShape"]=vector<int>{vocabularySize,timeSteps};
    Loss *pLoss=lossFactory("TemporalCrossEntropy",j_loss);

    for (int i=0; i<1000; i++) {
        train_params["startepoch"]=(floatN)currentEpoch;
        t_cppl states;
        t_cppl statesVal;
        states["y"] = new MatrixN(y);
        statesVal["y"] = new MatrixN(yVal);
        lb.train(X, &states, xVal, &statesVal, pOpt, &OptimizerState, pLoss, train_params);
        cppl_delete(&states);
        cppl_delete(&statesVal);

        currentEpoch+=episodes;

        int pos=rand() % 1000 + 5000;
        wstring instr=txt.text.substr(pos,timeSteps);

        MatrixN xg(1,timeSteps);
        for (int i=0; i<timeSteps; i++) {
            xg(0,i)=txt.w2v[instr[i]];
       }
        wstring sout{};
        Layer* plstm0=lb.layerMap["lstm0"];
        t_cppl statesg{};
        plstm0->genZeroStates(&statesg, 1);

        int g,t,v;
        for (g=0; g<300; g++) {
            t_cppl cache{};

            MatrixN probst=lb.forward(xg,&cache, &statesg);
            MatrixN probsd=MatrixN(timeSteps,vocabularySize);
            for (t=0; t<timeSteps; t++) {
                for (v=0; v<vocabularySize; v++) {
                    probsd(t,v)=probst(0,t*vocabularySize+v);
                }
            }
            int li = -1;
            for (t=0; t<timeSteps; t++) {
                vector<floatN> probs(vocabularySize);
                vector<floatN> index(vocabularySize);
                for (v=0; v<vocabularySize; v++) {
                    probs[v]=probsd(t,v);
                    index[v]=v;
                }
                li=(int)index[randomChoice(index, probs)];
            }
            cppl_delete(&cache);

            for (int t=0; t<timeSteps-1; t++) {
                xg(0,t)=xg(0,t+1);
            }
            xg(0,timeSteps-1)=li;
            sout += txt.v2w[li];
        }
        wcout << "output: " << sout << endl;
        wstring timestr;
        currentDateTime(timestr);
        std::wofstream fl("rnnreader.txt", std::ios_base::app);
        fl << "---- " << timestr << ", ep:" << currentEpoch << " ---" << endl;
        fl << sout << endl;
        fl.close();
        cppl_delete(&statesg);
    }
    delete pOpt;
    cppl_delete(&OptimizerState);
    delete pLoss;
}
<|endoftext|>


<commit_before>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2019 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

   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 "NFChatModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFPluginModule/NFIEventModule.h"

bool NFChatModule::Init()
{
	m_pNetModule = pPluginManager->FindModule<NFINetModule>();
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneModule = pPluginManager->FindModule<NFISceneModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();
	m_pGameServerToWorldModule = pPluginManager->FindModule<NFIGameServerToWorldModule>();

	return true;
}

bool NFChatModule::AfterInit()
{

	m_pNetModule->AddReceiveCallBack(NFMsg::EGMI_REQ_CHAT, this, &NFChatModule::OnClienChatProcess);

	return true;
}

bool NFChatModule::Shut()
{

	return true;
}

bool NFChatModule::Execute()
{
	return true;
}

void NFChatModule::OnClienChatProcess(const NFSOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	CLIENT_MSG_PROCESS( nMsgID, msg, nLen, NFMsg::ReqAckPlayerChat);

	switch (xMsg.chat_type())
	{
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_WORLD:
	{
		m_pNetModule->SendMsgPBToAllClient(NFMsg::EGMI_ACK_CHAT, xMsg);
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_CLAN:
	{
		NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
		NFGUID xClanID = m_pKernelModule->GetPropertyObject(nPlayerID, NFrame::Player::Clan_ID());
		if (!xClanID.IsNull() && xClanID == xTargetID)
		{
			//send to world server
			m_pGameServerToWorldModule->TransmitToWorld(xClanID.nData64, nMsgID, xMsg);
		}
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_PRIVATE:
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_TEAM:
	{
		if (xMsg.has_target_id())
		{
			NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
			if (!xTargetID.IsNull())
			{
				if (m_pKernelModule->GetObject(xTargetID))
				{

				}
				else
				{
					//send to world server
					m_pGameServerToWorldModule->TransmitToWorld(xTargetID.nData64, nMsgID, xMsg);
				}
			}
		}
	}
	break;
	default:
		break;;
	}
}<commit_msg>Chat system<commit_after>/*
            This file is part of:
                NoahFrame
            https://github.com/ketoo/NoahGameFrame

   Copyright 2009 - 2019 NoahFrame(NoahGameFrame)

   File creator: lvsheng.huang

   NoahFrame is open-source software and you can redistribute it and/or modify
   it under the terms of the License; besides, anyone who use this file/software must include this copyright announcement.

   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 "NFChatModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFPluginModule/NFIEventModule.h"

bool NFChatModule::Init()
{
	m_pNetModule = pPluginManager->FindModule<NFINetModule>();
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneModule = pPluginManager->FindModule<NFISceneModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();
	m_pGameServerToWorldModule = pPluginManager->FindModule<NFIGameServerToWorldModule>();

	return true;
}

bool NFChatModule::AfterInit()
{

	m_pNetModule->AddReceiveCallBack(NFMsg::EGMI_REQ_CHAT, this, &NFChatModule::OnClienChatProcess);

	return true;
}

bool NFChatModule::Shut()
{

	return true;
}

bool NFChatModule::Execute()
{
	return true;
}

void NFChatModule::OnClienChatProcess(const NFSOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	CLIENT_MSG_PROCESS( nMsgID, msg, nLen, NFMsg::ReqAckPlayerChat);

	switch (xMsg.chat_type())
	{
	case NFMsg::ReqAckPlayerChat::EGCT_WORLD:
	{
		m_pNetModule->SendMsgPBToAllClient(NFMsg::EGMI_ACK_CHAT, xMsg);
	}
	break;
	case NFMsg::ReqAckPlayerChat::EGCT_CLAN:
	{
		NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
		NFGUID xClanID = m_pKernelModule->GetPropertyObject(nPlayerID, NFrame::Player::Clan_ID());
		if (!xClanID.IsNull() && xClanID == xTargetID)
		{
			//send to world server
			m_pGameServerToWorldModule->TransmitToWorld(xClanID.nData64, nMsgID, xMsg);
		}
	}
	break;
	case NFMsg::ReqAckPlayerChat::EGCT_PRIVATE:
	{
		NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
		if (m_pKernelModule->ExistObject(xTargetID))
		{
			m_pGameServerNet_ServerModule->SendMsgPBToGate(nMsgID, xMsg, xTargetID);
		}
		else
		{
			//send to world server
			m_pGameServerToWorldModule->TransmitToWorld(xTargetID.nData64, nMsgID, xMsg);
		}
	}
	break;
	case NFMsg::ReqAckPlayerChat::EGCT_TEAM:
	{
		const int sceneID = m_pKernelModule->GetPropertyInt(nPlayerID, NFrame::Player::SceneID());
		const int groupID = m_pKernelModule->GetPropertyInt(nPlayerID, NFrame::Player::GroupID());

		m_pGameServerNet_ServerModule->SendGroupMsgPBToGate(nMsgID, xMsg, sceneID, groupID);
	}
	break;
	default:
		break;;
	}
}<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName			:    NFCoroutineModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2017-03-07
//    @Module           :    NFCoroutineModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCoroutineManager.h"

void ExecuteBody(NFCoroutine* co)
{

    //std::cout << "ExecuteBody " << co->nID << std::endl;

    co->func(co->arg);

    co->state = FREE;
    co->pSchdule->RemoveRunningID(co->nID);

    //std::cout << "func finished -- swap " << co->nID << " to -1" << std::endl;
}

NFCoroutineManager::NFCoroutineManager()
{
    std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    mnMainCoID = -1;
    mnRunningCoroutineID = -1;
    mnMaxIndex = 0;

    for (int i = 0; i < MAX_COROUTINE_CAPACITY; i++)
    {
        mxCoroutineList.push_back(new NFCoroutine(this, i));
    }

	std::cout << "created Coroutine number: " << MAX_COROUTINE_CAPACITY <<std::endl;
}

NFCoroutineManager::~NFCoroutineManager()
{
    for (int i = 0; i < MAX_COROUTINE_CAPACITY; i++)
    {
        delete mxCoroutineList[i];
    }
}

void NFCoroutineManager::Resume(int id)
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    if (id < 0 || id >= this->mnMaxIndex)
    {
        return;
    }

    NFCoroutine* t = GetCoroutine(id);
    if (t->state == SUSPEND)
    {
        std::cout << this->mnRunningCoroutineID << " swap to " << id << std::endl;

        this->mnRunningCoroutineID = id;

        swapcontext(&(this->mxMainCtx), &(t->ctx));
    }

#endif
}

void NFCoroutineManager::YieldCo()
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    if (this->mnRunningCoroutineID != -1)
    {
        NFCoroutine* t = GetRunningCoroutine();
        t->state = SUSPEND;

        //std::cout << "Yield " << this->mnRunningCoroutineID << " to -1" << std::endl;

        this->mnRunningCoroutineID = -1;

        swapcontext(&(t->ctx), &(mxMainCtx));
    }
#endif
}

void NFCoroutineManager::Init(CoroutineFunction func)
{
    mxMainFunc = func;
    mpMainArg = this;

    NewMainCoroutine();
}

void NFCoroutineManager::StartCoroutine()
{
    NewMainCoroutine();
}

void NFCoroutineManager::StartCoroutine(CoroutineFunction func)
{
    NewMainCoroutine();
    func(this);
}

void NFCoroutineManager::ScheduleJob()
{
    //std::cout << "threadid " << std::this_thread::get_id() << std::endl;

#if NF_PLATFORM != NF_PLATFORM_WIN
    if (mxRunningList.size() > 0)
    {
        int id = mxRunningList.front();
        mxRunningList.pop_front();

        NFCoroutine* pCoroutine = mxCoroutineList[id];

        if (pCoroutine->state == SUSPEND)
        {
            mxRunningList.push_back(id);

            Resume(id);
        }
    }
    else
    {
        NewMainCoroutine();
    }
#else
    mxMainFunc(this);
#endif
}

int NFCoroutineManager::GetRunningID()
{
    return mnRunningCoroutineID;
}

void NFCoroutineManager::SetRunningID(int id)
{
    mnRunningCoroutineID = id;
}

void NFCoroutineManager::RemoveRunningID(int id)
{
    mxRunningList.remove(id);
}

NFCoroutine* NFCoroutineManager::GetCoroutine(int id)
{
    if (id >= 0 && id < mnMaxIndex)
    {
        return mxCoroutineList[id];
    }

    return NULL;
}

NFCoroutine* NFCoroutineManager::GetRunningCoroutine()
{
    if (mnRunningCoroutineID < 0)
    {
        return NULL;
    }

    return mxCoroutineList[mnRunningCoroutineID];
}

NFCoroutine* NFCoroutineManager::AllotCoroutine()
{
    //std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    int id = 0;
    for (; id < mnMaxIndex; ++id)
    {
        if (mxCoroutineList[id]->state == FREE)
        {
            break;
        }
    }

    if (id == mnMaxIndex)
    {
        mnMaxIndex++;
    }

    return mxCoroutineList[id];
}

void NFCoroutineManager::NewMainCoroutine()
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    NFCoroutine* newCo = AllotCoroutine();
    if (newCo == NULL)
    {
        return;
    }

    mxRunningList.push_back(newCo->nID);
    //std::cout << "create NewMainCoroutine " << newCo->nID << std::endl;
    mnMainCoID = newCo->nID;

    newCo->state = CoroutineState::SUSPEND;
    newCo->func = mxMainFunc;
    newCo->arg = mpMainArg;

    getcontext(&(newCo->ctx));

    newCo->ctx.uc_stack.ss_sp = newCo->stack;
    newCo->ctx.uc_stack.ss_size = MAX_COROUTINE_STACK_SIZE;
    newCo->ctx.uc_stack.ss_flags = 0;
    newCo->ctx.uc_link = &(this->mxMainCtx);

    makecontext(&(newCo->ctx), (void (*)(void)) (ExecuteBody), 1, newCo);

#endif
}<commit_msg>removed log<commit_after>// -------------------------------------------------------------------------
//    @FileName			:    NFCoroutineModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2017-03-07
//    @Module           :    NFCoroutineModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCoroutineManager.h"

void ExecuteBody(NFCoroutine* co)
{

    //std::cout << "ExecuteBody " << co->nID << std::endl;

    co->func(co->arg);

    co->state = FREE;
    co->pSchdule->RemoveRunningID(co->nID);

    //std::cout << "func finished -- swap " << co->nID << " to -1" << std::endl;
}

NFCoroutineManager::NFCoroutineManager()
{
    std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    mnMainCoID = -1;
    mnRunningCoroutineID = -1;
    mnMaxIndex = 0;

    for (int i = 0; i < MAX_COROUTINE_CAPACITY; i++)
    {
        mxCoroutineList.push_back(new NFCoroutine(this, i));
    }

	std::cout << "created Coroutine number: " << MAX_COROUTINE_CAPACITY <<std::endl;
}

NFCoroutineManager::~NFCoroutineManager()
{
    for (int i = 0; i < MAX_COROUTINE_CAPACITY; i++)
    {
        delete mxCoroutineList[i];
    }
}

void NFCoroutineManager::Resume(int id)
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    if (id < 0 || id >= this->mnMaxIndex)
    {
        return;
    }

    NFCoroutine* t = GetCoroutine(id);
    if (t->state == SUSPEND)
    {
        //std::cout << this->mnRunningCoroutineID << " swap to " << id << std::endl;

        this->mnRunningCoroutineID = id;

        swapcontext(&(this->mxMainCtx), &(t->ctx));
    }

#endif
}

void NFCoroutineManager::YieldCo()
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    if (this->mnRunningCoroutineID != -1)
    {
        NFCoroutine* t = GetRunningCoroutine();
        t->state = SUSPEND;

        //std::cout << "Yield " << this->mnRunningCoroutineID << " to -1" << std::endl;

        this->mnRunningCoroutineID = -1;

        swapcontext(&(t->ctx), &(mxMainCtx));
    }
#endif
}

void NFCoroutineManager::Init(CoroutineFunction func)
{
    mxMainFunc = func;
    mpMainArg = this;

    NewMainCoroutine();
}

void NFCoroutineManager::StartCoroutine()
{
    NewMainCoroutine();
}

void NFCoroutineManager::StartCoroutine(CoroutineFunction func)
{
    NewMainCoroutine();
    func(this);
}

void NFCoroutineManager::ScheduleJob()
{
    //std::cout << "threadid " << std::this_thread::get_id() << std::endl;

#if NF_PLATFORM != NF_PLATFORM_WIN
    if (mxRunningList.size() > 0)
    {
        int id = mxRunningList.front();
        mxRunningList.pop_front();

        NFCoroutine* pCoroutine = mxCoroutineList[id];

        if (pCoroutine->state == SUSPEND)
        {
            mxRunningList.push_back(id);

            Resume(id);
        }
    }
    else
    {
        NewMainCoroutine();
    }
#else
    mxMainFunc(this);
#endif
}

int NFCoroutineManager::GetRunningID()
{
    return mnRunningCoroutineID;
}

void NFCoroutineManager::SetRunningID(int id)
{
    mnRunningCoroutineID = id;
}

void NFCoroutineManager::RemoveRunningID(int id)
{
    mxRunningList.remove(id);
}

NFCoroutine* NFCoroutineManager::GetCoroutine(int id)
{
    if (id >= 0 && id < mnMaxIndex)
    {
        return mxCoroutineList[id];
    }

    return NULL;
}

NFCoroutine* NFCoroutineManager::GetRunningCoroutine()
{
    if (mnRunningCoroutineID < 0)
    {
        return NULL;
    }

    return mxCoroutineList[mnRunningCoroutineID];
}

NFCoroutine* NFCoroutineManager::AllotCoroutine()
{
    //std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    int id = 0;
    for (; id < mnMaxIndex; ++id)
    {
        if (mxCoroutineList[id]->state == FREE)
        {
            break;
        }
    }

    if (id == mnMaxIndex)
    {
        mnMaxIndex++;
    }

    return mxCoroutineList[id];
}

void NFCoroutineManager::NewMainCoroutine()
{
#if NF_PLATFORM != NF_PLATFORM_WIN
    //std::cout << "threadid " << std::this_thread::get_id() << std::endl;

    NFCoroutine* newCo = AllotCoroutine();
    if (newCo == NULL)
    {
        return;
    }

    mxRunningList.push_back(newCo->nID);
    //std::cout << "create NewMainCoroutine " << newCo->nID << std::endl;
    mnMainCoID = newCo->nID;

    newCo->state = CoroutineState::SUSPEND;
    newCo->func = mxMainFunc;
    newCo->arg = mpMainArg;

    getcontext(&(newCo->ctx));

    newCo->ctx.uc_stack.ss_sp = newCo->stack;
    newCo->ctx.uc_stack.ss_size = MAX_COROUTINE_STACK_SIZE;
    newCo->ctx.uc_stack.ss_flags = 0;
    newCo->ctx.uc_link = &(this->mxMainCtx);

    makecontext(&(newCo->ctx), (void (*)(void)) (ExecuteBody), 1, newCo);

#endif
}<|endoftext|>


<commit_before>/* Copyright 2012-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

namespace watchman {

CookieSync::CookieSync(const w_string& dir) {
  setCookieDir(dir);
}

void CookieSync::setCookieDir(const w_string& dir) {
  cookieDir_ = dir;

  char hostname[256];
  gethostname(hostname, sizeof(hostname));
  hostname[sizeof(hostname) - 1] = '\0';

  cookiePrefix_ = w_string::printf(
      "%.*s/" WATCHMAN_COOKIE_PREFIX "%s-%d-",
      int(cookieDir_.size()),
      cookieDir_.data(),
      hostname,
      int(getpid()));
}

bool CookieSync::syncToNow(std::chrono::milliseconds timeout) {
  Cookie cookie;
  int errcode = 0;

  auto cookie_lock = std::unique_lock<std::mutex>(cookie.mutex);

  /* generate a cookie name: cookie prefix + id */
  auto path_str = w_string::printf(
      "%.*s%" PRIu32,
      int(cookiePrefix_.size()),
      cookiePrefix_.data(),
      serial_++);

  /* insert our cookie in the map */
  {
    auto wlock = cookies_.wlock();
    auto& map = *wlock;
    map[path_str] = &cookie;
  }

  /* compute deadline */
  auto deadline = std::chrono::system_clock::now() + timeout;

  /* touch the file */
  auto file = w_stm_open(
      path_str.c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0700);
  if (!file) {
    errcode = errno;
    w_log(
        W_LOG_ERR,
        "sync_to_now: creat(%s) failed: %s\n",
        path_str.c_str(),
        strerror(errcode));
    goto out;
  }
  file.reset();

  w_log(W_LOG_DBG, "sync_to_now [%s] waiting\n", path_str.c_str());

  /* timed cond wait (unlocks cookie lock, reacquires) */
  if (!cookie.cond.wait_until(
          cookie_lock, deadline, [&] { return cookie.seen; })) {
    w_log(
        W_LOG_ERR,
        "sync_to_now: %s timedwait failed: %d: istimeout=%d %s\n",
        path_str.c_str(),
        errcode,
        errcode == ETIMEDOUT,
        strerror(errcode));
    goto out;
  }
  w_log(W_LOG_DBG, "sync_to_now [%s] done\n", path_str.c_str());

out:
  cookie_lock.unlock();

  // can't unlink the file until after the cookie has been observed because
  // we don't know which file got changed until we look in the cookie dir
  unlink(path_str.c_str());

  {
    auto map = cookies_.wlock();
    map->erase(path_str);
  }

  if (!cookie.seen) {
    errno = errcode;
    return false;
  }

  return true;
}

void CookieSync::notifyCookie(const w_string& path) const {
  auto map = cookies_.rlock();
  auto cookie_iter = map->find(path);
  w_log(
      W_LOG_DBG,
      "cookie for %s? %s\n",
      path.c_str(),
      cookie_iter != map->end() ? "yes" : "no");

  if (cookie_iter != map->end()) {
    auto cookie = cookie_iter->second;
    auto cookie_lock = std::unique_lock<std::mutex>(cookie->mutex);
    cookie->seen = true;
    cookie->cond.notify_one();
  }
}
}
<commit_msg>fixup error messaging for timeout in cookie sync<commit_after>/* Copyright 2012-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

namespace watchman {

CookieSync::CookieSync(const w_string& dir) {
  setCookieDir(dir);
}

void CookieSync::setCookieDir(const w_string& dir) {
  cookieDir_ = dir;

  char hostname[256];
  gethostname(hostname, sizeof(hostname));
  hostname[sizeof(hostname) - 1] = '\0';

  cookiePrefix_ = w_string::printf(
      "%.*s/" WATCHMAN_COOKIE_PREFIX "%s-%d-",
      int(cookieDir_.size()),
      cookieDir_.data(),
      hostname,
      int(getpid()));
}

bool CookieSync::syncToNow(std::chrono::milliseconds timeout) {
  Cookie cookie;
  int errcode = 0;

  auto cookie_lock = std::unique_lock<std::mutex>(cookie.mutex);

  /* generate a cookie name: cookie prefix + id */
  auto path_str = w_string::printf(
      "%.*s%" PRIu32,
      int(cookiePrefix_.size()),
      cookiePrefix_.data(),
      serial_++);

  /* insert our cookie in the map */
  {
    auto wlock = cookies_.wlock();
    auto& map = *wlock;
    map[path_str] = &cookie;
  }

  /* compute deadline */
  auto deadline = std::chrono::system_clock::now() + timeout;

  /* touch the file */
  auto file = w_stm_open(
      path_str.c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0700);
  if (!file) {
    errcode = errno;
    log(ERR,
        "syncToNow: creat(",
        path_str,
        ") failed: ",
        strerror(errcode),
        "\n");
    goto out;
  }
  file.reset();

  log(DBG, "syncToNow [", path_str, "] waiting\n");

  /* timed cond wait (unlocks cookie lock, reacquires) */
  if (!cookie.cond.wait_until(
          cookie_lock, deadline, [&] { return cookie.seen; })) {
    log(ERR,
        "syncToNow: timed out waiting for cookie file ",
        path_str,
        " to be observed by watcher within ",
        timeout.count(),
        " milliseconds\n");
    errcode = ETIMEDOUT;
    goto out;
  }
  log(DBG, "syncToNow [", path_str, "] done\n");

out:
  cookie_lock.unlock();

  // can't unlink the file until after the cookie has been observed because
  // we don't know which file got changed until we look in the cookie dir
  unlink(path_str.c_str());

  {
    auto map = cookies_.wlock();
    map->erase(path_str);
  }

  if (!cookie.seen) {
    errno = errcode;
    return false;
  }

  return true;
}

void CookieSync::notifyCookie(const w_string& path) const {
  auto map = cookies_.rlock();
  auto cookie_iter = map->find(path);
  w_log(
      W_LOG_DBG,
      "cookie for %s? %s\n",
      path.c_str(),
      cookie_iter != map->end() ? "yes" : "no");

  if (cookie_iter != map->end()) {
    auto cookie = cookie_iter->second;
    auto cookie_lock = std::unique_lock<std::mutex>(cookie->mutex);
    cookie->seen = true;
    cookie->cond.notify_one();
  }
}
}
<|endoftext|>


<commit_before>#ifdef _WIN32

#include <windows.h>
#include <conio.h>

#else

#include <unistd.h> // for close()
#include <fcntl.h> // for open()
#include <sys/ioctl.h>

#endif

#include "libtorrent/config.hpp"

#include "print.hpp"

#include <stdlib.h> // for atoi
#include <string.h> // for strlen
#include <cmath>
#include <algorithm> // for std::min
#include <iterator> // for back_inserter

char const* esc(char const* code)
{
	// this is a silly optimization
	// to avoid copying of strings
	enum { num_strings = 200 };
	static char buf[num_strings][20];
	static int round_robin = 0;
	char* ret = buf[round_robin];
	++round_robin;
	if (round_robin >= num_strings) round_robin = 0;
	ret[0] = '\033';
	ret[1] = '[';
	int i = 2;
	int j = 0;
	while (code[j]) ret[i++] = code[j++];
	ret[i++] = 'm';
	ret[i++] = 0;
	return ret;
}

std::string to_string(int v, int width)
{
	char buf[100];
	snprintf(buf, sizeof(buf), "%*d", width, v);
	return buf;
}

std::string add_suffix(float val, char const* suffix)
{
	std::string ret;
	if (val == 0)
	{
		ret.resize(4 + 2, ' ');
		if (suffix) ret.resize(4 + 2 + strlen(suffix), ' ');
		return ret;
	}

	const char* prefix[] = {"kB", "MB", "GB", "TB"};
	const int num_prefix = sizeof(prefix) / sizeof(const char*);
	for (int i = 0; i < num_prefix; ++i)
	{
		val /= 1000.f;
		if (std::fabs(val) < 1000.f)
		{
			ret = to_string(val, 4);
			ret += prefix[i];
			if (suffix) ret += suffix;
			return ret;
		}
	}
	ret = to_string(val, 4);
	ret += "PB";
	if (suffix) ret += suffix;
	return ret;
}

std::string color(std::string const& s, color_code c)
{
	if (c == col_none) return s;

	char buf[1024];
	snprintf(buf, sizeof(buf), "\x1b[3%dm%s\x1b[39m", c, s.c_str());
	return buf;
}

std::string const& progress_bar(int progress, int width, color_code c
	, char fill, char bg, std::string caption, int flags)
{
	static std::string bar;
	bar.clear();
	bar.reserve(width + 10);

	int progress_chars = (progress * width + 500) / 1000;

	if (caption.empty())
	{
		char code[10];
		snprintf(code, sizeof(code), "\x1b[3%dm", c);
		bar = code;
		std::fill_n(std::back_inserter(bar), progress_chars, fill);
		std::fill_n(std::back_inserter(bar), width - progress_chars, bg);
		bar += esc("39");
	}
	else
	{
		// foreground color (depends a bit on background color)
		color_code tc = col_black;
		if (c == col_black || c == col_blue)
			tc = col_white;

		caption.resize(width, ' ');

		char str[256];
		if (flags & progress_invert)
			snprintf(str, sizeof(str), "\x1b[48;5;238m\x1b[37m%s\x1b[4%d;3%dm%s\x1b[49;39m"
				, caption.substr(0, progress_chars).c_str(), c, tc
				, caption.substr(progress_chars).c_str());
		else
			snprintf(str, sizeof(str), "\x1b[4%d;3%dm%s\x1b[48;5;238m\x1b[37m%s\x1b[49;39m"
				, c, tc, caption.substr(0, progress_chars).c_str(), caption.substr(progress_chars).c_str());
		bar = str;
	}
	return bar;
}

void set_cursor_pos(int x, int y)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD c = {x, y};
	SetConsoleCursorPosition(out, c);
#else
	printf("\033[%d;%dH", y + 1, x + 1);
#endif
}

void clear_screen()
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	COORD c = {0, 0};
	CONSOLE_SCREEN_BUFFER_INFO si;
	GetConsoleScreenBufferInfo(out, &si);
	DWORD n;
	FillConsoleOutputCharacter(out, ' ', si.dwSize.X * si.dwSize.Y, c, &n);
	FillConsoleOutputAttribute(out, 0x7, si.dwSize.X * si.dwSize.Y, c, &n);
#else
	printf("\033[2J");
#endif
}

void clear_rows(int y1, int y2)
{
	if (y1 > y2) return;

#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	COORD c = {0, y1};
	SetConsoleCursorPosition(out, c);
	CONSOLE_SCREEN_BUFFER_INFO si;
	GetConsoleScreenBufferInfo(out, &si);
	DWORD n;
	int num_chars = si.dwSize.X * (std::min)(si.dwSize.Y - y1, y2 - y1);
	FillConsoleOutputCharacter(out, ' ', num_chars, c, &n);
	FillConsoleOutputAttribute(out, 0x7, num_chars, c, &n);
#else
	for (int i = y1; i < y2; ++i)
		printf("\033[%d;1H\033[2K", i + 1);
#endif
}

void terminal_size(int* terminal_width, int* terminal_height)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO coninfo;
	if (GetConsoleScreenBufferInfo(out, &coninfo))
	{
		*terminal_width = coninfo.dwSize.X;
		*terminal_height = coninfo.srWindow.Bottom - coninfo.srWindow.Top;
#else
	int tty = open("/dev/tty", O_RDONLY);
	winsize size;
	int ret = ioctl(tty, TIOCGWINSZ, (char*)&size);
	close(tty);
	if (ret == 0)
	{
		*terminal_width = size.ws_col;
		*terminal_height = size.ws_row;
#endif

		if (*terminal_width < 64)
			*terminal_width = 64;
		if (*terminal_height < 25)
			*terminal_height = 25;
	}
	else
	{
		*terminal_width = 190;
		*terminal_height = 100;
	}
}

#ifdef _WIN32
void apply_ansi_code(int* attributes, bool* reverse, int code)
{
	const static int color_table[8] =
	{
		0, // black
		FOREGROUND_RED, // red
		FOREGROUND_GREEN, // green
		FOREGROUND_RED | FOREGROUND_GREEN, // yellow
		FOREGROUND_BLUE, // blue
		FOREGROUND_RED | FOREGROUND_BLUE, // magenta
		FOREGROUND_BLUE | FOREGROUND_GREEN, // cyan
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE // white
	};

	enum
	{
		foreground_mask = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
		background_mask = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
	};

	const static int fg_mask[2] = {foreground_mask, background_mask};
	const static int bg_mask[2] = {background_mask, foreground_mask};
	const static int fg_shift[2] = { 0, 4};
	const static int bg_shift[2] = { 4, 0};

	if (code == 0)
	{
		// reset
		*attributes = color_table[7];
		*reverse = false;
	}
	else if (code == 7)
	{
		if (*reverse) return;
		*reverse = true;
		int fg_col = *attributes & foreground_mask;
		int bg_col = (*attributes & background_mask) >> 4;
		*attributes &= ~(foreground_mask + background_mask);
		*attributes |= fg_col << 4;
		*attributes |= bg_col;
	}
	else if (code >= 30 && code <= 37)
	{
		// foreground color
		*attributes &= ~fg_mask[*reverse];
		*attributes |= color_table[code - 30] << fg_shift[*reverse];
	}
	else if (code >= 40 && code <= 47)
	{
		// foreground color
		*attributes &= ~bg_mask[*reverse];
		*attributes |= color_table[code - 40] << bg_shift[*reverse];
	}
}
#endif
void print(char const* str)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	char buffer[4096];
	char* buf = buffer;
	strcpy(buf, str);

	int current_attributes = 7;
	bool reverse = false;
	SetConsoleTextAttribute(out, current_attributes);

	char* start = buf;
	DWORD written;
	while (*buf != 0)
	{
		if (*buf == '\033' && buf[1] == '[')
		{
			*buf = 0;
			WriteFile(out, start, buf - start, &written, NULL);
			buf += 2; // skip escape and '['
			start = buf;
		one_more:
			while (*buf != 'm' && *buf != ';' && *buf != 0) ++buf;
			if (*buf == 0) break;
			int code = atoi(start);
			apply_ansi_code(&current_attributes, &reverse, code);
			if (*buf == ';')
			{
				++buf;
				start = buf;
				goto one_more;
			}
			SetConsoleTextAttribute(out, current_attributes);
			++buf; // skip 'm'
			start = buf;
		}
		else
		{
			++buf;
		}
	}
	WriteFile(out, start, buf - start, &written, NULL);

#else
	puts(str);
#endif
}

<commit_msg>improve printing of rates and counters in client_test<commit_after>#ifdef _WIN32

#include <windows.h>
#include <conio.h>

#else

#include <unistd.h> // for close()
#include <fcntl.h> // for open()
#include <sys/ioctl.h>

#endif

#include "libtorrent/config.hpp"

#include "print.hpp"

#include <stdlib.h> // for atoi
#include <string.h> // for strlen
#include <cmath>
#include <algorithm> // for std::min
#include <iterator> // for back_inserter

char const* esc(char const* code)
{
	// this is a silly optimization
	// to avoid copying of strings
	enum { num_strings = 200 };
	static char buf[num_strings][20];
	static int round_robin = 0;
	char* ret = buf[round_robin];
	++round_robin;
	if (round_robin >= num_strings) round_robin = 0;
	ret[0] = '\033';
	ret[1] = '[';
	int i = 2;
	int j = 0;
	while (code[j]) ret[i++] = code[j++];
	ret[i++] = 'm';
	ret[i++] = 0;
	return ret;
}

std::string to_string(int v, int width)
{
	char buf[100];
	snprintf(buf, sizeof(buf), "%*d", width, v);
	return buf;
}

std::string add_suffix(float val, char const* suffix)
{
	if (val == 0)
	{
		std::string ret;
		ret.resize(4 + 2, ' ');
		if (suffix) ret.resize(4 + 2 + strlen(suffix), ' ');
		return ret;
	}

	const char* prefix[] = {"kB", "MB", "GB", "TB", "PB"};
	const int num_prefix = sizeof(prefix) / sizeof(const char*);
	int i = 0;
	for (; i < num_prefix - 1; ++i)
	{
		val /= 1000.f;
		if (std::fabs(val) < 1000.f) break;
	}
	char ret[100];
	snprintf(ret, sizeof(ret), "%4.*f%s%s", val < 99 ? 1 : 0, val, prefix[i], suffix ? suffix : "");
	return ret;
}

std::string color(std::string const& s, color_code c)
{
	if (c == col_none) return s;

	char buf[1024];
	snprintf(buf, sizeof(buf), "\x1b[3%dm%s\x1b[39m", c, s.c_str());
	return buf;
}

std::string const& progress_bar(int progress, int width, color_code c
	, char fill, char bg, std::string caption, int flags)
{
	static std::string bar;
	bar.clear();
	bar.reserve(width + 10);

	int progress_chars = (progress * width + 500) / 1000;

	if (caption.empty())
	{
		char code[10];
		snprintf(code, sizeof(code), "\x1b[3%dm", c);
		bar = code;
		std::fill_n(std::back_inserter(bar), progress_chars, fill);
		std::fill_n(std::back_inserter(bar), width - progress_chars, bg);
		bar += esc("39");
	}
	else
	{
		// foreground color (depends a bit on background color)
		color_code tc = col_black;
		if (c == col_black || c == col_blue)
			tc = col_white;

		caption.resize(width, ' ');

		char str[256];
		if (flags & progress_invert)
			snprintf(str, sizeof(str), "\x1b[48;5;238m\x1b[37m%s\x1b[4%d;3%dm%s\x1b[49;39m"
				, caption.substr(0, progress_chars).c_str(), c, tc
				, caption.substr(progress_chars).c_str());
		else
			snprintf(str, sizeof(str), "\x1b[4%d;3%dm%s\x1b[48;5;238m\x1b[37m%s\x1b[49;39m"
				, c, tc, caption.substr(0, progress_chars).c_str(), caption.substr(progress_chars).c_str());
		bar = str;
	}
	return bar;
}

void set_cursor_pos(int x, int y)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD c = {x, y};
	SetConsoleCursorPosition(out, c);
#else
	printf("\033[%d;%dH", y + 1, x + 1);
#endif
}

void clear_screen()
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	COORD c = {0, 0};
	CONSOLE_SCREEN_BUFFER_INFO si;
	GetConsoleScreenBufferInfo(out, &si);
	DWORD n;
	FillConsoleOutputCharacter(out, ' ', si.dwSize.X * si.dwSize.Y, c, &n);
	FillConsoleOutputAttribute(out, 0x7, si.dwSize.X * si.dwSize.Y, c, &n);
#else
	printf("\033[2J");
#endif
}

void clear_rows(int y1, int y2)
{
	if (y1 > y2) return;

#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	COORD c = {0, y1};
	SetConsoleCursorPosition(out, c);
	CONSOLE_SCREEN_BUFFER_INFO si;
	GetConsoleScreenBufferInfo(out, &si);
	DWORD n;
	int num_chars = si.dwSize.X * (std::min)(si.dwSize.Y - y1, y2 - y1);
	FillConsoleOutputCharacter(out, ' ', num_chars, c, &n);
	FillConsoleOutputAttribute(out, 0x7, num_chars, c, &n);
#else
	for (int i = y1; i < y2; ++i)
		printf("\033[%d;1H\033[2K", i + 1);
#endif
}

void terminal_size(int* terminal_width, int* terminal_height)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO coninfo;
	if (GetConsoleScreenBufferInfo(out, &coninfo))
	{
		*terminal_width = coninfo.dwSize.X;
		*terminal_height = coninfo.srWindow.Bottom - coninfo.srWindow.Top;
#else
	int tty = open("/dev/tty", O_RDONLY);
	winsize size;
	int ret = ioctl(tty, TIOCGWINSZ, (char*)&size);
	close(tty);
	if (ret == 0)
	{
		*terminal_width = size.ws_col;
		*terminal_height = size.ws_row;
#endif

		if (*terminal_width < 64)
			*terminal_width = 64;
		if (*terminal_height < 25)
			*terminal_height = 25;
	}
	else
	{
		*terminal_width = 190;
		*terminal_height = 100;
	}
}

#ifdef _WIN32
void apply_ansi_code(int* attributes, bool* reverse, int code)
{
	const static int color_table[8] =
	{
		0, // black
		FOREGROUND_RED, // red
		FOREGROUND_GREEN, // green
		FOREGROUND_RED | FOREGROUND_GREEN, // yellow
		FOREGROUND_BLUE, // blue
		FOREGROUND_RED | FOREGROUND_BLUE, // magenta
		FOREGROUND_BLUE | FOREGROUND_GREEN, // cyan
		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE // white
	};

	enum
	{
		foreground_mask = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
		background_mask = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
	};

	const static int fg_mask[2] = {foreground_mask, background_mask};
	const static int bg_mask[2] = {background_mask, foreground_mask};
	const static int fg_shift[2] = { 0, 4};
	const static int bg_shift[2] = { 4, 0};

	if (code == 0)
	{
		// reset
		*attributes = color_table[7];
		*reverse = false;
	}
	else if (code == 7)
	{
		if (*reverse) return;
		*reverse = true;
		int fg_col = *attributes & foreground_mask;
		int bg_col = (*attributes & background_mask) >> 4;
		*attributes &= ~(foreground_mask + background_mask);
		*attributes |= fg_col << 4;
		*attributes |= bg_col;
	}
	else if (code >= 30 && code <= 37)
	{
		// foreground color
		*attributes &= ~fg_mask[*reverse];
		*attributes |= color_table[code - 30] << fg_shift[*reverse];
	}
	else if (code >= 40 && code <= 47)
	{
		// foreground color
		*attributes &= ~bg_mask[*reverse];
		*attributes |= color_table[code - 40] << bg_shift[*reverse];
	}
}
#endif
void print(char const* str)
{
#ifdef _WIN32
	HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);

	char buffer[4096];
	char* buf = buffer;
	strcpy(buf, str);

	int current_attributes = 7;
	bool reverse = false;
	SetConsoleTextAttribute(out, current_attributes);

	char* start = buf;
	DWORD written;
	while (*buf != 0)
	{
		if (*buf == '\033' && buf[1] == '[')
		{
			*buf = 0;
			WriteFile(out, start, buf - start, &written, NULL);
			buf += 2; // skip escape and '['
			start = buf;
		one_more:
			while (*buf != 'm' && *buf != ';' && *buf != 0) ++buf;
			if (*buf == 0) break;
			int code = atoi(start);
			apply_ansi_code(&current_attributes, &reverse, code);
			if (*buf == ';')
			{
				++buf;
				start = buf;
				goto one_more;
			}
			SetConsoleTextAttribute(out, current_attributes);
			++buf; // skip 'm'
			start = buf;
		}
		else
		{
			++buf;
		}
	}
	WriteFile(out, start, buf - start, &written, NULL);

#else
	puts(str);
#endif
}

<|endoftext|>


<commit_before>#include <sstream>
#include "FemusDefault.hpp"
#include "FemusInit.hpp"
#include "MultiLevelMesh.hpp"
#include "WriterEnum.hpp"

using namespace femus;

// Test for SalomeIO reading

int main(int argc,char **args) {

  FemusInit init(argc,args,MPI_COMM_WORLD);

  std::string med_file = "GroupsANDMeshes.med";
  std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file;
  const std::string infile = mystream.str();

  //Adimensional
  double Lref = 1.;

  MultiLevelMesh ml_msh;
  ml_msh.ReadCoarseMesh(infile.c_str(),"fifth",Lref);

  ml_msh.SetWriter(XDMF);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");
  ml_msh.SetWriter(VTK);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");
  ml_msh.SetWriter(GMV);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");

  return 0;
}
<commit_msg>Found problem in testSalome<commit_after>#include <sstream>
#include "FemusDefault.hpp"
#include "FemusInit.hpp"
#include "MultiLevelMesh.hpp"
#include "WriterEnum.hpp"

using namespace femus;

// Test for SalomeIO reading

int main(int argc,char **args) {

  FemusInit init(argc,args,MPI_COMM_WORLD);

  std::string med_file = "GroupsANDMeshes.med";
  std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file;
  const std::string infile = mystream.str();

  //Adimensional
  double Lref = 1.;

  MultiLevelMesh ml_msh;
  ml_msh.ReadCoarseMesh(infile.c_str(),"fifth",Lref);

  ml_msh.SetWriter(XDMF);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");
  ml_msh.SetWriter(GMV);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");
  ml_msh.SetWriter(VTK);
  ml_msh.GetWriter()->write(DEFAULT_OUTPUTDIR,"biquadratic");

  return 0;
}
<|endoftext|>


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

#include <nvbio/io/output_stream.h>
#include <nvbio/basic/console.h>
#include <zlib/zlib.h>
#include <lz4/lz4frame.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

namespace nvbio {

GZOutputFile::GZOutputFile(const char* name, const char* comp)
{
    char options_string[16];
    sprintf( options_string, "w%s", comp);

    m_file = gzopen( name, options_string );
}
GZOutputFile::~GZOutputFile()
{
    if (m_file)
        gzclose( m_file );
}

uint32 GZOutputFile::write(const uint32 bytes, const void* buffer)
{
    if (bytes == 0)
        return 0;

    const int r = gzwrite( m_file, buffer, bytes );
    if (r <= 0)
    {
        gzclose( m_file );
        m_file = NULL;
        return 0;
    }
    return uint32(r);
}

LZ4OutputFile::LZ4OutputFile(const char* name, const char* comp)
{
    fprintf(stderr, "LZ4OutputFile\n" );
    m_file = (FILE*)fopen( name, "wb" );
    if (m_file == NULL)
        return;

    m_buffer.resize( 1024*1024 );

    // create a compression context
    LZ4F_createCompressionContext( &m_context, LZ4F_VERSION );

    LZ4F_preferences_t* preferences = (LZ4F_preferences_t*)calloc( sizeof(LZ4F_preferences_t), 1u );
        // TODO: handle compression modes

    const size_t compressed_bytes = LZ4F_compressBegin( m_context, &m_buffer[0], m_buffer.size(), preferences );

    if (compressed_bytes == 0)
        return;

    // write down
    if (fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file ) < compressed_bytes)
    {
        // an error has occurred, shutdown the file
        fclose( (FILE*)m_file ); m_file = NULL;

        LZ4F_freeCompressionContext( m_context ); m_context = NULL;
    }
}
LZ4OutputFile::~LZ4OutputFile()
{
    // flush any remaining data
    if (m_context && m_file)
    {
        const size_t compressed_bytes = LZ4F_compressEnd( m_context, &m_buffer[0], m_buffer.size(), NULL );

        fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file );
    }

    if (m_file)
        fclose( (FILE*)m_file );

    if (m_context)
        LZ4F_freeCompressionContext( m_context );
}

uint32 LZ4OutputFile::write(const uint32 bytes, const void* buffer)
{
    if (bytes == 0)
        return 0;

    const size_t dst_max = LZ4F_compressBound( bytes, NULL );
    if (m_buffer.size() <= dst_max)
        m_buffer.resize( dst_max );

    // compress in-memory
    const size_t compressed_bytes = LZ4F_compressUpdate( m_context, &m_buffer[0], m_buffer.size(), buffer, bytes, NULL );

    // check whether the compressor has actually produced any output
    if (compressed_bytes == 0)
        return bytes;

    // write down
    if (fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file ) < compressed_bytes)
    {
        // an error has occurred, shutdown the file
        fclose( (FILE*)m_file ); m_file = NULL;

        LZ4F_freeCompressionContext( m_context ); m_context = NULL;
    }
    return bytes;
}

// output file factory method
//
OutputStream* open_output_file(const char* file_name, const char* compressor, const char* options)
{
    if (compressor == NULL || strcmp( compressor, "" ) == 0)
        return new GZOutputFile( file_name, "T" );
    else if (strcmp( compressor, "gzip" ) == 0 || strcmp( compressor, "gz" ) == 0)
        return new GZOutputFile( file_name, options );
    else if (strcmp( compressor, "lz4" ) == 0)
        return new LZ4OutputFile( file_name, options );

    log_warning(stderr, "unknown output file compressor \"%s\"\n", compressor );
    return NULL;
}

} // namespace nvbio
<commit_msg>removed debug printfs<commit_after>/*
 * nvbio
 * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the NVIDIA CORPORATION nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <nvbio/io/output_stream.h>
#include <nvbio/basic/console.h>
#include <zlib/zlib.h>
#include <lz4/lz4frame.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

namespace nvbio {

GZOutputFile::GZOutputFile(const char* name, const char* comp)
{
    char options_string[16];
    sprintf( options_string, "w%s", comp);

    m_file = gzopen( name, options_string );
}
GZOutputFile::~GZOutputFile()
{
    if (m_file)
        gzclose( m_file );
}

uint32 GZOutputFile::write(const uint32 bytes, const void* buffer)
{
    if (bytes == 0)
        return 0;

    const int r = gzwrite( m_file, buffer, bytes );
    if (r <= 0)
    {
        gzclose( m_file );
        m_file = NULL;
        return 0;
    }
    return uint32(r);
}

LZ4OutputFile::LZ4OutputFile(const char* name, const char* comp)
{
    m_file = (FILE*)fopen( name, "wb" );
    if (m_file == NULL)
        return;

    m_buffer.resize( 1024*1024 );

    // create a compression context
    LZ4F_createCompressionContext( &m_context, LZ4F_VERSION );

    LZ4F_preferences_t* preferences = (LZ4F_preferences_t*)calloc( sizeof(LZ4F_preferences_t), 1u );
        // TODO: handle compression modes

    const size_t compressed_bytes = LZ4F_compressBegin( m_context, &m_buffer[0], m_buffer.size(), preferences );

    if (compressed_bytes == 0)
        return;

    // write down
    if (fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file ) < compressed_bytes)
    {
        // an error has occurred, shutdown the file
        fclose( (FILE*)m_file ); m_file = NULL;

        LZ4F_freeCompressionContext( m_context ); m_context = NULL;
    }
}
LZ4OutputFile::~LZ4OutputFile()
{
    // flush any remaining data
    if (m_context && m_file)
    {
        const size_t compressed_bytes = LZ4F_compressEnd( m_context, &m_buffer[0], m_buffer.size(), NULL );

        fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file );
    }

    if (m_file)
        fclose( (FILE*)m_file );

    if (m_context)
        LZ4F_freeCompressionContext( m_context );
}

uint32 LZ4OutputFile::write(const uint32 bytes, const void* buffer)
{
    if (bytes == 0)
        return 0;

    const size_t dst_max = LZ4F_compressBound( bytes, NULL );
    if (m_buffer.size() <= dst_max)
        m_buffer.resize( dst_max );

    // compress in-memory
    const size_t compressed_bytes = LZ4F_compressUpdate( m_context, &m_buffer[0], m_buffer.size(), buffer, bytes, NULL );

    // check whether the compressor has actually produced any output
    if (compressed_bytes == 0)
        return bytes;

    // write down
    if (fwrite( &m_buffer[0], 1u, compressed_bytes, (FILE*)m_file ) < compressed_bytes)
    {
        // an error has occurred, shutdown the file
        fclose( (FILE*)m_file ); m_file = NULL;

        LZ4F_freeCompressionContext( m_context ); m_context = NULL;
    }
    return bytes;
}

// output file factory method
//
OutputStream* open_output_file(const char* file_name, const char* compressor, const char* options)
{
    if (compressor == NULL || strcmp( compressor, "" ) == 0)
        return new GZOutputFile( file_name, "T" );
    else if (strcmp( compressor, "gzip" ) == 0 || strcmp( compressor, "gz" ) == 0)
        return new GZOutputFile( file_name, options );
    else if (strcmp( compressor, "lz4" ) == 0)
        return new LZ4OutputFile( file_name, options );

    log_warning(stderr, "unknown output file compressor \"%s\"\n", compressor );
    return NULL;
}

} // namespace nvbio
<|endoftext|>


<commit_before>#include <ctime>

#include "uipcp-rib.hpp"

using namespace std;

static uint64_t time64()
{
    struct timespec tv;

    if (clock_gettime(CLOCK_MONOTONIC, &tv)) {
        PE("clock_gettime() failed\n");
        tv.tv_sec = 0;
        tv.tv_nsec = 0;
    }

    return (tv.tv_sec << 32) | (tv.tv_nsec & ((1L << 32) - 1L));
}

uint64_t
uipcp_rib::dft_lookup(const RinaName& appl_name) const
{
    map< string, DFTEntry >::const_iterator mit
         = dft.find(static_cast<string>(appl_name));

    if (mit == dft.end()) {
        return 0;
    }

    return mit->second.address;
}

int
uipcp_rib::dft_set(const RinaName& appl_name, uint64_t remote_addr)
{
    string key = static_cast<string>(appl_name);
    DFTEntry entry;

    entry.address = remote_addr;
    entry.appl_name = appl_name;
    entry.timestamp = time64();

    dft[key] = entry;

    PD("[uipcp %u] setting DFT entry '%s' --> %llu\n", uipcp->ipcp_id,
       key.c_str(), (long long unsigned)entry.address);

    return 0;
}

int
uipcp_rib::application_register(int reg, const RinaName& appl_name)
{
    map< string, DFTEntry >::iterator mit;
    uint64_t local_addr;
    string name_str;
    int ret;
    bool create = true;
    DFTSlice dft_slice;
    DFTEntry dft_entry;

    ret = rinalite_lookup_ipcp_addr_by_id(&uipcp->appl.loop,
                                          uipcp->ipcp_id,
                                          &local_addr);
    assert(!ret);

    dft_entry.address = local_addr;
    dft_entry.appl_name = appl_name;
    dft_entry.timestamp = time64();
    name_str = static_cast<string>(dft_entry.appl_name);

    mit = dft.find(name_str);

    if (reg) {
        if (mit != dft.end()) {
            PE("Application %s already registered on uipcp with address "
                    "[%llu], my address being [%llu]\n", name_str.c_str(),
                    (long long unsigned)mit->second.address,
                    (long long unsigned)local_addr);
            return -1;
        }

        /* Insert the object into the RIB. */
        dft.insert(make_pair(name_str, dft_entry));

    } else {
        if (mit == dft.end()) {
            PE("Application %s was not registered here\n",
                name_str.c_str());
            return -1;
        }

        /* Remove the object from the RIB. */
        dft.erase(mit);
        create = false;
    }

    dft_slice.entries.push_back(dft_entry);

    PD("Application %s %sregistered %s uipcp %d\n",
            name_str.c_str(), reg ? "" : "un", reg ? "to" : "from",
            uipcp->ipcp_id);

    remote_sync_all(create, obj_class::dft, obj_name::dft, &dft_slice);

    return 0;
}

int
uipcp_rib::dft_handler(const CDAPMessage *rm, Neighbor *neigh)
{
    const char *objbuf;
    size_t objlen;
    bool add = true;

    if (rm->op_code != gpb::M_CREATE && rm->op_code != gpb::M_DELETE) {
        PE("M_CREATE or M_DELETE expected\n");
        return 0;
    }

    if (rm->op_code == gpb::M_DELETE) {
        add = false;
    }

    rm->get_obj_value(objbuf, objlen);
    if (!objbuf) {
        PE("M_START does not contain a nested message\n");
        abort();
        return 0;
    }

    DFTSlice dft_slice(objbuf, objlen);
    DFTSlice prop_dft;

    for (list<DFTEntry>::iterator e = dft_slice.entries.begin();
                                e != dft_slice.entries.end(); e++) {
        string key = static_cast<string>(e->appl_name);
        map< string, DFTEntry >::iterator mit = dft.find(key);

        if (add) {
            if (mit == dft.end() || e->timestamp > mit->second.timestamp) {
                dft[key] = *e;
                PD("DFT entry %s %s remotely\n", key.c_str(),
                        (mit != dft.end() ? "updated" : "added"));
            }

        } else {
            if (mit == dft.end()) {
                PI("DFT entry does not exist\n");
            } else {
                dft.erase(mit);
                prop_dft.entries.push_back(*e);
                PD("DFT entry %s removed remotely\n", key.c_str());
            }

        }
    }

    if (add) {
        prop_dft = dft_slice;
    }

    if (prop_dft.entries.size()) {
        /* Propagate the DFT entries update to the other neighbors,
         * except for the one. */
        /* TODO loops are not managed here! */
        remote_sync_excluding(neigh, add, obj_class::dft,
                              obj_name::dft, &prop_dft);

    }

    return 0;
}

<commit_msg>uipcp: application-registration: avoid DFT update cycles<commit_after>#include <ctime>

#include "uipcp-rib.hpp"

using namespace std;

static uint64_t time64()
{
    struct timespec tv;

    if (clock_gettime(CLOCK_MONOTONIC, &tv)) {
        PE("clock_gettime() failed\n");
        tv.tv_sec = 0;
        tv.tv_nsec = 0;
    }

    return (tv.tv_sec << 32) | (tv.tv_nsec & ((1L << 32) - 1L));
}

uint64_t
uipcp_rib::dft_lookup(const RinaName& appl_name) const
{
    map< string, DFTEntry >::const_iterator mit
         = dft.find(static_cast<string>(appl_name));

    if (mit == dft.end()) {
        return 0;
    }

    return mit->second.address;
}

int
uipcp_rib::dft_set(const RinaName& appl_name, uint64_t remote_addr)
{
    string key = static_cast<string>(appl_name);
    DFTEntry entry;

    entry.address = remote_addr;
    entry.appl_name = appl_name;
    entry.timestamp = time64();

    dft[key] = entry;

    PD("[uipcp %u] setting DFT entry '%s' --> %llu\n", uipcp->ipcp_id,
       key.c_str(), (long long unsigned)entry.address);

    return 0;
}

int
uipcp_rib::application_register(int reg, const RinaName& appl_name)
{
    map< string, DFTEntry >::iterator mit;
    uint64_t local_addr;
    string name_str;
    int ret;
    bool create = true;
    DFTSlice dft_slice;
    DFTEntry dft_entry;

    ret = rinalite_lookup_ipcp_addr_by_id(&uipcp->appl.loop,
                                          uipcp->ipcp_id,
                                          &local_addr);
    assert(!ret);

    dft_entry.address = local_addr;
    dft_entry.appl_name = appl_name;
    dft_entry.timestamp = time64();
    name_str = static_cast<string>(dft_entry.appl_name);

    mit = dft.find(name_str);

    if (reg) {
        if (mit != dft.end()) {
            PE("Application %s already registered on uipcp with address "
                    "[%llu], my address being [%llu]\n", name_str.c_str(),
                    (long long unsigned)mit->second.address,
                    (long long unsigned)local_addr);
            return -1;
        }

        /* Insert the object into the RIB. */
        dft.insert(make_pair(name_str, dft_entry));

    } else {
        if (mit == dft.end()) {
            PE("Application %s was not registered here\n",
                name_str.c_str());
            return -1;
        }

        /* Remove the object from the RIB. */
        dft.erase(mit);
        create = false;
    }

    dft_slice.entries.push_back(dft_entry);

    PD("Application %s %sregistered %s uipcp %d\n",
            name_str.c_str(), reg ? "" : "un", reg ? "to" : "from",
            uipcp->ipcp_id);

    remote_sync_all(create, obj_class::dft, obj_name::dft, &dft_slice);

    return 0;
}

int
uipcp_rib::dft_handler(const CDAPMessage *rm, Neighbor *neigh)
{
    const char *objbuf;
    size_t objlen;
    bool add = true;

    if (rm->op_code != gpb::M_CREATE && rm->op_code != gpb::M_DELETE) {
        PE("M_CREATE or M_DELETE expected\n");
        return 0;
    }

    if (rm->op_code == gpb::M_DELETE) {
        add = false;
    }

    rm->get_obj_value(objbuf, objlen);
    if (!objbuf) {
        PE("M_START does not contain a nested message\n");
        abort();
        return 0;
    }

    DFTSlice dft_slice(objbuf, objlen);
    DFTSlice prop_dft;

    for (list<DFTEntry>::iterator e = dft_slice.entries.begin();
                                e != dft_slice.entries.end(); e++) {
        string key = static_cast<string>(e->appl_name);
        map< string, DFTEntry >::iterator mit = dft.find(key);

        if (add) {
            if (mit == dft.end() || e->timestamp > mit->second.timestamp) {
                dft[key] = *e;
                prop_dft.entries.push_back(*e);
                PD("DFT entry %s %s remotely\n", key.c_str(),
                        (mit != dft.end() ? "updated" : "added"));
            }

        } else {
            if (mit == dft.end()) {
                PI("DFT entry does not exist\n");
            } else {
                dft.erase(mit);
                prop_dft.entries.push_back(*e);
                PD("DFT entry %s removed remotely\n", key.c_str());
            }

        }
    }

    if (prop_dft.entries.size()) {
        /* Propagate the DFT entries update to the other neighbors,
         * except for the one. */
        remote_sync_excluding(neigh, add, obj_class::dft,
                              obj_name::dft, &prop_dft);

    }

    return 0;
}

<|endoftext|>