<commit_before>//===--- TerminalDisplayWin.h - Output To Windows Console -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for writing to a Windows console
//  i.e. cmd.exe.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifdef _WIN32
#include "textinput/TerminalDisplayWin.h"
#include "textinput/Color.h"

#include <assert.h>

namespace textinput {
  TerminalDisplayWin::TerminalDisplayWin():
    TerminalDisplay(false), fStartLine(0), fIsAttached(false),
    fDefaultAttributes(0), fOldCodePage(::GetConsoleOutputCP()) {
    DWORD mode;
    SetIsTTY(::GetConsoleMode(::GetStdHandle(STD_INPUT_HANDLE), &mode) != 0);

    fOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
    bool isConsole = ::GetConsoleMode(fOut, &fOldMode) != 0;
    if (!isConsole) {
      // Prevent redirection from stealing our console handle,
      // simply open our own.
      fOut = ::CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, NULL);
      ::GetConsoleMode(fOut, &fOldMode);

      CONSOLE_SCREEN_BUFFER_INFO csbi;
      ::GetConsoleScreenBufferInfo(fOut, &csbi);
      fDefaultAttributes = csbi.wAttributes;
      assert(fDefaultAttributes != 0 && "~TerminalDisplayWin broken");
    } else
      ::SetConsoleOutputCP(65001); // Force UTF-8 output
    fMyMode = fOldMode | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
    HandleResizeEvent();
  }

  TerminalDisplayWin::~TerminalDisplayWin() {
    if (fDefaultAttributes) {
      ::SetConsoleTextAttribute(fOut, fDefaultAttributes);
      // We allocated CONOUT$:
      CloseHandle(fOut);
    } else
      ::SetConsoleOutputCP(fOldCodePage);
  }

  void
  TerminalDisplayWin::HandleResizeEvent() {
    if (IsTTY()) {
      CONSOLE_SCREEN_BUFFER_INFO Info;
      if (!::GetConsoleScreenBufferInfo(fOut, &Info)) {
        ShowError("resize / getting console info");
        return;
      }
      SetWidth(Info.dwSize.X);
    }
  }

  void
  TerminalDisplayWin::SetColor(char CIdx, const Color& C) {
    WORD Attribs = 0;
    // There is no underline since DOS has died.
    if (C.fModifiers & Color::kModUnderline) Attribs |= BACKGROUND_INTENSITY;
    if (C.fModifiers & Color::kModBold) Attribs |= FOREGROUND_INTENSITY;
    if (C.fR > 64) Attribs |= FOREGROUND_RED;
    if (C.fG > 64) Attribs |= FOREGROUND_GREEN;
    if (C.fB > 64) Attribs |= FOREGROUND_BLUE;
    // if CIdx is 0 (default) then use the original console text color
    // (instead of the greyish one)
    if (CIdx == 0)
      ::SetConsoleTextAttribute(fOut, fDefaultAttributes);
    else
      ::SetConsoleTextAttribute(fOut, Attribs);
  }

  void
  TerminalDisplayWin::CheckCursorPos() {
    if (!IsTTY()) return;
    // Did something print something on the screen?
    // I.e. did the cursor move?
    CONSOLE_SCREEN_BUFFER_INFO CSI;
    if (::GetConsoleScreenBufferInfo(fOut, &CSI)) {
      if (CSI.dwCursorPosition.X != fWritePos.fCol
        || CSI.dwCursorPosition.Y != fWritePos.fLine + fStartLine) {
        fStartLine = CSI.dwCursorPosition.Y;
        if (CSI.dwCursorPosition.X) {
          // fStartLine may be a couple of lines higher (or more precisely
          // the number of written lines higher)
          fStartLine -= fWritePos.fLine;
        }
        fWritePos.fCol = 0;
        fWritePos.fLine = 0;
      }
    }
  }

  void
  TerminalDisplayWin::Move(Pos P) {
    CheckCursorPos();
    MoveInternal(P);
    fWritePos = P;
  }

  void
  TerminalDisplayWin::MoveInternal(Pos P) {
    if (IsTTY()) {
      COORD C = {P.fCol, P.fLine + fStartLine};
      ::SetConsoleCursorPosition(fOut, C);
    }
  }

  void
  TerminalDisplayWin::MoveFront() {
    Pos P(fWritePos);
    P.fCol = 0;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveUp(size_t nLines /* = 1 */) {
    Pos P(fWritePos);
    --P.fLine;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveDown(size_t nLines /* = 1 */) {
    Pos P(fWritePos);
    ++P.fLine;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveRight(size_t nCols /* = 1 */) {
    Pos P(fWritePos);
    ++P.fCol;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveLeft(size_t nCols /* = 1 */) {
    Pos P(fWritePos);
    --P.fCol;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::EraseToRight() {
    DWORD NumWritten;
    COORD C = {fWritePos.fCol, fWritePos.fLine + fStartLine};
    ::FillConsoleOutputCharacterA(fOut, ' ', GetWidth() - C.X, C,
      &NumWritten);
    // It wraps, so move up and reset WritePos:
    //MoveUp();
    //++WritePos.Line;
  }

  void
  TerminalDisplayWin::WriteRawString(const char *text, size_t len) {
    DWORD NumWritten = 0;
    if (IsTTY()) {
      WriteConsoleA(fOut, text, (DWORD) len, &NumWritten, NULL);
    } else {
      WriteFile(fOut, text, (DWORD) len, &NumWritten, NULL);
    }
    if (NumWritten != len) {
      ShowError("writing to output");
    }
  }

  void
  TerminalDisplayWin::Attach() {
    // set to noecho
    if (fIsAttached || !IsTTY()) return;
    if (!::SetConsoleMode(fOut, fMyMode)) {
      ShowError("attaching to console output");
    }
    CONSOLE_SCREEN_BUFFER_INFO Info;
    if (!::GetConsoleScreenBufferInfo(fOut, &Info)) {
      ShowError("attaching / getting console info");
    } else {
      fStartLine = Info.dwCursorPosition.Y;
      if (Info.dwCursorPosition.X) {
        // Whooa - where are we?! Newline and cross fingers:
        WriteRawString("\n", 1);
        ++fStartLine;
      }
    }
    fIsAttached = true;
  }

  void
  TerminalDisplayWin::Detach() {
    if (!fIsAttached || !IsTTY()) return;
    if (!SetConsoleMode(fOut, fOldMode)) {
      ShowError("detaching to console output");
    }
    TerminalDisplay::Detach();
    fIsAttached = false;
  }

  void
  TerminalDisplayWin::ShowError(const char* Where) const {
    DWORD Err = GetLastError();
    LPVOID MsgBuf = 0;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR) &MsgBuf, 0, NULL);

    printf("Error %d in textinput::TerminalDisplayWin %s: %s\n", Err, Where, MsgBuf);
    LocalFree(MsgBuf);
  }

}

#endif // ifdef _WIN32
<commit_msg>Fix uninitialized fDefaultAttributes (makes terminal black on black)<commit_after>//===--- TerminalDisplayWin.h - Output To Windows Console -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for writing to a Windows console
//  i.e. cmd.exe.
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#ifdef _WIN32
#include "textinput/TerminalDisplayWin.h"
#include "textinput/Color.h"

#include <assert.h>

namespace textinput {
  TerminalDisplayWin::TerminalDisplayWin():
    TerminalDisplay(false), fStartLine(0), fIsAttached(false),
    fDefaultAttributes(0), fOldCodePage(::GetConsoleOutputCP()) {
    DWORD mode;
    SetIsTTY(::GetConsoleMode(::GetStdHandle(STD_INPUT_HANDLE), &mode) != 0);

    fOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
    bool isConsole = ::GetConsoleMode(fOut, &fOldMode) != 0;
    if (!isConsole) {
      // Prevent redirection from stealing our console handle,
      // simply open our own.
      fOut = ::CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, NULL);
      ::GetConsoleMode(fOut, &fOldMode);
    } else
      ::SetConsoleOutputCP(65001); // Force UTF-8 output
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    ::GetConsoleScreenBufferInfo(fOut, &csbi);
    fDefaultAttributes = csbi.wAttributes;
    assert(fDefaultAttributes != 0 && "~TerminalDisplayWin broken");
    fMyMode = fOldMode | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
    HandleResizeEvent();
  }

  TerminalDisplayWin::~TerminalDisplayWin() {
    if (fDefaultAttributes) {
      ::SetConsoleTextAttribute(fOut, fDefaultAttributes);
      // We allocated CONOUT$:
      CloseHandle(fOut);
    } else
      ::SetConsoleOutputCP(fOldCodePage);
  }

  void
  TerminalDisplayWin::HandleResizeEvent() {
    if (IsTTY()) {
      CONSOLE_SCREEN_BUFFER_INFO Info;
      if (!::GetConsoleScreenBufferInfo(fOut, &Info)) {
        ShowError("resize / getting console info");
        return;
      }
      SetWidth(Info.dwSize.X);
    }
  }

  void
  TerminalDisplayWin::SetColor(char CIdx, const Color& C) {
    WORD Attribs = 0;
    // There is no underline since DOS has died.
    if (C.fModifiers & Color::kModUnderline) Attribs |= BACKGROUND_INTENSITY;
    if (C.fModifiers & Color::kModBold) Attribs |= FOREGROUND_INTENSITY;
    if (C.fR > 64) Attribs |= FOREGROUND_RED;
    if (C.fG > 64) Attribs |= FOREGROUND_GREEN;
    if (C.fB > 64) Attribs |= FOREGROUND_BLUE;
    // if CIdx is 0 (default) then use the original console text color
    // (instead of the greyish one)
    if (CIdx == 0)
      ::SetConsoleTextAttribute(fOut, fDefaultAttributes);
    else
      ::SetConsoleTextAttribute(fOut, Attribs);
  }

  void
  TerminalDisplayWin::CheckCursorPos() {
    if (!IsTTY()) return;
    // Did something print something on the screen?
    // I.e. did the cursor move?
    CONSOLE_SCREEN_BUFFER_INFO CSI;
    if (::GetConsoleScreenBufferInfo(fOut, &CSI)) {
      if (CSI.dwCursorPosition.X != fWritePos.fCol
        || CSI.dwCursorPosition.Y != fWritePos.fLine + fStartLine) {
        fStartLine = CSI.dwCursorPosition.Y;
        if (CSI.dwCursorPosition.X) {
          // fStartLine may be a couple of lines higher (or more precisely
          // the number of written lines higher)
          fStartLine -= fWritePos.fLine;
        }
        fWritePos.fCol = 0;
        fWritePos.fLine = 0;
      }
    }
  }

  void
  TerminalDisplayWin::Move(Pos P) {
    CheckCursorPos();
    MoveInternal(P);
    fWritePos = P;
  }

  void
  TerminalDisplayWin::MoveInternal(Pos P) {
    if (IsTTY()) {
      COORD C = {P.fCol, P.fLine + fStartLine};
      ::SetConsoleCursorPosition(fOut, C);
    }
  }

  void
  TerminalDisplayWin::MoveFront() {
    Pos P(fWritePos);
    P.fCol = 0;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveUp(size_t nLines /* = 1 */) {
    Pos P(fWritePos);
    --P.fLine;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveDown(size_t nLines /* = 1 */) {
    Pos P(fWritePos);
    ++P.fLine;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveRight(size_t nCols /* = 1 */) {
    Pos P(fWritePos);
    ++P.fCol;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::MoveLeft(size_t nCols /* = 1 */) {
    Pos P(fWritePos);
    --P.fCol;
    MoveInternal(P);
  }

  void
  TerminalDisplayWin::EraseToRight() {
    DWORD NumWritten;
    COORD C = {fWritePos.fCol, fWritePos.fLine + fStartLine};
    ::FillConsoleOutputCharacterA(fOut, ' ', GetWidth() - C.X, C,
      &NumWritten);
    // It wraps, so move up and reset WritePos:
    //MoveUp();
    //++WritePos.Line;
  }

  void
  TerminalDisplayWin::WriteRawString(const char *text, size_t len) {
    DWORD NumWritten = 0;
    if (IsTTY()) {
      WriteConsoleA(fOut, text, (DWORD) len, &NumWritten, NULL);
    } else {
      WriteFile(fOut, text, (DWORD) len, &NumWritten, NULL);
    }
    if (NumWritten != len) {
      ShowError("writing to output");
    }
  }

  void
  TerminalDisplayWin::Attach() {
    // set to noecho
    if (fIsAttached || !IsTTY()) return;
    if (!::SetConsoleMode(fOut, fMyMode)) {
      ShowError("attaching to console output");
    }
    CONSOLE_SCREEN_BUFFER_INFO Info;
    if (!::GetConsoleScreenBufferInfo(fOut, &Info)) {
      ShowError("attaching / getting console info");
    } else {
      fStartLine = Info.dwCursorPosition.Y;
      if (Info.dwCursorPosition.X) {
        // Whooa - where are we?! Newline and cross fingers:
        WriteRawString("\n", 1);
        ++fStartLine;
      }
    }
    fIsAttached = true;
  }

  void
  TerminalDisplayWin::Detach() {
    if (!fIsAttached || !IsTTY()) return;
    if (!SetConsoleMode(fOut, fOldMode)) {
      ShowError("detaching to console output");
    }
    TerminalDisplay::Detach();
    fIsAttached = false;
  }

  void
  TerminalDisplayWin::ShowError(const char* Where) const {
    DWORD Err = GetLastError();
    LPVOID MsgBuf = 0;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR) &MsgBuf, 0, NULL);

    printf("Error %d in textinput::TerminalDisplayWin %s: %s\n", Err, Where, MsgBuf);
    LocalFree(MsgBuf);
  }

}

#endif // ifdef _WIN32
<|endoftext|>


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

  Library: CppMicroServices

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include <usLDAPFilter.h>

#include "usTestingMacros.h"

#include <stdexcept>

US_USE_NAMESPACE

int TestParsing()
{
  // WELL FORMED Expr
  try
  {
    US_TEST_OUTPUT(<< "Parsing (cn=Babs Jensen)")
    LDAPFilter ldap( "(cn=Babs Jensen)" );
    US_TEST_OUTPUT(<< "Parsing (!(cn=Tim Howes))")
    ldap = LDAPFilter( "(!(cn=Tim Howes))" );
    US_TEST_OUTPUT(<< "Parsing " << std::string("(&(") + ServiceConstants::OBJECTCLASS() + "=Person)(|(sn=Jensen)(cn=Babs J*)))")
    ldap = LDAPFilter( std::string("(&(") + ServiceConstants::OBJECTCLASS() + "=Person)(|(sn=Jensen)(cn=Babs J*)))" );
    US_TEST_OUTPUT(<< "Parsing (o=univ*of*mich*)")
    ldap = LDAPFilter( "(o=univ*of*mich*)" );
  }
  catch (const std::invalid_argument& e)
  {
    US_TEST_OUTPUT(<< e.what());
    return EXIT_FAILURE;
  }

  // MALFORMED Expr
  try
  {
    US_TEST_OUTPUT( << "Parsing malformed expr: cn=Babs Jensen)")
    LDAPFilter ldap( "cn=Babs Jensen)" );
    return EXIT_FAILURE;
  }
  catch (const std::invalid_argument&)
  {
  }

  return EXIT_SUCCESS;
}

int TestEvaluate()
{
  // EVALUATE
  try
  {
    LDAPFilter ldap( "(Cn=Babs Jensen)" );
    ServiceProperties props;
    bool eval = false;

    // Several values
    props["cn"] = std::string("Babs Jensen");
    props["unused"] = std::string("Jansen");
    US_TEST_OUTPUT(<< "Evaluating expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if (!eval)
    {
      return EXIT_FAILURE;
    }

    // WILDCARD
    ldap = LDAPFilter( "(cn=Babs *)" );
    props.clear();
    props["cn"] = std::string("Babs Jensen");
    US_TEST_OUTPUT(<< "Evaluating wildcard expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if ( !eval )
    {
      return EXIT_FAILURE;
    }

    // NOT FOUND
    ldap = LDAPFilter( "(cn=Babs *)" );
    props.clear();
    props["unused"] = std::string("New");
    US_TEST_OUTPUT(<< "Expr not found test: " << ldap.ToString())
    eval = ldap.Match(props);
    if ( eval )
    {
      return EXIT_FAILURE;
    }

    // std::vector with integer values
    ldap = LDAPFilter( "  ( |(cn=Babs *)(sn=1) )" );
    props.clear();
    std::vector<Any> list;
    list.push_back(std::string("Babs Jensen"));
    list.push_back(std::string("1"));
    props["sn"] = list;
    US_TEST_OUTPUT(<< "Evaluating vector expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if (!eval)
    {
      return EXIT_FAILURE;
    }

    // wrong case
    ldap = LDAPFilter( "(cN=Babs *)" );
    props.clear();
    props["cn"] = std::string("Babs Jensen");
    US_TEST_OUTPUT(<< "Evaluating case sensitive expr: " << ldap.ToString())
    eval = ldap.MatchCase(props);
    if (eval)
    {
      return EXIT_FAILURE;
    }
  }
  catch (const std::invalid_argument& e)
  {
    US_TEST_OUTPUT( << e.what() )
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

int usLDAPFilterTest(int /*argc*/, char* /*argv*/[])
{
  US_TEST_BEGIN("LDAPFilterTest");

  US_TEST_CONDITION(TestParsing() == EXIT_SUCCESS, "Parsing LDAP expressions: ")
  US_TEST_CONDITION(TestEvaluate() == EXIT_SUCCESS, "Evaluating LDAP expressions: ")

  US_TEST_END()
}

<commit_msg>COMP: adapted test to explicit cast of mitk::Any<commit_after>/*=============================================================================

  Library: CppMicroServices

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

#include <usLDAPFilter.h>

#include "usTestingMacros.h"

#include <stdexcept>

US_USE_NAMESPACE

int TestParsing()
{
  // WELL FORMED Expr
  try
  {
    US_TEST_OUTPUT(<< "Parsing (cn=Babs Jensen)")
    LDAPFilter ldap( "(cn=Babs Jensen)" );
    US_TEST_OUTPUT(<< "Parsing (!(cn=Tim Howes))")
    ldap = LDAPFilter( "(!(cn=Tim Howes))" );
    US_TEST_OUTPUT(<< "Parsing " << std::string("(&(") + ServiceConstants::OBJECTCLASS() + "=Person)(|(sn=Jensen)(cn=Babs J*)))")
    ldap = LDAPFilter( std::string("(&(") + ServiceConstants::OBJECTCLASS() + "=Person)(|(sn=Jensen)(cn=Babs J*)))" );
    US_TEST_OUTPUT(<< "Parsing (o=univ*of*mich*)")
    ldap = LDAPFilter( "(o=univ*of*mich*)" );
  }
  catch (const std::invalid_argument& e)
  {
    US_TEST_OUTPUT(<< e.what());
    return EXIT_FAILURE;
  }

  // MALFORMED Expr
  try
  {
    US_TEST_OUTPUT( << "Parsing malformed expr: cn=Babs Jensen)")
    LDAPFilter ldap( "cn=Babs Jensen)" );
    return EXIT_FAILURE;
  }
  catch (const std::invalid_argument&)
  {
  }

  return EXIT_SUCCESS;
}

int TestEvaluate()
{
  // EVALUATE
  try
  {
    LDAPFilter ldap( "(Cn=Babs Jensen)" );
    ServiceProperties props;
    bool eval = false;

    // Several values
    props["cn"] = std::string("Babs Jensen");
    props["unused"] = std::string("Jansen");
    US_TEST_OUTPUT(<< "Evaluating expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if (!eval)
    {
      return EXIT_FAILURE;
    }

    // WILDCARD
    ldap = LDAPFilter( "(cn=Babs *)" );
    props.clear();
    props["cn"] = std::string("Babs Jensen");
    US_TEST_OUTPUT(<< "Evaluating wildcard expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if ( !eval )
    {
      return EXIT_FAILURE;
    }

    // NOT FOUND
    ldap = LDAPFilter( "(cn=Babs *)" );
    props.clear();
    props["unused"] = std::string("New");
    US_TEST_OUTPUT(<< "Expr not found test: " << ldap.ToString())
    eval = ldap.Match(props);
    if ( eval )
    {
      return EXIT_FAILURE;
    }

    // std::vector with integer values
    ldap = LDAPFilter( "  ( |(cn=Babs *)(sn=1) )" );
    props.clear();
    std::vector<Any> list;
    list.push_back(Any(std::string("Babs Jensen")));
    list.push_back(Any(std::string("1")));
    props["sn"] = list;
    US_TEST_OUTPUT(<< "Evaluating vector expr: " << ldap.ToString())
    eval = ldap.Match(props);
    if (!eval)
    {
      return EXIT_FAILURE;
    }

    // wrong case
    ldap = LDAPFilter( "(cN=Babs *)" );
    props.clear();
    props["cn"] = std::string("Babs Jensen");
    US_TEST_OUTPUT(<< "Evaluating case sensitive expr: " << ldap.ToString())
    eval = ldap.MatchCase(props);
    if (eval)
    {
      return EXIT_FAILURE;
    }
  }
  catch (const std::invalid_argument& e)
  {
    US_TEST_OUTPUT( << e.what() )
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

int usLDAPFilterTest(int /*argc*/, char* /*argv*/[])
{
  US_TEST_BEGIN("LDAPFilterTest");

  US_TEST_CONDITION(TestParsing() == EXIT_SUCCESS, "Parsing LDAP expressions: ")
  US_TEST_CONDITION(TestEvaluate() == EXIT_SUCCESS, "Evaluating LDAP expressions: ")

  US_TEST_END()
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "CppUnitTest.h"
#include "../DNAnalyzerServer/Dictionnaire.h"
#include <exception>
#include <cstring>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace DNAnalyzerServerTest
{
	TEST_CLASS(DictionnaireTest)
	{
	public:
		//ObtenirInstance
		TEST_METHOD(ObtenirInstance_NotNull)
		{
			// L'instance retourne ne doit pas tre null
			Assert::IsTrue(&(Dictionnaire::ObtenirInstance())!=(Dictionnaire*) nullptr);
		}

		TEST_METHOD(ObtenirInstance_SameReference)
		{
			// L'instance retourne doit toujours tre la mme
			Assert::IsTrue(&(Dictionnaire::ObtenirInstance()) == &(Dictionnaire::ObtenirInstance()));
		}
	};
}<commit_msg>Revert "Revert "Ajout de methode de test (incomplete) de Dictionnaire""<commit_after>#include "stdafx.h"
#include "CppUnitTest.h"
#include "../DNAnalyzerServer/Dictionnaire.h"
#include "../DNAnalyzerServer/Mots.h"
#include <exception>
#include <unordered_set>
#include <cstring>
#include <string>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace DNAnalyzerServerTest
{
	TEST_CLASS(DictionnaireTest)
	{
	public:
		//ObtenirInstance
		TEST_METHOD(ObtenirInstance_NotNull)
		{
			// L'instance retourne ne doit pas tre null
			Assert::IsTrue(&(Dictionnaire::ObtenirInstance())!=(Dictionnaire*) nullptr);
		}

		TEST_METHOD(ObtenirInstance_SameReference)
		{
			// L'instance retourne doit toujours tre la mme
			Assert::IsTrue(&(Dictionnaire::ObtenirInstance()) == &(Dictionnaire::ObtenirInstance()));
		}
		TEST_METHOD(ObtenirMaladie_KnownMaladie) {

		}
		TEST_METHOD(ObtenirMaladie_UnKnownMaladie) {

		}
		TEST_METHOD(ObtenirMaladies_NoMaladies) {
			char motInexistant[] = "ATCGINEXISTANT";
			unsigned int indexMotInexistant = Mots::ObtenirInstance().InsererMot(motInexistant);
			const unordered_set<const Maladie*> resutat = Dictionnaire::ObtenirInstance().ObtenirMaladies(indexMotInexistant);
			Assert::AreEqual(resutat.size, 0);
		}
		TEST_METHOD(ObtenirMaladies_OneMaladies) {

		}
		TEST_METHOD(ObtenirMaladies_TwoMaladies) {

		}
		TEST_METHOD(ObtenirNomMaladies_EmptyDictionnaire) {

		}
		TEST_METHOD(ObtenirNomMaladies_NotEmptyDictionnaire) {

		}
	};
}<|endoftext|>


<commit_before>#include "../../../shared/generated/cpp/<%= name.camel_case %>Base.h"

namespace rho {

using namespace apiGenerator;

class C<%= name.camel_case %>Impl: public C<%= name.camel_case %>Base
{
public:
    C<%= name.camel_case %>Impl(const rho::String& strID): C<%= name.camel_case %>Base()
    {
        m_hashProps.put( "display", "LCD");
        m_hashProps.put( "sound", "Dolby");
    }

    virtual void enable( const rho::Hashtable<rho::String, rho::String>& propertyMap, CMethodResult& oResult){}
    virtual void start(CMethodResult& oResult){}
    virtual void stop(CMethodResult& oResult){}
    virtual void disable(CMethodResult& oResult){}
    virtual void take( const rho::Hashtable<rho::String, rho::String>& propertyMap, CMethodResult& oResult){}

};

class C<%= name.camel_case %>Singleton: public C<%= name.camel_case %>SingletonBase
{
    ~C<%= name.camel_case %>Singleton(){}
    virtual rho::String getInitialDefaultID();
    virtual void enumerate(CMethodResult& oResult);
};

class C<%= name.camel_case %>Factory: public C<%= name.camel_case %>FactoryBase
{
    ~C<%= name.camel_case %>Factory(){}
    virtual I<%= name.camel_case %>Singleton* createModuleSingleton();
    virtual I<%= name.camel_case %>* createModuleByID(const rho::String& strID);
};

extern "C" void Init_<%= name.camel_case %>_extension()
{
    C<%= name.camel_case %>Factory::setInstance( new C<%= name.camel_case %>Factory() );
    Init_<%= name.camel_case %>_API();
}

I<%= name.camel_case %>* C<%= name.camel_case %>Factory::createModuleByID(const rho::String& strID)
{
    return new C<%= name.camel_case %>Impl(strID);
}

I<%= name.camel_case %>Singleton* C<%= name.camel_case %>Factory::createModuleSingleton()
{
    return new C<%= name.camel_case %>Singleton();
}

void C<%= name.camel_case %>Singleton::enumerate(CMethodResult& oResult)
{
    rho::Vector<rho::String> arIDs;
    arIDs.addElement("SC1");
    arIDs.addElement("SC2");

    oResult.set(arIDs);
}

rho::String C<%= name.camel_case %>Singleton::getInitialDefaultID()
{
    CMethodResult oRes;
    enumerate(oRes);

    rho::Vector<rho::String>& arIDs = oRes.getStringArray();

    return arIDs[0];
}

}<commit_msg>wm:ext generator: fix impl file<commit_after>#include "../../../shared/generated/cpp/<%= namecamelcase %>Base.h"

namespace rho {

using namespace apiGenerator;

class C<%= namecamelcase %>Impl: public C<%= namecamelcase %>Base
{
public:
    C<%= namecamelcase %>Impl(const rho::String& strID): C<%= namecamelcase %>Base()
    {
        m_hashProps.put( "display", "LCD");
        m_hashProps.put( "sound", "Dolby");
    }

    virtual void enable( const rho::Hashtable<rho::String, rho::String>& propertyMap, CMethodResult& oResult){}
    virtual void start(CMethodResult& oResult){}
    virtual void stop(CMethodResult& oResult){}
    virtual void disable(CMethodResult& oResult){}
    virtual void take( const rho::Hashtable<rho::String, rho::String>& propertyMap, CMethodResult& oResult){}

};

class C<%= namecamelcase %>Singleton: public C<%= namecamelcase %>SingletonBase
{
    ~C<%= namecamelcase %>Singleton(){}
    virtual rho::String getInitialDefaultID();
    virtual void enumerate(CMethodResult& oResult);
};

class C<%= namecamelcase %>Factory: public C<%= namecamelcase %>FactoryBase
{
    ~C<%= namecamelcase %>Factory(){}
    virtual I<%= namecamelcase %>Singleton* createModuleSingleton();
    virtual I<%= namecamelcase %>* createModuleByID(const rho::String& strID);
};

extern "C" void Init_<%= namecamelcase %>_extension()
{
    C<%= namecamelcase %>Factory::setInstance( new C<%= namecamelcase %>Factory() );
    Init_<%= namecamelcase %>_API();
}

I<%= namecamelcase %>* C<%= namecamelcase %>Factory::createModuleByID(const rho::String& strID)
{
    return new C<%= namecamelcase %>Impl(strID);
}

I<%= namecamelcase %>Singleton* C<%= namecamelcase %>Factory::createModuleSingleton()
{
    return new C<%= namecamelcase %>Singleton();
}

void C<%= namecamelcase %>Singleton::enumerate(CMethodResult& oResult)
{
    rho::Vector<rho::String> arIDs;
    arIDs.addElement("SC1");
    arIDs.addElement("SC2");

    oResult.set(arIDs);
}

rho::String C<%= namecamelcase %>Singleton::getInitialDefaultID()
{
    CMethodResult oRes;
    enumerate(oRes);

    rho::Vector<rho::String>& arIDs = oRes.getStringArray();

    return arIDs[0];
}

}<|endoftext|>


<commit_before>#line 2 "BitwiseAnd.cpp"
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <algorithm>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cassert>
#include <bitset>
#include <list>
#include <cmath>
#include <string>
#include <vector>
#include <numeric>

using namespace std;

class BitwiseAnd
{
	public:
		vector<long long> lexSmallest(vector<long long> subset, int N) {
			const int B = 60;

			int mask[B];
			vector <long long> ret = subset;
			int K = subset.size();
			memset(mask, -1, sizeof(mask));
			for(int i = 0; i < K; i++) {
				set <int> st;
				for(int j = 0; j < i; j++) {
					st.insert(j);
				}
				for(int j = 0; j < B; j++) {
					if(subset[i] & (1LL << j)) {
						if (mask[j] == -1) {
							mask[j] = i;
						} else if (mask[j] >= 0) {
							st.erase(mask[j]);
							mask[j] = -2;
						} else {
							return {};
						}
					}
				}
				if(!st.empty()) {
					return {};
				}
			}

			for(int i = K; i < N; i++) {
				set <int> st;
				for(int j = 0; j < i; j++) {
					st.insert(j);
				}
				long long x = 0;
				int zeroChange = N - i - 1;
				for(int j = 0; j < B; j++) {
					if(mask[j] == -1) {
						if(zeroChange > 0) {
							x |= 1LL << j;
							zeroChange--;
							mask[j] = i;
						}
					} else if (mask[j] >= 0) {
						if(st.find(mask[j]) != st.end()) {
							x |= 1LL << j;
							st.erase(mask[j]);
							mask[j] = -2;
						}
					}
				}
				if(!st.empty() || zeroChange > 0) {
					return {};
				}
				ret.push_back(x);
			}

			sort(ret.begin(), ret.end());
			return ret;
		}

		// BEGIN CUT HERE
	public:
		void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); }
	private:
		template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
		void verify_case(int Case, const vector<long long> &Expected, const vector<long long> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } }
		void test_case_0() { long Arr0[] = {14, 20}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; long Arr2[] = {14, 18, 20 }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(0, Arg2, lexSmallest(Arg0, Arg1)); }
		void test_case_1() { long Arr0[] = {11, 17, 20}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; long Arr2[] = { }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(1, Arg2, lexSmallest(Arg0, Arg1)); }
		void test_case_2() { long Arr0[] = {99, 157}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 4; long Arr2[] = {99, 157, 262, 296 }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(2, Arg2, lexSmallest(Arg0, Arg1)); }
		void test_case_3() { long Arr0[] = {1152921504606846975}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; long Arr2[] = { }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(3, Arg2, lexSmallest(Arg0, Arg1)); }
		void test_case_4() { long Arr0[] = {}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 5; long Arr2[] = {15, 113, 402, 676, 840 }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(4, Arg2, lexSmallest(Arg0, Arg1)); }
		void test_case_5() { long Arr0[] = {1, 3, 5, 7, 9, 11}; vector<long long> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 6; long Arr2[] = { }; vector<long long> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); verify_case(5, Arg2, lexSmallest(Arg0, Arg1)); }

		// END CUT HERE

};

// BEGIN CUT HERE
int main() {
	BitwiseAnd ___test;
	___test.run_test(-1);
	return 0;
}
<commit_msg>Delete BitwiseAnd.cpp<commit_after><|endoftext|>


<commit_before>

#include <sys/stat.h>		// mkdir

#include "engine/MemoryManager.h"					// samson::MemoryManager
#include "engine/MemoryRequest.h"
#include "engine/Notification.h"                // engine::Notification

#include "engine/Buffer.h"							// engine::Buffer
#include "engine/Notification.h"                    // engine::Notificaiton

#include "samson/network/Packet.h"							// samson::Packet
#include "samson/network/Message.h"						// samson::Message
#include "samson/delilah/Delilah.h"						// samson::Delilah
#include "samson/common/samson.pb.h"						// network::...
#include "DelilahClient.h"					// samson::DelilahClient
#include "samson/common/SamsonSetup.h"					// samson::SamsonSetup
#include "samson/common/MemoryTags.h"                     // samson::MemoryInput , samson::MemoryOutput...

#include "PushDelilahComponent.h"                      // Own interface

namespace samson
{

	PushDelilahComponent::PushDelilahComponent( DataSource * _dataSource , std::string _queue  ) : DelilahComponent( DelilahComponent::push )
	{

		// Queue name
		queues.insert( _queue );

        // Data source
        dataSource = _dataSource;

		uploadedSize = 0;
		processedSize = 0;
        totalSize = dataSource->getTotalSize();

        // Set this to false ( true will be the end of processing data )
        finish_process = false;

        setConcept( au::str("Pushing %s to queue/s %s" , au::str( dataSource->getTotalSize() , "bytes").c_str() , _queue.c_str() ) );
	}

    std::string PushDelilahComponent::getShortDescription()
    {
        if( isComponentFinished() )
        {
            std::ostringstream output;
            output << "[ ";
            output << "Id " << id << " ";
            output << "Finished ";
            output << "]";
            return output.str();

        }

        std::ostringstream output;
        output << "[ ";
        output << "Id " << id << " ";
        output << "Pushed ";
        output << au::str( processedSize , "B" ) << " / " << au::str( totalSize , "B" );
        output << "]";
        return output.str();
    }

    void PushDelilahComponent::addQueue( std::string  _queue )
    {
		queues.insert( _queue );
    }

    void PushDelilahComponent::run()
    {

		if( totalSize == 0)
		{
			error.set("Not data to upload.");
            finish_process = true;
            setComponentFinished();
		}
        else
        {
            // Request the first buffer of memory
            requestMemoryBuffer();
        }

    }

	PushDelilahComponent::~PushDelilahComponent()
	{
        delete dataSource;
	}

    // Request a memory buffer to upload the next packet...

    void PushDelilahComponent::requestMemoryBuffer()
    {
        // Add a memory request to be responded to me
    	LM_M(("PushDelilahComponent::requestMemoryBuffer: Request size:%lu by %lu", 64*1024*1024, getEngineId()));
        engine::MemoryManager::shared()->add( new engine::MemoryRequest( 64*1024*1024 , 1.0 , getEngineId() ) );
    }

    // Receive packets
    void PushDelilahComponent::receive(int fromId, Message::MessageCode msgCode, Packet* packet)
    {
        // At the moment we do not receive anything
        if( packet->msgCode != Message::PushBlockResponse )
            LM_X(1, ("Received an unexpected packet in a push block operation"));

        uploadedSize += packet->message->push_block_response().request().size();

        if( totalSize > 0 )
            setProgress((double) uploadedSize / (double) totalSize );

        if( finish_process )
        {

            if( totalSize == uploadedSize )
            {
                // Set this flag to indicate that the process has finished
                finish_process = true;
                setComponentFinished();
            }
        }

    }

    // Notifications

    void PushDelilahComponent::notify( engine::Notification* notification )
    {
        if( notification->isName( notification_memory_request_response ) )
        {
            // New buffer to be used to send data to the workers
        	LM_M(("PushDelilahComponent::notify: Received notification from memory request"));
            engine::MemoryRequest *memoryRequest = (engine::MemoryRequest *) notification->extractObject();

            if( !memoryRequest )
                LM_X(1, ("Internal error: Memory request returns without a buffer"));

            if ( !memoryRequest->buffer )
            {
                setComponentFinishedWithError( "Memory request returned without the allocated buffer" );
                return;
            }

            engine::Buffer *buffer = memoryRequest->buffer;
            delete memoryRequest;

            // Skip to write the header at the end
            buffer->skipWrite( sizeof(KVHeader) );

            // Full the buffer with the content from the files
            if( dataSource->fill( buffer ) != 0)
            {
                setComponentFinishedWithError("Error filling buffer");
                return;
            }

            // Set the header
            KVHeader *header = (KVHeader*) buffer->getData();
            header->initForTxt( buffer->getSize() - sizeof(KVHeader) );

            // Get the size to update the total process info
            processedSize += buffer->getSize();

            Packet* packet = new Packet( Message::PushBlock );
            packet->buffer = buffer;    // Set the buffer of data
            packet->message->set_delilah_id( id );

            network::PushBlock* pb =  packet->message->mutable_push_block();

            // Add queue
            std::set<std::string>::iterator q;
            for (q = queues.begin() ; q != queues.end() ; q++)
                pb->add_queue( *q );

            pb->set_size( buffer->getSize() - sizeof(KVHeader) );

            int worker = delilah->getNextWorker();
            delilah->network->sendToWorker( worker, packet);

            if( !dataSource->isFinish() )
            {
            	LM_M(("PushDelilahComponent::notify: Request a new MemoryBuffer"));
                requestMemoryBuffer();  // Request the next element
            }
            else
                finish_process = true;  // Mark as finished

        }
        else
        {
        	LM_M(("PushDelilahComponent::notify: Received another type of notification"));
        }

    }

    std::string PushDelilahComponent::getStatus()
    {
        std::ostringstream output;
        output << " ( Processed " << au::percentage_string(processedSize, totalSize) << " )\n";
        output << " ( Uploaded  " << au::percentage_string(uploadedSize, totalSize) << " )\n";
        return output.str();
    }

}
<commit_msg>Remove old trace messages2<commit_after>

#include <sys/stat.h>		// mkdir

#include "engine/MemoryManager.h"					// samson::MemoryManager
#include "engine/MemoryRequest.h"
#include "engine/Notification.h"                // engine::Notification

#include "engine/Buffer.h"							// engine::Buffer
#include "engine/Notification.h"                    // engine::Notificaiton

#include "samson/network/Packet.h"							// samson::Packet
#include "samson/network/Message.h"						// samson::Message
#include "samson/delilah/Delilah.h"						// samson::Delilah
#include "samson/common/samson.pb.h"						// network::...
#include "DelilahClient.h"					// samson::DelilahClient
#include "samson/common/SamsonSetup.h"					// samson::SamsonSetup
#include "samson/common/MemoryTags.h"                     // samson::MemoryInput , samson::MemoryOutput...

#include "PushDelilahComponent.h"                      // Own interface

namespace samson
{

	PushDelilahComponent::PushDelilahComponent( DataSource * _dataSource , std::string _queue  ) : DelilahComponent( DelilahComponent::push )
	{

		// Queue name
		queues.insert( _queue );

        // Data source
        dataSource = _dataSource;

		uploadedSize = 0;
		processedSize = 0;
        totalSize = dataSource->getTotalSize();

        // Set this to false ( true will be the end of processing data )
        finish_process = false;

        setConcept( au::str("Pushing %s to queue/s %s" , au::str( dataSource->getTotalSize() , "bytes").c_str() , _queue.c_str() ) );
	}

    std::string PushDelilahComponent::getShortDescription()
    {
        if( isComponentFinished() )
        {
            std::ostringstream output;
            output << "[ ";
            output << "Id " << id << " ";
            output << "Finished ";
            output << "]";
            return output.str();

        }

        std::ostringstream output;
        output << "[ ";
        output << "Id " << id << " ";
        output << "Pushed ";
        output << au::str( processedSize , "B" ) << " / " << au::str( totalSize , "B" );
        output << "]";
        return output.str();
    }

    void PushDelilahComponent::addQueue( std::string  _queue )
    {
		queues.insert( _queue );
    }

    void PushDelilahComponent::run()
    {

		if( totalSize == 0)
		{
			error.set("Not data to upload.");
            finish_process = true;
            setComponentFinished();
		}
        else
        {
            // Request the first buffer of memory
            requestMemoryBuffer();
        }

    }

	PushDelilahComponent::~PushDelilahComponent()
	{
        delete dataSource;
	}

    // Request a memory buffer to upload the next packet...

    void PushDelilahComponent::requestMemoryBuffer()
    {
        // Add a memory request to be responded to me
    	//LM_M(("PushDelilahComponent::requestMemoryBuffer: Request size:%lu by %lu", 64*1024*1024, getEngineId()));
        engine::MemoryManager::shared()->add( new engine::MemoryRequest( 64*1024*1024 , 1.0 , getEngineId() ) );
    }

    // Receive packets
    void PushDelilahComponent::receive(int fromId, Message::MessageCode msgCode, Packet* packet)
    {
        // At the moment we do not receive anything
        if( packet->msgCode != Message::PushBlockResponse )
            LM_X(1, ("Received an unexpected packet in a push block operation"));

        uploadedSize += packet->message->push_block_response().request().size();

        if( totalSize > 0 )
            setProgress((double) uploadedSize / (double) totalSize );

        if( finish_process )
        {

            if( totalSize == uploadedSize )
            {
                // Set this flag to indicate that the process has finished
                finish_process = true;
                setComponentFinished();
            }
        }

    }

    // Notifications

    void PushDelilahComponent::notify( engine::Notification* notification )
    {
        if( notification->isName( notification_memory_request_response ) )
        {
            // New buffer to be used to send data to the workers
        	//LM_M(("PushDelilahComponent::notify: Received notification from memory request"));
            engine::MemoryRequest *memoryRequest = (engine::MemoryRequest *) notification->extractObject();

            if( !memoryRequest )
                LM_X(1, ("Internal error: Memory request returns without a buffer"));

            if ( !memoryRequest->buffer )
            {
                setComponentFinishedWithError( "Memory request returned without the allocated buffer" );
                return;
            }

            engine::Buffer *buffer = memoryRequest->buffer;
            delete memoryRequest;

            // Skip to write the header at the end
            buffer->skipWrite( sizeof(KVHeader) );

            // Full the buffer with the content from the files
            if( dataSource->fill( buffer ) != 0)
            {
                setComponentFinishedWithError("Error filling buffer");
                return;
            }

            // Set the header
            KVHeader *header = (KVHeader*) buffer->getData();
            header->initForTxt( buffer->getSize() - sizeof(KVHeader) );

            // Get the size to update the total process info
            processedSize += buffer->getSize();

            Packet* packet = new Packet( Message::PushBlock );
            packet->buffer = buffer;    // Set the buffer of data
            packet->message->set_delilah_id( id );

            network::PushBlock* pb =  packet->message->mutable_push_block();

            // Add queue
            std::set<std::string>::iterator q;
            for (q = queues.begin() ; q != queues.end() ; q++)
                pb->add_queue( *q );

            pb->set_size( buffer->getSize() - sizeof(KVHeader) );

            int worker = delilah->getNextWorker();
            delilah->network->sendToWorker( worker, packet);

            if( !dataSource->isFinish() )
            {
            	LM_M(("PushDelilahComponent::notify: Request a new MemoryBuffer"));
                requestMemoryBuffer();  // Request the next element
            }
            else
                finish_process = true;  // Mark as finished

        }
        else
        {
        	LM_M(("PushDelilahComponent::notify: Received another type of notification"));
        }

    }

    std::string PushDelilahComponent::getStatus()
    {
        std::ostringstream output;
        output << " ( Processed " << au::percentage_string(processedSize, totalSize) << " )\n";
        output << " ( Uploaded  " << au::percentage_string(uploadedSize, totalSize) << " )\n";
        return output.str();
    }

}
<|endoftext|>


<commit_before>#include "fcntl.h"
#include "keyboard.h"
#include "processmgr.h"
#include "rootfilesystem.h"
#include "streamtable.h"
#include "sys/wait.h"
#include "system.h"
#include "systemcalls.h"
#include "unistd.h"
#include "unittests.h"

namespace systemcall
{

int close(int fildes)
{
    int rv = -1;
    ProcessMgr::ProcessInfo* process = processMgr.getCurrentProcessInfo();

    int masterStreamIdx = process->getStreamIndex(fildes);
    if (masterStreamIdx >= 0)
    {
        process->removeStreamIndex(fildes);

        rootFileSystem.close(masterStreamIdx);

        // success
        rv = 0;
    }
    else
    {
        // an error occurred
        rv = -1;
    }

    return rv;
}

int dup(int fildes)
{
    int rv = processMgr.getCurrentProcessInfo()->duplicateStreamIndex(fildes);
    return rv;
}

int dup2(int fildes, int fildes2)
{
    int rv = processMgr.getCurrentProcessInfo()->duplicateStreamIndex(fildes, fildes2);
    return rv;
}

int execv(const char* path, char* const argv[])
{
    processMgr.switchCurrentProcessExecutable(path, argv);

    // we should only get here if an error occurred
    return -1;
}

void exit(int status)
{
    processMgr.exitCurrentProcess(status);
}

pid_t fork()
{
    return processMgr.forkCurrentProcess();
}

int getNumModules()
{
    return processMgr.getNumModules();
}

void getModuleName(int index, char* name)
{
    processMgr.getModuleName(index, name);
}

pid_t getpid()
{
    return processMgr.getCurrentProcessInfo()->getId();
}

pid_t getppid()
{
    return processMgr.getCurrentProcessInfo()->parentProcess->getId();
}

int open(const char *path, int oflag)
{
    /// @todo Support other modes besides read-only
    if (oflag != O_RDONLY)
    {
        return -1;
    }

    int fd = -1;
    int masterStreamIdx = rootFileSystem.open(path);

    if (masterStreamIdx >= 0)
    {
        fd = processMgr.getCurrentProcessInfo()->addStreamIndex(masterStreamIdx);

        // close the stream if there was an error
        if (fd < 0)
        {
            rootFileSystem.close(masterStreamIdx);
        }
    }

    return fd;
}

ssize_t read(int fildes, void* buf, size_t nbyte)
{
    // convert the local stream index to the master stream table index
    int masterStreamIdx = processMgr.getCurrentProcessInfo()->getStreamIndex(fildes);
    if (masterStreamIdx < 0)
    {
        return -1;
    }

    // look up the stream in the master stream table
    Stream* stream = streamTable.getStream(masterStreamIdx);
    if (stream == nullptr)
    {
        return -1;
    }

    // read from the stream
    ssize_t rv = stream->read(reinterpret_cast<uint8_t*>(buf), nbyte);

    return rv;
}

int runKernelTests(size_t* numTestsPtr, size_t* numFailedPtr)
{
    size_t numTests = 0;
    size_t numFailed = 0;
    bool passed = runUnitTests(numTests, numFailed);

    if (numTestsPtr != nullptr)
    {
        *numTestsPtr = numTests;
    }
    if (numFailedPtr != nullptr)
    {
        *numFailedPtr = numFailed;
    }

    return passed ? 0 : 1;
}

int sched_yield()
{
    processMgr.yieldCurrentProcess();

    return 0;
}

pid_t waitpid(pid_t pid, int* stat_loc, int options)
{
    if ( options & (WCONTINUED | WUNTRACED) )
    {
        /// @todo support these options
        return -1;
    }

    if (pid == 0 || pid < -1)
    {
        /// @todo support these options
        return -1;
    }

    bool hang = !(options & WNOHANG);

    ProcessMgr::ProcessInfo* proc = processMgr.getCurrentProcessInfo();
    ProcessMgr::ProcessInfo* child = nullptr;
    do
    {
        for (size_t i = 0; i < proc->childProcesses.getSize(); ++i)
        {
            ProcessMgr::ProcessInfo* p = proc->childProcesses[i];

            // check if the child has terminated
            if (p->getStatus() == ProcessMgr::ProcessInfo::eTerminated)
            {
                if (pid == -1 || pid == p->getId())
                {
                    child = p;
                    break;
                }
            }
        }

        if (child == nullptr && hang)
        {
            // if no child process was found, yield so we don't waste the CPU
            // (a CPU is a terrible thing to waste)
            processMgr.yieldCurrentProcess();
        }
    } while (child == nullptr && hang);

    if (child == nullptr)
    {
        return 0;
    }
    else
    {
        if (stat_loc != nullptr)
        {
            /// @todo encode more info in stat_loc (as required by posix)
            *stat_loc = child->exitCode;
        }

        // save ID before we clean up the process
        pid_t childId = child->getId();

        // clean up process
        processMgr.cleanUpCurrentProcessChild(child);

        return childId;
    }
}

ssize_t write(int fildes, const void* buf, size_t nbyte)
{
    // convert the local stream index to the master stream table index
    int masterStreamIdx = processMgr.getCurrentProcessInfo()->getStreamIndex(fildes);
    if (masterStreamIdx < 0)
    {
        return -1;
    }

    // look up the stream in the master stream table
    Stream* stream = streamTable.getStream(masterStreamIdx);
    if (stream == nullptr)
    {
        return -1;
    }

    // write to the stream
    ssize_t rv = stream->write(reinterpret_cast<const uint8_t*>(buf), nbyte);

    return rv;
}

} // namespace systemcall

constexpr uint32_t SYSTEM_CALLS_SIZE = 16;
const void* SYSTEM_CALLS[SYSTEM_CALLS_SIZE] = {
    reinterpret_cast<const void*>(systemcall::write),
    reinterpret_cast<const void*>(systemcall::getpid),
    reinterpret_cast<const void*>(systemcall::exit),
    reinterpret_cast<const void*>(systemcall::fork),
    reinterpret_cast<const void*>(systemcall::read),
    reinterpret_cast<const void*>(systemcall::sched_yield),
    reinterpret_cast<const void*>(systemcall::getppid),
    reinterpret_cast<const void*>(systemcall::waitpid),
    reinterpret_cast<const void*>(systemcall::execv),
    reinterpret_cast<const void*>(systemcall::getNumModules),
    reinterpret_cast<const void*>(systemcall::getModuleName),
    reinterpret_cast<const void*>(systemcall::runKernelTests),
    reinterpret_cast<const void*>(systemcall::open),
    reinterpret_cast<const void*>(systemcall::close),
    reinterpret_cast<const void*>(systemcall::dup),
    reinterpret_cast<const void*>(systemcall::dup2),
};

extern "C"
uint32_t systemCallHandler(uint32_t sysCallNum, uint32_t numArgs, const uint32_t* argPtr)
{
    if (sysCallNum >= SYSTEM_CALLS_SIZE || SYSTEM_CALLS[sysCallNum] == nullptr)
    {
        /// @todo Temporarily calling PANIC. This needs to
        /// be changed to something else like killing the
        /// calling process.
        PANIC("Unknown system call.");

        return 0xbad'ca11;
    }
    else
    {
        const void* funcPtr = SYSTEM_CALLS[sysCallNum];

        return execSystemCall(funcPtr, numArgs, argPtr);
    }
}
<commit_msg>Bugfix: Serial port write now blocks until done writing<commit_after>#include "fcntl.h"
#include "keyboard.h"
#include "processmgr.h"
#include "rootfilesystem.h"
#include "streamtable.h"
#include "sys/wait.h"
#include "system.h"
#include "systemcalls.h"
#include "unistd.h"
#include "unittests.h"

namespace systemcall
{

int close(int fildes)
{
    int rv = -1;
    ProcessMgr::ProcessInfo* process = processMgr.getCurrentProcessInfo();

    int masterStreamIdx = process->getStreamIndex(fildes);
    if (masterStreamIdx >= 0)
    {
        process->removeStreamIndex(fildes);

        rootFileSystem.close(masterStreamIdx);

        // success
        rv = 0;
    }
    else
    {
        // an error occurred
        rv = -1;
    }

    return rv;
}

int dup(int fildes)
{
    int rv = processMgr.getCurrentProcessInfo()->duplicateStreamIndex(fildes);
    return rv;
}

int dup2(int fildes, int fildes2)
{
    int rv = processMgr.getCurrentProcessInfo()->duplicateStreamIndex(fildes, fildes2);
    return rv;
}

int execv(const char* path, char* const argv[])
{
    processMgr.switchCurrentProcessExecutable(path, argv);

    // we should only get here if an error occurred
    return -1;
}

void exit(int status)
{
    processMgr.exitCurrentProcess(status);
}

pid_t fork()
{
    return processMgr.forkCurrentProcess();
}

int getNumModules()
{
    return processMgr.getNumModules();
}

void getModuleName(int index, char* name)
{
    processMgr.getModuleName(index, name);
}

pid_t getpid()
{
    return processMgr.getCurrentProcessInfo()->getId();
}

pid_t getppid()
{
    return processMgr.getCurrentProcessInfo()->parentProcess->getId();
}

int open(const char *path, int oflag)
{
    /// @todo Support other modes besides read-only
    if (oflag != O_RDONLY)
    {
        return -1;
    }

    int fd = -1;
    int masterStreamIdx = rootFileSystem.open(path);

    if (masterStreamIdx >= 0)
    {
        fd = processMgr.getCurrentProcessInfo()->addStreamIndex(masterStreamIdx);

        // close the stream if there was an error
        if (fd < 0)
        {
            rootFileSystem.close(masterStreamIdx);
        }
    }

    return fd;
}

ssize_t read(int fildes, void* buf, size_t nbyte)
{
    // convert the local stream index to the master stream table index
    int masterStreamIdx = processMgr.getCurrentProcessInfo()->getStreamIndex(fildes);
    if (masterStreamIdx < 0)
    {
        return -1;
    }

    // look up the stream in the master stream table
    Stream* stream = streamTable.getStream(masterStreamIdx);
    if (stream == nullptr)
    {
        return -1;
    }

    // read from the stream
    ssize_t rv = stream->read(reinterpret_cast<uint8_t*>(buf), nbyte);

    return rv;
}

int runKernelTests(size_t* numTestsPtr, size_t* numFailedPtr)
{
    size_t numTests = 0;
    size_t numFailed = 0;
    bool passed = runUnitTests(numTests, numFailed);

    if (numTestsPtr != nullptr)
    {
        *numTestsPtr = numTests;
    }
    if (numFailedPtr != nullptr)
    {
        *numFailedPtr = numFailed;
    }

    return passed ? 0 : 1;
}

int sched_yield()
{
    processMgr.yieldCurrentProcess();

    return 0;
}

pid_t waitpid(pid_t pid, int* stat_loc, int options)
{
    if ( options & (WCONTINUED | WUNTRACED) )
    {
        /// @todo support these options
        return -1;
    }

    if (pid == 0 || pid < -1)
    {
        /// @todo support these options
        return -1;
    }

    bool hang = !(options & WNOHANG);

    ProcessMgr::ProcessInfo* proc = processMgr.getCurrentProcessInfo();
    ProcessMgr::ProcessInfo* child = nullptr;
    do
    {
        for (size_t i = 0; i < proc->childProcesses.getSize(); ++i)
        {
            ProcessMgr::ProcessInfo* p = proc->childProcesses[i];

            // check if the child has terminated
            if (p->getStatus() == ProcessMgr::ProcessInfo::eTerminated)
            {
                if (pid == -1 || pid == p->getId())
                {
                    child = p;
                    break;
                }
            }
        }

        if (child == nullptr && hang)
        {
            // if no child process was found, yield so we don't waste the CPU
            // (a CPU is a terrible thing to waste)
            processMgr.yieldCurrentProcess();
        }
    } while (child == nullptr && hang);

    if (child == nullptr)
    {
        return 0;
    }
    else
    {
        if (stat_loc != nullptr)
        {
            /// @todo encode more info in stat_loc (as required by posix)
            *stat_loc = child->exitCode;
        }

        // save ID before we clean up the process
        pid_t childId = child->getId();

        // clean up process
        processMgr.cleanUpCurrentProcessChild(child);

        return childId;
    }
}

ssize_t write(int fildes, const void* buf, size_t nbyte)
{
    // convert the local stream index to the master stream table index
    int masterStreamIdx = processMgr.getCurrentProcessInfo()->getStreamIndex(fildes);
    if (masterStreamIdx < 0)
    {
        return -1;
    }

    // look up the stream in the master stream table
    Stream* stream = streamTable.getStream(masterStreamIdx);
    if (stream == nullptr)
    {
        return -1;
    }

    // write to the stream
    ssize_t rv = stream->write(reinterpret_cast<const uint8_t*>(buf), nbyte, true);

    return rv;
}

} // namespace systemcall

constexpr uint32_t SYSTEM_CALLS_SIZE = 16;
const void* SYSTEM_CALLS[SYSTEM_CALLS_SIZE] = {
    reinterpret_cast<const void*>(systemcall::write),
    reinterpret_cast<const void*>(systemcall::getpid),
    reinterpret_cast<const void*>(systemcall::exit),
    reinterpret_cast<const void*>(systemcall::fork),
    reinterpret_cast<const void*>(systemcall::read),
    reinterpret_cast<const void*>(systemcall::sched_yield),
    reinterpret_cast<const void*>(systemcall::getppid),
    reinterpret_cast<const void*>(systemcall::waitpid),
    reinterpret_cast<const void*>(systemcall::execv),
    reinterpret_cast<const void*>(systemcall::getNumModules),
    reinterpret_cast<const void*>(systemcall::getModuleName),
    reinterpret_cast<const void*>(systemcall::runKernelTests),
    reinterpret_cast<const void*>(systemcall::open),
    reinterpret_cast<const void*>(systemcall::close),
    reinterpret_cast<const void*>(systemcall::dup),
    reinterpret_cast<const void*>(systemcall::dup2),
};

extern "C"
uint32_t systemCallHandler(uint32_t sysCallNum, uint32_t numArgs, const uint32_t* argPtr)
{
    if (sysCallNum >= SYSTEM_CALLS_SIZE || SYSTEM_CALLS[sysCallNum] == nullptr)
    {
        /// @todo Temporarily calling PANIC. This needs to
        /// be changed to something else like killing the
        /// calling process.
        PANIC("Unknown system call.");

        return 0xbad'ca11;
    }
    else
    {
        const void* funcPtr = SYSTEM_CALLS[sysCallNum];

        return execSystemCall(funcPtr, numArgs, argPtr);
    }
}
<|endoftext|>


<commit_before>#include <ROOT/REveDataTable.hxx>
#include <ROOT/REveDataCollection.hxx>
#include <TClass.h>
#include <json.hpp>
#include <sstream>
#include <TROOT.h>

using namespace ROOT::Experimental;

//==============================================================================
// REveDataTable
//==============================================================================

REveDataTable::REveDataTable(const std::string& n, const std::string& t) :
   REveElement(n, t)
{
   fChildClass = TClass::GetClass<REveDataColumn>();
}

void REveDataTable::PrintTable()
{
   Int_t Nit = fCollection->GetNItems();

   for (Int_t i = 0; i< Nit; ++i)
   {
      void         *data = fCollection->GetDataPtr(i);
      REveDataItem *item = fCollection->GetDataItem(i);

      printf("| %-20s |", item->GetCName());

      for (auto & chld : fChildren)
      {
         auto clmn = dynamic_cast<REveDataColumn*>(chld);

         printf(" %10s |", clmn->EvalExpr(data).c_str());
      }
      printf("\n");
   }
}

Int_t REveDataTable::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
{
   int ret = REveElement::WriteCoreJson(j, rnr_offset);
   Int_t Nit = fCollection->GetNItems();

   nlohmann::json jarr = nlohmann::json::array();

   for (Int_t i = 0; i < Nit; ++i) {
      void *data = fCollection->GetDataPtr(i);
      nlohmann::json row;
      for (auto &chld : fChildren) {
         auto clmn = dynamic_cast<REveDataColumn *>(chld);
         row[chld->GetCName()] = clmn->EvalExpr(data);
      }
      jarr.push_back(row);
   }
   j["body"] = jarr;
   j["fCollectionId"] = fCollection->GetElementId();
   return ret;
}

void REveDataTable::AddNewColumn(const std::string& expr, const std::string& title, int prec)
{
   auto c = new REveDataColumn(title);
   AddElement(c);

   c->SetExpressionAndType(expr, REveDataColumn::FT_Double);
   c->SetPrecision(prec);

   StampObjProps();
}

//==============================================================================
// REveDataColumn
//==============================================================================

REveDataColumn::REveDataColumn(const std::string& n, const std::string& t) :
   REveElement(n, t)
{
}

void REveDataColumn::SetExpressionAndType(const std::string& expr, FieldType_e type)
{
   auto table = dynamic_cast<REveDataTable*>(fMother);
   auto coll = table->GetCollection();
   auto icls = coll->GetItemClass();

   fExpression = expr;
   fType       = type;

   const char *rtyp   = nullptr;
   const void *fooptr = nullptr;

   switch (fType)
   {
      case FT_Double: rtyp = "double";      fooptr = &fDoubleFoo; break;
      case FT_Bool:   rtyp = "bool";        fooptr = &fBoolFoo;   break;
      case FT_String: rtyp = "std::string"; fooptr = &fStringFoo; break;
   }

   std::stringstream s;
   s << "*((std::function<" << rtyp << "(" << icls->GetName() << "*)>*)" << std::hex << std::showbase << (size_t)fooptr
     << ") = [](" << icls->GetName() << "* p){" << icls->GetName() << " &i=*p; return (" << fExpression.Data()
     << "); }";

   // printf("%s\n", s.str().c_str());
   try {
      gROOT->ProcessLine(s.str().c_str());
   }
   catch (const std::exception &exc)
   {
      std::cerr << "REveDataColumn::SetExpressionAndType" << exc.what();
   }
}

void REveDataColumn::SetPrecision(Int_t prec)
{
   fPrecision = prec;
}

std::string REveDataColumn::EvalExpr(void *iptr)
{
   switch (fType)
   {
      case FT_Double:
      {
         TString ostr;
         ostr.Form("%.*f", fPrecision, fDoubleFoo(iptr));
         return ostr.Data();
      }
      case FT_Bool:
      {
         return fBoolFoo(iptr) ? fTrue : fFalse;
      }
      case FT_String:
      {
         return fStringFoo(iptr);
      }
   }
   return "XYZ";
}
<commit_msg>Skip streaming of items name<commit_after>#include <ROOT/REveDataTable.hxx>
#include <ROOT/REveDataCollection.hxx>
#include <TClass.h>
#include <json.hpp>
#include <sstream>
#include <TROOT.h>

using namespace ROOT::Experimental;

//==============================================================================
// REveDataTable
//==============================================================================

REveDataTable::REveDataTable(const std::string& n, const std::string& t) :
   REveElement(n, t)
{
   fChildClass = TClass::GetClass<REveDataColumn>();
}

void REveDataTable::PrintTable()
{
   Int_t Nit = fCollection->GetNItems();

   for (Int_t i = 0; i< Nit; ++i)
   {
      void         *data = fCollection->GetDataPtr(i);
      // const REveDataItem &item = fCollection->RetDataItem(i);

      // !!!      printf("| %-20s |", item->GetCName());

      for (auto & chld : fChildren)
      {
         auto clmn = dynamic_cast<REveDataColumn*>(chld);

         printf(" %10s |", clmn->EvalExpr(data).c_str());
      }
      printf("\n");
   }
}

Int_t REveDataTable::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
{
   int ret = REveElement::WriteCoreJson(j, rnr_offset);
   Int_t Nit = fCollection->GetNItems();

   nlohmann::json jarr = nlohmann::json::array();

   for (Int_t i = 0; i < Nit; ++i) {
      void *data = fCollection->GetDataPtr(i);
      nlohmann::json row;
      for (auto &chld : fChildren) {
         auto clmn = dynamic_cast<REveDataColumn *>(chld);
         row[chld->GetCName()] = clmn->EvalExpr(data);
      }
      jarr.push_back(row);
   }
   j["body"] = jarr;
   j["fCollectionId"] = fCollection->GetElementId();
   return ret;
}

void REveDataTable::AddNewColumn(const std::string& expr, const std::string& title, int prec)
{
   auto c = new REveDataColumn(title);
   AddElement(c);

   c->SetExpressionAndType(expr, REveDataColumn::FT_Double);
   c->SetPrecision(prec);

   StampObjProps();
}

//==============================================================================
// REveDataColumn
//==============================================================================

REveDataColumn::REveDataColumn(const std::string& n, const std::string& t) :
   REveElement(n, t)
{
}

void REveDataColumn::SetExpressionAndType(const std::string& expr, FieldType_e type)
{
   auto table = dynamic_cast<REveDataTable*>(fMother);
   auto coll = table->GetCollection();
   auto icls = coll->GetItemClass();

   fExpression = expr;
   fType       = type;

   const char *rtyp   = nullptr;
   const void *fooptr = nullptr;

   switch (fType)
   {
      case FT_Double: rtyp = "double";      fooptr = &fDoubleFoo; break;
      case FT_Bool:   rtyp = "bool";        fooptr = &fBoolFoo;   break;
      case FT_String: rtyp = "std::string"; fooptr = &fStringFoo; break;
   }

   std::stringstream s;
   s << "*((std::function<" << rtyp << "(" << icls->GetName() << "*)>*)" << std::hex << std::showbase << (size_t)fooptr
     << ") = [](" << icls->GetName() << "* p){" << icls->GetName() << " &i=*p; return (" << fExpression.Data()
     << "); }";

   // printf("%s\n", s.str().c_str());
   try {
      gROOT->ProcessLine(s.str().c_str());
   }
   catch (const std::exception &exc)
   {
      std::cerr << "REveDataColumn::SetExpressionAndType" << exc.what();
   }
}

void REveDataColumn::SetPrecision(Int_t prec)
{
   fPrecision = prec;
}

std::string REveDataColumn::EvalExpr(void *iptr)
{
   switch (fType)
   {
      case FT_Double:
      {
         TString ostr;
         ostr.Form("%.*f", fPrecision, fDoubleFoo(iptr));
         return ostr.Data();
      }
      case FT_Bool:
      {
         return fBoolFoo(iptr) ? fTrue : fFalse;
      }
      case FT_String:
      {
         return fStringFoo(iptr);
      }
   }
   return "XYZ";
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/type.hpp"

#include "vast/concept/parseable/core/list.hpp"
#include "vast/concept/parseable/core/operators.hpp"
#include "vast/concept/parseable/core/parser.hpp"
#include "vast/concept/parseable/numeric/integral.hpp"
#include "vast/concept/parseable/string/quoted_string.hpp"
#include "vast/concept/parseable/string/symbol_table.hpp"
#include "vast/concept/parseable/vast/identifier.hpp"

namespace vast {

class type_table : public parser<type_table> {
public:
  using attribute = type;

  type_table() = default;

  type_table(std::initializer_list<std::pair<const std::string, type>> init) {
    for (auto& pair : init)
      add(pair.first, pair.second);
  }

  bool add(const std::string& name, type t) {
    if (name.empty() || name != t.name())
      return false;
    t.name(name);
    symbols_.symbols.insert({name, t});
    return true;
  }

  template <class Iterator, class Attribute>
  bool parse(Iterator& f, const Iterator& l, Attribute& a) const {
    return symbols_(f, l, a);
  }

private:
  symbol_table<type> symbols_;
};

/// Parses a type with the help of a symbol table.
struct type_parser : parser<type_parser> {
  using attribute = type;

  type_parser(const type_table* symbols = nullptr) : symbol_type{symbols} {
    // nop
  }

  template <class T>
  static type to_basic_type(std::vector<vast::attribute> a) {
    T b;
    return b.attributes(std::move(a));
  }

  template <class Iterator, class Attribute>
  bool parse(Iterator& f, const Iterator& l, Attribute& a) const {
    // clang-format off
    // Whitespace
    static auto ws = ignore(*parsers::space);
    // Attributes: type meta data
    static auto to_attr =
      [](std::tuple<std::string, optional<std::string>> xs) {
        auto& [key, value] = xs;
        return vast::attribute{std::move(key), std::move(value)};
      };
    static auto attr
      = ('#' >> parsers::identifier >> -('=' >> parsers::qq_str)) ->* to_attr;
    static auto attr_list = *(ws >> attr);
    // Basic types
    static auto basic_type_parser
      = "bool" >> attr_list      ->* to_basic_type<bool_type>
      | "int" >> attr_list       ->* to_basic_type<integer_type>
      | "count" >> attr_list     ->* to_basic_type<count_type>
      | "real" >> attr_list      ->* to_basic_type<real_type>
      | "duration" >> attr_list  ->* to_basic_type<timespan_type>
      | "time" >> attr_list      ->* to_basic_type<timestamp_type>
      | "string" >> attr_list    ->* to_basic_type<string_type>
      | "pattern" >> attr_list   ->* to_basic_type<pattern_type>
      | "addr" >> attr_list      ->* to_basic_type<address_type>
      | "subnet" >> attr_list    ->* to_basic_type<subnet_type>
      | "port" >> attr_list      ->* to_basic_type<port_type>
      ;
    // Enumeration
    using enum_tuple = std::tuple<
      std::vector<std::string>,
      std::vector<vast::attribute>
    >;
    static auto to_enum = [](enum_tuple xs) -> type {
      auto& [fields, attrs] = xs;
      return enumeration_type{std::move(fields)}.attributes(std::move(attrs));
    };
    static auto enum_type_parser
      = ("enum" >> ws >> '{'
      >> (ws >> parsers::identifier) % ','
      >> ws >> '}' >> attr_list) ->* to_enum
      ;
    // Compound types
    rule<Iterator, type> type_type;
    // Vector
    using sequence_tuple = std::tuple<type, std::vector<vast::attribute>>;
    static auto to_vector = [](sequence_tuple xs) -> type {
      auto& [value_type, attrs] = xs;
      return vector_type{std::move(value_type)}.attributes(std::move(attrs));
    };
    auto vector_type_parser
      = ("vector" >> ws >> '<' >> ws >> type_type >> ws >> '>') ->* to_vector
      ;
    // Set
    static auto to_set = [](sequence_tuple xs) -> type {
      auto& [value_type, attrs] = xs;
      return set_type{std::move(value_type)}.attributes(std::move(attrs));
    };
    auto set_type_parser
      = ("set" >> ws >> '<' >> ws >> type_type >> ws >> '>') ->* to_set
      ;
    // Map
    using map_tuple = std::tuple<type, type, std::vector<vast::attribute>>;
    static auto to_map = [](map_tuple xs) -> type {
      auto& [key_type, value_type, attrs] = xs;
      auto m = map_type{std::move(key_type), std::move(value_type)};
      return m.attributes(std::move(attrs));
    };
    auto map_type_parser
      = ("map" >> ws >> '<' >> ws
      >> type_type >> ws >> ',' >> ws >> type_type >> ws
      >> '>' >> attr_list) ->* to_map;
      ;
    // Record
    using record_tuple = std::tuple<
      std::vector<record_field>,
      std::vector<vast::attribute>
    >;
    static auto to_field = [](std::tuple<std::string, type> xs) {
      auto& [field_name, field_type] = xs;
      return record_field{std::move(field_name), std::move(field_type)};
    };
    static auto to_record = [](record_tuple xs) -> type {
      auto& [fields, attrs] = xs;
      return record_type{std::move(fields)}.attributes(std::move(attrs));
    };
    auto field
      = (parsers::identifier >> ws >> ':' >> ws >> type_type) ->* to_field
      ;
    auto record_type_parser
      = ("record" >> ws >> '{'
      >> (ws >> field) % ',' >> ws
      >> '}' >> attr_list) ->* to_record;
      ;
    // Complete type
    if (symbol_type)
      type_type
        = *symbol_type
        | basic_type_parser
        | enum_type_parser
        | vector_type_parser
        | set_type_parser
        | map_type_parser
        | record_type_parser
        ;
    else // As above, just without the symbol table.
      type_type
        = basic_type_parser
        | enum_type_parser
        | vector_type_parser
        | set_type_parser
        | map_type_parser
        | record_type_parser
        ;
    return type_type(f, l, a);
    // clang-format on
  }

  const type_table* symbol_type;
};

template <>
struct parser_registry<type> {
  using type = type_parser;
};

namespace parsers {

auto const type = make_parser<vast::type>();

} // namespace parsers
} // namespace vast
<commit_msg>Fix memory leak in the schema parser<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/type.hpp"

#include "vast/concept/parseable/core/list.hpp"
#include "vast/concept/parseable/core/operators.hpp"
#include "vast/concept/parseable/core/parser.hpp"
#include "vast/concept/parseable/core/rule.hpp"
#include "vast/concept/parseable/numeric/integral.hpp"
#include "vast/concept/parseable/string/quoted_string.hpp"
#include "vast/concept/parseable/string/symbol_table.hpp"
#include "vast/concept/parseable/vast/identifier.hpp"

namespace vast {

class type_table : public parser<type_table> {
public:
  using attribute = type;

  type_table() = default;

  type_table(std::initializer_list<std::pair<const std::string, type>> init) {
    for (auto& pair : init)
      add(pair.first, pair.second);
  }

  bool add(const std::string& name, type t) {
    if (name.empty() || name != t.name())
      return false;
    t.name(name);
    symbols_.symbols.insert({name, t});
    return true;
  }

  template <class Iterator, class Attribute>
  bool parse(Iterator& f, const Iterator& l, Attribute& a) const {
    return symbols_(f, l, a);
  }

private:
  symbol_table<type> symbols_;
};

/// Parses a type with the help of a symbol table.
struct type_parser : parser<type_parser> {
  using attribute = type;

  type_parser(const type_table* symbols = nullptr) : symbol_type{symbols} {
    // nop
  }

  template <class T>
  static type to_basic_type(std::vector<vast::attribute> a) {
    T b;
    return b.attributes(std::move(a));
  }

  template <class Iterator, class Attribute>
  bool parse(Iterator& f, const Iterator& l, Attribute& a) const {
    // clang-format off
    // Whitespace
    static auto ws = ignore(*parsers::space);
    // Attributes: type meta data
    static auto to_attr =
      [](std::tuple<std::string, optional<std::string>> xs) {
        auto& [key, value] = xs;
        return vast::attribute{std::move(key), std::move(value)};
      };
    static auto attr
      = ('#' >> parsers::identifier >> -('=' >> parsers::qq_str)) ->* to_attr;
    static auto attr_list = *(ws >> attr);
    // Basic types
    static auto basic_type_parser
      = "bool" >> attr_list      ->* to_basic_type<bool_type>
      | "int" >> attr_list       ->* to_basic_type<integer_type>
      | "count" >> attr_list     ->* to_basic_type<count_type>
      | "real" >> attr_list      ->* to_basic_type<real_type>
      | "duration" >> attr_list  ->* to_basic_type<timespan_type>
      | "time" >> attr_list      ->* to_basic_type<timestamp_type>
      | "string" >> attr_list    ->* to_basic_type<string_type>
      | "pattern" >> attr_list   ->* to_basic_type<pattern_type>
      | "addr" >> attr_list      ->* to_basic_type<address_type>
      | "subnet" >> attr_list    ->* to_basic_type<subnet_type>
      | "port" >> attr_list      ->* to_basic_type<port_type>
      ;
    // Enumeration
    using enum_tuple = std::tuple<
      std::vector<std::string>,
      std::vector<vast::attribute>
    >;
    static auto to_enum = [](enum_tuple xs) -> type {
      auto& [fields, attrs] = xs;
      return enumeration_type{std::move(fields)}.attributes(std::move(attrs));
    };
    static auto enum_type_parser
      = ("enum" >> ws >> '{'
      >> (ws >> parsers::identifier) % ','
      >> ws >> '}' >> attr_list) ->* to_enum
      ;
    // Compound types
    rule<Iterator, type> type_type;
    // Vector
    using sequence_tuple = std::tuple<type, std::vector<vast::attribute>>;
    static auto to_vector = [](sequence_tuple xs) -> type {
      auto& [value_type, attrs] = xs;
      return vector_type{std::move(value_type)}.attributes(std::move(attrs));
    };
    auto vector_type_parser
      = ("vector" >> ws >> '<' >> ws >> vast::ref(type_type) >> ws >> '>')
        ->* to_vector
      ;
    // Set
    static auto to_set = [](sequence_tuple xs) -> type {
      auto& [value_type, attrs] = xs;
      return set_type{std::move(value_type)}.attributes(std::move(attrs));
    };
    auto set_type_parser
      = ("set" >> ws >> '<' >> ws >> vast::ref(type_type) >> ws >> '>')
      ->* to_set
      ;
    // Map
    using map_tuple = std::tuple<type, type, std::vector<vast::attribute>>;
    static auto to_map = [](map_tuple xs) -> type {
      auto& [key_type, value_type, attrs] = xs;
      auto m = map_type{std::move(key_type), std::move(value_type)};
      return m.attributes(std::move(attrs));
    };
    auto map_type_parser
      = ("map" >> ws >> '<' >> ws
      >> vast::ref(type_type) >> ws >> ',' >> ws >> vast::ref(type_type) >> ws
      >> '>' >> attr_list) ->* to_map;
      ;
    // Record
    using record_tuple = std::tuple<
      std::vector<record_field>,
      std::vector<vast::attribute>
    >;
    static auto to_field = [](std::tuple<std::string, type> xs) {
      auto& [field_name, field_type] = xs;
      return record_field{std::move(field_name), std::move(field_type)};
    };
    static auto to_record = [](record_tuple xs) -> type {
      auto& [fields, attrs] = xs;
      return record_type{std::move(fields)}.attributes(std::move(attrs));
    };
    auto field
      = (parsers::identifier >> ws >> ':' >> ws >> vast::ref(type_type))
      ->* to_field
      ;
    auto record_type_parser
      = ("record" >> ws >> '{'
      >> (ws >> field) % ',' >> ws
      >> '}' >> attr_list) ->* to_record;
      ;
    // Complete type
    if (symbol_type)
      type_type
        = *symbol_type
        | basic_type_parser
        | enum_type_parser
        | vector_type_parser
        | set_type_parser
        | map_type_parser
        | record_type_parser
        ;
    else // As above, just without the symbol table.
      type_type
        = basic_type_parser
        | enum_type_parser
        | vector_type_parser
        | set_type_parser
        | map_type_parser
        | record_type_parser
        ;
    return type_type(f, l, a);
    // clang-format on
  }

  const type_table* symbol_type;
};

template <>
struct parser_registry<type> {
  using type = type_parser;
};

namespace parsers {

auto const type = make_parser<vast::type>();

} // namespace parsers
} // namespace vast
<|endoftext|>