<commit_before>#include <QFileInfo>
#include <QRegularExpression>

#include "OutputParser.h"
#include "ParseState.h"
#include "TestModel.h"

using namespace QtcGtest::Internal;
namespace
{
  const QRegularExpression gtestStartPattern (
      QLatin1String (R"(^(.*)\[==========\] Running \d+ tests? from \d+ test cases?\.\s*$)"));
  enum GtestStart {GtestStartUnrelated = 1};
  const QRegularExpression gtestEndPattern   (
      QLatin1String (R"(^(.*)\[==========\] (\d+) tests? from (\d+) test cases? ran. \((\d+) ms total\)\s*$)"));
  enum GtestEnd{GtestEndUnrelated = 1, GtestEndTestsRun, GtestEndCasesRun, GtestEndTimeSpent};
  const QRegularExpression gtestDisabledPattern (
      QLatin1String (R"(^\s*YOU HAVE (\d+) DISABLED TESTS\s*$)"));
  enum GtestDisabled{GtestDisabledCount = 1};
  const QRegularExpression gtestFilterPattern (
      QLatin1String (R"(^\s*Note: (Google Test filter = .*)\s*$)"));
  enum GtestFilter{GtestFilterLine = 1};

  const QRegularExpression newCasePattern    (
      QLatin1String (R"(^(.*)\[\-{10}\] \d+ tests? from ([\w/]+)(, where TypeParam = (\w+))?\s*$)"));
  enum NewCase{NewCaseUnrelated = 1, NewCaseName, NewCaseFullParameter, NewCaseParameterType};
  const QRegularExpression endCasePattern    (
      QLatin1String (R"(^(.*)\[\-{10}\] \d+ tests? from ([\w/]+) \((\d+) ms total\)\s*$)"));
  enum EndCase{EndCaseUnrelated = 1, EndCaseName, EndCaseTimeSpent};

  const QRegularExpression beginTestPattern  (
      QLatin1String (R"(^(.*)\[ RUN      \] ([\w/]+)\.([\w/]+)\s*$)"));
  enum NewTest{NewTestUnrelated = 1, NewTestCaseName, NewTestName};
  const QRegularExpression failTestPattern   (
      QLatin1String (R"(^(.*)\[  FAILED  \] ([\w/]+)\.([\w/]+)(, where (GetParam\(\)|TypeParam) = (.+))? \((\d+) ms\)\s*$)"));
  enum FailTest{FailTestUnrelated = 1, FailTestCaseName, FailTestName, FailTestFullParameter,
                FailTestParameterType, FailTestParameterDetail, FailTestTimeSpent};
  const QRegularExpression passTestPattern   (
      QLatin1String (R"(^(.*)\[       OK \] ([\w/]+)\.([\w/]+) \((\d+) ms\)\s*$)"));
  enum PassTest{PassTestUnrelated = 1, PassTestCaseName, PassTestName, PassTestTimeSpent};
  const QRegularExpression failDetailPattern (
      QLatin1String (R"(^(.+):(\d+): Failure\s*$)"));
  enum FailDetail{FailDetailFileName = 1, FailDetailLine};
}

OutputParser::OutputParser(QObject *parent) :
  QObject(parent)
{
}

bool OutputParser::isGoogleTestRun(const QString &line) const
{
  QRegularExpressionMatch match = gtestStartPattern.match (line);
  QRegularExpressionMatch matchFilter = gtestFilterPattern.match (line);
  return (match.hasMatch () || matchFilter.hasMatch ());
}

void OutputParser::parseMessage(const QString &line, TestModel &model, ParseState &state)
{
  QRegularExpressionMatch match;
  match = newCasePattern.match (line);
  if (match.hasMatch ())
  {
    state.currentCase = match.captured (NewCaseName);
    if (match.lastCapturedIndex() == NewCaseParameterType)
    {
      state.currentCase += QString (QLatin1String(" <%1>")).arg (match.captured (NewCaseParameterType));
    }
    state.passedCount = state.failedCount = 0;
    model.addCase (state.currentCase);
    return;
  }

  match = endCasePattern.match (line);
  if (match.hasMatch ())
  {
    int totalTime = match.captured (EndCaseTimeSpent).toInt ();
    model.updateCase (state.currentCase, state.passedCount, state.failedCount, totalTime);
    state.currentCase.clear ();
    state.currentTest.clear ();
    return;
  }

  match = beginTestPattern.match (line);
  if (match.hasMatch ())
  {
    state.currentTest = match.captured (NewTestName);
    model.addTest (state.currentTest, state.currentCase);
    return;
  }

  match = passTestPattern.match (line);
  if (match.hasMatch ())
  {
    QString unrelated = match.captured(PassTestUnrelated);
    if (!unrelated.isEmpty()) {
      model.addTestDetail (state.currentTest, state.currentCase, unrelated);
    }
    ++state.passedCount;
    ++state.passedTotalCount;
    int totalTime = match.captured (PassTestTimeSpent).toInt ();
    model.updateTest (state.currentTest, state.currentCase, true, totalTime);
    state.currentTest.clear ();
    return;
  }

  match = failTestPattern.match (line);
  if (match.hasMatch ())
  {
    QString unrelated = match.captured(PassTestUnrelated);
    if (!unrelated.isEmpty()) {
      model.addTestDetail (state.currentTest, state.currentCase, unrelated);
    }
    ++state.failedCount;
    ++state.failedTotalCount;
    int totalTime = match.captured (FailTestTimeSpent).toInt ();
    model.updateTest (state.currentTest, state.currentCase, false, totalTime);
    QString parameterDetail = match.captured(FailTestParameterDetail);
    if (!parameterDetail.isEmpty()) {
      QString newTestName = state.currentTest + QString (QLatin1String(" <%1>")).arg (parameterDetail);
      model.renameTest (state.currentTest, newTestName, state.currentCase);
    }
    state.currentTest.clear ();
    return;
  }

  match = failDetailPattern.match (line);
  if (match.hasMatch ())
  {
    Q_ASSERT (!state.projectPath.isEmpty ());
    QString file = match.captured (FailDetailFileName);
    QFileInfo info (file);
    if (info.isRelative ())
    {
      file = state.projectPath + QLatin1Char ('/') + match.captured (FailDetailFileName);
    }
    int lineNumber = match.captured (FailDetailLine).toInt ();
    model.addTestError (state.currentTest, state.currentCase, line, file, lineNumber);
    return;
  }

  match = gtestEndPattern.match (line);
  if (match.hasMatch ())
  {
    state.totalTime = match.captured (GtestEndTimeSpent).toInt ();
    return;
  }

  match = gtestDisabledPattern.match (line);
  if (match.hasMatch ())
  {
    state.disabledCount = match.captured (GtestDisabledCount).toInt ();
    return;
  }

  match = gtestFilterPattern.match (line);
  if (match.hasMatch ())
  {
    model.addNote(match.captured (GtestFilterLine));
    return;
  }

  if (!state.currentTest.isEmpty ())
  {
    Q_ASSERT (!state.currentCase.isEmpty ());
    model.addTestDetail (state.currentTest, state.currentCase, line);
  }
}
<commit_msg>Fall back to escaped strings (msvc2010 does not support raw ones).<commit_after>#include <QFileInfo>
#include <QRegularExpression>

#include "OutputParser.h"
#include "ParseState.h"
#include "TestModel.h"

using namespace QtcGtest::Internal;
namespace
{
  const QRegularExpression gtestStartPattern (
      QLatin1String ("^(.*)\\[==========\\] Running \\d+ tests? from \\d+ test cases?\\.\\s*$"));
  enum GtestStart {GtestStartUnrelated = 1};
  const QRegularExpression gtestEndPattern   (
      QLatin1String ("^(.*)\\[==========\\] (\\d+) tests? from (\\d+) test cases? ran. \\((\\d+) ms total\\)\\s*$"));
  enum GtestEnd{GtestEndUnrelated = 1, GtestEndTestsRun, GtestEndCasesRun, GtestEndTimeSpent};
  const QRegularExpression gtestDisabledPattern (
      QLatin1String ("^\\s*YOU HAVE (\\d+) DISABLED TESTS\\s*$"));
  enum GtestDisabled{GtestDisabledCount = 1};
  const QRegularExpression gtestFilterPattern (
      QLatin1String ("^\\s*Note: (Google Test filter = .*)\\s*$"));
  enum GtestFilter{GtestFilterLine = 1};

  const QRegularExpression newCasePattern    (
      QLatin1String ("^(.*)\\[\\-{10}\\] \\d+ tests? from ([\\w/]+)(, where TypeParam = (.+))?\\s*$"));
  enum NewCase{NewCaseUnrelated = 1, NewCaseName, NewCaseFullParameter, NewCaseParameterType};
  const QRegularExpression endCasePattern    (
      QLatin1String ("^(.*)\\[\\-{10}\\] \\d+ tests? from ([\\w/]+) \\((\\d+) ms total\\)\\s*$"));
  enum EndCase{EndCaseUnrelated = 1, EndCaseName, EndCaseTimeSpent};

  const QRegularExpression beginTestPattern  (
      QLatin1String ("^(.*)\\[ RUN      \\] ([\\w/]+)\\.([\\w/]+)\\s*$"));
  enum NewTest{NewTestUnrelated = 1, NewTestCaseName, NewTestName};
  const QRegularExpression failTestPattern   (
      QLatin1String ("^(.*)\\[  FAILED  \\] ([\\w/]+)\\.([\\w/]+)(, where (GetParam\\(\\)|TypeParam) = (.+))? \\((\\d+) ms\\)\\s*$"));
  enum FailTest{FailTestUnrelated = 1, FailTestCaseName, FailTestName, FailTestFullParameter,
                FailTestParameterType, FailTestParameterDetail, FailTestTimeSpent};
  const QRegularExpression passTestPattern   (
      QLatin1String ("^(.*)\\[       OK \\] ([\\w/]+)\\.([\\w/]+) \\((\\d+) ms\\)\\s*$"));
  enum PassTest{PassTestUnrelated = 1, PassTestCaseName, PassTestName, PassTestTimeSpent};
  const QRegularExpression failDetailPattern (
      QLatin1String ("^(.+):(\\d+): Failure\\s*$"));
  enum FailDetail{FailDetailFileName = 1, FailDetailLine};
}

OutputParser::OutputParser(QObject *parent) :
  QObject(parent)
{
}

bool OutputParser::isGoogleTestRun(const QString &line) const
{
  QRegularExpressionMatch match = gtestStartPattern.match (line);
  QRegularExpressionMatch matchFilter = gtestFilterPattern.match (line);
  return (match.hasMatch () || matchFilter.hasMatch ());
}

void OutputParser::parseMessage(const QString &line, TestModel &model, ParseState &state)
{
  QRegularExpressionMatch match;
  match = newCasePattern.match (line);
  if (match.hasMatch ())
  {
    state.currentCase = match.captured (NewCaseName);
    if (match.lastCapturedIndex() == NewCaseParameterType)
    {
      state.currentCase += QString (QLatin1String(" <%1>")).arg (match.captured (NewCaseParameterType));
    }
    state.passedCount = state.failedCount = 0;
    model.addCase (state.currentCase);
    return;
  }

  match = endCasePattern.match (line);
  if (match.hasMatch ())
  {
    int totalTime = match.captured (EndCaseTimeSpent).toInt ();
    model.updateCase (state.currentCase, state.passedCount, state.failedCount, totalTime);
    state.currentCase.clear ();
    state.currentTest.clear ();
    return;
  }

  match = beginTestPattern.match (line);
  if (match.hasMatch ())
  {
    state.currentTest = match.captured (NewTestName);
    model.addTest (state.currentTest, state.currentCase);
    return;
  }

  match = passTestPattern.match (line);
  if (match.hasMatch ())
  {
    QString unrelated = match.captured(PassTestUnrelated);
    if (!unrelated.isEmpty()) {
      model.addTestDetail (state.currentTest, state.currentCase, unrelated);
    }
    ++state.passedCount;
    ++state.passedTotalCount;
    int totalTime = match.captured (PassTestTimeSpent).toInt ();
    model.updateTest (state.currentTest, state.currentCase, true, totalTime);
    state.currentTest.clear ();
    return;
  }

  match = failTestPattern.match (line);
  if (match.hasMatch ())
  {
    QString unrelated = match.captured(PassTestUnrelated);
    if (!unrelated.isEmpty()) {
      model.addTestDetail (state.currentTest, state.currentCase, unrelated);
    }
    ++state.failedCount;
    ++state.failedTotalCount;
    int totalTime = match.captured (FailTestTimeSpent).toInt ();
    model.updateTest (state.currentTest, state.currentCase, false, totalTime);
    QString parameterDetail = match.captured(FailTestParameterDetail);
    if (!parameterDetail.isEmpty()) {
      QString newTestName = state.currentTest + QString (QLatin1String(" <%1>")).arg (parameterDetail);
      model.renameTest (state.currentTest, newTestName, state.currentCase);
    }
    state.currentTest.clear ();
    return;
  }

  match = failDetailPattern.match (line);
  if (match.hasMatch ())
  {
    Q_ASSERT (!state.projectPath.isEmpty ());
    QString file = match.captured (FailDetailFileName);
    QFileInfo info (file);
    if (info.isRelative ())
    {
      file = state.projectPath + QLatin1Char ('/') + match.captured (FailDetailFileName);
    }
    int lineNumber = match.captured (FailDetailLine).toInt ();
    model.addTestError (state.currentTest, state.currentCase, line, file, lineNumber);
    return;
  }

  match = gtestEndPattern.match (line);
  if (match.hasMatch ())
  {
    state.totalTime = match.captured (GtestEndTimeSpent).toInt ();
    return;
  }

  match = gtestDisabledPattern.match (line);
  if (match.hasMatch ())
  {
    state.disabledCount = match.captured (GtestDisabledCount).toInt ();
    return;
  }

  match = gtestFilterPattern.match (line);
  if (match.hasMatch ())
  {
    model.addNote(match.captured (GtestFilterLine));
    return;
  }

  if (!state.currentTest.isEmpty ())
  {
    Q_ASSERT (!state.currentCase.isEmpty ());
    model.addTestDetail (state.currentTest, state.currentCase, line);
  }
}
<|endoftext|>


<commit_before>#ifndef _SMRH_
#define _SMRH_

#include <list>
#include <vector>
#include <algorithm>
#include <atomic>

template<typename T>
class HazardPointer
{
public:
  struct HazardPointerRecord
  {
    std::vector<std::atomic<T *>> hp;
    std::list<T *> rlist;
    std::atomic<bool> active;
    HazardPointerRecord *next;
  };

  void subscribe();
  void unsubscribe();
  T *get_pointer(const int &index);
  void delete_node(const T *node);

  HazardPointer(int a) : nbpointers(a), nbhp(0), head(NULL){};
  ~HazardPointer(){};

private:
  inline HazardPointer<T>::HazardPointerRecord *get_myhp();
  inline unsigned int get_batch_size();
  void scan();
  void help_scan();

  std::atomic<HazardPointerRecord*> head;
  std::atomic<int> nbhp;
  int nbpointers;
};

#endif
<commit_msg>[IMP] HazardPointer porting<commit_after>#ifndef _SMRH_
#define _SMRH_

#include <list>
#include <vector>
#include <algorithm>
#include <atomic>

template<typename T>
class HazardPointer
{
public:
  struct HazardPointerRecord
  {
    std::vector<std::atomic<T *>> hp;
    std::list<T *> rlist;
    std::atomic<bool> active;
    HazardPointerRecord *next;
  };

  void subscribe();
  void unsubscribe();
  T *get_pointer(const int &index);
  void delete_node(const T *node);

  HazardPointer(int a) : nbpointers(a), nbhp(0), head(nullptr){};
  ~HazardPointer(){};

private:
  inline HazardPointer<T>::HazardPointerRecord *get_myhp();
  inline unsigned int get_batch_size();
  void scan();
  void help_scan();

  std::atomic<HazardPointerRecord*> head;
  std::atomic<int> nbhp;
  int nbpointers;
};

#endif
<|endoftext|>


<commit_before>#include "rendermanager.hpp"

#include <lib/core/log.hpp>

#include "transformation.hpp"
#include "renderstates.hpp"
#include "rendernode.hpp"
#include "camera.hpp"

#include <lib/drivers/render/rendertarget.hpp>
#include <lib/core/appcontroller.hpp>
#include <lib/core/driver.hpp>
#include <SFML/Graphics/Shader.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/VertexArray.hpp>

namespace lib
{
	namespace draw
	{

		RenderManager::RenderManager()
		{
			LOG_CONSTRUCT_NOPARAMS;
		}

		RenderManager::~RenderManager()
		{
			LOG_DESTRUCT_NOPARAMS;
		}

		void RenderManager::Init()
		{
			AppService::Init();
		}

		void RenderManager::startFrame(sptr<drivers::render::RenderTarget> renderTarget, sptr<Camera> camera)
		{
			m_renderTarget = renderTarget;
			m_camera = camera;
			m_renderTarget->setView(m_camera->view(), m_camera->getViewport());
		}

		void RenderManager::finishFrame()
		{
			for (const RenderNode*node : m_renderList)
			{
				m_renderTarget->draw(node);
			}

			m_renderList.clear();

		}

		void RenderManager::preRenderNode(const sptr<RenderNode> &node)
		{
//			m_renderTarget->draw(node);

			m_renderList.push_back(node.get());
		}
	}
}
<commit_msg>Small speed up<commit_after>#include "rendermanager.hpp"

#include <lib/core/log.hpp>

#include "transformation.hpp"
#include "renderstates.hpp"
#include "rendernode.hpp"
#include "camera.hpp"

#include <lib/drivers/render/rendertarget.hpp>
#include <lib/core/appcontroller.hpp>
#include <lib/core/driver.hpp>
#include <SFML/Graphics/Shader.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/VertexArray.hpp>

namespace lib
{
	namespace draw
	{

		RenderManager::RenderManager()
		{
			LOG_CONSTRUCT_NOPARAMS;
		}

		RenderManager::~RenderManager()
		{
			LOG_DESTRUCT_NOPARAMS;
		}

		void RenderManager::Init()
		{
			AppService::Init();
		}

		void RenderManager::startFrame(sptr<drivers::render::RenderTarget> renderTarget, sptr<Camera> camera)
		{
			m_renderTarget = renderTarget;
			m_camera = camera;
		}

		void RenderManager::finishFrame()
		{
			lib::drivers::render::RenderTarget *renderTarget{ m_renderTarget.get() };
			renderTarget->setView(m_camera->view(), m_camera->getViewport());
			for (const RenderNode*node : m_renderList)
			{
				renderTarget->draw(node);
			}

			m_renderList.clear();
		}

		void RenderManager::preRenderNode(const sptr<RenderNode> &node)
		{
//			m_renderTarget->draw(node);
			m_renderList.push_back(node.get());
		}
	}
}
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include <mysql/mysql.h>

sstring fmt::doFormat(const sstring &fmt, const char *x)
{
  unsigned int MY_MAX_STRING_LENGTH=MAX_STRING_LENGTH * 2;
  char buf[MY_MAX_STRING_LENGTH];
  char to[MY_MAX_STRING_LENGTH];
  sstring fmtq=fmt;

  if(fmt[1] == 'q'){
    fmtq[1]='s';
    mysql_escape_string(to, x, strlen(x));

    snprintf(buf, MY_MAX_STRING_LENGTH, fmtq.c_str(), to);
  } else if(fmt[1] == 'x'){
    fmtq[1]='s';
    sstring oBuf=x;
    oBuf=oBuf.replaceString("&", "&");
    oBuf=oBuf.replaceString("<", "<");
    oBuf=oBuf.replaceString(">", ">");

    // styles
    oBuf=oBuf.replaceString(VT_BOLDTEX, "");
    oBuf=oBuf.replaceString(ANSI_UNDER, "");
    oBuf=oBuf.replaceString(VT_INVERTT, "");
    oBuf=oBuf.replaceString(ANSI_FLASH, "");

    // colors
    oBuf=oBuf.replaceString(ANSI_WHITE, "");
    oBuf=oBuf.replaceString(ANSI_BLACK, "");
    oBuf=oBuf.replaceString(ANSI_RED, "");
    oBuf=oBuf.replaceString(ANSI_NORMAL, "");
    oBuf=oBuf.replaceString(ANSI_BLUE, "");
    oBuf=oBuf.replaceString(ANSI_CYAN, "");
    oBuf=oBuf.replaceString(ANSI_GREEN, "");
    oBuf=oBuf.replaceString(ANSI_ORANGE, "");
    oBuf=oBuf.replaceString(ANSI_PURPLE, "");

    // colors with styles
    oBuf=oBuf.replaceString(ANSI_RED_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_GREEN_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_ORANGE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_YELLOW_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_BLUE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_PURPLE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_CYAN_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_WHITE_BOLD,
			    "");

    // colors with background
    oBuf=oBuf.replaceString(ANSI_BK_ON_BK,
			    "");
    oBuf=oBuf.replaceString(ANSI_BK_ON_WH,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_BL,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_CY,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_GR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_OR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_PR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_RD,
			    "");

    snprintf(buf, MY_MAX_STRING_LENGTH, fmtq.c_str(), oBuf.c_str());
  } else {
    snprintf(buf, MY_MAX_STRING_LENGTH, fmt.c_str(), x);
  }

  if(strlen(buf) == MY_MAX_STRING_LENGTH - 1){
    vlogf(LOG_BUG, "fmt::doFormat(): buffer reached MAX_STRING_LENGTH");

    // can't use fmt here of course
    vlogf(LOG_BUG, sstring("fmt::doFormat(): buffer=")+
	  sstring(buf).substr(70));
  }

  return (sstring) buf;
}

sstring fmt::doFormat(const sstring &fmt, const sstring &x)
{
  return doFormat(fmt, x.c_str());
}

sstring fmt::doFormat(const sstring &fmt, const string &x)
{
  return doFormat(fmt, x.c_str());
}

<commit_msg>fixed minor color code typo<commit_after>#include "stdsneezy.h"
#include <mysql/mysql.h>

sstring fmt::doFormat(const sstring &fmt, const char *x)
{
  unsigned int MY_MAX_STRING_LENGTH=MAX_STRING_LENGTH * 2;
  char buf[MY_MAX_STRING_LENGTH];
  char to[MY_MAX_STRING_LENGTH];
  sstring fmtq=fmt;

  if(fmt[1] == 'q'){
    fmtq[1]='s';
    mysql_escape_string(to, x, strlen(x));

    snprintf(buf, MY_MAX_STRING_LENGTH, fmtq.c_str(), to);
  } else if(fmt[1] == 'x'){
    fmtq[1]='s';
    sstring oBuf=x;
    oBuf=oBuf.replaceString("&", "&");
    oBuf=oBuf.replaceString("<", "<");
    oBuf=oBuf.replaceString(">", ">");

    // styles
    oBuf=oBuf.replaceString(VT_BOLDTEX, "");
    oBuf=oBuf.replaceString(ANSI_UNDER, "");
    oBuf=oBuf.replaceString(VT_INVERTT, "");
    oBuf=oBuf.replaceString(ANSI_FLASH, "");

    // colors
    oBuf=oBuf.replaceString(ANSI_WHITE, "");
    oBuf=oBuf.replaceString(ANSI_BLACK, "");
    oBuf=oBuf.replaceString(ANSI_RED, "");
    oBuf=oBuf.replaceString(ANSI_NORMAL, "");
    oBuf=oBuf.replaceString(ANSI_BLUE, "");
    oBuf=oBuf.replaceString(ANSI_CYAN, "");
    oBuf=oBuf.replaceString(ANSI_GREEN, "");
    oBuf=oBuf.replaceString(ANSI_ORANGE, "");
    oBuf=oBuf.replaceString(ANSI_PURPLE, "");

    // colors with styles
    oBuf=oBuf.replaceString(ANSI_RED_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_GREEN_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_ORANGE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_YELLOW_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_BLUE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_PURPLE_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_CYAN_BOLD,
			    "");
    oBuf=oBuf.replaceString(ANSI_WHITE_BOLD,
			    "");

    // colors with background
    oBuf=oBuf.replaceString(ANSI_BK_ON_BK,
			    "");
    oBuf=oBuf.replaceString(ANSI_BK_ON_WH,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_BL,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_CY,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_GR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_OR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_PR,
			    "");
    oBuf=oBuf.replaceString(ANSI_WH_ON_RD,
			    "");

    snprintf(buf, MY_MAX_STRING_LENGTH, fmtq.c_str(), oBuf.c_str());
  } else {
    snprintf(buf, MY_MAX_STRING_LENGTH, fmt.c_str(), x);
  }

  if(strlen(buf) == MY_MAX_STRING_LENGTH - 1){
    vlogf(LOG_BUG, "fmt::doFormat(): buffer reached MAX_STRING_LENGTH");

    // can't use fmt here of course
    vlogf(LOG_BUG, sstring("fmt::doFormat(): buffer=")+
	  sstring(buf).substr(70));
  }

  return (sstring) buf;
}

sstring fmt::doFormat(const sstring &fmt, const sstring &x)
{
  return doFormat(fmt, x.c_str());
}

sstring fmt::doFormat(const sstring &fmt, const string &x)
{
  return doFormat(fmt, x.c_str());
}

<|endoftext|>


<commit_before>#include <vector>
#include <thread>
#include <chrono>
#include <cstring>
#include <iostream>
#include <Poco/Net/StreamSocket.h>

#include "SimplePocoHandler.h"

namespace
{
    class Buffer
    {
    public:
        Buffer(size_t size) :
                m_data(size, 0),
                m_use(0)
        {
        }

        size_t write(const char* data, size_t size)
        {
            if (m_use == m_data.size())
            {
                return 0;
            }

            const size_t length = (size + m_use);
            size_t write =
                    length < m_data.size() ? size : m_data.size() - m_use;
            memcpy(m_data.data() + m_use, data, write);
            m_use += write;
            return write;
        }

        void drain()
        {
            m_use = 0;
        }

        size_t available() const
        {
            return m_use;
        }

        const char* data() const
        {
            return m_data.data();
        }

    private:
        std::vector<char> m_data;
        size_t m_use;
    };

}

struct SimplePocoHandlerImpl
{
    SimplePocoHandlerImpl() :
            connected(false),
            connection(nullptr),
            quit(false),
            inputBuffer(SimplePocoHandler::BUFFER_SIZE),
            outBuffer(SimplePocoHandler::BUFFER_SIZE),
            tmpBuff(SimplePocoHandler::TEMP_BUFFER_SIZE)
    {
    }

    Poco::Net::StreamSocket socket;
    bool connected;
    AMQP::Connection* connection;
    bool quit;
    Buffer inputBuffer;
    Buffer outBuffer;
    std::vector<char> tmpBuff;
};
SimplePocoHandler::SimplePocoHandler(const std::string& host, uint16_t port) :
        m_impl(new SimplePocoHandlerImpl)
{
    const Poco::Net::SocketAddress address(host, port);
    m_impl->socket.connect(address);
    m_impl->socket.setKeepAlive(true);
}

SimplePocoHandler::~SimplePocoHandler()
{
    close();
}

void SimplePocoHandler::loop()
{
    try
    {
        while (!m_impl->quit)
        {
            if (m_impl->socket.available() > 0)
            {
                size_t avail = m_impl->socket.available();
                if(m_impl->tmpBuff.size()<avail)
                {
                    m_impl->tmpBuff.resize(avail,0);
                }

                m_impl->socket.receiveBytes(&m_impl->tmpBuff[0], avail);
                m_impl->inputBuffer.write(m_impl->tmpBuff.data(), avail);

            }
            if(m_impl->socket.available()<0)
            {
                std::cerr<<"SOME socket error!!!"<<std::endl;
            }

            if (m_impl->connection && m_impl->inputBuffer.available())
            {
                size_t count = m_impl->connection->parse(m_impl->inputBuffer.data(),
                        m_impl->inputBuffer.available());

                if (count == m_impl->inputBuffer.available())
                {
                    m_impl->inputBuffer.drain();
                }
            }
            sendDataFromBuffer();

            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }

        if (m_impl->quit && m_impl->outBuffer.available())
        {
            sendDataFromBuffer();
        }

    } catch (const Poco::Exception& exc)
    {
        std::cerr<< "Poco exception " << exc.displayText();
    }
}

void SimplePocoHandler::quit()
{
    m_impl->quit = true;
}

void SimplePocoHandler::SimplePocoHandler::close()
{
    m_impl->socket.close();
}

void SimplePocoHandler::onData(
        AMQP::Connection *connection, const char *data, size_t size)
{
    m_impl->connection = connection;
    const size_t writen = m_impl->outBuffer.write(data, size);
    if (writen != size)
    {
        sendDataFromBuffer();
        m_impl->outBuffer.write(data + writen, size - writen);
    }
}

void SimplePocoHandler::onConnected(AMQP::Connection *connection)
{
    m_impl->connected = true;
}

void SimplePocoHandler::onError(
        AMQP::Connection *connection, const char *message)
{
    std::cerr<<"AMQP error "<<message<<std::endl;
}

void SimplePocoHandler::onClosed(AMQP::Connection *connection)
{
    std::cout<<"AMQP closed connection"<<std::endl;
    m_impl->quit  = true;
}

bool SimplePocoHandler::connected() const
{
    return m_impl->connected;
}

void SimplePocoHandler::sendDataFromBuffer()
{
    if (m_impl->outBuffer.available())
    {
        m_impl->socket.sendBytes(m_impl->outBuffer.data(), m_impl->outBuffer.available());
        m_impl->outBuffer.drain();
    }
}

<commit_msg>fix parse <commit_after>#include <vector>
#include <thread>
#include <chrono>
#include <cstring>
#include <cassert>
#include <iostream>
#include <Poco/Net/StreamSocket.h>

#include "SimplePocoHandler.h"

namespace
{
    class Buffer
    {
    public:
        Buffer(size_t size) :
                m_data(size, 0),
                m_use(0)
        {
        }

        size_t write(const char* data, size_t size)
        {
            if (m_use == m_data.size())
            {
                return 0;
            }

            const size_t length = (size + m_use);
            size_t write =
                    length < m_data.size() ? size : m_data.size() - m_use;
            memcpy(m_data.data() + m_use, data, write);
            m_use += write;
            return write;
        }

        void drain()
        {
            m_use = 0;
        }

        size_t available() const
        {
            return m_use;
        }

        const char* data() const
        {
            return m_data.data();
        }

        void shl(size_t count)
        {
            assert(count<m_use);
            const size_t diff = m_use - count;
            std::memmove(m_data.data(), m_data.data()+count, diff);
            m_use -= diff;
        }

    private:
        std::vector<char> m_data;
        size_t m_use;
    };
}

struct SimplePocoHandlerImpl
{
    SimplePocoHandlerImpl() :
            connected(false),
            connection(nullptr),
            quit(false),
            inputBuffer(SimplePocoHandler::BUFFER_SIZE),
            outBuffer(SimplePocoHandler::BUFFER_SIZE),
            tmpBuff(SimplePocoHandler::TEMP_BUFFER_SIZE)
    {
    }

    Poco::Net::StreamSocket socket;
    bool connected;
    AMQP::Connection* connection;
    bool quit;
    Buffer inputBuffer;
    Buffer outBuffer;
    std::vector<char> tmpBuff;
};
SimplePocoHandler::SimplePocoHandler(const std::string& host, uint16_t port) :
        m_impl(new SimplePocoHandlerImpl)
{
    const Poco::Net::SocketAddress address(host, port);
    m_impl->socket.connect(address);
    m_impl->socket.setKeepAlive(true);
}

SimplePocoHandler::~SimplePocoHandler()
{
    close();
}

void SimplePocoHandler::loop()
{
    try
    {
        while (!m_impl->quit)
        {
            if (m_impl->socket.available() > 0)
            {
                size_t avail = m_impl->socket.available();
                if(m_impl->tmpBuff.size()<avail)
                {
                    m_impl->tmpBuff.resize(avail,0);
                }

                m_impl->socket.receiveBytes(&m_impl->tmpBuff[0], avail);
                m_impl->inputBuffer.write(m_impl->tmpBuff.data(), avail);

            }
            if(m_impl->socket.available()<0)
            {
                std::cerr<<"SOME socket error!!!"<<std::endl;
            }

            if (m_impl->connection && m_impl->inputBuffer.available())
            {
                size_t count = m_impl->connection->parse(m_impl->inputBuffer.data(),
                        m_impl->inputBuffer.available());

                if (count == m_impl->inputBuffer.available())
                {
                    m_impl->inputBuffer.drain();
                } else if(count >0 ){
                    m_impl->inputBuffer.shl(count);
                }
            }
            sendDataFromBuffer();

            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }

        if (m_impl->quit && m_impl->outBuffer.available())
        {
            sendDataFromBuffer();
        }

    } catch (const Poco::Exception& exc)
    {
        std::cerr<< "Poco exception " << exc.displayText();
    }
}

void SimplePocoHandler::quit()
{
    m_impl->quit = true;
}

void SimplePocoHandler::SimplePocoHandler::close()
{
    m_impl->socket.close();
}

void SimplePocoHandler::onData(
        AMQP::Connection *connection, const char *data, size_t size)
{
    m_impl->connection = connection;
    const size_t writen = m_impl->outBuffer.write(data, size);
    if (writen != size)
    {
        sendDataFromBuffer();
        m_impl->outBuffer.write(data + writen, size - writen);
    }
}

void SimplePocoHandler::onConnected(AMQP::Connection *connection)
{
    m_impl->connected = true;
}

void SimplePocoHandler::onError(
        AMQP::Connection *connection, const char *message)
{
    std::cerr<<"AMQP error "<<message<<std::endl;
}

void SimplePocoHandler::onClosed(AMQP::Connection *connection)
{
    std::cout<<"AMQP closed connection"<<std::endl;
    m_impl->quit  = true;
}

bool SimplePocoHandler::connected() const
{
    return m_impl->connected;
}

void SimplePocoHandler::sendDataFromBuffer()
{
    if (m_impl->outBuffer.available())
    {
        m_impl->socket.sendBytes(m_impl->outBuffer.data(), m_impl->outBuffer.available());
        m_impl->outBuffer.drain();
    }
}

<|endoftext|>


<commit_before>#include "Graphics.h"

Graphics::Graphics()
{
}

Graphics::~Graphics()
{
	//switch to windowed mode
	m_SwapChain->SetFullscreenState(FALSE, NULL);

	RELEASEMACRO(m_SwapChain);
	RELEASEMACRO(m_BackBuffer);

	//Restore default device settings
	if (m_DevCon)
		m_DevCon->ClearState();

	RELEASEMACRO(m_DevCon);
	RELEASEMACRO(m_Dev);
}

ID3D11Device* Graphics::getDevicePtr()
{
	return m_Dev;
}

bool Graphics::InitD3D(HWND hWnd, int screenWidth, int screenHeight)
{
	bool result;

	//Initialize Direct3D

	//create and set default values in the struct
	DXGI_SWAP_CHAIN_DESC scd;
	ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

	//fill the struct

	//number of back buffers
	scd.BufferCount = 1;
	//save color format to 32-bit (8bits per channel/value) color
	scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	//back buffer screen width
	scd.BufferDesc.Width = screenWidth;
	//back buffer screen height
	scd.BufferDesc.Height = screenHeight;
	//how the swap chain is to be used
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	//the window to use
	scd.OutputWindow = hWnd;
	//MSAA number
	scd.SampleDesc.Count = 4;
	//to use windowed mode
	scd.Windowed = true;
	//allows fullscreen switching using Alt + Enter
	//scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	//method(lets machine decide graphics adapter, use hardware or software
		//used to set software code, flags,feature levels list, number in feature levels list,
		//SDK version, double pointer to swap chain description,
		//double pointer to swap chain, double pointer to device,
		//pointer to feature level var, double pointer to device context)
	result = D3D11CreateDeviceAndSwapChain(
		NULL,
		D3D_DRIVER_TYPE_HARDWARE,
		NULL,
		NULL,
		NULL,
		NULL,
		D3D11_SDK_VERSION,
		&scd,
		&m_SwapChain,
		&m_Dev,
		NULL,
		&m_DevCon);

	if (FAILED(result))
		return false;

	//Set the render target

	//create a texture using the back buffer
	ID3D11Texture2D* texture2D;
	m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&texture2D);

	//create a render target object (backBuffer)
	m_Dev->CreateRenderTargetView(texture2D, NULL, &m_BackBuffer);
	texture2D->Release();

	//sets the render target as the back buffer
	m_DevCon->OMSetRenderTargets(1, &m_BackBuffer, NULL);

	//Set the viewport
	D3D11_VIEWPORT viewport;
	ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = screenWidth;
	viewport.Height = screenHeight;

	m_DevCon->RSSetViewports(1, &viewport);

	return true;
}

void Graphics::RenderFrame()
{
	//clear the back buffer to a blue
	const FLOAT backColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
	m_DevCon->ClearRenderTargetView(m_BackBuffer, backColor);

	//do 3D rendering here

	//switch the back buffer and the front buffer
	m_SwapChain->Present(0, 0);
}

bool Graphics::compileShader(ShaderInfo* shader)
{
	HRESULT result = S_OK;

	ID3DBlob* compiledShaderBlob = NULL;
	ID3DBlob* errorMessagesBlob = NULL;

	const char* loadedFile = loadTextFile(shader->file);

	//if something happens and it doesn't read in the file
	if (loadedFile == NULL)
	{
		//write the problem to the console and return 0
		printf("PROBLEM: Loaded File returned NULL\n");
		return false;
	}

	//might have to do strlen()+1
	if ( FAILED( result = D3DCompile(
		(LPCVOID)loadedFile,
		strlen(loadedFile),
		NULL,
		NULL,
		NULL,
		shader->shaderType,
		shader->shaderVersion,
		NULL,
		NULL,
		&compiledShaderBlob,
		&errorMessagesBlob ) ) )
		return false;

	//shader reflection code below

	ID3D11ShaderReflection* shaderReflection = nullptr;
	if(FAILED(result = D3DReflect(compiledShaderBlob->GetBufferPointer(), compiledShaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&shaderReflection)));

	return true;
}

//http://stackoverflow.com/questions/27220/how-to-convert-stdstring-to-lpcwstr-in-c-unicode
//going to go through this more indepth
<commit_msg>Removed a comment.<commit_after>#include "Graphics.h"

Graphics::Graphics()
{
}

Graphics::~Graphics()
{
	//switch to windowed mode
	m_SwapChain->SetFullscreenState(FALSE, NULL);

	RELEASEMACRO(m_SwapChain);
	RELEASEMACRO(m_BackBuffer);

	//Restore default device settings
	if (m_DevCon)
		m_DevCon->ClearState();

	RELEASEMACRO(m_DevCon);
	RELEASEMACRO(m_Dev);
}

ID3D11Device* Graphics::getDevicePtr()
{
	return m_Dev;
}

bool Graphics::InitD3D(HWND hWnd, int screenWidth, int screenHeight)
{
	bool result;

	//Initialize Direct3D

	//create and set default values in the struct
	DXGI_SWAP_CHAIN_DESC scd;
	ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

	//fill the struct

	//number of back buffers
	scd.BufferCount = 1;
	//save color format to 32-bit (8bits per channel/value) color
	scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	//back buffer screen width
	scd.BufferDesc.Width = screenWidth;
	//back buffer screen height
	scd.BufferDesc.Height = screenHeight;
	//how the swap chain is to be used
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	//the window to use
	scd.OutputWindow = hWnd;
	//MSAA number
	scd.SampleDesc.Count = 4;
	//to use windowed mode
	scd.Windowed = true;
	//allows fullscreen switching using Alt + Enter
	//scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	//method(lets machine decide graphics adapter, use hardware or software
		//used to set software code, flags,feature levels list, number in feature levels list,
		//SDK version, double pointer to swap chain description,
		//double pointer to swap chain, double pointer to device,
		//pointer to feature level var, double pointer to device context)
	result = D3D11CreateDeviceAndSwapChain(
		NULL,
		D3D_DRIVER_TYPE_HARDWARE,
		NULL,
		NULL,
		NULL,
		NULL,
		D3D11_SDK_VERSION,
		&scd,
		&m_SwapChain,
		&m_Dev,
		NULL,
		&m_DevCon);

	if (FAILED(result))
		return false;

	//Set the render target

	//create a texture using the back buffer
	ID3D11Texture2D* texture2D;
	m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&texture2D);

	//create a render target object (backBuffer)
	m_Dev->CreateRenderTargetView(texture2D, NULL, &m_BackBuffer);
	texture2D->Release();

	//sets the render target as the back buffer
	m_DevCon->OMSetRenderTargets(1, &m_BackBuffer, NULL);

	//Set the viewport
	D3D11_VIEWPORT viewport;
	ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = screenWidth;
	viewport.Height = screenHeight;

	m_DevCon->RSSetViewports(1, &viewport);

	return true;
}

void Graphics::RenderFrame()
{
	//clear the back buffer to a blue
	const FLOAT backColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
	m_DevCon->ClearRenderTargetView(m_BackBuffer, backColor);

	//do 3D rendering here

	//switch the back buffer and the front buffer
	m_SwapChain->Present(0, 0);
}

bool Graphics::compileShader(ShaderInfo* shader)
{
	HRESULT result = S_OK;

	ID3DBlob* compiledShaderBlob = NULL;
	ID3DBlob* errorMessagesBlob = NULL;

	const char* loadedFile = loadTextFile(shader->file);

	//if something happens and it doesn't read in the file
	if (loadedFile == NULL)
	{
		//write the problem to the console and return 0
		printf("PROBLEM: Loaded File returned NULL\n");
		return false;
	}

	//might have to do strlen()+1
	if ( FAILED( result = D3DCompile(
		(LPCVOID)loadedFile,
		strlen(loadedFile),
		NULL,
		NULL,
		NULL,
		shader->shaderType,
		shader->shaderVersion,
		NULL,
		NULL,
		&compiledShaderBlob,
		&errorMessagesBlob ) ) )
		return false;

	//shader reflection code below

	ID3D11ShaderReflection* shaderReflection = nullptr;
	if(FAILED(result = D3DReflect(compiledShaderBlob->GetBufferPointer(), compiledShaderBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&shaderReflection)));

	return true;
}

//http://stackoverflow.com/questions/27220/how-to-convert-stdstring-to-lpcwstr-in-c-unicode
<|endoftext|>


<commit_before>/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 "xmppclient.h"
#include "xmpptask.h"
#include "talk/xmpp/xmppconstants.h"
#include "talk/base/sigslot.h"
#include "talk/xmpp/saslplainmechanism.h"
#include "talk/xmpp/saslhandler.h"
#include "talk/xmpp/prexmppauth.h"
#include "talk/base/scoped_ptr.h"
#include "talk/xmpp/plainsaslhandler.h"

namespace buzz {

talk_base::Task* XmppClient::GetParent(int code) {
  if (code == XMPP_CLIENT_TASK_CODE)
    return this;
  else
    return talk_base::Task::GetParent(code);
}

class XmppClient::Private :
    public sigslot::has_slots<>,
    public XmppSessionHandler,
    public XmppOutputHandler {
public:

  Private(XmppClient * client) :
    client_(client),
    socket_(NULL),
    engine_(NULL),
    proxy_port_(0),
    pre_engine_error_(XmppEngine::ERROR_NONE),
    pre_engine_subcode_(0),
    signal_closed_(false),
    allow_plain_(false) {}

  // the owner
  XmppClient * const client_;

  // the two main objects
  scoped_ptr<AsyncSocket> socket_;
  scoped_ptr<XmppEngine> engine_;
  scoped_ptr<PreXmppAuth> pre_auth_;
  scoped_ptr<SaslHandler> sasl_handler_;
  talk_base::CryptString pass_;
  std::string auth_cookie_;
  talk_base::SocketAddress server_;
  std::string proxy_host_;
  int proxy_port_;
  XmppEngine::Error pre_engine_error_;
  int pre_engine_subcode_;
  CaptchaChallenge captcha_challenge_;
  bool signal_closed_;
  bool allow_plain_;

  // implementations of interfaces
  void OnStateChange(int state);
  void WriteOutput(const char * bytes, size_t len);
  void StartTls(const std::string & domainname);
  void CloseConnection();

  // slots for socket signals
  void OnSocketConnected();
  void OnSocketRead();
  void OnSocketClosed();
};

XmppReturnStatus
XmppClient::Connect(const XmppClientSettings & settings,
                    const std::string & lang,
                    AsyncSocket * socket,
                    PreXmppAuth * pre_auth,
                    SaslHandler * sasl_handler) {
  if (socket == NULL)
    return XMPP_RETURN_BADARGUMENT;
  if (d_->socket_.get() != NULL)
    return XMPP_RETURN_BADSTATE;

  d_->socket_.reset(socket);

  d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
  d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
  d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);

  d_->engine_.reset(XmppEngine::Create());
  d_->engine_->SetSessionHandler(d_.get());
  d_->engine_->SetOutputHandler(d_.get());
  if (!settings.resource().empty()) {
    d_->engine_->SetRequestedResource(settings.resource());
  }
  d_->engine_->SetUseTls(settings.use_tls());

  //
  // The talk.google.com server expects you to use "gmail.com" in the
  // stream, and expects the domain certificate to be "gmail.com" as well.
  // For all other servers, we leave the strings empty, which causes
  // the jid's domain to be used.  "foo@example.com" -> stream to="example.com"
  // tls certificate for "example.com"
  //
  // This is only true when using Gaia auth, so let's say if there's no preauth,
  // we should use the actual server name
  if ((settings.server().IPAsString() == buzz::STR_TALK_GOOGLE_COM ||
      settings.server().IPAsString() == buzz::STR_TALKX_L_GOOGLE_COM) &&
      pre_auth != NULL) {
    d_->engine_->SetTlsServer(buzz::STR_GMAIL_COM, buzz::STR_GMAIL_COM);
  }

  // Set language
  d_->engine_->SetLanguage(lang);

  d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY));

  d_->pass_ = settings.pass();
  d_->auth_cookie_ = settings.auth_cookie();
  d_->server_ = settings.server();
  d_->proxy_host_ = settings.proxy_host();
  d_->proxy_port_ = settings.proxy_port();
  d_->allow_plain_ = settings.allow_plain();
  d_->pre_auth_.reset(pre_auth);
  d_->sasl_handler_.reset(sasl_handler);

  return XMPP_RETURN_OK;
}

XmppEngine::State
XmppClient::GetState() {
  if (d_->engine_.get() == NULL)
    return XmppEngine::STATE_NONE;
  return d_->engine_->GetState();
}

XmppEngine::Error
XmppClient::GetError(int *subcode) {
  if (subcode) {
    *subcode = 0;
  }
  if (d_->engine_.get() == NULL)
    return XmppEngine::ERROR_NONE;
  if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
    if (subcode) {
      *subcode = d_->pre_engine_subcode_;
    }
    return d_->pre_engine_error_;
  }
  return d_->engine_->GetError(subcode);
}

const XmlElement *
XmppClient::GetStreamError() {
  if (d_->engine_.get() == NULL) {
    return NULL;
  }
  return d_->engine_->GetStreamError();
}

CaptchaChallenge XmppClient::GetCaptchaChallenge() {
  if (d_->engine_.get() == NULL)
    return CaptchaChallenge();
  return d_->captcha_challenge_;
}

std::string
XmppClient::GetAuthCookie() {
  if (d_->engine_.get() == NULL)
    return "";
  return d_->auth_cookie_;
}

static void
ForgetPassword(std::string & to_erase) {
  size_t len = to_erase.size();
  for (size_t i = 0; i < len; i++) {
    // get rid of characters
    to_erase[i] = 'x';
  }
  // get rid of length
  to_erase.erase();
}

int
XmppClient::ProcessStart() {
  if (d_->sasl_handler_.get()) {
    d_->engine_->SetSaslHandler(d_->sasl_handler_.release());
  }
  else {
    d_->engine_->SetSaslHandler(new PlainSaslHandler(
        d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
  }

  if (d_->pre_auth_.get()) {
    d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
    d_->pre_auth_->StartPreXmppAuth(
        d_->engine_->GetUser(), d_->server_, d_->pass_, d_->auth_cookie_);
    d_->pass_.Clear(); // done with this;
    return STATE_PRE_XMPP_LOGIN;
  }
  else {
    d_->pass_.Clear(); // done with this;
    return STATE_START_XMPP_LOGIN;
  }
}

void
XmppClient::OnAuthDone() {
  Wake();
}

int
XmppClient::ProcessCookieLogin() {
  // Don't know how this could happen, but crash reports show it as NULL
  if (!d_->pre_auth_.get()) {
    d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
    EnsureClosed();
    return STATE_ERROR;
  }

  // Wait until pre authentication is done is done
  if (!d_->pre_auth_->IsAuthDone())
    return STATE_BLOCKED;

  if (!d_->pre_auth_->IsAuthorized()) {
    // maybe split out a case when gaia is down?
    if (d_->pre_auth_->HadError()) {
      d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
      d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
    }
    else {
      d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
      d_->pre_engine_subcode_ = 0;
      d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
    }
    d_->pre_auth_.reset(NULL); // done with this
    EnsureClosed();
    return STATE_ERROR;
  }

  // Save auth cookie as a result
  d_->auth_cookie_ = d_->pre_auth_->GetAuthCookie();

  return STATE_START_XMPP_LOGIN;
}

int
XmppClient::ProcessStartXmppLogin() {
  // Done with pre-connect tasks - connect!
  if (!d_->socket_->Connect(d_->server_)) {
    d_->pre_engine_error_ = XmppEngine::ERROR_SOCKET;
    d_->pre_engine_subcode_ = d_->socket_->GetError();
    EnsureClosed();
    return STATE_ERROR;
  }

  return STATE_RESPONSE;
}

int
XmppClient::ProcessResponse() {
  // Hang around while we are connected.
  if (!delivering_signal_ && (d_->engine_.get() == NULL ||
    d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
    return STATE_DONE;
  return STATE_BLOCKED;
}

XmppReturnStatus
XmppClient::Disconnect() {
  if (d_->socket_.get() == NULL)
    return XMPP_RETURN_BADSTATE;
  d_->engine_->Disconnect();
  return XMPP_RETURN_OK;
}

XmppClient::XmppClient(Task * parent)
    : Task(parent),
      delivering_signal_(false),
      valid_(false) {
  d_.reset(new Private(this));
  valid_ = true;
}

XmppClient::~XmppClient() {
  valid_ = false;
}

const Jid &
XmppClient::jid() {
  return d_->engine_->FullJid();
}

std::string
XmppClient::NextId() {
  return d_->engine_->NextId();
}

XmppReturnStatus
XmppClient::SendStanza(const XmlElement * stanza) {
  return d_->engine_->SendStanza(stanza);
}

XmppReturnStatus
XmppClient::SendStanzaError(const XmlElement * old_stanza, XmppStanzaError xse, const std::string & message) {
  return d_->engine_->SendStanzaError(old_stanza, xse, message);
}

XmppReturnStatus
XmppClient::SendRaw(const std::string & text) {
  return d_->engine_->SendRaw(text);
}

XmppEngine*
XmppClient::engine() {
  return d_->engine_.get();
}

void
XmppClient::Private::OnSocketConnected() {
  engine_->Connect();
}

void
XmppClient::Private::OnSocketRead() {
  char bytes[4096];
  size_t bytes_read;
  for (;;) {
    if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
      // TODO: deal with error information
      return;
    }

    if (bytes_read == 0)
      return;

//#if !defined(NDEBUG)
    client_->SignalLogInput(bytes, bytes_read);
//#endif

    engine_->HandleInput(bytes, bytes_read);
  }
}

void
XmppClient::Private::OnSocketClosed() {
  int code = socket_->GetError();
  engine_->ConnectionClosed(code);
}

void
XmppClient::Private::OnStateChange(int state) {
  if (state == XmppEngine::STATE_CLOSED) {
    client_->EnsureClosed();
  }
  else {
    client_->SignalStateChange((XmppEngine::State)state);
  }
  client_->Wake();
}

void
XmppClient::Private::WriteOutput(const char * bytes, size_t len) {

//#if !defined(NDEBUG)
  client_->SignalLogOutput(bytes, len);
//#endif

  socket_->Write(bytes, len);
  // TODO: deal with error information
}

void
XmppClient::Private::StartTls(const std::string & domain) {
#if defined(FEATURE_ENABLE_SSL)
  socket_->StartTls(domain);
#endif
}

void
XmppClient::Private::CloseConnection() {
  socket_->Close();
}

void
XmppClient::AddXmppTask(XmppTask * task, XmppEngine::HandlerLevel level) {
  d_->engine_->AddStanzaHandler(task, level);
}

void
XmppClient::RemoveXmppTask(XmppTask * task) {
  d_->engine_->RemoveStanzaHandler(task);
}

void
XmppClient::EnsureClosed() {
  if (!d_->signal_closed_) {
    d_->signal_closed_ = true;
    delivering_signal_ = true;
    SignalStateChange(XmppEngine::STATE_CLOSED);
    delivering_signal_ = false;
  }
}

}
<commit_msg>Quick fix for a problem introduced by 41865 which causes sync notifications to break for non-gmail.com accounts.<commit_after>/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 "xmppclient.h"
#include "xmpptask.h"
#include "talk/xmpp/xmppconstants.h"
#include "talk/base/sigslot.h"
#include "talk/xmpp/saslplainmechanism.h"
#include "talk/xmpp/saslhandler.h"
#include "talk/xmpp/prexmppauth.h"
#include "talk/base/scoped_ptr.h"
#include "talk/xmpp/plainsaslhandler.h"

namespace buzz {

talk_base::Task* XmppClient::GetParent(int code) {
  if (code == XMPP_CLIENT_TASK_CODE)
    return this;
  else
    return talk_base::Task::GetParent(code);
}

class XmppClient::Private :
    public sigslot::has_slots<>,
    public XmppSessionHandler,
    public XmppOutputHandler {
public:

  Private(XmppClient * client) :
    client_(client),
    socket_(NULL),
    engine_(NULL),
    proxy_port_(0),
    pre_engine_error_(XmppEngine::ERROR_NONE),
    pre_engine_subcode_(0),
    signal_closed_(false),
    allow_plain_(false) {}

  // the owner
  XmppClient * const client_;

  // the two main objects
  scoped_ptr<AsyncSocket> socket_;
  scoped_ptr<XmppEngine> engine_;
  scoped_ptr<PreXmppAuth> pre_auth_;
  scoped_ptr<SaslHandler> sasl_handler_;
  talk_base::CryptString pass_;
  std::string auth_cookie_;
  talk_base::SocketAddress server_;
  std::string proxy_host_;
  int proxy_port_;
  XmppEngine::Error pre_engine_error_;
  int pre_engine_subcode_;
  CaptchaChallenge captcha_challenge_;
  bool signal_closed_;
  bool allow_plain_;

  // implementations of interfaces
  void OnStateChange(int state);
  void WriteOutput(const char * bytes, size_t len);
  void StartTls(const std::string & domainname);
  void CloseConnection();

  // slots for socket signals
  void OnSocketConnected();
  void OnSocketRead();
  void OnSocketClosed();
};

XmppReturnStatus
XmppClient::Connect(const XmppClientSettings & settings,
                    const std::string & lang,
                    AsyncSocket * socket,
                    PreXmppAuth * pre_auth,
                    SaslHandler * sasl_handler) {
  if (socket == NULL)
    return XMPP_RETURN_BADARGUMENT;
  if (d_->socket_.get() != NULL)
    return XMPP_RETURN_BADSTATE;

  d_->socket_.reset(socket);

  d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
  d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
  d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);

  d_->engine_.reset(XmppEngine::Create());
  d_->engine_->SetSessionHandler(d_.get());
  d_->engine_->SetOutputHandler(d_.get());
  if (!settings.resource().empty()) {
    d_->engine_->SetRequestedResource(settings.resource());
  }
  d_->engine_->SetUseTls(settings.use_tls());

  //
  // The talk.google.com server expects you to use "gmail.com" in the
  // stream, and expects the domain certificate to be "gmail.com" as well.
  // For all other servers, we leave the strings empty, which causes
  // the jid's domain to be used.  "foo@example.com" -> stream to="example.com"
  // tls certificate for "example.com"
  //
  // This is only true when using Gaia auth, so let's say if there's
  // no sasl_handler, we should use the actual server name
  // TODO(akalin): Do this in a less hackish way.
  if ((settings.server().IPAsString() == buzz::STR_TALK_GOOGLE_COM ||
      settings.server().IPAsString() == buzz::STR_TALKX_L_GOOGLE_COM) &&
      sasl_handler != NULL) {
    d_->engine_->SetTlsServer(buzz::STR_GMAIL_COM, buzz::STR_GMAIL_COM);
  }

  // Set language
  d_->engine_->SetLanguage(lang);

  d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY));

  d_->pass_ = settings.pass();
  d_->auth_cookie_ = settings.auth_cookie();
  d_->server_ = settings.server();
  d_->proxy_host_ = settings.proxy_host();
  d_->proxy_port_ = settings.proxy_port();
  d_->allow_plain_ = settings.allow_plain();
  d_->pre_auth_.reset(pre_auth);
  d_->sasl_handler_.reset(sasl_handler);

  return XMPP_RETURN_OK;
}

XmppEngine::State
XmppClient::GetState() {
  if (d_->engine_.get() == NULL)
    return XmppEngine::STATE_NONE;
  return d_->engine_->GetState();
}

XmppEngine::Error
XmppClient::GetError(int *subcode) {
  if (subcode) {
    *subcode = 0;
  }
  if (d_->engine_.get() == NULL)
    return XmppEngine::ERROR_NONE;
  if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
    if (subcode) {
      *subcode = d_->pre_engine_subcode_;
    }
    return d_->pre_engine_error_;
  }
  return d_->engine_->GetError(subcode);
}

const XmlElement *
XmppClient::GetStreamError() {
  if (d_->engine_.get() == NULL) {
    return NULL;
  }
  return d_->engine_->GetStreamError();
}

CaptchaChallenge XmppClient::GetCaptchaChallenge() {
  if (d_->engine_.get() == NULL)
    return CaptchaChallenge();
  return d_->captcha_challenge_;
}

std::string
XmppClient::GetAuthCookie() {
  if (d_->engine_.get() == NULL)
    return "";
  return d_->auth_cookie_;
}

static void
ForgetPassword(std::string & to_erase) {
  size_t len = to_erase.size();
  for (size_t i = 0; i < len; i++) {
    // get rid of characters
    to_erase[i] = 'x';
  }
  // get rid of length
  to_erase.erase();
}

int
XmppClient::ProcessStart() {
  if (d_->sasl_handler_.get()) {
    d_->engine_->SetSaslHandler(d_->sasl_handler_.release());
  }
  else {
    d_->engine_->SetSaslHandler(new PlainSaslHandler(
        d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
  }

  if (d_->pre_auth_.get()) {
    d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
    d_->pre_auth_->StartPreXmppAuth(
        d_->engine_->GetUser(), d_->server_, d_->pass_, d_->auth_cookie_);
    d_->pass_.Clear(); // done with this;
    return STATE_PRE_XMPP_LOGIN;
  }
  else {
    d_->pass_.Clear(); // done with this;
    return STATE_START_XMPP_LOGIN;
  }
}

void
XmppClient::OnAuthDone() {
  Wake();
}

int
XmppClient::ProcessCookieLogin() {
  // Don't know how this could happen, but crash reports show it as NULL
  if (!d_->pre_auth_.get()) {
    d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
    EnsureClosed();
    return STATE_ERROR;
  }

  // Wait until pre authentication is done is done
  if (!d_->pre_auth_->IsAuthDone())
    return STATE_BLOCKED;

  if (!d_->pre_auth_->IsAuthorized()) {
    // maybe split out a case when gaia is down?
    if (d_->pre_auth_->HadError()) {
      d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
      d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
    }
    else {
      d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
      d_->pre_engine_subcode_ = 0;
      d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
    }
    d_->pre_auth_.reset(NULL); // done with this
    EnsureClosed();
    return STATE_ERROR;
  }

  // Save auth cookie as a result
  d_->auth_cookie_ = d_->pre_auth_->GetAuthCookie();

  return STATE_START_XMPP_LOGIN;
}

int
XmppClient::ProcessStartXmppLogin() {
  // Done with pre-connect tasks - connect!
  if (!d_->socket_->Connect(d_->server_)) {
    d_->pre_engine_error_ = XmppEngine::ERROR_SOCKET;
    d_->pre_engine_subcode_ = d_->socket_->GetError();
    EnsureClosed();
    return STATE_ERROR;
  }

  return STATE_RESPONSE;
}

int
XmppClient::ProcessResponse() {
  // Hang around while we are connected.
  if (!delivering_signal_ && (d_->engine_.get() == NULL ||
    d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
    return STATE_DONE;
  return STATE_BLOCKED;
}

XmppReturnStatus
XmppClient::Disconnect() {
  if (d_->socket_.get() == NULL)
    return XMPP_RETURN_BADSTATE;
  d_->engine_->Disconnect();
  return XMPP_RETURN_OK;
}

XmppClient::XmppClient(Task * parent)
    : Task(parent),
      delivering_signal_(false),
      valid_(false) {
  d_.reset(new Private(this));
  valid_ = true;
}

XmppClient::~XmppClient() {
  valid_ = false;
}

const Jid &
XmppClient::jid() {
  return d_->engine_->FullJid();
}

std::string
XmppClient::NextId() {
  return d_->engine_->NextId();
}

XmppReturnStatus
XmppClient::SendStanza(const XmlElement * stanza) {
  return d_->engine_->SendStanza(stanza);
}

XmppReturnStatus
XmppClient::SendStanzaError(const XmlElement * old_stanza, XmppStanzaError xse, const std::string & message) {
  return d_->engine_->SendStanzaError(old_stanza, xse, message);
}

XmppReturnStatus
XmppClient::SendRaw(const std::string & text) {
  return d_->engine_->SendRaw(text);
}

XmppEngine*
XmppClient::engine() {
  return d_->engine_.get();
}

void
XmppClient::Private::OnSocketConnected() {
  engine_->Connect();
}

void
XmppClient::Private::OnSocketRead() {
  char bytes[4096];
  size_t bytes_read;
  for (;;) {
    if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
      // TODO: deal with error information
      return;
    }

    if (bytes_read == 0)
      return;

//#if !defined(NDEBUG)
    client_->SignalLogInput(bytes, bytes_read);
//#endif

    engine_->HandleInput(bytes, bytes_read);
  }
}

void
XmppClient::Private::OnSocketClosed() {
  int code = socket_->GetError();
  engine_->ConnectionClosed(code);
}

void
XmppClient::Private::OnStateChange(int state) {
  if (state == XmppEngine::STATE_CLOSED) {
    client_->EnsureClosed();
  }
  else {
    client_->SignalStateChange((XmppEngine::State)state);
  }
  client_->Wake();
}

void
XmppClient::Private::WriteOutput(const char * bytes, size_t len) {

//#if !defined(NDEBUG)
  client_->SignalLogOutput(bytes, len);
//#endif

  socket_->Write(bytes, len);
  // TODO: deal with error information
}

void
XmppClient::Private::StartTls(const std::string & domain) {
#if defined(FEATURE_ENABLE_SSL)
  socket_->StartTls(domain);
#endif
}

void
XmppClient::Private::CloseConnection() {
  socket_->Close();
}

void
XmppClient::AddXmppTask(XmppTask * task, XmppEngine::HandlerLevel level) {
  d_->engine_->AddStanzaHandler(task, level);
}

void
XmppClient::RemoveXmppTask(XmppTask * task) {
  d_->engine_->RemoveStanzaHandler(task);
}

void
XmppClient::EnsureClosed() {
  if (!d_->signal_closed_) {
    d_->signal_closed_ = true;
    delivering_signal_ = true;
    SignalStateChange(XmppEngine::STATE_CLOSED);
    delivering_signal_ = false;
  }
}

}
<|endoftext|>


<commit_before>#include "catch.hpp"

#include "../include/vector.h"

TEST_CASE("construct a new vector", "[vector]") {
    jade::vector<int> v;
    REQUIRE(v.size() == 0);
    REQUIRE(v.capacity() == 0);
}

TEST_CASE("copy construct a new vector", "[vector]") {
    jade::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);

    jade::vector<int> v2(v1);

    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 4);

    int k = 1;
    for (const auto& i : v2) {
        REQUIRE(k++ == i);
    }
}

TEST_CASE("assignment operator", "[vector]") {
    jade::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);

    REQUIRE(v1.size() == 2);
    REQUIRE(v1.capacity() == 2);

    jade::vector<int> v2;
    v2.push_back(3);
    v2.push_back(4);
    v2.push_back(5);

    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 4);

    v2 = v1;

    REQUIRE(v2.size() == 2);
    REQUIRE(v2.capacity() == 2);

    int k = 1;
    for (const auto& i : v2) {
        REQUIRE(k++ == i);
    }
}

TEST_CASE("move assignment operator", "[vector]") {
    jade::vector<int> v1{1,2,3};
    REQUIRE(v1.size() == 3);
    REQUIRE(v1.capacity() == 3);

    jade::vector<int> v2{4,5,6,7,8};
    REQUIRE(v2.size() == 5);
    REQUIRE(v2.capacity() == 5);

    v1 = std::move(v2);
    REQUIRE(v1.size() == 5);
    REQUIRE(v1.capacity() == 5);
    REQUIRE(v2.size() == 0);
    REQUIRE(v2.capacity() == 0);
}

TEST_CASE("initializer list assginment operator") {
    jade::vector<int> v{1,2,3};
    REQUIRE(v.size() == 3);
    REQUIRE(v.capacity() == 3);
    REQUIRE(v[0] == 1);
    REQUIRE(v[1] == 2);
    REQUIRE(v[2] == 3);

    v = {4,5,6,7};
    REQUIRE(v.size() == 4);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v[0] == 4);
    REQUIRE(v[1] == 5);
    REQUIRE(v[2] == 6);
    REQUIRE(v[3] == 7);
}

TEST_CASE("capacity doubles everytime the size increases to the current max. capacity", "[vector]") {
    jade::vector<int> v;
    v.push_back(1);
    REQUIRE(v.size() == 1);
    REQUIRE(v.capacity() == 1);
    v.push_back(2);
    REQUIRE(v.size() == 2);
    REQUIRE(v.capacity() == 2);
    v.push_back(3);
    REQUIRE(v.size() == 3);
    REQUIRE(v.capacity() == 4);
    v.push_back(4);
    REQUIRE(v.size() == 4);
    REQUIRE(v.capacity() == 4);
    v.push_back(5);
    REQUIRE(v.size() == 5);
    REQUIRE(v.capacity() == 8);
    v.push_back(6);
    v.push_back(7);
    v.push_back(8);
    REQUIRE(v.size() == 8);
    REQUIRE(v.capacity() == 8);
    v.push_back(9);
    REQUIRE(v.size() == 9);
    REQUIRE(v.capacity() == 16);
}

TEST_CASE("constructor with initializer list", "[vector]") {
    jade::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    REQUIRE(v.capacity() == 9);
    REQUIRE(v.size() == 9);
    REQUIRE(v[0] == 1);
    REQUIRE(v[1] == 2);
    REQUIRE(v[2] == 3);
    REQUIRE(v[3] == 4);
    REQUIRE(v[4] == 5);
    REQUIRE(v[5] == 6);
    REQUIRE(v[6] == 7);
    REQUIRE(v[7] == 8);
    REQUIRE(v[8] == 9);
}

TEST_CASE("vector can be constructed with a number copies of elements with a certain value", "[vector]") {
    SECTION("default-inserted instances of T", "[vector]") {
        jade::vector<int> v1(50);
        REQUIRE(v1.capacity() == 50);
        REQUIRE(v1.size() == 50);
        for (const auto i : v1) {
            REQUIRE(i == 0);
        }
    }
    SECTION("copies of provided value", "[vector]") {
        jade::vector<int> v1(50, 123);
        REQUIRE(v1.capacity() == 50);
        REQUIRE(v1.size() == 50);
        for (const auto i : v1) {
            REQUIRE(i == 123);
        }
    }
}

TEST_CASE("move constructor", "[vector]") {
    jade::vector<int> v1 = { 1, 2, 3 };
    REQUIRE(v1.size() == 3);
    REQUIRE(v1.capacity() == 3);

    jade::vector<int> v2{std::move(v1)};
    REQUIRE(v1.size() == 0);
    REQUIRE(v1.capacity() == 0);
    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 3);
}

TEST_CASE("a vector is resizable", "[vector]") {
    jade::vector<int> v;
    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 0);
}

TEST_CASE("a new vector is resizable to zero", "[vector]") {
    jade::vector<int> v;
    v.resize(0);
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);
}

TEST_CASE("resizing a vector keeps it consistent", "[vector]") {
    jade::vector<int> v;
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v.size() == 3);

    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 3);

    v.resize(0);
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v.size() == 3);

    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 3);
}

TEST_CASE("at method checks bounds of vector", "[vector]") {
    jade::vector<int> v = { 1, 2, 3, 4, 5 };
    REQUIRE_THROWS_AS(v.at(-1), std::out_of_range);
    REQUIRE_NOTHROW(v.at(0));
    REQUIRE_NOTHROW(v.at(2));
    REQUIRE_NOTHROW(v.at(4));
    REQUIRE_THROWS_AS(v.at(5), std::out_of_range);
}
<commit_msg>more testing for assignments with initializer lists<commit_after>#include "catch.hpp"

#include "../include/vector.h"

TEST_CASE("construct a new vector", "[vector]") {
    jade::vector<int> v;
    REQUIRE(v.size() == 0);
    REQUIRE(v.capacity() == 0);
}

TEST_CASE("copy construct a new vector", "[vector]") {
    jade::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);

    jade::vector<int> v2(v1);

    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 4);

    int k = 1;
    for (const auto& i : v2) {
        REQUIRE(k++ == i);
    }
}

TEST_CASE("assignment operator", "[vector]") {
    jade::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);

    REQUIRE(v1.size() == 2);
    REQUIRE(v1.capacity() == 2);

    jade::vector<int> v2;
    v2.push_back(3);
    v2.push_back(4);
    v2.push_back(5);

    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 4);

    v2 = v1;

    REQUIRE(v2.size() == 2);
    REQUIRE(v2.capacity() == 2);

    int k = 1;
    for (const auto& i : v2) {
        REQUIRE(k++ == i);
    }
}

TEST_CASE("move assignment operator", "[vector]") {
    jade::vector<int> v1{1,2,3};
    REQUIRE(v1.size() == 3);
    REQUIRE(v1.capacity() == 3);

    jade::vector<int> v2{4,5,6,7,8};
    REQUIRE(v2.size() == 5);
    REQUIRE(v2.capacity() == 5);

    v1 = std::move(v2);
    REQUIRE(v1.size() == 5);
    REQUIRE(v1.capacity() == 5);
    REQUIRE(v2.size() == 0);
    REQUIRE(v2.capacity() == 0);
}

TEST_CASE("initializer list assginment operator") {
    jade::vector<int> v{1,2,3};
    REQUIRE(v.size() == 3);
    REQUIRE(v.capacity() == 3);
    REQUIRE(v[0] == 1);
    REQUIRE(v[1] == 2);
    REQUIRE(v[2] == 3);

    v = {4,5,6,7};
    REQUIRE(v.size() == 4);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v[0] == 4);
    REQUIRE(v[1] == 5);
    REQUIRE(v[2] == 6);
    REQUIRE(v[3] == 7);

    v = {};
    REQUIRE(v.size() == 0);
    REQUIRE(v.capacity() == 0);
}

TEST_CASE("capacity doubles everytime the size increases to the current max. capacity", "[vector]") {
    jade::vector<int> v;
    v.push_back(1);
    REQUIRE(v.size() == 1);
    REQUIRE(v.capacity() == 1);
    v.push_back(2);
    REQUIRE(v.size() == 2);
    REQUIRE(v.capacity() == 2);
    v.push_back(3);
    REQUIRE(v.size() == 3);
    REQUIRE(v.capacity() == 4);
    v.push_back(4);
    REQUIRE(v.size() == 4);
    REQUIRE(v.capacity() == 4);
    v.push_back(5);
    REQUIRE(v.size() == 5);
    REQUIRE(v.capacity() == 8);
    v.push_back(6);
    v.push_back(7);
    v.push_back(8);
    REQUIRE(v.size() == 8);
    REQUIRE(v.capacity() == 8);
    v.push_back(9);
    REQUIRE(v.size() == 9);
    REQUIRE(v.capacity() == 16);
}

TEST_CASE("constructor with initializer list", "[vector]") {
    jade::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    REQUIRE(v.capacity() == 9);
    REQUIRE(v.size() == 9);
    REQUIRE(v[0] == 1);
    REQUIRE(v[1] == 2);
    REQUIRE(v[2] == 3);
    REQUIRE(v[3] == 4);
    REQUIRE(v[4] == 5);
    REQUIRE(v[5] == 6);
    REQUIRE(v[6] == 7);
    REQUIRE(v[7] == 8);
    REQUIRE(v[8] == 9);
}

TEST_CASE("vector can be constructed with a number copies of elements with a certain value", "[vector]") {
    SECTION("default-inserted instances of T", "[vector]") {
        jade::vector<int> v1(50);
        REQUIRE(v1.capacity() == 50);
        REQUIRE(v1.size() == 50);
        for (const auto i : v1) {
            REQUIRE(i == 0);
        }
    }
    SECTION("copies of provided value", "[vector]") {
        jade::vector<int> v1(50, 123);
        REQUIRE(v1.capacity() == 50);
        REQUIRE(v1.size() == 50);
        for (const auto i : v1) {
            REQUIRE(i == 123);
        }
    }
}

TEST_CASE("move constructor", "[vector]") {
    jade::vector<int> v1 = { 1, 2, 3 };
    REQUIRE(v1.size() == 3);
    REQUIRE(v1.capacity() == 3);

    jade::vector<int> v2{std::move(v1)};
    REQUIRE(v1.size() == 0);
    REQUIRE(v1.capacity() == 0);
    REQUIRE(v2.size() == 3);
    REQUIRE(v2.capacity() == 3);
}

TEST_CASE("a vector is resizable", "[vector]") {
    jade::vector<int> v;
    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 0);
}

TEST_CASE("a new vector is resizable to zero", "[vector]") {
    jade::vector<int> v;
    v.resize(0);
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);
}

TEST_CASE("resizing a vector keeps it consistent", "[vector]") {
    jade::vector<int> v;
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v.size() == 3);

    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 3);

    v.resize(0);
    REQUIRE(v.capacity() == 0);
    REQUIRE(v.size() == 0);

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    REQUIRE(v.capacity() == 4);
    REQUIRE(v.size() == 3);

    v.resize(16);
    REQUIRE(v.capacity() == 16);
    REQUIRE(v.size() == 3);
}

TEST_CASE("at method checks bounds of vector", "[vector]") {
    jade::vector<int> v = { 1, 2, 3, 4, 5 };
    REQUIRE_THROWS_AS(v.at(-1), std::out_of_range);
    REQUIRE_NOTHROW(v.at(0));
    REQUIRE_NOTHROW(v.at(2));
    REQUIRE_NOTHROW(v.at(4));
    REQUIRE_THROWS_AS(v.at(5), std::out_of_range);
}
<|endoftext|>


<commit_before>#include "Common.h"
#include "Engine.h"

CCommon::CCommon(void)
{

}

CCommon::~CCommon(void)
{

}

vec3 CCommon::GetTransformDirection(const mat4& matTransform, const vec3& vUP)
{
	return MakeRotationFromYZ(matTransform.getColumn3(1), vUP) * vec3(0.0f, -1.0f, 0.0f);
}

int CCommon::GetIntersectionPosition(vec3& vRetPoint, const vec3& p0, const vec3& p1, int nMask /*= 2|4*/)
{
	vec3 n;
	int s;

	g_Engine.pWorld->GetIntersection(p0, p1, nMask, vRetPoint, n, s);

	return s >= 0;
}

int CCommon::GetIntersectionObject(CBRObject** vRetObject, const vec3& p0, const vec3& p1, int nMask /*= 2|4*/)
{

}

float CCommon::CalcAxisScale(const mat4& modelview, float fov, vec4 objectPosW, float sizeInPixels, float viewHeight)
{

}<commit_msg>vector set<commit_after>#include "Common.h"
#include "Engine.h"

CCommon::CCommon(void)
{

}

CCommon::~CCommon(void)
{

}

vec3 CCommon::GetTransformDirection(const mat4& matTransform, const vec3& vUP)
{
	return MakeRotationFromYZ(matTransform.getColumn3(1), vUP) * vec3(0.0f, -1.0f, 0.0f);
}

int CCommon::GetIntersectionPosition(vec3& vRetPoint, const vec3& p0, const vec3& p1, int nMask /*= 2|4*/)
{
	vec3 n;
	int s;

	g_Engine.pWorld->GetIntersection(p0, p1, nMask, vRetPoint, n, s);

	return s >= 0;
}

int CCommon::GetIntersectionObject(CBRObject** vRetObject, const vec3& p0, const vec3& p1, int nMask /*= 2|4*/)
{
	vec3 p, n;
	int s;
	*vRetObject = g_Engine.pWorld->GetIntersection(p0, p1, nMask, p, n, s);

	return s >= 0;
}

float CCommon::CalcAxisScale(const mat4& modelview, float fov, vec4 objectPosW, float sizeInPixels, float viewHeight)
{
	float worldHeight;
	// World height on origin's z value
	vec4 objPosV;
	objPosV = modelview * objectPosW;
	worldHeight = 2.0f * CMathCore::Abs(objPosV.z) * (float)CMathCore::Tan(fov / 2.0f * DEG2RAD);

	return sizeInPixels * (worldHeight / viewHeight);
}<|endoftext|>


<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "DeclarationVisitor.h"

#include "VisitorDefs.h"

#include "OOModel/src/declarations/Project.h"
#include "OOModel/src/declarations/NameImport.h"

#include "Export/src/tree/SourceDir.h"
#include "Export/src/tree/SourceFile.h"
#include "Export/src/tree/CompositeFragment.h"
#include "Export/src/tree/TextFragment.h"

using namespace Export;
using namespace OOModel;

namespace JavaExport {

SourceFragment* DeclarationVisitor::visit(Declaration* declaration)
{
	if (auto castDeclaration = DCast<Method>(declaration)) return visit(castDeclaration);
	if (auto castDeclaration = DCast<Class>(declaration)) return visit(castDeclaration);
	if (auto castDeclaration = DCast<VariableDeclaration>(declaration)) return visit(castDeclaration);

	notAllowed(declaration);

	// TODO: handle comments
	auto fragment = new CompositeFragment(declaration);
	*fragment << "Invalid Declaration";
	return fragment;
}

SourceDir* DeclarationVisitor::visitProject(Project* project, SourceDir* parent)
{
	auto projectDir = parent ? &parent->subDir(project->name()) : new SourceDir(nullptr, "src");

	if (parent) packageStack().append(project->name());

	for (auto node : *project->projects()) visitProject(node, projectDir);
	for (auto node : *project->modules()) visitModule(node, projectDir);
	for (auto node : *project->classes()) visitTopLevelClass(node, projectDir);

	if (parent) packageStack().removeLast();

	notAllowed(project->methods());
	notAllowed(project->fields());

	return projectDir;
}

SourceDir* DeclarationVisitor::visitModule(Module* module, SourceDir* parent)
{
	Q_ASSERT(parent);
	auto moduleDir = &parent->subDir(module->name());

	packageStack().append(module->name());

	for (auto node : *module->modules()) visitModule(node, moduleDir);
	for (auto node : *module->classes()) visitTopLevelClass(node, moduleDir);

	packageStack().removeLast();

	notAllowed(module->methods());
	notAllowed(module->fields());

	return moduleDir;
}

SourceFile* DeclarationVisitor::visitTopLevelClass(Class* classs, SourceDir* parent)
{
	Q_ASSERT(parent);
	auto classFile = &parent->file(classs->name() + ".java");

	auto fragment = classFile->append(new CompositeFragment(classs, "sections"));

	auto header = fragment->append(new CompositeFragment(classs));
	if (!packageStack().isEmpty())
		*header << "package " << packagesSoFar() << ";";

	auto imports = fragment->append(new CompositeFragment(classs, "vertical"));
	for (auto node : *classs->subDeclarations())
	{
		if (auto ni = DCast<NameImport>(node)) *imports << visit(ni);
		else notAllowed(node);
	}

	*fragment << visit(classs);

	return classFile;
}

SourceFragment* DeclarationVisitor::visit(Class* classs)
{
	auto fragment = new CompositeFragment(classs);
	if (Class::ConstructKind::Class == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "class " << classs->nameNode();
	else if (Class::ConstructKind::Interface == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "interface " << classs->nameNode();
	else if (Class::ConstructKind::Enum == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "enum " << classs->nameNode();
	else // TODO: how to handle annotations?
		notAllowed(classs);

	if (!classs->typeArguments()->isEmpty())
		*fragment << list(classs->typeArguments(), ElementVisitor(data()), "typeArgsList");

	if (!classs->baseClasses()->isEmpty())
	{
		*fragment << " extends ";
		*fragment << expression(classs->baseClasses()->at(0));

		if (classs->baseClasses()->size() > 1)
		{
			*fragment << " implements ";
			int i = 1;
			for (; i < classs->baseClasses()->size() - 1; ++i)
				*fragment << expression(classs->baseClasses()->at(i)) << ", ";
			*fragment << expression(classs->baseClasses()->at(i));
		}
	}

	notAllowed(classs->friends());

	//TODO
	auto sections = fragment->append( new CompositeFragment(classs, "bodySections"));
	*sections << list(classs->methods(), this, "sections");
	*sections << list(classs->fields(), this, "vertical");

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(Method* method)
{
	auto fragment = new CompositeFragment(method);
	*fragment << printAnnotationsAndModifiers(method);

	if (method->results()->size() > 1)
		error(method->results(), "Cannot have more than one return value in Java");

	if (!method->results()->isEmpty())
		*fragment << expression(method->results()->at(0)->typeExpression()) << " ";
	else if (method->methodKind() != Method::MethodKind::Constructor)
		*fragment << "void ";

	if (method->methodKind() == Method::MethodKind::Destructor)
		error(method, "Can not have a method of type Destructor in Java");

	*fragment << method->nameNode();

	if (!method->typeArguments()->isEmpty())
		*fragment << list(method->typeArguments(), ElementVisitor(data()), "typeArgsList");

	*fragment << list(method->arguments(), ElementVisitor(data()), "argsList");
	*fragment << list(method->items(), StatementVisitor(data()), "body");

	notAllowed(method->subDeclarations());
	notAllowed(method->memberInitializers());

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(VariableDeclaration* vd)
{
	auto fragment = new CompositeFragment(vd);
	*fragment << printAnnotationsAndModifiers(vd);
	*fragment << expression(vd->typeExpression()) << " " << vd->nameNode();
	if (vd->initialValue())
		*fragment << " = " << expression(vd->initialValue());

	if (!DCast<Expression>(vd->parent())) *fragment << ";";
	return fragment;
}

SourceFragment* DeclarationVisitor::visit(NameImport* nameImport)
{
	auto fragment = new CompositeFragment(nameImport);
	*fragment << printAnnotationsAndModifiers(nameImport);

	notAllowed(nameImport->annotations());

	*fragment << "import " << expression(nameImport->importedName());
	if (nameImport->importAll()) *fragment << ".*";
	*fragment << ";";

	return fragment;
}

SourceFragment* DeclarationVisitor::printAnnotationsAndModifiers(Declaration* declaration)
{
	auto fragment = new CompositeFragment(declaration, "vertical");
	if (!declaration->annotations()->isEmpty()) // avoid an extra new line if there are no annotations
		*fragment << list(declaration->annotations(), StatementVisitor(data()), "vertical");
	auto header = fragment->append(new CompositeFragment(declaration, "space"));

	if (declaration->modifiers()->isSet(Modifier::Public))
		*header << new TextFragment(declaration->modifiers(), "public");
	if (declaration->modifiers()->isSet(Modifier::Private))
		*header << new TextFragment(declaration->modifiers(), "private");
	if (declaration->modifiers()->isSet(Modifier::Protected))
		*header << new TextFragment(declaration->modifiers(), "protected");

	if (declaration->modifiers()->isSet(Modifier::Static))
		*header << new TextFragment(declaration->modifiers(), "static");

	if (declaration->modifiers()->isSet(Modifier::Final))
		*header << new TextFragment(declaration->modifiers(), "final");
	if (declaration->modifiers()->isSet(Modifier::Abstract))
		*header << new TextFragment(declaration->modifiers(), "abstract");

	if (declaration->modifiers()->isSet(Modifier::Virtual))
		error(declaration->modifiers(), "Virtual modifier is invalid in Java");
	if (declaration->modifiers()->isSet(Modifier::Override))
		error(declaration->modifiers(), "Override modifier is invalid in Java");
	if (declaration->modifiers()->isSet(Modifier::Inline))
		error(declaration->modifiers(), "Inline modifier is invalid in Java");

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(ExplicitTemplateInstantiation* eti)
{
	notAllowed(eti);
	return new TextFragment(eti);
}

SourceFragment* DeclarationVisitor::visit(TypeAlias* ta)
{
	notAllowed(ta);
	return new TextFragment(ta);
}

} /* namespace JavaExport */
<commit_msg>Export declarations in Class nodes as well<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2014 ETH Zurich
 ** All rights reserved.
 **
 ** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 ** following conditions are met:
 **
 **    * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 **      following disclaimer.
 **    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 **      following disclaimer in the documentation and/or other materials provided with the distribution.
 **    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
 **      derived from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 ** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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 "DeclarationVisitor.h"

#include "VisitorDefs.h"

#include "OOModel/src/declarations/Project.h"
#include "OOModel/src/declarations/NameImport.h"

#include "Export/src/tree/SourceDir.h"
#include "Export/src/tree/SourceFile.h"
#include "Export/src/tree/CompositeFragment.h"
#include "Export/src/tree/TextFragment.h"

using namespace Export;
using namespace OOModel;

namespace JavaExport {

SourceFragment* DeclarationVisitor::visit(Declaration* declaration)
{
	if (auto castDeclaration = DCast<Method>(declaration)) return visit(castDeclaration);
	if (auto castDeclaration = DCast<Class>(declaration)) return visit(castDeclaration);
	if (auto castDeclaration = DCast<VariableDeclaration>(declaration)) return visit(castDeclaration);

	notAllowed(declaration);

	// TODO: handle comments
	auto fragment = new CompositeFragment(declaration);
	*fragment << "Invalid Declaration";
	return fragment;
}

SourceDir* DeclarationVisitor::visitProject(Project* project, SourceDir* parent)
{
	auto projectDir = parent ? &parent->subDir(project->name()) : new SourceDir(nullptr, "src");

	if (parent) packageStack().append(project->name());

	for (auto node : *project->projects()) visitProject(node, projectDir);
	for (auto node : *project->modules()) visitModule(node, projectDir);
	for (auto node : *project->classes()) visitTopLevelClass(node, projectDir);

	if (parent) packageStack().removeLast();

	notAllowed(project->methods());
	notAllowed(project->fields());

	return projectDir;
}

SourceDir* DeclarationVisitor::visitModule(Module* module, SourceDir* parent)
{
	Q_ASSERT(parent);
	auto moduleDir = &parent->subDir(module->name());

	packageStack().append(module->name());

	for (auto node : *module->modules()) visitModule(node, moduleDir);
	for (auto node : *module->classes()) visitTopLevelClass(node, moduleDir);

	packageStack().removeLast();

	notAllowed(module->methods());
	notAllowed(module->fields());

	return moduleDir;
}

SourceFile* DeclarationVisitor::visitTopLevelClass(Class* classs, SourceDir* parent)
{
	Q_ASSERT(parent);
	auto classFile = &parent->file(classs->name() + ".java");

	auto fragment = classFile->append(new CompositeFragment(classs, "sections"));

	auto header = fragment->append(new CompositeFragment(classs));
	if (!packageStack().isEmpty())
		*header << "package " << packagesSoFar() << ";";

	auto imports = fragment->append(new CompositeFragment(classs, "vertical"));
	for (auto node : *classs->subDeclarations())
	{
		if (auto ni = DCast<NameImport>(node)) *imports << visit(ni);
		else notAllowed(node);
	}

	*fragment << visit(classs);

	return classFile;
}

SourceFragment* DeclarationVisitor::visit(Class* classs)
{
	auto fragment = new CompositeFragment(classs);
	if (Class::ConstructKind::Class == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "class " << classs->nameNode();
	else if (Class::ConstructKind::Interface == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "interface " << classs->nameNode();
	else if (Class::ConstructKind::Enum == classs->constructKind())
		*fragment << printAnnotationsAndModifiers(classs) << "enum " << classs->nameNode();
	else // TODO: how to handle annotations?
		notAllowed(classs);

	if (!classs->typeArguments()->isEmpty())
		*fragment << list(classs->typeArguments(), ElementVisitor(data()), "typeArgsList");

	if (!classs->baseClasses()->isEmpty())
	{
		*fragment << " extends ";
		*fragment << expression(classs->baseClasses()->at(0));

		if (classs->baseClasses()->size() > 1)
		{
			*fragment << " implements ";
			int i = 1;
			for (; i < classs->baseClasses()->size() - 1; ++i)
				*fragment << expression(classs->baseClasses()->at(i)) << ", ";
			*fragment << expression(classs->baseClasses()->at(i));
		}
	}

	notAllowed(classs->friends());

	//TODO
	auto sections = fragment->append( new CompositeFragment(classs, "bodySections"));
	*sections << list(classs->classes(), this, "declarations");
	*sections << list(classs->methods(), this, "sections");
	*sections << list(classs->fields(), this, "vertical");

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(Method* method)
{
	auto fragment = new CompositeFragment(method);
	*fragment << printAnnotationsAndModifiers(method);

	if (method->results()->size() > 1)
		error(method->results(), "Cannot have more than one return value in Java");

	if (!method->results()->isEmpty())
		*fragment << expression(method->results()->at(0)->typeExpression()) << " ";
	else if (method->methodKind() != Method::MethodKind::Constructor)
		*fragment << "void ";

	if (method->methodKind() == Method::MethodKind::Destructor)
		error(method, "Can not have a method of type Destructor in Java");

	*fragment << method->nameNode();

	if (!method->typeArguments()->isEmpty())
		*fragment << list(method->typeArguments(), ElementVisitor(data()), "typeArgsList");

	*fragment << list(method->arguments(), ElementVisitor(data()), "argsList");
	*fragment << list(method->items(), StatementVisitor(data()), "body");

	notAllowed(method->subDeclarations());
	notAllowed(method->memberInitializers());

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(VariableDeclaration* vd)
{
	auto fragment = new CompositeFragment(vd);
	*fragment << printAnnotationsAndModifiers(vd);
	*fragment << expression(vd->typeExpression()) << " " << vd->nameNode();
	if (vd->initialValue())
		*fragment << " = " << expression(vd->initialValue());

	if (!DCast<Expression>(vd->parent())) *fragment << ";";
	return fragment;
}

SourceFragment* DeclarationVisitor::visit(NameImport* nameImport)
{
	auto fragment = new CompositeFragment(nameImport);
	*fragment << printAnnotationsAndModifiers(nameImport);

	notAllowed(nameImport->annotations());

	*fragment << "import " << expression(nameImport->importedName());
	if (nameImport->importAll()) *fragment << ".*";
	*fragment << ";";

	return fragment;
}

SourceFragment* DeclarationVisitor::printAnnotationsAndModifiers(Declaration* declaration)
{
	auto fragment = new CompositeFragment(declaration, "vertical");
	if (!declaration->annotations()->isEmpty()) // avoid an extra new line if there are no annotations
		*fragment << list(declaration->annotations(), StatementVisitor(data()), "vertical");
	auto header = fragment->append(new CompositeFragment(declaration, "space"));

	if (declaration->modifiers()->isSet(Modifier::Public))
		*header << new TextFragment(declaration->modifiers(), "public");
	if (declaration->modifiers()->isSet(Modifier::Private))
		*header << new TextFragment(declaration->modifiers(), "private");
	if (declaration->modifiers()->isSet(Modifier::Protected))
		*header << new TextFragment(declaration->modifiers(), "protected");

	if (declaration->modifiers()->isSet(Modifier::Static))
		*header << new TextFragment(declaration->modifiers(), "static");

	if (declaration->modifiers()->isSet(Modifier::Final))
		*header << new TextFragment(declaration->modifiers(), "final");
	if (declaration->modifiers()->isSet(Modifier::Abstract))
		*header << new TextFragment(declaration->modifiers(), "abstract");

	if (declaration->modifiers()->isSet(Modifier::Virtual))
		error(declaration->modifiers(), "Virtual modifier is invalid in Java");
	if (declaration->modifiers()->isSet(Modifier::Override))
		error(declaration->modifiers(), "Override modifier is invalid in Java");
	if (declaration->modifiers()->isSet(Modifier::Inline))
		error(declaration->modifiers(), "Inline modifier is invalid in Java");

	return fragment;
}

SourceFragment* DeclarationVisitor::visit(ExplicitTemplateInstantiation* eti)
{
	notAllowed(eti);
	return new TextFragment(eti);
}

SourceFragment* DeclarationVisitor::visit(TypeAlias* ta)
{
	notAllowed(ta);
	return new TextFragment(ta);
}

} /* namespace JavaExport */
<|endoftext|>