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

#include <list>
#include <memory>
#include <map>
#include <vector>

#include "extension/xwalk/XW_Extension.h"
#include "extension/xwalk/XW_Extension_EntryPoints.h"
#include "extension/xwalk/XW_Extension_Permissions.h"
#include "extension/xwalk/XW_Extension_Runtime.h"
#include "extension/xwalk/XW_Extension_SyncMessage.h"

#include "extension/widget/picojson.h"
#include "common/logger.h"
#include "common/app_db.h"
#include "common/application_data.h"
#include "common/locale_manager.h"
#include "common/string_utils.h"

XW_Extension g_xw_extension = 0;
std::string g_appid;
std::unique_ptr<wrt::ApplicationData> g_appdata;
const XW_CoreInterface* g_core = NULL;
const XW_MessagingInterface* g_messaging = NULL;
const XW_Internal_SyncMessagingInterface* g_sync_messaging = NULL;
const XW_Internal_EntryPointsInterface* g_entry_points = NULL;
const XW_Internal_RuntimeInterface* g_runtime = NULL;
extern const char kSource_widget_api[];

typedef void (*CmdHandler)(const picojson::value& args, picojson::object* out);

static void InitHandler(const picojson::value& args, picojson::object* out);
static void KeyHandler(const picojson::value& args, picojson::object* out);
static void GetItemHandler(const picojson::value& args,
                           picojson::object* out);
static void LengthHandler(const picojson::value& args,
                           picojson::object* out);
static void ClearHandler(const picojson::value& args,
                           picojson::object* out);
static void SetItemHandler(const picojson::value& args,
                           picojson::object* out);
static void RemoveHandler(const picojson::value& args,
                           picojson::object* out);

std::map<std::string, CmdHandler> g_handler = {
  {"init", InitHandler},
  {"key", KeyHandler},
  {"length", LengthHandler},
  {"clear", ClearHandler},
  {"getItem", GetItemHandler},
  {"setItem", SetItemHandler},
  {"removeItem", RemoveHandler},
};

static void HandleMessage(XW_Instance instance,
                          const char* message,
                          bool sync);

extern "C" int32_t XW_Initialize(XW_Extension extension,
                                 XW_GetInterface get_interface) {
  g_xw_extension = extension;
  g_core = reinterpret_cast<const XW_CoreInterface*>(
      get_interface(XW_CORE_INTERFACE));
  if (!g_core) {
    LOGGER(ERROR)
        << "Can't initialize extension: error getting Core interface.";
    return XW_ERROR;
  }

  g_messaging = reinterpret_cast<const XW_MessagingInterface*>(
      get_interface(XW_MESSAGING_INTERFACE));
  if (!g_messaging) {
    LOGGER(ERROR)
        << "Can't initialize extension: error getting Messaging interface.";
    return XW_ERROR;
  }

  g_sync_messaging =
      reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
          get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
  if (!g_sync_messaging) {
    LOGGER(ERROR)
        << "Can't initialize extension: "
        << "error getting SyncMessaging interface.";
    return XW_ERROR;
  }

  g_entry_points = reinterpret_cast<const XW_Internal_EntryPointsInterface*>(
      get_interface(XW_INTERNAL_ENTRY_POINTS_INTERFACE));
  if (!g_entry_points) {
    LOGGER(ERROR)
        << "NOTE: Entry points interface not available in this version "
        << "of Crosswalk, ignoring entry point data for extensions.\n";
    return XW_ERROR;
  }

  g_runtime = reinterpret_cast<const XW_Internal_RuntimeInterface*>(
      get_interface(XW_INTERNAL_RUNTIME_INTERFACE));
  if (!g_runtime) {
    LOGGER(ERROR)
        << "NOTE: runtime interface not available in this version "
        << "of Crosswalk, ignoring runtime variables for extensions.\n";
    return XW_ERROR;
  }

  std::vector<char> res(256, 0);
  g_runtime->GetRuntimeVariableString(extension, "app_id", &res[0], 256);
  g_appid = std::string(res.begin(), res.end());
  if (g_appid.at(0) == '"') {
    g_appid = g_appid.substr(1, g_appid.size()-2);
  }

  g_core->RegisterInstanceCallbacks(
      g_xw_extension,
      [](XW_Instance /*instance*/){
        if (g_appdata.get() == NULL) {
          g_appdata.reset(new wrt::ApplicationData(g_appid));
        }
        wrt::Widget::GetInstance()->Initialize(g_appdata.get());
      },
      NULL);

  g_messaging->Register(g_xw_extension, [](XW_Instance instance,
                                           const char* message) {
    HandleMessage(instance, message, false);
  });
  g_sync_messaging->Register(g_xw_extension, [](XW_Instance instance,
                                                const char* message) {
    HandleMessage(instance, message, true);
  });

  g_core->SetExtensionName(g_xw_extension, "Widget");
  const char* entry_points[] = {"widget", NULL};
  g_entry_points->SetExtraJSEntryPoints(g_xw_extension, entry_points);
  g_core->SetJavaScriptAPI(g_xw_extension, kSource_widget_api);

  return XW_OK;
}

static void InitHandler(const picojson::value& /*args*/,
                        picojson::object* out) {
  picojson::value result = picojson::value(picojson::object());
  picojson::object& obj = result.get<picojson::object>();

  auto widget_info = g_appdata->widget_info();
  if (widget_info.get() == NULL) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));

  wrt::LocaleManager locale_manager;
  if (!widget_info->default_locale().empty()) {
    locale_manager.SetDefaultLocale(widget_info->default_locale());
  }

  // TODO(sngn.lee): should be returned localized string
  obj["author"] = picojson::value(widget_info->author());
  obj["description"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->description_set()));
  obj["name"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->name_set()));
  obj["shortName"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->short_name_set()));
  obj["version"] = picojson::value(widget_info->version());
  obj["id"] = picojson::value(widget_info->id());
  obj["authorEmail"] = picojson::value(widget_info->author_email());
  obj["authorHref"] = picojson::value(widget_info->author_href());
  obj["height"] = picojson::value(static_cast<double>(widget_info->height()));
  obj["width"] = picojson::value(static_cast<double>(widget_info->width()));

  out->insert(std::make_pair("result", result));
}

static void KeyHandler(const picojson::value& args, picojson::object* out) {
  int idx = static_cast<int>(args.get("idx").get<double>());
  std::string key;
  if (!wrt::Widget::GetInstance()->Key(idx, &key)) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(std::make_pair("result", picojson::value(key)));
}

static void GetItemHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  std::string value;
  if (!wrt::Widget::GetInstance()->GetItem(key, &value)) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(std::make_pair("result", picojson::value(value)));
}

static void LengthHandler(const picojson::value& /*args*/,
                           picojson::object* out) {
  int length = wrt::Widget::GetInstance()->Length();
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(
      std::make_pair("result", picojson::value(static_cast<double>(length))));
}

static void ClearHandler(const picojson::value& /*args*/,
                           picojson::object* out) {
  wrt::Widget::GetInstance()->Clear();
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void SetItemHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  const std::string& value = args.get("value").get<std::string>();
  std::string oldvalue;
  if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
    out->insert(std::make_pair("result", picojson::value(oldvalue)));
  } else {
    out->insert(std::make_pair("result", picojson::value()));
  }
  wrt::Widget::GetInstance()->SetItem(key, value);
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void RemoveHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  std::string oldvalue;
  if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
    out->insert(std::make_pair("result", picojson::value(oldvalue)));
  } else {
    out->insert(std::make_pair("result", picojson::value()));
  }
  wrt::Widget::GetInstance()->RemoveItem(key);
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void HandleMessage(XW_Instance instance,
                          const char* message,
                          bool sync) {
  picojson::value value;
  std::string err;
  picojson::parse(value, message, message + strlen(message), &err);
  if (!err.empty()) {
    LOGGER(ERROR) << "Ignoring message. " << err;
    return;
  }

  if (!value.is<picojson::object>()) {
    LOGGER(ERROR) << "Ignoring message. It is not an object.";
    return;
  }

  std::string cmd = value.get("cmd").to_str();
  // check for args in JSON message
  const picojson::value& args = value.get("args");
  picojson::value result = picojson::value(picojson::object());

  auto handler = g_handler.find(cmd);
  if (handler != g_handler.end()) {
    handler->second(args, &result.get<picojson::object>());
  } else {
    result.get<picojson::object>().insert(
        std::make_pair("status", picojson::value("error")));
  }

  if (sync) {
    g_sync_messaging->SetSyncReply(instance, result.serialize().c_str());
  }
}

namespace wrt {

namespace {
  const char* kDbInitedCheckKey = "__WRT_DB_INITED__";
  const char* kDBPublicSection = "public";
  const char* kDBPrivateSection = "private";
}  // namespace

Widget* Widget::GetInstance() {
  static Widget instance;
  return &instance;
}

Widget::Widget() {
}
Widget::~Widget() {
}

void Widget::Initialize(const ApplicationData* appdata) {
  AppDB* db = AppDB::GetInstance();
  if (db->HasKey(kDBPrivateSection, kDbInitedCheckKey))
    return;
  if (appdata->widget_info() == NULL)
    return;

  auto preferences = appdata->widget_info()->preferences();
  auto it = preferences.begin();
  for ( ; it != preferences.end(); ++it) {
    db->Set(kDBPublicSection,
            (*it)->Name(),
            (*it)->Value());
  }
  db->Set(kDBPrivateSection, kDbInitedCheckKey, "true");
}

int Widget::Length() {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);
  return list.size();
}

bool Widget::Key(int idx, std::string* key) {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);

  auto it = list.begin();
  for ( ; it != list.end() && idx >= 0; ++it) {
    if (idx == 0) {
      *key = *it;
      return true;
    }
    idx--;
  }
  return false;
}

bool Widget::GetItem(const std::string& key, std::string* value) {
  AppDB* db = AppDB::GetInstance();
  if (!db->HasKey(kDBPublicSection, key))
    return false;
  *value = db->Get(kDBPublicSection, key);
  return true;
}

bool Widget::SetItem(const std::string& key, const std::string& value) {
  AppDB* db = AppDB::GetInstance();
  db->Set(kDBPublicSection, key, value);
  return true;
}

bool Widget::RemoveItem(const std::string& key) {
  AppDB* db = AppDB::GetInstance();
  if (!db->HasKey(kDBPublicSection, key))
    return false;
  db->Remove(kDBPublicSection, key);
  return true;
}

void Widget::Clear() {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);
  auto it = list.begin();
  for ( ; it != list.end(); ++it) {
    db->Remove(kDBPublicSection, *it);
  }
}

}  // namespace wrt
<commit_msg>Widget API : Bug fix  - App id quote related bug  - Missing LoadManifestData bug<commit_after>/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#include "extension/widget/widget.h"

#include <list>
#include <memory>
#include <map>
#include <vector>

#include "extension/xwalk/XW_Extension.h"
#include "extension/xwalk/XW_Extension_EntryPoints.h"
#include "extension/xwalk/XW_Extension_Permissions.h"
#include "extension/xwalk/XW_Extension_Runtime.h"
#include "extension/xwalk/XW_Extension_SyncMessage.h"

#include "extension/widget/picojson.h"
#include "common/logger.h"
#include "common/app_db.h"
#include "common/application_data.h"
#include "common/locale_manager.h"
#include "common/string_utils.h"

XW_Extension g_xw_extension = 0;
std::string g_appid;
std::unique_ptr<wrt::ApplicationData> g_appdata;
const XW_CoreInterface* g_core = NULL;
const XW_MessagingInterface* g_messaging = NULL;
const XW_Internal_SyncMessagingInterface* g_sync_messaging = NULL;
const XW_Internal_EntryPointsInterface* g_entry_points = NULL;
const XW_Internal_RuntimeInterface* g_runtime = NULL;
extern const char kSource_widget_api[];

typedef void (*CmdHandler)(const picojson::value& args, picojson::object* out);

static void InitHandler(const picojson::value& args, picojson::object* out);
static void KeyHandler(const picojson::value& args, picojson::object* out);
static void GetItemHandler(const picojson::value& args,
                           picojson::object* out);
static void LengthHandler(const picojson::value& args,
                           picojson::object* out);
static void ClearHandler(const picojson::value& args,
                           picojson::object* out);
static void SetItemHandler(const picojson::value& args,
                           picojson::object* out);
static void RemoveHandler(const picojson::value& args,
                           picojson::object* out);

std::map<std::string, CmdHandler> g_handler = {
  {"init", InitHandler},
  {"key", KeyHandler},
  {"length", LengthHandler},
  {"clear", ClearHandler},
  {"getItem", GetItemHandler},
  {"setItem", SetItemHandler},
  {"removeItem", RemoveHandler},
};

static void HandleMessage(XW_Instance instance,
                          const char* message,
                          bool sync);

extern "C" int32_t XW_Initialize(XW_Extension extension,
                                 XW_GetInterface get_interface) {
  g_xw_extension = extension;
  g_core = reinterpret_cast<const XW_CoreInterface*>(
      get_interface(XW_CORE_INTERFACE));
  if (!g_core) {
    LOGGER(ERROR)
        << "Can't initialize extension: error getting Core interface.";
    return XW_ERROR;
  }

  g_messaging = reinterpret_cast<const XW_MessagingInterface*>(
      get_interface(XW_MESSAGING_INTERFACE));
  if (!g_messaging) {
    LOGGER(ERROR)
        << "Can't initialize extension: error getting Messaging interface.";
    return XW_ERROR;
  }

  g_sync_messaging =
      reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
          get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
  if (!g_sync_messaging) {
    LOGGER(ERROR)
        << "Can't initialize extension: "
        << "error getting SyncMessaging interface.";
    return XW_ERROR;
  }

  g_entry_points = reinterpret_cast<const XW_Internal_EntryPointsInterface*>(
      get_interface(XW_INTERNAL_ENTRY_POINTS_INTERFACE));
  if (!g_entry_points) {
    LOGGER(ERROR)
        << "NOTE: Entry points interface not available in this version "
        << "of Crosswalk, ignoring entry point data for extensions.\n";
    return XW_ERROR;
  }

  g_runtime = reinterpret_cast<const XW_Internal_RuntimeInterface*>(
      get_interface(XW_INTERNAL_RUNTIME_INTERFACE));
  if (!g_runtime) {
    LOGGER(ERROR)
        << "NOTE: runtime interface not available in this version "
        << "of Crosswalk, ignoring runtime variables for extensions.\n";
    return XW_ERROR;
  }

  std::vector<char> res(256, 0);
  g_runtime->GetRuntimeVariableString(extension, "app_id", &res[0], 256);
  g_appid = std::string(res.begin(), res.end());
  if (g_appid.at(0) == '"') {
    g_appid = g_appid.substr(1, strlen(g_appid.c_str())-2);
  }

  g_core->RegisterInstanceCallbacks(
      g_xw_extension,
      [](XW_Instance /*instance*/){
        if (g_appdata.get() == NULL) {
          g_appdata.reset(new wrt::ApplicationData(g_appid));
          g_appdata->LoadManifestData();
        }
        wrt::Widget::GetInstance()->Initialize(g_appdata.get());
      },
      NULL);

  g_messaging->Register(g_xw_extension, [](XW_Instance instance,
                                           const char* message) {
    HandleMessage(instance, message, false);
  });
  g_sync_messaging->Register(g_xw_extension, [](XW_Instance instance,
                                                const char* message) {
    HandleMessage(instance, message, true);
  });

  g_core->SetExtensionName(g_xw_extension, "Widget");
  const char* entry_points[] = {"widget", NULL};
  g_entry_points->SetExtraJSEntryPoints(g_xw_extension, entry_points);
  g_core->SetJavaScriptAPI(g_xw_extension, kSource_widget_api);

  return XW_OK;
}

static void InitHandler(const picojson::value& /*args*/,
                        picojson::object* out) {
  picojson::value result = picojson::value(picojson::object());
  picojson::object& obj = result.get<picojson::object>();

  auto widget_info = g_appdata->widget_info();
  if (widget_info.get() == NULL) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));

  wrt::LocaleManager locale_manager;
  if (!widget_info->default_locale().empty()) {
    locale_manager.SetDefaultLocale(widget_info->default_locale());
  }

  // TODO(sngn.lee): should be returned localized string
  obj["author"] = picojson::value(widget_info->author());
  obj["description"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->description_set()));
  obj["name"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->name_set()));
  obj["shortName"] = picojson::value(
      locale_manager.GetLocalizedString(widget_info->short_name_set()));
  obj["version"] = picojson::value(widget_info->version());
  obj["id"] = picojson::value(widget_info->id());
  obj["authorEmail"] = picojson::value(widget_info->author_email());
  obj["authorHref"] = picojson::value(widget_info->author_href());
  obj["height"] = picojson::value(static_cast<double>(widget_info->height()));
  obj["width"] = picojson::value(static_cast<double>(widget_info->width()));

  out->insert(std::make_pair("result", result));
}

static void KeyHandler(const picojson::value& args, picojson::object* out) {
  int idx = static_cast<int>(args.get("idx").get<double>());
  std::string key;
  if (!wrt::Widget::GetInstance()->Key(idx, &key)) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(std::make_pair("result", picojson::value(key)));
}

static void GetItemHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  std::string value;
  if (!wrt::Widget::GetInstance()->GetItem(key, &value)) {
    out->insert(std::make_pair("status", picojson::value("error")));
    return;
  }
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(std::make_pair("result", picojson::value(value)));
}

static void LengthHandler(const picojson::value& /*args*/,
                           picojson::object* out) {
  int length = wrt::Widget::GetInstance()->Length();
  out->insert(std::make_pair("status", picojson::value("success")));
  out->insert(
      std::make_pair("result", picojson::value(static_cast<double>(length))));
}

static void ClearHandler(const picojson::value& /*args*/,
                           picojson::object* out) {
  wrt::Widget::GetInstance()->Clear();
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void SetItemHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  const std::string& value = args.get("value").get<std::string>();
  std::string oldvalue;
  if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
    out->insert(std::make_pair("result", picojson::value(oldvalue)));
  } else {
    out->insert(std::make_pair("result", picojson::value()));
  }
  wrt::Widget::GetInstance()->SetItem(key, value);
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void RemoveHandler(const picojson::value& args,
                           picojson::object* out) {
  const std::string& key = args.get("key").get<std::string>();
  std::string oldvalue;
  if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
    out->insert(std::make_pair("result", picojson::value(oldvalue)));
  } else {
    out->insert(std::make_pair("result", picojson::value()));
  }
  wrt::Widget::GetInstance()->RemoveItem(key);
  out->insert(std::make_pair("status", picojson::value("success")));
}

static void HandleMessage(XW_Instance instance,
                          const char* message,
                          bool sync) {
  picojson::value value;
  std::string err;
  picojson::parse(value, message, message + strlen(message), &err);
  if (!err.empty()) {
    LOGGER(ERROR) << "Ignoring message. " << err;
    return;
  }

  if (!value.is<picojson::object>()) {
    LOGGER(ERROR) << "Ignoring message. It is not an object.";
    return;
  }

  std::string cmd = value.get("cmd").to_str();
  // check for args in JSON message
  const picojson::value& args = value.get("args");
  picojson::value result = picojson::value(picojson::object());

  auto handler = g_handler.find(cmd);
  if (handler != g_handler.end()) {
    handler->second(args, &result.get<picojson::object>());
  } else {
    result.get<picojson::object>().insert(
        std::make_pair("status", picojson::value("error")));
  }

  if (sync) {
    g_sync_messaging->SetSyncReply(instance, result.serialize().c_str());
  }
}

namespace wrt {

namespace {
  const char* kDbInitedCheckKey = "__WRT_DB_INITED__";
  const char* kDBPublicSection = "public";
  const char* kDBPrivateSection = "private";
}  // namespace

Widget* Widget::GetInstance() {
  static Widget instance;
  return &instance;
}

Widget::Widget() {
}
Widget::~Widget() {
}

void Widget::Initialize(const ApplicationData* appdata) {
  AppDB* db = AppDB::GetInstance();
  if (db->HasKey(kDBPrivateSection, kDbInitedCheckKey))
    return;
  if (appdata->widget_info() == NULL)
    return;

  auto preferences = appdata->widget_info()->preferences();
  auto it = preferences.begin();
  for ( ; it != preferences.end(); ++it) {
    db->Set(kDBPublicSection,
            (*it)->Name(),
            (*it)->Value());
  }
  db->Set(kDBPrivateSection, kDbInitedCheckKey, "true");
}

int Widget::Length() {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);
  return list.size();
}

bool Widget::Key(int idx, std::string* key) {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);

  auto it = list.begin();
  for ( ; it != list.end() && idx >= 0; ++it) {
    if (idx == 0) {
      *key = *it;
      return true;
    }
    idx--;
  }
  return false;
}

bool Widget::GetItem(const std::string& key, std::string* value) {
  AppDB* db = AppDB::GetInstance();
  if (!db->HasKey(kDBPublicSection, key))
    return false;
  *value = db->Get(kDBPublicSection, key);
  return true;
}

bool Widget::SetItem(const std::string& key, const std::string& value) {
  AppDB* db = AppDB::GetInstance();
  db->Set(kDBPublicSection, key, value);
  return true;
}

bool Widget::RemoveItem(const std::string& key) {
  AppDB* db = AppDB::GetInstance();
  if (!db->HasKey(kDBPublicSection, key))
    return false;
  db->Remove(kDBPublicSection, key);
  return true;
}

void Widget::Clear() {
  AppDB* db = AppDB::GetInstance();
  std::list<std::string> list;
  db->GetKeys(kDBPublicSection, &list);
  auto it = list.begin();
  for ( ; it != list.end(); ++it) {
    db->Remove(kDBPublicSection, *it);
  }
}

}  // namespace wrt
<|endoftext|>


<commit_before>#ifndef STAN_MATH_OPENCL_KERNEL_GENERATOR_OPENCL_CODE_HPP
#define STAN_MATH_OPENCL_KERNEL_GENERATOR_OPENCL_CODE_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta.hpp>
#include <stan/math/opencl/matrix_cl_view.hpp>
#include <stan/math/opencl/kernel_generator/type_str.hpp>
#include <stan/math/opencl/kernel_generator/name_generator.hpp>
#include <stan/math/opencl/kernel_generator/operation_cl.hpp>
#include <stan/math/opencl/kernel_generator/as_operation_cl.hpp>
#include <stan/math/opencl/kernel_generator/common_return_scalar.hpp>
#include <stan/math/prim/functor/for_each.hpp>
#include <algorithm>
#include <set>
#include <string>
#include <type_traits>
#include <utility>

namespace stan {
namespace math {

/** \addtogroup opencl_kernel_generator
 *  @{
 */
/**
 * Represents output variable of custom code in kernel generator expressions.
 * @tparam T_code intantiation of `opencl_code_` class template this is output
 * of
 * @tparam T_scalar scalar type of the output variable
 */
template <typename T_code, typename T_scalar>
class opencl_code_output
    : public operation_cl<opencl_code_output<T_code, T_scalar>, T_scalar,
                          T_code> {
 public:
  using Scalar = T_scalar;
  using base
      = operation_cl<opencl_code_output<T_code, T_scalar>, T_scalar, T_code>;
  using base::var_name_;
  const char* custom_var_name_;

  /**
   * Constructor
   * @param code code object
   * @param custom_var_name variable name from the custom code
   */
  opencl_code_output(T_code code, const char* custom_var_name)
      : base(std::move(code)), custom_var_name_(custom_var_name) {}

  /**
   * Creates a deep copy of this expression.
   * @return copy of \c *this
   */
  inline auto deep_copy() const {
    auto&& code_copy = this->template get_arg<0>().deep_copy();
    return opencl_code_output<std::remove_reference_t<decltype(code_copy)>,
                              T_scalar>(std::move(code_copy), custom_var_name_);
  }

  /**
   * Generates kernel code for this operation.
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether whether caller already handled matrix view
   * @param var_name_condition variable name of the condition expression
   * @param var_name_else variable name of the then expression
   * @param var_name_then variable name of the else expression
   * @return part of kernel with code for this expression
   */
  inline kernel_parts generate(const std::string& row_index_name,
                               const std::string& col_index_name,
                               const bool view_handled,
                               const std::string& dummy_var_name_code) const {
    kernel_parts res{};
    res.body = type_str<Scalar>() + " " + var_name_ + " = " + custom_var_name_
               + ";\n";
    return res;
  }

  /**
   * Determine indices of extreme sub- and superdiagonals written.
   * @return pair of indices - bottom and top diagonal
   */
  inline std::pair<int, int> extreme_diagonals() const {
    return {-this->rows() + 1, this->cols() - 1};
  }
};

namespace internal {
template <const char* Code, typename... T_arguments>
class opencl_code_impl
    : public operation_cl<opencl_code_impl<Code, T_arguments...>, double,
                          T_arguments...> {
 public:
  //  using Scalar = double;
  using base = operation_cl<opencl_code_impl<Code, T_arguments...>, double,
                            T_arguments...>;
  using names_tuple
      = std::tuple<typename std::pair<const char*, T_arguments>::first_type...>;
  using base::var_name_;
  names_tuple names_;

  /**
   * Constructor
   * @param condition condition expression
   * @param then then expression
   * @param els else expression
   */
  opencl_code_impl(names_tuple names, T_arguments&&... arguments)
      : base(std::forward<T_arguments>(arguments)...), names_(names) {}

  /**
   * Generates kernel code for this (select) operation.
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether whether caller already handled matrix
   * view
   * @param var_name_condition variable name of the condition
   * expression
   * @param var_name_else variable name of the then expression
   * @param var_name_then variable name of the else expression
   * @return part of kernel with code for this expression
   */
  inline kernel_parts generate(
      const std::string& row_index_name, const std::string& col_index_name,
      const bool view_handled,
      std::tuple_element_t<
          0, std::pair<const std::string&, T_arguments>>... var_names) const {
    return index_apply<sizeof...(T_arguments)>([this](auto... Is) {
      kernel_parts res{};
      std::array<std::string, sizeof...(T_arguments)> input_renames{
          (type_str<scalar_type_t<decltype(this->template get_arg<Is>())>>()
           + " " + std::get<Is>(names_) + " = "
           + this->template get_arg<Is>().var_name_ + ";\n")...};
      res.body = std::accumulate(input_renames.begin(), input_renames.end(),
                                 std::string())
                 + Code;
      return res;
    });
  }
};
}  // namespace internal

/**
 * Represents custom code in kernel generator expressions.
 * @tparam Code custom code
 * @tparam T_arguments types of argument expressions
 */
template <const char* Code, typename... T_arguments>
class opencl_code_ : public operation_cl_base {
 public:
  std::shared_ptr<internal::opencl_code_impl<Code, T_arguments...>> impl_;
  std::string& var_name_;
  using names_tuple
      = std::tuple<typename std::pair<const char*, T_arguments>::first_type...>;
  using Deriv = internal::opencl_code_impl<Code, T_arguments...>;

  /**
   * Constructor
   * @param names tuple of names of the input variables (that hold values of
   * argument expressions)
   * @param arguments arguments to this operation
   */
  opencl_code_(const names_tuple& names, T_arguments&&... arguments)
      : impl_(
            std::make_shared<internal::opencl_code_impl<Code, T_arguments...>>(
                names, std::forward<T_arguments>(arguments)...)),
        var_name_(impl_->var_name_) {}

  /**
   * Copy constructor.
   * @param other object to copy
   */
  opencl_code_(const opencl_code_<Code, T_arguments...>& other)
      : impl_(other.impl_), var_name_(impl_->var_name_) {}

  /**
   * Generates kernel code for this and nested expressions.
   * @param[in,out] generated map from (pointer to) already generated local
   * operations to variable names
   * @param[in,out] generated_all map from (pointer to) already generated all
   * operations to variable names
   * @param name_gen name generator for this kernel
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether caller already handled matrix view
   * @return part of kernel with code for this and nested expressions
   */
  auto get_kernel_parts(std::map<const void*, const char*>& generated,
                        std::map<const void*, const char*>& generated_all,
                        name_generator& name_gen,
                        const std::string& row_index_name,
                        const std::string& col_index_name,
                        bool view_handled) const {
    return impl_->get_kernel_parts(generated, generated_all, name_gen,
                                   row_index_name, col_index_name,
                                   view_handled);
  }

  /**
   * Sets kernel arguments for nested expressions.
   * @param[in,out] generated map from (pointer to) already generated local
   * operations to variable names
   * @param[in,out] generated_all map from (pointer to) already generated all
   * operations to variable names
   * @param kernel kernel to set arguments on
   * @param[in,out] arg_num consecutive number of the first argument to set.
   * This is incremented for each argument set by this function.
   */
  auto set_args(std::map<const void*, const char*>& generated,
                std::map<const void*, const char*>& generated_all,
                cl::Kernel& kernel, int& arg_num) const {
    return impl_->set_args(generated, generated_all, kernel, arg_num);
  }

  /**
   * Adds read event to any matrices used by nested expressions.
   * @param e the event to add
   */
  auto add_read_event(cl::Event& e) const { return impl_->add_read_event(e); }

  /**
   * Adds all write events on any matrices used by nested expressions to a list.
   * @param[out] events List of all events.
   */
  auto get_write_events(std::vector<cl::Event>& events) const {
    return impl_->get_write_events(events);
  }

  /**
   * Number of rows of a matrix that would be the result of evaluating this
   * expression. Some subclasses may need to override this.
   * @return number of rows
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto rows() const {
    return impl_->rows();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto rows() const {
    return -1;
  }

  /**
   * Number of columns of a matrix that would be the result of evaluating this
   * expression. Some subclasses may need to override this.
   * @return number of columns
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto cols() const {
    return impl_->cols();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto cols() const {
    return -1;
  }

  /**
   * Number of rows threads need to be launched for. For most expressions this
   * equals number of rows of the result.
   * @return number of rows
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto thread_rows() const {
    return impl_->thread_rows();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto thread_rows() const {
    return -1;
  }

  /**
   * Number of columns threads need to be launched for. For most expressions
   * this equals number of cols of the result.
   * @return number of columns
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto thread_cols() const {
    return impl_->thread_cols();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto thread_cols() const {
    return -1;
  }

  /**
   * Determine indices of extreme sub- and superdiagonals written.
   * @return pair of indices - bottom and top diagonal
   */
  auto extreme_diagonals() const { return impl_->extreme_diagonals(); }

  /**
   * Collects data that is needed beside types to uniqly identify a kernel
   * generator expression.
   * @param[out] uids ids of unique matrix accesses
   * @param[in,out] id_map map from memory addresses to unique ids
   * @param[in,out] next_id neqt unique id to use
   */
  auto get_unique_matrix_accesses(std::vector<int>& uids,
                                  std::map<const void*, int>& id_map,
                                  int& next_id) const {
    return impl_->get_unique_matrix_accesses(uids, id_map, next_id);
  }

  /**
   * Creates a deep copy of this expression.
   * @return copy of \c *this
   */
  inline auto deep_copy() const {
    return index_apply<sizeof...(T_arguments)>([this](auto... Is) {
      auto args_copy
          = std::make_tuple(this->impl_->template get_arg<Is>().deep_copy()...);
      return opencl_code_<
          Code, std::remove_reference_t<decltype(std::get<Is>(args_copy))>...>(
          this->impl_->names_, std::move(std::get<Is>(args_copy))...);
    });
  }

  /**
   * Get object representing output variable of ccustom code.
   * @param var_name name of the variable output object represents
   */
  template <typename T_scalar>
  inline auto output(const char* var_name) const {
    return opencl_code_output<opencl_code_<Code, T_arguments...>, T_scalar>(
        *this, var_name);
  }
};

/**
 * Custom code in kernel generator expressions.
 * @tparam Code custom code
 * @tparam T_arguments types of argument expressions
 * @param names tuple of names of the input variables (that hold values of
 * argument expressions)
 * @param arguments arguments to this operation
 */
template <const char* Code, typename... T_arguments,
          require_all_kernel_expressions_t<T_arguments...>* = nullptr>
inline opencl_code_<Code, as_operation_cl_t<T_arguments>...> opencl_code(
    std::tuple<typename std::pair<const char*, T_arguments>::first_type...>
        names,
    T_arguments&&... arguments) {
  return {names, as_operation_cl(std::forward<T_arguments>(arguments))...};
}

/** @}*/
}  // namespace math
}  // namespace stan
#endif
#endif
<commit_msg>fixed explicit constructors<commit_after>#ifndef STAN_MATH_OPENCL_KERNEL_GENERATOR_OPENCL_CODE_HPP
#define STAN_MATH_OPENCL_KERNEL_GENERATOR_OPENCL_CODE_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta.hpp>
#include <stan/math/opencl/matrix_cl_view.hpp>
#include <stan/math/opencl/kernel_generator/type_str.hpp>
#include <stan/math/opencl/kernel_generator/name_generator.hpp>
#include <stan/math/opencl/kernel_generator/operation_cl.hpp>
#include <stan/math/opencl/kernel_generator/as_operation_cl.hpp>
#include <stan/math/opencl/kernel_generator/common_return_scalar.hpp>
#include <stan/math/prim/functor/for_each.hpp>
#include <algorithm>
#include <set>
#include <string>
#include <type_traits>
#include <utility>

namespace stan {
namespace math {

/** \addtogroup opencl_kernel_generator
 *  @{
 */
/**
 * Represents output variable of custom code in kernel generator expressions.
 * @tparam T_code intantiation of `opencl_code_` class template this is output
 * of
 * @tparam T_scalar scalar type of the output variable
 */
template <typename T_code, typename T_scalar>
class opencl_code_output
    : public operation_cl<opencl_code_output<T_code, T_scalar>, T_scalar,
                          T_code> {
 public:
  using Scalar = T_scalar;
  using base
      = operation_cl<opencl_code_output<T_code, T_scalar>, T_scalar, T_code>;
  using base::var_name_;
  const char* custom_var_name_;

  /**
   * Constructor
   * @param code code object
   * @param custom_var_name variable name from the custom code
   */
  opencl_code_output(T_code code, const char* custom_var_name)
      : base(std::move(code)), custom_var_name_(custom_var_name) {}

  /**
   * Creates a deep copy of this expression.
   * @return copy of \c *this
   */
  inline auto deep_copy() const {
    auto&& code_copy = this->template get_arg<0>().deep_copy();
    return opencl_code_output<std::remove_reference_t<decltype(code_copy)>,
                              T_scalar>(std::move(code_copy), custom_var_name_);
  }

  /**
   * Generates kernel code for this operation.
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether whether caller already handled matrix view
   * @param var_name_condition variable name of the condition expression
   * @param var_name_else variable name of the then expression
   * @param var_name_then variable name of the else expression
   * @return part of kernel with code for this expression
   */
  inline kernel_parts generate(const std::string& row_index_name,
                               const std::string& col_index_name,
                               const bool view_handled,
                               const std::string& dummy_var_name_code) const {
    kernel_parts res{};
    res.body = type_str<Scalar>() + " " + var_name_ + " = " + custom_var_name_
               + ";\n";
    return res;
  }

  /**
   * Determine indices of extreme sub- and superdiagonals written.
   * @return pair of indices - bottom and top diagonal
   */
  inline std::pair<int, int> extreme_diagonals() const {
    return {-this->rows() + 1, this->cols() - 1};
  }
};

namespace internal {
template <const char* Code, typename... T_arguments>
class opencl_code_impl
    : public operation_cl<opencl_code_impl<Code, T_arguments...>, double,
                          T_arguments...> {
 public:
  //  using Scalar = double;
  using base = operation_cl<opencl_code_impl<Code, T_arguments...>, double,
                            T_arguments...>;
  using names_tuple
      = std::tuple<typename std::pair<const char*, T_arguments>::first_type...>;
  using base::var_name_;
  names_tuple names_;

  /**
   * Constructor
   * @param condition condition expression
   * @param then then expression
   * @param els else expression
   */
  explicit opencl_code_impl(names_tuple names, T_arguments&&... arguments)
      : base(std::forward<T_arguments>(arguments)...), names_(names) {}

  /**
   * Generates kernel code for this (select) operation.
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether whether caller already handled matrix
   * view
   * @param var_name_condition variable name of the condition
   * expression
   * @param var_name_else variable name of the then expression
   * @param var_name_then variable name of the else expression
   * @return part of kernel with code for this expression
   */
  inline kernel_parts generate(
      const std::string& row_index_name, const std::string& col_index_name,
      const bool view_handled,
      std::tuple_element_t<
          0, std::pair<const std::string&, T_arguments>>... var_names) const {
    return index_apply<sizeof...(T_arguments)>([this](auto... Is) {
      kernel_parts res{};
      std::array<std::string, sizeof...(T_arguments)> input_renames{
          (type_str<scalar_type_t<decltype(this->template get_arg<Is>())>>()
           + " " + std::get<Is>(names_) + " = "
           + this->template get_arg<Is>().var_name_ + ";\n")...};
      res.body = std::accumulate(input_renames.begin(), input_renames.end(),
                                 std::string())
                 + Code;
      return res;
    });
  }
};
}  // namespace internal

/**
 * Represents custom code in kernel generator expressions.
 * @tparam Code custom code
 * @tparam T_arguments types of argument expressions
 */
template <const char* Code, typename... T_arguments>
class opencl_code_ : public operation_cl_base {
 public:
  std::shared_ptr<internal::opencl_code_impl<Code, T_arguments...>> impl_;
  std::string& var_name_;
  using names_tuple
      = std::tuple<typename std::pair<const char*, T_arguments>::first_type...>;
  using Deriv = internal::opencl_code_impl<Code, T_arguments...>;

  /**
   * Constructor
   * @param names tuple of names of the input variables (that hold values of
   * argument expressions)
   * @param arguments arguments to this operation
   */
  explicit opencl_code_(const names_tuple& names, T_arguments&&... arguments)
      : impl_(
          std::make_shared<internal::opencl_code_impl<Code, T_arguments...>>(
              names, std::forward<T_arguments>(arguments)...)),
        var_name_(impl_->var_name_) {}

  /**
   * Copy constructor.
   * @param other object to copy
   */
  opencl_code_(const opencl_code_<Code, T_arguments...>& other)
      : impl_(other.impl_), var_name_(impl_->var_name_) {}

  /**
   * Generates kernel code for this and nested expressions.
   * @param[in,out] generated map from (pointer to) already generated local
   * operations to variable names
   * @param[in,out] generated_all map from (pointer to) already generated all
   * operations to variable names
   * @param name_gen name generator for this kernel
   * @param row_index_name row index variable name
   * @param col_index_name column index variable name
   * @param view_handled whether caller already handled matrix view
   * @return part of kernel with code for this and nested expressions
   */
  auto get_kernel_parts(std::map<const void*, const char*>& generated,
                        std::map<const void*, const char*>& generated_all,
                        name_generator& name_gen,
                        const std::string& row_index_name,
                        const std::string& col_index_name,
                        bool view_handled) const {
    return impl_->get_kernel_parts(generated, generated_all, name_gen,
                                   row_index_name, col_index_name,
                                   view_handled);
  }

  /**
   * Sets kernel arguments for nested expressions.
   * @param[in,out] generated map from (pointer to) already generated local
   * operations to variable names
   * @param[in,out] generated_all map from (pointer to) already generated all
   * operations to variable names
   * @param kernel kernel to set arguments on
   * @param[in,out] arg_num consecutive number of the first argument to set.
   * This is incremented for each argument set by this function.
   */
  auto set_args(std::map<const void*, const char*>& generated,
                std::map<const void*, const char*>& generated_all,
                cl::Kernel& kernel, int& arg_num) const {
    return impl_->set_args(generated, generated_all, kernel, arg_num);
  }

  /**
   * Adds read event to any matrices used by nested expressions.
   * @param e the event to add
   */
  auto add_read_event(cl::Event& e) const { return impl_->add_read_event(e); }

  /**
   * Adds all write events on any matrices used by nested expressions to a list.
   * @param[out] events List of all events.
   */
  auto get_write_events(std::vector<cl::Event>& events) const {
    return impl_->get_write_events(events);
  }

  /**
   * Number of rows of a matrix that would be the result of evaluating this
   * expression. Some subclasses may need to override this.
   * @return number of rows
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto rows() const {
    return impl_->rows();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto rows() const {
    return -1;
  }

  /**
   * Number of columns of a matrix that would be the result of evaluating this
   * expression. Some subclasses may need to override this.
   * @return number of columns
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto cols() const {
    return impl_->cols();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto cols() const {
    return -1;
  }

  /**
   * Number of rows threads need to be launched for. For most expressions this
   * equals number of rows of the result.
   * @return number of rows
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto thread_rows() const {
    return impl_->thread_rows();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto thread_rows() const {
    return -1;
  }

  /**
   * Number of columns threads need to be launched for. For most expressions
   * this equals number of cols of the result.
   * @return number of columns
   */
  template <std::enable_if_t<(sizeof...(T_arguments) > 0)>* = nullptr>
  auto thread_cols() const {
    return impl_->thread_cols();
  }
  template <std::enable_if_t<(sizeof...(T_arguments) == 0)>* = nullptr>
  auto thread_cols() const {
    return -1;
  }

  /**
   * Determine indices of extreme sub- and superdiagonals written.
   * @return pair of indices - bottom and top diagonal
   */
  auto extreme_diagonals() const { return impl_->extreme_diagonals(); }

  /**
   * Collects data that is needed beside types to uniqly identify a kernel
   * generator expression.
   * @param[out] uids ids of unique matrix accesses
   * @param[in,out] id_map map from memory addresses to unique ids
   * @param[in,out] next_id neqt unique id to use
   */
  auto get_unique_matrix_accesses(std::vector<int>& uids,
                                  std::map<const void*, int>& id_map,
                                  int& next_id) const {
    return impl_->get_unique_matrix_accesses(uids, id_map, next_id);
  }

  /**
   * Creates a deep copy of this expression.
   * @return copy of \c *this
   */
  inline auto deep_copy() const {
    return index_apply<sizeof...(T_arguments)>([this](auto... Is) {
      auto args_copy
          = std::make_tuple(this->impl_->template get_arg<Is>().deep_copy()...);
      return opencl_code_<
          Code, std::remove_reference_t<decltype(std::get<Is>(args_copy))>...>(
          this->impl_->names_, std::move(std::get<Is>(args_copy))...);
    });
  }

  /**
   * Get object representing output variable of ccustom code.
   * @param var_name name of the variable output object represents
   */
  template <typename T_scalar>
  inline auto output(const char* var_name) const {
    return opencl_code_output<opencl_code_<Code, T_arguments...>, T_scalar>(
        *this, var_name);
  }
};

/**
 * Custom code in kernel generator expressions.
 * @tparam Code custom code
 * @tparam T_arguments types of argument expressions
 * @param names tuple of names of the input variables (that hold values of
 * argument expressions)
 * @param arguments arguments to this operation
 */
template <const char* Code, typename... T_arguments,
          require_all_kernel_expressions_t<T_arguments...>* = nullptr>
inline auto opencl_code(
    std::tuple<typename std::pair<const char*, T_arguments>::first_type...>
        names,
    T_arguments&&... arguments) {
  return opencl_code_<Code, as_operation_cl_t<T_arguments>...>(
      names, as_operation_cl(std::forward<T_arguments>(arguments))...);
}

/** @}*/
}  // namespace math
}  // namespace stan
#endif
#endif
<|endoftext|>


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

#include <glog/logging.h>
#include "paddle/fluid/inference/api/paddle_inference_api.h"

namespace paddle {

int PaddleDtypeSize(PaddleDType dtype) {
  switch (dtype) {
    case PaddleDType::FLOAT32:
      return sizeof(float);
    case PaddleDType::INT64:
      return sizeof(int64_t);
    default:
      assert(false);
      return -1;
  }
}

PaddleBuf::PaddleBuf(PaddleBuf&& other)
    : data_(other.data_),
      length_(other.length_),
      memory_owned_(other.memory_owned_) {
  other.memory_owned_ = false;
  other.data_ = nullptr;
  other.length_ = 0;
}

PaddleBuf::PaddleBuf(const PaddleBuf& other) { *this = other; }

PaddleBuf& PaddleBuf::operator=(const PaddleBuf& other) {
  if (!other.memory_owned_) {
    data_ = other.data_;
    length_ = other.length_;
    memory_owned_ = other.memory_owned_;
  } else {
    Resize(other.length());
    memcpy(data_, other.data(), other.length());
    length_ = other.length();
    memory_owned_ = true;
  }
  return *this;
}

PaddleBuf& PaddleBuf::operator=(PaddleBuf&& other) {
  // only the buffer with external memory can be copied
  data_ = other.data_;
  length_ = other.length_;
  memory_owned_ = other.memory_owned_;
  other.data_ = nullptr;
  other.length_ = 0;
  other.memory_owned_ = false;
  return *this;
}

void PaddleBuf::Resize(size_t length) {
  // Only the owned memory can be reset, the external memory can't be changed.
  if (length_ == length) return;
  if (memory_owned_) {
    Free();
  }
  data_ = new char[length];
  length_ = length;
  memory_owned_ = true;
}

void PaddleBuf::Reset(void* data, size_t length) {
  Free();
  memory_owned_ = false;
  data_ = data;
  length_ = length;
}

void PaddleBuf::Free() {
  if (memory_owned_ && data_) {
    assert(length_ > 0);
    delete[] static_cast<char*>(data_);
    data_ = nullptr;
    length_ = 0;
  }
}

}  // namespace paddle
<commit_msg>Hotfix/api predictor (#13383)<commit_after>/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "paddle/fluid/inference/api/paddle_inference_api.h"
#include "paddle/fluid/platform/enforce.h"

namespace paddle {

int PaddleDtypeSize(PaddleDType dtype) {
  switch (dtype) {
    case PaddleDType::FLOAT32:
      return sizeof(float);
    case PaddleDType::INT64:
      return sizeof(int64_t);
    default:
      assert(false);
      return -1;
  }
}

PaddleBuf::PaddleBuf(PaddleBuf&& other)
    : data_(other.data_),
      length_(other.length_),
      memory_owned_(other.memory_owned_) {
  other.memory_owned_ = false;
  other.data_ = nullptr;
  other.length_ = 0;
}

PaddleBuf::PaddleBuf(const PaddleBuf& other) { *this = other; }

PaddleBuf& PaddleBuf::operator=(const PaddleBuf& other) {
  if (!other.memory_owned_) {
    data_ = other.data_;
    length_ = other.length_;
    memory_owned_ = other.memory_owned_;
  } else {
    Resize(other.length());
    memcpy(data_, other.data(), other.length());
    length_ = other.length();
    memory_owned_ = true;
  }
  return *this;
}

PaddleBuf& PaddleBuf::operator=(PaddleBuf&& other) {
  // only the buffer with external memory can be copied
  data_ = other.data_;
  length_ = other.length_;
  memory_owned_ = other.memory_owned_;
  other.data_ = nullptr;
  other.length_ = 0;
  other.memory_owned_ = false;
  return *this;
}

void PaddleBuf::Resize(size_t length) {
  // Only the owned memory can be reset, the external memory can't be changed.
  if (length_ >= length) return;
  if (memory_owned_) {
    Free();
    data_ = malloc(length);
    length_ = length;
    memory_owned_ = true;
  } else {
    PADDLE_THROW("The memory is allocated externally, can not Resized");
  }
}

void PaddleBuf::Reset(void* data, size_t length) {
  Free();
  memory_owned_ = false;
  data_ = data;
  length_ = length;
}

void PaddleBuf::Free() {
  if (memory_owned_ && data_) {
    PADDLE_ENFORCE_GT(length_, 0);
    free(static_cast<char*>(data_));
    data_ = nullptr;
    length_ = 0;
  }
}

}  // namespace paddle
<|endoftext|>


<commit_before>#include "FileDialog.h"

#ifdef SYSTEM_WINDOWS
  #include <windows.h>
  #include <shlobj.h>
#endif
#ifdef SYSTEM_LINUX
  #include <gtk/gtk.h>
  #include <cstring>
  #include <malloc.h>
#endif

#include <iostream>
#include <cassert>

namespace FileDialog
{
#ifdef SYSTEM_WINDOWS
    // Function that opens a dialoge window to choose a file
    bool openFilen( std::string const & filterList,
                    std::string const & defaultPath,
                    std::string & outPath )
    {
        OPENFILENAMEA ofn;
        char fileName[MAX_PATH] = "";
        ZeroMemory(&ofn, sizeof(ofn));

        ofn.lStructSize = sizeof(OPENFILENAME);
        ofn.hwndOwner = NULL;
        ofn.lpstrInitialDir = defaultPath.c_str();
        ofn.lpstrFilter = filter.c_str();
        ofn.lpstrFile = fileName;
        ofn.nMaxFile = MAX_PATH;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
		ofn.lpstrDefExt = "";

		if(!GetOpenFileNameA(&ofn))
			return false;

		outPath = fileName;

        return true;
    }

	static int CALLBACK browseFolderCallback( HWND hwnd,
											  UINT uMsg,
											  LPARAM lParam,
											  LPARAM lpData )
	{
		if (uMsg == BFFM_INITIALIZED)
		{
			LPCTSTR path = reinterpret_cast<LPCTSTR>(lpData);
			::SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM)path);
		}
		return 0;
	}

    // Function to browse the folder with the DICOM Series
    bool openFolder( std::string const & defaultPath,
                     std::string& outPath )
    {
        BROWSEINFO   bi = { 0 };
        LPITEMIDLIST pidl;
        TCHAR        szDisplay[MAX_PATH];

        LPVOID pvReserved = NULL;
        CoInitialize(pvReserved);

        bi.hwndOwner = NULL;
        bi.pszDisplayName = szDisplay;
        bi.lpszTitle = TEXT("Please choose a folder.");
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
		bi.lpfn = browseFolderCallback;
		if (defaultPath.empty())
		{
			bi.lParam = NULL;
		}
		else
		{
			bi.lParam = (LPARAM)(defaultPath.c_str());
		}

        pidl = SHBrowseForFolder(&bi);

		std::string result;
		LPTSTR szPath = new TCHAR[MAX_PATH];
		if (!SHGetPathFromIDList(pidl, szPath))
			return false;

		result = std::string(szPath);
		delete[] szPath;

		CoUninitialize();

        return true;
    }
#endif

#ifdef SYSTEM_LINUX
    static void WaitForCleanup(void)
    {
        while (gtk_events_pending())
            gtk_main_iteration();
    }

    static void AddTypeToFilterName( const char *typebuf, char *filterName, size_t bufsize )
    {
        const char SEP[] = ", ";

        size_t len = strlen(filterName);
        if ( len != 0 )
        {
            strncat( filterName, SEP, bufsize - len - 1 );
            len += strlen(SEP);
        }

        strncat( filterName, typebuf, bufsize - len - 1 );
    }

    static bool NFDi_IsFilterSegmentChar( char ch )
    {
        return (ch==','||ch==';'||ch=='\0');
    }

    static void AddFiltersToDialog( GtkWidget *dialog, const char *filterList )
    {
        GtkFileFilter *filter;
        char typebuf[4096] = {0};
        const char *p_filterList = filterList;
        char *p_typebuf = typebuf;
        char filterName[4096] = {0};

        if ( !filterList || strlen(filterList) == 0 )
            return;

        filter = gtk_file_filter_new();
        while ( 1 )
        {

            if ( NFDi_IsFilterSegmentChar(*p_filterList) )
            {
                char typebufWildcard[4096];
                /* add another type to the filter */
                assert( strlen(typebuf) > 0 );
                assert( strlen(typebuf) < 4096-1 );

                snprintf( typebufWildcard, 4096, "*.%s", typebuf );
                AddTypeToFilterName( typebuf, filterName, 4096 );

                gtk_file_filter_add_pattern( filter, typebufWildcard );

                p_typebuf = typebuf;
                memset( typebuf, 0, sizeof(char) * 4096 );
            }

            if ( *p_filterList == ';' || *p_filterList == '\0' )
            {
                /* end of filter -- add it to the dialog */

                gtk_file_filter_set_name( filter, filterName );
                gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );

                filterName[0] = '\0';

                if ( *p_filterList == '\0' )
                    break;

                filter = gtk_file_filter_new();
            }

            if ( !NFDi_IsFilterSegmentChar( *p_filterList ) )
            {
                *p_typebuf = *p_filterList;
                p_typebuf++;
            }

            p_filterList++;
        }

        /* always append a wildcard option to the end*/

        filter = gtk_file_filter_new();
        gtk_file_filter_set_name( filter, "*.*" );
        gtk_file_filter_add_pattern( filter, "*" );
        gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
    }

    static void SetDefaultPath( GtkWidget *dialog, const char *defaultPath )
    {
        if ( !defaultPath || strlen(defaultPath) == 0 )
            return;

        /* GTK+ manual recommends not specifically setting the default path.
           We do it anyway in order to be consistent across platforms.
           If consistency with the native OS is preferred, this is the line
           to comment out. -ml */
        gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), defaultPath );
    }

    bool openFilen( std::string const & filterList,
                    std::string const & defaultPath,
                    std::string & outPath )
    {
        GtkWidget *dialog;
        bool result;

        if ( !gtk_init_check( NULL, NULL ) )
        {
            return false;
        }

        dialog = gtk_file_chooser_dialog_new( "Open File",
                                              NULL,
                                              GTK_FILE_CHOOSER_ACTION_OPEN,
                                              "_Cancel", GTK_RESPONSE_CANCEL,
                                              "_Open", GTK_RESPONSE_ACCEPT,
                                              NULL );

        /* Build the filter list */
        AddFiltersToDialog(dialog, filterList.c_str() );

        /* Set the default path */
        SetDefaultPath(dialog, defaultPath.c_str() );

        result = false;
        if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
        {
            char *filename;

            filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

            {
                outPath = std::string( filename );
                if ( outPath.empty() )
                {
                    g_free( filename );
                    gtk_widget_destroy(dialog);
                    return false;
                }
            }
            g_free( filename );

            result = true;
        }

        WaitForCleanup();
        gtk_widget_destroy(dialog);
        WaitForCleanup();

        return result;
    }

    bool openFolder( std::string const & defaultPath,
                     std::string& outPath )
    {
        GtkWidget *dialog;
        bool result;

        if (!gtk_init_check(NULL, NULL))
        {
            return false;
        }

        dialog = gtk_file_chooser_dialog_new( "Select folder",
                                              NULL,
                                              GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                              "_Cancel", GTK_RESPONSE_CANCEL,
                                              "_Select", GTK_RESPONSE_ACCEPT,
                                              NULL );
        gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );

        /* Set the default path */
        SetDefaultPath( dialog, defaultPath.c_str() );

        result = false;
        if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
        {
            char *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

            {
                outPath = std::string( filename );
                if ( outPath.empty() )
                {
                    g_free( filename );
                    gtk_widget_destroy(dialog);
                    return false;
                }
            }
            g_free(filename);

            result = true;
        }

        WaitForCleanup();
        gtk_widget_destroy(dialog);
        WaitForCleanup();

        return result;
    }
#endif
} // namespace FileDialog
<commit_msg>#1 fixed minor bug in openFolder function<commit_after>#include "FileDialog.h"

#ifdef SYSTEM_WINDOWS
  #include <windows.h>
  #include <shlobj.h>
#endif
#ifdef SYSTEM_LINUX
  #include <gtk/gtk.h>
  #include <cstring>
  #include <malloc.h>
#endif

#include <iostream>
#include <cassert>

namespace FileDialog
{
#ifdef SYSTEM_WINDOWS
    // Function that opens a dialoge window to choose a file
    bool openFile( std::string const & filterList,
                   std::string const & defaultPath,
                   std::string & outPath )
    {
        OPENFILENAMEA ofn;
        char fileName[MAX_PATH] = "";
        ZeroMemory(&ofn, sizeof(ofn));

        ofn.lStructSize = sizeof(OPENFILENAME);
        ofn.hwndOwner = NULL;
        ofn.lpstrInitialDir = defaultPath.c_str();
        ofn.lpstrFilter = filterList.c_str();
        ofn.lpstrFile = fileName;
        ofn.nMaxFile = MAX_PATH;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
		ofn.lpstrDefExt = "";

		if(!GetOpenFileNameA(&ofn))
			return false;

		outPath = fileName;

        return true;
    }

	static int CALLBACK browseFolderCallback( HWND hwnd,
											  UINT uMsg,
											  LPARAM lParam,
											  LPARAM lpData )
	{
		if (uMsg == BFFM_INITIALIZED)
		{
			LPCTSTR path = reinterpret_cast<LPCTSTR>(lpData);
			::SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM)path);
		}
		return 0;
	}

    // Function to browse the folder with the DICOM Series
    bool openFolder( std::string const & defaultPath,
                     std::string& outPath )
    {
        BROWSEINFO   bi = { 0 };
        LPITEMIDLIST pidl;
        TCHAR        szDisplay[MAX_PATH];

        LPVOID pvReserved = NULL;
        CoInitialize(pvReserved);

        bi.hwndOwner = NULL;
        bi.pszDisplayName = szDisplay;
        bi.lpszTitle = TEXT("Please choose a folder.");
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
		bi.lpfn = browseFolderCallback;
		if (defaultPath.empty())
		{
			bi.lParam = NULL;
		}
		else
		{
			bi.lParam = (LPARAM)(defaultPath.c_str());
		}

        pidl = SHBrowseForFolder(&bi);

		LPTSTR szPath = new TCHAR[MAX_PATH];
		if (!SHGetPathFromIDList(pidl, szPath))
			return false;

		outPath = std::string(szPath);
		delete[] szPath;

		CoUninitialize();

        return true;
    }
#endif

#ifdef SYSTEM_LINUX
    static void WaitForCleanup(void)
    {
        while (gtk_events_pending())
            gtk_main_iteration();
    }

    static void AddTypeToFilterName( const char *typebuf, char *filterName, size_t bufsize )
    {
        const char SEP[] = ", ";

        size_t len = strlen(filterName);
        if ( len != 0 )
        {
            strncat( filterName, SEP, bufsize - len - 1 );
            len += strlen(SEP);
        }

        strncat( filterName, typebuf, bufsize - len - 1 );
    }

    static bool NFDi_IsFilterSegmentChar( char ch )
    {
        return (ch==','||ch==';'||ch=='\0');
    }

    static void AddFiltersToDialog( GtkWidget *dialog, const char *filterList )
    {
        GtkFileFilter *filter;
        char typebuf[4096] = {0};
        const char *p_filterList = filterList;
        char *p_typebuf = typebuf;
        char filterName[4096] = {0};

        if ( !filterList || strlen(filterList) == 0 )
            return;

        filter = gtk_file_filter_new();
        while ( 1 )
        {

            if ( NFDi_IsFilterSegmentChar(*p_filterList) )
            {
                char typebufWildcard[4096];
                /* add another type to the filter */
                assert( strlen(typebuf) > 0 );
                assert( strlen(typebuf) < 4096-1 );

                snprintf( typebufWildcard, 4096, "*.%s", typebuf );
                AddTypeToFilterName( typebuf, filterName, 4096 );

                gtk_file_filter_add_pattern( filter, typebufWildcard );

                p_typebuf = typebuf;
                memset( typebuf, 0, sizeof(char) * 4096 );
            }

            if ( *p_filterList == ';' || *p_filterList == '\0' )
            {
                /* end of filter -- add it to the dialog */

                gtk_file_filter_set_name( filter, filterName );
                gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );

                filterName[0] = '\0';

                if ( *p_filterList == '\0' )
                    break;

                filter = gtk_file_filter_new();
            }

            if ( !NFDi_IsFilterSegmentChar( *p_filterList ) )
            {
                *p_typebuf = *p_filterList;
                p_typebuf++;
            }

            p_filterList++;
        }

        /* always append a wildcard option to the end*/

        filter = gtk_file_filter_new();
        gtk_file_filter_set_name( filter, "*.*" );
        gtk_file_filter_add_pattern( filter, "*" );
        gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
    }

    static void SetDefaultPath( GtkWidget *dialog, const char *defaultPath )
    {
        if ( !defaultPath || strlen(defaultPath) == 0 )
            return;

        /* GTK+ manual recommends not specifically setting the default path.
           We do it anyway in order to be consistent across platforms.
           If consistency with the native OS is preferred, this is the line
           to comment out. -ml */
        gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), defaultPath );
    }

    bool openFilen( std::string const & filterList,
                    std::string const & defaultPath,
                    std::string & outPath )
    {
        GtkWidget *dialog;
        bool result;

        if ( !gtk_init_check( NULL, NULL ) )
        {
            return false;
        }

        dialog = gtk_file_chooser_dialog_new( "Open File",
                                              NULL,
                                              GTK_FILE_CHOOSER_ACTION_OPEN,
                                              "_Cancel", GTK_RESPONSE_CANCEL,
                                              "_Open", GTK_RESPONSE_ACCEPT,
                                              NULL );

        /* Build the filter list */
        AddFiltersToDialog(dialog, filterList.c_str() );

        /* Set the default path */
        SetDefaultPath(dialog, defaultPath.c_str() );

        result = false;
        if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
        {
            char *filename;

            filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

            {
                outPath = std::string( filename );
                if ( outPath.empty() )
                {
                    g_free( filename );
                    gtk_widget_destroy(dialog);
                    return false;
                }
            }
            g_free( filename );

            result = true;
        }

        WaitForCleanup();
        gtk_widget_destroy(dialog);
        WaitForCleanup();

        return result;
    }

    bool openFolder( std::string const & defaultPath,
                     std::string& outPath )
    {
        GtkWidget *dialog;
        bool result;

        if (!gtk_init_check(NULL, NULL))
        {
            return false;
        }

        dialog = gtk_file_chooser_dialog_new( "Select folder",
                                              NULL,
                                              GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                              "_Cancel", GTK_RESPONSE_CANCEL,
                                              "_Select", GTK_RESPONSE_ACCEPT,
                                              NULL );
        gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );

        /* Set the default path */
        SetDefaultPath( dialog, defaultPath.c_str() );

        result = false;
        if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
        {
            char *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

            {
                outPath = std::string( filename );
                if ( outPath.empty() )
                {
                    g_free( filename );
                    gtk_widget_destroy(dialog);
                    return false;
                }
            }
            g_free(filename);

            result = true;
        }

        WaitForCleanup();
        gtk_widget_destroy(dialog);
        WaitForCleanup();

        return result;
    }
#endif
} // namespace FileDialog
<|endoftext|>