<commit_before>//
// Created by Sam on 2/11/2018.
//

#include <iostream>
#include <fstream>
#include <sstream>
#include <utility>
#include "../../../include/Game/Utilities/Database.h"
#include "../../../include/Game/Python/Factory.h"

void Database::setupUser(const std::string &steamID)
{
    createUser(steamID);
    giveCards(steamID);
    createFirstTimeDeck(steamID);
}

std::vector<std::string> Database::getDeckCards(const std::string& steamID, const std::string& deckID)
{
    std::vector<std::string> rows;

    std::string query = formatGetDeckCardsQuery(steamID, deckID);
    result = PQexec(connection, query.c_str());

    for (int i = 0; i < PQntuples(result); i++)
    {
        rows.emplace_back(PQgetvalue(result, i, 0));
    }

    return rows;
}

std::string Database::formatGetDeckCardsQuery(const std::string& steamID, const std::string& deckID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
                R"("Card"."PythonName" )" <<
              "FROM " <<
                R"(public."Card", )" <<
                R"(public."CardToUser", )" <<
                R"(public."CardUserToDeck", )" <<
                R"(public."Deck", )" <<
                R"(public."DeckToUser", )" <<
                R"(public."User" )" <<
              "WHERE " <<
                R"("Card"."ID" = "CardToUser"."CardID" AND )" <<
                R"("CardUserToDeck"."CardUserID" = "CardToUser"."ID" AND )" <<
                R"("CardUserToDeck"."DeckID" = "Deck"."ID" AND )" <<
                R"("Deck"."ID" = "DeckToUser"."DeckID" AND )" <<
                R"("DeckToUser"."UserID" = "User"."ID" AND )" <<
                R"("User"."ID" = "CardToUser"."UserID" AND )" <<
                R"("User"."SteamID" = ')" << steamID << R"(' AND "Deck"."ID" = )" << deckID << ";";

    return sqlStream.str();
}

std::map<std::string, Deck> Database::getAllDeckCards(const std::string &steamID, Factory* factory)
{
    std::map<std::string, Deck> deckMap;

    std::string query = formatGetAllDecksAndCardsQuery(steamID);
    result = PQexec(connection, query.c_str());

    for (int i = 0; i < PQntuples(result); i++)
    {
        std::string name = PQgetvalue(result, i, 0);
        std::string ID = PQgetvalue(result, i, 1);
        std::string pythonName = PQgetvalue(result, i, 2);

        if (deckMap[name].name.empty())
        {
            deckMap[name].name = name;
        }

        if (deckMap[name].id.empty())
        {
            deckMap[name].id = ID;
        }

        deckMap[name].cards.push_back(factory->createCard(pythonName));
    }

    return deckMap;
}

std::string Database::formatGetAllDecksAndCardsQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
              R"("Deck"."Name", )" <<
              R"("Deck"."ID", )" <<
              R"("Card"."PythonName" )" <<
              "FROM " <<
              R"(public."Card", )" <<
              R"(public."CardToUser", )" <<
              R"(public."CardUserToDeck", )" <<
              R"(public."Deck", )" <<
              R"(public."DeckToUser", )" <<
              R"(public."User" )" <<
              "WHERE " <<
              R"("Card"."ID" = "CardToUser"."CardID" AND )" <<
              R"("CardUserToDeck"."CardUserID" = "CardToUser"."ID" AND )" <<
              R"("CardUserToDeck"."DeckID" = "Deck"."ID" AND )" <<
              R"("Deck"."ID" = "DeckToUser"."DeckID" AND )" <<
              R"("DeckToUser"."UserID" = "User"."ID" AND )" <<
              R"("User"."ID" = "CardToUser"."UserID" AND )" <<
              R"("User"."SteamID" = ')" << steamID << "';";

    return sqlStream.str();
}

bool Database::isNewSteamID(const std::string& steamID)
{
    std::string query = formatIsNewSteamIDQuery(steamID);

    std::cout << "Executing isNewSteamID..." << std::endl;
    std::cout << query << std::endl;

    result = PQexec(connection, query.c_str());

    std::string strCount;
    int count;
    for (int i = 0; i < PQntuples(result); i++)
    {
        strCount = PQgetvalue(result, i, 0);
    }

    count = stoi(strCount);

    return count == 0;
}

std::string Database::formatIsNewSteamIDQuery(const std::string& steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
              R"(COUNT("SteamID"))" <<
              "FROM " <<
              R"(public."User" )" <<
              "WHERE " <<
              R"("SteamID" = ')" << steamID << "';";

    return sqlStream.str();
}

void Database::createUser(const std::string &steamID)
{
    std::string query = formatCreateUserQuery(steamID);

    std::cout << "Executing createUser..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateUserQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
        "INSERT INTO " <<
            R"("User" ("SteamID"))" <<
        "VALUES('" << steamID << "')";

    return sqlStream.str();
}

void Database::giveCards(const std::string &steamID)
{
    std::string query = formatGiveCardsQuery(steamID);

    std::cout << "Executing giveCards..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatGiveCardsQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
        "DO $$ DECLARE i bigint; " <<
        "BEGIN " <<
            R"(FOR i IN 1..11 LOOP )" <<
                R"(INSERT INTO "CardToUser"("CardID", "UserID") SELECT "Card"."ID", "User"."ID" )" <<
                R"(FROM "Card", "User" WHERE "User"."SteamID" = ')" << steamID << "'; " <<
            "END LOOP; " <<
        "END$$;";

    return sqlStream.str();
}

void Database::createDeckFor(const std::string &steamID)
{
    int deckID = createDeckAndGetID();
    std::string query = formatCreateDeckForQuery(steamID, deckID);

    std::cout << "Executing createDeckFor..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateDeckForQuery(const std::string &steamID, int deckID)
{
    std::ostringstream getUserIDSQL;
    getUserIDSQL <<
        R"(SELECT "ID" )" <<
        R"(FROM public."User" )" <<
        R"(WHERE "SteamID" = ')" << steamID << "'";

    std::ostringstream linkDeckToUserSQL;
    linkDeckToUserSQL <<
        R"(INSERT INTO "DeckToUser" ("UserID", "DeckID") )" <<
        "VALUES(" << "(" << getUserIDSQL.str() << ")" << ", (" << deckID << "))" ;

    return linkDeckToUserSQL.str();
}

void Database::createFirstTimeDeck(const std::string &steamID)
{
    createDeckFor(steamID);
    std::string query = formatCreateFirstTimeDeck(steamID);

    std::cout << "Executing createFirstTimeDeck..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateFirstTimeDeck(const std::string &steamID)
{
    std::ostringstream getFirstUserDeckIDSQL;
    getFirstUserDeckIDSQL <<
        R"(SELECT "Deck"."ID" )" <<
        R"(FROM "Deck", "User", "DeckToUser" )" <<
        R"(WHERE "Deck"."ID" = "DeckToUser"."DeckID" AND "User"."ID" = "DeckToUser"."UserID" )" <<
        R"(AND "User"."SteamID" = ')" << steamID << "' LIMIT 1";

    std::ostringstream getCardUserIDSQLStream;
    getCardUserIDSQLStream <<
        R"(SELECT "CardToUser"."ID", ()" << getFirstUserDeckIDSQL.str() << ") " <<
        R"(FROM "User", "Card", "CardToUser" )" <<
        R"(WHERE "User"."ID" = "CardToUser"."UserID" AND "Card"."ID" = "CardToUser"."CardID" )" <<
        R"(AND User"."SteamID" = ')" << steamID << "' LIMIT 40)";

    std::ostringstream createSQLStream;
    createSQLStream << R"(INSERT INTO "CardUserToDeck"("CardUserID", "DeckID") )" << getCardUserIDSQLStream.str();

    return createSQLStream.str();
}

int Database::createDeckAndGetID()
{
    std::string query = formatCreateDeckAndGetIDQuery();

    std::cout << "Executing createDeckAndGetID..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());

    std::string strDeckID;
    int deckID;
    for (int i = 0; i < PQntuples(result); i++)
    {
        strDeckID = PQgetvalue(result, i, 0);
    }

    deckID = stoi(strDeckID);

    return deckID;
}

std::string Database::formatCreateDeckAndGetIDQuery()
{
    std::ostringstream createDeckSQL;
    createDeckSQL <<
                  R"(INSERT INTO "Deck" ("Name"))" <<
                  "VALUES('" << "Starter Deck" << R"(') RETURNING "Deck"."ID")";

    return createDeckSQL.str();
}

Database::Database()
        : result(nullptr)
{
    initializeConfig();
    CONNECTION_INFO = config["CONNECTION_INFO"];
    initializeConnection();
}

Database::~Database()
{
    PQfinish(connection);
}

void Database::initializeConnection()
{
    connection = PQconnectdb(CONNECTION_INFO.c_str());
    if (PQstatus(connection) != CONNECTION_OK)
    {
        std::cout << "Connection to database failed: " << PQerrorMessage(connection) << std::endl;
    }
    else
    {
        std::cout << "Connected to " << CONNECTION_INFO << std::endl;
    }
}

void Database::initializeConfig()
{
    // Path is relative to the exe in the build folder. This should probably be updated at some point?
    std::ifstream dbfile("../dbconfig.json", std::ifstream::in);
    std::stringstream buffer;
    buffer << dbfile.rdbuf();
    std::string rawJSON = buffer.str();
    config = json::parse(rawJSON);
}
<commit_msg>Changed number of given cards back to 20<commit_after>//
// Created by Sam on 2/11/2018.
//

#include <iostream>
#include <fstream>
#include <sstream>
#include <utility>
#include "../../../include/Game/Utilities/Database.h"
#include "../../../include/Game/Python/Factory.h"

void Database::setupUser(const std::string &steamID)
{
    createUser(steamID);
    giveCards(steamID);
    createFirstTimeDeck(steamID);
}

std::vector<std::string> Database::getDeckCards(const std::string& steamID, const std::string& deckID)
{
    std::vector<std::string> rows;

    std::string query = formatGetDeckCardsQuery(steamID, deckID);
    result = PQexec(connection, query.c_str());

    for (int i = 0; i < PQntuples(result); i++)
    {
        rows.emplace_back(PQgetvalue(result, i, 0));
    }

    return rows;
}

std::string Database::formatGetDeckCardsQuery(const std::string& steamID, const std::string& deckID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
                R"("Card"."PythonName" )" <<
              "FROM " <<
                R"(public."Card", )" <<
                R"(public."CardToUser", )" <<
                R"(public."CardUserToDeck", )" <<
                R"(public."Deck", )" <<
                R"(public."DeckToUser", )" <<
                R"(public."User" )" <<
              "WHERE " <<
                R"("Card"."ID" = "CardToUser"."CardID" AND )" <<
                R"("CardUserToDeck"."CardUserID" = "CardToUser"."ID" AND )" <<
                R"("CardUserToDeck"."DeckID" = "Deck"."ID" AND )" <<
                R"("Deck"."ID" = "DeckToUser"."DeckID" AND )" <<
                R"("DeckToUser"."UserID" = "User"."ID" AND )" <<
                R"("User"."ID" = "CardToUser"."UserID" AND )" <<
                R"("User"."SteamID" = ')" << steamID << R"(' AND "Deck"."ID" = )" << deckID << ";";

    return sqlStream.str();
}

std::map<std::string, Deck> Database::getAllDeckCards(const std::string &steamID, Factory* factory)
{
    std::map<std::string, Deck> deckMap;

    std::string query = formatGetAllDecksAndCardsQuery(steamID);
    result = PQexec(connection, query.c_str());

    for (int i = 0; i < PQntuples(result); i++)
    {
        std::string name = PQgetvalue(result, i, 0);
        std::string ID = PQgetvalue(result, i, 1);
        std::string pythonName = PQgetvalue(result, i, 2);

        if (deckMap[name].name.empty())
        {
            deckMap[name].name = name;
        }

        if (deckMap[name].id.empty())
        {
            deckMap[name].id = ID;
        }

        deckMap[name].cards.push_back(factory->createCard(pythonName));
    }

    return deckMap;
}

std::string Database::formatGetAllDecksAndCardsQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
              R"("Deck"."Name", )" <<
              R"("Deck"."ID", )" <<
              R"("Card"."PythonName" )" <<
              "FROM " <<
              R"(public."Card", )" <<
              R"(public."CardToUser", )" <<
              R"(public."CardUserToDeck", )" <<
              R"(public."Deck", )" <<
              R"(public."DeckToUser", )" <<
              R"(public."User" )" <<
              "WHERE " <<
              R"("Card"."ID" = "CardToUser"."CardID" AND )" <<
              R"("CardUserToDeck"."CardUserID" = "CardToUser"."ID" AND )" <<
              R"("CardUserToDeck"."DeckID" = "Deck"."ID" AND )" <<
              R"("Deck"."ID" = "DeckToUser"."DeckID" AND )" <<
              R"("DeckToUser"."UserID" = "User"."ID" AND )" <<
              R"("User"."ID" = "CardToUser"."UserID" AND )" <<
              R"("User"."SteamID" = ')" << steamID << "';";

    return sqlStream.str();
}

bool Database::isNewSteamID(const std::string& steamID)
{
    std::string query = formatIsNewSteamIDQuery(steamID);

    std::cout << "Executing isNewSteamID..." << std::endl;
    std::cout << query << std::endl;

    result = PQexec(connection, query.c_str());

    std::string strCount;
    int count;
    for (int i = 0; i < PQntuples(result); i++)
    {
        strCount = PQgetvalue(result, i, 0);
    }

    count = stoi(strCount);

    return count == 0;
}

std::string Database::formatIsNewSteamIDQuery(const std::string& steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
              "SELECT " <<
              R"(COUNT("SteamID"))" <<
              "FROM " <<
              R"(public."User" )" <<
              "WHERE " <<
              R"("SteamID" = ')" << steamID << "';";

    return sqlStream.str();
}

void Database::createUser(const std::string &steamID)
{
    std::string query = formatCreateUserQuery(steamID);

    std::cout << "Executing createUser..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateUserQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
        "INSERT INTO " <<
            R"("User" ("SteamID"))" <<
        "VALUES('" << steamID << "')";

    return sqlStream.str();
}

void Database::giveCards(const std::string &steamID)
{
    std::string query = formatGiveCardsQuery(steamID);

    std::cout << "Executing giveCards..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatGiveCardsQuery(const std::string &steamID)
{
    std::ostringstream sqlStream;
    sqlStream <<
        "DO $$ DECLARE i bigint; " <<
        "BEGIN " <<
            R"(FOR i IN 1..20 LOOP )" <<
                R"(INSERT INTO "CardToUser"("CardID", "UserID") SELECT "Card"."ID", "User"."ID" )" <<
                R"(FROM "Card", "User" WHERE "User"."SteamID" = ')" << steamID << "'; " <<
            "END LOOP; " <<
        "END$$;";

    return sqlStream.str();
}

void Database::createDeckFor(const std::string &steamID)
{
    int deckID = createDeckAndGetID();
    std::string query = formatCreateDeckForQuery(steamID, deckID);

    std::cout << "Executing createDeckFor..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateDeckForQuery(const std::string &steamID, int deckID)
{
    std::ostringstream getUserIDSQL;
    getUserIDSQL <<
        R"(SELECT "ID" )" <<
        R"(FROM public."User" )" <<
        R"(WHERE "SteamID" = ')" << steamID << "'";

    std::ostringstream linkDeckToUserSQL;
    linkDeckToUserSQL <<
        R"(INSERT INTO "DeckToUser" ("UserID", "DeckID") )" <<
        "VALUES(" << "(" << getUserIDSQL.str() << ")" << ", (" << deckID << "))" ;

    return linkDeckToUserSQL.str();
}

void Database::createFirstTimeDeck(const std::string &steamID)
{
    createDeckFor(steamID);
    std::string query = formatCreateFirstTimeDeck(steamID);

    std::cout << "Executing createFirstTimeDeck..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());
}

std::string Database::formatCreateFirstTimeDeck(const std::string &steamID)
{
    std::ostringstream getFirstUserDeckIDSQL;
    getFirstUserDeckIDSQL <<
        R"(SELECT "Deck"."ID" )" <<
        R"(FROM "Deck", "User", "DeckToUser" )" <<
        R"(WHERE "Deck"."ID" = "DeckToUser"."DeckID" AND "User"."ID" = "DeckToUser"."UserID" )" <<
        R"(AND "User"."SteamID" = ')" << steamID << "' LIMIT 1";

    std::ostringstream getCardUserIDSQLStream;
    getCardUserIDSQLStream <<
        R"(SELECT "CardToUser"."ID", ()" << getFirstUserDeckIDSQL.str() << ") " <<
        R"(FROM "User", "Card", "CardToUser" )" <<
        R"(WHERE "User"."ID" = "CardToUser"."UserID" AND "Card"."ID" = "CardToUser"."CardID" )" <<
        R"(AND User"."SteamID" = ')" << steamID << "' LIMIT 40)";

    std::ostringstream createSQLStream;
    createSQLStream << R"(INSERT INTO "CardUserToDeck"("CardUserID", "DeckID") )" << getCardUserIDSQLStream.str();

    return createSQLStream.str();
}

int Database::createDeckAndGetID()
{
    std::string query = formatCreateDeckAndGetIDQuery();

    std::cout << "Executing createDeckAndGetID..." << std::endl;
    std::cout << query << "\n" << std::endl;

    result = PQexec(connection, query.c_str());

    std::string strDeckID;
    int deckID;
    for (int i = 0; i < PQntuples(result); i++)
    {
        strDeckID = PQgetvalue(result, i, 0);
    }

    deckID = stoi(strDeckID);

    return deckID;
}

std::string Database::formatCreateDeckAndGetIDQuery()
{
    std::ostringstream createDeckSQL;
    createDeckSQL <<
                  R"(INSERT INTO "Deck" ("Name"))" <<
                  "VALUES('" << "Starter Deck" << R"(') RETURNING "Deck"."ID")";

    return createDeckSQL.str();
}

Database::Database()
        : result(nullptr)
{
    initializeConfig();
    CONNECTION_INFO = config["CONNECTION_INFO"];
    initializeConnection();
}

Database::~Database()
{
    PQfinish(connection);
}

void Database::initializeConnection()
{
    connection = PQconnectdb(CONNECTION_INFO.c_str());
    if (PQstatus(connection) != CONNECTION_OK)
    {
        std::cout << "Connection to database failed: " << PQerrorMessage(connection) << std::endl;
    }
    else
    {
        std::cout << "Connected to " << CONNECTION_INFO << std::endl;
    }
}

void Database::initializeConfig()
{
    // Path is relative to the exe in the build folder. This should probably be updated at some point?
    std::ifstream dbfile("../dbconfig.json", std::ifstream::in);
    std::stringstream buffer;
    buffer << dbfile.rdbuf();
    std::string rawJSON = buffer.str();
    config = json::parse(rawJSON);
}
<|endoftext|>


<commit_before>#include <fstream>
#include <gtest/gtest.h>
#include "codec_def.h"
#include "codec_app_def.h"
#include "utils/BufferedData.h"
#include "BaseDecoderTest.h"

static void ReadFrame(std::ifstream* file, BufferedData* buf) {
  // start code of a frame is {0, 0, 0, 1}
  int zeroCount = 0;
  char b;

  buf->Clear();
  for (;;) {
    file->read(&b, 1);
    if (file->gcount() != 1) { // end of file
      return;
    }
    if (!buf->PushBack(b)) {
      FAIL() << "unable to allocate memory";
    }

    if (buf->Length() <= 4) {
      continue;
    }

    if (zeroCount < 3) {
      zeroCount = b != 0 ? 0 : zeroCount + 1;
    } else {
      if (b == 1) {
        if (file->seekg(-4, file->cur).good()) {
          buf->SetLength(buf->Length() - 4);
          return;
        } else {
          FAIL() << "unable to seek file";
        }
      } else if (b == 0) {
        zeroCount = 3;
      } else {
        zeroCount = 0;
      }
    }
  }
}

BaseDecoderTest::BaseDecoderTest()
  : decoder_(NULL), decodeStatus_(OpenFile) {}

void BaseDecoderTest::SetUp() {
  long rv = CreateDecoder(&decoder_);
  ASSERT_EQ(0, rv);
  ASSERT_TRUE(decoder_ != NULL);

  SDecodingParam decParam;
  memset(&decParam, 0, sizeof(SDecodingParam));
  decParam.iOutputColorFormat  = videoFormatI420;
  decParam.uiTargetDqLayer = UCHAR_MAX;
  decParam.uiEcActiveFlag  = 1;
  decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;

  rv = decoder_->Initialize(&decParam, INIT_TYPE_PARAMETER_BASED);
  ASSERT_EQ(0, rv);
}

void BaseDecoderTest::TearDown() {
  if (decoder_ != NULL) {
    decoder_->Uninitialize();
    DestroyDecoder(decoder_);
  }
}

void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) {
  void* data[3];
  SBufferInfo bufInfo;
  memset(data, 0, sizeof(data));
  memset(&bufInfo, 0, sizeof(SBufferInfo));

  DECODING_STATE rv = decoder_->DecodeFrame2(src, sliceSize, data, &bufInfo);
  ASSERT_TRUE(rv == dsErrorFree);

  if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
    const Frame frame = {
        { // y plane
            static_cast<uint8_t*>(data[0]),
            bufInfo.UsrData.sSystemBuffer.iWidth,
            bufInfo.UsrData.sSystemBuffer.iHeight,
            bufInfo.UsrData.sSystemBuffer.iStride[0]
        },
        { // u plane
            static_cast<uint8_t*>(data[1]),
            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
            bufInfo.UsrData.sSystemBuffer.iStride[1]
        },
        { // v plane
            static_cast<uint8_t*>(data[2]),
            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
            bufInfo.UsrData.sSystemBuffer.iStride[1]
        },
    };
    cbk->onDecodeFrame(frame);
  }
}
void BaseDecoderTest::DecodeFile(const char* fileName, Callback* cbk) {
  std::ifstream file(fileName, std::ios::in | std::ios::binary);
  ASSERT_TRUE(file.is_open());

  BufferedData buf;
  while (true) {
    ReadFrame(&file, &buf);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
    if (buf.Length() == 0) {
      break;
    }
    DecodeFrame(buf.data(), buf.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
  }

  int32_t iEndOfStreamFlag = 1;
  decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);

  // Get pending last frame
  DecodeFrame(NULL, 0, cbk);
}

bool BaseDecoderTest::Open(const char* fileName) {
  if (decodeStatus_ == OpenFile) {
    file_.open(fileName);
    if (file_.is_open()) {
      decodeStatus_ = Decoding;
      return true;
    }
  }
  return false;
}

bool BaseDecoderTest::DecodeNextFrame(Callback* cbk) {
  switch (decodeStatus_) {
  case Decoding:
    ReadFrame(&file_, &buf_);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    if (buf_.Length() == 0) {
      decodeStatus_ = EndOfStream;
      return true;
    }
    DecodeFrame(buf_.data(), buf_.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    return true;
  case EndOfStream: {
    int32_t iEndOfStreamFlag = 1;
    decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
    DecodeFrame(NULL, 0, cbk);
    decodeStatus_ = End;
    break;
  }
  }
  return false;
}
<commit_msg>fix clang error<commit_after>#include <fstream>
#include <gtest/gtest.h>
#include "codec_def.h"
#include "codec_app_def.h"
#include "utils/BufferedData.h"
#include "BaseDecoderTest.h"

static void ReadFrame(std::ifstream* file, BufferedData* buf) {
  // start code of a frame is {0, 0, 0, 1}
  int zeroCount = 0;
  char b;

  buf->Clear();
  for (;;) {
    file->read(&b, 1);
    if (file->gcount() != 1) { // end of file
      return;
    }
    if (!buf->PushBack(b)) {
      FAIL() << "unable to allocate memory";
    }

    if (buf->Length() <= 4) {
      continue;
    }

    if (zeroCount < 3) {
      zeroCount = b != 0 ? 0 : zeroCount + 1;
    } else {
      if (b == 1) {
        if (file->seekg(-4, file->cur).good()) {
          buf->SetLength(buf->Length() - 4);
          return;
        } else {
          FAIL() << "unable to seek file";
        }
      } else if (b == 0) {
        zeroCount = 3;
      } else {
        zeroCount = 0;
      }
    }
  }
}

BaseDecoderTest::BaseDecoderTest()
  : decoder_(NULL), decodeStatus_(OpenFile) {}

void BaseDecoderTest::SetUp() {
  long rv = CreateDecoder(&decoder_);
  ASSERT_EQ(0, rv);
  ASSERT_TRUE(decoder_ != NULL);

  SDecodingParam decParam;
  memset(&decParam, 0, sizeof(SDecodingParam));
  decParam.iOutputColorFormat  = videoFormatI420;
  decParam.uiTargetDqLayer = UCHAR_MAX;
  decParam.uiEcActiveFlag  = 1;
  decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;

  rv = decoder_->Initialize(&decParam, INIT_TYPE_PARAMETER_BASED);
  ASSERT_EQ(0, rv);
}

void BaseDecoderTest::TearDown() {
  if (decoder_ != NULL) {
    decoder_->Uninitialize();
    DestroyDecoder(decoder_);
  }
}

void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) {
  void* data[3];
  SBufferInfo bufInfo;
  memset(data, 0, sizeof(data));
  memset(&bufInfo, 0, sizeof(SBufferInfo));

  DECODING_STATE rv = decoder_->DecodeFrame2(src, sliceSize, data, &bufInfo);
  ASSERT_TRUE(rv == dsErrorFree);

  if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
    const Frame frame = {
        { // y plane
            static_cast<uint8_t*>(data[0]),
            bufInfo.UsrData.sSystemBuffer.iWidth,
            bufInfo.UsrData.sSystemBuffer.iHeight,
            bufInfo.UsrData.sSystemBuffer.iStride[0]
        },
        { // u plane
            static_cast<uint8_t*>(data[1]),
            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
            bufInfo.UsrData.sSystemBuffer.iStride[1]
        },
        { // v plane
            static_cast<uint8_t*>(data[2]),
            bufInfo.UsrData.sSystemBuffer.iWidth / 2,
            bufInfo.UsrData.sSystemBuffer.iHeight / 2,
            bufInfo.UsrData.sSystemBuffer.iStride[1]
        },
    };
    cbk->onDecodeFrame(frame);
  }
}
void BaseDecoderTest::DecodeFile(const char* fileName, Callback* cbk) {
  std::ifstream file(fileName, std::ios::in | std::ios::binary);
  ASSERT_TRUE(file.is_open());

  BufferedData buf;
  while (true) {
    ReadFrame(&file, &buf);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
    if (buf.Length() == 0) {
      break;
    }
    DecodeFrame(buf.data(), buf.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
  }

  int32_t iEndOfStreamFlag = 1;
  decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);

  // Get pending last frame
  DecodeFrame(NULL, 0, cbk);
}

bool BaseDecoderTest::Open(const char* fileName) {
  if (decodeStatus_ == OpenFile) {
    file_.open(fileName);
    if (file_.is_open()) {
      decodeStatus_ = Decoding;
      return true;
    }
  }
  return false;
}

bool BaseDecoderTest::DecodeNextFrame(Callback* cbk) {
  switch (decodeStatus_) {
  case Decoding:
    ReadFrame(&file_, &buf_);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    if (buf_.Length() == 0) {
      decodeStatus_ = EndOfStream;
      return true;
    }
    DecodeFrame(buf_.data(), buf_.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    return true;
  case EndOfStream: {
    int32_t iEndOfStreamFlag = 1;
    decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
    DecodeFrame(NULL, 0, cbk);
    decodeStatus_ = End;
    break;
  }
  case OpenFile:
  case End:
    break;
  }
  return false;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: basicparser.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-15 17:19:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_XML_BASICPARSER_HXX
#define CONFIGMGR_XML_BASICPARSER_HXX

#ifndef CONFIGMGR_XML_ELEMENTPARSER_HXX
#include "elementparser.hxx"
#endif

#ifndef CONFIGMGR_UTILITY_HXX_
#include "utility.hxx"
#endif
#ifndef CONFIGMGR_STACK_HXX_
#include "stack.hxx"
#endif

#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP_
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace xml
    {
// -----------------------------------------------------------------------------
        namespace uno           = ::com::sun::star::uno;
        namespace lang          = ::com::sun::star::lang;

        namespace sax           = ::com::sun::star::xml::sax;

        using rtl::OUString;
// -----------------------------------------------------------------------------

        typedef ::cppu::WeakImplHelper1<sax::XDocumentHandler> Parser_Base;

        class BasicParser
        :   public Parser_Base
        {
            struct ValueData;

            uno::Reference< uno::XInterface > m_xTypeConverter;
            uno::Reference< sax::XLocator > m_xLocator;
            ElementParser                   m_aDataParser;
            Stack< ElementInfo >            m_aNodes;
            uno::Type                       m_aValueType;
            ValueData *                     m_pValueData;
            sal_uInt16                      m_nSkipLevels;
            bool                            m_bEmpty;
            bool                            m_bInProperty;

#if OSL_DEBUG_LEVEL > 0
#ifdef DBG_UTIL
            OUString  dbgPublicId,    dbgSystemId;
            sal_Int32 dbgLineNo,      dbgColumnNo;
#endif // DBG_UTIL
            void dbgUpdateLocation();
#endif // OSL_DEBUG_LEVEL

        public:
            typedef uno::Reference< lang::XMultiServiceFactory > ServiceFactory;

            explicit BasicParser(ServiceFactory const & _xSvcFactory);
            virtual ~BasicParser();

        // XDocumentHandler
        public:
            virtual void SAL_CALL
                startDocument(  )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                endDocument(  ) throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                characters( const OUString& aChars )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                ignorableWhitespace( const OUString& aWhitespaces )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                processingInstruction( const OUString& aTarget, const OUString& aData )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                setDocumentLocator( const uno::Reference< sax::XLocator >& xLocator )
                    throw (sax::SAXException, uno::RuntimeException);

        protected:
            ElementParser const & getDataParser() const { return m_aDataParser; }

            /// start an node
            void startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we in the content of a  node ?
            bool isInNode();
            /// are we in the content of node for which no content was started yet ?
            bool isEmptyNode();
            /// make sure we are in the content of a  node ?
            void ensureInNode();
            /// get the info about of the node currently being processed
            ElementInfo const & getActiveNodeInfo();
            /// end a node
            void endNode();

            /// start a property
            void startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we in the content of a property node ?
            bool isInProperty();
            /// are we in the content of a property node (and there has been no value for that property) ?
            bool isInUnhandledProperty();
            /// get the data type of the active property ?
            uno::Type getActivePropertyType();
            /// end a property
            void endProperty();

            /// start collecting data for a value - returns the locale of the value (property must have been started)
            void startValueData(const uno::Reference< sax::XAttributeList >& xAttribs);
            /// are we in the content of a property node ?
            bool isInValueData();
            /// check if the current value data has a locale set
            bool isValueDataLocalized();
            /// get the locale of the current value data, if localized
            OUString getValueDataLocale();
            /// return the collected value
            uno::Any getCurrentValue();
            /// end collecting data for a value
            void endValueData();

            /// start a node to be skipped
            void startSkipping( const OUString& aTag, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we inside a skipped node ?
            bool isSkipping( );
            /// ending a node: was this skipped ?
            bool wasSkipping( const OUString& aTag );

        protected:
            void raiseParseException( uno::Any const & _aTargetException, sal_Char const * _pMsg = NULL)
                    CFG_THROW2 (sax::SAXException, uno::RuntimeException);
            void raiseParseException( sal_Char const * _pMsg )
                    CFG_THROW2 (sax::SAXException, uno::RuntimeException);
        };
// -----------------------------------------------------------------------------
    } // namespace xml
// -----------------------------------------------------------------------------

} // namespace configmgr
#endif

<commit_msg>INTEGRATION: CWS cfglogging (1.5.120); FILE MERGED 2004/08/27 07:49:01 jb 1.5.120.1: #i25940#,#i25939# Add log output to parsing services<commit_after>/*************************************************************************
 *
 *  $RCSfile: basicparser.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2004-08-31 14:58:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_XML_BASICPARSER_HXX
#define CONFIGMGR_XML_BASICPARSER_HXX

#ifndef CONFIGMGR_XML_ELEMENTPARSER_HXX
#include "elementparser.hxx"
#endif

#ifndef CONFIGMGR_UTILITY_HXX_
#include "utility.hxx"
#endif
#ifndef CONFIGMGR_STACK_HXX_
#include "stack.hxx"
#endif
#ifndef CONFIGMGR_LOGGER_HXX_
#include "logger.hxx"
#endif

#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP_
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace xml
    {
// -----------------------------------------------------------------------------
        namespace uno           = ::com::sun::star::uno;
        namespace lang          = ::com::sun::star::lang;

        namespace sax           = ::com::sun::star::xml::sax;

        using rtl::OUString;
// -----------------------------------------------------------------------------

        typedef ::cppu::WeakImplHelper1<sax::XDocumentHandler> Parser_Base;

        class BasicParser
        :   public Parser_Base
        {
            struct ValueData;

            uno::Reference< uno::XInterface > m_xTypeConverter;
            uno::Reference< sax::XLocator > m_xLocator;
            ElementParser                   m_aDataParser;
            Stack< ElementInfo >            m_aNodes;
            uno::Type                       m_aValueType;
            ValueData *                     m_pValueData;
            sal_uInt16                      m_nSkipLevels;
            bool                            m_bEmpty;
            bool                            m_bInProperty;

#if OSL_DEBUG_LEVEL > 0
#ifdef DBG_UTIL
            OUString  dbgPublicId,    dbgSystemId;
            sal_Int32 dbgLineNo,      dbgColumnNo;
#endif // DBG_UTIL
            void dbgUpdateLocation();
#endif // OSL_DEBUG_LEVEL

        public:
            typedef uno::Reference< uno::XComponentContext > Context;

            explicit BasicParser(Context const & _xContext);
            virtual ~BasicParser();

        // XDocumentHandler
        public:
            virtual void SAL_CALL
                startDocument(  )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                endDocument(  ) throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                characters( const OUString& aChars )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                ignorableWhitespace( const OUString& aWhitespaces )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                processingInstruction( const OUString& aTarget, const OUString& aData )
                    throw (sax::SAXException, uno::RuntimeException);

            virtual void SAL_CALL
                setDocumentLocator( const uno::Reference< sax::XLocator >& xLocator )
                    throw (sax::SAXException, uno::RuntimeException);

        protected:
            ElementParser const & getDataParser() const { return m_aDataParser; }

            Logger const & getLogger() { return m_aDataParser.logger(); }

            /// start an node
            void startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we in the content of a  node ?
            bool isInNode();
            /// are we in the content of node for which no content was started yet ?
            bool isEmptyNode();
            /// make sure we are in the content of a  node ?
            void ensureInNode();
            /// get the info about of the node currently being processed
            ElementInfo const & getActiveNodeInfo();
            /// end a node
            void endNode();

            /// start a property
            void startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we in the content of a property node ?
            bool isInProperty();
            /// are we in the content of a property node (and there has been no value for that property) ?
            bool isInUnhandledProperty();
            /// get the data type of the active property ?
            uno::Type getActivePropertyType();
            /// end a property
            void endProperty();

            /// start collecting data for a value - returns the locale of the value (property must have been started)
            void startValueData(const uno::Reference< sax::XAttributeList >& xAttribs);
            /// are we in the content of a property node ?
            bool isInValueData();
            /// check if the current value data has a locale set
            bool isValueDataLocalized();
            /// get the locale of the current value data, if localized
            OUString getValueDataLocale();
            /// return the collected value
            uno::Any getCurrentValue();
            /// end collecting data for a value
            void endValueData();

            /// start a node to be skipped
            void startSkipping( const OUString& aTag, const uno::Reference< sax::XAttributeList >& xAttribs );
            /// are we inside a skipped node ?
            bool isSkipping( );
            /// ending a node: was this skipped ?
            bool wasSkipping( const OUString& aTag );

        protected:
            void raiseParseException( uno::Any const & _aTargetException, sal_Char const * _pMsg = NULL)
                    CFG_THROW2 (sax::SAXException, uno::RuntimeException);
            void raiseParseException( sal_Char const * _pMsg )
                    CFG_THROW2 (sax::SAXException, uno::RuntimeException);
        };
// -----------------------------------------------------------------------------
    } // namespace xml
// -----------------------------------------------------------------------------

} // namespace configmgr
#endif

<|endoftext|>


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

#include "webkit/glue/plugins/pepper_char_set.h"

#include <stdlib.h>

#include "base/i18n/icu_string_conversions.h"
#include "third_party/ppapi/c/ppb_char_set.h"
#include "unicode/ucnv.h"
#include "unicode/ucnv_cb.h"
#include "unicode/ucnv_err.h"
#include "unicode/ustring.h"

namespace pepper {

namespace {

// Converts the given PP error handling behavior to the version in base,
// placing the result in |*result| and returning true on success. Returns false
// if the enum is invalid.
bool PPToBaseConversionError(PP_CharSet_ConversionError on_error,
                             base::OnStringConversionError::Type* result) {
  switch (on_error) {
    case PP_CHARSET_CONVERSIONERROR_FAIL:
      *result = base::OnStringConversionError::FAIL;
      return true;
    case PP_CHARSET_CONVERSIONERROR_SKIP:
      *result = base::OnStringConversionError::SKIP;
      return true;
    case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE:
      *result = base::OnStringConversionError::SUBSTITUTE;
      return true;
    default:
      return false;
  }
}

// The "substitution" behavior of this function does not match the
// implementation in base, so we partially duplicate the code from
// icu_string_conversions.cc with the correct error handling setup required
// by this pepper interface.
char* UTF16ToCharSet(const uint16_t* utf16, uint32_t utf16_len,
                     const char* output_char_set,
                     PP_CharSet_ConversionError on_error,
                     uint32_t* output_length) {
  *output_length = 0;

  UErrorCode status = U_ZERO_ERROR;
  UConverter* converter = ucnv_open(output_char_set, &status);
  if (!U_SUCCESS(status))
    return NULL;

  int encoded_max_length = UCNV_GET_MAX_BYTES_FOR_STRING(utf16_len,
      ucnv_getMaxCharSize(converter));

  // Setup our error handler.
  switch (on_error) {
    case PP_CHARSET_CONVERSIONERROR_FAIL:
      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_STOP, 0,
                            NULL, NULL, &status);
      break;
    case PP_CHARSET_CONVERSIONERROR_SKIP:
      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SKIP, 0,
                            NULL, NULL, &status);
      break;
    case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE: {
      // ICU sets the substitution char for some character sets (like latin1)
      // to be the ASCII "substitution character" (26). We want to use '?'
      // instead for backwards-compat with Windows behavior.
      char subst_chars[32];
      int8_t subst_chars_len = 32;
      ucnv_getSubstChars(converter, subst_chars, &subst_chars_len, &status);
      if (subst_chars_len == 1 && subst_chars[0] == 26) {
        // Override to the question mark character if possible. When using
        // setSubstString, the input is a Unicode character. The function will
        // try to convert it to the destination character set and fail if that
        // can not be converted to the destination character set.
        //
        // We just ignore any failure. If the dest char set has no
        // representation for '?', then we'll just stick to the ICU default
        // substitution character.
        UErrorCode subst_status = U_ZERO_ERROR;
        UChar question_mark = '?';
        ucnv_setSubstString(converter, &question_mark, 1, &subst_status);
      }

      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0,
                            NULL, NULL, &status);
      break;
    }
    default:
      return NULL;
  }

  // ucnv_fromUChars returns size not including terminating null.
  char* encoded = static_cast<char*>(malloc(encoded_max_length + 1));
  int actual_size = ucnv_fromUChars(converter, encoded,
      encoded_max_length, utf16, utf16_len, &status);
  ucnv_close(converter);
  if (!U_SUCCESS(status)) {
    free(encoded);
    return NULL;
  }
  encoded[actual_size] = 0;
  *output_length = actual_size;
  return encoded;
}

uint16_t* CharSetToUTF16(const char* input, uint32_t input_len,
                         const char* input_char_set,
                         PP_CharSet_ConversionError on_error,
                         uint32_t* output_length) {
  *output_length = 0;

  base::OnStringConversionError::Type base_on_error;
  if (!PPToBaseConversionError(on_error, &base_on_error))
    return NULL;  // Invalid enum value.

  // We can convert this call to the implementation in base to avoid code
  // duplication, although this does introduce an extra copy of the data.
  string16 output;
  if (!base::CodepageToUTF16(std::string(input, input_len), input_char_set,
                             base_on_error, &output))
    return NULL;

  uint16_t* ret_buf = static_cast<uint16_t*>(
      malloc((output.size() + 1) * sizeof(uint16_t)));
  if (!ret_buf)
    return NULL;

  *output_length = static_cast<uint32_t>(output.size());
  memcpy(ret_buf, output.c_str(), (output.size() + 1) * sizeof(uint16_t));
  return ret_buf;
}

PP_Var GetDefaultCodePageForUILanguage() {
  // TODO(brettw) bug 52865: Implement this function.
  return PP_MakeVoid();
}

const PPB_CharSetDev ppb_charset = {
  &UTF16ToCharSet,
  &CharSetToUTF16,
  &GetDefaultCodePageForUILanguage
};

}  // namespace

// static
const PPB_CharSetDev* CharSet::GetInterface() {
  return &ppb_charset;
}

}  // namespace pepper
<commit_msg>Fix the windows build by casting for ICU.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/plugins/pepper_char_set.h"

#include <stdlib.h>

#include "base/i18n/icu_string_conversions.h"
#include "third_party/ppapi/c/ppb_char_set.h"
#include "unicode/ucnv.h"
#include "unicode/ucnv_cb.h"
#include "unicode/ucnv_err.h"
#include "unicode/ustring.h"

namespace pepper {

namespace {

// Converts the given PP error handling behavior to the version in base,
// placing the result in |*result| and returning true on success. Returns false
// if the enum is invalid.
bool PPToBaseConversionError(PP_CharSet_ConversionError on_error,
                             base::OnStringConversionError::Type* result) {
  switch (on_error) {
    case PP_CHARSET_CONVERSIONERROR_FAIL:
      *result = base::OnStringConversionError::FAIL;
      return true;
    case PP_CHARSET_CONVERSIONERROR_SKIP:
      *result = base::OnStringConversionError::SKIP;
      return true;
    case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE:
      *result = base::OnStringConversionError::SUBSTITUTE;
      return true;
    default:
      return false;
  }
}

// The "substitution" behavior of this function does not match the
// implementation in base, so we partially duplicate the code from
// icu_string_conversions.cc with the correct error handling setup required
// by this pepper interface.
char* UTF16ToCharSet(const uint16_t* utf16, uint32_t utf16_len,
                     const char* output_char_set,
                     PP_CharSet_ConversionError on_error,
                     uint32_t* output_length) {
  *output_length = 0;

  UErrorCode status = U_ZERO_ERROR;
  UConverter* converter = ucnv_open(output_char_set, &status);
  if (!U_SUCCESS(status))
    return NULL;

  int encoded_max_length = UCNV_GET_MAX_BYTES_FOR_STRING(utf16_len,
      ucnv_getMaxCharSize(converter));

  // Setup our error handler.
  switch (on_error) {
    case PP_CHARSET_CONVERSIONERROR_FAIL:
      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_STOP, 0,
                            NULL, NULL, &status);
      break;
    case PP_CHARSET_CONVERSIONERROR_SKIP:
      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SKIP, 0,
                            NULL, NULL, &status);
      break;
    case PP_CHARSET_CONVERSIONERROR_SUBSTITUTE: {
      // ICU sets the substitution char for some character sets (like latin1)
      // to be the ASCII "substitution character" (26). We want to use '?'
      // instead for backwards-compat with Windows behavior.
      char subst_chars[32];
      int8_t subst_chars_len = 32;
      ucnv_getSubstChars(converter, subst_chars, &subst_chars_len, &status);
      if (subst_chars_len == 1 && subst_chars[0] == 26) {
        // Override to the question mark character if possible. When using
        // setSubstString, the input is a Unicode character. The function will
        // try to convert it to the destination character set and fail if that
        // can not be converted to the destination character set.
        //
        // We just ignore any failure. If the dest char set has no
        // representation for '?', then we'll just stick to the ICU default
        // substitution character.
        UErrorCode subst_status = U_ZERO_ERROR;
        UChar question_mark = '?';
        ucnv_setSubstString(converter, &question_mark, 1, &subst_status);
      }

      ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0,
                            NULL, NULL, &status);
      break;
    }
    default:
      return NULL;
  }

  // ucnv_fromUChars returns size not including terminating null.
  char* encoded = static_cast<char*>(malloc(encoded_max_length + 1));
  int actual_size = ucnv_fromUChars(converter, encoded,
      encoded_max_length, reinterpret_cast<const UChar*>(utf16), utf16_len,
      &status);
  ucnv_close(converter);
  if (!U_SUCCESS(status)) {
    free(encoded);
    return NULL;
  }
  encoded[actual_size] = 0;
  *output_length = actual_size;
  return encoded;
}

uint16_t* CharSetToUTF16(const char* input, uint32_t input_len,
                         const char* input_char_set,
                         PP_CharSet_ConversionError on_error,
                         uint32_t* output_length) {
  *output_length = 0;

  base::OnStringConversionError::Type base_on_error;
  if (!PPToBaseConversionError(on_error, &base_on_error))
    return NULL;  // Invalid enum value.

  // We can convert this call to the implementation in base to avoid code
  // duplication, although this does introduce an extra copy of the data.
  string16 output;
  if (!base::CodepageToUTF16(std::string(input, input_len), input_char_set,
                             base_on_error, &output))
    return NULL;

  uint16_t* ret_buf = static_cast<uint16_t*>(
      malloc((output.size() + 1) * sizeof(uint16_t)));
  if (!ret_buf)
    return NULL;

  *output_length = static_cast<uint32_t>(output.size());
  memcpy(ret_buf, output.c_str(), (output.size() + 1) * sizeof(uint16_t));
  return ret_buf;
}

PP_Var GetDefaultCodePageForUILanguage() {
  // TODO(brettw) bug 52865: Implement this function.
  return PP_MakeVoid();
}

const PPB_CharSetDev ppb_charset = {
  &UTF16ToCharSet,
  &CharSetToUTF16,
  &GetDefaultCodePageForUILanguage
};

}  // namespace

// static
const PPB_CharSetDev* CharSet::GetInterface() {
  return &ppb_charset;
}

}  // namespace pepper
<|endoftext|>


<commit_before>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

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.

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 HOLDER 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.

*/

#include <iostream>

#include <SFML/OpenGL.hpp>

#include <DMUtils/sfml.hpp>

#include <LightSystem/LightSystem.hpp>

namespace DMGDVT {
namespace LS {

    const sf::RenderStates LightSystem::_multiplyState(sf::BlendMultiply);
    const sf::RenderStates LightSystem::_addState(sf::BlendAdd);
    //const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One, sf::BlendMode::ReverseSubtract));
    const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::Zero, sf::BlendMode::OneMinusSrcColor, sf::BlendMode::Add));

    LightSystem::LightSystem(bool isometric) : _ambiant(sf::Color::Black), _isometric(isometric), _autoDelete(true) {
        //this will be loaded from internal memory when lib is created
        //or loaded external crypted
        //the idea is not to allow the user to modify it
        if(!_lightAttenuationShader.loadFromFile("shaders/lightAttenuation.frag",sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }

    }

    LightSystem::~LightSystem() {
        reset();
    }

    void LightSystem::addLight(Light* l) {
        l->setIsometric(_isometric);//ignore what user set before
        l->preRender(&_lightAttenuationShader);
        if(l->isNegative()) _negativeLights.emplace_back(l);
        else _lights.emplace_back(l);
    }

    void LightSystem::removeLight(Light* l) {
        if(l->isNegative()) _negativeLights.remove(l);
        else _lights.remove(l);
    }

    void LightSystem::reset() {
        if(_autoDelete) for(Light* l : _lights) delete l;

        _lights.empty();
    }

    void LightSystem::render(const sf::View& screenView, sf::RenderTarget& target) {
        debugRender(screenView,target,LightSystem::DEBUG_FLAGS::DEFAULT);
    }

    void LightSystem::debugRender(const sf::View& screenView, sf::RenderTarget& target, int flags) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);

        _sprite.setPosition(screen.left,screen.top);

        _renderTexture.clear(_ambiant);
        sf::RenderStates stAdd(_addState);
        sf::RenderStates stRm(_subtractState);
        sf::Transform t;
        t.translate(-_sprite.getPosition());
        stAdd.transform.combine(t);
        stRm.transform.combine(t);
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DEBUG_FLAGS::SHADER_OFF) l->debugRender(_renderTexture,(stAdd));
                else l->render(screen,_renderTexture,&_lightAttenuationShader,(stAdd));
            }
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DEBUG_FLAGS::SHADER_OFF) l->debugRender(_renderTexture,(stRm));
                else l->render(screen,_renderTexture,&_lightAttenuationShader,(stRm));
            }
        }

        _renderTexture.display();

        if(flags & DEBUG_FLAGS::LIGHTMAP_ONLY) target.clear(sf::Color::White);
    }

    void LightSystem::draw(const sf::View& screenView, sf::RenderTarget& target) {
        target.draw(_sprite,_multiplyState);
    }

    void LightSystem::drawAABB(const sf::View& screen, sf::RenderTarget& target) {
        drawAABB(target.getViewport(screen),target);
    }

    void LightSystem::drawAABB(const sf::IntRect& screen, sf::RenderTarget& target) {
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
    }

    void LightSystem::update() {
        for(Light* l : _lights) update(l);
        for(Light* l : _negativeLights) update(l);
    }

    void LightSystem::update(Light* l) {
        bool wasNegative = l->isNegative();
        l->preRender(&_lightAttenuationShader);
        bool isNegative = l->isNegative();
        if(wasNegative xor isNegative) {
            if(isNegative) {
                _lights.remove(l);
                _negativeLights.emplace_back(l);
            } else {
                _negativeLights.remove(l);
                _lights.emplace_back(l);
            }
        }
    }

    size_t LightSystem::getLightsCount() const {
        return getNormalLightsCount() + getNegativeLightsCount();
    }

    size_t LightSystem::getNormalLightsCount() const {
        return _lights.size();
    }

    size_t LightSystem::getNegativeLightsCount() const {
        return _negativeLights.size();
    }

    sf::Image LightSystem::getLightMap() const {
        return _renderTexture.getTexture().copyToImage();
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, int x, int y) const {
        x -= view.getViewport().left;
        y -= view.getViewport().top;
        return getLightMap().getPixel(x,y);
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, sf::Vector2f p) const {
        return getLightMapPixel(view,p.x,p.y);
    }

    void LightSystem::setAmbiantLight(sf::Color c) {
        _ambiant = c;
    }

    sf::Color LightSystem::getAmbiantLight() const {
        return _ambiant;
    }

    void LightSystem::setIsometric(bool i) {
        _isometric = i;
        update();
    }

    bool LightSystem::isIsometric() const {
        return _isometric;
    }

    void LightSystem::setAutoDelete(bool ad) {
        _autoDelete = ad;
    }

    void LightSystem::setView(const sf::View& view) {
        _renderTexture.create(view.getSize().x,view.getSize().y);
        _sprite.setTexture(_renderTexture.getTexture());
    }
}
}
<commit_msg>Previous commit was retarded, abort<commit_after>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

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.

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 HOLDER 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.

*/

#include <iostream>

#include <SFML/OpenGL.hpp>

#include <DMUtils/sfml.hpp>

#include <LightSystem/LightSystem.hpp>

namespace DMGDVT {
namespace LS {

    const sf::RenderStates LightSystem::_multiplyState(sf::BlendMultiply);
    const sf::RenderStates LightSystem::_addState(sf::BlendAdd);
    //const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One, sf::BlendMode::ReverseSubtract));
    const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::Zero, sf::BlendMode::OneMinusSrcColor, sf::BlendMode::Add));

    LightSystem::LightSystem(bool isometric) : _ambiant(sf::Color::Black), _isometric(isometric), _autoDelete(true) {
        //this will be loaded from internal memory when lib is created
        //or loaded external crypted
        //the idea is not to allow the user to modify it
        if(!_lightAttenuationShader.loadFromFile("shaders/lightAttenuation.frag",sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }

    }

    LightSystem::~LightSystem() {
        reset();
    }

    void LightSystem::addLight(Light* l) {
        l->setIsometric(_isometric);//ignore what user set before
        l->preRender(&_lightAttenuationShader);
        if(l->isNegative()) _negativeLights.emplace_back(l);
        else _lights.emplace_back(l);
    }

    void LightSystem::removeLight(Light* l) {
        if(l->isNegative()) _negativeLights.remove(l);
        else _lights.remove(l);
    }

    void LightSystem::reset() {
        if(_autoDelete) for(Light* l : _lights) delete l;

        _lights.empty();
    }

    void LightSystem::render(const sf::View& screenView, sf::RenderTarget& target) {
        debugRender(screenView,target,LightSystem::DEBUG_FLAGS::DEFAULT);
    }

    void LightSystem::debugRender(const sf::View& screenView, sf::RenderTarget& target, int flags) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);

        _sprite.setPosition(screen.left,screen.top);

        _renderTexture.clear(_ambiant);
        sf::RenderStates stAdd(_addState);
        sf::RenderStates stRm(_subtractState);
        sf::Transform t;
        t.translate(-_sprite.getPosition());
        stAdd.transform.combine(t);
        stRm.transform.combine(t);
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DEBUG_FLAGS::SHADER_OFF) l->debugRender(_renderTexture,(stAdd));
                else l->render(screen,_renderTexture,&_lightAttenuationShader,(stAdd));
            }
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DEBUG_FLAGS::SHADER_OFF) l->debugRender(_renderTexture,(stRm));
                else l->render(screen,_renderTexture,&_lightAttenuationShader,(stRm));
            }
        }

        _renderTexture.display();

        if(flags & DEBUG_FLAGS::LIGHTMAP_ONLY) target.clear(sf::Color::White);
    }

    void LightSystem::draw(const sf::View& screenView, sf::RenderTarget& target) {
        target.draw(_sprite,_multiplyState);
    }

    void LightSystem::drawAABB(const sf::View& screen, sf::RenderTarget& target) {
        drawAABB(DMUtils::sfml::getViewInWorldAABB(screen),target);
    }

    void LightSystem::drawAABB(const sf::IntRect& screen, sf::RenderTarget& target) {
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
    }

    void LightSystem::update() {
        for(Light* l : _lights) update(l);
        for(Light* l : _negativeLights) update(l);
    }

    void LightSystem::update(Light* l) {
        bool wasNegative = l->isNegative();
        l->preRender(&_lightAttenuationShader);
        bool isNegative = l->isNegative();
        if(wasNegative xor isNegative) {
            if(isNegative) {
                _lights.remove(l);
                _negativeLights.emplace_back(l);
            } else {
                _negativeLights.remove(l);
                _lights.emplace_back(l);
            }
        }
    }

    size_t LightSystem::getLightsCount() const {
        return getNormalLightsCount() + getNegativeLightsCount();
    }

    size_t LightSystem::getNormalLightsCount() const {
        return _lights.size();
    }

    size_t LightSystem::getNegativeLightsCount() const {
        return _negativeLights.size();
    }

    sf::Image LightSystem::getLightMap() const {
        return _renderTexture.getTexture().copyToImage();
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, int x, int y) const {
        x -= view.getViewport().left;
        y -= view.getViewport().top;
        return getLightMap().getPixel(x,y);
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, sf::Vector2f p) const {
        return getLightMapPixel(view,p.x,p.y);
    }

    void LightSystem::setAmbiantLight(sf::Color c) {
        _ambiant = c;
    }

    sf::Color LightSystem::getAmbiantLight() const {
        return _ambiant;
    }

    void LightSystem::setIsometric(bool i) {
        _isometric = i;
        update();
    }

    bool LightSystem::isIsometric() const {
        return _isometric;
    }

    void LightSystem::setAutoDelete(bool ad) {
        _autoDelete = ad;
    }

    void LightSystem::setView(const sf::View& view) {
        _renderTexture.create(view.getSize().x,view.getSize().y);
        _sprite.setTexture(_renderTexture.getTexture());
    }
}
}
<|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/RMakeUnique.hxx" // std::make_unique
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as an array_view
            // TODO change array_view to span when available
            return "std::array_view<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   const auto friends = tree ? std::unique_ptr<TList>(tree->GetListOfFriends()) : std::make_unique<TList>();
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      if (friends) {
         bool isFriendBranch = false;
         for (auto friendTree : *friends) {
            const auto friendBranch = static_cast<TFriendElement*>(friendTree)->GetTree()->GetBranch(column.c_str());
            if (friendBranch != nullptr) {
               isFriendBranch = true;
               break;
            }
         }
         if (isFriendBranch)
            continue;
      }

      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return colName.find("__TDF_") == 0;
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<commit_msg>[TO FIXUP] Make clang-format happy<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/RMakeUnique.hxx" // std::make_unique
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as an array_view
            // TODO change array_view to span when available
            return "std::array_view<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   const auto friends = tree ? std::unique_ptr<TList>(tree->GetListOfFriends()) : std::make_unique<TList>();
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      if (friends) {
         bool isFriendBranch = false;
         for (auto friendTree : *friends) {
            const auto friendBranch = static_cast<TFriendElement *>(friendTree)->GetTree()->GetBranch(column.c_str());
            if (friendBranch != nullptr) {
               isFriendBranch = true;
               break;
            }
         }
         if (isFriendBranch)
            continue;
      }

      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return colName.find("__TDF_") == 0;
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<|endoftext|>