<commit_before>/** ==========================================================================
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
* with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations.
*
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
* ============================================================================*/

#include "g3log/logmessage.hpp"
#include "g3log/crashhandler.hpp"
#include "g3log/time.hpp"
#include "g3log/std2_make_unique.hpp"
#include <algorithm>
#include <mutex>

namespace {
   std::once_flag g_start_time_flag;
   std::chrono::steady_clock::time_point g_start_time;

   int64_t  microsecondsCounter() {
      std::call_once(g_start_time_flag, []() {
         g_start_time = std::chrono::steady_clock::now();
      });
      auto  now = std::chrono::steady_clock::now();
      return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
   }

   std::string splitFileName(const std::string& str) {
      size_t found;
      found = str.find_last_of("(/\\");
      return str.substr(found + 1);
   }
} // anonymous

namespace g3 {

   // helper for setting the normal log details in an entry
   std::string LogDetailsToString(const LogMessage& msg) {
      std::string out;
      out.append("\n" + msg.timestamp() + " " + msg.microseconds() +  "\t"
                 + msg.level() + " [" + msg.file() + " L: " + msg.line() + "]\t");
      return out;
   }

   // helper for normal
   std::string normalToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      out.append('"' + msg.message() + '"');
      return out;
   }

   // helper for fatal signal
   std::string  fatalSignalToString(const LogMessage& msg) {
      std::string out; // clear any previous text and formatting
      out.append("\n" + msg.timestamp() + "." + msg.microseconds()
                 + "\n\n***** FATAL SIGNAL RECEIVED ******* \n"
                 + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal exception (windows only)
   std::string  fatalExceptionToString(const LogMessage& msg) {
      std::string out; // clear any previous text and formatting
      out.append("\n" + msg.timestamp() + "." + msg.microseconds()
                 + "\n\n***** FATAL EXCEPTION RECEIVED ******* \n"
                 + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal LOG
   std::string fatalLogToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      static const std::string fatalExitReason = {"EXIT trigger caused by LOG(FATAL) entry: "};
      out.append("\n\t*******\t " + fatalExitReason + "\n\t" + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal CHECK
   std::string fatalCheckToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      static const std::string contractExitReason = {"EXIT trigger caused by broken Contract:"};
      out.append("\n\t*******\t " + contractExitReason + " CHECK(" + msg.expression() + ")\n\t"
                 + '"' + msg. message() + '"');
      return out;
   }

   // Format the log message according to it's type
   std::string LogMessage::toString() const {
      if (false == wasFatal()) {
         return normalToString(*this);
      }

      const auto level_value = _level.value;
      if (internal::FATAL_SIGNAL.value == _level.value) {
         return fatalSignalToString(*this);
      }

      if (internal::FATAL_EXCEPTION.value == _level.value) {
         return fatalExceptionToString(*this);
      }

      if (FATAL.value == _level.value) {
         return fatalLogToString(*this);
      }

      if (internal::CONTRACT.value == level_value) {
         return fatalCheckToString(*this);
      }

      // What? Did we hit a custom made level?
      auto out = LogDetailsToString(*this);
      static const std::string errorUnknown = {"UNKNOWN or Custom made Log Message Type"};
      out.append("\n\t*******" + errorUnknown + "\t\n" + '"' + message() + '"');
      return out;
   }

   std::string LogMessage::timestamp(const std::string& time_look) const {
      return  localtime_formatted(_timestamp, time_look);
   }

// By copy, not by reference. See this explanation for details:
// http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
   LogMessage& LogMessage::operator=(LogMessage other) {
      swap(*this, other);
      return *this;
   }

   LogMessage::LogMessage(const std::string& file, const int line,
                          const std::string& function, const LEVELS& level)
      : _timestamp(g3::systemtime_now())
      , _call_thread_id(std::this_thread::get_id())
      , _microseconds(microsecondsCounter())
      , _file(splitFileName(file))
      , _line(line)
      , _function(function)
      , _level(level)
   {}

   LogMessage::LogMessage(const std::string& fatalOsSignalCrashMessage)
      : LogMessage( {""}, 0, {""}, internal::FATAL_SIGNAL) {
      _message.append(fatalOsSignalCrashMessage);
   }

   LogMessage::LogMessage(const LogMessage& other)
      : _timestamp(other._timestamp)
      , _call_thread_id(other._call_thread_id)
      , _microseconds(other._microseconds)
      , _file(other._file)
      , _line(other._line)
      , _function(other._function)
      , _level(other._level)
      , _expression(other._expression)
      , _message(other._message) {
   }

   LogMessage::LogMessage(LogMessage &&other)
      : _timestamp(other._timestamp)
      , _call_thread_id(other._call_thread_id)
      , _microseconds(other._microseconds)
      , _file(std::move(other._file))
      , _line(other._line)
      , _function(std::move(other._function))
      , _level(other._level)
      , _expression(std::move(other._expression))
      , _message(std::move(other._message)) {
   }

   std::string LogMessage::threadID() const {
      std::ostringstream oss;
      oss << _call_thread_id;
      return oss.str();
   }

   FatalMessage::FatalMessage(const LogMessage& details, g3::SignalType signal_id)
      : LogMessage(details), _signal_id(signal_id) { }

   FatalMessage::FatalMessage(const FatalMessage& other)
      : LogMessage(other), _signal_id(other._signal_id) {}

   LogMessage  FatalMessage::copyToLogMessage() const {
      return LogMessage(*this);
   }

   std::string FatalMessage::reason() const {
      return internal::exitReasonName(_level, _signal_id);
   }

} // g3
<commit_msg>Improve default formatting <commit_after>/** ==========================================================================
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
* with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations.
*
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
* ============================================================================*/

#include "g3log/logmessage.hpp"
#include "g3log/crashhandler.hpp"
#include "g3log/time.hpp"
#include "g3log/std2_make_unique.hpp"
#include <algorithm>
#include <mutex>

namespace {
   std::once_flag g_start_time_flag;
   std::chrono::steady_clock::time_point g_start_time;

   int64_t  microsecondsCounter() {
      std::call_once(g_start_time_flag, []() {
         g_start_time = std::chrono::steady_clock::now();
      });
      auto  now = std::chrono::steady_clock::now();
      return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
   }

   std::string splitFileName(const std::string& str) {
      size_t found;
      found = str.find_last_of("(/\\");
      return str.substr(found + 1);
   }
} // anonymous

namespace g3 {

   // helper for setting the normal log details in an entry
   std::string LogDetailsToString(const LogMessage& msg) {
      std::string out;
      out.append("\n" + msg.timestamp() + " " + msg.microseconds() +  "\t"
                 + msg.level() + " [" + msg.file() + ":" + msg.line() + "]\t");
      return out;
   }

   // helper for normal
   std::string normalToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      out.append('"' + msg.message() + '"');
      return out;
   }

   // helper for fatal signal
   std::string  fatalSignalToString(const LogMessage& msg) {
      std::string out; // clear any previous text and formatting
      out.append("\n" + msg.timestamp() + "." + msg.microseconds()
                 + "\n\n***** FATAL SIGNAL RECEIVED ******* \n"
                 + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal exception (windows only)
   std::string  fatalExceptionToString(const LogMessage& msg) {
      std::string out; // clear any previous text and formatting
      out.append("\n" + msg.timestamp() + "." + msg.microseconds()
                 + "\n\n***** FATAL EXCEPTION RECEIVED ******* \n"
                 + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal LOG
   std::string fatalLogToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      static const std::string fatalExitReason = {"EXIT trigger caused by LOG(FATAL) entry: "};
      out.append("\n\t*******\t " + fatalExitReason + "\n\t" + '"' + msg.message() + '"');
      return out;
   }

   // helper for fatal CHECK
   std::string fatalCheckToString(const LogMessage& msg) {
      auto out = LogDetailsToString(msg);
      static const std::string contractExitReason = {"EXIT trigger caused by broken Contract:"};
      out.append("\n\t*******\t " + contractExitReason + " CHECK(" + msg.expression() + ")\n\t"
                 + '"' + msg. message() + '"');
      return out;
   }

   // Format the log message according to it's type
   std::string LogMessage::toString() const {
      if (false == wasFatal()) {
         return normalToString(*this);
      }

      const auto level_value = _level.value;
      if (internal::FATAL_SIGNAL.value == _level.value) {
         return fatalSignalToString(*this);
      }

      if (internal::FATAL_EXCEPTION.value == _level.value) {
         return fatalExceptionToString(*this);
      }

      if (FATAL.value == _level.value) {
         return fatalLogToString(*this);
      }

      if (internal::CONTRACT.value == level_value) {
         return fatalCheckToString(*this);
      }

      // What? Did we hit a custom made level?
      auto out = LogDetailsToString(*this);
      static const std::string errorUnknown = {"UNKNOWN or Custom made Log Message Type"};
      out.append("\n\t*******" + errorUnknown + "\t\n" + '"' + message() + '"');
      return out;
   }

   std::string LogMessage::timestamp(const std::string& time_look) const {
      return  localtime_formatted(_timestamp, time_look);
   }

// By copy, not by reference. See this explanation for details:
// http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
   LogMessage& LogMessage::operator=(LogMessage other) {
      swap(*this, other);
      return *this;
   }

   LogMessage::LogMessage(const std::string& file, const int line,
                          const std::string& function, const LEVELS& level)
      : _timestamp(g3::systemtime_now())
      , _call_thread_id(std::this_thread::get_id())
      , _microseconds(microsecondsCounter())
      , _file(splitFileName(file))
      , _line(line)
      , _function(function)
      , _level(level)
   {}

   LogMessage::LogMessage(const std::string& fatalOsSignalCrashMessage)
      : LogMessage( {""}, 0, {""}, internal::FATAL_SIGNAL) {
      _message.append(fatalOsSignalCrashMessage);
   }

   LogMessage::LogMessage(const LogMessage& other)
      : _timestamp(other._timestamp)
      , _call_thread_id(other._call_thread_id)
      , _microseconds(other._microseconds)
      , _file(other._file)
      , _line(other._line)
      , _function(other._function)
      , _level(other._level)
      , _expression(other._expression)
      , _message(other._message) {
   }

   LogMessage::LogMessage(LogMessage &&other)
      : _timestamp(other._timestamp)
      , _call_thread_id(other._call_thread_id)
      , _microseconds(other._microseconds)
      , _file(std::move(other._file))
      , _line(other._line)
      , _function(std::move(other._function))
      , _level(other._level)
      , _expression(std::move(other._expression))
      , _message(std::move(other._message)) {
   }

   std::string LogMessage::threadID() const {
      std::ostringstream oss;
      oss << _call_thread_id;
      return oss.str();
   }

   FatalMessage::FatalMessage(const LogMessage& details, g3::SignalType signal_id)
      : LogMessage(details), _signal_id(signal_id) { }

   FatalMessage::FatalMessage(const FatalMessage& other)
      : LogMessage(other), _signal_id(other._signal_id) {}

   LogMessage  FatalMessage::copyToLogMessage() const {
      return LogMessage(*this);
   }

   std::string FatalMessage::reason() const {
      return internal::exitReasonName(_level, _signal_id);
   }

} // g3
<|endoftext|>


<commit_before>
#include "common.h"

// interface header
#include "LuaZip.h"

// system headers
#include <errno.h>
#include <string.h>
#include <string>
#include <vector>
using std::string;
using std::vector;

// common headers
#include "zlib.h"

// local headers
#include "LuaInclude.h"
#include "LuaHashString.h"

const int bufSize = 65536;

enum CompressMode {
	CompressRaw  = 0,
	CompressGzip = 1,
	CompressZlib = 2
};

/******************************************************************************/
/******************************************************************************/

bool LuaZip::PushEntries(lua_State* L)
{
	PUSH_LUA_CFUNC(L, Zip);
	PUSH_LUA_CFUNC(L, Unzip);

	return true;
}

/******************************************************************************/
/******************************************************************************/

static void PushZlibErrorString(lua_State* L, int zCode)
{
	switch (zCode) {
		case Z_BUF_ERROR:     { lua_pushliteral(L, "buffer error");  break; }
		case Z_DATA_ERROR:    { lua_pushliteral(L, "data error");    break; }
		case Z_MEM_ERROR:     { lua_pushliteral(L, "memory error");  break; }
		case Z_STREAM_ERROR:  { lua_pushliteral(L, "stream error");  break; }
		case Z_VERSION_ERROR: { lua_pushliteral(L, "version error"); break; }
		case Z_ERRNO: {
			lua_pushstring(L, strerror(errno));
			break;
		}
		default: {
			lua_pushliteral(L, "unknown error");
			break;
		}
	}
}

static char* ConcatVector(const vector<string>& vs, size_t total)
{
	char* data = new char[total];
	char* pos = data;
	for (size_t i = 0; i < vs.size(); i++) {
		const string& str = vs[i];
		memcpy(pos, str.data(), str.size());
		pos += str.size();
	}
	return data;
}

static void SetupZStream(z_stream& zs, const char* inData, size_t inLen)
{
	zs.next_in = (Bytef*)inData;
	zs.avail_in = inLen;
	zs.total_in = inLen;
	zs.total_out = 0;
	zs.zalloc = (alloc_func)Z_NULL;
	zs.zfree  =  (free_func)Z_NULL;
	zs.opaque =     (voidpf)Z_NULL;
}

CompressMode ParseCompressMode(lua_State* L, int index, const char* def)
{
	const string modeStr = luaL_optstring(L, index, def);
	if (modeStr == "raw")  { return CompressRaw;  }
	if (modeStr == "gzip") { return CompressGzip; }
	if (modeStr == "zlib") { return CompressZlib; }
	luaL_error(L, "invalid zip mode (%s)", modeStr.c_str());
	return CompressRaw;
}

/******************************************************************************/
/******************************************************************************/

static int CompressString(const char* inData, size_t inLen,
                          char*& outData, size_t& outLen,
                          CompressMode mode)
{
	int windowBits;
	switch (mode) {
		case CompressRaw:  { windowBits = -MAX_WBITS;      break; }
		case CompressGzip: { windowBits = +MAX_WBITS + 16; break; }
		case CompressZlib: { windowBits = +MAX_WBITS;      break; }
		default: {
			return Z_VERSION_ERROR;
		}
	}

	z_stream zs;
	SetupZStream(zs, inData, inLen);

	const int initCode = deflateInit2(&zs, 9, Z_DEFLATED, windowBits,
	                                  MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
	if (initCode != Z_OK) {
		return initCode;
	}

	outLen = 0;
	vector<string> outVec;
	char bufData[bufSize];

	int flushMode = Z_NO_FLUSH;
	while (true) {
		zs.next_out = (Bytef*)bufData;
		zs.avail_out = bufSize;
		const int retcode = deflate(&zs, flushMode);
		if (retcode == Z_STREAM_END) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
			break;
		}
		else if (retcode == Z_OK) {
			flushMode = Z_FINISH;
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
		}
		else {
			deflateEnd(&zs);
			outLen = 0;
			outData = NULL;
			return retcode;
		}
	}

	deflateEnd(&zs);

	outData = ConcatVector(outVec, outLen);

	return Z_OK;
}

static int DecompressString(const char* inData, size_t inLen,
                            char*& outData, size_t& outLen,
                            CompressMode mode)
{
	int windowBits;
	switch (mode) {
		case CompressRaw:  { windowBits = -MAX_WBITS;      break; }
		case CompressGzip: { windowBits = +MAX_WBITS + 16; break; }
		case CompressZlib: { windowBits = +MAX_WBITS + 32; break; } // zlib or gzip
		default: {
			return Z_VERSION_ERROR;
		}
	}

	z_stream zs;
	SetupZStream(zs, inData, inLen);

	const int initCode = inflateInit2(&zs, windowBits);
	if (initCode != Z_OK) {
		return initCode;
	}

	outLen = 0;
	vector<string> outVec;
	char bufData[bufSize];

	while (true) {
		zs.next_out = (Bytef*)bufData;
		zs.avail_out = bufSize;
		const int retcode = inflate(&zs, Z_NO_FLUSH);
		if (retcode == Z_STREAM_END) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
			break;
		}
		else if (retcode == Z_OK) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
		}
		else {
			inflateEnd(&zs);
			outLen = 0;
			outData = NULL;
			return retcode;
		}
	}

	inflateEnd(&zs);

	outData = ConcatVector(outVec, outLen);

	return Z_OK;
}

/******************************************************************************/
/******************************************************************************/

int LuaZip::Zip(lua_State* L)
{
	size_t inLen;
	const char* inData = luaL_checklstring(L, 1, &inLen);

	CompressMode mode = ParseCompressMode(L, 2, "gzip");

	char* outData = NULL;
	size_t outLen;
	const int zCode = CompressString(inData, inLen, outData, outLen, mode);
	if (zCode != Z_OK) {
		lua_pushnil(L);
		PushZlibErrorString(L, zCode);
		return 2;
	}

	lua_pushlstring(L, outData, outLen);
	delete[] outData;

	return 1;
}

int LuaZip::Unzip(lua_State* L)
{
	size_t inLen;
	const char* inData = luaL_checklstring(L, 1, &inLen);

	CompressMode mode = ParseCompressMode(L, 2, "zlib"); // zlib or gzip

	char* outData = NULL;
	size_t outLen;
	const int zCode = DecompressString(inData, inLen, outData, outLen, mode);
	if (zCode != Z_OK) {
		lua_pushnil(L);
		PushZlibErrorString(L, zCode);
		return 2;
	}

	lua_pushlstring(L, outData, outLen);
	delete[] outData;

	return 1;
}

/******************************************************************************/
/******************************************************************************/
<commit_msg>* 'const' when you can ...<commit_after>
#include "common.h"

// interface header
#include "LuaZip.h"

// system headers
#include <errno.h>
#include <string.h>
#include <string>
#include <vector>
using std::string;
using std::vector;

// common headers
#include "zlib.h"

// local headers
#include "LuaInclude.h"
#include "LuaHashString.h"

const int bufSize = 65536;

enum CompressMode {
	CompressRaw  = 0,
	CompressGzip = 1,
	CompressZlib = 2
};

/******************************************************************************/
/******************************************************************************/

bool LuaZip::PushEntries(lua_State* L)
{
	PUSH_LUA_CFUNC(L, Zip);
	PUSH_LUA_CFUNC(L, Unzip);

	return true;
}

/******************************************************************************/
/******************************************************************************/

static void PushZlibErrorString(lua_State* L, int zCode)
{
	switch (zCode) {
		case Z_BUF_ERROR:     { lua_pushliteral(L, "buffer error");  break; }
		case Z_DATA_ERROR:    { lua_pushliteral(L, "data error");    break; }
		case Z_MEM_ERROR:     { lua_pushliteral(L, "memory error");  break; }
		case Z_STREAM_ERROR:  { lua_pushliteral(L, "stream error");  break; }
		case Z_VERSION_ERROR: { lua_pushliteral(L, "version error"); break; }
		case Z_ERRNO: {
			lua_pushstring(L, strerror(errno));
			break;
		}
		default: {
			lua_pushliteral(L, "unknown error");
			break;
		}
	}
}

static char* ConcatVector(const vector<string>& vs, size_t total)
{
	char* data = new char[total];
	char* pos = data;
	for (size_t i = 0; i < vs.size(); i++) {
		const string& str = vs[i];
		memcpy(pos, str.data(), str.size());
		pos += str.size();
	}
	return data;
}

static void SetupZStream(z_stream& zs, const char* inData, size_t inLen)
{
	zs.next_in = (Bytef*)inData;
	zs.avail_in = inLen;
	zs.total_in = inLen;
	zs.total_out = 0;
	zs.zalloc = (alloc_func)Z_NULL;
	zs.zfree  =  (free_func)Z_NULL;
	zs.opaque =     (voidpf)Z_NULL;
}

CompressMode ParseCompressMode(lua_State* L, int index, const char* def)
{
	const string modeStr = luaL_optstring(L, index, def);
	if (modeStr == "raw")  { return CompressRaw;  }
	if (modeStr == "gzip") { return CompressGzip; }
	if (modeStr == "zlib") { return CompressZlib; }
	luaL_error(L, "invalid zip mode (%s)", modeStr.c_str());
	return CompressRaw;
}

/******************************************************************************/
/******************************************************************************/

static int CompressString(const char* inData, size_t inLen,
                          char*& outData, size_t& outLen,
                          CompressMode mode)
{
	int windowBits;
	switch (mode) {
		case CompressRaw:  { windowBits = -MAX_WBITS;      break; }
		case CompressGzip: { windowBits = +MAX_WBITS + 16; break; }
		case CompressZlib: { windowBits = +MAX_WBITS;      break; }
		default: {
			return Z_VERSION_ERROR;
		}
	}

	z_stream zs;
	SetupZStream(zs, inData, inLen);

	const int initCode = deflateInit2(&zs, 9, Z_DEFLATED, windowBits,
	                                  MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
	if (initCode != Z_OK) {
		return initCode;
	}

	outLen = 0;
	vector<string> outVec;
	char bufData[bufSize];

	int flushMode = Z_NO_FLUSH;
	while (true) {
		zs.next_out = (Bytef*)bufData;
		zs.avail_out = bufSize;
		const int retcode = deflate(&zs, flushMode);
		if (retcode == Z_STREAM_END) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
			break;
		}
		else if (retcode == Z_OK) {
			flushMode = Z_FINISH;
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
		}
		else {
			deflateEnd(&zs);
			outLen = 0;
			outData = NULL;
			return retcode;
		}
	}

	deflateEnd(&zs);

	outData = ConcatVector(outVec, outLen);

	return Z_OK;
}

static int DecompressString(const char* inData, size_t inLen,
                            char*& outData, size_t& outLen,
                            CompressMode mode)
{
	int windowBits;
	switch (mode) {
		case CompressRaw:  { windowBits = -MAX_WBITS;      break; }
		case CompressGzip: { windowBits = +MAX_WBITS + 16; break; }
		case CompressZlib: { windowBits = +MAX_WBITS + 32; break; } // zlib or gzip
		default: {
			return Z_VERSION_ERROR;
		}
	}

	z_stream zs;
	SetupZStream(zs, inData, inLen);

	const int initCode = inflateInit2(&zs, windowBits);
	if (initCode != Z_OK) {
		return initCode;
	}

	outLen = 0;
	vector<string> outVec;
	char bufData[bufSize];

	while (true) {
		zs.next_out = (Bytef*)bufData;
		zs.avail_out = bufSize;
		const int retcode = inflate(&zs, Z_NO_FLUSH);
		if (retcode == Z_STREAM_END) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
			break;
		}
		else if (retcode == Z_OK) {
			const size_t outSize = (bufSize - zs.avail_out);
			outLen += outSize;
			outVec.push_back(string(bufData, outSize));
		}
		else {
			inflateEnd(&zs);
			outLen = 0;
			outData = NULL;
			return retcode;
		}
	}

	inflateEnd(&zs);

	outData = ConcatVector(outVec, outLen);

	return Z_OK;
}

/******************************************************************************/
/******************************************************************************/

int LuaZip::Zip(lua_State* L)
{
	size_t inLen;
	const char* inData = luaL_checklstring(L, 1, &inLen);

	const CompressMode mode = ParseCompressMode(L, 2, "gzip");

	char* outData = NULL;
	size_t outLen;
	const int zCode = CompressString(inData, inLen, outData, outLen, mode);
	if (zCode != Z_OK) {
		lua_pushnil(L);
		PushZlibErrorString(L, zCode);
		return 2;
	}

	lua_pushlstring(L, outData, outLen);
	delete[] outData;

	return 1;
}

int LuaZip::Unzip(lua_State* L)
{
	size_t inLen;
	const char* inData = luaL_checklstring(L, 1, &inLen);

	const CompressMode mode = ParseCompressMode(L, 2, "zlib"); // zlib or gzip

	char* outData = NULL;
	size_t outLen;
	const int zCode = DecompressString(inData, inLen, outData, outLen, mode);
	if (zCode != Z_OK) {
		lua_pushnil(L);
		PushZlibErrorString(L, zCode);
		return 2;
	}

	lua_pushlstring(L, outData, outLen);
	delete[] outData;

	return 1;
}

/******************************************************************************/
/******************************************************************************/
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mvdDatasetDescriptor.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdVectorImageModel.h"
#include "mvdSystemError.h"

/*****************************************************************************/
/* MACROS                                                                    */

/** \brief Indent space when writing XML DOM documents. */
#define XML_INDENT 2

namespace mvd
{

/*
  TRANSLATOR mvd::DatasetDescriptor

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

const char*
DatasetDescriptor::TAG_NAMES[ ELEMENT_COUNT ] =
{
  PROJECT_NAME "_Dataset",
  "image_information",
  "input_image",
  "ql_input_image",
  "settings",
  "rgb",
  "dynamics"
};

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatasetDescriptor
::DatasetDescriptor( QObject* parent ) :
  AbstractModel( parent ),
  m_DomDocument( TAG_NAMES[ ELEMENT_DOCUMENT_ROOT ] ),
  m_DatasetElement()
{
}

/*******************************************************************************/
DatasetDescriptor
::~DatasetDescriptor()
{
}

/*******************************************************************************/
void
DatasetDescriptor
::InsertImageModel( int id,
		    const QString& imageFilename,
		    void* imageSettings,
		    const QString& quicklookFilename )
{
  //
  // Image information node.
  QDomElement imagesElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_IMAGE_GROUP ] )
  );
  m_DatasetElement.appendChild(imagesElement);
  imagesElement.setAttribute( "id", QString( "%1" ).arg( id ) );

  // Input image filename
  QDomElement imgElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_IMAGE ] )
  );
  imagesElement.appendChild(imgElement);
  imgElement.setAttribute("href",imageFilename);

  // QL input image filename
  QDomElement qlElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_QUICKLOOK ] )
  );
  imagesElement.appendChild(qlElement);
  qlElement.setAttribute("href",quicklookFilename);

  //
  // Settings node.
  QDomElement settingsElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_SETTINGS_GROUP ] )
  );
  imagesElement.appendChild(settingsElement);

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // RGB channels.
  QDomElement rgbElement(
    CreateContainerNode(
      settings->GetRgbChannels().begin(),
      settings->GetRgbChannels().end(),
      TAG_NAMES[ ELEMENT_RGB_CHANNELS ]
    )
  );
  settingsElement.appendChild( rgbElement );

  //
  // Dynamics parameters.
  QDomElement dynamicsElement(
    CreateContainerNode(
      settings->GetDynamicsParams().begin(),
      settings->GetDynamicsParams().end(),
      TAG_NAMES[ ELEMENT_DYNAMICS_PARAMETERS ]
    )
  );
  settingsElement.appendChild( dynamicsElement );
  }
}

/*******************************************************************************/
void
DatasetDescriptor
::GetImageModel( const QDomElement& imageSibling,
		 int& id,
		 QString& imageFilename,
		 void* imageSettings,
		 QString& quicklookFilename )
{
  imageFilename = imageSibling.attribute( "filename" );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // Settings
  QDomElement settingsElement( imageSibling.firstChildElement( "settings" ) );

  // RGB
  QDomElement rgbElement( settingsElement.firstChildElement( "rgb" ) );

  // Dynamics
  QDomElement dynamicsElement( settingsElement.firstChildElement( "dynamics" ) );

  // Ensure there is only one '<settings>...</settings>' child.
  settingsElement = settingsElement.nextSiblingElement( "settings" );
  assert( settingsElement.isNull() );
  }

  quicklookFilename = imageSibling.attribute( "quicklook" );
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( const QString& filename )
{
  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  // Read file context.
  Read( &file );

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( QIODevice* device )
{
  // Temporary DOM document.
  QDomDocument domDoc;

  // Error information.
  QString error;
  int line;
  int column;

  // Link to content and manages error.
  if( !domDoc.setContent( device, true, &error, &line, &column ) )
    throw /* XmlError( error, line, column ) */;

  // If Ok, remember DOM document data (otherwise, forget temporary
  // DOM document and leave class state unchanged).
  m_DomDocument = domDoc;
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( const QString& filename ) const
{
  qDebug() << filename;

  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  try
    {
    // Read file context.
    Write( file );
    }
  catch( SystemError& syserr )
    {
    // Catch any SystemError thrown by DatasetDescriptor::Write() and
    // morph it into the same SystemError containing filename
    // information.
    syserr = SystemError(
      syserr.GetErrorCode(),
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

    // Throw morphed SystemError.
    throw syserr;
    }

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( QIODevice& device ) const
{
  qDebug() << "descriptor.xml: " << m_DomDocument.toByteArray( XML_INDENT );

  // TODO: Check IO device is formatted to UTF-8 data.
  if( device.write( m_DomDocument.toByteArray( XML_INDENT ) )==-1 )
    throw SystemError();
}

/*******************************************************************************/
void
DatasetDescriptor
::virtual_BuildModel( void* context )
{
  qDebug() << "DatasetDescriptor::virtual_BuildModel()";

#if 0
  // Get build-context.
  assert( context!=NULL );
  BuildContext* buildContext = static_cast< BuildContext* >( context );
#endif

  const DatasetModel* model = GetParentModel< DatasetModel >();
  assert( model );

  // Add the root element
  QDomElement root(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_DOCUMENT_ROOT ] )
  );
  m_DomDocument.appendChild(root);

  // Root document element: '<dataset>...</dataset>'.
  QDomElement dsElt = m_DomDocument.createElement("dataset_path");
  dsElt.setAttribute(
    "href",
    QDir::cleanPath( model->GetDirectory().path() )
  );
  m_DomDocument.firstChild().appendChild(dsElt);

  // keep the dataset element
  m_DatasetElement =  m_DomDocument.firstChild().toElement();

  // TODO Add the encoding in the processing instruction
  QDomNode node = m_DomDocument.createProcessingInstruction("xml", "version = \"1.0\"");
  m_DomDocument.insertBefore(node, m_DomDocument.firstChild());
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/

/*******************************************************************************/

} // end namespace 'mvd'
<commit_msg>ENH: Added version string as attribute of descriptor.xml root node.<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mvdDatasetDescriptor.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdVectorImageModel.h"
#include "mvdSystemError.h"

/*****************************************************************************/
/* MACROS                                                                    */

/** \brief Indent space when writing XML DOM documents. */
#define XML_INDENT 2

namespace mvd
{

/*
  TRANSLATOR mvd::DatasetDescriptor

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

const char*
DatasetDescriptor::TAG_NAMES[ ELEMENT_COUNT ] =
{
  PROJECT_NAME "_Dataset",
  "image_information",
  "input_image",
  "ql_input_image",
  "settings",
  "rgb",
  "dynamics"
};

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
DatasetDescriptor
::DatasetDescriptor( QObject* parent ) :
  AbstractModel( parent ),
  m_DomDocument( TAG_NAMES[ ELEMENT_DOCUMENT_ROOT ] ),
  m_DatasetElement()
{
}

/*******************************************************************************/
DatasetDescriptor
::~DatasetDescriptor()
{
}

/*******************************************************************************/
void
DatasetDescriptor
::InsertImageModel( int id,
		    const QString& imageFilename,
		    void* imageSettings,
		    const QString& quicklookFilename )
{
  //
  // Image information node.
  QDomElement imagesElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_IMAGE_GROUP ] )
  );
  m_DatasetElement.appendChild(imagesElement);
  imagesElement.setAttribute( "id", QString( "%1" ).arg( id ) );

  // Input image filename
  QDomElement imgElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_IMAGE ] )
  );
  imagesElement.appendChild(imgElement);
  imgElement.setAttribute("href",imageFilename);

  // QL input image filename
  QDomElement qlElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_QUICKLOOK ] )
  );
  imagesElement.appendChild(qlElement);
  qlElement.setAttribute("href",quicklookFilename);

  //
  // Settings node.
  QDomElement settingsElement(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_SETTINGS_GROUP ] )
  );
  imagesElement.appendChild(settingsElement);

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // RGB channels.
  QDomElement rgbElement(
    CreateContainerNode(
      settings->GetRgbChannels().begin(),
      settings->GetRgbChannels().end(),
      TAG_NAMES[ ELEMENT_RGB_CHANNELS ]
    )
  );
  settingsElement.appendChild( rgbElement );

  //
  // Dynamics parameters.
  QDomElement dynamicsElement(
    CreateContainerNode(
      settings->GetDynamicsParams().begin(),
      settings->GetDynamicsParams().end(),
      TAG_NAMES[ ELEMENT_DYNAMICS_PARAMETERS ]
    )
  );
  settingsElement.appendChild( dynamicsElement );
  }
}

/*******************************************************************************/
void
DatasetDescriptor
::GetImageModel( const QDomElement& imageSibling,
		 int& id,
		 QString& imageFilename,
		 void* imageSettings,
		 QString& quicklookFilename )
{
  imageFilename = imageSibling.attribute( "filename" );

  // TODO: Generalize code section
  {
  VectorImageModel::Settings* settings =
    static_cast< VectorImageModel::Settings* >( imageSettings );

  // Settings
  QDomElement settingsElement( imageSibling.firstChildElement( "settings" ) );

  // RGB
  QDomElement rgbElement( settingsElement.firstChildElement( "rgb" ) );

  // Dynamics
  QDomElement dynamicsElement( settingsElement.firstChildElement( "dynamics" ) );

  // Ensure there is only one '<settings>...</settings>' child.
  settingsElement = settingsElement.nextSiblingElement( "settings" );
  assert( settingsElement.isNull() );
  }

  quicklookFilename = imageSibling.attribute( "quicklook" );
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( const QString& filename )
{
  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  // Read file context.
  Read( &file );

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Read( QIODevice* device )
{
  // Temporary DOM document.
  QDomDocument domDoc;

  // Error information.
  QString error;
  int line;
  int column;

  // Link to content and manages error.
  if( !domDoc.setContent( device, true, &error, &line, &column ) )
    throw /* XmlError( error, line, column ) */;

  // If Ok, remember DOM document data (otherwise, forget temporary
  // DOM document and leave class state unchanged).
  m_DomDocument = domDoc;
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( const QString& filename ) const
{
  qDebug() << filename;

  // File instance.
  QFile file( filename );

  // Open file on device.
  if( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
    throw SystemError(
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

  try
    {
    // Read file context.
    Write( file );
    }
  catch( SystemError& syserr )
    {
    // Catch any SystemError thrown by DatasetDescriptor::Write() and
    // morph it into the same SystemError containing filename
    // information.
    syserr = SystemError(
      syserr.GetErrorCode(),
      ToStdString(
	QString( "('%1')" ).arg( filename ) )
    );

    // Throw morphed SystemError.
    throw syserr;
    }

  // File is closed by automatic scope detruction of QFile instance.
}

/*******************************************************************************/
void
DatasetDescriptor
::Write( QIODevice& device ) const
{
  qDebug() << "descriptor.xml: " << m_DomDocument.toByteArray( XML_INDENT );

  // TODO: Check IO device is formatted to UTF-8 data.
  if( device.write( m_DomDocument.toByteArray( XML_INDENT ) )==-1 )
    throw SystemError();
}

/*******************************************************************************/
void
DatasetDescriptor
::virtual_BuildModel( void* context )
{
  qDebug() << "DatasetDescriptor::virtual_BuildModel()";

#if 0
  // Get build-context.
  assert( context!=NULL );
  BuildContext* buildContext = static_cast< BuildContext* >( context );
#endif

  const DatasetModel* model = GetParentModel< DatasetModel >();
  assert( model );

  // Add the root element
  QDomElement rootElt(
    m_DomDocument.createElement( TAG_NAMES[ ELEMENT_DOCUMENT_ROOT ] )
  );
  rootElt.setAttribute( "version", Monteverdi2_VERSION_STRING );
  m_DomDocument.appendChild( rootElt );

  // Root document element: '<dataset>...</dataset>'.
  QDomElement dsElt = m_DomDocument.createElement("dataset_path");
  dsElt.setAttribute(
    "href",
    QDir::cleanPath( model->GetDirectory().path() )
  );
  m_DomDocument.firstChild().appendChild(dsElt);

  // keep the dataset element
  m_DatasetElement =  m_DomDocument.firstChild().toElement();

  // TODO Add the encoding in the processing instruction
  QDomNode node = m_DomDocument.createProcessingInstruction("xml", "version = \"1.0\"");
  m_DomDocument.insertBefore(node, m_DomDocument.firstChild());
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/

/*******************************************************************************/

} // end namespace 'mvd'
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "base/compiler_specific.h"

#include "KeyboardCodes.h"
#include "StringImpl.h"  // This is so that the KJS build works

MSVC_PUSH_WARNING_LEVEL(0);
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "Widget.h"
MSVC_POP_WARNING();

#undef LOG
#include "base/gfx/point.h"
#include "base/logging.h"
#include "webkit/glue/event_conversion.h"
#include "webkit/glue/webinputevent.h"
#include "webkit/glue/webkit_glue.h"

using namespace WebCore;

// MakePlatformMouseEvent -----------------------------------------------------

int MakePlatformMouseEvent::last_click_count_ = 0;
uint32 MakePlatformMouseEvent::last_click_time_ = 0;

MakePlatformMouseEvent::MakePlatformMouseEvent(Widget* widget,
                                               const WebMouseEvent& e) {
  // TODO(mpcomplete): widget is always toplevel, unless it's a popup.  We
  // may be able to get rid of this once we abstract popups into a WebKit API.
  m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
  m_globalPosition = IntPoint(e.global_x, e.global_y);
  m_button = static_cast<MouseButton>(e.button);
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
  m_modifierFlags = e.modifiers;
  m_timestamp = e.timestamp_sec;

  // This differs slightly from the WebKit code in WebKit/win/WebView.cpp where
  // their original code looks buggy.
  static IntPoint last_click_position;
  static MouseButton last_click_button = LeftButton;

  const uint32 current_time = static_cast<uint32>(m_timestamp * 1000);
#if defined(OS_WIN)
  const bool cancel_previous_click =
      (abs(last_click_position.x() - m_position.x()) >
       (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) ||
      (abs(last_click_position.y() - m_position.y()) >
       (GetSystemMetrics(SM_CYDOUBLECLK) / 2)) ||
      ((current_time - last_click_time_) > GetDoubleClickTime());
#elif defined(OS_MACOSX) || defined(OS_LINUX)
  const bool cancel_previous_click = false;
#endif

  switch (e.type) {
    case WebInputEvent::MOUSE_MOVE:
    case WebInputEvent::MOUSE_LEAVE:  // synthesize a move event
      if (cancel_previous_click) {
        last_click_count_ = 0;
        last_click_position = IntPoint();
        last_click_time_ = 0;
      }
      m_clickCount = last_click_count_;
      m_eventType = MouseEventMoved;
      break;

  // TODO(port): make these platform agnostic when we restructure this code.
#if defined(OS_LINUX)
    case WebInputEvent::MOUSE_DOUBLE_CLICK:
      ++m_clickCount;
      // fall through
    case WebInputEvent::MOUSE_DOWN:
      ++m_clickCount;
      last_click_time_ = current_time;
      last_click_button = m_button;
      m_eventType = MouseEventPressed;
      break;
#else
    case WebInputEvent::MOUSE_DOWN:
    case WebInputEvent::MOUSE_DOUBLE_CLICK:
      if (!cancel_previous_click && (m_button == last_click_button)) {
        ++last_click_count_;
      } else {
        last_click_count_ = 1;
        last_click_position = m_position;
      }
      last_click_time_ = current_time;
      last_click_button = m_button;
      m_clickCount = last_click_count_;
      m_eventType = MouseEventPressed;
      break;
#endif

    case WebInputEvent::MOUSE_UP:
      m_clickCount = last_click_count_;
      m_eventType = MouseEventReleased;
      break;

    default:
      NOTREACHED() << "unexpected mouse event type";
  }

  if (webkit_glue::IsLayoutTestMode()) {
    m_clickCount = e.layout_test_click_count;
  }
}

// MakePlatformWheelEvent -----------------------------------------------------

MakePlatformWheelEvent::MakePlatformWheelEvent(Widget* widget,
                                               const WebMouseWheelEvent& e) {
  m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
  m_globalPosition = IntPoint(e.global_x, e.global_y);
  m_deltaX = static_cast<float>(e.delta_x);
  m_deltaY = static_cast<float>(e.delta_y);
  m_isAccepted = false;
  m_granularity = ScrollByLineWheelEvent;
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
}

// MakePlatformKeyboardEvent --------------------------------------------------

static inline const PlatformKeyboardEvent::Type ToPlatformKeyboardEventType(
    WebInputEvent::Type type) {
  switch (type) {
    case WebInputEvent::KEY_UP:
      return PlatformKeyboardEvent::KeyUp;
    case WebInputEvent::KEY_DOWN:
      return PlatformKeyboardEvent::KeyDown;
    case WebInputEvent::CHAR:
      return PlatformKeyboardEvent::Char;
    default:
      ASSERT_NOT_REACHED();
  }
  return PlatformKeyboardEvent::KeyDown;
}

static inline String ToSingleCharacterString(UChar c) {
  return String(&c, 1);
}

static String GetKeyIdentifierForWindowsKeyCode(unsigned short keyCode) {
  switch (keyCode) {
    case VKEY_MENU:
      return "Alt";
    case VKEY_CONTROL:
      return "Control";
    case VKEY_SHIFT:
      return "Shift";
    case VKEY_CAPITAL:
      return "CapsLock";
    case VKEY_LWIN:
    case VKEY_RWIN:
      return "Win";
    case VKEY_CLEAR:
      return "Clear";
    case VKEY_DOWN:
      return "Down";
    // "End"
    case VKEY_END:
      return "End";
    // "Enter"
    case VKEY_RETURN:
      return "Enter";
    case VKEY_EXECUTE:
      return "Execute";
    case VKEY_F1:
      return "F1";
    case VKEY_F2:
      return "F2";
    case VKEY_F3:
      return "F3";
    case VKEY_F4:
      return "F4";
    case VKEY_F5:
      return "F5";
    case VKEY_F6:
      return "F6";
    case VKEY_F7:
      return "F7";
    case VKEY_F8:
      return "F8";
    case VKEY_F9:
      return "F9";
    case VKEY_F10:
      return "F11";
    case VKEY_F12:
      return "F12";
    case VKEY_F13:
      return "F13";
    case VKEY_F14:
      return "F14";
    case VKEY_F15:
      return "F15";
    case VKEY_F16:
      return "F16";
    case VKEY_F17:
      return "F17";
    case VKEY_F18:
      return "F18";
    case VKEY_F19:
      return "F19";
    case VKEY_F20:
      return "F20";
    case VKEY_F21:
      return "F21";
    case VKEY_F22:
      return "F22";
    case VKEY_F23:
      return "F23";
    case VKEY_F24:
      return "F24";
    case VKEY_HELP:
      return "Help";
    case VKEY_HOME:
      return "Home";
    case VKEY_INSERT:
      return "Insert";
    case VKEY_LEFT:
      return "Left";
    case VKEY_NEXT:
      return "PageDown";
    case VKEY_PRIOR:
      return "PageUp";
    case VKEY_PAUSE:
      return "Pause";
    case VKEY_SNAPSHOT:
      return "PrintScreen";
    case VKEY_RIGHT:
      return "Right";
    case VKEY_SCROLL:
      return "Scroll";
    case VKEY_SELECT:
      return "Select";
    case VKEY_UP:
      return "Up";
    // Standard says that DEL becomes U+007F.
    case VKEY_DELETE:
      return "U+007F";
    default:
      return String::format("U+%04X", toupper(keyCode));
  }
}

MakePlatformKeyboardEvent::MakePlatformKeyboardEvent(const WebKeyboardEvent& e)
  {
  m_type = ToPlatformKeyboardEventType(e.type);
  if (m_type == Char || m_type == KeyDown) {
#if defined(OS_MACOSX)
    m_text = &e.text[0];
    m_unmodifiedText = &e.unmodified_text[0];
    m_keyIdentifier = &e.key_identifier[0];

    // Always use 13 for Enter/Return -- we don't want to use AppKit's
    // different character for Enter.
    if (m_windowsVirtualKeyCode == '\r') {
        m_text = "\r";
        m_unmodifiedText = "\r";
    }

    // The adjustments below are only needed in backward compatibility mode,
    // but we cannot tell what mode we are in from here.

    // Turn 0x7F into 8, because backspace needs to always be 8.
    if (m_text == "\x7F")
        m_text = "\x8";
    if (m_unmodifiedText == "\x7F")
        m_unmodifiedText = "\x8";
    // Always use 9 for tab -- we don't want to use AppKit's different character for shift-tab.
    if (m_windowsVirtualKeyCode == 9) {
        m_text = "\x9";
        m_unmodifiedText = "\x9";
    }
#elif defined(OS_WIN)
    m_text = m_unmodifiedText = ToSingleCharacterString(e.key_code);
#elif defined(OS_LINUX)
    m_text = m_unmodifiedText = ToSingleCharacterString(e.text);
#endif
  }
#if defined(OS_WIN) || defined(OS_LINUX)
  if (m_type != Char)
    m_keyIdentifier = GetKeyIdentifierForWindowsKeyCode(e.key_code);
#endif
  if (m_type == Char || m_type == KeyDown || m_type == KeyUp ||
      m_type == RawKeyDown) {
    m_windowsVirtualKeyCode = e.key_code;
  } else {
    m_windowsVirtualKeyCode = 0;
  }
  m_autoRepeat = (e.modifiers & WebInputEvent::IS_AUTO_REPEAT) != 0;
  m_isKeypad = (e.modifiers & WebInputEvent::IS_KEYPAD) != 0;
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
#if defined(OS_WIN)
  m_isSystemKey = e.system_key;
#else
  m_isSystemKey = false;  // TODO(port): make this proper.
#endif
}

void MakePlatformKeyboardEvent::SetKeyType(Type type) {
  // According to the behavior of Webkit in Windows platform,
  // we need to convert KeyDown to RawKeydown and Char events
  // See WebKit/WebKit/Win/WebView.cpp
  ASSERT(m_type == KeyDown);
  ASSERT(type == RawKeyDown || type == Char);
  m_type = type;

  if (type == RawKeyDown) {
    m_text = String();
    m_unmodifiedText = String();
  } else {
    m_keyIdentifier = String();
    m_windowsVirtualKeyCode = 0;
  }
}

// Please refer to bug http://b/issue?id=961192, which talks about Webkit
// keyboard event handling changes. It also mentions the list of keys
// which don't have associated character events.
bool MakePlatformKeyboardEvent::IsCharacterKey() const {
  switch (windowsVirtualKeyCode()) {
    case VKEY_BACK:
    case VKEY_ESCAPE:
      return false;

    default:
      break;
  }
  return true;
}
<commit_msg>Fix text selection for the Mac test_shell, for some value of "fix". Review URL: http://codereview.chromium.org/12853<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "base/compiler_specific.h"

#include "KeyboardCodes.h"
#include "StringImpl.h"  // This is so that the KJS build works

MSVC_PUSH_WARNING_LEVEL(0);
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "Widget.h"
MSVC_POP_WARNING();

#undef LOG
#include "base/gfx/point.h"
#include "base/logging.h"
#include "webkit/glue/event_conversion.h"
#include "webkit/glue/webinputevent.h"
#include "webkit/glue/webkit_glue.h"

using namespace WebCore;

// MakePlatformMouseEvent -----------------------------------------------------

int MakePlatformMouseEvent::last_click_count_ = 0;
uint32 MakePlatformMouseEvent::last_click_time_ = 0;

MakePlatformMouseEvent::MakePlatformMouseEvent(Widget* widget,
                                               const WebMouseEvent& e) {
  // TODO(mpcomplete): widget is always toplevel, unless it's a popup.  We
  // may be able to get rid of this once we abstract popups into a WebKit API.
  m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
  m_globalPosition = IntPoint(e.global_x, e.global_y);
  m_button = static_cast<MouseButton>(e.button);
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
  m_modifierFlags = e.modifiers;
  m_timestamp = e.timestamp_sec;

  // This differs slightly from the WebKit code in WebKit/win/WebView.cpp where
  // their original code looks buggy.
  static IntPoint last_click_position;
  static MouseButton last_click_button = LeftButton;

  const uint32 current_time = static_cast<uint32>(m_timestamp * 1000);
#if defined(OS_WIN)
  const bool cancel_previous_click =
      (abs(last_click_position.x() - m_position.x()) >
       (GetSystemMetrics(SM_CXDOUBLECLK) / 2)) ||
      (abs(last_click_position.y() - m_position.y()) >
       (GetSystemMetrics(SM_CYDOUBLECLK) / 2)) ||
      ((current_time - last_click_time_) > GetDoubleClickTime());
#elif defined(OS_MACOSX) || defined(OS_LINUX)
  const bool cancel_previous_click = false;
#endif

  switch (e.type) {
    case WebInputEvent::MOUSE_MOVE:
    case WebInputEvent::MOUSE_LEAVE:  // synthesize a move event
      if (cancel_previous_click) {
        last_click_count_ = 0;
        last_click_position = IntPoint();
        last_click_time_ = 0;
      }
      m_clickCount = last_click_count_;
      m_eventType = MouseEventMoved;
      break;

  // TODO(port): make these platform agnostic when we restructure this code.
#if defined(OS_LINUX) || defined(OS_MACOSX)
    case WebInputEvent::MOUSE_DOUBLE_CLICK:
      ++m_clickCount;
      // fall through
    case WebInputEvent::MOUSE_DOWN:
      ++m_clickCount;
      last_click_time_ = current_time;
      last_click_button = m_button;
      m_eventType = MouseEventPressed;
      break;
#else
    case WebInputEvent::MOUSE_DOWN:
    case WebInputEvent::MOUSE_DOUBLE_CLICK:
      if (!cancel_previous_click && (m_button == last_click_button)) {
        ++last_click_count_;
      } else {
        last_click_count_ = 1;
        last_click_position = m_position;
      }
      last_click_time_ = current_time;
      last_click_button = m_button;
      m_clickCount = last_click_count_;
      m_eventType = MouseEventPressed;
      break;
#endif

    case WebInputEvent::MOUSE_UP:
      m_clickCount = last_click_count_;
      m_eventType = MouseEventReleased;
      break;

    default:
      NOTREACHED() << "unexpected mouse event type";
  }

  if (webkit_glue::IsLayoutTestMode()) {
    m_clickCount = e.layout_test_click_count;
  }
}

// MakePlatformWheelEvent -----------------------------------------------------

MakePlatformWheelEvent::MakePlatformWheelEvent(Widget* widget,
                                               const WebMouseWheelEvent& e) {
  m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
  m_globalPosition = IntPoint(e.global_x, e.global_y);
  m_deltaX = static_cast<float>(e.delta_x);
  m_deltaY = static_cast<float>(e.delta_y);
  m_isAccepted = false;
  m_granularity = ScrollByLineWheelEvent;
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
}

// MakePlatformKeyboardEvent --------------------------------------------------

static inline const PlatformKeyboardEvent::Type ToPlatformKeyboardEventType(
    WebInputEvent::Type type) {
  switch (type) {
    case WebInputEvent::KEY_UP:
      return PlatformKeyboardEvent::KeyUp;
    case WebInputEvent::KEY_DOWN:
      return PlatformKeyboardEvent::KeyDown;
    case WebInputEvent::CHAR:
      return PlatformKeyboardEvent::Char;
    default:
      ASSERT_NOT_REACHED();
  }
  return PlatformKeyboardEvent::KeyDown;
}

static inline String ToSingleCharacterString(UChar c) {
  return String(&c, 1);
}

static String GetKeyIdentifierForWindowsKeyCode(unsigned short keyCode) {
  switch (keyCode) {
    case VKEY_MENU:
      return "Alt";
    case VKEY_CONTROL:
      return "Control";
    case VKEY_SHIFT:
      return "Shift";
    case VKEY_CAPITAL:
      return "CapsLock";
    case VKEY_LWIN:
    case VKEY_RWIN:
      return "Win";
    case VKEY_CLEAR:
      return "Clear";
    case VKEY_DOWN:
      return "Down";
    // "End"
    case VKEY_END:
      return "End";
    // "Enter"
    case VKEY_RETURN:
      return "Enter";
    case VKEY_EXECUTE:
      return "Execute";
    case VKEY_F1:
      return "F1";
    case VKEY_F2:
      return "F2";
    case VKEY_F3:
      return "F3";
    case VKEY_F4:
      return "F4";
    case VKEY_F5:
      return "F5";
    case VKEY_F6:
      return "F6";
    case VKEY_F7:
      return "F7";
    case VKEY_F8:
      return "F8";
    case VKEY_F9:
      return "F9";
    case VKEY_F10:
      return "F11";
    case VKEY_F12:
      return "F12";
    case VKEY_F13:
      return "F13";
    case VKEY_F14:
      return "F14";
    case VKEY_F15:
      return "F15";
    case VKEY_F16:
      return "F16";
    case VKEY_F17:
      return "F17";
    case VKEY_F18:
      return "F18";
    case VKEY_F19:
      return "F19";
    case VKEY_F20:
      return "F20";
    case VKEY_F21:
      return "F21";
    case VKEY_F22:
      return "F22";
    case VKEY_F23:
      return "F23";
    case VKEY_F24:
      return "F24";
    case VKEY_HELP:
      return "Help";
    case VKEY_HOME:
      return "Home";
    case VKEY_INSERT:
      return "Insert";
    case VKEY_LEFT:
      return "Left";
    case VKEY_NEXT:
      return "PageDown";
    case VKEY_PRIOR:
      return "PageUp";
    case VKEY_PAUSE:
      return "Pause";
    case VKEY_SNAPSHOT:
      return "PrintScreen";
    case VKEY_RIGHT:
      return "Right";
    case VKEY_SCROLL:
      return "Scroll";
    case VKEY_SELECT:
      return "Select";
    case VKEY_UP:
      return "Up";
    // Standard says that DEL becomes U+007F.
    case VKEY_DELETE:
      return "U+007F";
    default:
      return String::format("U+%04X", toupper(keyCode));
  }
}

MakePlatformKeyboardEvent::MakePlatformKeyboardEvent(const WebKeyboardEvent& e)
  {
  m_type = ToPlatformKeyboardEventType(e.type);
  if (m_type == Char || m_type == KeyDown) {
#if defined(OS_MACOSX)
    m_text = &e.text[0];
    m_unmodifiedText = &e.unmodified_text[0];
    m_keyIdentifier = &e.key_identifier[0];

    // Always use 13 for Enter/Return -- we don't want to use AppKit's
    // different character for Enter.
    if (m_windowsVirtualKeyCode == '\r') {
        m_text = "\r";
        m_unmodifiedText = "\r";
    }

    // The adjustments below are only needed in backward compatibility mode,
    // but we cannot tell what mode we are in from here.

    // Turn 0x7F into 8, because backspace needs to always be 8.
    if (m_text == "\x7F")
        m_text = "\x8";
    if (m_unmodifiedText == "\x7F")
        m_unmodifiedText = "\x8";
    // Always use 9 for tab -- we don't want to use AppKit's different character for shift-tab.
    if (m_windowsVirtualKeyCode == 9) {
        m_text = "\x9";
        m_unmodifiedText = "\x9";
    }
#elif defined(OS_WIN)
    m_text = m_unmodifiedText = ToSingleCharacterString(e.key_code);
#elif defined(OS_LINUX)
    m_text = m_unmodifiedText = ToSingleCharacterString(e.text);
#endif
  }
#if defined(OS_WIN) || defined(OS_LINUX)
  if (m_type != Char)
    m_keyIdentifier = GetKeyIdentifierForWindowsKeyCode(e.key_code);
#endif
  if (m_type == Char || m_type == KeyDown || m_type == KeyUp ||
      m_type == RawKeyDown) {
    m_windowsVirtualKeyCode = e.key_code;
  } else {
    m_windowsVirtualKeyCode = 0;
  }
  m_autoRepeat = (e.modifiers & WebInputEvent::IS_AUTO_REPEAT) != 0;
  m_isKeypad = (e.modifiers & WebInputEvent::IS_KEYPAD) != 0;
  m_shiftKey = (e.modifiers & WebInputEvent::SHIFT_KEY) != 0;
  m_ctrlKey = (e.modifiers & WebInputEvent::CTRL_KEY) != 0;
  m_altKey = (e.modifiers & WebInputEvent::ALT_KEY) != 0;
  m_metaKey = (e.modifiers & WebInputEvent::META_KEY) != 0;
#if defined(OS_WIN)
  m_isSystemKey = e.system_key;
#else
  m_isSystemKey = false;  // TODO(port): make this proper.
#endif
}

void MakePlatformKeyboardEvent::SetKeyType(Type type) {
  // According to the behavior of Webkit in Windows platform,
  // we need to convert KeyDown to RawKeydown and Char events
  // See WebKit/WebKit/Win/WebView.cpp
  ASSERT(m_type == KeyDown);
  ASSERT(type == RawKeyDown || type == Char);
  m_type = type;

  if (type == RawKeyDown) {
    m_text = String();
    m_unmodifiedText = String();
  } else {
    m_keyIdentifier = String();
    m_windowsVirtualKeyCode = 0;
  }
}

// Please refer to bug http://b/issue?id=961192, which talks about Webkit
// keyboard event handling changes. It also mentions the list of keys
// which don't have associated character events.
bool MakePlatformKeyboardEvent::IsCharacterKey() const {
  switch (windowsVirtualKeyCode()) {
    case VKEY_BACK:
    case VKEY_ESCAPE:
      return false;

    default:
      break;
  }
  return true;
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkHeldIsotropicWavelet.h"
#include "itkVowIsotropicWavelet.h"
#include "itkSimoncelliIsotropicWavelet.h"
#include "itkShannonIsotropicWavelet.h"

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkNumberToString.h"

#include "itkTestingMacros.h"

#include <string>
#include <fstream>

namespace itk
{
namespace Testing
{
// Generate values from a linear space
std::vector<double> linSpaceForIWFF( double init = 0.0, double end = 1.0, size_t points = 1000 )
{
  std::vector< double > wArray( points );
  if( points <= 1 )
    {
    throw ("linSpace needs more points");
    }
  double interval = (end - init) / (points - 1);
  for( unsigned int i = 0; i < points; ++i )
    {
    wArray[i] = init + interval * i;
    }
  return wArray;
}
}
}

template< unsigned int VDimension, typename TWaveletFunction >
int runIsotropicWaveletFrequencyFunctionTest(
  const std::string& profileDataRootPath,
  const std::string&, // outputImage,
  const unsigned int& inputBands,
  const std::string & waveletTypeName)
{
  itk::NumberToString<float> n2s;
  typedef TWaveletFunction WaveletFunctionType;
  typename WaveletFunctionType::Pointer motherWavelet =
    WaveletFunctionType::New();
  motherWavelet->SetHighPassSubBands( inputBands );

  double init   = 0.0;
  double end    = 1.0;
  size_t points = 1000;
  std::vector< double > wArray = itk::Testing::linSpaceForIWFF( init, end, points );
  // Generate profile data for sub-bands and mother wavelet itself
  std::vector< std::vector< double > > subBandsResults;
  for( unsigned int k = 0; k < inputBands + 2; ++k )
    {
    std::vector< double > bandResults;
    for( unsigned int i = 0; i < points; ++i )
      {
      if ( k == inputBands + 1 ) // mother wavelet
        {
        bandResults.push_back( motherWavelet->EvaluateMagnitude( wArray[i] ) );
        }
      else // bands
        {
        bandResults.push_back( motherWavelet->EvaluateForwardSubBand( wArray[i], k ) );
        }
      }
    subBandsResults.push_back( bandResults );
    }

  // Write profile
  const std::string outputFilePath = profileDataRootPath + "_" + waveletTypeName +  "_" + n2s(inputBands) + ".txt";
  std::ofstream ofs(outputFilePath.c_str(), std::ofstream::out);
  for( unsigned int i = 0; i < points; ++i )
    {
    ofs << wArray[i];
    for( unsigned int k = 0; k < inputBands + 2; ++k )
      {
      ofs << "," << subBandsResults[k][i];
      }
    ofs << std::endl;
    }
  ofs.close();
  return EXIT_SUCCESS;
}

int itkIsotropicWaveletFrequencyFunctionTest( int argc, char *argv[] )
{
  if( argc < 5 || argc > 6 )
    {
    std::cerr << "Usage: " << argv[0]
              << "profileDataRootPath outputImage inputBands waveletFunction [dimension]" << std::endl;
    return EXIT_FAILURE;
    }
  const std::string profileDataRootPath = argv[1];
  const std::string outputImage = argv[2];
  const unsigned int inputBands = atoi( argv[3] );
  const std:: string waveletFunction = argv[4];

  unsigned int dimension = 3;
  if( argc == 6 )
    {
    dimension = atoi( argv[5] );
    }

  typedef itk::HeldIsotropicWavelet<>       HeldWavelet;
  typedef itk::VowIsotropicWavelet<>        VowWavelet;
  typedef itk::SimoncelliIsotropicWavelet<> SimoncelliWavelet;
  typedef itk::ShannonIsotropicWavelet<>    ShannonWavelet;
  if( dimension == 2 )
    {
    if (waveletFunction == "Held")
      return runIsotropicWaveletFrequencyFunctionTest<2, HeldWavelet>(profileDataRootPath,
                                                                      outputImage,
                                                                      inputBands,
                                                                      waveletFunction);
    else if (waveletFunction == "Vow")
      return runIsotropicWaveletFrequencyFunctionTest<2, VowWavelet>(profileDataRootPath,
                                                                     outputImage,
                                                                     inputBands,
                                                                     waveletFunction);
    else if (waveletFunction == "Simoncelli")
      return runIsotropicWaveletFrequencyFunctionTest<2, SimoncelliWavelet>(profileDataRootPath,
                                                                            outputImage,
                                                                            inputBands,
                                                                            waveletFunction);
    else if (waveletFunction == "Shannon")
      return runIsotropicWaveletFrequencyFunctionTest<2, ShannonWavelet>(profileDataRootPath,
                                                                         outputImage,
                                                                         inputBands,
                                                                         waveletFunction);
    else
      {
      std::cerr << argv[4] << " is an unknown wavelet type " << std::endl;
      return EXIT_FAILURE;
      }
    }
  else if( dimension == 3 )
    {
    if (waveletFunction == "Held")
      return runIsotropicWaveletFrequencyFunctionTest<3, HeldWavelet>(profileDataRootPath,
                                                                      outputImage,
                                                                      inputBands,
                                                                      waveletFunction);
    else if (waveletFunction == "Vow")
      return runIsotropicWaveletFrequencyFunctionTest<3, VowWavelet>(profileDataRootPath,
                                                                     outputImage,
                                                                     inputBands,
                                                                     waveletFunction);
    else if (waveletFunction == "Simoncelli")
      return runIsotropicWaveletFrequencyFunctionTest<3, SimoncelliWavelet>(profileDataRootPath,
                                                                            outputImage,
                                                                            inputBands,
                                                                            waveletFunction);
    else if (waveletFunction == "Shannon")
      return runIsotropicWaveletFrequencyFunctionTest<3, ShannonWavelet>(profileDataRootPath,
                                                                         outputImage,
                                                                         inputBands,
                                                                         waveletFunction);
    else
      {
    std::cerr << "Test failed!" << std::endl;
      std::cerr << argv[4] << " wavelet type not supported." << std::endl;
      return EXIT_FAILURE;
      }
    }
  else
    {
    std::cerr << "Test failed!" << std::endl;
    std::cerr << "Error: only 2 or 3 dimensions allowed, " << dimension << " selected." << std::endl;
    return EXIT_FAILURE;
    }
}
<commit_msg>DOC: Test generate .txt file for figures in paper.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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 "itkHeldIsotropicWavelet.h"
#include "itkVowIsotropicWavelet.h"
#include "itkSimoncelliIsotropicWavelet.h"
#include "itkShannonIsotropicWavelet.h"

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkNumberToString.h"

#include "itkTestingMacros.h"

#include <string>
#include <fstream>

namespace itk
{
namespace Testing
{
// Generate values from a linear space
std::vector<double> linSpaceForIWFF( double init = 0.0, double end = 1.0, size_t points = 1000 )
{
  std::vector< double > wArray( points );
  if( points <= 1 )
    {
    throw ("linSpace needs more points");
    }
  double interval = (end - init) / (points - 1);
  for( unsigned int i = 0; i < points; ++i )
    {
    wArray[i] = init + interval * i;
    }
  return wArray;
}
}
}

template< unsigned int VDimension, typename TWaveletFunction >
int runIsotropicWaveletFrequencyFunctionTest(
  const std::string& profileDataRootPath,
  const std::string&, // outputImage,
  const unsigned int& inputBands,
  const std::string & waveletTypeName)
{
  itk::NumberToString<float> n2s;
  typedef TWaveletFunction WaveletFunctionType;
  typename WaveletFunctionType::Pointer motherWavelet =
    WaveletFunctionType::New();
  motherWavelet->SetHighPassSubBands( inputBands );

  double init   = 0.0;
  double end    = 1.0;
  size_t points = 1000;
  std::vector< double > wArray = itk::Testing::linSpaceForIWFF( init, end, points );
  // Generate profile data for sub-bands
  std::vector< std::vector< double > > subBandsResults;
  for( unsigned int k = 0; k < inputBands + 1; ++k )
    {
    std::vector< double > bandResults;
    for( unsigned int i = 0; i < points; ++i )
      {
      bandResults.push_back( motherWavelet->EvaluateForwardSubBand( wArray[i], k ) );
      }
    subBandsResults.push_back( bandResults );
    }

  // Generate mother wavelet profile h(2^i w) at different levels
  std::vector< std::vector< double > > radialFrequenciesMotherWavelet;
  unsigned int numLevels = 4;
  for (unsigned int levels = 0; levels < numLevels ; ++levels)
    {
    std::vector< double > resultPerLevel;
    double levelFactor = (levels == 0) ? 1.0 : std::pow(2.0, static_cast<double>(levels));
    for( unsigned int i = 0; i < points; ++i )
      {
      resultPerLevel.push_back( motherWavelet->EvaluateMagnitude( levelFactor * wArray[i] ) );
      }
    radialFrequenciesMotherWavelet.push_back( resultPerLevel );
    }

  // Write subbands
  const std::string outputFilePathSubBands = profileDataRootPath + "_" + waveletTypeName +  "_" + n2s(inputBands) + "_SubBands.txt";
  std::ofstream ofsSB(outputFilePathSubBands.c_str(), std::ofstream::out);
  for( unsigned int i = 0; i < points; ++i )
    {
    ofsSB << wArray[i];
    for( unsigned int k = 0; k < inputBands + 1; ++k )
      {
      ofsSB << "," << subBandsResults[k][i];
      }
    ofsSB << std::endl;
    }
  ofsSB.close();
  // Write mother wavelets
  const std::string outputFilePathMotherWavelet = profileDataRootPath + "_" + waveletTypeName +  "_" + n2s(inputBands) + "_Mother.txt";
  std::ofstream ofsMW(outputFilePathMotherWavelet.c_str(), std::ofstream::out);
  for( unsigned int i = 0; i < points; ++i )
    {
    ofsMW << wArray[i];
    for (unsigned int levels = 0; levels < numLevels ; ++levels)
      {
      ofsMW << "," << radialFrequenciesMotherWavelet[levels][i];
      }
    ofsMW << std::endl;
    }
  ofsMW.close();
  return EXIT_SUCCESS;
}

int itkIsotropicWaveletFrequencyFunctionTest( int argc, char *argv[] )
{
  if( argc < 5 || argc > 6 )
    {
    std::cerr << "Usage: " << argv[0]
              << "profileDataRootPath outputImage inputBands waveletFunction [dimension]" << std::endl;
    return EXIT_FAILURE;
    }
  const std::string profileDataRootPath = argv[1];
  const std::string outputImage = argv[2];
  const unsigned int inputBands = atoi( argv[3] );
  const std:: string waveletFunction = argv[4];

  unsigned int dimension = 3;
  if( argc == 6 )
    {
    dimension = atoi( argv[5] );
    }

  typedef itk::HeldIsotropicWavelet<>       HeldWavelet;
  typedef itk::VowIsotropicWavelet<>        VowWavelet;
  typedef itk::SimoncelliIsotropicWavelet<> SimoncelliWavelet;
  typedef itk::ShannonIsotropicWavelet<>    ShannonWavelet;
  if( dimension == 2 )
    {
    if (waveletFunction == "Held")
      return runIsotropicWaveletFrequencyFunctionTest<2, HeldWavelet>(profileDataRootPath,
                                                                      outputImage,
                                                                      inputBands,
                                                                      waveletFunction);
    else if (waveletFunction == "Vow")
      return runIsotropicWaveletFrequencyFunctionTest<2, VowWavelet>(profileDataRootPath,
                                                                     outputImage,
                                                                     inputBands,
                                                                     waveletFunction);
    else if (waveletFunction == "Simoncelli")
      return runIsotropicWaveletFrequencyFunctionTest<2, SimoncelliWavelet>(profileDataRootPath,
                                                                            outputImage,
                                                                            inputBands,
                                                                            waveletFunction);
    else if (waveletFunction == "Shannon")
      return runIsotropicWaveletFrequencyFunctionTest<2, ShannonWavelet>(profileDataRootPath,
                                                                         outputImage,
                                                                         inputBands,
                                                                         waveletFunction);
    else
      {
      std::cerr << argv[4] << " is an unknown wavelet type " << std::endl;
      return EXIT_FAILURE;
      }
    }
  else if( dimension == 3 )
    {
    if (waveletFunction == "Held")
      return runIsotropicWaveletFrequencyFunctionTest<3, HeldWavelet>(profileDataRootPath,
                                                                      outputImage,
                                                                      inputBands,
                                                                      waveletFunction);
    else if (waveletFunction == "Vow")
      return runIsotropicWaveletFrequencyFunctionTest<3, VowWavelet>(profileDataRootPath,
                                                                     outputImage,
                                                                     inputBands,
                                                                     waveletFunction);
    else if (waveletFunction == "Simoncelli")
      return runIsotropicWaveletFrequencyFunctionTest<3, SimoncelliWavelet>(profileDataRootPath,
                                                                            outputImage,
                                                                            inputBands,
                                                                            waveletFunction);
    else if (waveletFunction == "Shannon")
      return runIsotropicWaveletFrequencyFunctionTest<3, ShannonWavelet>(profileDataRootPath,
                                                                         outputImage,
                                                                         inputBands,
                                                                         waveletFunction);
    else
      {
    std::cerr << "Test failed!" << std::endl;
      std::cerr << argv[4] << " wavelet type not supported." << std::endl;
      return EXIT_FAILURE;
      }
    }
  else
    {
    std::cerr << "Test failed!" << std::endl;
    std::cerr << "Error: only 2 or 3 dimensions allowed, " << dimension << " selected." << std::endl;
    return EXIT_FAILURE;
    }
}
<|endoftext|>