<commit_before>#include <climits>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <algorithm>
#include <list>
#include <deque>
#include <vector>
#include <X11/keysym.h>
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/xcb_keysyms.h>
#include <xcb/damage.h>
#include <xcb/xinerama.h>
#include <xcb/composite.h>

#include "data_types.hpp"
#include "x_event_handler.hpp"
#include "x_connection.hpp"
#include "x_client.hpp"
#include "x_event_source.hpp"
#include "x_client_container.hpp"

// http://svn.enlightenment.org/svn/e/tags/evas-1.0.2/src/modules/engines/xrender_x11/evas_engine_xcb_render.c
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))

xcb_render_pictformat_t
render_find_visual_format(const x_connection & c, xcb_visualid_t visual);

xcb_render_picture_t
make_picture(const x_connection & c, xcb_window_t window);

std::list<x_client>
make_x_clients(const x_connection & c, const std::vector<xcb_window_t> & windows);

std::vector<x_client>
make_thumbnails(const x_connection & c, const std::vector<xcb_window_t> & windows);

class layout_t {
  public:
    virtual void arrange(const rectangle_t &, x_client_container &) const = 0;
};

class grid_t : public layout_t {
  public:
    void arrange(const rectangle_t & screen, x_client_container & clients) const
    {
      int gap = 5;

      int factor = std::round(std::sqrt(clients.size()));
      int rest = (factor * factor) - clients.size();

      auto cells = decompose(factor, factor * factor);

      if (rest >= 0) {
        for (auto rit = cells.rbegin(); rit != cells.rend(); ) {
          if (rest == 0) {
            break;
          } else if (rest < *rit) {
            *rit -= rest;
            break;
          } else if (rest >= *rit) {
            rest -= *rit;
            ++rit;
            cells.pop_back();
          }
        }
      } else {
        cells.push_back((-1) * rest);
      }

      int ncol = cells.size();
      int colw = screen.width() / ncol;

      std::vector<rectangle_t> rects;
      for (int c = 0; c < ncol; ++c) {
        int nrow = cells[c];
        int rowh = screen.height() / nrow;
        for (int r = 0; r < nrow; ++r) {
          rects.push_back(rectangle_t(c * colw + screen.x() + gap,
                                      r * rowh + screen.y() + gap,
                                      colw - 2 * gap, rowh - 2 * gap));
        }
      }

      int i = 0;
      for (auto & client : clients) {
        double scale_x = (double)rects[i].width()
                       / (double)client.rectangle().width();
        double scale_y = (double)rects[i].height()
                       / (double)client.rectangle().height();
        client.preview_scale() = std::min(scale_x, scale_y);
        client.preview_position().x = rects[i].x();
        client.preview_position().y = rects[i].y();

        unsigned int realwidth  = client.rectangle().width()
                                * client.preview_scale();
        unsigned int realheight = client.rectangle().height()
                                * client.preview_scale();

        if (realwidth < rects[i].width()) {
          client.preview_position().x += (rects[i].width() - realwidth) / 2;
        }
        if (realheight < rects[i].height()) {
          client.preview_position().y += (rects[i].height() - realheight) / 2;
        }
        i++;
      }
    }

  private:
    std::deque<int> decompose(int f, int n) const
    {
      std::deque<int> result;
      while (true) {
        n -= f;
        if (n > 0) {
          result.push_back(f);
        } else {
          result.push_back(n + f);
          break;
        }
      }
      return result;
    }
};

class x_clients_preview : public x_event_handler {
  public:
    x_clients_preview(const x_connection & c,
                      const layout_t * layout,
                      x_client_container & x_clients)
      : _c(c), _layout(layout), _x_clients(x_clients) {}

    void handle(xcb_generic_event_t * ge)
    {
      if (XCB_KEY_PRESS == (ge->response_type & ~0x80)) {
        xcb_key_press_event_t * e = (xcb_key_press_event_t *)ge;
        xcb_keysym_t keysym = _c.keycode_to_keysym(e->detail);
        if (keysym == XK_Escape && e->state == 0) {
          _active = false;

        } else if (keysym == XK_Tab
            && (e->state == XCB_MOD_MASK_4
              || e->state == (XCB_MOD_MASK_4 | XCB_MOD_MASK_SHIFT))) {
          if (_active) {
            _current_client->update_preview(false);
            move_client(e->state == XCB_MOD_MASK_4);
            _current_client->update_preview(true);
          } else {
            _active = true;
            _c.grab_keyboard();
            _active_window = _c.net_active_window();
            _x_clients.update();

            _layout->arrange(_c.current_screen(), _x_clients);

            _current_client =
              std::find(_x_clients.begin(), _x_clients.end(), _active_window);
            move_client(e->state == XCB_MOD_MASK_4);

            for (auto & client : _x_clients) {
              client.show_preview(client == _current_client->window());
            }
          }
        }

      } else if (XCB_KEY_RELEASE == (ge->response_type & ~0x80)) {
        xcb_key_release_event_t * e = (xcb_key_release_event_t *)ge;
        xcb_keysym_t keysym = _c.keycode_to_keysym(e->detail);
        if (keysym == XK_Super_L) {
          for (auto & client : _x_clients) {
            client.hide_preview();
          }
          _c.request_change_active_window(_current_client->window());
          _active = false;
          _c.ungrab_keyboard();
        }
      }
    }

  private:
    bool _active = false;
    xcb_window_t _active_window;

    const x_connection & _c;
    const layout_t * _layout;
    x_client_container & _x_clients;
    x_client_container::iterator _current_client;

    void move_client(bool next)
    {
      if (next) {
        if (++_current_client == _x_clients.end()) {
          _current_client = _x_clients.begin();
        }
      } else {
        if (_current_client == _x_clients.begin()) {
          _current_client = _x_clients.end();
        }
        --_current_client;
      }
    }
};

xcb_render_pictformat_t
render_find_visual_format(const x_connection & c, xcb_visualid_t visual)
{
  // http://lists.freedesktop.org/archives/xcb/2004-December/000236.html

  xcb_render_query_pict_formats_reply_t * query_pict_formats_reply =
    xcb_render_query_pict_formats_reply(
        c(), xcb_render_query_pict_formats(c()), NULL);

  xcb_render_pictscreen_iterator_t pictscreen_iterator =
    xcb_render_query_pict_formats_screens_iterator(query_pict_formats_reply);

  while (pictscreen_iterator.rem) {
    xcb_render_pictdepth_iterator_t pictdepth_iterator =
      xcb_render_pictscreen_depths_iterator(pictscreen_iterator.data);

    while (pictdepth_iterator.rem) {
      xcb_render_pictvisual_iterator_t pictvisual_iterator =
        xcb_render_pictdepth_visuals_iterator(pictdepth_iterator.data);

      while (pictvisual_iterator.rem) {
        if (pictvisual_iterator.data->visual == visual) {
          delete query_pict_formats_reply;
          return pictvisual_iterator.data->format;
        }
        xcb_render_pictvisual_next(&pictvisual_iterator);
      }
      xcb_render_pictdepth_next(&pictdepth_iterator);
    }
    xcb_render_pictscreen_next(&pictscreen_iterator);
  }

  delete query_pict_formats_reply;
  return 0;
}

xcb_render_picture_t
make_picture(const x_connection & c, xcb_window_t window)
{
  xcb_get_window_attributes_reply_t * window_attributes_reply =
    xcb_get_window_attributes_reply(c(),
                                    xcb_get_window_attributes(c(), window),
                                    NULL);

  if (window_attributes_reply) {
    xcb_render_pictformat_t format =
      render_find_visual_format(c, window_attributes_reply->visual);

    delete window_attributes_reply;

    uint32_t mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_SUBWINDOW_MODE;
    uint32_t list[] = { XCB_RENDER_REPEAT_NONE,
                        XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };

    xcb_render_picture_t picture = xcb_generate_id(c());
    xcb_render_create_picture(c(), picture, window, format, mask, list);

    return picture;
  }

  return XCB_NONE;
}

std::list<x_client>
make_x_clients(const x_connection & c, const std::vector<xcb_window_t> & windows)
{
  std::list<x_client> x_clients;
  for (auto & window : windows) { x_clients.emplace_back(c, window); }
  return x_clients;
}

xcb_visualtype_t *
argb_visual(const x_connection & c)
{
  xcb_depth_iterator_t depth_iter =
    xcb_screen_allowed_depths_iterator(c.default_screen());

  if (depth_iter.data) {
    for (; depth_iter.rem; xcb_depth_next (&depth_iter)) {
      if (depth_iter.data->depth == 32) {
        xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
        for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
          return visual_iter.data;
        }
      }
    }
  }

  return NULL;
}

int main(int argc, char ** argv)
{
  x_connection c;
  c.grab_key(XCB_MOD_MASK_4, XK_Tab);

  x_event_source es(c);
  x_client_container cc(c, es);

  grid_t grid;
  x_clients_preview cp(c, &grid, cc);

  es.register_handler(&c);
  es.register_handler(&cp);

  es.run_event_loop();

  return 0;
}
<commit_msg>This function does not even exists anymore<commit_after>#include <climits>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <algorithm>
#include <list>
#include <deque>
#include <vector>
#include <X11/keysym.h>
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/xcb_keysyms.h>
#include <xcb/damage.h>
#include <xcb/xinerama.h>
#include <xcb/composite.h>

#include "data_types.hpp"
#include "x_event_handler.hpp"
#include "x_connection.hpp"
#include "x_client.hpp"
#include "x_event_source.hpp"
#include "x_client_container.hpp"

// http://svn.enlightenment.org/svn/e/tags/evas-1.0.2/src/modules/engines/xrender_x11/evas_engine_xcb_render.c
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))

xcb_render_pictformat_t
render_find_visual_format(const x_connection & c, xcb_visualid_t visual);

xcb_render_picture_t
make_picture(const x_connection & c, xcb_window_t window);

class layout_t {
  public:
    virtual void arrange(const rectangle_t &, x_client_container &) const = 0;
};

class grid_t : public layout_t {
  public:
    void arrange(const rectangle_t & screen, x_client_container & clients) const
    {
      int gap = 5;

      int factor = std::round(std::sqrt(clients.size()));
      int rest = (factor * factor) - clients.size();

      auto cells = decompose(factor, factor * factor);

      if (rest >= 0) {
        for (auto rit = cells.rbegin(); rit != cells.rend(); ) {
          if (rest == 0) {
            break;
          } else if (rest < *rit) {
            *rit -= rest;
            break;
          } else if (rest >= *rit) {
            rest -= *rit;
            ++rit;
            cells.pop_back();
          }
        }
      } else {
        cells.push_back((-1) * rest);
      }

      int ncol = cells.size();
      int colw = screen.width() / ncol;

      std::vector<rectangle_t> rects;
      for (int c = 0; c < ncol; ++c) {
        int nrow = cells[c];
        int rowh = screen.height() / nrow;
        for (int r = 0; r < nrow; ++r) {
          rects.push_back(rectangle_t(c * colw + screen.x() + gap,
                                      r * rowh + screen.y() + gap,
                                      colw - 2 * gap, rowh - 2 * gap));
        }
      }

      int i = 0;
      for (auto & client : clients) {
        double scale_x = (double)rects[i].width()
                       / (double)client.rectangle().width();
        double scale_y = (double)rects[i].height()
                       / (double)client.rectangle().height();
        client.preview_scale() = std::min(scale_x, scale_y);
        client.preview_position().x = rects[i].x();
        client.preview_position().y = rects[i].y();

        unsigned int realwidth  = client.rectangle().width()
                                * client.preview_scale();
        unsigned int realheight = client.rectangle().height()
                                * client.preview_scale();

        if (realwidth < rects[i].width()) {
          client.preview_position().x += (rects[i].width() - realwidth) / 2;
        }
        if (realheight < rects[i].height()) {
          client.preview_position().y += (rects[i].height() - realheight) / 2;
        }
        i++;
      }
    }

  private:
    std::deque<int> decompose(int f, int n) const
    {
      std::deque<int> result;
      while (true) {
        n -= f;
        if (n > 0) {
          result.push_back(f);
        } else {
          result.push_back(n + f);
          break;
        }
      }
      return result;
    }
};

class x_clients_preview : public x_event_handler {
  public:
    x_clients_preview(const x_connection & c,
                      const layout_t * layout,
                      x_client_container & x_clients)
      : _c(c), _layout(layout), _x_clients(x_clients) {}

    void handle(xcb_generic_event_t * ge)
    {
      if (XCB_KEY_PRESS == (ge->response_type & ~0x80)) {
        xcb_key_press_event_t * e = (xcb_key_press_event_t *)ge;
        xcb_keysym_t keysym = _c.keycode_to_keysym(e->detail);
        if (keysym == XK_Escape && e->state == 0) {
          _active = false;

        } else if (keysym == XK_Tab
            && (e->state == XCB_MOD_MASK_4
              || e->state == (XCB_MOD_MASK_4 | XCB_MOD_MASK_SHIFT))) {
          if (_active) {
            _current_client->update_preview(false);
            move_client(e->state == XCB_MOD_MASK_4);
            _current_client->update_preview(true);
          } else {
            _active = true;
            _c.grab_keyboard();
            _active_window = _c.net_active_window();
            _x_clients.update();

            _layout->arrange(_c.current_screen(), _x_clients);

            _current_client =
              std::find(_x_clients.begin(), _x_clients.end(), _active_window);
            move_client(e->state == XCB_MOD_MASK_4);

            for (auto & client : _x_clients) {
              client.show_preview(client == _current_client->window());
            }
          }
        }

      } else if (XCB_KEY_RELEASE == (ge->response_type & ~0x80)) {
        xcb_key_release_event_t * e = (xcb_key_release_event_t *)ge;
        xcb_keysym_t keysym = _c.keycode_to_keysym(e->detail);
        if (keysym == XK_Super_L) {
          for (auto & client : _x_clients) {
            client.hide_preview();
          }
          _c.request_change_active_window(_current_client->window());
          _active = false;
          _c.ungrab_keyboard();
        }
      }
    }

  private:
    bool _active = false;
    xcb_window_t _active_window;

    const x_connection & _c;
    const layout_t * _layout;
    x_client_container & _x_clients;
    x_client_container::iterator _current_client;

    void move_client(bool next)
    {
      if (next) {
        if (++_current_client == _x_clients.end()) {
          _current_client = _x_clients.begin();
        }
      } else {
        if (_current_client == _x_clients.begin()) {
          _current_client = _x_clients.end();
        }
        --_current_client;
      }
    }
};

xcb_render_pictformat_t
render_find_visual_format(const x_connection & c, xcb_visualid_t visual)
{
  // http://lists.freedesktop.org/archives/xcb/2004-December/000236.html

  xcb_render_query_pict_formats_reply_t * query_pict_formats_reply =
    xcb_render_query_pict_formats_reply(
        c(), xcb_render_query_pict_formats(c()), NULL);

  xcb_render_pictscreen_iterator_t pictscreen_iterator =
    xcb_render_query_pict_formats_screens_iterator(query_pict_formats_reply);

  while (pictscreen_iterator.rem) {
    xcb_render_pictdepth_iterator_t pictdepth_iterator =
      xcb_render_pictscreen_depths_iterator(pictscreen_iterator.data);

    while (pictdepth_iterator.rem) {
      xcb_render_pictvisual_iterator_t pictvisual_iterator =
        xcb_render_pictdepth_visuals_iterator(pictdepth_iterator.data);

      while (pictvisual_iterator.rem) {
        if (pictvisual_iterator.data->visual == visual) {
          delete query_pict_formats_reply;
          return pictvisual_iterator.data->format;
        }
        xcb_render_pictvisual_next(&pictvisual_iterator);
      }
      xcb_render_pictdepth_next(&pictdepth_iterator);
    }
    xcb_render_pictscreen_next(&pictscreen_iterator);
  }

  delete query_pict_formats_reply;
  return 0;
}

xcb_render_picture_t
make_picture(const x_connection & c, xcb_window_t window)
{
  xcb_get_window_attributes_reply_t * window_attributes_reply =
    xcb_get_window_attributes_reply(c(),
                                    xcb_get_window_attributes(c(), window),
                                    NULL);

  if (window_attributes_reply) {
    xcb_render_pictformat_t format =
      render_find_visual_format(c, window_attributes_reply->visual);

    delete window_attributes_reply;

    uint32_t mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_SUBWINDOW_MODE;
    uint32_t list[] = { XCB_RENDER_REPEAT_NONE,
                        XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };

    xcb_render_picture_t picture = xcb_generate_id(c());
    xcb_render_create_picture(c(), picture, window, format, mask, list);

    return picture;
  }

  return XCB_NONE;
}

std::list<x_client>
make_x_clients(const x_connection & c, const std::vector<xcb_window_t> & windows)
{
  std::list<x_client> x_clients;
  for (auto & window : windows) { x_clients.emplace_back(c, window); }
  return x_clients;
}

xcb_visualtype_t *
argb_visual(const x_connection & c)
{
  xcb_depth_iterator_t depth_iter =
    xcb_screen_allowed_depths_iterator(c.default_screen());

  if (depth_iter.data) {
    for (; depth_iter.rem; xcb_depth_next (&depth_iter)) {
      if (depth_iter.data->depth == 32) {
        xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
        for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
          return visual_iter.data;
        }
      }
    }
  }

  return NULL;
}

int main(int argc, char ** argv)
{
  x_connection c;
  c.grab_key(XCB_MOD_MASK_4, XK_Tab);

  x_event_source es(c);
  x_client_container cc(c, es);

  grid_t grid;
  x_clients_preview cp(c, &grid, cc);

  es.register_handler(&c);
  es.register_handler(&cp);

  es.run_event_loop();

  return 0;
}
<|endoftext|>


<commit_before>//
//
//

#include "Constants.h"

ConstantsClass::ConstantsClass()
{
	adminStartButton = 3;
	adminResetButton = 2;

	firstPlayerButton = 11;
	secondPlayerButton = 10;
	thirdPlayerButton = 9;
	fourthPlayerButton = 8;
	fifthPlayerButton = 7;

	speakerPin = 12;

	ledShiftRegisterClk = A4;
	ledShiftRegisterData = A2;
	ledShiftRegisterRefresh = A3;

	displayShiftRegisterClk = 6;
	displayShiftRegisterData = 5;
	displayShiftRegisterRefresh = 4;

	player1 = 0;
	player2 = 1;
	player3 = 2;
	player4 = 3;
	player5 = 4;

	signalPeriod = 600;
	playerSignalPeriodFrequency = 1000;
	brainFaultStartFrequency = 900;
	adminSignalPeriodFrequency = 2000;
	wwwTenSecondsLeftFrequency = 2000;
	wwwPeriodExpiredFrequency = 3000;
	adminSet = 0;
	adminReset = 1;

	led[5] = 0b00000000;
	led[0] = 0b00000001;
	led[1] = 0b00000010;
	led[2] = 0b00000100;
	led[3] = 0b00001000;
	led[4] = 0b00010000;

	ownGameMainTimer= 30;
	ownGameSecondaryTimer = 10;

	brainRingMainTimer = 30;
	brainRingSecondaryTimer = 10;
}

ConstantsClass::~ConstantsClass()
{
}
ConstantsClass Constants;

<commit_msg>Display for v3.1<commit_after>//
//
//

#include "Constants.h"

ConstantsClass::ConstantsClass()
{
	adminStartButton = 3;
	adminResetButton = 2;

	firstPlayerButton = 11;
	secondPlayerButton = 10;
	thirdPlayerButton = 9;
	fourthPlayerButton = 8;
	fifthPlayerButton = 7;

	speakerPin = 12;

	ledShiftRegisterClk = A4;
	ledShiftRegisterData = A2;
	ledShiftRegisterRefresh = A3;

	displayShiftRegisterClk = 4;
	displayShiftRegisterData = 5;
	displayShiftRegisterRefresh = 6;

	player1 = 0;
	player2 = 1;
	player3 = 2;
	player4 = 3;
	player5 = 4;

	signalPeriod = 600;
	playerSignalPeriodFrequency = 1000;
	brainFaultStartFrequency = 900;
	adminSignalPeriodFrequency = 2000;
	wwwTenSecondsLeftFrequency = 2000;
	wwwPeriodExpiredFrequency = 3000;
	adminSet = 0;
	adminReset = 1;

	led[5] = 0b00000000;
	led[0] = 0b00000001;
	led[1] = 0b00000010;
	led[2] = 0b00000100;
	led[3] = 0b00001000;
	led[4] = 0b00010000;

	ownGameMainTimer= 30;
	ownGameSecondaryTimer = 10;

	brainRingMainTimer = 30;
	brainRingSecondaryTimer = 10;
}

ConstantsClass::~ConstantsClass()
{
}
ConstantsClass Constants;

<|endoftext|>


<commit_before>/* Definition of member functions of class Scanner */

#include "../headers/Scanner.hpp"

#include <string>
#include <sstream>
#ifdef DEBUG
# include <iostream>
# include <iomanip>
#endif

using namespace std;

Scanner::Scanner(FileReader* fileReader, ErrorReporter* errorReporter) :
  m_lineNo(1),
  m_column(1),
  m_currentToken(0),
  m_nTokens(0),
  m_nTokensProcessed(0),
  m_tokensLexemes(),
  m_keywordsMap(),
  m_errorReporter(errorReporter),
  m_fileReader(fileReader)
{
  buildKeywordsMap();
}

void Scanner::scan()
{
  if (m_fileReader->getTotalLines() > 0)
  {
    char currentChar;
    int nextState = 0, currentState = 0;
    TokenType_t token;
    string lexeme;

    string line;
    size_t lineLength;
    m_lineNo = 1;
    while (m_lineNo <= m_fileReader->getTotalLines() &&
           m_errorReporter->getErrors() < m_errorReporter->getMaxErrors())
    {
      line = m_fileReader->getTextAtLine(m_lineNo - 1);

      lineLength = line.length();
      m_column = 1;
      while (m_column <= lineLength &&
             m_errorReporter->getErrors() <= m_errorReporter->getMaxErrors())
      {
        currentChar = line.at(m_column - 1);
        nextState = automata[currentState][getTransitionIndex(currentChar)];

#ifdef DEBUG
        cout << "CState: " << setw(2) << currentState << "  NState: " <<
                setw(2) << nextState << "  TIndex: " <<
                setw(2) << getTransitionIndex(currentChar) <<
                " Char: ";
        if (!isspace(currentChar))
            cout << currentChar;
        else
            cout << ' ';
        cout << " : " << setw(3) << (int)currentChar << endl;
#endif

        if (nextState == STATE_ACCEPT_ERROR)
        {
          switch (currentState)
          {
          case 1 :
          case 2 : token = TOKEN_OCT;
            break;
          case 4 :
            token = TOKEN_HEX;
            break;
          case 5 :
            token = TOKEN_DEC;
            break;
          case 6 :
          case 11 :
            token = TOKEN_FLOAT;
            break;
          case 7 :
          case 26 :
            token = TOKEN_DELIMITER;
            break;
          case 8 :
            token = TOKEN_FLOAT;
            break;
          case 13 :
            token = TOKEN_STRING;
            break;
          case 14 :
          case 19 :
            token = TOKEN_ARITHOP;
            break;
          case 16 :
            token = TOKEN_LINECOMMENT;
            break;
          case 18 :
            token = TOKEN_MULTICOMMENT;
            break;
          case 22 :
          case 24 :
            token = TOKEN_LOGICOP;
            break;
          case 23 :
          case 27 :
            token = TOKEN_ASSIGNOP;
            break;
          case 25 :
          case 35 :
          case 36 :
            token = TOKEN_RELOP;
            break;
          case 28 :
            token = TOKEN_IDEN;
            if (m_keywordsMap.find(lexeme) != m_keywordsMap.end())
            {
              token = TOKEN_KEYWORD;
            }
            else if (lexeme.compare("verdadero") == 0 ||
                     lexeme.compare("falso") == 0)
            {
              token = TOKEN_LOGICCONST;
            }
            break;
          case 29 :
            token = TOKEN_DELIMITER;
            break;
          case 33 :
            token = TOKEN_CHARCONST;
            break;
          case 37 :
            token = TOKEN_NEWLINE;
            break;
          default :
#ifdef DEBUG
            cerr << "vecomp: error de estado siguiente" << endl;
#endif
            break;
          }

          if (token != TOKEN_LINECOMMENT && token != TOKEN_MULTICOMMENT)
          {
            m_tokensLexemes.push(TokenLexeme(token, lexeme, m_lineNo,
                                             m_column - lexeme.length()));
#ifdef DEBUG
            cout << "pushed element: " << setw(20) <<
                TokenLexeme::getTokenString(token) << ": " << setw(20) <<
                lexeme << "    at: " << m_lineNo << ", " <<
                m_column - lexeme.length() << endl;
#endif
          }

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
          --m_column;
        }
        else if (nextState == STATE_ERROR)
        {
#ifdef DEBUG
          cout << "calling lexicalerror" << currentState << " " <<
              currentChar << endl;
#endif
          m_errorReporter->writeLexicalError(currentState, currentChar, lexeme,
                                             m_lineNo, m_column);

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
        }
        else if ( isspace(currentChar) &&
                 (currentState == 12 || currentState == 15 ||
                  currentState == 17))
          lexeme += currentChar;
        else if (!isspace(currentChar))
          lexeme += currentChar;

        currentState = nextState;

        ++m_column;
      }
      ++m_lineNo;
      line = "";
    }

#ifdef DEBUG
    cout << "final state: " << currentState << endl;
#endif
    if (currentState != 0 && !isTerminalState(currentState))
      m_errorReporter->writeLexicalError(currentState, currentChar, lexeme,
                                         m_lineNo, m_column);

    m_nTokens = m_tokensLexemes.size();

    if (m_tokensLexemes.empty())
    {
      m_errorReporter->writeError("archivo vacio");
    }
  }
}

TokenLexeme Scanner::getNextTokenLexeme()
{
  TokenLexeme temporal;
  if (!m_tokensLexemes.empty())
  {
    temporal = m_tokensLexemes.front();
    m_tokensLexemes.pop();
  }
  ++m_nTokensProcessed;

  return temporal;
}

Transition_t Scanner::getTransitionIndex(char character)
{
  Transition_t transitionIndex = TRANS_ANY;

  if (isdigit(character))
  {
    if (character == '0')
      transitionIndex = TRANS_ZERO;
    else if (character <= '7')
      transitionIndex = TRANS_OCT;
    else
      transitionIndex = TRANS_DEC;
  }
  else if (isalpha(character))
  {
    if (tolower(character) == 'e')
      transitionIndex = TRANS_E;
    else if (tolower(character) == 'x')
      transitionIndex = TRANS_X;
    else if (tolower(character) <= 'f')
      transitionIndex = TRANS_HEX;
    else
      transitionIndex = TRANS_LETTER;
  }
  else
  {
    switch (character)
    {
    case '|' :
      transitionIndex = TRANS_PIPE;
      break;
    case '&' :
      transitionIndex = TRANS_AMPERS;
      break;
    case '!' :
      transitionIndex = TRANS_EXCLAMATION;
      break;
    case ' ' :
    case '\t' :
    case '\r' :
      transitionIndex = TRANS_SPACE;
      break;
    case '\n' :
      transitionIndex = TRANS_NEWLINE;
      break;
    case ',' :
    case ';' :
    case '(' :
    case ')' :
    case '[' :
    case ']' :
    case '{' :
    case '}' :
      transitionIndex = TRANS_DELIMITER;
      break;
    case '+' :
    case '-' :
      transitionIndex = TRANS_SIGN;
      break;
    case '*' :
      transitionIndex = TRANS_ASTERISK;
      break;
    case '/' :
      transitionIndex = TRANS_SLASH;
      break;
    case '%' :
    case '^' :
      transitionIndex = TRANS_ARITHMETIC;
      break;
    case ':' :
      transitionIndex = TRANS_COLON;
      break;
    case '=' :
      transitionIndex = TRANS_EQUAL;
      break;
    case '<' :
      transitionIndex = TRANS_LESSER;
      break;
    case '>' :
      transitionIndex = TRANS_GREATER;
      break;
    case '_' :
      transitionIndex = TRANS_UNDERSCORE;
      break;
    case '\'' :
      transitionIndex = TRANS_SQUOTE;
      break;
    case '\\' :
      transitionIndex = TRANS_BACKSLASH;
    case '"' :
      transitionIndex = TRANS_DQUOTE;
      break;
    case '.' :
      transitionIndex = TRANS_DOT;
      break;
    default :
      transitionIndex = TRANS_ANY;
      break;
    }
  }

  return transitionIndex;
}

int Scanner::getMaxTokens() const
{
  return m_nTokens;
}

int Scanner::getTokensProcessed() const
{
  return m_nTokensProcessed;
}

bool Scanner::isTerminalState(int state)
{
  switch (state)
  {
  case 1 :
  case 2 :
  case 4 :
  case 5 :
  case 6 :
  case 7 :
  case 8 :
  case 11 :
  case 13 :
  case 14 :
  case 16 :
  case 18 :
  case 19 :
  case 22 :
  case 23 :
  case 24 :
  case 25 :
  case 26 :
  case 27 :
  case 28 :
  case 29 :
  case 33 :
  case 35 :
  case 36 :
  case 37 :
    return true;
    break;
  }

  return false;
}

void Scanner::buildKeywordsMap()
{
  m_keywordsMap["alfanumerico"] = KEYWORD_ALPHANUM;
  m_keywordsMap["canal"] =        KEYWORD_CHANNEL;
  m_keywordsMap["caracter"] =     KEYWORD_CHAR;
  m_keywordsMap["caso"] =         KEYWORD_CASE;
  m_keywordsMap["const"] =        KEYWORD_CONST;
  m_keywordsMap["continua"] =     KEYWORD_CONTINUE;
  m_keywordsMap["defecto"] =      KEYWORD_DEFAULT;
  m_keywordsMap["desde"] =        KEYWORD_FOR;
  m_keywordsMap["diferir"] =      KEYWORD_DIFFER;
  m_keywordsMap["div"] =          KEYWORD_DIV;
  m_keywordsMap["entero"] =       KEYWORD_INT;
  m_keywordsMap["enteros"] =      KEYWORD_UINT;
  m_keywordsMap["estructura"] =   KEYWORD_STRUCT;
  m_keywordsMap["funcion"] =      KEYWORD_FUNCTION;
  m_keywordsMap["importar"] =     KEYWORD_IMPORT;
  m_keywordsMap["interfaz"] =     KEYWORD_INTERFACE;
  m_keywordsMap["interrumpe"] =   KEYWORD_BREAK;
  m_keywordsMap["ir"] =           KEYWORD_GO;
  m_keywordsMap["ir_a"] =         KEYWORD_GOTO;
  m_keywordsMap["logico"] =       KEYWORD_LOGIC;
  m_keywordsMap["mapa"] =         KEYWORD_MAP;
  m_keywordsMap["mod"] =          KEYWORD_MOD;
  m_keywordsMap["paquete"] =      KEYWORD_PACKET;
  m_keywordsMap["principal"] =    KEYWORD_MAIN;
  m_keywordsMap["rango"] =        KEYWORD_RANGE;
  m_keywordsMap["real"] =         KEYWORD_REAL;
  m_keywordsMap["regresa"] =      KEYWORD_RETURN;
  m_keywordsMap["si"] =           KEYWORD_IF;
  m_keywordsMap["sino"] =         KEYWORD_ELSE;
  m_keywordsMap["selecciona"] =   KEYWORD_SELECT;
  m_keywordsMap["tipo"] =         KEYWORD_TYPE;
  m_keywordsMap["valor"] =        KEYWORD_SWITCH;
  m_keywordsMap["variable"] =     KEYWORD_VAR;
}

<commit_msg>changed wrong keyword 'var'<commit_after>/* Definition of member functions of class Scanner */

#include "../headers/Scanner.hpp"

#include <string>
#include <sstream>
#ifdef DEBUG
# include <iostream>
# include <iomanip>
#endif

using namespace std;

Scanner::Scanner(FileReader* fileReader, ErrorReporter* errorReporter) :
  m_lineNo(1),
  m_column(1),
  m_currentToken(0),
  m_nTokens(0),
  m_nTokensProcessed(0),
  m_tokensLexemes(),
  m_keywordsMap(),
  m_errorReporter(errorReporter),
  m_fileReader(fileReader)
{
  buildKeywordsMap();
}

void Scanner::scan()
{
  if (m_fileReader->getTotalLines() > 0)
  {
    char currentChar;
    int nextState = 0, currentState = 0;
    TokenType_t token;
    string lexeme;

    string line;
    size_t lineLength;
    m_lineNo = 1;
    while (m_lineNo <= m_fileReader->getTotalLines() &&
           m_errorReporter->getErrors() < m_errorReporter->getMaxErrors())
    {
      line = m_fileReader->getTextAtLine(m_lineNo - 1);

      lineLength = line.length();
      m_column = 1;
      while (m_column <= lineLength &&
             m_errorReporter->getErrors() <= m_errorReporter->getMaxErrors())
      {
        currentChar = line.at(m_column - 1);
        nextState = automata[currentState][getTransitionIndex(currentChar)];

#ifdef DEBUG
        cout << "CState: " << setw(2) << currentState << "  NState: " <<
                setw(2) << nextState << "  TIndex: " <<
                setw(2) << getTransitionIndex(currentChar) <<
                " Char: ";
        if (!isspace(currentChar))
            cout << currentChar;
        else
            cout << ' ';
        cout << " : " << setw(3) << (int)currentChar << endl;
#endif

        if (nextState == STATE_ACCEPT_ERROR)
        {
          switch (currentState)
          {
          case 1 :
          case 2 : token = TOKEN_OCT;
            break;
          case 4 :
            token = TOKEN_HEX;
            break;
          case 5 :
            token = TOKEN_DEC;
            break;
          case 6 :
          case 11 :
            token = TOKEN_FLOAT;
            break;
          case 7 :
          case 26 :
            token = TOKEN_DELIMITER;
            break;
          case 8 :
            token = TOKEN_FLOAT;
            break;
          case 13 :
            token = TOKEN_STRING;
            break;
          case 14 :
          case 19 :
            token = TOKEN_ARITHOP;
            break;
          case 16 :
            token = TOKEN_LINECOMMENT;
            break;
          case 18 :
            token = TOKEN_MULTICOMMENT;
            break;
          case 22 :
          case 24 :
            token = TOKEN_LOGICOP;
            break;
          case 23 :
          case 27 :
            token = TOKEN_ASSIGNOP;
            break;
          case 25 :
          case 35 :
          case 36 :
            token = TOKEN_RELOP;
            break;
          case 28 :
            token = TOKEN_IDEN;
            if (m_keywordsMap.find(lexeme) != m_keywordsMap.end())
            {
              token = TOKEN_KEYWORD;
            }
            else if (lexeme.compare("verdadero") == 0 ||
                     lexeme.compare("falso") == 0)
            {
              token = TOKEN_LOGICCONST;
            }
            break;
          case 29 :
            token = TOKEN_DELIMITER;
            break;
          case 33 :
            token = TOKEN_CHARCONST;
            break;
          case 37 :
            token = TOKEN_NEWLINE;
            break;
          default :
#ifdef DEBUG
            cerr << "vecomp: error de estado siguiente" << endl;
#endif
            break;
          }

          if (token != TOKEN_LINECOMMENT && token != TOKEN_MULTICOMMENT)
          {
            m_tokensLexemes.push(TokenLexeme(token, lexeme, m_lineNo,
                                             m_column - lexeme.length()));
#ifdef DEBUG
            cout << "pushed element: " << setw(20) <<
                TokenLexeme::getTokenString(token) << ": " << setw(20) <<
                lexeme << "    at: " << m_lineNo << ", " <<
                m_column - lexeme.length() << endl;
#endif
          }

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
          --m_column;
        }
        else if (nextState == STATE_ERROR)
        {
#ifdef DEBUG
          cout << "calling lexicalerror" << currentState << " " <<
              currentChar << endl;
#endif
          m_errorReporter->writeLexicalError(currentState, currentChar, lexeme,
                                             m_lineNo, m_column);

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
        }
        else if ( isspace(currentChar) &&
                 (currentState == 12 || currentState == 15 ||
                  currentState == 17))
          lexeme += currentChar;
        else if (!isspace(currentChar))
          lexeme += currentChar;

        currentState = nextState;

        ++m_column;
      }
      ++m_lineNo;
      line = "";
    }

#ifdef DEBUG
    cout << "final state: " << currentState << endl;
#endif
    if (currentState != 0 && !isTerminalState(currentState))
      m_errorReporter->writeLexicalError(currentState, currentChar, lexeme,
                                         m_lineNo, m_column);

    m_nTokens = m_tokensLexemes.size();

    if (m_tokensLexemes.empty())
    {
      m_errorReporter->writeError("archivo vacio");
    }
  }
}

TokenLexeme Scanner::getNextTokenLexeme()
{
  TokenLexeme temporal;
  if (!m_tokensLexemes.empty())
  {
    temporal = m_tokensLexemes.front();
    m_tokensLexemes.pop();
  }
  ++m_nTokensProcessed;

  return temporal;
}

Transition_t Scanner::getTransitionIndex(char character)
{
  Transition_t transitionIndex = TRANS_ANY;

  if (isdigit(character))
  {
    if (character == '0')
      transitionIndex = TRANS_ZERO;
    else if (character <= '7')
      transitionIndex = TRANS_OCT;
    else
      transitionIndex = TRANS_DEC;
  }
  else if (isalpha(character))
  {
    if (tolower(character) == 'e')
      transitionIndex = TRANS_E;
    else if (tolower(character) == 'x')
      transitionIndex = TRANS_X;
    else if (tolower(character) <= 'f')
      transitionIndex = TRANS_HEX;
    else
      transitionIndex = TRANS_LETTER;
  }
  else
  {
    switch (character)
    {
    case '|' :
      transitionIndex = TRANS_PIPE;
      break;
    case '&' :
      transitionIndex = TRANS_AMPERS;
      break;
    case '!' :
      transitionIndex = TRANS_EXCLAMATION;
      break;
    case ' ' :
    case '\t' :
    case '\r' :
      transitionIndex = TRANS_SPACE;
      break;
    case '\n' :
      transitionIndex = TRANS_NEWLINE;
      break;
    case ',' :
    case ';' :
    case '(' :
    case ')' :
    case '[' :
    case ']' :
    case '{' :
    case '}' :
      transitionIndex = TRANS_DELIMITER;
      break;
    case '+' :
    case '-' :
      transitionIndex = TRANS_SIGN;
      break;
    case '*' :
      transitionIndex = TRANS_ASTERISK;
      break;
    case '/' :
      transitionIndex = TRANS_SLASH;
      break;
    case '%' :
    case '^' :
      transitionIndex = TRANS_ARITHMETIC;
      break;
    case ':' :
      transitionIndex = TRANS_COLON;
      break;
    case '=' :
      transitionIndex = TRANS_EQUAL;
      break;
    case '<' :
      transitionIndex = TRANS_LESSER;
      break;
    case '>' :
      transitionIndex = TRANS_GREATER;
      break;
    case '_' :
      transitionIndex = TRANS_UNDERSCORE;
      break;
    case '\'' :
      transitionIndex = TRANS_SQUOTE;
      break;
    case '\\' :
      transitionIndex = TRANS_BACKSLASH;
    case '"' :
      transitionIndex = TRANS_DQUOTE;
      break;
    case '.' :
      transitionIndex = TRANS_DOT;
      break;
    default :
      transitionIndex = TRANS_ANY;
      break;
    }
  }

  return transitionIndex;
}

int Scanner::getMaxTokens() const
{
  return m_nTokens;
}

int Scanner::getTokensProcessed() const
{
  return m_nTokensProcessed;
}

bool Scanner::isTerminalState(int state)
{
  switch (state)
  {
  case 1 :
  case 2 :
  case 4 :
  case 5 :
  case 6 :
  case 7 :
  case 8 :
  case 11 :
  case 13 :
  case 14 :
  case 16 :
  case 18 :
  case 19 :
  case 22 :
  case 23 :
  case 24 :
  case 25 :
  case 26 :
  case 27 :
  case 28 :
  case 29 :
  case 33 :
  case 35 :
  case 36 :
  case 37 :
    return true;
    break;
  }

  return false;
}

void Scanner::buildKeywordsMap()
{
  m_keywordsMap["alfanumerico"] = KEYWORD_ALPHANUM;
  m_keywordsMap["canal"] =        KEYWORD_CHANNEL;
  m_keywordsMap["caracter"] =     KEYWORD_CHAR;
  m_keywordsMap["caso"] =         KEYWORD_CASE;
  m_keywordsMap["const"] =        KEYWORD_CONST;
  m_keywordsMap["continua"] =     KEYWORD_CONTINUE;
  m_keywordsMap["defecto"] =      KEYWORD_DEFAULT;
  m_keywordsMap["desde"] =        KEYWORD_FOR;
  m_keywordsMap["diferir"] =      KEYWORD_DIFFER;
  m_keywordsMap["div"] =          KEYWORD_DIV;
  m_keywordsMap["entero"] =       KEYWORD_INT;
  m_keywordsMap["enteros"] =      KEYWORD_UINT;
  m_keywordsMap["estructura"] =   KEYWORD_STRUCT;
  m_keywordsMap["funcion"] =      KEYWORD_FUNCTION;
  m_keywordsMap["importar"] =     KEYWORD_IMPORT;
  m_keywordsMap["interfaz"] =     KEYWORD_INTERFACE;
  m_keywordsMap["interrumpe"] =   KEYWORD_BREAK;
  m_keywordsMap["ir"] =           KEYWORD_GO;
  m_keywordsMap["ir_a"] =         KEYWORD_GOTO;
  m_keywordsMap["logico"] =       KEYWORD_LOGIC;
  m_keywordsMap["mapa"] =         KEYWORD_MAP;
  m_keywordsMap["mod"] =          KEYWORD_MOD;
  m_keywordsMap["paquete"] =      KEYWORD_PACKET;
  m_keywordsMap["principal"] =    KEYWORD_MAIN;
  m_keywordsMap["rango"] =        KEYWORD_RANGE;
  m_keywordsMap["real"] =         KEYWORD_REAL;
  m_keywordsMap["regresa"] =      KEYWORD_RETURN;
  m_keywordsMap["si"] =           KEYWORD_IF;
  m_keywordsMap["sino"] =         KEYWORD_ELSE;
  m_keywordsMap["selecciona"] =   KEYWORD_SELECT;
  m_keywordsMap["tipo"] =         KEYWORD_TYPE;
  m_keywordsMap["valor"] =        KEYWORD_SWITCH;
  m_keywordsMap["var"] =          KEYWORD_VAR;
}

<|endoftext|>


<commit_before>
#include <algorithm>
#include <queue>
#include <iostream>
#include <sstream>

#include <treezeug/Tree.h>

#include "TreeData.h"

namespace zeug
{

Tree::Tree(const std::string & name)
: m_data(new TreeData(name))
, m_root(m_data->m_root)
{
}

Tree::Tree(std::shared_ptr<TreeData> data)
: m_data(data)
, m_root(m_data->m_root)
{
}

Tree::Tree(const Tree& other)
: m_data(other.m_data)
, m_root(other.m_root)
{
}

Tree::~Tree()
{
}

Tree * Tree::copy() const
{
    return new Tree(*this);
}

Tree * Tree::restrictTo(Node * newRoot) const
{
    Tree* newTree = copy();
    newTree->m_root = newRoot;
    return newTree;
}

Tree * Tree::restrictTo(int id) const
{
	Node* newRoot = getNode(id);

	if (!newRoot)
		return nullptr;

	return restrictTo(newRoot);
}

const std::string & Tree::name() const
{
    return m_data->m_name;
}

void Tree::setName(const std::string & name)
{
    m_data->m_name = name;
}

Node * Tree::root()
{
    if (m_root == nullptr)
    {
        m_root = m_data->m_root;
    }

    return m_root;
}

const Node * Tree::root() const
{
    if (m_root == nullptr)
    {
        m_root = m_data->m_root;
    }

    return m_root;
}

void Tree::setRoot(Node * node, int id)
{
    if (m_root == m_data->m_root)
    {
        std::cout << "#warning: replacing inner root while Trees have pointers to old root";
        m_root = nullptr;
    }

    m_data->setRoot(node, id);
}

unsigned Tree::size() const
{
    return m_root->size();
}

int Tree::maxId() const
{
    return m_data->m_nextId - 1;
}

unsigned Tree::depth() const
{
    return m_data->m_depth;
}

Node * Tree::getNode(int id) const
{
    if (!m_data->m_idMap.count(id))
		return nullptr;

    return m_data->m_idMap.at(id);
}

Node * Tree::getNodeByPath(const std::string & path, char separator)
{
	if (path.empty())
        return nullptr;

    if (path == std::to_string(separator))
        return m_data->m_root;

    std::stringstream ss(path);
	std::string item;

    Node * node = m_data->m_root;

	std::getline(ss, item, separator);
	if (!item.empty())
        return nullptr;

    while (node && std::getline(ss, item, separator))
	{
        node = node->getChildByName(item);
    }

    return node;
}

const std::vector<std::string> & Tree::attributes() const
{
    return m_data->m_attributes;
}

bool Tree::hasAttributeMap(const std::string & name) const
{
    return m_data->hasAttributeMap(name);
}

void Tree::addAttributeMap(const std::string & name, AttributeMap::Type type)
{
	if (hasAttributeMap(name))
	{
		if (attributeMapType(name) != type)
		{
			std::cout << "Try to overwrite AttributeMap " << name << " with differing type";
		}
		return;
	}

    m_data->m_attributeMaps[name] = new AttributeMap(name, type);
    m_data->m_attributes.push_back(name);
}

AttributeMap::Type Tree::attributeMapType(const std::string & name) const
{
	if (!hasAttributeMap(name))
		return AttributeMap::None;

    return m_data->m_attributeMaps.at(name)->type();
}

void Tree::renormalizeAttributeForLeaves(const std::string& attribute)
{
    if (!hasAttributeMap(attribute))
        return;

    m_data->m_attributeMaps.at(attribute)->renormalizeForLeaves();
}

void Tree::nodesDo(std::function<void(Node*)> action)
{
    m_root->withAllChildrenDo(action);
}

void Tree::nodesDo(std::function<void(const Node*)> action) const
{
    const_cast<const Node*>(m_root)->withAllChildrenDo(action); // const cast to prevent unnecessary ambiguous warning (gcc compiler bug?)
}

void Tree::leavesDo(std::function<void(Node*)> action)
{
	nodesDo([&action](Node * node)
    {
		if (node->isLeaf())
            action(node);
	});
}

void Tree::leavesDo(std::function<void(const Node*)> action) const
{
	nodesDo([&action](const Node * node)
    {
		if (node->isLeaf())
            action(node);
	});
}

void Tree::nodesOrderedByDepthDo(std::function<void(Node*)> action)
{
	std::queue<Node*> queue;

    queue.push(root());

	while (!queue.empty())
	{
		Node * current = queue.front();
		queue.pop();

		action(current);

		for (Node * child : current->children())
			queue.push(child);
	}
}

void Tree::nodesOrderedByDepthDo(std::function<void(const Node*)> action) const
{
	std::queue<const Node*> queue;

    queue.push(root());

	while (!queue.empty())
	{
		const Node* current = queue.front();
		queue.pop();

		action(current);

		for (const Node * child : current->children())
			queue.push(child);
	}
}

} // namespace zeug
<commit_msg>Add missing endline<commit_after>
#include <algorithm>
#include <queue>
#include <iostream>
#include <sstream>

#include <treezeug/Tree.h>

#include "TreeData.h"

namespace zeug
{

Tree::Tree(const std::string & name)
: m_data(new TreeData(name))
, m_root(m_data->m_root)
{
}

Tree::Tree(std::shared_ptr<TreeData> data)
: m_data(data)
, m_root(m_data->m_root)
{
}

Tree::Tree(const Tree& other)
: m_data(other.m_data)
, m_root(other.m_root)
{
}

Tree::~Tree()
{
}

Tree * Tree::copy() const
{
    return new Tree(*this);
}

Tree * Tree::restrictTo(Node * newRoot) const
{
    Tree* newTree = copy();
    newTree->m_root = newRoot;
    return newTree;
}

Tree * Tree::restrictTo(int id) const
{
	Node* newRoot = getNode(id);

	if (!newRoot)
		return nullptr;

	return restrictTo(newRoot);
}

const std::string & Tree::name() const
{
    return m_data->m_name;
}

void Tree::setName(const std::string & name)
{
    m_data->m_name = name;
}

Node * Tree::root()
{
    if (m_root == nullptr)
    {
        m_root = m_data->m_root;
    }

    return m_root;
}

const Node * Tree::root() const
{
    if (m_root == nullptr)
    {
        m_root = m_data->m_root;
    }

    return m_root;
}

void Tree::setRoot(Node * node, int id)
{
    if (m_root == m_data->m_root)
    {
        std::cout << "#warning: replacing inner root while Trees have pointers to old root" << std::endl;
        m_root = nullptr;
    }

    m_data->setRoot(node, id);
}

unsigned Tree::size() const
{
    return m_root->size();
}

int Tree::maxId() const
{
    return m_data->m_nextId - 1;
}

unsigned Tree::depth() const
{
    return m_data->m_depth;
}

Node * Tree::getNode(int id) const
{
    if (!m_data->m_idMap.count(id))
		return nullptr;

    return m_data->m_idMap.at(id);
}

Node * Tree::getNodeByPath(const std::string & path, char separator)
{
	if (path.empty())
        return nullptr;

    if (path == std::to_string(separator))
        return m_data->m_root;

    std::stringstream ss(path);
	std::string item;

    Node * node = m_data->m_root;

	std::getline(ss, item, separator);
	if (!item.empty())
        return nullptr;

    while (node && std::getline(ss, item, separator))
	{
        node = node->getChildByName(item);
    }

    return node;
}

const std::vector<std::string> & Tree::attributes() const
{
    return m_data->m_attributes;
}

bool Tree::hasAttributeMap(const std::string & name) const
{
    return m_data->hasAttributeMap(name);
}

void Tree::addAttributeMap(const std::string & name, AttributeMap::Type type)
{
	if (hasAttributeMap(name))
	{
		if (attributeMapType(name) != type)
		{
			std::cout << "Try to overwrite AttributeMap " << name << " with differing type";
		}
		return;
	}

    m_data->m_attributeMaps[name] = new AttributeMap(name, type);
    m_data->m_attributes.push_back(name);
}

AttributeMap::Type Tree::attributeMapType(const std::string & name) const
{
	if (!hasAttributeMap(name))
		return AttributeMap::None;

    return m_data->m_attributeMaps.at(name)->type();
}

void Tree::renormalizeAttributeForLeaves(const std::string& attribute)
{
    if (!hasAttributeMap(attribute))
        return;

    m_data->m_attributeMaps.at(attribute)->renormalizeForLeaves();
}

void Tree::nodesDo(std::function<void(Node*)> action)
{
    m_root->withAllChildrenDo(action);
}

void Tree::nodesDo(std::function<void(const Node*)> action) const
{
    const_cast<const Node*>(m_root)->withAllChildrenDo(action); // const cast to prevent unnecessary ambiguous warning (gcc compiler bug?)
}

void Tree::leavesDo(std::function<void(Node*)> action)
{
	nodesDo([&action](Node * node)
    {
		if (node->isLeaf())
            action(node);
	});
}

void Tree::leavesDo(std::function<void(const Node*)> action) const
{
	nodesDo([&action](const Node * node)
    {
		if (node->isLeaf())
            action(node);
	});
}

void Tree::nodesOrderedByDepthDo(std::function<void(Node*)> action)
{
	std::queue<Node*> queue;

    queue.push(root());

	while (!queue.empty())
	{
		Node * current = queue.front();
		queue.pop();

		action(current);

		for (Node * child : current->children())
			queue.push(child);
	}
}

void Tree::nodesOrderedByDepthDo(std::function<void(const Node*)> action) const
{
	std::queue<const Node*> queue;

    queue.push(root());

	while (!queue.empty())
	{
		const Node* current = queue.front();
		queue.pop();

		action(current);

		for (const Node * child : current->children())
			queue.push(child);
	}
}

} // namespace zeug
<|endoftext|>


<commit_before>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "leveldb/table.h"

#include "leveldb/cache.h"
#include "leveldb/comparator.h"
#include "leveldb/env.h"
#include "leveldb/filter_policy.h"
#include "leveldb/options.h"
#include "leveldb/perf_count.h"
#include "table/block.h"
#include "table/filter_block.h"
#include "table/format.h"
#include "table/two_level_iterator.h"
#include "util/coding.h"

namespace leveldb {

struct Table::Rep {
  ~Rep() {
    delete filter;
    delete [] filter_data;
    delete index_block;
  }

  Options options;
  Status status;
  RandomAccessFile* file;
  uint64_t file_size;
  uint64_t cache_id;
  FilterBlockReader* filter;
  const char* filter_data;
  size_t filter_data_size;

  BlockHandle metaindex_handle;  // Handle to metaindex_block: saved from footer
  Block* index_block;
  SstCounters sst_counters;
  BlockHandle filter_handle;
  const FilterPolicy * filter_policy;
  volatile uint32_t filter_flag;
};

Status Table::Open(const Options& options,
                   RandomAccessFile* file,
                   uint64_t size,
                   Table** table) {
  *table = NULL;
  if (size < Footer::kEncodedLength) {
    return Status::InvalidArgument("file is too short to be an sstable");
  }

  char footer_space[Footer::kEncodedLength];
  // stop valgrind uninitialize warning
  // let footer.DecodeFrom returned status do the talking for read of bad info
  memset(footer_space, 0, Footer::kEncodedLength);

  Slice footer_input;
  Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,
                        &footer_input, footer_space);
  if (!s.ok()) return s;

  Footer footer;
  s = footer.DecodeFrom(&footer_input);
  if (!s.ok()) return s;

  // Read the index block
  BlockContents contents;
  Block* index_block = NULL;
  if (s.ok()) {
    s = ReadBlock(file, ReadOptions(), footer.index_handle(), &contents);
    if (s.ok()) {
      index_block = new Block(contents);
    }
  }

  if (s.ok()) {
    // We've successfully read the footer and the index block: we're
    // ready to serve requests.
    Rep* rep = new Table::Rep;
    rep->options = options;
    rep->file = file;
    rep->file_size = size;
    rep->metaindex_handle = footer.metaindex_handle();
    rep->index_block = index_block;
    rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0);
    rep->filter_data = NULL;
    rep->filter_data_size = 0;
    rep->filter = NULL;
    rep->filter_policy = NULL;
    rep->filter_flag = 0;
    *table = new Table(rep);
    (*table)->ReadMeta(footer);
  } else {
    if (index_block) delete index_block;
  }

  return s;
}

void Table::ReadMeta(const Footer& footer) {

  // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates
  // it is an empty block.
  std::string key;
  ReadOptions opt;
  BlockContents contents;

  if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) {
    // Do not propagate errors since meta info is not needed for operation
    return;
  }
  Block* meta = new Block(contents);

  Iterator* iter = meta->NewIterator(BytewiseComparator());

  // read filter only if policy set
  if (NULL != rep_->options.filter_policy) {
      bool found,first;
      const FilterPolicy * policy, * next;

      first=true;
      next=NULL;

      do
      {
          found=false;

          if (first)
          {
              policy=rep_->options.filter_policy;
              next=FilterInventory::ListHead;
              first=false;
          }   // if
          else
          {
              policy=next;
              if (NULL!=policy)
                  next=policy->GetNext();
              else
                  next=NULL;
          }   // else

          if (NULL!=policy)
          {
              key = "filter.";
              key.append(policy->Name());
              iter->Seek(key);
              if (iter->Valid() && iter->key() == Slice(key))
              {
#if 0
                  ReadFilter(iter->value(), policy);
                  gPerfCounters->Inc(ePerfBlockFilterRead);
#else
                  Slice v = iter->value();
                  rep_->filter_handle.DecodeFrom(&v);
                  rep_->filter_policy = policy;
#endif
                  found=true;
              }   // if
          }   //if
      } while(!found && NULL!=policy);
  }   // if

  // always read counters
  key="stats.sst1";
  iter->Seek(key);
  if (iter->Valid() && iter->key() == Slice(key)) {
      ReadSstCounters(iter->value());
  }

  delete iter;
  delete meta;
}

// public version that reads filter at some time
//  after open ... true if filter read
bool
Table::ReadFilter()
{
    bool ret_flag;

    ret_flag=false;

    if (0!=rep_->filter_handle.size()
        && NULL!=rep_->filter_policy
        && 1 == inc_and_fetch(&rep_->filter_flag))
    {
        gPerfCounters->Inc(ePerfBlockFilterRead);

        ReadFilter(rep_->filter_handle, rep_->filter_policy);
        ret_flag=(NULL != rep_->filter);

        // only attempt the read once
        rep_->filter_handle.set_size(0);
    }   // if

    return(ret_flag);
}   // ReadFilter

void
Table::ReadFilter(
//    const Slice& filter_handle_value,
    BlockHandle & filter_handle,
    const FilterPolicy * policy)
{
#if 0
  Slice v = filter_handle_value;
  BlockHandle filter_handle;
  if (!filter_handle.DecodeFrom(&v).ok()) {
    return;
  }
#endif

  // We might want to unify with ReadBlock() if we start
  // requiring checksum verification in Table::Open.
  ReadOptions opt;
  BlockContents block;
  if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) {
    return;
  }
  if (block.heap_allocated) {
    rep_->filter_data = block.data.data();     // Will need to delete later
    rep_->filter_data_size = block.data.size();
  }

  rep_->filter = new FilterBlockReader(policy, block.data);
}

void Table::ReadSstCounters(const Slice& sst_counters_handle_value) {
  Slice v = sst_counters_handle_value;
  BlockHandle counters_handle;
  if (!counters_handle.DecodeFrom(&v).ok()) {
    return;
  }

  // We might want to unify with ReadBlock() if we start
  // requiring checksum verification in Table::Open.
  ReadOptions opt;
  BlockContents block;
  if (!ReadBlock(rep_->file, opt, counters_handle, &block).ok()) {
    return;
  }
  if (block.heap_allocated) {
    rep_->sst_counters.DecodeFrom(block.data);
    delete [] block.data.data();
  }

}

SstCounters Table::GetSstCounters() const
{
    return(rep_->sst_counters);
}   // Table::GetSstCounters

Table::~Table() {
  delete rep_;
}

static void DeleteBlock(void* arg, void* ignored) {
  delete reinterpret_cast<Block*>(arg);
}

static void DeleteCachedBlock(const Slice& key, void* value) {
  Block* block = reinterpret_cast<Block*>(value);
  delete block;
}

static void ReleaseBlock(void* arg, void* h) {
  Cache* cache = reinterpret_cast<Cache*>(arg);
  Cache::Handle* handle = reinterpret_cast<Cache::Handle*>(h);
  cache->Release(handle);
}

// Convert an index iterator value (i.e., an encoded BlockHandle)
// into an iterator over the contents of the corresponding block.
Iterator* Table::BlockReader(void* arg,
                             const ReadOptions& options,
                             const Slice& index_value) {
  Table* table = reinterpret_cast<Table*>(arg);
  Cache* block_cache = table->rep_->options.block_cache;
  Block* block = NULL;
  Cache::Handle* cache_handle = NULL;

  BlockHandle handle;
  Slice input = index_value;
  Status s = handle.DecodeFrom(&input);
  // We intentionally allow extra stuff in index_value so that we
  // can add more features in the future.

  if (s.ok()) {
    BlockContents contents;
    if (block_cache != NULL) {
      char cache_key_buffer[16];
      EncodeFixed64(cache_key_buffer, table->rep_->cache_id);
      EncodeFixed64(cache_key_buffer+8, handle.offset());
      Slice key(cache_key_buffer, sizeof(cache_key_buffer));
      cache_handle = block_cache->Lookup(key);
      if (cache_handle != NULL) {
        block = reinterpret_cast<Block*>(block_cache->Value(cache_handle));
        gPerfCounters->Inc(ePerfBlockCached);
      } else {
        s = ReadBlock(table->rep_->file, options, handle, &contents);
        gPerfCounters->Inc(ePerfBlockRead);
        if (s.ok()) {
          block = new Block(contents);
          if (contents.cachable && options.fill_cache) {
            cache_handle = block_cache->Insert(
                key, block,
                (block->size() + /*block_cache->EntryOverheadSize() +*/ sizeof(cache_key_buffer)),
                &DeleteCachedBlock);
          }
        }
      }
    } else {
      s = ReadBlock(table->rep_->file, options, handle, &contents);
        gPerfCounters->Inc(ePerfBlockRead);
      if (s.ok()) {
        block = new Block(contents);
      }
    }
  }

  Iterator* iter;
  if (block != NULL) {
    iter = block->NewIterator(table->rep_->options.comparator);
    if (cache_handle == NULL) {
      iter->RegisterCleanup(&DeleteBlock, block, NULL);
    } else {
      iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle);
    }
  } else {
    iter = NewErrorIterator(s);
  }
  return iter;
}

Iterator* Table::NewIterator(const ReadOptions& options) const {
  return NewTwoLevelIterator(
      rep_->index_block->NewIterator(rep_->options.comparator),
      &Table::BlockReader, const_cast<Table*>(this), options);
}

Status Table::InternalGet(const ReadOptions& options, const Slice& k,
                          void* arg,
                          bool (*saver)(void*, const Slice&, const Slice&)) {
  Status s;
  Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);
  iiter->Seek(k);
  if (iiter->Valid()) {
    Slice handle_value = iiter->value();
    FilterBlockReader* filter = rep_->filter;
    BlockHandle handle;
    if (filter != NULL &&
        handle.DecodeFrom(&handle_value).ok() &&
        !filter->KeyMayMatch(handle.offset(), k)) {
      // Not found
        gPerfCounters->Inc(ePerfBlockFiltered);
    } else {
      Iterator* block_iter = BlockReader(this, options, iiter->value());
      block_iter->Seek(k);
      if (block_iter->Valid()) {
        bool match;
        match=(*saver)(arg, block_iter->key(), block_iter->value());
        if (!match && NULL!=filter)
            gPerfCounters->Inc(ePerfBlockFilterFalse);
        if (match)
            gPerfCounters->Inc(ePerfBlockValidGet);
      }

      s = block_iter->status();
      delete block_iter;
    }
  }
  if (s.ok()) {
    s = iiter->status();
  }
  delete iiter;
  return s;
}

uint64_t Table::ApproximateOffsetOf(const Slice& key) const {
  Iterator* index_iter =
      rep_->index_block->NewIterator(rep_->options.comparator);
  index_iter->Seek(key);
  uint64_t result;
  if (index_iter->Valid()) {
    BlockHandle handle;
    Slice input = index_iter->value();
    Status s = handle.DecodeFrom(&input);
    if (s.ok()) {
      result = handle.offset();
    } else {
      // Strange: we can't decode the block handle in the index block.
      // We'll just return the offset of the metaindex block, which is
      // close to the whole file size for this case.
      result = rep_->metaindex_handle.offset();
    }
  } else {
    // key is past the last key in the file.  Approximate the offset
    // by returning the offset of the metaindex block (which is
    // right near the end of the file).
    result = rep_->metaindex_handle.offset();
  }
  delete index_iter;
  return result;
}

uint64_t
Table::GetFileSize()
{
    return(rep_->file_size);
};

Block *
Table::TEST_GetIndexBlock() {return(rep_->index_block);};

// Riak specific routine.  Calculates total footprint of an open
//  table in memory.
size_t
Table::TableObjectSize()
{
    return(sizeof(Table) + sizeof(Table::Rep) + rep_->index_block->size() + rep_->filter_data_size + rep_->file->ObjectSize()
           + sizeof(FilterBlockReader) + sizeof(Block));
};

size_t
Table::TEST_FilterDataSize() {return(rep_->filter_data_size);};

}  // namespace leveldb
<commit_msg>remove dead code in preparation for code review.<commit_after>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "leveldb/table.h"

#include "leveldb/cache.h"
#include "leveldb/comparator.h"
#include "leveldb/env.h"
#include "leveldb/filter_policy.h"
#include "leveldb/options.h"
#include "leveldb/perf_count.h"
#include "table/block.h"
#include "table/filter_block.h"
#include "table/format.h"
#include "table/two_level_iterator.h"
#include "util/coding.h"

namespace leveldb {

struct Table::Rep {
  ~Rep() {
    delete filter;
    delete [] filter_data;
    delete index_block;
  }

  Options options;
  Status status;
  RandomAccessFile* file;
  uint64_t file_size;
  uint64_t cache_id;
  FilterBlockReader* filter;
  const char* filter_data;
  size_t filter_data_size;

  BlockHandle metaindex_handle;  // Handle to metaindex_block: saved from footer
  Block* index_block;
  SstCounters sst_counters;
  BlockHandle filter_handle;
  const FilterPolicy * filter_policy;
  volatile uint32_t filter_flag;
};

Status Table::Open(const Options& options,
                   RandomAccessFile* file,
                   uint64_t size,
                   Table** table) {
  *table = NULL;
  if (size < Footer::kEncodedLength) {
    return Status::InvalidArgument("file is too short to be an sstable");
  }

  char footer_space[Footer::kEncodedLength];
  // stop valgrind uninitialize warning
  // let footer.DecodeFrom returned status do the talking for read of bad info
  memset(footer_space, 0, Footer::kEncodedLength);

  Slice footer_input;
  Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,
                        &footer_input, footer_space);
  if (!s.ok()) return s;

  Footer footer;
  s = footer.DecodeFrom(&footer_input);
  if (!s.ok()) return s;

  // Read the index block
  BlockContents contents;
  Block* index_block = NULL;
  if (s.ok()) {
    s = ReadBlock(file, ReadOptions(), footer.index_handle(), &contents);
    if (s.ok()) {
      index_block = new Block(contents);
    }
  }

  if (s.ok()) {
    // We've successfully read the footer and the index block: we're
    // ready to serve requests.
    Rep* rep = new Table::Rep;
    rep->options = options;
    rep->file = file;
    rep->file_size = size;
    rep->metaindex_handle = footer.metaindex_handle();
    rep->index_block = index_block;
    rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0);
    rep->filter_data = NULL;
    rep->filter_data_size = 0;
    rep->filter = NULL;
    rep->filter_policy = NULL;
    rep->filter_flag = 0;
    *table = new Table(rep);
    (*table)->ReadMeta(footer);
  } else {
    if (index_block) delete index_block;
  }

  return s;
}

void Table::ReadMeta(const Footer& footer) {

  // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates
  // it is an empty block.
  std::string key;
  ReadOptions opt;
  BlockContents contents;

  if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) {
    // Do not propagate errors since meta info is not needed for operation
    return;
  }
  Block* meta = new Block(contents);

  Iterator* iter = meta->NewIterator(BytewiseComparator());

  // read filter only if policy set
  if (NULL != rep_->options.filter_policy) {
      bool found,first;
      const FilterPolicy * policy, * next;

      first=true;
      next=NULL;

      do
      {
          found=false;

          if (first)
          {
              policy=rep_->options.filter_policy;
              next=FilterInventory::ListHead;
              first=false;
          }   // if
          else
          {
              policy=next;
              if (NULL!=policy)
                  next=policy->GetNext();
              else
                  next=NULL;
          }   // else

          if (NULL!=policy)
          {
              key = "filter.";
              key.append(policy->Name());
              iter->Seek(key);
              if (iter->Valid() && iter->key() == Slice(key))
              {
		  // store information needed to load bloom filter
		  //  at a later time
		  Slice v = iter->value();
                  rep_->filter_handle.DecodeFrom(&v);
                  rep_->filter_policy = policy;

                  found=true;
              }   // if
          }   //if
      } while(!found && NULL!=policy);
  }   // if

  // always read counters
  key="stats.sst1";
  iter->Seek(key);
  if (iter->Valid() && iter->key() == Slice(key)) {
      ReadSstCounters(iter->value());
  }

  delete iter;
  delete meta;
}

// public version that reads filter at some time
//  after open ... true if filter read
bool
Table::ReadFilter()
{
    bool ret_flag;

    ret_flag=false;

    if (0!=rep_->filter_handle.size()
        && NULL!=rep_->filter_policy
        && 1 == inc_and_fetch(&rep_->filter_flag))
    {
        gPerfCounters->Inc(ePerfBlockFilterRead);

        ReadFilter(rep_->filter_handle, rep_->filter_policy);
        ret_flag=(NULL != rep_->filter);

        // only attempt the read once
        rep_->filter_handle.set_size(0);
    }   // if

    return(ret_flag);
}   // ReadFilter

// Private version of ReadFilter that does the actual work
void
Table::ReadFilter(
    BlockHandle & filter_handle,
    const FilterPolicy * policy)
{
  // We might want to unify with ReadBlock() if we start
  // requiring checksum verification in Table::Open.
  ReadOptions opt;
  BlockContents block;
  if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) {
    return;
  }
  if (block.heap_allocated) {
    rep_->filter_data = block.data.data();     // Will need to delete later
    rep_->filter_data_size = block.data.size();
  }

  rep_->filter = new FilterBlockReader(policy, block.data);
}

void Table::ReadSstCounters(const Slice& sst_counters_handle_value) {
  Slice v = sst_counters_handle_value;
  BlockHandle counters_handle;
  if (!counters_handle.DecodeFrom(&v).ok()) {
    return;
  }

  // We might want to unify with ReadBlock() if we start
  // requiring checksum verification in Table::Open.
  ReadOptions opt;
  BlockContents block;
  if (!ReadBlock(rep_->file, opt, counters_handle, &block).ok()) {
    return;
  }
  if (block.heap_allocated) {
    rep_->sst_counters.DecodeFrom(block.data);
    delete [] block.data.data();
  }

}

SstCounters Table::GetSstCounters() const
{
    return(rep_->sst_counters);
}   // Table::GetSstCounters

Table::~Table() {
  delete rep_;
}

static void DeleteBlock(void* arg, void* ignored) {
  delete reinterpret_cast<Block*>(arg);
}

static void DeleteCachedBlock(const Slice& key, void* value) {
  Block* block = reinterpret_cast<Block*>(value);
  delete block;
}

static void ReleaseBlock(void* arg, void* h) {
  Cache* cache = reinterpret_cast<Cache*>(arg);
  Cache::Handle* handle = reinterpret_cast<Cache::Handle*>(h);
  cache->Release(handle);
}

// Convert an index iterator value (i.e., an encoded BlockHandle)
// into an iterator over the contents of the corresponding block.
Iterator* Table::BlockReader(void* arg,
                             const ReadOptions& options,
                             const Slice& index_value) {
  Table* table = reinterpret_cast<Table*>(arg);
  Cache* block_cache = table->rep_->options.block_cache;
  Block* block = NULL;
  Cache::Handle* cache_handle = NULL;

  BlockHandle handle;
  Slice input = index_value;
  Status s = handle.DecodeFrom(&input);
  // We intentionally allow extra stuff in index_value so that we
  // can add more features in the future.

  if (s.ok()) {
    BlockContents contents;
    if (block_cache != NULL) {
      char cache_key_buffer[16];
      EncodeFixed64(cache_key_buffer, table->rep_->cache_id);
      EncodeFixed64(cache_key_buffer+8, handle.offset());
      Slice key(cache_key_buffer, sizeof(cache_key_buffer));
      cache_handle = block_cache->Lookup(key);
      if (cache_handle != NULL) {
        block = reinterpret_cast<Block*>(block_cache->Value(cache_handle));
        gPerfCounters->Inc(ePerfBlockCached);
      } else {
        s = ReadBlock(table->rep_->file, options, handle, &contents);
        gPerfCounters->Inc(ePerfBlockRead);
        if (s.ok()) {
          block = new Block(contents);
          if (contents.cachable && options.fill_cache) {
            cache_handle = block_cache->Insert(
                key, block,
                (block->size() + /*block_cache->EntryOverheadSize() +*/ sizeof(cache_key_buffer)),
                &DeleteCachedBlock);
          }
        }
      }
    } else {
      s = ReadBlock(table->rep_->file, options, handle, &contents);
        gPerfCounters->Inc(ePerfBlockRead);
      if (s.ok()) {
        block = new Block(contents);
      }
    }
  }

  Iterator* iter;
  if (block != NULL) {
    iter = block->NewIterator(table->rep_->options.comparator);
    if (cache_handle == NULL) {
      iter->RegisterCleanup(&DeleteBlock, block, NULL);
    } else {
      iter->RegisterCleanup(&ReleaseBlock, block_cache, cache_handle);
    }
  } else {
    iter = NewErrorIterator(s);
  }
  return iter;
}

Iterator* Table::NewIterator(const ReadOptions& options) const {
  return NewTwoLevelIterator(
      rep_->index_block->NewIterator(rep_->options.comparator),
      &Table::BlockReader, const_cast<Table*>(this), options);
}

Status Table::InternalGet(const ReadOptions& options, const Slice& k,
                          void* arg,
                          bool (*saver)(void*, const Slice&, const Slice&)) {
  Status s;
  Iterator* iiter = rep_->index_block->NewIterator(rep_->options.comparator);
  iiter->Seek(k);
  if (iiter->Valid()) {
    Slice handle_value = iiter->value();
    FilterBlockReader* filter = rep_->filter;
    BlockHandle handle;
    if (filter != NULL &&
        handle.DecodeFrom(&handle_value).ok() &&
        !filter->KeyMayMatch(handle.offset(), k)) {
      // Not found
        gPerfCounters->Inc(ePerfBlockFiltered);
    } else {
      Iterator* block_iter = BlockReader(this, options, iiter->value());
      block_iter->Seek(k);
      if (block_iter->Valid()) {
        bool match;
        match=(*saver)(arg, block_iter->key(), block_iter->value());
        if (!match && NULL!=filter)
            gPerfCounters->Inc(ePerfBlockFilterFalse);
        if (match)
            gPerfCounters->Inc(ePerfBlockValidGet);
      }

      s = block_iter->status();
      delete block_iter;
    }
  }
  if (s.ok()) {
    s = iiter->status();
  }
  delete iiter;
  return s;
}

uint64_t Table::ApproximateOffsetOf(const Slice& key) const {
  Iterator* index_iter =
      rep_->index_block->NewIterator(rep_->options.comparator);
  index_iter->Seek(key);
  uint64_t result;
  if (index_iter->Valid()) {
    BlockHandle handle;
    Slice input = index_iter->value();
    Status s = handle.DecodeFrom(&input);
    if (s.ok()) {
      result = handle.offset();
    } else {
      // Strange: we can't decode the block handle in the index block.
      // We'll just return the offset of the metaindex block, which is
      // close to the whole file size for this case.
      result = rep_->metaindex_handle.offset();
    }
  } else {
    // key is past the last key in the file.  Approximate the offset
    // by returning the offset of the metaindex block (which is
    // right near the end of the file).
    result = rep_->metaindex_handle.offset();
  }
  delete index_iter;
  return result;
}

uint64_t
Table::GetFileSize()
{
    return(rep_->file_size);
};

Block *
Table::TEST_GetIndexBlock() {return(rep_->index_block);};

// Riak specific routine.  Calculates total footprint of an open
//  table in memory.
size_t
Table::TableObjectSize()
{
    return(sizeof(Table) + sizeof(Table::Rep) + rep_->index_block->size() + rep_->filter_data_size + rep_->file->ObjectSize()
           + sizeof(FilterBlockReader) + sizeof(Block));
};

size_t
Table::TEST_FilterDataSize() {return(rep_->filter_data_size);};

}  // namespace leveldb
<|endoftext|>


<commit_before>/*
 * GMAC
 * (C) 2016 Matthias Gierlings, René Korthaus
 * (C) 2017 Jack Lloyd
 *
 * Botan is released under the Simplified BSD License (see license.txt)
 */

#include <botan/gmac.h>
#include <botan/ghash.h>
#include <botan/exceptn.h>
#include <botan/block_cipher.h>

namespace Botan {

GMAC::GMAC(BlockCipher* cipher) :
   m_cipher(cipher),
   m_ghash(new GHASH),
   m_aad_buf(GCM_BS),
   m_aad_buf_pos(0),
   m_initialized(false)
   {
   }

void GMAC::clear()
   {
   m_cipher->clear();
   m_ghash->clear();
   zeroise(m_aad_buf);
   m_aad_buf_pos = 0;
   m_initialized = false;
   }

GMAC::~GMAC() { /* for unique_ptr */ }

Key_Length_Specification GMAC::key_spec() const
   {
   return m_cipher->key_spec();
   }

std::string GMAC::name() const
   {
   return "GMAC(" + m_cipher->name() + ")";
   }

size_t GMAC::output_length() const
   {
   return GCM_BS;
   }

void GMAC::add_data(const uint8_t input[], size_t size)
   {
   if(m_aad_buf_pos > 0)
      {
      const size_t taking = std::min(GCM_BS - m_aad_buf_pos, size);
      copy_mem(&m_aad_buf[m_aad_buf_pos], input, taking);
      m_aad_buf_pos += taking;
      input += taking;
      size -= taking;

      if(m_aad_buf_pos == GCM_BS)
         {
         m_ghash->update_associated_data(m_aad_buf.data(), GCM_BS);
         m_aad_buf_pos = 0;
         }
      }

   const size_t left_over = size % GCM_BS;
   const size_t full_blocks = size - left_over;
   m_ghash->update_associated_data(input, full_blocks);
   input += full_blocks;

   if(left_over > 0)
      {
      copy_mem(&m_aad_buf[m_aad_buf_pos], input, left_over);
      m_aad_buf_pos += left_over;
      }
   }

void GMAC::key_schedule(const uint8_t key[], size_t size)
   {
   clear();
   m_cipher->set_key(key, size);

   secure_vector<uint8_t> H(GCM_BS);
   m_cipher->encrypt(H);
   m_ghash->set_key(H);
   }

void GMAC::start_msg(const uint8_t nonce[], size_t nonce_len)
   {
   secure_vector<uint8_t> y0(GCM_BS);

   if(nonce_len == 12)
      {
      copy_mem(y0.data(), nonce, nonce_len);
      y0[GCM_BS - 1] = 1;
      }
   else
      {
      m_ghash->ghash_update(y0, nonce, nonce_len);
      m_ghash->add_final_block(y0, 0, nonce_len);
      }

   secure_vector<uint8_t> m_enc_y0(GCM_BS);
   m_cipher->encrypt(y0.data(), m_enc_y0.data());
   m_ghash->start(m_enc_y0.data(), m_enc_y0.size());
   m_initialized = true;
   }

void GMAC::final_result(uint8_t mac[])
   {
   // This ensures the GMAC computation has been initialized with a fresh
   // nonce. The aim of this check is to prevent developers from re-using
   // nonces (and potential nonce-reuse attacks).
   if(m_initialized == false)
      throw Invalid_State("GMAC was not used with a fresh nonce");

   // process the rest of the aad buffer. Even if it is a partial block only
   // ghash_update will process it properly.
   if(m_aad_buf_pos > 0)
       {
       m_ghash->update_associated_data(m_aad_buf.data(), m_aad_buf_pos);
       }
   secure_vector<uint8_t> result = m_ghash->final();
   copy_mem(mac, result.data(), result.size());
   clear();
   }

MessageAuthenticationCode* GMAC::clone() const
   {
   return new GMAC(m_cipher->clone());
   }
}
<commit_msg>Avoid needless allocation during GMAC finalization<commit_after>/*
 * GMAC
 * (C) 2016 Matthias Gierlings, René Korthaus
 * (C) 2017 Jack Lloyd
 *
 * Botan is released under the Simplified BSD License (see license.txt)
 */

#include <botan/gmac.h>
#include <botan/ghash.h>
#include <botan/exceptn.h>
#include <botan/block_cipher.h>

namespace Botan {

GMAC::GMAC(BlockCipher* cipher) :
   m_cipher(cipher),
   m_ghash(new GHASH),
   m_aad_buf(GCM_BS),
   m_aad_buf_pos(0),
   m_initialized(false)
   {
   }

void GMAC::clear()
   {
   m_cipher->clear();
   m_ghash->clear();
   zeroise(m_aad_buf);
   m_aad_buf_pos = 0;
   m_initialized = false;
   }

GMAC::~GMAC() { /* for unique_ptr */ }

Key_Length_Specification GMAC::key_spec() const
   {
   return m_cipher->key_spec();
   }

std::string GMAC::name() const
   {
   return "GMAC(" + m_cipher->name() + ")";
   }

size_t GMAC::output_length() const
   {
   return GCM_BS;
   }

void GMAC::add_data(const uint8_t input[], size_t size)
   {
   if(m_aad_buf_pos > 0)
      {
      const size_t taking = std::min(GCM_BS - m_aad_buf_pos, size);
      copy_mem(&m_aad_buf[m_aad_buf_pos], input, taking);
      m_aad_buf_pos += taking;
      input += taking;
      size -= taking;

      if(m_aad_buf_pos == GCM_BS)
         {
         m_ghash->update_associated_data(m_aad_buf.data(), GCM_BS);
         m_aad_buf_pos = 0;
         }
      }

   const size_t left_over = size % GCM_BS;
   const size_t full_blocks = size - left_over;
   m_ghash->update_associated_data(input, full_blocks);
   input += full_blocks;

   if(left_over > 0)
      {
      copy_mem(&m_aad_buf[m_aad_buf_pos], input, left_over);
      m_aad_buf_pos += left_over;
      }
   }

void GMAC::key_schedule(const uint8_t key[], size_t size)
   {
   clear();
   m_cipher->set_key(key, size);

   secure_vector<uint8_t> H(GCM_BS);
   m_cipher->encrypt(H);
   m_ghash->set_key(H);
   }

void GMAC::start_msg(const uint8_t nonce[], size_t nonce_len)
   {
   secure_vector<uint8_t> y0(GCM_BS);

   if(nonce_len == 12)
      {
      copy_mem(y0.data(), nonce, nonce_len);
      y0[GCM_BS - 1] = 1;
      }
   else
      {
      m_ghash->ghash_update(y0, nonce, nonce_len);
      m_ghash->add_final_block(y0, 0, nonce_len);
      }

   secure_vector<uint8_t> m_enc_y0(GCM_BS);
   m_cipher->encrypt(y0.data(), m_enc_y0.data());
   m_ghash->start(m_enc_y0.data(), m_enc_y0.size());
   m_initialized = true;
   }

void GMAC::final_result(uint8_t mac[])
   {
   // This ensures the GMAC computation has been initialized with a fresh
   // nonce. The aim of this check is to prevent developers from re-using
   // nonces (and potential nonce-reuse attacks).
   if(m_initialized == false)
      throw Invalid_State("GMAC was not used with a fresh nonce");

   // process the rest of the aad buffer. Even if it is a partial block only
   // ghash_update will process it properly.
   if(m_aad_buf_pos > 0)
       {
       m_ghash->update_associated_data(m_aad_buf.data(), m_aad_buf_pos);
       }

   m_ghash->final(mac, output_length());
   clear();
   }

MessageAuthenticationCode* GMAC::clone() const
   {
   return new GMAC(m_cipher->clone());
   }
}
<|endoftext|>


<commit_before>
#include <sys/epoll.h>
#include <unistd.h>
#include <pthread.h>
#include <nanosoft/netdaemon.h>
#include <iostream>
#include <errno.h>
#include <string.h>

using namespace std;

/**
* Конструктор демона
* @param maxStreams максимальное число одновременных виртуальных потоков
*/
NetDaemon::NetDaemon(int maxObjects)
{
	epoll = epoll_create(maxObjects);
}

/**
* Деструктор демона
*/
NetDaemon::~NetDaemon()
{
	int r = ::close(epoll);
	if ( r < 0 ) stderror();
}

/**
* Обработчик ошибок
*
* По умолчанию выводит все ошибки в stderr
*/
void NetDaemon::onError(const char *message)
{
	cerr << "[NetDaemon]: " << message << endl;
}

/**
* Обработка системной ошибки
*/
void NetDaemon::stderror()
{
	onError(strerror(errno));
}

/**
* Вернуть число воркеров
*/
int NetDaemon::getWorkerCount()
{
	return workerCount;
}

/**
* Установить число воркеров
*/
void NetDaemon::setWorkerCount(int count)
{
	workerCount = count;
}

/**
* Добавить асинхронный объект
*/
bool NetDaemon::addObject(AsyncObject *object)
{
	struct epoll_event event;
	objects[object->fd] = object;
	event.events = object->getEventsMask();
	event.data.fd = object->fd;
	return epoll_ctl(epoll, EPOLL_CTL_ADD, object->fd, &event) == 0;
}

/**
* Удалить асинхронный объект
*/
bool NetDaemon::removeObject(AsyncObject *object)
{
	if ( objects.erase(object->fd) > 0 )
	{
		if ( epoll_ctl(epoll, EPOLL_CTL_DEL, object->fd, 0) != 0 ) stderror();
	}
}

/**
* Возобновить работу с асинхронным объектом
*/
bool NetDaemon::resetObject(AsyncObject *object)
{
	struct epoll_event event;
	event.events = object->getEventsMask();
	event.data.fd = object->fd;
	if ( epoll_ctl(epoll, EPOLL_CTL_MOD, object->fd, &event) != 0 )
	{
		stderror();
	}
}

struct Context
{
	NetDaemon *d;
	int tid;
};

/**
* Точка входа в воркер
*/
void* NetDaemon::workerEntry(void *pContext)
{
	struct epoll_event event;
	Context *context = static_cast<Context *>(pContext);
	NetDaemon *daemon = context->d;

	while ( daemon->active )
	{
		int r = epoll_wait(daemon->epoll, &event, 1, -1);
		if ( r > 0 )
		{
			AsyncObject *obj = daemon->objects[event.data.fd];
			obj->onEvent(event.events);
			if ( daemon->objects[event.data.fd] != 0 )
			{
				daemon->resetObject(obj);
			}
		}
		if ( r < 0 ) daemon->stderror();
		if ( r == 0 ) daemon->onError("skip");
	}

	daemon->onError("worker exiting");
	delete context;
	return 0;
}

/**
* Запустить воркеров
*/
void NetDaemon::startWorkers()
{
	//printf("todo startWorkers\n");
	workers = new worker_info[workerCount];
	for(int i = 0; i < workerCount; i++)
	{
		Context *context = new Context;
		context->d = this;
		context->tid = i + 1;
		pthread_attr_init(&workers[i].attr);
		size_t stack_size = sizeof(double) * 1024 * 1024;
		pthread_attr_setstacksize(&workers[i].attr, stack_size);
		cout << "worker stack size: " << stack_size << endl;
		// TODO delete attr somewhere...
		pthread_create(&workers[i].thread, &workers[i].attr, workerEntry, context);
	}
}

/**
* Остановить воркеров
*/
void NetDaemon::stopWorkers()
{
	//printf("todo stopWorkers\n");
	delete [] workers;
}

/**
* Запустить демона
*/
int NetDaemon::run()
{
	active = true;
	startWorkers();
	Context *context = new Context;
	context->d = this;
	context->tid = 0;
	workerEntry(context);
	stopWorkers();
	return 0;
}

/**
* Завершить работу демона
*/
void NetDaemon::terminate(int code)
{
	onError("terminate...");
	exitCode = code;
	active = false;
}
<commit_msg>fix stack size<commit_after>
#include <sys/epoll.h>
#include <unistd.h>
#include <pthread.h>
#include <nanosoft/netdaemon.h>
#include <iostream>
#include <errno.h>
#include <string.h>

using namespace std;

/**
* Конструктор демона
* @param maxStreams максимальное число одновременных виртуальных потоков
*/
NetDaemon::NetDaemon(int maxObjects)
{
	epoll = epoll_create(maxObjects);
}

/**
* Деструктор демона
*/
NetDaemon::~NetDaemon()
{
	int r = ::close(epoll);
	if ( r < 0 ) stderror();
}

/**
* Обработчик ошибок
*
* По умолчанию выводит все ошибки в stderr
*/
void NetDaemon::onError(const char *message)
{
	cerr << "[NetDaemon]: " << message << endl;
}

/**
* Обработка системной ошибки
*/
void NetDaemon::stderror()
{
	onError(strerror(errno));
}

/**
* Вернуть число воркеров
*/
int NetDaemon::getWorkerCount()
{
	return workerCount;
}

/**
* Установить число воркеров
*/
void NetDaemon::setWorkerCount(int count)
{
	workerCount = count;
}

/**
* Добавить асинхронный объект
*/
bool NetDaemon::addObject(AsyncObject *object)
{
	struct epoll_event event;
	objects[object->fd] = object;
	event.events = object->getEventsMask();
	event.data.fd = object->fd;
	return epoll_ctl(epoll, EPOLL_CTL_ADD, object->fd, &event) == 0;
}

/**
* Удалить асинхронный объект
*/
bool NetDaemon::removeObject(AsyncObject *object)
{
	if ( objects.erase(object->fd) > 0 )
	{
		if ( epoll_ctl(epoll, EPOLL_CTL_DEL, object->fd, 0) != 0 ) stderror();
	}
}

/**
* Возобновить работу с асинхронным объектом
*/
bool NetDaemon::resetObject(AsyncObject *object)
{
	struct epoll_event event;
	event.events = object->getEventsMask();
	event.data.fd = object->fd;
	if ( epoll_ctl(epoll, EPOLL_CTL_MOD, object->fd, &event) != 0 )
	{
		stderror();
	}
}

struct Context
{
	NetDaemon *d;
	int tid;
};

/**
* Точка входа в воркер
*/
void* NetDaemon::workerEntry(void *pContext)
{
	struct epoll_event event;
	Context *context = static_cast<Context *>(pContext);
	NetDaemon *daemon = context->d;

	while ( daemon->active )
	{
		int r = epoll_wait(daemon->epoll, &event, 1, -1);
		if ( r > 0 )
		{
			AsyncObject *obj = daemon->objects[event.data.fd];
			obj->onEvent(event.events);
			if ( daemon->objects[event.data.fd] != 0 )
			{
				daemon->resetObject(obj);
			}
		}
		if ( r < 0 ) daemon->stderror();
		if ( r == 0 ) daemon->onError("skip");
	}

	daemon->onError("worker exiting");
	delete context;
	return 0;
}

/**
* Запустить воркеров
*/
void NetDaemon::startWorkers()
{
	//printf("todo startWorkers\n");
	workers = new worker_info[workerCount];
	for(int i = 0; i < workerCount; i++)
	{
		Context *context = new Context;
		context->d = this;
		context->tid = i + 1;
		pthread_attr_init(&workers[i].attr);
		size_t stack_size = sizeof(size_t) * 2 * 1024 * 1024;
		pthread_attr_setstacksize(&workers[i].attr, stack_size);
		cout << "worker stack size: " << stack_size << endl;
		pthread_create(&workers[i].thread, &workers[i].attr, workerEntry, context);
	}
}

/**
* Остановить воркеров
*/
void NetDaemon::stopWorkers()
{
	//printf("todo stopWorkers\n");
	delete [] workers;
}

/**
* Запустить демона
*/
int NetDaemon::run()
{
	active = true;
	startWorkers();
	Context *context = new Context;
	context->d = this;
	context->tid = 0;
	workerEntry(context);
	stopWorkers();
	return 0;
}

/**
* Завершить работу демона
*/
void NetDaemon::terminate(int code)
{
	onError("terminate...");
	exitCode = code;
	active = false;
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Franka Emika GmbH
// Use of this source code is governed by the Apache-2.0 license, see LICENSE
#include "load_calculations.h"

namespace franka {

std::array<double, 3> combineCenterOfMass(
    double m_ee,
    const std::array<double, 3>& F_x_Cee,  // NOLINT(readability-identifier-naming)
    double m_load,
    const std::array<double, 3>& F_x_Cload) {  // NOLINT(readability-identifier-naming)
  std::array<double, 3> F_x_Ctotal{};          // NOLINT(readability-identifier-naming)
  if ((m_ee + m_load) > 0) {
    for (size_t i = 0; i < F_x_Ctotal.size(); i++) {
      F_x_Ctotal[i] = (m_ee * F_x_Cee[i] + m_load * F_x_Cload[i]) / (m_ee + m_load);
    }
  }

  return F_x_Ctotal;
}

Eigen::Matrix3d skewSymmetricMatrixFromVector(const Eigen::Vector3d& input) {
  Eigen::Matrix3d input_hat;
  input_hat << 0, -input(2), input(1), input(2), 0, -input(0), -input(1), input(0), 0;
  return input_hat;
}

std::array<double, 9> combineInertiaTensor(
    double m_ee,
    const std::array<double, 3>& F_x_Cee,  // NOLINT(readability-identifier-naming)
    const std::array<double, 9>& I_ee,     // NOLINT(readability-identifier-naming)
    double m_load,
    const std::array<double, 3>& F_x_Cload,  // NOLINT(readability-identifier-naming)
    const std::array<double, 9>& I_load,     // NOLINT(readability-identifier-naming)
    double m_total,
    const std::array<double, 3>& F_x_Ctotal) {  // NOLINT(readability-identifier-naming)
  // If the combined mass equals to zero, the combined inertia is also zero.
  if (m_total == 0) {
    return std::array<double, 9>{};
  }

  Eigen::Vector3d center_of_mass_ee(F_x_Cee.data());
  Eigen::Vector3d center_of_mass_load(F_x_Cload.data());
  Eigen::Vector3d center_of_mass_total(F_x_Ctotal.data());

  Eigen::Matrix3d inertia_ee(I_ee.data());
  Eigen::Matrix3d inertia_ee_flange = Eigen::Matrix3d::Zero();
  Eigen::Matrix3d inertia_load(I_load.data());
  Eigen::Matrix3d inertia_load_flange = Eigen::Matrix3d::Zero();
  Eigen::Matrix3d inertia_total_flange = Eigen::Matrix3d::Zero();

  // Check if the mass equals zero, the inertia should then be zero as well.
  if (m_ee == 0) {
    inertia_ee = Eigen::Matrix3d::Zero();
  }
  if (m_load == 0) {
    inertia_load = Eigen::Matrix3d::Zero();
  }

  // Calculate inertia tensor of EE and load in flange coordinates.
  inertia_ee_flange = inertia_ee - m_ee * (skewSymmetricMatrixFromVector(center_of_mass_ee) *
                                           skewSymmetricMatrixFromVector(center_of_mass_ee));
  inertia_load_flange =
      inertia_load - m_load * (skewSymmetricMatrixFromVector(center_of_mass_load) *
                               skewSymmetricMatrixFromVector(center_of_mass_load));

  // Calculate combined inertia tensor in flange coordinate.
  inertia_total_flange = inertia_ee_flange + inertia_load_flange;

  // Calculate combined inertia tensor in combined body center of mass coordinate.
  std::array<double, 9> I_total;  // NOLINT(readability-identifier-naming)
  Eigen::Map<Eigen::Matrix3d> inertia_total(I_total.data(), 3, 3);
  inertia_total =
      inertia_total_flange + m_total * (skewSymmetricMatrixFromVector(center_of_mass_total) *
                                        skewSymmetricMatrixFromVector(center_of_mass_total));

  return I_total;
}

}  // namespace franka<commit_msg>fix formatting<commit_after>// Copyright (c) 2017 Franka Emika GmbH
// Use of this source code is governed by the Apache-2.0 license, see LICENSE
#include "load_calculations.h"

namespace franka {

std::array<double, 3> combineCenterOfMass(
    double m_ee,
    const std::array<double, 3>& F_x_Cee,  // NOLINT(readability-identifier-naming)
    double m_load,
    const std::array<double, 3>& F_x_Cload) {  // NOLINT(readability-identifier-naming)
  std::array<double, 3> F_x_Ctotal{};          // NOLINT(readability-identifier-naming)
  if ((m_ee + m_load) > 0) {
    for (size_t i = 0; i < F_x_Ctotal.size(); i++) {
      F_x_Ctotal[i] = (m_ee * F_x_Cee[i] + m_load * F_x_Cload[i]) / (m_ee + m_load);
    }
  }

  return F_x_Ctotal;
}

Eigen::Matrix3d skewSymmetricMatrixFromVector(const Eigen::Vector3d& input) {
  Eigen::Matrix3d input_hat;
  input_hat << 0, -input(2), input(1), input(2), 0, -input(0), -input(1), input(0), 0;
  return input_hat;
}

std::array<double, 9> combineInertiaTensor(
    double m_ee,
    const std::array<double, 3>& F_x_Cee,  // NOLINT(readability-identifier-naming)
    const std::array<double, 9>& I_ee,     // NOLINT(readability-identifier-naming)
    double m_load,
    const std::array<double, 3>& F_x_Cload,  // NOLINT(readability-identifier-naming)
    const std::array<double, 9>& I_load,     // NOLINT(readability-identifier-naming)
    double m_total,
    const std::array<double, 3>& F_x_Ctotal) {  // NOLINT(readability-identifier-naming)
  // If the combined mass equals to zero, the combined inertia is also zero.
  if (m_total == 0) {
    return std::array<double, 9>{};
  }

  Eigen::Vector3d center_of_mass_ee(F_x_Cee.data());
  Eigen::Vector3d center_of_mass_load(F_x_Cload.data());
  Eigen::Vector3d center_of_mass_total(F_x_Ctotal.data());

  Eigen::Matrix3d inertia_ee(I_ee.data());
  Eigen::Matrix3d inertia_ee_flange = Eigen::Matrix3d::Zero();
  Eigen::Matrix3d inertia_load(I_load.data());
  Eigen::Matrix3d inertia_load_flange = Eigen::Matrix3d::Zero();
  Eigen::Matrix3d inertia_total_flange = Eigen::Matrix3d::Zero();

  // Check if the mass equals zero, the inertia should then be zero as well.
  if (m_ee == 0) {
    inertia_ee = Eigen::Matrix3d::Zero();
  }
  if (m_load == 0) {
    inertia_load = Eigen::Matrix3d::Zero();
  }

  // Calculate inertia tensor of EE and load in flange coordinates.
  inertia_ee_flange = inertia_ee - m_ee * (skewSymmetricMatrixFromVector(center_of_mass_ee) *
                                           skewSymmetricMatrixFromVector(center_of_mass_ee));
  inertia_load_flange =
      inertia_load - m_load * (skewSymmetricMatrixFromVector(center_of_mass_load) *
                               skewSymmetricMatrixFromVector(center_of_mass_load));

  // Calculate combined inertia tensor in flange coordinate.
  inertia_total_flange = inertia_ee_flange + inertia_load_flange;

  // Calculate combined inertia tensor in combined body center of mass coordinate.
  std::array<double, 9> I_total;  // NOLINT(readability-identifier-naming)
  Eigen::Map<Eigen::Matrix3d> inertia_total(I_total.data(), 3, 3);
  inertia_total =
      inertia_total_flange + m_total * (skewSymmetricMatrixFromVector(center_of_mass_total) *
                                        skewSymmetricMatrixFromVector(center_of_mass_total));

  return I_total;
}

}  // namespace franka<|endoftext|>


<commit_before>void PopulateLocalOCDB(const char* storageUri, const char* dets="ALL", Int_t runMin=0, Int_t runMax=0)
{
  // dets: comma-separated list of detectors for which to make the CDB objects
  //
  TString storageString(storageUri);
  if(!storageUri || storageString.IsNull()) {
    storageUri = gSystem->ExpandPathName("local://$ALICE_ROOT/OCDB");
  }
  AliCDBManager *cdb = AliCDBManager::Instance();
  cdb->SetDefaultStorage(storageUri);
  if (runMax==0)
    runMax=AliCDBRunRange::Infinity();
  const Int_t nDets=20;
  const char* detectorNames[nDets] = {"ACORDE", "AD", "EMCAL", "FIT", "FMD", "GRP", "HLT", "HMPID", "ITS", "MFT", "MUON", "PHOS", "PMD", "T0", "TOF", "TPC", "TRD", "TRIGGER", "VZERO", "ZDC"};
  TString detectors(dets);
  if (dets == "ALL") {
    detectors = "";
    for (Int_t i=0; i<nDets; ++i) {
      detectors += detectorNames[i];
      detectors += ",";
    }
  }

  // For the 'MakeZeroMisalignment' macros
  gSystem->Setenv("TOCDB", "kTRUE");
  gSystem->Setenv("STORAGE", storageUri);

  TObjArray *detsArray = detectors.Tokenize(',');
  TString macroPath = gROOT->GetMacroPath();
  TIter iter(detsArray);
  TObjString *oStringDet = 0;
  TString sDetMacro("");
  while ((oStringDet = (TObjString*) iter.Next()))
  {
    TString stringDet(oStringDet->String());
    stringDet.ReplaceAll(" ","");
    Printf("\n   ----  Making conditions'objects for \"%s\"  ----", stringDet.Data());
    sDetMacro = "Make";
    sDetMacro += stringDet;
    sDetMacro += "CDBObjects.C";
    if (! macroPath.EndsWith(":")) {
      macroPath += ":";
    }
    macroPath += gSystem->ExpandPathName("${ALICE_ROOT}/");
    macroPath += stringDet;
    macroPath += "/macros";
    gROOT->SetMacroPath(macroPath);
    gROOT->LoadMacro(sDetMacro.Data());
    sDetMacro = (sDetMacro(0, sDetMacro.Length()-2));
    sDetMacro += "()";
    gROOT->ProcessLine(sDetMacro.Data());
  }
}
<commit_msg>Remove final comma in det list<commit_after>void PopulateLocalOCDB(const char* storageUri="local://$ALICE_ROOT/OCDB", const char* dets="ALL", Int_t runMin=0, Int_t runMax=0)
{
  // dets: comma-separated list of detectors for which to make the CDB objects
  //
  /*
  TString storageString(storageUri);
  if(!storageUri || storageString.IsNull()) {
    storageUri = gSystem->ExpandPathName("local://$ALICE_ROOT/OCDB");
  }*/
  AliCDBManager *cdb = AliCDBManager::Instance();
  cdb->SetDefaultStorage(storageUri);
  if (runMax==0)
    runMax=AliCDBRunRange::Infinity();
  const Int_t nDets=20;
  const char* detectorNames[nDets] = {"ACORDE", "AD", "EMCAL", "FIT", "FMD", "GRP", "HLT", "HMPID", "ITS", "MFT", "MUON", "PHOS", "PMD", "T0", "TOF", "TPC", "TRD", "TRIGGER", "VZERO", "ZDC"};
  TString detectors(dets);
  if (dets == "ALL") {
    detectors = "";
    for (Int_t i=0; i<nDets; ++i) {
      detectors += detectorNames[i];
      detectors += ",";
    }
    detectors.Chop();
  }

  // For the 'MakeZeroMisalignment' macros
  gSystem->Setenv("TOCDB", "kTRUE");
  gSystem->Setenv("STORAGE", storageUri);

  TObjArray *detsArray = detectors.Tokenize(',');
  TString macroPath = gROOT->GetMacroPath();
  TIter iter(detsArray);
  TObjString *oStringDet = 0;
  TString sDetMacro("");
  while ((oStringDet = (TObjString*) iter.Next()))
  {
    TString stringDet(oStringDet->String());
    stringDet.ReplaceAll(" ","");
    Printf("\n   ----  Making conditions'objects for \"%s\"  ----", stringDet.Data());
    sDetMacro = "Make";
    sDetMacro += stringDet;
    sDetMacro += "CDBObjects.C";
    if (! macroPath.EndsWith(":")) {
      macroPath += ":";
    }
    macroPath += gSystem->ExpandPathName("${ALICE_ROOT}/");
    macroPath += stringDet;
    macroPath += "/macros";
    gROOT->SetMacroPath(macroPath);
    gROOT->LoadMacro(sDetMacro.Data());
    sDetMacro = (sDetMacro(0, sDetMacro.Length()-2));
    sDetMacro += "()";
    gROOT->ProcessLine(sDetMacro.Data());
  }
}
<|endoftext|>