<commit_before>// Copyright (c) 2014 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <string>
#include <sstream>

#include "nan.h"
#include "steam/steam_api.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "greenworks_utils.h"

namespace {

v8::Local<v8::Object> GetSteamUserCountType(int type_id) {
  v8::Local<v8::Object> account_type = NanNew<v8::Object>();
  std::string name;
  switch (type_id){
    case k_EAccountTypeAnonGameServer:
      name = "k_EAccountTypeAnonGameServer";
      break;
    case k_EAccountTypeAnonUser:
      name = "k_EAccountTypeAnonUser";
      break;
    case k_EAccountTypeChat:
      name = "k_EAccountTypeChat";
      break;
    case k_EAccountTypeClan:
      name = "k_EAccountTypeClan";
      break;
    case k_EAccountTypeConsoleUser:
      name = "k_EAccountTypeConsoleUser";
      break;
    case k_EAccountTypeContentServer:
      name = "k_EAccountTypeContentServer";
      break;
    case k_EAccountTypeGameServer:
      name = "k_EAccountTypeGameServer";
      break;
    case k_EAccountTypeIndividual:
      name = "k_EAccountTypeIndividual";
      break;
    case k_EAccountTypeInvalid:
      name = "k_EAccountTypeInvalid";
      break;
    case k_EAccountTypeMax:
      name = "k_EAccountTypeMax";
      break;
    case k_EAccountTypeMultiseat:
      name = "k_EAccountTypeMultiseat";
      break;
    case k_EAccountTypePending:
      name = "k_EAccountTypePending";
      break;
  }
  account_type->Set(NanNew("name"), NanNew(name));
  account_type->Set(NanNew("value"), NanNew(type_id));
  return account_type;
}

NAN_METHOD(InitAPI) {
  NanScope();

  bool success = SteamAPI_Init();

  if (success) {
    ISteamUserStats* stream_user_stats = SteamUserStats();
    stream_user_stats->RequestCurrentStats();
  }

  NanReturnValue(NanNew(success));
}

NAN_METHOD(GetSteamId) {
  NanScope();
  CSteamID user_id = SteamUser()->GetSteamID();
  v8::Local<v8::Object> flags = NanNew<v8::Object>();
  flags->Set(NanNew("anonymous"), NanNew(user_id.BAnonAccount()));
  flags->Set(NanNew("anonymousGameServer"),
      NanNew(user_id.BAnonGameServerAccount()));
  flags->Set(NanNew("anonymousGameServerLogin"),
      NanNew(user_id.BBlankAnonAccount()));
  flags->Set(NanNew("anonymousUser"), NanNew(user_id.BAnonUserAccount()));
  flags->Set(NanNew("chat"), NanNew(user_id.BChatAccount()));
  flags->Set(NanNew("clan"), NanNew(user_id.BClanAccount()));
  flags->Set(NanNew("consoleUser"), NanNew(user_id.BConsoleUserAccount()));
  flags->Set(NanNew("contentServer"), NanNew(user_id.BContentServerAccount()));
  flags->Set(NanNew("gameServer"), NanNew(user_id.BGameServerAccount()));
  flags->Set(NanNew("individual"), NanNew(user_id.BIndividualAccount()));
  flags->Set(NanNew("gameServerPersistent"),
      NanNew(user_id.BPersistentGameServerAccount()));
  flags->Set(NanNew("lobby"), NanNew(user_id.IsLobby()));

  v8::Local<v8::Object> result = NanNew<v8::Object>();
  result->Set(NanNew("flags"), flags);
  result->Set(NanNew("type"), GetSteamUserCountType(user_id.GetEAccountType()));
  result->Set(NanNew("accountId"), NanNew<v8::Integer>(user_id.GetAccountID()));
  result->Set(NanNew("staticAccountId"),
              NanNew<v8::Integer>(user_id.GetStaticAccountKey()));
  result->Set(NanNew("isValid"), NanNew<v8::Integer>(user_id.IsValid()));
  result->Set(NanNew("level"), NanNew<v8::Integer>(
        SteamUser()->GetPlayerSteamLevel()));

  if (!SteamFriends()->RequestUserInformation(user_id, true)) {
    result->Set(NanNew("screenName"),
                NanNew(SteamFriends()->GetFriendPersonaName(user_id)));
  } else {
    std::ostringstream sout;
    sout << user_id.GetAccountID();
    result->Set(NanNew("screenName"), NanNew(sout.str()));
  }
  NanReturnValue(result);
}

NAN_METHOD(SaveTextToFile) {
  NanScope();

  if (args.Length() < 4) {
    NanThrowTypeError("Wrong numer of arguments, should be 4.");
    NanReturnUndefined();
  }

  std::string file_name(*(v8::String::Utf8Value(args[0])));
  std::string content(*(v8::String::Utf8Value(args[1])));
  NanCallback* successCallback = new NanCallback(args[2].As<v8::Function>());
  NanCallback* errorCallback = new NanCallback(args[3].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileSaveWorker(successCallback,
                                                     errorCallback,
                                                     file_name,
                                                     content));
  NanReturnUndefined();
}

NAN_METHOD(ReadTextFromFile) {
  NanScope();

  if (args.Length() < 3) {
    NanThrowTypeError("Wrong numer of arguments, should be 3.");
    NanReturnUndefined();
  }

  std::string file_name(*(v8::String::Utf8Value(args[0])));
  NanCallback* successCallback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* errorCallback = new NanCallback(args[2].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileReadWorker(successCallback,
                                                     errorCallback,
                                                     file_name));
  NanReturnUndefined();
}

NAN_METHOD(IsCloudEnabled) {
  NanScope();
  ISteamRemoteStorage* steam_remote_storage = SteamRemoteStorage();
  NanReturnValue(NanNew<v8::Boolean>(
      steam_remote_storage->IsCloudEnabledForApp()));
}

NAN_METHOD(IsCloudEnabledForUser) {
  NanScope();
  ISteamRemoteStorage* steam_remote_storage = SteamRemoteStorage();
  NanReturnValue(NanNew<v8::Boolean>(
      steam_remote_storage->IsCloudEnabledForAccount()));
}

NAN_METHOD(EnableCloud) {
  NanScope();

  if (args.Length() < 1) {
    NanThrowTypeError("Wrong numer of arguments, should be 1.");
    NanReturnUndefined();
  }
  bool enable_flag = args[0]->BooleanValue();
  SteamRemoteStorage()->SetCloudEnabledForApp(enable_flag);
  NanReturnUndefined();
}

NAN_METHOD(GetCloudQuota) {
  NanScope();

  if (args.Length() < 2) {
    NanThrowTypeError("Wrong numer of arguments, should be 2.");
    NanReturnUndefined();
  }
  NanCallback* success_callback = new NanCallback(args[0].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[1].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::CloudQuotaGetWorker(success_callback,
                                                          error_callback));
  NanReturnUndefined();
}

NAN_METHOD(ActivateAchievement) {
  NanScope();

  if (args.Length() < 3) {
    NanThrowTypeError("Wrong numer of arguments, should be 3.");
    NanReturnUndefined();
  }
  std::string achievement = (*(v8::String::Utf8Value(args[0])));
  NanCallback* success_callback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[2].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::ActivateAchievementWorker(
      success_callback, error_callback, achievement));
  NanReturnUndefined();
}

NAN_METHOD(GetCurrentGameLanguage) {
  NanScope();
  NanReturnValue(NanNew(SteamApps()->GetCurrentGameLanguage()));
}

NAN_METHOD(GetCurrentUILanguage) {
  NanScope();
  NanReturnValue(NanNew(SteamUtils()->GetSteamUILanguage()));
}

// TODO: Implement get game install directory.
NAN_METHOD(GetCurrentGameInstallDir) {
  NanScope();
  NanReturnValue(NanNew("NOT IMPLEMENTED"));
}

NAN_METHOD(GetNumberOfPlayers) {
  NanScope();
  if (args.Length() < 2) {
    NanThrowTypeError("Wrong numer of arguments, should be 2.");
    NanReturnUndefined();
  }
  NanCallback* success_callback = new NanCallback(args[0].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[1].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::GetNumberOfPlayersWorker(
      success_callback, error_callback));
  NanReturnUndefined();
}

NAN_METHOD(FileShare) {
  NanScope();

  if (args.Length() < 2) {
    NanThrowTypeError("Wrong numer of arguments, should be 2.");
    NanReturnUndefined();
  }
  std::string file_name(*(v8::String::Utf8Value(args[0])));
  NanCallback* success_callback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[2].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileShareWorker(
      success_callback, error_callback, file_name));
  NanReturnUndefined();
}

void init(v8::Handle<v8::Object> exports) {
  // Common APIs.
  exports->Set(NanNew("initAPI"),
               NanNew<v8::FunctionTemplate>(InitAPI)->GetFunction());
  exports->Set(NanNew("getSteamId"),
               NanNew<v8::FunctionTemplate>(GetSteamId)->GetFunction());
  // File related APIs.
  exports->Set(NanNew("saveTextToFile"),
               NanNew<v8::FunctionTemplate>(SaveTextToFile)->GetFunction());
  exports->Set(NanNew("readTextFromFile"),
               NanNew<v8::FunctionTemplate>(ReadTextFromFile)->GetFunction());
  // Cloud related APIs.
  exports->Set(NanNew("isCloudEnabled"),
               NanNew<v8::FunctionTemplate>(IsCloudEnabled)->GetFunction());
  exports->Set(NanNew("isCloudEnabledForUser"),
               NanNew<v8::FunctionTemplate>(
                   IsCloudEnabledForUser)->GetFunction());
  exports->Set(NanNew("enableCloud"),
               NanNew<v8::FunctionTemplate>(EnableCloud)->GetFunction());
  exports->Set(NanNew("getCloudQuota"),
               NanNew<v8::FunctionTemplate>(GetCloudQuota)->GetFunction());
  // Achievement related APIs.
  exports->Set(NanNew("activateAchievement"),
               NanNew<v8::FunctionTemplate>(
                   ActivateAchievement)->GetFunction());
  // Game setting related APIs.
  exports->Set(NanNew("getCurrentGameLanguage"),
                      NanNew<v8::FunctionTemplate>(
                          GetCurrentGameLanguage)->GetFunction());
  exports->Set(NanNew("getCurrentUILanguage"),
               NanNew<v8::FunctionTemplate>(
                   GetCurrentUILanguage)->GetFunction());
  exports->Set(NanNew("getCurrentGameInstallDir"),
               NanNew<v8::FunctionTemplate>(
                   GetCurrentGameInstallDir)->GetFunction());
  exports->Set(NanNew("getNumberOfPlayers"),
               NanNew<v8::FunctionTemplate>(GetNumberOfPlayers)->GetFunction());
  // WorkShop related APIs
  exports->Set(NanNew("fileShare"),
               NanNew<v8::FunctionTemplate>(FileShare)->GetFunction());
  // Utils related APIs.
  utils::InitUtilsObject(exports);
}

}  // namespace

#ifdef _WIN32
	NODE_MODULE(greenworks_win, init)
#elif __APPLE__
	NODE_MODULE(greenworks_osx, init)
#elif __linux__
  #if __x86_64__ || __ppc64__
    NODE_MODULE(greenworks_linux64, init)
  #else
    NODE_MODULE(greenworks_linux32, init)
  #endif
#endif
<commit_msg>Fix wrong args check in shareFile API.<commit_after>// Copyright (c) 2014 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <string>
#include <sstream>

#include "nan.h"
#include "steam/steam_api.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "greenworks_utils.h"

namespace {

v8::Local<v8::Object> GetSteamUserCountType(int type_id) {
  v8::Local<v8::Object> account_type = NanNew<v8::Object>();
  std::string name;
  switch (type_id){
    case k_EAccountTypeAnonGameServer:
      name = "k_EAccountTypeAnonGameServer";
      break;
    case k_EAccountTypeAnonUser:
      name = "k_EAccountTypeAnonUser";
      break;
    case k_EAccountTypeChat:
      name = "k_EAccountTypeChat";
      break;
    case k_EAccountTypeClan:
      name = "k_EAccountTypeClan";
      break;
    case k_EAccountTypeConsoleUser:
      name = "k_EAccountTypeConsoleUser";
      break;
    case k_EAccountTypeContentServer:
      name = "k_EAccountTypeContentServer";
      break;
    case k_EAccountTypeGameServer:
      name = "k_EAccountTypeGameServer";
      break;
    case k_EAccountTypeIndividual:
      name = "k_EAccountTypeIndividual";
      break;
    case k_EAccountTypeInvalid:
      name = "k_EAccountTypeInvalid";
      break;
    case k_EAccountTypeMax:
      name = "k_EAccountTypeMax";
      break;
    case k_EAccountTypeMultiseat:
      name = "k_EAccountTypeMultiseat";
      break;
    case k_EAccountTypePending:
      name = "k_EAccountTypePending";
      break;
  }
  account_type->Set(NanNew("name"), NanNew(name));
  account_type->Set(NanNew("value"), NanNew(type_id));
  return account_type;
}

NAN_METHOD(InitAPI) {
  NanScope();

  bool success = SteamAPI_Init();

  if (success) {
    ISteamUserStats* stream_user_stats = SteamUserStats();
    stream_user_stats->RequestCurrentStats();
  }

  NanReturnValue(NanNew(success));
}

NAN_METHOD(GetSteamId) {
  NanScope();
  CSteamID user_id = SteamUser()->GetSteamID();
  v8::Local<v8::Object> flags = NanNew<v8::Object>();
  flags->Set(NanNew("anonymous"), NanNew(user_id.BAnonAccount()));
  flags->Set(NanNew("anonymousGameServer"),
      NanNew(user_id.BAnonGameServerAccount()));
  flags->Set(NanNew("anonymousGameServerLogin"),
      NanNew(user_id.BBlankAnonAccount()));
  flags->Set(NanNew("anonymousUser"), NanNew(user_id.BAnonUserAccount()));
  flags->Set(NanNew("chat"), NanNew(user_id.BChatAccount()));
  flags->Set(NanNew("clan"), NanNew(user_id.BClanAccount()));
  flags->Set(NanNew("consoleUser"), NanNew(user_id.BConsoleUserAccount()));
  flags->Set(NanNew("contentServer"), NanNew(user_id.BContentServerAccount()));
  flags->Set(NanNew("gameServer"), NanNew(user_id.BGameServerAccount()));
  flags->Set(NanNew("individual"), NanNew(user_id.BIndividualAccount()));
  flags->Set(NanNew("gameServerPersistent"),
      NanNew(user_id.BPersistentGameServerAccount()));
  flags->Set(NanNew("lobby"), NanNew(user_id.IsLobby()));

  v8::Local<v8::Object> result = NanNew<v8::Object>();
  result->Set(NanNew("flags"), flags);
  result->Set(NanNew("type"), GetSteamUserCountType(user_id.GetEAccountType()));
  result->Set(NanNew("accountId"), NanNew<v8::Integer>(user_id.GetAccountID()));
  result->Set(NanNew("staticAccountId"),
              NanNew<v8::Integer>(user_id.GetStaticAccountKey()));
  result->Set(NanNew("isValid"), NanNew<v8::Integer>(user_id.IsValid()));
  result->Set(NanNew("level"), NanNew<v8::Integer>(
        SteamUser()->GetPlayerSteamLevel()));

  if (!SteamFriends()->RequestUserInformation(user_id, true)) {
    result->Set(NanNew("screenName"),
                NanNew(SteamFriends()->GetFriendPersonaName(user_id)));
  } else {
    std::ostringstream sout;
    sout << user_id.GetAccountID();
    result->Set(NanNew("screenName"), NanNew(sout.str()));
  }
  NanReturnValue(result);
}

NAN_METHOD(SaveTextToFile) {
  NanScope();

  if (args.Length() < 4) {
    NanThrowTypeError("Wrong numer of arguments, should be 4.");
    NanReturnUndefined();
  }

  std::string file_name(*(v8::String::Utf8Value(args[0])));
  std::string content(*(v8::String::Utf8Value(args[1])));
  NanCallback* successCallback = new NanCallback(args[2].As<v8::Function>());
  NanCallback* errorCallback = new NanCallback(args[3].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileSaveWorker(successCallback,
                                                     errorCallback,
                                                     file_name,
                                                     content));
  NanReturnUndefined();
}

NAN_METHOD(ReadTextFromFile) {
  NanScope();

  if (args.Length() < 3) {
    NanThrowTypeError("Wrong numer of arguments, should be 3.");
    NanReturnUndefined();
  }

  std::string file_name(*(v8::String::Utf8Value(args[0])));
  NanCallback* successCallback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* errorCallback = new NanCallback(args[2].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileReadWorker(successCallback,
                                                     errorCallback,
                                                     file_name));
  NanReturnUndefined();
}

NAN_METHOD(IsCloudEnabled) {
  NanScope();
  ISteamRemoteStorage* steam_remote_storage = SteamRemoteStorage();
  NanReturnValue(NanNew<v8::Boolean>(
      steam_remote_storage->IsCloudEnabledForApp()));
}

NAN_METHOD(IsCloudEnabledForUser) {
  NanScope();
  ISteamRemoteStorage* steam_remote_storage = SteamRemoteStorage();
  NanReturnValue(NanNew<v8::Boolean>(
      steam_remote_storage->IsCloudEnabledForAccount()));
}

NAN_METHOD(EnableCloud) {
  NanScope();

  if (args.Length() < 1) {
    NanThrowTypeError("Wrong numer of arguments, should be 1.");
    NanReturnUndefined();
  }
  bool enable_flag = args[0]->BooleanValue();
  SteamRemoteStorage()->SetCloudEnabledForApp(enable_flag);
  NanReturnUndefined();
}

NAN_METHOD(GetCloudQuota) {
  NanScope();

  if (args.Length() < 2) {
    NanThrowTypeError("Wrong numer of arguments, should be 2.");
    NanReturnUndefined();
  }
  NanCallback* success_callback = new NanCallback(args[0].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[1].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::CloudQuotaGetWorker(success_callback,
                                                          error_callback));
  NanReturnUndefined();
}

NAN_METHOD(ActivateAchievement) {
  NanScope();

  if (args.Length() < 3) {
    NanThrowTypeError("Wrong numer of arguments, should be 3.");
    NanReturnUndefined();
  }
  std::string achievement = (*(v8::String::Utf8Value(args[0])));
  NanCallback* success_callback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[2].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::ActivateAchievementWorker(
      success_callback, error_callback, achievement));
  NanReturnUndefined();
}

NAN_METHOD(GetCurrentGameLanguage) {
  NanScope();
  NanReturnValue(NanNew(SteamApps()->GetCurrentGameLanguage()));
}

NAN_METHOD(GetCurrentUILanguage) {
  NanScope();
  NanReturnValue(NanNew(SteamUtils()->GetSteamUILanguage()));
}

// TODO: Implement get game install directory.
NAN_METHOD(GetCurrentGameInstallDir) {
  NanScope();
  NanReturnValue(NanNew("NOT IMPLEMENTED"));
}

NAN_METHOD(GetNumberOfPlayers) {
  NanScope();
  if (args.Length() < 2) {
    NanThrowTypeError("Wrong numer of arguments, should be 2.");
    NanReturnUndefined();
  }
  NanCallback* success_callback = new NanCallback(args[0].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[1].As<v8::Function>());
  NanAsyncQueueWorker(new greenworks::GetNumberOfPlayersWorker(
      success_callback, error_callback));
  NanReturnUndefined();
}

NAN_METHOD(FileShare) {
  NanScope();

  if (args.Length() < 3) {
    NanThrowTypeError("Wrong numer of arguments, should be 3.");
    NanReturnUndefined();
  }
  std::string file_name(*(v8::String::Utf8Value(args[0])));
  NanCallback* success_callback = new NanCallback(args[1].As<v8::Function>());
  NanCallback* error_callback = new NanCallback(args[2].As<v8::Function>());

  NanAsyncQueueWorker(new greenworks::FileShareWorker(
      success_callback, error_callback, file_name));
  NanReturnUndefined();
}

void init(v8::Handle<v8::Object> exports) {
  // Common APIs.
  exports->Set(NanNew("initAPI"),
               NanNew<v8::FunctionTemplate>(InitAPI)->GetFunction());
  exports->Set(NanNew("getSteamId"),
               NanNew<v8::FunctionTemplate>(GetSteamId)->GetFunction());
  // File related APIs.
  exports->Set(NanNew("saveTextToFile"),
               NanNew<v8::FunctionTemplate>(SaveTextToFile)->GetFunction());
  exports->Set(NanNew("readTextFromFile"),
               NanNew<v8::FunctionTemplate>(ReadTextFromFile)->GetFunction());
  // Cloud related APIs.
  exports->Set(NanNew("isCloudEnabled"),
               NanNew<v8::FunctionTemplate>(IsCloudEnabled)->GetFunction());
  exports->Set(NanNew("isCloudEnabledForUser"),
               NanNew<v8::FunctionTemplate>(
                   IsCloudEnabledForUser)->GetFunction());
  exports->Set(NanNew("enableCloud"),
               NanNew<v8::FunctionTemplate>(EnableCloud)->GetFunction());
  exports->Set(NanNew("getCloudQuota"),
               NanNew<v8::FunctionTemplate>(GetCloudQuota)->GetFunction());
  // Achievement related APIs.
  exports->Set(NanNew("activateAchievement"),
               NanNew<v8::FunctionTemplate>(
                   ActivateAchievement)->GetFunction());
  // Game setting related APIs.
  exports->Set(NanNew("getCurrentGameLanguage"),
                      NanNew<v8::FunctionTemplate>(
                          GetCurrentGameLanguage)->GetFunction());
  exports->Set(NanNew("getCurrentUILanguage"),
               NanNew<v8::FunctionTemplate>(
                   GetCurrentUILanguage)->GetFunction());
  exports->Set(NanNew("getCurrentGameInstallDir"),
               NanNew<v8::FunctionTemplate>(
                   GetCurrentGameInstallDir)->GetFunction());
  exports->Set(NanNew("getNumberOfPlayers"),
               NanNew<v8::FunctionTemplate>(GetNumberOfPlayers)->GetFunction());
  // WorkShop related APIs
  exports->Set(NanNew("fileShare"),
               NanNew<v8::FunctionTemplate>(FileShare)->GetFunction());
  // Utils related APIs.
  utils::InitUtilsObject(exports);
}

}  // namespace

#ifdef _WIN32
	NODE_MODULE(greenworks_win, init)
#elif __APPLE__
	NODE_MODULE(greenworks_osx, init)
#elif __linux__
  #if __x86_64__ || __ppc64__
    NODE_MODULE(greenworks_linux64, init)
  #else
    NODE_MODULE(greenworks_linux32, init)
  #endif
#endif
<|endoftext|>


<commit_before>// Copyright 2007, Google Inc.
// 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 Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)

// Google Test - The Google C++ Testing Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
//
//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
//
// It uses the << operator when possible, and prints the bytes in the
// object otherwise.  A user can override its behavior for a class
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
// defines Foo.

#include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h>
#include <ostream>  // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"

namespace testing {

namespace {

using ::std::ostream;

#if GTEST_OS_WINDOWS_MOBILE  // Windows CE does not define _snprintf_s.
# define snprintf _snprintf
#elif _MSC_VER >= 1400  // VC 8.0 and later deprecate snprintf and _snprintf.
# define snprintf _snprintf_s
#elif _MSC_VER
# define snprintf _snprintf
#endif  // GTEST_OS_WINDOWS_MOBILE

// Prints a segment of bytes in the given object.
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
                                size_t count, ostream* os) {
  char text[5] = "";
  for (size_t i = 0; i != count; i++) {
    const size_t j = start + i;
    if (i != 0) {
      // Organizes the bytes into groups of 2 for easy parsing by
      // human.
      if ((j % 2) == 0)
        *os << ' ';
      else
        *os << '-';
    }
    snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
    *os << text;
  }
}

// Prints the bytes in the given value to the given ostream.
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
                              ostream* os) {
  // Tells the user how big the object is.
  *os << count << "-byte object <";

  const size_t kThreshold = 132;
  const size_t kChunkSize = 64;
  // If the object size is bigger than kThreshold, we'll have to omit
  // some details by printing only the first and the last kChunkSize
  // bytes.
  // TODO(wan): let the user control the threshold using a flag.
  if (count < kThreshold) {
    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
  } else {
    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
    *os << " ... ";
    // Rounds up to 2-byte boundary.
    const size_t resume_pos = (count - kChunkSize + 1)/2*2;
    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
  }
  *os << ">";
}

}  // namespace

namespace internal2 {

// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object.  The delegation simplifies the implementation, which
// uses the << operator and thus is easier done outside of the
// ::testing::internal namespace, which contains a << operator that
// sometimes conflicts with the one in STL.
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
                          ostream* os) {
  PrintBytesInObjectToImpl(obj_bytes, count, os);
}

}  // namespace internal2

namespace internal {

// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
//   - as a hexidecimal escape sequence (e.g. '\x7F'), or
//   - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
  kAsIs,
  kHexEscape,
  kSpecialEscape
};

// Returns true if c is a printable ASCII character.  We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
  return 0x20 <= c && c <= 0x7E;
}

// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
  switch (static_cast<wchar_t>(c)) {
    case L'\0':
      *os << "\\0";
      break;
    case L'\'':
      *os << "\\'";
      break;
    case L'\\':
      *os << "\\\\";
      break;
    case L'\a':
      *os << "\\a";
      break;
    case L'\b':
      *os << "\\b";
      break;
    case L'\f':
      *os << "\\f";
      break;
    case L'\n':
      *os << "\\n";
      break;
    case L'\r':
      *os << "\\r";
      break;
    case L'\t':
      *os << "\\t";
      break;
    case L'\v':
      *os << "\\v";
      break;
    default:
      if (IsPrintableAscii(c)) {
        *os << static_cast<char>(c);
        return kAsIs;
      } else {
        *os << String::Format("\\x%X", static_cast<UnsignedChar>(c));
        return kHexEscape;
      }
  }
  return kSpecialEscape;
}

// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
  switch (c) {
    case L'\'':
      *os << "'";
      return kAsIs;
    case L'"':
      *os << "\\\"";
      return kSpecialEscape;
    default:
      return PrintAsCharLiteralTo<wchar_t>(c, os);
  }
}

// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
  return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
}

// Prints a wide or narrow character c and its code.  '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence.  The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) {
  // First, print c as a literal in the most readable form we can find.
  *os << ((sizeof(c) > 1) ? "L'" : "'");
  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
  *os << "'";

  // To aid user debugging, we also print c's code in decimal, unless
  // it's 0 (in which case c was printed as '\\0', making the code
  // obvious).
  if (c == 0)
    return;
  *os << " (" << String::Format("%d", c).c_str();

  // For more convenience, we print c's code again in hexidecimal,
  // unless c was already printed in the form '\x##' or the code is in
  // [1, 9].
  if (format == kHexEscape || (1 <= c && c <= 9)) {
    // Do nothing.
  } else {
    *os << String::Format(", 0x%X",
                          static_cast<UnsignedChar>(c)).c_str();
  }
  *os << ")";
}

void PrintTo(unsigned char c, ::std::ostream* os) {
  PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
  PrintCharAndCodeTo<unsigned char>(c, os);
}

// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code.  L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) {
  PrintCharAndCodeTo<wchar_t>(wc, os);
}

// Prints the given array of characters to the ostream.
// The array starts at *begin, the length is len, it may include '\0' characters
// and may not be null-terminated.
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
  *os << "\"";
  bool is_previous_hex = false;
  for (size_t index = 0; index < len; ++index) {
    const char cur = begin[index];
    if (is_previous_hex && IsXDigit(cur)) {
      // Previous character is of '\x..' form and this character can be
      // interpreted as another hexadecimal digit in its number. Break string to
      // disambiguate.
      *os << "\" \"";
    }
    is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
  }
  *os << "\"";
}

// Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
  PrintCharsAsStringTo(begin, len, os);
}

// Prints the given array of wide characters to the ostream.
// The array starts at *begin, the length is len, it may include L'\0'
// characters and may not be null-terminated.
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
                                     ostream* os) {
  *os << "L\"";
  bool is_previous_hex = false;
  for (size_t index = 0; index < len; ++index) {
    const wchar_t cur = begin[index];
    if (is_previous_hex && 0 <= cur && cur < 128 &&
        IsXDigit(static_cast<char>(cur))) {
      // Previous character is of '\x..' form and this character can be
      // interpreted as another hexadecimal digit in its number. Break string to
      // disambiguate.
      *os << "\" L\"";
    }
    is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
  }
  *os << "\"";
}

// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
  if (s == NULL) {
    *os << "NULL";
  } else {
    *os << ImplicitCast_<const void*>(s) << " pointing to ";
    PrintCharsAsStringTo(s, strlen(s), os);
  }
}

// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
  if (s == NULL) {
    *os << "NULL";
  } else {
    *os << ImplicitCast_<const void*>(s) << " pointing to ";
    PrintWideCharsAsStringTo(s, wcslen(s), os);
  }
}
#endif  // wchar_t is native

// Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) {
  PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_GLOBAL_STRING

void PrintStringTo(const ::std::string& s, ostream* os) {
  PrintCharsAsStringTo(s.data(), s.size(), os);
}

// Prints a ::wstring object.
#if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) {
  PrintWideCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_GLOBAL_WSTRING

#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
  PrintWideCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_STD_WSTRING

}  // namespace internal

}  // namespace testing
<commit_msg>Simplifies ASCII character detection in gtest-printers.h. This also makes it possible to build Google Test on MinGW.<commit_after>// Copyright 2007, Google Inc.
// 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 Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)

// Google Test - The Google C++ Testing Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
//
//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
//
// It uses the << operator when possible, and prints the bytes in the
// object otherwise.  A user can override its behavior for a class
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
// defines Foo.

#include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h>
#include <ostream>  // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"

namespace testing {

namespace {

using ::std::ostream;

#if GTEST_OS_WINDOWS_MOBILE  // Windows CE does not define _snprintf_s.
# define snprintf _snprintf
#elif _MSC_VER >= 1400  // VC 8.0 and later deprecate snprintf and _snprintf.
# define snprintf _snprintf_s
#elif _MSC_VER
# define snprintf _snprintf
#endif  // GTEST_OS_WINDOWS_MOBILE

// Prints a segment of bytes in the given object.
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
                                size_t count, ostream* os) {
  char text[5] = "";
  for (size_t i = 0; i != count; i++) {
    const size_t j = start + i;
    if (i != 0) {
      // Organizes the bytes into groups of 2 for easy parsing by
      // human.
      if ((j % 2) == 0)
        *os << ' ';
      else
        *os << '-';
    }
    snprintf(text, sizeof(text), "%02X", obj_bytes[j]);
    *os << text;
  }
}

// Prints the bytes in the given value to the given ostream.
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
                              ostream* os) {
  // Tells the user how big the object is.
  *os << count << "-byte object <";

  const size_t kThreshold = 132;
  const size_t kChunkSize = 64;
  // If the object size is bigger than kThreshold, we'll have to omit
  // some details by printing only the first and the last kChunkSize
  // bytes.
  // TODO(wan): let the user control the threshold using a flag.
  if (count < kThreshold) {
    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
  } else {
    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
    *os << " ... ";
    // Rounds up to 2-byte boundary.
    const size_t resume_pos = (count - kChunkSize + 1)/2*2;
    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
  }
  *os << ">";
}

}  // namespace

namespace internal2 {

// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object.  The delegation simplifies the implementation, which
// uses the << operator and thus is easier done outside of the
// ::testing::internal namespace, which contains a << operator that
// sometimes conflicts with the one in STL.
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
                          ostream* os) {
  PrintBytesInObjectToImpl(obj_bytes, count, os);
}

}  // namespace internal2

namespace internal {

// Depending on the value of a char (or wchar_t), we print it in one
// of three formats:
//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
//   - as a hexidecimal escape sequence (e.g. '\x7F'), or
//   - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
  kAsIs,
  kHexEscape,
  kSpecialEscape
};

// Returns true if c is a printable ASCII character.  We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
  return 0x20 <= c && c <= 0x7E;
}

// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
  switch (static_cast<wchar_t>(c)) {
    case L'\0':
      *os << "\\0";
      break;
    case L'\'':
      *os << "\\'";
      break;
    case L'\\':
      *os << "\\\\";
      break;
    case L'\a':
      *os << "\\a";
      break;
    case L'\b':
      *os << "\\b";
      break;
    case L'\f':
      *os << "\\f";
      break;
    case L'\n':
      *os << "\\n";
      break;
    case L'\r':
      *os << "\\r";
      break;
    case L'\t':
      *os << "\\t";
      break;
    case L'\v':
      *os << "\\v";
      break;
    default:
      if (IsPrintableAscii(c)) {
        *os << static_cast<char>(c);
        return kAsIs;
      } else {
        *os << String::Format("\\x%X", static_cast<UnsignedChar>(c));
        return kHexEscape;
      }
  }
  return kSpecialEscape;
}

// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {
  switch (c) {
    case L'\'':
      *os << "'";
      return kAsIs;
    case L'"':
      *os << "\\\"";
      return kSpecialEscape;
    default:
      return PrintAsCharLiteralTo<wchar_t>(c, os);
  }
}

// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {
  return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);
}

// Prints a wide or narrow character c and its code.  '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence.  The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) {
  // First, print c as a literal in the most readable form we can find.
  *os << ((sizeof(c) > 1) ? "L'" : "'");
  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
  *os << "'";

  // To aid user debugging, we also print c's code in decimal, unless
  // it's 0 (in which case c was printed as '\\0', making the code
  // obvious).
  if (c == 0)
    return;
  *os << " (" << String::Format("%d", c).c_str();

  // For more convenience, we print c's code again in hexidecimal,
  // unless c was already printed in the form '\x##' or the code is in
  // [1, 9].
  if (format == kHexEscape || (1 <= c && c <= 9)) {
    // Do nothing.
  } else {
    *os << String::Format(", 0x%X",
                          static_cast<UnsignedChar>(c)).c_str();
  }
  *os << ")";
}

void PrintTo(unsigned char c, ::std::ostream* os) {
  PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
  PrintCharAndCodeTo<unsigned char>(c, os);
}

// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code.  L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) {
  PrintCharAndCodeTo<wchar_t>(wc, os);
}

// Prints the given array of characters to the ostream.
// The array starts at *begin, the length is len, it may include '\0' characters
// and may not be null-terminated.
static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {
  *os << "\"";
  bool is_previous_hex = false;
  for (size_t index = 0; index < len; ++index) {
    const char cur = begin[index];
    if (is_previous_hex && IsXDigit(cur)) {
      // Previous character is of '\x..' form and this character can be
      // interpreted as another hexadecimal digit in its number. Break string to
      // disambiguate.
      *os << "\" \"";
    }
    is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;
  }
  *os << "\"";
}

// Prints a (const) char array of 'len' elements, starting at address 'begin'.
void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
  PrintCharsAsStringTo(begin, len, os);
}

// Prints the given array of wide characters to the ostream.
// The array starts at *begin, the length is len, it may include L'\0'
// characters and may not be null-terminated.
static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,
                                     ostream* os) {
  *os << "L\"";
  bool is_previous_hex = false;
  for (size_t index = 0; index < len; ++index) {
    const wchar_t cur = begin[index];
    if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {
      // Previous character is of '\x..' form and this character can be
      // interpreted as another hexadecimal digit in its number. Break string to
      // disambiguate.
      *os << "\" L\"";
    }
    is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;
  }
  *os << "\"";
}

// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
  if (s == NULL) {
    *os << "NULL";
  } else {
    *os << ImplicitCast_<const void*>(s) << " pointing to ";
    PrintCharsAsStringTo(s, strlen(s), os);
  }
}

// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
  if (s == NULL) {
    *os << "NULL";
  } else {
    *os << ImplicitCast_<const void*>(s) << " pointing to ";
    PrintWideCharsAsStringTo(s, wcslen(s), os);
  }
}
#endif  // wchar_t is native

// Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) {
  PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_GLOBAL_STRING

void PrintStringTo(const ::std::string& s, ostream* os) {
  PrintCharsAsStringTo(s.data(), s.size(), os);
}

// Prints a ::wstring object.
#if GTEST_HAS_GLOBAL_WSTRING
void PrintWideStringTo(const ::wstring& s, ostream* os) {
  PrintWideCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_GLOBAL_WSTRING

#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
  PrintWideCharsAsStringTo(s.data(), s.size(), os);
}
#endif  // GTEST_HAS_STD_WSTRING

}  // namespace internal

}  // namespace testing
<|endoftext|>


<commit_before>/* Copyright 2014 Jonas Platte
 *
 * This file is part of Cyvasse Online.
 *
 * Cyvasse Online is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Cyvasse Online is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _HEXAGON_BOARD_HPP_
#define _HEXAGON_BOARD_HPP_

#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <fea/rendering/renderer2d.hpp>
#include <fea/rendering/quad.hpp>
#include "hexagon.hpp"

template<int l>
class HexagonBoard
{
	public:
		typedef typename cyvmath::hexagon<l> Hexagon;
		typedef typename Hexagon::Coordinate Coordinate;
		typedef typename std::unordered_map<Coordinate, fea::Quad*> TileMap;
		typedef std::vector<fea::Quad*> TileVec;

	private:
		// non-copyable
		HexagonBoard(const HexagonBoard&) = delete;
		const HexagonBoard& operator= (const HexagonBoard&) = delete;

		fea::Renderer2D& _renderer;

		bool _upsideDown;

		glm::uvec2 _size;
		glm::uvec2 _position;
		glm::vec2 _tileSize;

		TileMap _tileMap;
		TileVec _tileVec;

	public:
		glm::vec2 getTilePosition(Coordinate c)
		{
			glm::vec2 ret;

			if(!_upsideDown) // 'normal' orientation first
			{
				ret.x = _position.x // padding
					// normal horizontal position offset
					+ _tileSize.x * c.x()
					// additional horizontal offset due to non-orthogonal y axis
					+ (_tileSize.x / 2) * (c.y() - (Hexagon::edgeLength - 1));

				ret.y = _position.y // padding
					// inverted normal vertical offset
					// because coordinate y = 0 should be on the bottom
					// but Feather Kit has y = 0 on the top
					+ (_size.y - (_tileSize.y * c.y()))
					// to get correct origin point with inverted offsets
					- _tileSize.y;
			}
			else // upsideDown
			{
				ret.x = _position.x // padding
					// inverted normal horizontal position offset
					+ (_size.x - (_tileSize.x * c.x()))
					// to get correct origin point with inverted offsets
					- _tileSize.x
					// additional horizontal offset due to non-orthogonal y axis
					- (_tileSize.x / 2) * (c.y() - (Hexagon::edgeLength - 1));

				ret.y = _position.y // padding
					// twice-inverted -> normal vertical offset
					+ _tileSize.y * c.y();
			}

			return ret;
		}

		std::unique_ptr<Coordinate> getCoordinate(glm::ivec2 tilePosition)
		{
			// This is some crap I got from my CAS because that math part is a bit of getting over my head
			// It is very close to be fully functional, but probably no one can understand it.
			// TODO: find someone to tame this beast of a mathematical formula and rewrite this!
			int8_t y = (_size.y - (tilePosition.y - _position.y)) / _tileSize.y;
			std::unique_ptr<Coordinate> c = Coordinate::create(
					(2 * tilePosition.x + Hexagon::edgeLength * _tileSize.x - y * _tileSize.x - 2 * _position.x - _tileSize.x)
					/ (2 * _tileSize.x), y
				);

			return c;
		}

		fea::Quad* getTileAt(Coordinate c)
		{
			typename TileMap::iterator it = _tileMap.find(c);
			if(it == _tileMap.end())
				return nullptr;

			return it->second;
		}

		fea::Color getTileColor(Coordinate c, bool setup)
		{
			static fea::Color tileColors[3] = {
					{0.8f, 0.8f, 0.8f},
					{0.7f, 0.7f, 0.7f},
					{0.6f, 0.6f, 0.6f}
				};
			static fea::Color tileColorsDark[3] = {
					{0.5f, 0.5f, 0.5f},
					{0.4f, 0.4f, 0.4f},
					{0.3f, 0.3f, 0.3f}
				};

			int8_t index = (((c.x() - c.y()) % 3) + 3) % 3;

			if(setup && ((!_upsideDown && c.y() >= (l - 1)) ||
			              (_upsideDown && c.y() <= (l - 1))))
				return tileColorsDark[index];
			else
				return tileColors[index];
		}

		HexagonBoard(fea::Renderer2D& renderer, bool upsideDown)
			: _renderer(renderer)
			, _upsideDown(upsideDown)
		{
			const glm::uvec2 windowSize = renderer.getViewport().getSize();

			unsigned padding = std::min(windowSize.x, windowSize.y) / 20;

			_size = {windowSize.x - padding * 2, windowSize.y - padding * 2};

			if(_size.x / _size.y < 4.0f / 3.0f) // wider than 4:3
			{
				_tileSize.y = _size.y / static_cast<float>(l * 2 - 1);
				_tileSize.x = _tileSize.y / 3 * 4;

				_size.x = _tileSize.x * (l * 2 - 1);

				_position = {(windowSize.x - _size.x) / 2, padding};
			}
			else
			{
				_tileSize.x = _size.x / static_cast<float>(l * 2 - 1);
				_tileSize.y = _tileSize.x / 4 * 3;

				_size.y = _tileSize.x * (l * 2 - 1);

				_position = {padding, (windowSize.y - _size.y) / 2};
			}

			for(Coordinate c : Hexagon::getAllCoordinates())
			{
				fea::Quad* quad = new fea::Quad(_tileSize);

				quad->setPosition(getTilePosition(c));
				quad->setColor(getTileColor(c, true));

				// add the tile to the map and vector
				_tileVec.push_back(quad);
				std::pair<typename TileMap::iterator, bool> res = _tileMap.insert({c, quad});

				assert(res.second); // assert the insertion was successful
			}
		}

		~HexagonBoard()
		{
			for(fea::Quad* it : _tileVec)
				delete it;
		}

		const glm::vec2& getTileSize() const
		{
			return _tileSize;
		}

		void updateTileColors(int8_t fromRow, int8_t toRow, bool setup = false)
		{
			assert(fromRow <= toRow);
			for(auto it : _tileMap)
			{
				if(it.first.y() >= fromRow && it.first.y() <= toRow)
					it.second->setColor(getTileColor(it.first, setup));
			}
		}

		void tick()
		{
			for(const fea::Quad* it : _tileVec)
				_renderer.queue(*it);
		}
};

#endif // _HEXAGON_BOARD_HPP_
<commit_msg>Completed upsideDown board stuff<commit_after>/* Copyright 2014 Jonas Platte
 *
 * This file is part of Cyvasse Online.
 *
 * Cyvasse Online is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Cyvasse Online is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _HEXAGON_BOARD_HPP_
#define _HEXAGON_BOARD_HPP_

#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <fea/rendering/renderer2d.hpp>
#include <fea/rendering/quad.hpp>
#include "hexagon.hpp"

template<int l>
class HexagonBoard
{
	public:
		typedef typename cyvmath::hexagon<l> Hexagon;
		typedef typename Hexagon::Coordinate Coordinate;
		typedef typename std::unordered_map<Coordinate, fea::Quad*> TileMap;
		typedef std::vector<fea::Quad*> TileVec;

	private:
		// non-copyable
		HexagonBoard(const HexagonBoard&) = delete;
		const HexagonBoard& operator= (const HexagonBoard&) = delete;

		fea::Renderer2D& _renderer;

		bool _upsideDown;

		glm::uvec2 _size;
		glm::uvec2 _position;
		glm::vec2 _tileSize;

		TileMap _tileMap;
		TileVec _tileVec;

	public:
		glm::vec2 getTilePosition(Coordinate c)
		{
			glm::vec2 ret;

			if(!_upsideDown) // 'normal' orientation first
			{
				ret.x = _position.x // padding
					// normal horizontal position offset
					+ _tileSize.x * c.x()
					// additional horizontal offset due to non-orthogonal y axis
					+ (_tileSize.x / 2) * (c.y() - (l - 1));

				ret.y = _position.y // padding
					// inverted normal vertical offset
					// because coordinate y = 0 should be on the bottom
					// but Feather Kit has y = 0 on the top
					+ (_size.y - (_tileSize.y * c.y()))
					// to get correct origin point with inverted offsets
					- _tileSize.y;
			}
			else // upsideDown
			{
				ret.x = _position.x // padding
					// inverted normal horizontal position offset
					+ (_size.x - (_tileSize.x * c.x()))
					// to get correct origin point with inverted offsets
					- _tileSize.x
					// additional horizontal offset due to non-orthogonal y axis
					- (_tileSize.x / 2) * (c.y() - (l - 1));

				ret.y = _position.y // padding
					// twice-inverted -> normal vertical offset
					+ _tileSize.y * c.y();
			}

			return ret;
		}

		std::unique_ptr<Coordinate> getCoordinate(glm::ivec2 tilePosition)
		{
			// remove padding - we're just altering a temporary variable
			tilePosition -= glm::ivec2(_position.x, _position.y);

			int8_t x, y;

			if(!_upsideDown) // 'normal' orientation first
			{
				// y = (maximal y) - ('inverted' coord y)
				y = (l * 2 - 1)
					- tilePosition.y / _tileSize.y;

				x = (
						tilePosition.x
						+ ((l - y) * _tileSize.x / 2)
						- _tileSize.x / 2
					)
					/ _tileSize.x;
			}
			else // upsideDown
			{
				y = tilePosition.y / _tileSize.y;

				x = (l * 2 - 1)
					- ((
							tilePosition.x
							- ((l - y) * _tileSize.x / 2)
							+ _tileSize.x / 2
						)
						/ _tileSize.x
					);
			}

			return std::unique_ptr<Coordinate>(Coordinate::create(x, y));
		}

		fea::Quad* getTileAt(Coordinate c)
		{
			typename TileMap::iterator it = _tileMap.find(c);
			if(it == _tileMap.end())
				return nullptr;

			return it->second;
		}

		fea::Color getTileColor(Coordinate c, bool setup)
		{
			static fea::Color tileColors[3] = {
					{0.8f, 0.8f, 0.8f},
					{0.7f, 0.7f, 0.7f},
					{0.6f, 0.6f, 0.6f}
				};
			static fea::Color tileColorsDark[3] = {
					{0.5f, 0.5f, 0.5f},
					{0.4f, 0.4f, 0.4f},
					{0.3f, 0.3f, 0.3f}
				};

			int8_t index = (((c.x() - c.y()) % 3) + 3) % 3;

			if(setup && ((!_upsideDown && c.y() >= (l - 1)) ||
			              (_upsideDown && c.y() <= (l - 1))))
				return tileColorsDark[index];
			else
				return tileColors[index];
		}

		HexagonBoard(fea::Renderer2D& renderer, bool upsideDown)
			: _renderer(renderer)
			, _upsideDown(upsideDown)
		{
			const glm::uvec2 windowSize = renderer.getViewport().getSize();

			unsigned padding = std::min(windowSize.x, windowSize.y) / 20;

			_size = {windowSize.x - padding * 2, windowSize.y - padding * 2};

			if(_size.x / _size.y < 4.0f / 3.0f) // wider than 4:3
			{
				_tileSize.y = _size.y / static_cast<float>(l * 2 - 1);
				_tileSize.x = _tileSize.y / 3 * 4;

				_size.x = _tileSize.x * (l * 2 - 1);

				_position = {(windowSize.x - _size.x) / 2, padding};
			}
			else
			{
				_tileSize.x = _size.x / static_cast<float>(l * 2 - 1);
				_tileSize.y = _tileSize.x / 4 * 3;

				_size.y = _tileSize.x * (l * 2 - 1);

				_position = {padding, (windowSize.y - _size.y) / 2};
			}

			for(Coordinate c : Hexagon::getAllCoordinates())
			{
				fea::Quad* quad = new fea::Quad(_tileSize);

				quad->setPosition(getTilePosition(c));
				quad->setColor(getTileColor(c, true));

				// add the tile to the map and vector
				_tileVec.push_back(quad);
				std::pair<typename TileMap::iterator, bool> res = _tileMap.insert({c, quad});

				assert(res.second); // assert the insertion was successful
			}
		}

		~HexagonBoard()
		{
			for(fea::Quad* it : _tileVec)
				delete it;
		}

		const glm::vec2& getTileSize() const
		{
			return _tileSize;
		}

		void updateTileColors(int8_t fromRow, int8_t toRow, bool setup = false)
		{
			assert(fromRow <= toRow);
			for(auto it : _tileMap)
			{
				if(it.first.y() >= fromRow && it.first.y() <= toRow)
					it.second->setColor(getTileColor(it.first, setup));
			}
		}

		void tick()
		{
			for(const fea::Quad* it : _tileVec)
				_renderer.queue(*it);
		}
};

#endif // _HEXAGON_BOARD_HPP_
<|endoftext|>


<commit_before>#include <soci.h>
#include <sqlite3/soci-sqlite3.h>

#include <exception>
#include <fstream>
#include <iostream>
#include <string>

#include "log.hpp"
#include "main.hpp"
#include "parser.hpp"

/*
 * @brief Greeting message.
 */
static void greeting()
{
  std::cout << "Here we go!" << std::endl;
  std::cout << "DGSN BigWhoop parser v" << VERSION_MAJOR << "."
      << VERSION_MINOR << "." << VERSION_REVISION << std::endl;
}

/*
 * @brief Message to say good bye.
 */
static void valediction()
{
  std::cout << "Good bye!" << std::endl;
}

/*
 * @brief Check if a table exists in the database.
 */
static bool table_exists(soci::session& sql, const std::string& table)
{
  int table_found;
  std::string query = "select count(type) from sqlite_master where "
    "type='table' and name='" + table + "';";
  sql << query, soci::into(table_found);
  return table_found;
}

/*
 * @brief Check and setup the database.
 */
static void db_init(soci::session& sql)
{
  log::write(log::debug, "  database initialization ...\n");

  if(table_exists(sql, "version")) {
    int v_major, v_minor, v_revision;
    sql << "SELECT major FROM version", soci::into(v_major);
    sql << "SELECT minor FROM version", soci::into(v_minor);
    sql << "SELECT revision FROM version", soci::into(v_revision);
    log:: write(log::debug, "    database found: v%u.%u.%u\n",
      v_major, v_minor, v_revision);
    if(VERSION_MAJOR != v_major ||
       VERSION_MINOR != v_minor ||
       VERSION_REVISION != v_revision) {
      log::write(log::warning, "    [Warning] Version mismatch between parser and database\n");
    }
  } else {
    sql << "CREATE TABLE IF NOT EXISTS version(major INTEGER, "
      "minor INTEGER, revision INTEGER);";
    sql << "INSERT INTO version VALUES(:v_major,:v_minor,:v_revision)",
      soci::use(VERSION_MAJOR), soci::use(VERSION_MINOR),
      soci::use(VERSION_REVISION);
    log:: write(log::debug, "    created database: v%u.%u.%u\n",
      VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
  }

  //sql << "CREATE TABLE IF NOT EXISTS data(Id INTEGER);";

  log::write(log::debug, "  database initialized\n");
}

/*
 * @brief Get file extension.
 */
std::string get_ext(std::string path)
{
   size_t period = path.find_last_of(".");
   std::string ext = path.substr(period + 1);
   return ext;
}

/*
 * @brief Main function
 */
int main(int argc, char** argv)
{
  int result = EXIT_SUCCESS;

  greeting();
  std::filebuf fb;
  if(argc < 2 ||
  !(get_ext(argv[1]) != "json" || get_ext(argv[1]) != "js")) {
    std::cout << "Usage: " << argv[0] << " <file.json>" << std::endl;
  } else {
    try {
      soci::session sql(soci::sqlite3, DB_FILE);
      db_init(sql);

      if(fb.open(argv[1], std::ios::in)) {
        std::istream is(&fb);
        Parser parser(is);
        fb.close();
      }
    } catch (const std::exception & exception) {
      log::write(log::fatal, "[Error] %s\n", exception.what());
      result = EXIT_FAILURE;
    }
  }
  valediction();

  return result;
}

//int main(int argc, char** argv)
//{
//
//  return EXIT_SUCCESS;
//}

<commit_msg>Store and compare only relevant version information.<commit_after>#include <soci.h>
#include <sqlite3/soci-sqlite3.h>

#include <exception>
#include <fstream>
#include <iostream>
#include <string>

#include "log.hpp"
#include "main.hpp"
#include "parser.hpp"

/*
 * @brief Greeting message.
 */
static void greeting()
{
  std::cout << "Here we go!" << std::endl;
  std::cout << "DGSN BigWhoop parser v" << VERSION_MAJOR << "."
      << VERSION_MINOR << "." << VERSION_REVISION << std::endl;
}

/*
 * @brief Message to say good bye.
 */
static void valediction()
{
  std::cout << "Good bye!" << std::endl;
}

/*
 * @brief Check if a table exists in the database.
 */
static bool table_exists(soci::session& sql, const std::string& table)
{
  int table_found;
  std::string query = "select count(type) from sqlite_master where "
    "type='table' and name='" + table + "';";
  sql << query, soci::into(table_found);
  return table_found;
}

/*
 * @brief Check and setup the database.
 */
static void db_init(soci::session& sql)
{
  log::write(log::debug, "  database initialization ...\n");

  if(table_exists(sql, "version")) {
    int v_major, v_minor;
    sql << "SELECT major FROM version", soci::into(v_major);
    sql << "SELECT minor FROM version", soci::into(v_minor);
    log:: write(log::debug, "    database found: v%u.%u\n",
      v_major, v_minor);
    if(VERSION_MAJOR != v_major ||
       VERSION_MINOR != v_minor) {
      log::write(log::warning,
          "    [Warning] Version mismatch between parser and database\n");
    }
  } else {
    sql << "CREATE TABLE IF NOT EXISTS version(major INTEGER, "
      "minor INTEGER);";
    sql << "INSERT INTO version VALUES(:v_major,:v_minor)",
      soci::use(VERSION_MAJOR), soci::use(VERSION_MINOR);
    log:: write(log::debug, "    created database: v%u.%u\n",
      VERSION_MAJOR, VERSION_MINOR);
  }

  if(table_exists(sql, "data")) {
    log:: write(log::verbose, "    data found\n");
  } else {
    // TODO: Create proper data table
    sql << "CREATE TABLE IF NOT EXISTS data(Id INTEGER);";
    log:: write(log::verbose, "    data table created\n");
  }

  log::write(log::debug, "  database initialized\n");
}

/*
 * @brief Get file extension.
 */
std::string get_ext(std::string path)
{
   size_t period = path.find_last_of(".");
   std::string ext = path.substr(period + 1);
   return ext;
}

/*
 * @brief Main function
 */
int main(int argc, char** argv)
{
  int result = EXIT_SUCCESS;

  greeting();
  std::filebuf fb;
  if(argc < 2 ||
  !(get_ext(argv[1]) != "json" || get_ext(argv[1]) != "js")) {
    std::cout << "Usage: " << argv[0] << " <file.json>" << std::endl;
  } else {
    try {
      soci::session sql(soci::sqlite3, DB_FILE);
      db_init(sql);

      if(fb.open(argv[1], std::ios::in)) {
        std::istream is(&fb);
        Parser parser(is);
        fb.close();
      }
    } catch (const std::exception & exception) {
      log::write(log::fatal, "[Error] %s\n", exception.what());
      result = EXIT_FAILURE;
    }
  }
  valediction();

  return result;
}

//int main(int argc, char** argv)
//{
//
//  return EXIT_SUCCESS;
//}

<|endoftext|>


<commit_before>// UjoImro, 2013

#include <chrono>
#include <opencv2/opencv.hpp>
#include <opencv2/ocl/ocl.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "opencl.hpp"
#include "utility.hpp"
#include "filtering_morph.clh"
#include "dilate.pencil.h"

namespace {
    inline void normalizeAnchor(int & anchor, int ksize)
    {
        if (anchor < 0)
        {
            anchor = ksize >> 1;
        }

        CV_Assert(0 <= anchor && anchor < ksize);
    } // normalizeAnchor

    inline void normalizeAnchor(cv::Point & anchor, const cv::Size &ksize)
    {
        normalizeAnchor(anchor.x, ksize.width);
        normalizeAnchor(anchor.y, ksize.height);
    } // normalizeAnchor

    inline cv::Mat normalizeKernel(const cv::Mat &kernel, int type = CV_8U, int *nDivisor = 0, bool reverse = false)
    {
        int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1;
                if (nDivisor)
        {
            *nDivisor = scale;
        }

        cv::Mat temp(kernel.size(), type);
        kernel.convertTo(temp, type, scale);
        cv::Mat cont_krnl = temp.reshape(1, 1);

        if (reverse)
        {
            int count = cont_krnl.cols >> 1;

            for (int i = 0; i < count; ++i)
            {
                std::swap(cont_krnl.at<int>(0, i), cont_krnl.at<int>(0, cont_krnl.cols - 1 - i));
            }
        }

        return cont_krnl;
    } // normalizeKernel
} // unnamed namespace

namespace carp {
    cv::ocl::oclMat dilate( carp::opencl::device & device, cv::ocl::oclMat src, cv::ocl::oclMat mat_kernel, cv::Point anchor, int border_type, cv::Size ksize, bool noZero ) {

        cv::ocl::oclMat dst(src.size(), src.type());
        normalizeAnchor(anchor, ksize);

        //! data type supported: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4
        //Normalize the result by default
        //float alpha = ksize.height * ksize.width;
        CV_Assert(src.clCxt == dst.clCxt);
        CV_Assert((src.cols == dst.cols) &&
                  (src.rows == dst.rows));
        CV_Assert((src.oclchannels() == dst.oclchannels()));

        int srcStep = src.step1() / src.oclchannels();
        int dstStep = dst.step1() / dst.oclchannels();
        int srcOffset = src.offset /  src.elemSize();
        int dstOffset = dst.offset /  dst.elemSize();

        int srcOffset_x = srcOffset % srcStep;
        int srcOffset_y = srcOffset / srcStep;
        std::string kernelName;
        std::vector<size_t> localThreads = {16, 16, 1};
        std::vector<size_t> globalThreads = { (src.cols + localThreads[0] - 1) / localThreads[0] *localThreads[0]
                                            , (src.rows + localThreads[1] - 1) / localThreads[1] *localThreads[1]
                                            , 1
                                            };

        if (src.type() == CV_8UC1)
        {
            kernelName = "morph_C1_D0";
            globalThreads[0] = ((src.cols + 3) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
            CV_Assert(localThreads[0]*localThreads[1] * 8 >= (localThreads[0] * 4 + ksize.width - 1) * (localThreads[1] + ksize.height - 1));
        }
        else
        {
            kernelName = "morph";
            CV_Assert(localThreads[0]*localThreads[1] * 2 >= (localThreads[0] + ksize.width - 1) * (localThreads[1] + ksize.height - 1));
        }

        std::string compile_option;

        switch (src.type())
        {
        case CV_8UC1:
            compile_option = " -D VAL=0 ";
            break;
        case CV_8UC3:
        case CV_8UC4:
            compile_option = " -D VAL=0 -D GENTYPE=uchar4 ";
            break;
        case CV_32FC1:
            compile_option = " -D VAL=-FLT_MAX -D GENTYPE=float ";
            break;
        case CV_32FC3:
        case CV_32FC4:
            compile_option = " -D VAL=-FLT_MAX -D GENTYPE=float4 ";
            break;
        default:
            CV_Error(CV_StsUnsupportedFormat, "unsupported type");
        }
        compile_option += " -D RADIUSX=" + std::to_string(anchor.x)
            + " -D RADIUSY=" + std::to_string(anchor.y)
            + " -D LSIZE0=" + std::to_string(localThreads[0])
            + " -D LSIZE1=" + std::to_string(localThreads[1])
            + " -D DILATE ";

//                if (rectKernel) compiler_option += " -D RECTKERNEL ";

        if (noZero) compile_option += " -D RECTKERNEL ";

        device.source_compile( filtering_morph_cl, filtering_morph_cl_len, {kernelName}, compile_option );
        device[kernelName](
            reinterpret_cast<cl_mem>(src.data),
            reinterpret_cast<cl_mem>(dst.data),
            srcOffset_x,
            srcOffset_y,
            src.cols,
            src.rows,
            srcStep,
            dstStep,
            reinterpret_cast<cl_mem>(mat_kernel.data),
            src.wholecols,
            src.wholerows,
            dstOffset
            ).groupsize( localThreads, globalThreads );
        device.erase(kernelName);
        return dst;
    } // dilate

    void dilate( carp::opencl::device & device, cv::Mat cpu_gray, cv::Mat & result, cv::Mat structuring_element, cv::Point anchor, int border_type, cv::Size ksize ) {
    }

} // namespace carp

void time_dilate( const std::vector<carp::record_t>& pool, const std::vector<int>& elemsizes )
{
    carp::Timing timing("dilate image");

    for ( auto & item : pool ) {
        PRINT(item.path());
        for ( auto & elemsize : elemsizes ) {
            PRINT(elemsize);

            // acquiring the image for the test
            cv::Mat cpu_gray;
            cv::cvtColor( item.cpuimg(), cpu_gray, CV_RGB2GRAY );

            cv::Point anchor( elemsize/2, elemsize/2 );
            cv::Size ksize(elemsize, elemsize);
            cv::Mat structuring_element = cv::getStructuringElement( cv::MORPH_ELLIPSE, ksize, anchor );

            cv::Mat cpu_result, gpu_result, pen_result;
            std::chrono::microseconds elapsed_time_cpu, elapsed_time_gpu_p_copy, elapsed_time_gpu_nocopy, elapsed_time_pencil;

            {
                const auto cpu_start = std::chrono::high_resolution_clock::now();
                cv::dilate( cpu_gray, cpu_result, structuring_element, anchor, /*iteration = */1, cv::BORDER_CONSTANT );
                const auto cpu_end = std::chrono::high_resolution_clock::now();
                elapsed_time_cpu = cpu_end - cpu_start;
            }
            {
                cv::ocl::Context * context = cv::ocl::Context::getContext();
                carp::opencl::device device(context);

                bool noZero = true;
                for(int i = 0; i < structuring_element.rows * structuring_element.cols; ++i)
                    if(structuring_element.data[i] != 1)    //?!? This is NOT iterating through elements, but on BYTES!!!
                        noZero = false;

                const auto gpu_start_copy = std::chrono::high_resolution_clock::now();
                cv::ocl::oclMat src(cpu_gray);
                cv::ocl::oclMat mat_kernel(normalizeKernel(structuring_element));
                const auto gpu_start = std::chrono::high_resolution_clock::now();
                auto result = carp::dilate( device, src, mat_kernel, anchor, cv::BORDER_CONSTANT, ksize, noZero );
                const auto gpu_end = std::chrono::high_resolution_clock::now();
                gpu_result = result;
                const auto gpu_end_copy = std::chrono::high_resolution_clock::now();
                elapsed_time_gpu_p_copy = gpu_end_copy - gpu_start_copy;
                elapsed_time_gpu_nocopy = gpu_end      - gpu_start;
            }
            {
                pen_result = cv::Mat(cpu_gray.size(), CV_8U);

                const auto pencil_start = std::chrono::high_resolution_clock::now();
                pencil_dilate( cpu_gray.rows, cpu_gray.cols, cpu_gray.step1(), cpu_gray.ptr()
                             , pen_result.step1(), pen_result.ptr()
                             , structuring_element.rows, structuring_element.cols, structuring_element.step1(), structuring_element.ptr()
                             , anchor.x, anchor.y, cv::BORDER_CONSTANT
                             );
                const auto pencil_end = std::chrono::high_resolution_clock::now();
                elapsed_time_pencil = pencil_end - pencil_start;
            }
            // Verifying the results
            if ( (cv::norm(cpu_result - gpu_result) > 0.01) || (cv::norm(cpu_result - pen_result) > 0.01) ) {
                PRINT(cv::norm(gpu_result - cpu_result));
                PRINT(cv::norm(cpu_result - pen_result));
                cv::imwrite("cpu_dilate.png", cpu_result);
                cv::imwrite("gpu_dilate.png", gpu_result );
                cv::imwrite("pencil_dilate.png", pen_result );
                throw std::runtime_error("The GPU results are not equivalent with the CPU results.");
            }
            timing.print( elapsed_time_cpu, elapsed_time_gpu_p_copy, elapsed_time_gpu_nocopy, elapsed_time_pencil );
        }
    }
}

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

#ifndef BENCHMARK_PRINT_GPU_PENCIL_SPEEDUP_ONLY
    std::cout << "This executable is iterating over all the files which are present in the directory `./pool'. " << std::endl;
#endif
    auto pool = carp::get_pool("pool");
    time_dilate( pool, { /*5, 7,*/ 9/*, 11, 15, 17*/ } );
    return EXIT_SUCCESS;
}
<commit_msg>Change dilate kernel sizes<commit_after>// UjoImro, 2013

#include <chrono>
#include <opencv2/opencv.hpp>
#include <opencv2/ocl/ocl.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "opencl.hpp"
#include "utility.hpp"
#include "filtering_morph.clh"
#include "dilate.pencil.h"

namespace {
    inline void normalizeAnchor(int & anchor, int ksize)
    {
        if (anchor < 0)
        {
            anchor = ksize >> 1;
        }

        CV_Assert(0 <= anchor && anchor < ksize);
    } // normalizeAnchor

    inline void normalizeAnchor(cv::Point & anchor, const cv::Size &ksize)
    {
        normalizeAnchor(anchor.x, ksize.width);
        normalizeAnchor(anchor.y, ksize.height);
    } // normalizeAnchor

    inline cv::Mat normalizeKernel(const cv::Mat &kernel, int type = CV_8U, int *nDivisor = 0, bool reverse = false)
    {
        int scale = nDivisor && (kernel.depth() == CV_32F || kernel.depth() == CV_64F) ? 256 : 1;
                if (nDivisor)
        {
            *nDivisor = scale;
        }

        cv::Mat temp(kernel.size(), type);
        kernel.convertTo(temp, type, scale);
        cv::Mat cont_krnl = temp.reshape(1, 1);

        if (reverse)
        {
            int count = cont_krnl.cols >> 1;

            for (int i = 0; i < count; ++i)
            {
                std::swap(cont_krnl.at<int>(0, i), cont_krnl.at<int>(0, cont_krnl.cols - 1 - i));
            }
        }

        return cont_krnl;
    } // normalizeKernel
} // unnamed namespace

namespace carp {
    cv::ocl::oclMat dilate( carp::opencl::device & device, cv::ocl::oclMat src, cv::ocl::oclMat mat_kernel, cv::Point anchor, int border_type, cv::Size ksize, bool noZero ) {

        cv::ocl::oclMat dst(src.size(), src.type());
        normalizeAnchor(anchor, ksize);

        //! data type supported: CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4
        //Normalize the result by default
        //float alpha = ksize.height * ksize.width;
        CV_Assert(src.clCxt == dst.clCxt);
        CV_Assert((src.cols == dst.cols) &&
                  (src.rows == dst.rows));
        CV_Assert((src.oclchannels() == dst.oclchannels()));

        int srcStep = src.step1() / src.oclchannels();
        int dstStep = dst.step1() / dst.oclchannels();
        int srcOffset = src.offset /  src.elemSize();
        int dstOffset = dst.offset /  dst.elemSize();

        int srcOffset_x = srcOffset % srcStep;
        int srcOffset_y = srcOffset / srcStep;
        std::string kernelName;
        std::vector<size_t> localThreads = {16, 16, 1};
        std::vector<size_t> globalThreads = { (src.cols + localThreads[0] - 1) / localThreads[0] *localThreads[0]
                                            , (src.rows + localThreads[1] - 1) / localThreads[1] *localThreads[1]
                                            , 1
                                            };

        if (src.type() == CV_8UC1)
        {
            kernelName = "morph_C1_D0";
            globalThreads[0] = ((src.cols + 3) / 4 + localThreads[0] - 1) / localThreads[0] * localThreads[0];
            CV_Assert(localThreads[0]*localThreads[1] * 8 >= (localThreads[0] * 4 + ksize.width - 1) * (localThreads[1] + ksize.height - 1));
        }
        else
        {
            kernelName = "morph";
            CV_Assert(localThreads[0]*localThreads[1] * 2 >= (localThreads[0] + ksize.width - 1) * (localThreads[1] + ksize.height - 1));
        }

        std::string compile_option;

        switch (src.type())
        {
        case CV_8UC1:
            compile_option = " -D VAL=0 ";
            break;
        case CV_8UC3:
        case CV_8UC4:
            compile_option = " -D VAL=0 -D GENTYPE=uchar4 ";
            break;
        case CV_32FC1:
            compile_option = " -D VAL=-FLT_MAX -D GENTYPE=float ";
            break;
        case CV_32FC3:
        case CV_32FC4:
            compile_option = " -D VAL=-FLT_MAX -D GENTYPE=float4 ";
            break;
        default:
            CV_Error(CV_StsUnsupportedFormat, "unsupported type");
        }
        compile_option += " -D RADIUSX=" + std::to_string(anchor.x)
            + " -D RADIUSY=" + std::to_string(anchor.y)
            + " -D LSIZE0=" + std::to_string(localThreads[0])
            + " -D LSIZE1=" + std::to_string(localThreads[1])
            + " -D DILATE ";

//                if (rectKernel) compiler_option += " -D RECTKERNEL ";

        if (noZero) compile_option += " -D RECTKERNEL ";

        device.source_compile( filtering_morph_cl, filtering_morph_cl_len, {kernelName}, compile_option );
        device[kernelName](
            reinterpret_cast<cl_mem>(src.data),
            reinterpret_cast<cl_mem>(dst.data),
            srcOffset_x,
            srcOffset_y,
            src.cols,
            src.rows,
            srcStep,
            dstStep,
            reinterpret_cast<cl_mem>(mat_kernel.data),
            src.wholecols,
            src.wholerows,
            dstOffset
            ).groupsize( localThreads, globalThreads );
        device.erase(kernelName);
        return dst;
    } // dilate

    void dilate( carp::opencl::device & device, cv::Mat cpu_gray, cv::Mat & result, cv::Mat structuring_element, cv::Point anchor, int border_type, cv::Size ksize ) {
    }

} // namespace carp

void time_dilate( const std::vector<carp::record_t>& pool, const std::vector<int>& elemsizes )
{
    carp::Timing timing("dilate image");

    for ( auto & item : pool ) {
        PRINT(item.path());
        for ( auto & elemsize : elemsizes ) {
            PRINT(elemsize);

            // acquiring the image for the test
            cv::Mat cpu_gray;
            cv::cvtColor( item.cpuimg(), cpu_gray, CV_RGB2GRAY );

            cv::Point anchor( elemsize/2, elemsize/2 );
            cv::Size ksize(elemsize, elemsize);
            cv::Mat structuring_element = cv::getStructuringElement( cv::MORPH_ELLIPSE, ksize, anchor );

            cv::Mat cpu_result, gpu_result, pen_result;
            std::chrono::microseconds elapsed_time_cpu, elapsed_time_gpu_p_copy, elapsed_time_gpu_nocopy, elapsed_time_pencil;

            {
                const auto cpu_start = std::chrono::high_resolution_clock::now();
                cv::dilate( cpu_gray, cpu_result, structuring_element, anchor, /*iteration = */1, cv::BORDER_CONSTANT );
                const auto cpu_end = std::chrono::high_resolution_clock::now();
                elapsed_time_cpu = cpu_end - cpu_start;
            }
            {
                cv::ocl::Context * context = cv::ocl::Context::getContext();
                carp::opencl::device device(context);

                bool noZero = true;
                for(int i = 0; i < structuring_element.rows * structuring_element.cols; ++i)
                    if(structuring_element.data[i] != 1)    //?!? This is NOT iterating through elements, but on BYTES!!!
                        noZero = false;

                const auto gpu_start_copy = std::chrono::high_resolution_clock::now();
                cv::ocl::oclMat src(cpu_gray);
                cv::ocl::oclMat mat_kernel(normalizeKernel(structuring_element));
                const auto gpu_start = std::chrono::high_resolution_clock::now();
                auto result = carp::dilate( device, src, mat_kernel, anchor, cv::BORDER_CONSTANT, ksize, noZero );
                const auto gpu_end = std::chrono::high_resolution_clock::now();
                gpu_result = result;
                const auto gpu_end_copy = std::chrono::high_resolution_clock::now();
                elapsed_time_gpu_p_copy = gpu_end_copy - gpu_start_copy;
                elapsed_time_gpu_nocopy = gpu_end      - gpu_start;
            }
            {
                pen_result = cv::Mat(cpu_gray.size(), CV_8U);

                const auto pencil_start = std::chrono::high_resolution_clock::now();
                pencil_dilate( cpu_gray.rows, cpu_gray.cols, cpu_gray.step1(), cpu_gray.ptr()
                             , pen_result.step1(), pen_result.ptr()
                             , structuring_element.rows, structuring_element.cols, structuring_element.step1(), structuring_element.ptr()
                             , anchor.x, anchor.y, cv::BORDER_CONSTANT
                             );
                const auto pencil_end = std::chrono::high_resolution_clock::now();
                elapsed_time_pencil = pencil_end - pencil_start;
            }
            // Verifying the results
            if ( (cv::norm(cpu_result - gpu_result) > 0.01) || (cv::norm(cpu_result - pen_result) > 0.01) ) {
                PRINT(cv::norm(gpu_result - cpu_result));
                PRINT(cv::norm(cpu_result - pen_result));
                cv::imwrite("cpu_dilate.png", cpu_result);
                cv::imwrite("gpu_dilate.png", gpu_result );
                cv::imwrite("pencil_dilate.png", pen_result );
                throw std::runtime_error("The GPU results are not equivalent with the CPU results.");
            }
            timing.print( elapsed_time_cpu, elapsed_time_gpu_p_copy, elapsed_time_gpu_nocopy, elapsed_time_pencil );
        }
    }
}

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

#ifndef BENCHMARK_PRINT_GPU_PENCIL_SPEEDUP_ONLY
    std::cout << "This executable is iterating over all the files which are present in the directory `./pool'. " << std::endl;
#endif
    auto pool = carp::get_pool("pool");
    time_dilate( pool, { 3, 5, 7, 9 } );
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "gfxeditor.h"

void gfxeditor::mouse() {
  if (*mB&1) {
    temppoint.x=*mX;
    temppoint.y=*mY;
    temprect.x=offX+24;
    temprect.y=h-75;
    temprect.w=256;
    temprect.h=10;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.r=*mX-offX-24;
      } else {
        fg.r=*mX-offX-24;
      }
    }
    temprect.y=h-55;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.g=*mX-offX-24;
      } else {
        fg.g=*mX-offX-24;
      }
    }
    temprect.y=h-35;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.b=*mX-offX-24;
      } else {
        fg.b=*mX-offX-24;
      }
    }
    temprect.y=h-15;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.a=*mX-offX-24;
      } else {
        fg.a=*mX-offX-24;
      }
    }
    temprect.x=offX+288;
    temprect.y=h-80;
    temprect.w=25;
    temprect.h=20;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      fgorbg=false;
    }
    temprect.x=offX+288+29;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      fgorbg=true;
    }
  }
}

void gfxeditor::draw() {
  SDL_SetRenderDrawColor(r,color[0].r,color[0].g,color[0].b,color[0].a);
  SDL_RenderDrawLine(r,offX,h-84,w,h-84);
  gf->draw(offX+8,h-80,color[0],0,0,0,"R");
  gf->draw(offX+8,h-60,color[0],0,0,0,"G");
  gf->draw(offX+8,h-40,color[0],0,0,0,"B");
  gf->draw(offX+8,h-20,color[0],0,0,0,"A");
  // color sliders
  SDL_SetRenderDrawColor(r,color[0].r,color[0].g,color[0].b,color[0].a);
  temprect.x=offX+24;
  temprect.y=h-75;
  temprect.w=256;
  temprect.h=10;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-55;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-35;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-15;
  SDL_RenderDrawRect(r,&temprect);

  temprect.x=offX+288;
  temprect.y=h-80;
  temprect.w=25;
  temprect.h=20;
  SDL_RenderDrawRect(r,&temprect);
  temprect.x=offX+288+29;
  SDL_RenderDrawRect(r,&temprect);

  gf->draw(offX+288+29+11,h-70,color[(fgorbg)?(2):(0)],1,1,0,"B");
  gf->draw(offX+288+11,h-70,color[(fgorbg)?(0):(2)],1,1,0,"F");

  if (fgorbg) {
    SDL_RenderDrawPoint(r,offX+24+bg.r,h-76);
    SDL_RenderDrawPoint(r,offX+24+bg.g,h-56);
    SDL_RenderDrawPoint(r,offX+24+bg.b,h-36);
    SDL_RenderDrawPoint(r,offX+24+bg.a,h-16);
  } else {
    SDL_RenderDrawPoint(r,offX+24+fg.r,h-76);
    SDL_RenderDrawPoint(r,offX+24+fg.g,h-56);
    SDL_RenderDrawPoint(r,offX+24+fg.b,h-36);
    SDL_RenderDrawPoint(r,offX+24+fg.a,h-16);
  }

  if (!fgorbg) {
    SDL_SetRenderDrawColor(r,bg.r,bg.g,bg.b,255);
  } else {
    SDL_SetRenderDrawColor(r,fg.r,fg.g,fg.b,255);
  }
  temprect.x=offX+294;
  temprect.y=h-46;
  temprect.w=48;
  temprect.h=48;
  SDL_RenderFillRect(r,&temprect);
  if (fgorbg) {
    SDL_SetRenderDrawColor(r,bg.r,bg.g,bg.b,255);
  } else {
    SDL_SetRenderDrawColor(r,fg.r,fg.g,fg.b,255);
  }
  temprect.x=offX+288;
  temprect.y=h-52;
  SDL_RenderFillRect(r,&temprect);

  gf->drawf(offX+8,offY+8,color[0],0,0,"%d %d %d",*mX,*mY,*mB);
}

void gfxeditor::drawcolorpicker() {

}

void gfxeditor::setdata(unsigned char* data, int width, int height) {

}

void gfxeditor::setfont(font* fontset) {
  gf=fontset;
}

void gfxeditor::setrenderer(SDL_Renderer* renderer) {
  r=renderer;
}

void gfxeditor::setcolor(int colindex, SDL_Color colcol) {
  color[colindex]=colcol;
}

void gfxeditor::setmouse(int* x, int* y, unsigned int* b, unsigned int* bold) {
  mX=x; mY=y; mB=b; mBold=bold;
}

gfxeditor::gfxeditor() {
  bg.r=0; bg.g=0; bg.b=0; bg.a=255;
  fg.r=255; fg.g=255; fg.b=255; fg.a=255;
  fgorbg=0; // 0 is fg, 1 is bg
}<commit_msg>tiny fix to color viewer<commit_after>#include "gfxeditor.h"

void gfxeditor::mouse() {
  if (*mB&1) {
    temppoint.x=*mX;
    temppoint.y=*mY;
    temprect.x=offX+24;
    temprect.y=h-75;
    temprect.w=256;
    temprect.h=10;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.r=*mX-offX-24;
      } else {
        fg.r=*mX-offX-24;
      }
    }
    temprect.y=h-55;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.g=*mX-offX-24;
      } else {
        fg.g=*mX-offX-24;
      }
    }
    temprect.y=h-35;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.b=*mX-offX-24;
      } else {
        fg.b=*mX-offX-24;
      }
    }
    temprect.y=h-15;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      if (fgorbg) {
        bg.a=*mX-offX-24;
      } else {
        fg.a=*mX-offX-24;
      }
    }
    temprect.x=offX+288;
    temprect.y=h-80;
    temprect.w=25;
    temprect.h=20;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      fgorbg=false;
    }
    temprect.x=offX+288+29;
    if (SDL_PointInRect(&temppoint,&temprect)) {
      fgorbg=true;
    }
  }
}

void gfxeditor::draw() {
  SDL_SetRenderDrawColor(r,color[0].r,color[0].g,color[0].b,color[0].a);
  SDL_RenderDrawLine(r,offX,h-84,w,h-84);
  gf->draw(offX+8,h-80,color[0],0,0,0,"R");
  gf->draw(offX+8,h-60,color[0],0,0,0,"G");
  gf->draw(offX+8,h-40,color[0],0,0,0,"B");
  gf->draw(offX+8,h-20,color[0],0,0,0,"A");
  // color sliders
  SDL_SetRenderDrawColor(r,color[0].r,color[0].g,color[0].b,color[0].a);
  temprect.x=offX+24;
  temprect.y=h-75;
  temprect.w=256;
  temprect.h=10;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-55;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-35;
  SDL_RenderDrawRect(r,&temprect);
  temprect.y=h-15;
  SDL_RenderDrawRect(r,&temprect);

  temprect.x=offX+288;
  temprect.y=h-80;
  temprect.w=25;
  temprect.h=20;
  SDL_RenderDrawRect(r,&temprect);
  temprect.x=offX+288+29;
  SDL_RenderDrawRect(r,&temprect);

  gf->draw(offX+288+29+11,h-70,color[(fgorbg)?(2):(0)],1,1,0,"B");
  gf->draw(offX+288+11,h-70,color[(fgorbg)?(0):(2)],1,1,0,"F");

  if (fgorbg) {
    SDL_RenderDrawPoint(r,offX+24+bg.r,h-76);
    SDL_RenderDrawPoint(r,offX+24+bg.g,h-56);
    SDL_RenderDrawPoint(r,offX+24+bg.b,h-36);
    SDL_RenderDrawPoint(r,offX+24+bg.a,h-16);
  } else {
    SDL_RenderDrawPoint(r,offX+24+fg.r,h-76);
    SDL_RenderDrawPoint(r,offX+24+fg.g,h-56);
    SDL_RenderDrawPoint(r,offX+24+fg.b,h-36);
    SDL_RenderDrawPoint(r,offX+24+fg.a,h-16);
  }

  if (!fgorbg) {
    SDL_SetRenderDrawColor(r,bg.r,bg.g,bg.b,bg.a);
  } else {
    SDL_SetRenderDrawColor(r,fg.r,fg.g,fg.b,fg.a);
  }
  temprect.x=offX+294;
  temprect.y=h-46;
  temprect.w=48;
  temprect.h=48;
  SDL_RenderFillRect(r,&temprect);
  if (fgorbg) {
    SDL_SetRenderDrawColor(r,bg.r,bg.g,bg.b,bg.a);
  } else {
    SDL_SetRenderDrawColor(r,fg.r,fg.g,fg.b,fg.a);
  }
  temprect.x=offX+288;
  temprect.y=h-52;
  SDL_RenderFillRect(r,&temprect);

  gf->drawf(offX+8,offY+8,color[0],0,0,"%d %d %d",*mX,*mY,*mB);
}

void gfxeditor::drawcolorpicker() {

}

void gfxeditor::setdata(unsigned char* data, int width, int height) {

}

void gfxeditor::setfont(font* fontset) {
  gf=fontset;
}

void gfxeditor::setrenderer(SDL_Renderer* renderer) {
  r=renderer;
}

void gfxeditor::setcolor(int colindex, SDL_Color colcol) {
  color[colindex]=colcol;
}

void gfxeditor::setmouse(int* x, int* y, unsigned int* b, unsigned int* bold) {
  mX=x; mY=y; mB=b; mBold=bold;
}

gfxeditor::gfxeditor() {
  bg.r=0; bg.g=0; bg.b=0; bg.a=255;
  fg.r=255; fg.g=255; fg.b=255; fg.a=255;
  fgorbg=0; // 0 is fg, 1 is bg
}<|endoftext|>


<commit_before>/*!
 * Copyright (C) 2014 Nomovok Ltd. All rights reserved.
 * Contact: info@nomovok.com
 *
 * This file may be used under the terms of the GNU Lesser
 * General Public License version 2.1 as published by the Free Software
 * Foundation and appearing in the file LICENSE.LGPL included in the
 * packaging of this file.  Please review the following information to
 * ensure the GNU Lesser General Public License version 2.1 requirements
 * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 * In addition, as a special exception, copyright holders
 * give you certain additional rights.  These rights are described in
 * the Digia Qt LGPL Exception version 1.1, included in the file
 * LGPL_EXCEPTION.txt in this package.
 */

#include "testsimpleqmlload.h"
#include "testcreatefile.h"

#include <QTest>
#include <QCoreApplication>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    TestSimpleQmlLoad st;
    QTest::qExec(&st);

    TestCreateFile tf;
    QTest::qExec(&tf);

    return 0;
}
<commit_msg>Pass argc and argv so one can pass command line options to the tests<commit_after>/*!
 * Copyright (C) 2014 Nomovok Ltd. All rights reserved.
 * Contact: info@nomovok.com
 *
 * This file may be used under the terms of the GNU Lesser
 * General Public License version 2.1 as published by the Free Software
 * Foundation and appearing in the file LICENSE.LGPL included in the
 * packaging of this file.  Please review the following information to
 * ensure the GNU Lesser General Public License version 2.1 requirements
 * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 * In addition, as a special exception, copyright holders
 * give you certain additional rights.  These rights are described in
 * the Digia Qt LGPL Exception version 1.1, included in the file
 * LGPL_EXCEPTION.txt in this package.
 */

#include "testsimpleqmlload.h"
#include "testcreatefile.h"

#include <QTest>
#include <QCoreApplication>

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    TestSimpleQmlLoad st;
    QTest::qExec(&st, argc, argv);

    TestCreateFile tf;
    QTest::qExec(&tf, argc, argv);

    return 0;
}
<|endoftext|>


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

#include <iostream>
#include <unistd.h>
#include "ina132.h"

using namespace upm;
using namespace std;

INA132::INA132(int pin)
{
    if ( !(m_aio = mraa_aio_init(pin)) )
    {
      cerr << __FUNCTION__ << ": mraa_aio_init() failed" << endl;
      return;
    }
}

INA132::~INA132()
{
  mraa_aio_close(m_aio);
}

float INA132::value()
{
	int val, i;
	float v, vo;
	float sum=0;
	for(i=0;i<10;i++)
	{
		val = mraa_aio_read(m_aio);
		v = val*5.00/1023;
		sum += v;
		usleep(10000);
	}
	vo = sum/10;
	return vo;
}
<commit_msg>ina132: throw exception(s) on fatal errors<commit_after>/*
 * Author: Zion Orent <zorent@ics.com>
 * Copyright (c) 2015 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <iostream>
#include <string>
#include <stdexcept>
#include <unistd.h>

#include "ina132.h"

using namespace upm;
using namespace std;

INA132::INA132(int pin)
{
    if ( !(m_aio = mraa_aio_init(pin)) )
    {
      throw std::invalid_argument(std::string(__FUNCTION__) +
                                  ": mraa_aio_init() failed, invalid pin?");
      return;
    }
}

INA132::~INA132()
{
  mraa_aio_close(m_aio);
}

float INA132::value()
{
	int val, i;
	float v, vo;
	float sum=0;
	for(i=0;i<10;i++)
	{
		val = mraa_aio_read(m_aio);
		v = val*5.00/1023;
		sum += v;
		usleep(10000);
	}
	vo = sum/10;
	return vo;
}
<|endoftext|>