<commit_before>#include "QXmppInformationRequestResult.h"
#include "QXmppConstants.h"
#include <QXmlStreamWriter>

QXmppInformationRequestResult::QXmppInformationRequestResult() : QXmppIq(QXmppIq::Result)
{
}

void QXmppInformationRequestResult::toXmlElementFromChild(QXmlStreamWriter *writer) const
{
    writer->writeStartElement("query");
    writer->writeAttribute("xmlns", ns_disco_info );
    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_disco_info );
    writer->writeEndElement();
    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_ibb );
    writer->writeEndElement();
    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_rpc);
    writer->writeEndElement();
    writer->writeStartElement("identity");
    writer->writeAttribute("category", "automation" );
    writer->writeAttribute("type", "rpc" );
    writer->writeEndElement();
    writer->writeEndElement();
}
<commit_msg>Add XEP-0199:XMPP Ping support http://xmpp.org/extensions/xep-0199.html#disco<commit_after>#include "QXmppInformationRequestResult.h"
#include "QXmppConstants.h"
#include <QXmlStreamWriter>

QXmppInformationRequestResult::QXmppInformationRequestResult() : QXmppIq(QXmppIq::Result)
{
}

void QXmppInformationRequestResult::toXmlElementFromChild(QXmlStreamWriter *writer) const
{
    writer->writeStartElement("query");
    writer->writeAttribute("xmlns", ns_disco_info );

    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_disco_info );
    writer->writeEndElement();

    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_ibb );
    writer->writeEndElement();

    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_rpc);
    writer->writeEndElement();
    writer->writeStartElement("identity");
    writer->writeAttribute("category", "automation" );
    writer->writeAttribute("type", "rpc" );
    writer->writeEndElement();

    writer->writeStartElement("feature");
    writer->writeAttribute("var", ns_ping);
    writer->writeEndElement();

    writer->writeEndElement();
}
<|endoftext|>


<commit_before>#include "emu.h"

#include <cstdio>

#include "../fs/load.h"
#include "../fs/util.h"

EmuModule::EmuModule(SharedState& gui)
: GUIModule(gui)
{
  /*-------------------------------  SDL init  -------------------------------*/

  fprintf(stderr, "[GUI][Emu] Initializing...\n");

  // make window
  this->sdl.window = SDL_CreateWindow(
    "anese",
    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    256 * this->gui.config.window_scale,
    240 * this->gui.config.window_scale,
    SDL_WINDOW_RESIZABLE
  );

  // make renderer
  this->sdl.renderer = SDL_CreateRenderer(
    this->sdl.window,
    -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
  );

  // make screen rect (to render texture onto)
  this->sdl.screen_rect.x = 0;
  this->sdl.screen_rect.y = 0;
  this->sdl.screen_rect.w = 256 * this->gui.config.window_scale;
  this->sdl.screen_rect.h = 240 * this->gui.config.window_scale;

  // Letterbox the screen in the window
  SDL_RenderSetLogicalSize(this->sdl.renderer,
    256 * this->gui.config.window_scale,
    240 * this->gui.config.window_scale);

  // Allow opacity
  SDL_SetRenderDrawBlendMode(this->sdl.renderer, SDL_BLENDMODE_BLEND);

  // NES screen texture
  this->sdl.screen_texture = SDL_CreateTexture(
    this->sdl.renderer,
    SDL_PIXELFORMAT_ARGB8888,
    SDL_TEXTUREACCESS_STREAMING,
    256, 240
  );

  // SDL_AudioSpec as, have;
  // as.freq = SDL_GUI::SAMPLE_RATE;
  // as.format = AUDIO_F32SYS;
  // as.channels = 1;
  // as.samples = 4096;
  // as.callback = nullptr; // use SDL_QueueAudio
  // this->sdl_common.nes_audiodev = SDL_OpenAudioDevice(NULL, 0, &as, &have, 0);
  // SDL_PauseAudioDevice(this->sdl_common.nes_audiodev, 0);

//  this->sdl.sound_queue.init(this->gui.nes_params.apu_sample_rate);

  /*----------  Submodule Init  ----------*/

  this->menu_submodule = new MenuSubModule(gui, this->sdl.window, this->sdl.renderer);

  /*----------  NES Init  ----------*/

  this->gui.nes.attach_joy(0, &this->joy_1);
  this->gui.nes.attach_joy(1, &this->zap_2);

  // ---------------------------- Movie Support ----------------------------- //

  if (this->gui.config.cli.replay_fm2_path != "") {
    bool did_load = this->fm2_replay.init(this->gui.config.cli.replay_fm2_path.c_str());
    if (!did_load)
      fprintf(stderr, "[Replay][fm2] Movie loading failed!\n");
    else fprintf(stderr, "[Replay][fm2] Movie successfully loaded!\n");
  }

  if (this->gui.config.cli.record_fm2_path != "") {
    bool did_load = this->fm2_record.init(this->gui.config.cli.record_fm2_path.c_str());
    if (!did_load)
      fprintf(stderr, "[Record][fm2] Failed to setup Movie recording!\n");
    else fprintf(stderr, "[Record][fm2] Movie recording is setup!\n");
  }

  // pass controllers to this->fm2_record
  if (this->fm2_record.is_enabled()) {
    this->fm2_record.set_joy(0, FM2_Controller::SI_GAMEPAD, &this->joy_1);
    this->fm2_record.set_joy(1, FM2_Controller::SI_GAMEPAD, &this->joy_2);
  }

  // attach fm2_replay controllers (if needed)
  if (this->fm2_replay.is_enabled()) {
    this->gui.nes.attach_joy(0, this->fm2_replay.get_joy(0));
    this->gui.nes.attach_joy(1, this->fm2_replay.get_joy(1));
  }
}

EmuModule::~EmuModule() {
  fprintf(stderr, "[GUI][Emu] Shutting down...\n");

  delete this->menu_submodule;

  /*------------------------------  SDL Cleanup  -----------------------------*/

  SDL_DestroyTexture(this->sdl.screen_texture);
  SDL_DestroyRenderer(this->sdl.renderer);
  SDL_DestroyWindow(this->sdl.window);
}

void EmuModule::input(const SDL_Event& event) {
  this->menu_submodule->input(event);
  if (this->gui.status.in_menu) return;

  // Update from Controllers
  if (event.type == SDL_CONTROLLERBUTTONDOWN ||
      event.type == SDL_CONTROLLERBUTTONUP) {
    bool new_state = (event.type == SDL_CONTROLLERBUTTONDOWN) ? true : false;
    using namespace JOY_Standard_Button;

    // Player 1
    switch (event.cbutton.button) {
    case SDL_CONTROLLER_BUTTON_A:          this->joy_1.set_button(A,      new_state); break;
    case SDL_CONTROLLER_BUTTON_X:          this->joy_1.set_button(B,      new_state); break;
    case SDL_CONTROLLER_BUTTON_START:      this->joy_1.set_button(Start,  new_state); break;
    case SDL_CONTROLLER_BUTTON_BACK:       this->joy_1.set_button(Select, new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_UP:    this->joy_1.set_button(Up,     new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_DOWN:  this->joy_1.set_button(Down,   new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_LEFT:  this->joy_1.set_button(Left,   new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: this->joy_1.set_button(Right,  new_state); break;
    }

    // Player 2
    // switch (event.cbutton.button) {
    // case SDL_CONTROLLER_BUTTON_A:          this->joy_2.set_button(A,      new_state); break;
    // case SDL_CONTROLLER_BUTTON_X:          this->joy_2.set_button(B,      new_state); break;
    // case SDL_CONTROLLER_BUTTON_START:      this->joy_2.set_button(Start,  new_state); break;
    // case SDL_CONTROLLER_BUTTON_BACK:       this->joy_2.set_button(Select, new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_UP:    this->joy_2.set_button(Up,     new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_DOWN:  this->joy_2.set_button(Down,   new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_LEFT:  this->joy_2.set_button(Left,   new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: this->joy_2.set_button(Right,  new_state); break;
    // }
  }

  // Update from Keyboard
  if (event.type == SDL_KEYDOWN ||
      event.type == SDL_KEYUP) {
    // ------ Keyboard controls ------ //
    bool new_state = (event.type == SDL_KEYDOWN) ? true : false;
    using namespace JOY_Standard_Button;

    // Player 1
    switch (event.key.keysym.sym) {
    case SDLK_z:      this->joy_1.set_button(A,      new_state); break;
    case SDLK_x:      this->joy_1.set_button(B,      new_state); break;
    case SDLK_RETURN: this->joy_1.set_button(Start,  new_state); break;
    case SDLK_RSHIFT: this->joy_1.set_button(Select, new_state); break;
    case SDLK_UP:     this->joy_1.set_button(Up,     new_state); break;
    case SDLK_DOWN:   this->joy_1.set_button(Down,   new_state); break;
    case SDLK_LEFT:   this->joy_1.set_button(Left,   new_state); break;
    case SDLK_RIGHT:  this->joy_1.set_button(Right,  new_state); break;
    }

    // Player 2
    // switch (event.key.keysym.sym) {
    // case SDLK_z:      this->joy_2.set_button(A,      new_state); break;
    // case SDLK_x:      this->joy_2.set_button(B,      new_state); break;
    // case SDLK_RETURN: this->joy_2.set_button(Start,  new_state); break;
    // case SDLK_RSHIFT: this->joy_2.set_button(Select, new_state); break;
    // case SDLK_UP:     this->joy_2.set_button(Up,     new_state); break;
    // case SDLK_DOWN:   this->joy_2.set_button(Down,   new_state); break;
    // case SDLK_LEFT:   this->joy_2.set_button(Left,   new_state); break;
    // case SDLK_RIGHT:  this->joy_2.set_button(Right,  new_state); break;
    // }
  }

  // Zapper

  // if (event.type == SDL_MOUSEMOTION) {
  //   // getting the light from the screen is a bit trickier...
  //   const u8* screen;
  //   this->gui.nes.getFramebuff(screen);
  //   const uint offset = (256 * 4 * (event.motion.y / this->gui.config.window_scale))
  //                     + (      4 * (event.motion.x / this->gui.config.window_scale));
  //   const bool new_light = screen[offset+ 0]  // R
  //                        | screen[offset+ 1]  // G
  //                        | screen[offset+ 2]; // B
  //   this->zap_2.set_light(new_light);
  // }

  // if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
  //   bool new_state = (event.type == SDL_MOUSEBUTTONDOWN) ? true : false;
  //   this->zap_2.set_trigger(new_state);
  // }

  // Handle Key-events
  if (event.type == SDL_KEYDOWN ||
      event.type == SDL_KEYUP) {
    bool mod_shift = event.key.keysym.mod & KMOD_SHIFT;
    // Use CMD on macOS, and CTRL on windows / linux
    bool mod_ctrl = strcmp(SDL_GetPlatform(), "Mac OS X") == 0
      ? event.key.keysym.mod & (KMOD_LGUI | KMOD_RGUI)
      : event.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL);

    // Regular 'ol keys
    switch (event.key.keysym.sym) {
      case SDLK_SPACE:
        // Fast-Forward
        this->speed_counter = 0;
        this->gui.nes_params.speed = (event.type == SDL_KEYDOWN) ? 200 : 100;
        this->gui.nes.updated_params();
        break;
    }

    // Controller
    if (event.type == SDL_CONTROLLERBUTTONDOWN ||
        event.type == SDL_CONTROLLERBUTTONUP) {
      switch (event.cbutton.button) {
      case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
        this->speed_counter = 0;
        this->gui.nes_params.speed = (event.type == SDL_CONTROLLERBUTTONDOWN) ? 200 : 100;
        this->gui.nes.updated_params();
        break;
      }
    }

    // Meta Modified keys
    if (event.type == SDL_KEYDOWN && mod_ctrl) {
      #define SAVESTATE(i) do {                                   \
        if (mod_shift) {                                          \
          delete this->gui.savestate[i];                          \
          this->gui.savestate[i] = this->gui.nes.serialize();     \
        } else this->gui.nes.deserialize(this->gui.savestate[i]); \
      } while(0);

      switch (event.key.keysym.sym) {
      case SDLK_1: SAVESTATE(0); break; // Savestate Slot 1
      case SDLK_2: SAVESTATE(1); break; // Savestate Slot 2
      case SDLK_3: SAVESTATE(2); break; // Savestate Slot 3
      case SDLK_4: SAVESTATE(3); break; // Savestate Slot 4
      case SDLK_r: this->gui.nes.reset();       break; // Reset
      case SDLK_p: this->gui.nes.power_cycle(); break; // Power-Cycle
      case SDLK_EQUALS:
        // Speed up
        this->speed_counter = 0;
        this->gui.nes_params.speed += 25;
        this->gui.nes.updated_params();
        break;
      case SDLK_MINUS:
        // Speed down
        if (this->gui.nes_params.speed - 25 != 0) {
          this->speed_counter = 0;
          this->gui.nes_params.speed -= 25;
          this->gui.nes.updated_params();
        }
        break;
      case SDLK_c: {
        // Toggle CPU trace
        bool log = this->gui.nes_params.log_cpu = !this->gui.nes_params.log_cpu;
        this->gui.nes.updated_params();
        fprintf(stderr, "NESTEST CPU logging: %s\n", log ? "ON" : "OFF");
      } break;
      default: break;
      }
    }
  }
}

void EmuModule::update() {
  this->menu_submodule->update();
  if (this->gui.status.in_menu) return;

  // log frame to fm2
  if (this->fm2_record.is_enabled())
    this->fm2_record.step_frame();

  // set input from fm2
  if (this->fm2_replay.is_enabled())
    this->fm2_replay.step_frame();
}

void EmuModule::output() {
/^  // output audio!
  float* samples = nullptr;
  uint   count = 0;
  this->gui.nes.getAudiobuff(&samples, &count);
  // SDL_QueueAudio(this->gui.sdl.nes_audiodev, samples, count * sizeof(float));
  if (count) this->sdl.sound_queue.write(samples, count);
^/
  // output video!
  const u8* framebuffer;
  this->gui.nes.getFramebuff(&framebuffer);
  SDL_UpdateTexture(this->sdl.screen_texture, nullptr, framebuffer, 256 * 4);

  // actual NES screen
  SDL_SetRenderDrawColor(this->sdl.renderer, 0, 0, 0, 0xff);
  SDL_RenderClear(this->sdl.renderer);
  SDL_RenderCopy(this->sdl.renderer, this->sdl.screen_texture, nullptr, &this->sdl.screen_rect);

  this->menu_submodule->output();

  SDL_RenderPresent(this->sdl.renderer);

  // Present fups though the title of the main window
  char window_title [64];
  sprintf(window_title, "anese - %u fups - %u%% speed",
    uint(this->gui.status.avg_fps), this->gui.nes_params.speed);
  SDL_SetWindowTitle(this->sdl.window, window_title);
}
<commit_msg>Update emu.cc<commit_after>#include "emu.h"

#include <cstdio>

#include "../fs/load.h"
#include "../fs/util.h"

EmuModule::EmuModule(SharedState& gui)
: GUIModule(gui)
{
  /*-------------------------------  SDL init  -------------------------------*/

  fprintf(stderr, "[GUI][Emu] Initializing...\n");

  // make window
  this->sdl.window = SDL_CreateWindow(
    "anese",
    SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    256 * this->gui.config.window_scale,
    240 * this->gui.config.window_scale,
    SDL_WINDOW_RESIZABLE
  );

  // make renderer
  this->sdl.renderer = SDL_CreateRenderer(
    this->sdl.window,
    -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
  );

  // make screen rect (to render texture onto)
  this->sdl.screen_rect.x = 0;
  this->sdl.screen_rect.y = 0;
  this->sdl.screen_rect.w = 256 * this->gui.config.window_scale;
  this->sdl.screen_rect.h = 240 * this->gui.config.window_scale;

  // Letterbox the screen in the window
  SDL_RenderSetLogicalSize(this->sdl.renderer,
    256 * this->gui.config.window_scale,
    240 * this->gui.config.window_scale);

  // Allow opacity
  SDL_SetRenderDrawBlendMode(this->sdl.renderer, SDL_BLENDMODE_BLEND);

  // NES screen texture
  this->sdl.screen_texture = SDL_CreateTexture(
    this->sdl.renderer,
    SDL_PIXELFORMAT_ARGB8888,
    SDL_TEXTUREACCESS_STREAMING,
    256, 240
  );

  // SDL_AudioSpec as, have;
  // as.freq = SDL_GUI::SAMPLE_RATE;
  // as.format = AUDIO_F32SYS;
  // as.channels = 1;
  // as.samples = 4096;
  // as.callback = nullptr; // use SDL_QueueAudio
  // this->sdl_common.nes_audiodev = SDL_OpenAudioDevice(NULL, 0, &as, &have, 0);
  // SDL_PauseAudioDevice(this->sdl_common.nes_audiodev, 0);

//  this->sdl.sound_queue.init(this->gui.nes_params.apu_sample_rate);

  /*----------  Submodule Init  ----------*/

  this->menu_submodule = new MenuSubModule(gui, this->sdl.window, this->sdl.renderer);

  /*----------  NES Init  ----------*/

  this->gui.nes.attach_joy(0, &this->joy_1);
  this->gui.nes.attach_joy(1, &this->zap_2);

  // ---------------------------- Movie Support ----------------------------- //

  if (this->gui.config.cli.replay_fm2_path != "") {
    bool did_load = this->fm2_replay.init(this->gui.config.cli.replay_fm2_path.c_str());
    if (!did_load)
      fprintf(stderr, "[Replay][fm2] Movie loading failed!\n");
    else fprintf(stderr, "[Replay][fm2] Movie successfully loaded!\n");
  }

  if (this->gui.config.cli.record_fm2_path != "") {
    bool did_load = this->fm2_record.init(this->gui.config.cli.record_fm2_path.c_str());
    if (!did_load)
      fprintf(stderr, "[Record][fm2] Failed to setup Movie recording!\n");
    else fprintf(stderr, "[Record][fm2] Movie recording is setup!\n");
  }

  // pass controllers to this->fm2_record
  if (this->fm2_record.is_enabled()) {
    this->fm2_record.set_joy(0, FM2_Controller::SI_GAMEPAD, &this->joy_1);
    this->fm2_record.set_joy(1, FM2_Controller::SI_GAMEPAD, &this->joy_2);
  }

  // attach fm2_replay controllers (if needed)
  if (this->fm2_replay.is_enabled()) {
    this->gui.nes.attach_joy(0, this->fm2_replay.get_joy(0));
    this->gui.nes.attach_joy(1, this->fm2_replay.get_joy(1));
  }
}

EmuModule::~EmuModule() {
  fprintf(stderr, "[GUI][Emu] Shutting down...\n");

  delete this->menu_submodule;

  /*------------------------------  SDL Cleanup  -----------------------------*/

  SDL_DestroyTexture(this->sdl.screen_texture);
  SDL_DestroyRenderer(this->sdl.renderer);
  SDL_DestroyWindow(this->sdl.window);
}

void EmuModule::input(const SDL_Event& event) {
  this->menu_submodule->input(event);
  if (this->gui.status.in_menu) return;

  // Update from Controllers
  if (event.type == SDL_CONTROLLERBUTTONDOWN ||
      event.type == SDL_CONTROLLERBUTTONUP) {
    bool new_state = (event.type == SDL_CONTROLLERBUTTONDOWN) ? true : false;
    using namespace JOY_Standard_Button;

    // Player 1
    switch (event.cbutton.button) {
    case SDL_CONTROLLER_BUTTON_A:          this->joy_1.set_button(A,      new_state); break;
    case SDL_CONTROLLER_BUTTON_X:          this->joy_1.set_button(B,      new_state); break;
    case SDL_CONTROLLER_BUTTON_START:      this->joy_1.set_button(Start,  new_state); break;
    case SDL_CONTROLLER_BUTTON_BACK:       this->joy_1.set_button(Select, new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_UP:    this->joy_1.set_button(Up,     new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_DOWN:  this->joy_1.set_button(Down,   new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_LEFT:  this->joy_1.set_button(Left,   new_state); break;
    case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: this->joy_1.set_button(Right,  new_state); break;
    }

    // Player 2
    // switch (event.cbutton.button) {
    // case SDL_CONTROLLER_BUTTON_A:          this->joy_2.set_button(A,      new_state); break;
    // case SDL_CONTROLLER_BUTTON_X:          this->joy_2.set_button(B,      new_state); break;
    // case SDL_CONTROLLER_BUTTON_START:      this->joy_2.set_button(Start,  new_state); break;
    // case SDL_CONTROLLER_BUTTON_BACK:       this->joy_2.set_button(Select, new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_UP:    this->joy_2.set_button(Up,     new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_DOWN:  this->joy_2.set_button(Down,   new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_LEFT:  this->joy_2.set_button(Left,   new_state); break;
    // case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: this->joy_2.set_button(Right,  new_state); break;
    // }
  }

  // Update from Keyboard
  if (event.type == SDL_KEYDOWN ||
      event.type == SDL_KEYUP) {
    // ------ Keyboard controls ------ //
    bool new_state = (event.type == SDL_KEYDOWN) ? true : false;
    using namespace JOY_Standard_Button;

    // Player 1
    switch (event.key.keysym.sym) {
    case SDLK_z:      this->joy_1.set_button(A,      new_state); break;
    case SDLK_x:      this->joy_1.set_button(B,      new_state); break;
    case SDLK_RETURN: this->joy_1.set_button(Start,  new_state); break;
    case SDLK_RSHIFT: this->joy_1.set_button(Select, new_state); break;
    case SDLK_UP:     this->joy_1.set_button(Up,     new_state); break;
    case SDLK_DOWN:   this->joy_1.set_button(Down,   new_state); break;
    case SDLK_LEFT:   this->joy_1.set_button(Left,   new_state); break;
    case SDLK_RIGHT:  this->joy_1.set_button(Right,  new_state); break;
    }

    // Player 2
    // switch (event.key.keysym.sym) {
    // case SDLK_z:      this->joy_2.set_button(A,      new_state); break;
    // case SDLK_x:      this->joy_2.set_button(B,      new_state); break;
    // case SDLK_RETURN: this->joy_2.set_button(Start,  new_state); break;
    // case SDLK_RSHIFT: this->joy_2.set_button(Select, new_state); break;
    // case SDLK_UP:     this->joy_2.set_button(Up,     new_state); break;
    // case SDLK_DOWN:   this->joy_2.set_button(Down,   new_state); break;
    // case SDLK_LEFT:   this->joy_2.set_button(Left,   new_state); break;
    // case SDLK_RIGHT:  this->joy_2.set_button(Right,  new_state); break;
    // }
  }

  // Zapper

  // if (event.type == SDL_MOUSEMOTION) {
  //   // getting the light from the screen is a bit trickier...
  //   const u8* screen;
  //   this->gui.nes.getFramebuff(screen);
  //   const uint offset = (256 * 4 * (event.motion.y / this->gui.config.window_scale))
  //                     + (      4 * (event.motion.x / this->gui.config.window_scale));
  //   const bool new_light = screen[offset+ 0]  // R
  //                        | screen[offset+ 1]  // G
  //                        | screen[offset+ 2]; // B
  //   this->zap_2.set_light(new_light);
  // }

  // if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
  //   bool new_state = (event.type == SDL_MOUSEBUTTONDOWN) ? true : false;
  //   this->zap_2.set_trigger(new_state);
  // }

  // Handle Key-events
  if (event.type == SDL_KEYDOWN ||
      event.type == SDL_KEYUP) {
    bool mod_shift = event.key.keysym.mod & KMOD_SHIFT;
    // Use CMD on macOS, and CTRL on windows / linux
    bool mod_ctrl = strcmp(SDL_GetPlatform(), "Mac OS X") == 0
      ? event.key.keysym.mod & (KMOD_LGUI | KMOD_RGUI)
      : event.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL);

    // Regular 'ol keys
    switch (event.key.keysym.sym) {
      case SDLK_SPACE:
        // Fast-Forward
        this->speed_counter = 0;
        this->gui.nes_params.speed = (event.type == SDL_KEYDOWN) ? 200 : 100;
        this->gui.nes.updated_params();
        break;
    }

    // Controller
    if (event.type == SDL_CONTROLLERBUTTONDOWN ||
        event.type == SDL_CONTROLLERBUTTONUP) {
      switch (event.cbutton.button) {
      case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
        this->speed_counter = 0;
        this->gui.nes_params.speed = (event.type == SDL_CONTROLLERBUTTONDOWN) ? 200 : 100;
        this->gui.nes.updated_params();
        break;
      }
    }

    // Meta Modified keys
    if (event.type == SDL_KEYDOWN && mod_ctrl) {
      #define SAVESTATE(i) do {                                   \
        if (mod_shift) {                                          \
          delete this->gui.savestate[i];                          \
          this->gui.savestate[i] = this->gui.nes.serialize();     \
        } else this->gui.nes.deserialize(this->gui.savestate[i]); \
      } while(0);

      switch (event.key.keysym.sym) {
      case SDLK_1: SAVESTATE(0); break; // Savestate Slot 1
      case SDLK_2: SAVESTATE(1); break; // Savestate Slot 2
      case SDLK_3: SAVESTATE(2); break; // Savestate Slot 3
      case SDLK_4: SAVESTATE(3); break; // Savestate Slot 4
      case SDLK_r: this->gui.nes.reset();       break; // Reset
      case SDLK_p: this->gui.nes.power_cycle(); break; // Power-Cycle
      case SDLK_EQUALS:
        // Speed up
        this->speed_counter = 0;
        this->gui.nes_params.speed += 25;
        this->gui.nes.updated_params();
        break;
      case SDLK_MINUS:
        // Speed down
        if (this->gui.nes_params.speed - 25 != 0) {
          this->speed_counter = 0;
          this->gui.nes_params.speed -= 25;
          this->gui.nes.updated_params();
        }
        break;
      case SDLK_c: {
        // Toggle CPU trace
        bool log = this->gui.nes_params.log_cpu = !this->gui.nes_params.log_cpu;
        this->gui.nes.updated_params();
        fprintf(stderr, "NESTEST CPU logging: %s\n", log ? "ON" : "OFF");
      } break;
      default: break;
      }
    }
  }
}

void EmuModule::update() {
  this->menu_submodule->update();
  if (this->gui.status.in_menu) return;

  // log frame to fm2
  if (this->fm2_record.is_enabled())
    this->fm2_record.step_frame();

  // set input from fm2
  if (this->fm2_replay.is_enabled())
    this->fm2_replay.step_frame();
}

void EmuModule::output() {
/*  // output audio!
  float* samples = nullptr;
  uint   count = 0;
  this->gui.nes.getAudiobuff(&samples, &count);
  // SDL_QueueAudio(this->gui.sdl.nes_audiodev, samples, count * sizeof(float));
  if (count) this->sdl.sound_queue.write(samples, count);
*/
  // output video!
  const u8* framebuffer;
  this->gui.nes.getFramebuff(&framebuffer);
  SDL_UpdateTexture(this->sdl.screen_texture, nullptr, framebuffer, 256 * 4);

  // actual NES screen
  SDL_SetRenderDrawColor(this->sdl.renderer, 0, 0, 0, 0xff);
  SDL_RenderClear(this->sdl.renderer);
  SDL_RenderCopy(this->sdl.renderer, this->sdl.screen_texture, nullptr, &this->sdl.screen_rect);

  this->menu_submodule->output();

  SDL_RenderPresent(this->sdl.renderer);

  // Present fups though the title of the main window
  char window_title [64];
  sprintf(window_title, "anese - %u fups - %u%% speed",
    uint(this->gui.status.avg_fps), this->gui.nes_params.speed);
  SDL_SetWindowTitle(this->sdl.window, window_title);
}
<|endoftext|>


<commit_before>#ifndef FULL_MATRIX_HPP_
#define FULL_MATRIX_HPP_

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

#include "../Matrix.hpp"

namespace aff3ct
{
namespace tools
{
/*
 * \param T must be int8_t or int16_t or int32_t or int64_t
 * Warning ! Never call modification methods (resize, erase, push_back and so on), on the second dimension of the Full_matrix
 *   always pass through Full_matrix methods, else you may obtain runtime errors
 */

template <typename T = int32_t>
class Full_matrix : public Matrix, public std::vector<std::vector<T>>
{
public:
	using Container = std::vector<std::vector<T>>;
	using value_type = T;

	Full_matrix(const unsigned n_rows = 0, const unsigned n_cols = 1);

	virtual ~Full_matrix() = default;

	/*
	 * return true if there is a connection there
	 */
	bool at(const size_t row_index, const size_t col_index) const;

	/*
	 * Add a connection and update the rows and cols degrees values
	 */
	void add_connection(const size_t row_index, const size_t col_index);

	/*
	 * Remove the connection and update the rows and cols degrees values
	 */
	void rm_connection(const size_t row_index, const size_t col_index);

	/*
	 * Resize the matrix to the new dimensions in function of the part of the matrix considered as the origin
	 * Ex: if o == BOTTOM_RIGHT, and need to extend the matrix then add rows on the top and columns on the left
	 */
	void self_resize(const size_t n_rows, const size_t n_cols, Origin o);

	/*
	 * Resize the matrix by calling self_resize on a copy matrix
	 */
	Full_matrix resize(const size_t n_rows, const size_t n_cols, Origin o) const;

	/*
	 * Erase the 'n_rows' rows from the given index 'row_index'
	 */
	void erase_row(const size_t row_index, const size_t n_rows = 1);

	/*
	 * Erase the 'n_cols' cols from the given index 'col_index'
	 */
	void erase_col(const size_t col_index, const size_t n_cols = 1);

	void erase(); // never use 'erase' methods, use instead erase_col or erase_row

	/*
	 * Compute the rows and cols degrees values when the matrix values have been modified
	 * without the use of 'add_connection' and 'rm_connection' interface, so after any modification
	 * call this function if you need degrees information
	 */
	void parse_connections();

	/*
	 * Return the transposed matrix of this matrix
	 */
	Full_matrix transpose() const;

	/*
	 * Transpose internally this matrix
	 */
	void self_transpose();

	/*
	 * Return turn the matrix in horizontal or vertical way
	 */
	Full_matrix turn(Way w) const;

	/*
	 * Sort the matrix per density of lines in ascending or descending order
	 * You need to call 'parse_connections()' before to assure good work.
	 */
	void sort_cols_per_density(Sort order);

	/*
	 * Print the matrix in its full view with 0s and 1s.
	 * 'transpose' allow the print in its transposed view
	 */
	void print(bool transpose = false, std::ostream& os = std::cout) const;

	/*
	 * \brief create a matrix of the given size filled with identity diagonal
	 * \return the identity matrix
	 */
	static Full_matrix<T> identity(const size_t n_rows, const size_t n_cols);

	/*
	 * \brief create a matrix of the given size filled with only zeros
	 * \return the zero matrix
	 */
	static Full_matrix<T> zero(const size_t n_rows, const size_t n_cols);

private:
	std::vector<size_t> rows_degrees;
	std::vector<size_t> cols_degrees;
};
}
}

#endif /* FULL_MATRIX_HPP_ */
<commit_msg>Set the inheritance of the Full_matrix container as private and use as public only size() and operator[]<commit_after>#ifndef FULL_MATRIX_HPP_
#define FULL_MATRIX_HPP_

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

#include "../Matrix.hpp"

namespace aff3ct
{
namespace tools
{
/*
 * \param T must be int8_t or int16_t or int32_t or int64_t
 * Warning ! Never call modification methods (resize, erase, push_back and so on), on the second dimension of the Full_matrix
 *   always pass through Full_matrix methods, else you may obtain runtime errors
 */

template <typename T = int32_t>
class Full_matrix : public Matrix, private std::vector<std::vector<T>>
{
public:
	using Container = std::vector<std::vector<T>>;
	using value_type = T;

	explicit Full_matrix(const unsigned n_rows = 0, const unsigned n_cols = 1);

	virtual ~Full_matrix() = default;

	/*
	 * return true if there is a connection there
	 */
	bool at(const size_t row_index, const size_t col_index) const;

	/*
	 * Add a connection and update the rows and cols degrees values
	 */
	void add_connection(const size_t row_index, const size_t col_index);

	/*
	 * Remove the connection and update the rows and cols degrees values
	 */
	void rm_connection(const size_t row_index, const size_t col_index);

	/*
	 * Resize the matrix to the new dimensions in function of the part of the matrix considered as the origin
	 * Ex: if o == BOTTOM_RIGHT, and need to extend the matrix then add rows on the top and columns on the left
	 */
	void self_resize(const size_t n_rows, const size_t n_cols, Origin o);

	/*
	 * Resize the matrix by calling self_resize on a copy matrix
	 */
	Full_matrix resize(const size_t n_rows, const size_t n_cols, Origin o) const;

	/*
	 * Erase the 'n_rows' rows from the given index 'row_index'
	 */
	void erase_row(const size_t row_index, const size_t n_rows = 1);

	/*
	 * Erase the 'n_cols' cols from the given index 'col_index'
	 */
	void erase_col(const size_t col_index, const size_t n_cols = 1);

	using Container::size;
	using Container::operator[];

	/*
	 * Compute the rows and cols degrees values when the matrix values have been modified
	 * without the use of 'add_connection' and 'rm_connection' interface, so after any modification
	 * call this function if you need degrees information
	 */
	void parse_connections();

	/*
	 * Return the transposed matrix of this matrix
	 */
	Full_matrix transpose() const;

	/*
	 * Transpose internally this matrix
	 */
	void self_transpose();

	/*
	 * Return turn the matrix in horizontal or vertical way
	 */
	Full_matrix turn(Way w) const;

	/*
	 * Sort the matrix per density of lines in ascending or descending order
	 * You need to call 'parse_connections()' before to assure good work.
	 */
	void sort_cols_per_density(Sort order);

	/*
	 * Print the matrix in its full view with 0s and 1s.
	 * 'transpose' allow the print in its transposed view
	 */
	void print(bool transpose = false, std::ostream& os = std::cout) const;

	/*
	 * \brief create a matrix of the given size filled with identity diagonal
	 * \return the identity matrix
	 */
	static Full_matrix<T> identity(const size_t n_rows, const size_t n_cols);

	/*
	 * \brief create a matrix of the given size filled with only zeros
	 * \return the zero matrix
	 */
	static Full_matrix<T> zero(const size_t n_rows, const size_t n_cols);

private:
	std::vector<size_t> rows_degrees;
	std::vector<size_t> cols_degrees;
};
}
}

#endif /* FULL_MATRIX_HPP_ */
<|endoftext|>


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

#include <cmath>

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/guardian/common/guardian_gflags.h"
#include "ros/include/ros/ros.h"

namespace apollo {
namespace guardian {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;
using apollo::control::ControlCommand;
using apollo::guardian::GuardianCommand;
using apollo::monitor::SystemStatus;

std::string Guardian::Name() const { return FLAGS_module_name; }

Status Guardian::Init() {
  AdapterManager::Init(FLAGS_adapter_config_filename);
  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";
  CHECK(AdapterManager::GetSystemStatus())
      << "SystemStatus is not initialized.";
  CHECK(AdapterManager::GetControlCommand()) << "Control is not initialized.";
  return Status::OK();
}

Status Guardian::Start() {
  AdapterManager::AddChassisCallback(&Guardian::OnChassis, this);
  AdapterManager::AddSystemStatusCallback(&Guardian::OnSystemStatus, this);
  AdapterManager::AddControlCommandCallback(&Guardian::OnControl, this);
  const double duration = 1.0 / FLAGS_guardian_cmd_freq;
  timer_ = AdapterManager::CreateTimer(ros::Duration(duration),
                                       &Guardian::OnTimer, this);

  return Status::OK();
}

void Guardian::Stop() { timer_.stop(); }

void Guardian::OnTimer(const ros::TimerEvent&) {
  ADEBUG << "Timer is triggered: publish Guardian result";
  bool safety_mode_triggered = false;
  if (FLAGS_guardian_enabled) {
    std::lock_guard<std::mutex> lock(mutex_);
    safety_mode_triggered = system_status_.has_safety_mode_trigger_time();
  }

  if (safety_mode_triggered) {
    ADEBUG << "Safety mode triggerd, enable safty mode";
    TriggerSafetyMode();
  } else {
    ADEBUG << "Safety mode not triggerd, bypass control command";
    ByPassControlCommand();
  }

  AdapterManager::FillGuardianHeader(FLAGS_node_name, &guardian_cmd_);
  AdapterManager::PublishGuardian(guardian_cmd_);
}

void Guardian::OnChassis(const Chassis& message) {
  ADEBUG << "Received chassis data: run chassis callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  chassis_.CopyFrom(message);
}

void Guardian::OnSystemStatus(const SystemStatus& message) {
  ADEBUG << "Received monitor data: run monitor callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  system_status_.CopyFrom(message);
}

void Guardian::OnControl(const ControlCommand& message) {
  ADEBUG << "Received control data: run control command callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  control_cmd_.CopyFrom(message);
}

void Guardian::ByPassControlCommand() {
  std::lock_guard<std::mutex> lock(mutex_);
  guardian_cmd_.mutable_control_command()->CopyFrom(control_cmd_);
}

void Guardian::TriggerSafetyMode() {
  ADEBUG << "Received chassis data: run chassis callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  bool sensor_malfunction = false, obstacle_detected = false;
  if (!chassis_.surround().sonar_enabled() ||
      chassis_.surround().sonar_fault()) {
    AINFO << "Ultrasonic sensor not enabled for faulted, will do emergency "
             "stop!";
    sensor_malfunction = true;
  } else {
    // TODO(QiL) : Load for config
    for (int i = 0; i < chassis_.surround().sonar_range_size(); ++i) {
      if ((chassis_.surround().sonar_range(i) > 0.0 &&
           chassis_.surround().sonar_range(i) < 2.5) ||
          chassis_.surround().sonar_range(i) > 30) {
        AINFO << "Object detected or ultrasonic sensor fault output, will do "
                 "emergency stop!";
        obstacle_detected = true;
      }
    }
  }

  guardian_cmd_.mutable_control_command()->set_throttle(0.0);
  guardian_cmd_.mutable_control_command()->set_steering_target(0.0);
  guardian_cmd_.mutable_control_command()->set_steering_rate(0.0);
  guardian_cmd_.mutable_control_command()->set_is_in_safe_mode(true);

  if (system_status_.require_emergency_stop() || sensor_malfunction ||
      obstacle_detected) {
    AINFO << "Emergency stop triggered! with system status from monitor as : "
          << system_status_.require_emergency_stop();
    guardian_cmd_.mutable_control_command()->set_brake(
        FLAGS_guardian_cmd_emergency_stop_percentage);
  } else {
    AINFO << "Soft stop triggered! with system status from monitor as : "
          << system_status_.require_emergency_stop();
    guardian_cmd_.mutable_control_command()->set_brake(
        FLAGS_guardian_cmd_soft_stop_percentage);
  }
}

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

#include <cmath>

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/guardian/common/guardian_gflags.h"
#include "ros/include/ros/ros.h"

namespace apollo {
namespace guardian {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;
using apollo::control::ControlCommand;
using apollo::guardian::GuardianCommand;
using apollo::monitor::SystemStatus;

std::string Guardian::Name() const { return FLAGS_module_name; }

Status Guardian::Init() {
  AdapterManager::Init(FLAGS_adapter_config_filename);
  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";
  CHECK(AdapterManager::GetSystemStatus())
      << "SystemStatus is not initialized.";
  CHECK(AdapterManager::GetControlCommand()) << "Control is not initialized.";
  return Status::OK();
}

Status Guardian::Start() {
  AdapterManager::AddChassisCallback(&Guardian::OnChassis, this);
  AdapterManager::AddSystemStatusCallback(&Guardian::OnSystemStatus, this);
  AdapterManager::AddControlCommandCallback(&Guardian::OnControl, this);
  const double duration = 1.0 / FLAGS_guardian_cmd_freq;
  timer_ = AdapterManager::CreateTimer(ros::Duration(duration),
                                       &Guardian::OnTimer, this);

  return Status::OK();
}

void Guardian::Stop() { timer_.stop(); }

void Guardian::OnTimer(const ros::TimerEvent&) {
  ADEBUG << "Timer is triggered: publish Guardian result";
  bool safety_mode_triggered = false;
  if (FLAGS_guardian_enabled) {
    std::lock_guard<std::mutex> lock(mutex_);
    safety_mode_triggered = system_status_.has_safety_mode_trigger_time();
  }

  if (safety_mode_triggered) {
    ADEBUG << "Safety mode triggerd, enable safty mode";
    TriggerSafetyMode();
  } else {
    ADEBUG << "Safety mode not triggerd, bypass control command";
    ByPassControlCommand();
  }

  AdapterManager::FillGuardianHeader(FLAGS_node_name, &guardian_cmd_);
  AdapterManager::PublishGuardian(guardian_cmd_);
}

void Guardian::OnChassis(const Chassis& message) {
  ADEBUG << "Received chassis data: run chassis callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  chassis_.CopyFrom(message);
}

void Guardian::OnSystemStatus(const SystemStatus& message) {
  ADEBUG << "Received monitor data: run monitor callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  system_status_.CopyFrom(message);
}

void Guardian::OnControl(const ControlCommand& message) {
  ADEBUG << "Received control data: run control command callback.";
  std::lock_guard<std::mutex> lock(mutex_);
  control_cmd_.CopyFrom(message);
}

void Guardian::ByPassControlCommand() {
  std::lock_guard<std::mutex> lock(mutex_);
  guardian_cmd_.mutable_control_command()->CopyFrom(control_cmd_);
}

void Guardian::TriggerSafetyMode() {
  AINFO << "Safety state triggered, with system safety mode trigger time : "
        << system_status_.safety_mode_trigger_time();
  std::lock_guard<std::mutex> lock(mutex_);
  bool sensor_malfunction = false, obstacle_detected = false;
  if (!chassis_.surround().sonar_enabled() ||
      chassis_.surround().sonar_fault()) {
    AINFO << "Ultrasonic sensor not enabled for faulted, will do emergency "
             "stop!";
    sensor_malfunction = true;
  } else {
    // TODO(QiL) : Load for config
    for (int i = 0; i < chassis_.surround().sonar_range_size(); ++i) {
      if ((chassis_.surround().sonar_range(i) > 0.0 &&
           chassis_.surround().sonar_range(i) < 2.5) ||
          chassis_.surround().sonar_range(i) > 30) {
        AINFO << "Object detected or ultrasonic sensor fault output, will do "
                 "emergency stop!";
        obstacle_detected = true;
      }
    }
  }

  guardian_cmd_.mutable_control_command()->set_throttle(0.0);
  guardian_cmd_.mutable_control_command()->set_steering_target(0.0);
  guardian_cmd_.mutable_control_command()->set_steering_rate(0.0);
  guardian_cmd_.mutable_control_command()->set_is_in_safe_mode(true);

  // TODO(QiL) : Remove this one once hardware re-alignment is done.
  sensor_malfunction = false;
  obstacle_detected = false;
  AINFO << "Temperarily ignore the ultrasonic sensor output during hardware "
           "re-alignment!";

  if (system_status_.require_emergency_stop() || sensor_malfunction ||
      obstacle_detected) {
    AINFO << "Emergency stop triggered! with system status from monitor as : "
          << system_status_.require_emergency_stop();
    guardian_cmd_.mutable_control_command()->set_brake(
        FLAGS_guardian_cmd_emergency_stop_percentage);
  } else {
    AINFO << "Soft stop triggered! with system status from monitor as : "
          << system_status_.require_emergency_stop();
    guardian_cmd_.mutable_control_command()->set_brake(
        FLAGS_guardian_cmd_soft_stop_percentage);
  }
}

}  // namespace guardian
}  // namespace apollo
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_StringBuilder_inl_
#define _Stroika_Foundation_Characters_StringBuilder_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    <memory>
#include    "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Characters {

            /*
             ********************************************************************************
             ***************************** Implementation Details ***************************
             ********************************************************************************
             */
            inline  StringBuilder::StringBuilder ()
                : fData_ (0)
                , fLength_ (0)
            {
            }
            inline StringBuilder::StringBuilder (const String& initialValue)
                : fData_ (0)
                , fLength_ (0)
            {
                operator+= (initialValue);
            }
            inline  StringBuilder&  StringBuilder::operator+= (const wchar_t* s)
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                size_t  i   =   fLength_;
                size_t  l   =   ::wcslen (s);
                fData_.GrowToSize (i + l);
                fLength_ = i + i;
                memcpy (fData_.begin () + i, s, sizeof (wchar_t) * l);
            }
            inline  StringBuilder&  StringBuilder::operator+= (const String& s)
            {
                return operator+= (s.c_str ());
            }
            inline  StringBuilder&  StringBuilder::operator<< (const String& s)
            {
                return operator+= (s.c_str ());
            }
            inline  StringBuilder&  StringBuilder::operator<< (const wchar_t* s)
            {
                return operator+= (s);
            }
            inline  StringBuilder::operator String () const
            {
                return str ();
            }
            inline  const wchar_t*  StringBuilder::c_str () const
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                fData_.GrowToSize (fLength_ + 1);
                fData_[fLength_] = '\0';
                return fData_.begin ();
            }
            inline  String StringBuilder::str () const
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                size_t  l   =   fLength_;
                return String (fData_.begin (), fData_.begin () + l);
            }

        }
    }
}
#endif // _Stroika_Foundation_Characters_StringBuilder_inl_
<commit_msg>fixed small bug with StringBuilder<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2014.  All rights reserved
 */
#ifndef _Stroika_Foundation_Characters_StringBuilder_inl_
#define _Stroika_Foundation_Characters_StringBuilder_inl_

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    <memory>
#include    "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Characters {

            /*
             ********************************************************************************
             ***************************** Implementation Details ***************************
             ********************************************************************************
             */
            inline  StringBuilder::StringBuilder ()
                : fData_ (0)
                , fLength_ (0)
            {
            }
            inline StringBuilder::StringBuilder (const String& initialValue)
                : fData_ (0)
                , fLength_ (0)
            {
                operator+= (initialValue);
            }
            inline  StringBuilder&  StringBuilder::operator+= (const wchar_t* s)
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                size_t  i   =   fLength_;
                size_t  l   =   ::wcslen (s);
                fData_.GrowToSize (i + l);
                fLength_ = i + i;
                memcpy (fData_.begin () + i, s, sizeof (wchar_t) * l);
                return *this;
            }
            inline  StringBuilder&  StringBuilder::operator+= (const String& s)
            {
                return operator+= (s.c_str ());
            }
            inline  StringBuilder&  StringBuilder::operator<< (const String& s)
            {
                return operator+= (s.c_str ());
            }
            inline  StringBuilder&  StringBuilder::operator<< (const wchar_t* s)
            {
                return operator+= (s);
            }
            inline  StringBuilder::operator String () const
            {
                return str ();
            }
            inline  const wchar_t*  StringBuilder::c_str () const
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                fData_.GrowToSize (fLength_ + 1);
                fData_[fLength_] = '\0';
                return fData_.begin ();
            }
            inline  String StringBuilder::str () const
            {
                lock_guard<Execution::ExternallySynchronizedLock> critSec (fLock_);
                size_t  l   =   fLength_;
                return String (fData_.begin (), fData_.begin () + l);
            }

        }
    }
}
#endif // _Stroika_Foundation_Characters_StringBuilder_inl_
<|endoftext|>


<commit_before>#include <algorithm>
#include <vector>

#include "unittest/gtest.hpp"

#include "btree/node.hpp"
#include "btree/leaf_node.hpp"

namespace unittest {

// TODO: This is rather duplicative of fsck::check_value.
void expect_valid_value_shallowly(const btree_value *value) {
    EXPECT_EQ(0, value->metadata_flags & ~(MEMCACHED_FLAGS | MEMCACHED_CAS | MEMCACHED_EXPTIME | LARGE_VALUE));

    size_t size = value->value_size();

    if (value->is_large()) {
        EXPECT_GT(size, MAX_IN_NODE_VALUE_SIZE);

        // This isn't fsck, we can't follow large buf pointers.
    } else {
        EXPECT_LE(size, MAX_IN_NODE_VALUE_SIZE);
    }
}

// TODO: This is rather duplicative of fsck::check_subtree_leaf_node.
void verify(block_size_t block_size, const leaf_node_t *buf, int expected_free_space) {

    int end_of_pair_offsets = offsetof(leaf_node_t, pair_offsets) + buf->npairs * 2;
    ASSERT_LE(end_of_pair_offsets, buf->frontmost_offset);
    ASSERT_LE(buf->frontmost_offset, block_size.value());
    ASSERT_EQ(expected_free_space, buf->frontmost_offset - end_of_pair_offsets);

    std::vector<uint16_t> offsets(buf->pair_offsets, buf->pair_offsets + buf->npairs);
    std::sort(offsets.begin(), offsets.end());

    uint16_t expected = buf->frontmost_offset;
    for (std::vector<uint16_t>::const_iterator p = offsets.begin(), e = offsets.end(); p < e; ++p) {
        ASSERT_LE(expected, block_size.value());
        ASSERT_EQ(expected, *p);
        expected += leaf_node_handler::pair_size(leaf_node_handler::get_pair(buf, *p));
    }
    ASSERT_EQ(block_size.value(), expected);

    const btree_key *last_key = NULL;
    for (const uint16_t *p = buf->pair_offsets, *e = p + buf->npairs; p < e; ++p) {
        const btree_leaf_pair *pair = leaf_node_handler::get_pair(buf, *p);
        if (last_key != NULL) {
            const btree_key *next_key = &pair->key;
            EXPECT_LT(leaf_key_comp::compare(last_key, next_key), 0);
            last_key = next_key;
        }
        expect_valid_value_shallowly(pair->value());
    }
}

TEST(LeafNodeTest, Offsets) {
    // Check leaf_node_t.
    EXPECT_EQ(0, offsetof(leaf_node_t, magic));
    EXPECT_EQ(4, offsetof(leaf_node_t, times));
    EXPECT_EQ(12, offsetof(leaf_node_t, npairs));
    EXPECT_EQ(14, offsetof(leaf_node_t, frontmost_offset));
    EXPECT_EQ(16, offsetof(leaf_node_t, pair_offsets));
    EXPECT_EQ(16, sizeof(leaf_node_t));

    // Check leaf_timestamps_t, since that's specifically part of leaf_node_t.
    EXPECT_EQ(0, offsetof(leaf_timestamps_t, last_modified));
    EXPECT_EQ(4, offsetof(leaf_timestamps_t, earlier));

    // Changing NUM_LEAF_NODE_EARLIER_TIMES changes the disk format.
    EXPECT_EQ(2, NUM_LEAF_NODE_EARLIER_TIMES);

    EXPECT_EQ(8, sizeof(leaf_timestamps_t));

    // Check btree_leaf_pair.
    EXPECT_EQ(0, offsetof(btree_leaf_pair, key));

    btree_leaf_pair p;
    p.key.size = 173;
    EXPECT_EQ(174, reinterpret_cast<byte *>(p.value()) - reinterpret_cast<byte *>(&p));

    EXPECT_EQ(1, sizeof(btree_key));
    EXPECT_EQ(1, offsetof(btree_key, contents));
    EXPECT_EQ(2, sizeof(btree_value));
}

class Value {
public:
    Value(const std::string& data = "", mcflags_t mcflags = 0, cas_t cas = 0, bool has_cas = false, exptime_t exptime = 0)
        : mcflags_(mcflags), cas_(cas), exptime_(exptime),
          has_cas_(has_cas),
          data_(data) {
        EXPECT_LE(data_.size(), MAX_IN_NODE_VALUE_SIZE);
    }

    void WriteBtreeValue(btree_value *out) const {
        out->size = 0;
        out->metadata_flags = 0;

        ASSERT_LE(data_.size(), MAX_IN_NODE_VALUE_SIZE);
        out->value_size(data_.size());
        out->set_mcflags(mcflags_);
        out->set_exptime(exptime_);
        if (has_cas_) {
            out->set_cas(cas_);
        }
        memcpy(out->value(), data_.c_str(), data_.size());
    }

    static Value Make(const btree_value *v) {
        EXPECT_FALSE(v->is_large());
        return Value(std::string(v->value(), v->value() + v->value_size()),
                     v->mcflags(), v->has_cas() ? v->cas() : 0, v->has_cas(), v->exptime());
    }

    bool operator==(const Value& rhs) const {
        return mcflags_ == rhs.mcflags_
            && exptime_ == rhs.exptime_
            && data_ == rhs.data_
            && has_cas_ == rhs.has_cas_
            && (has_cas_ ? cas_ == rhs.cas_ : true);
    }

    int full_size() const {
        return sizeof(btree_value) + (mcflags_ ? sizeof(mcflags_t) : 0) + (has_cas_ ? sizeof(cas_t) : 0)
            + (exptime_ ? sizeof(exptime_t) : 0) + data_.size();
    }

    friend std::ostream& operator<<(std::ostream&, const Value&);

private:
    mcflags_t mcflags_;
    cas_t cas_;
    exptime_t exptime_;
    bool has_cas_;
    std::string data_;
};

std::ostream& operator<<(std::ostream& out, const Value& v) {
    out << "Value[mcflags=" << v.mcflags_;
    if (v.has_cas_) {
        out << " cas=" << v.cas_;
    }

    // TODO: string escape v.data_.
    out << " exptime=" << v.exptime_
        << " data='" << v.data_ << "']";
    return out;
}

class StackKey {
public:
    explicit StackKey(const std::string& key) {
        EXPECT_LE(key.size(), MAX_KEY_SIZE);
        keyval.size = key.size();
        memcpy(keyval.contents, key.c_str(), key.size());
    }

    const btree_key *look() const {
        return &keyval;
    }

private:
    union {
        byte keyval_padding[sizeof(btree_key) + MAX_KEY_SIZE];
        btree_key keyval;
    };
};

class StackValue {
public:
    StackValue() {
        memset(val_padding, 0, sizeof(val_padding));
    }
    explicit StackValue(const Value& value) {
        value.WriteBtreeValue(&val);
    }
    const btree_value *look() const {
        return &val;
    }
    btree_value *look_write() {
        return &val;
    }
private:
    union {
        byte val_padding[sizeof(btree_value) + MAX_TOTAL_NODE_CONTENTS_SIZE];
        btree_value val;
    };
};

template <int block_size>
class LeafNodeGrinder {
    block_size_t bs;
    typedef std::map<std::string, Value> expected_t;
    expected_t expected;
    int expected_frontmost_offset;
    int expected_npairs;
    leaf_node_t *node;

public:
    LeafNodeGrinder() : bs(block_size_t::unsafe_make(block_size)), expected(), expected_frontmost_offset(bs.value()), expected_npairs(0), node(reinterpret_cast<leaf_node_t *>(malloc(bs.value()))) {
    }

    ~LeafNodeGrinder() {
        free(node);
    }

    int expected_space() const {
        return expected_frontmost_offset - (offsetof(leaf_node_t, pair_offsets) + sizeof(*node->pair_offsets) * expected_npairs);
    }

    void init() {
        SCOPED_TRACE("init");
        leaf_node_handler::init(bs, node, repli_timestamp::invalid);
        validate();
    }

    void insert(const std::string& k, const Value& v) {
        SCOPED_TRACE("insert");
        StackKey skey(k);
        StackValue sval(v);

        if (expected_space() < int((1 + k.size()) + v.full_size() + sizeof(*node->pair_offsets))) {
            ASSERT_FALSE(leaf_node_handler::insert(bs, node, skey.look(), sval.look(), repli_timestamp::invalid));
        } else {
            ASSERT_TRUE(leaf_node_handler::insert(bs, node, skey.look(), sval.look(), repli_timestamp::invalid));

            std::pair<expected_t::iterator, bool> res = expected.insert(std::make_pair(k, v));
            if (res.second) {
                // The key didn't previously exist.
                expected_frontmost_offset -= (1 + k.size()) + v.full_size();
                expected_npairs++;
            } else {
                // The key previously existed.
                expected_frontmost_offset += res.first->second.full_size();
                expected_frontmost_offset -= v.full_size();
                res.first->second = v;
            }
        }

        validate();
    }

    void lookup(const std::string& k, const Value& expected) const {
        StackKey skey(k);
        StackValue sval;
        ASSERT_TRUE(leaf_node_handler::lookup(node, skey.look(), sval.look_write()));
        ASSERT_EQ(expected, Value::Make(sval.look()));
    }

    // Expects the key to be in the node.
    void remove(const std::string& k) {
        SCOPED_TRACE("remove");
        expected_t::iterator p = expected.find(k);

        // There's a bug in the test if we're trying to remove a key that's not there.
        ASSERT_TRUE(p != expected.end());

        // The key should be in there.
        StackKey skey(k);
        StackValue sval;

        ASSERT_TRUE(leaf_node_handler::lookup(node, skey.look(), sval.look_write()));

        leaf_node_handler::remove(bs, node, skey.look());
        expected.erase(p);
        expected_frontmost_offset += (1 + k.size()) + sval.look()->full_size();
        -- expected_npairs;

        validate();
    }

    void validate() const {
        ASSERT_EQ(expected_npairs, node->npairs);
        ASSERT_EQ(expected_frontmost_offset, node->frontmost_offset);

        verify(bs, node, expected_space());

        for (expected_t::const_iterator p = expected.begin(), e = expected.end(); p != e; ++p) {
            lookup(p->first, p->second);
        }

        // We're confident there are no bad keys because
        // expected_free_space matched up.
    }

};

block_size_t make_bs() {
    // TODO: Test weird block sizes.
    return block_size_t::unsafe_make(4096);
}

leaf_node_t *malloc_leaf_node(block_size_t bs) {
    return reinterpret_cast<leaf_node_t *>(malloc(bs.value()));
}

btree_key *malloc_key(const char *s) {
    size_t origlen = strlen(s);
    EXPECT_LE(origlen, MAX_KEY_SIZE);

    size_t len = std::min<size_t>(origlen, MAX_KEY_SIZE);
    btree_key *k = reinterpret_cast<btree_key *>(malloc(sizeof(btree_key) + len));
    k->size = len;
    memcpy(k->contents, s, len);
    return k;
}

btree_value *malloc_value(const char *s) {
    size_t origlen = strlen(s);
    EXPECT_LE(origlen, MAX_IN_NODE_VALUE_SIZE);

    size_t len = std::min<size_t>(origlen, MAX_IN_NODE_VALUE_SIZE);

    btree_value *v = reinterpret_cast<btree_value *>(malloc(sizeof(btree_value) + len));
    v->size = len;
    v->metadata_flags = 0;
    memcpy(v->value(), s, len);
    return v;
}

TEST(LeafNodeTest, Initialization) {
    block_size_t bs = make_bs();
    leaf_node_t *node = malloc_leaf_node(bs);

    leaf_node_handler::init(bs, node, repli_timestamp::invalid);
    verify(bs, node, bs.value() - offsetof(leaf_node_t, pair_offsets));
    free(node);
}

void InsertLookupRemoveHelper(const std::string& key, const char *value) {
    LeafNodeGrinder<4096> gr;

    Value v(value);

    gr.init();
    gr.insert(key, v);
    gr.lookup(key, v);
    gr.remove(key);
}

TEST(LeafNodeTest, ElementaryInsertLookupRemove) {
    InsertLookupRemoveHelper("the_key", "the_value");
}
TEST(LeafNodeTest, EmptyValueInsertLookupRemove) {
    InsertLookupRemoveHelper("the_key", "");
}
TEST(LeafNodeTest, EmptyKeyInsertLookupRemove) {
    InsertLookupRemoveHelper("", "the_value");
}
TEST(LeafNodeTest, EmptyKeyValueInsertLookupRemove) {
    InsertLookupRemoveHelper("", "");
}

}  // namespace unittest

<commit_msg>Made lookup private, moved variables around.<commit_after>#include <algorithm>
#include <vector>

#include "unittest/gtest.hpp"

#include "btree/node.hpp"
#include "btree/leaf_node.hpp"

namespace unittest {

// TODO: This is rather duplicative of fsck::check_value.
void expect_valid_value_shallowly(const btree_value *value) {
    EXPECT_EQ(0, value->metadata_flags & ~(MEMCACHED_FLAGS | MEMCACHED_CAS | MEMCACHED_EXPTIME | LARGE_VALUE));

    size_t size = value->value_size();

    if (value->is_large()) {
        EXPECT_GT(size, MAX_IN_NODE_VALUE_SIZE);

        // This isn't fsck, we can't follow large buf pointers.
    } else {
        EXPECT_LE(size, MAX_IN_NODE_VALUE_SIZE);
    }
}

// TODO: This is rather duplicative of fsck::check_subtree_leaf_node.
void verify(block_size_t block_size, const leaf_node_t *buf, int expected_free_space) {

    int end_of_pair_offsets = offsetof(leaf_node_t, pair_offsets) + buf->npairs * 2;
    ASSERT_LE(end_of_pair_offsets, buf->frontmost_offset);
    ASSERT_LE(buf->frontmost_offset, block_size.value());
    ASSERT_EQ(expected_free_space, buf->frontmost_offset - end_of_pair_offsets);

    std::vector<uint16_t> offsets(buf->pair_offsets, buf->pair_offsets + buf->npairs);
    std::sort(offsets.begin(), offsets.end());

    uint16_t expected = buf->frontmost_offset;
    for (std::vector<uint16_t>::const_iterator p = offsets.begin(), e = offsets.end(); p < e; ++p) {
        ASSERT_LE(expected, block_size.value());
        ASSERT_EQ(expected, *p);
        expected += leaf_node_handler::pair_size(leaf_node_handler::get_pair(buf, *p));
    }
    ASSERT_EQ(block_size.value(), expected);

    const btree_key *last_key = NULL;
    for (const uint16_t *p = buf->pair_offsets, *e = p + buf->npairs; p < e; ++p) {
        const btree_leaf_pair *pair = leaf_node_handler::get_pair(buf, *p);
        if (last_key != NULL) {
            const btree_key *next_key = &pair->key;
            EXPECT_LT(leaf_key_comp::compare(last_key, next_key), 0);
            last_key = next_key;
        }
        expect_valid_value_shallowly(pair->value());
    }
}

TEST(LeafNodeTest, Offsets) {
    // Check leaf_node_t.
    EXPECT_EQ(0, offsetof(leaf_node_t, magic));
    EXPECT_EQ(4, offsetof(leaf_node_t, times));
    EXPECT_EQ(12, offsetof(leaf_node_t, npairs));
    EXPECT_EQ(14, offsetof(leaf_node_t, frontmost_offset));
    EXPECT_EQ(16, offsetof(leaf_node_t, pair_offsets));
    EXPECT_EQ(16, sizeof(leaf_node_t));

    // Check leaf_timestamps_t, since that's specifically part of leaf_node_t.
    EXPECT_EQ(0, offsetof(leaf_timestamps_t, last_modified));
    EXPECT_EQ(4, offsetof(leaf_timestamps_t, earlier));

    // Changing NUM_LEAF_NODE_EARLIER_TIMES changes the disk format.
    EXPECT_EQ(2, NUM_LEAF_NODE_EARLIER_TIMES);

    EXPECT_EQ(8, sizeof(leaf_timestamps_t));

    // Check btree_leaf_pair.
    EXPECT_EQ(0, offsetof(btree_leaf_pair, key));

    btree_leaf_pair p;
    p.key.size = 173;
    EXPECT_EQ(174, reinterpret_cast<byte *>(p.value()) - reinterpret_cast<byte *>(&p));

    EXPECT_EQ(1, sizeof(btree_key));
    EXPECT_EQ(1, offsetof(btree_key, contents));
    EXPECT_EQ(2, sizeof(btree_value));
}

class Value {
public:
    Value(const std::string& data = "", mcflags_t mcflags = 0, cas_t cas = 0, bool has_cas = false, exptime_t exptime = 0)
        : mcflags_(mcflags), cas_(cas), exptime_(exptime),
          has_cas_(has_cas),
          data_(data) {
        EXPECT_LE(data_.size(), MAX_IN_NODE_VALUE_SIZE);
    }

    void WriteBtreeValue(btree_value *out) const {
        out->size = 0;
        out->metadata_flags = 0;

        ASSERT_LE(data_.size(), MAX_IN_NODE_VALUE_SIZE);
        out->value_size(data_.size());
        out->set_mcflags(mcflags_);
        out->set_exptime(exptime_);
        if (has_cas_) {
            out->set_cas(cas_);
        }
        memcpy(out->value(), data_.c_str(), data_.size());
    }

    static Value Make(const btree_value *v) {
        EXPECT_FALSE(v->is_large());
        return Value(std::string(v->value(), v->value() + v->value_size()),
                     v->mcflags(), v->has_cas() ? v->cas() : 0, v->has_cas(), v->exptime());
    }

    bool operator==(const Value& rhs) const {
        return mcflags_ == rhs.mcflags_
            && exptime_ == rhs.exptime_
            && data_ == rhs.data_
            && has_cas_ == rhs.has_cas_
            && (has_cas_ ? cas_ == rhs.cas_ : true);
    }

    int full_size() const {
        return sizeof(btree_value) + (mcflags_ ? sizeof(mcflags_t) : 0) + (has_cas_ ? sizeof(cas_t) : 0)
            + (exptime_ ? sizeof(exptime_t) : 0) + data_.size();
    }

    friend std::ostream& operator<<(std::ostream&, const Value&);

private:
    mcflags_t mcflags_;
    cas_t cas_;
    exptime_t exptime_;
    bool has_cas_;
    std::string data_;
};

std::ostream& operator<<(std::ostream& out, const Value& v) {
    out << "Value[mcflags=" << v.mcflags_;
    if (v.has_cas_) {
        out << " cas=" << v.cas_;
    }

    // TODO: string escape v.data_.
    out << " exptime=" << v.exptime_
        << " data='" << v.data_ << "']";
    return out;
}

class StackKey {
public:
    explicit StackKey(const std::string& key) {
        EXPECT_LE(key.size(), MAX_KEY_SIZE);
        keyval.size = key.size();
        memcpy(keyval.contents, key.c_str(), key.size());
    }

    const btree_key *look() const {
        return &keyval;
    }

private:
    union {
        byte keyval_padding[sizeof(btree_key) + MAX_KEY_SIZE];
        btree_key keyval;
    };
};

class StackValue {
public:
    StackValue() {
        memset(val_padding, 0, sizeof(val_padding));
    }
    explicit StackValue(const Value& value) {
        value.WriteBtreeValue(&val);
    }
    const btree_value *look() const {
        return &val;
    }
    btree_value *look_write() {
        return &val;
    }
private:
    union {
        byte val_padding[sizeof(btree_value) + MAX_TOTAL_NODE_CONTENTS_SIZE];
        btree_value val;
    };
};

template <int block_size>
class LeafNodeGrinder {
public:
    LeafNodeGrinder() : bs(block_size_t::unsafe_make(block_size)), expected(), expected_frontmost_offset(bs.value()), expected_npairs(0), node(reinterpret_cast<leaf_node_t *>(malloc(bs.value()))) {
    }

    ~LeafNodeGrinder() {
        free(node);
    }

    int expected_space() const {
        return expected_frontmost_offset - (offsetof(leaf_node_t, pair_offsets) + sizeof(*node->pair_offsets) * expected_npairs);
    }

    void init() {
        SCOPED_TRACE("init");
        leaf_node_handler::init(bs, node, repli_timestamp::invalid);
        validate();
    }

    void insert(const std::string& k, const Value& v) {
        SCOPED_TRACE("insert");
        StackKey skey(k);
        StackValue sval(v);

        if (expected_space() < int((1 + k.size()) + v.full_size() + sizeof(*node->pair_offsets))) {
            ASSERT_FALSE(leaf_node_handler::insert(bs, node, skey.look(), sval.look(), repli_timestamp::invalid));
        } else {
            ASSERT_TRUE(leaf_node_handler::insert(bs, node, skey.look(), sval.look(), repli_timestamp::invalid));

            std::pair<expected_t::iterator, bool> res = expected.insert(std::make_pair(k, v));
            if (res.second) {
                // The key didn't previously exist.
                expected_frontmost_offset -= (1 + k.size()) + v.full_size();
                expected_npairs++;
            } else {
                // The key previously existed.
                expected_frontmost_offset += res.first->second.full_size();
                expected_frontmost_offset -= v.full_size();
                res.first->second = v;
            }
        }

        validate();
    }

    // Expects the key to be in the node.
    void remove(const std::string& k) {
        SCOPED_TRACE("remove");
        expected_t::iterator p = expected.find(k);

        // There's a bug in the test if we're trying to remove a key that's not there.
        ASSERT_TRUE(p != expected.end());

        // The key should be in there.
        StackKey skey(k);
        StackValue sval;

        ASSERT_TRUE(leaf_node_handler::lookup(node, skey.look(), sval.look_write()));

        leaf_node_handler::remove(bs, node, skey.look());
        expected.erase(p);
        expected_frontmost_offset += (1 + k.size()) + sval.look()->full_size();
        -- expected_npairs;

        validate();
    }

    void validate() const {
        ASSERT_EQ(expected_npairs, node->npairs);
        ASSERT_EQ(expected_frontmost_offset, node->frontmost_offset);

        verify(bs, node, expected_space());

        for (expected_t::const_iterator p = expected.begin(), e = expected.end(); p != e; ++p) {
            lookup(p->first, p->second);
        }

        // We're confident there are no bad keys because
        // expected_free_space matched up.
    }

private:
    void lookup(const std::string& k, const Value& expected) const {
        StackKey skey(k);
        StackValue sval;
        ASSERT_TRUE(leaf_node_handler::lookup(node, skey.look(), sval.look_write()));
        ASSERT_EQ(expected, Value::Make(sval.look()));
    }

    block_size_t bs;
    typedef std::map<std::string, Value> expected_t;
    expected_t expected;
    int expected_frontmost_offset;
    int expected_npairs;
    leaf_node_t *node;
};

block_size_t make_bs() {
    // TODO: Test weird block sizes.
    return block_size_t::unsafe_make(4096);
}

leaf_node_t *malloc_leaf_node(block_size_t bs) {
    return reinterpret_cast<leaf_node_t *>(malloc(bs.value()));
}

btree_key *malloc_key(const char *s) {
    size_t origlen = strlen(s);
    EXPECT_LE(origlen, MAX_KEY_SIZE);

    size_t len = std::min<size_t>(origlen, MAX_KEY_SIZE);
    btree_key *k = reinterpret_cast<btree_key *>(malloc(sizeof(btree_key) + len));
    k->size = len;
    memcpy(k->contents, s, len);
    return k;
}

btree_value *malloc_value(const char *s) {
    size_t origlen = strlen(s);
    EXPECT_LE(origlen, MAX_IN_NODE_VALUE_SIZE);

    size_t len = std::min<size_t>(origlen, MAX_IN_NODE_VALUE_SIZE);

    btree_value *v = reinterpret_cast<btree_value *>(malloc(sizeof(btree_value) + len));
    v->size = len;
    v->metadata_flags = 0;
    memcpy(v->value(), s, len);
    return v;
}

TEST(LeafNodeTest, Initialization) {
    block_size_t bs = make_bs();
    leaf_node_t *node = malloc_leaf_node(bs);

    leaf_node_handler::init(bs, node, repli_timestamp::invalid);
    verify(bs, node, bs.value() - offsetof(leaf_node_t, pair_offsets));
    free(node);
}

void InsertLookupRemoveHelper(const std::string& key, const char *value) {
    LeafNodeGrinder<4096> gr;

    Value v(value);

    gr.init();
    gr.insert(key, v);
    gr.remove(key);
}

TEST(LeafNodeTest, ElementaryInsertLookupRemove) {
    InsertLookupRemoveHelper("the_key", "the_value");
}
TEST(LeafNodeTest, EmptyValueInsertLookupRemove) {
    InsertLookupRemoveHelper("the_key", "");
}
TEST(LeafNodeTest, EmptyKeyInsertLookupRemove) {
    InsertLookupRemoveHelper("", "the_value");
}
TEST(LeafNodeTest, EmptyKeyValueInsertLookupRemove) {
    InsertLookupRemoveHelper("", "");
}

}  // namespace unittest

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesBridgeNavigator.hpp"

#include <XalanDOM/XalanNode.hpp>

#include "XercesAttrBridge.hpp"
#include "XercesDocumentBridge.hpp"
#include "XercesTextBridge.hpp"
#include "XercesDOMException.hpp"

// I'm using this to distinguish between null nodes, which are valid, and
// an uninitialized cached node address.  This is probably bogus, and I'll
// probably just change this to 0, but this is experimental anyway...
#if defined(XALAN_OLD_STYLE_CASTS)
static XalanNode* const		invalidNodeAddress = (XalanNode*)1;
#else
static XalanNode* const		invalidNodeAddress = reinterpret_cast<XalanNode*>(1);
#endif

XercesBridgeNavigator::XercesBridgeNavigator(
			XercesDocumentBridge*	theOwnerDocument,
			bool					mappingMode) :
	m_ownerDocument(theOwnerDocument),
	m_parentNode(mappingMode == true ? invalidNodeAddress : 0),
	m_previousSibling(mappingMode == true ? invalidNodeAddress : 0),
	m_nextSibling(mappingMode == true ? invalidNodeAddress : 0),
	m_firstChild(mappingMode == true ? invalidNodeAddress : 0),
	m_lastChild(mappingMode == true ? invalidNodeAddress : 0),
	m_index(UINT_MAX)
{
}

XercesBridgeNavigator::XercesBridgeNavigator(const XercesBridgeNavigator&	theSource) :
	m_ownerDocument(theSource.m_ownerDocument),
	m_parentNode(theSource.m_parentNode),
	m_previousSibling(theSource.m_previousSibling),
	m_nextSibling(theSource.m_nextSibling),
	m_firstChild(theSource.m_firstChild),
	m_lastChild(theSource.m_lastChild),
	m_index(theSource.m_index)
{
}

XercesBridgeNavigator::~XercesBridgeNavigator()
{
}

XalanNode*
XercesBridgeNavigator::mapNode(const DOM_Node&		theXercesNode) const
{
	return m_ownerDocument->mapNode(theXercesNode);
}

XalanAttr*
XercesBridgeNavigator::mapNode(const DOM_Attr&		theXercesNode) const
{
	return m_ownerDocument->mapNode(theXercesNode);
}

DOM_Node
XercesBridgeNavigator::mapNode(const XalanNode*		theXalanNode) const
{
	return m_ownerDocument->mapNode(theXalanNode);
}

DOM_Attr
XercesBridgeNavigator::mapNode(const XalanAttr*		theXalanNode) const
{
	return m_ownerDocument->mapNode(theXalanNode);
}

XalanNode*
XercesBridgeNavigator::getParentNode(const DOM_Node&	theXercesNode) const
{
	if (m_parentNode == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_parentNode = m_ownerDocument->mapNode(theXercesNode.getParentNode());
#else
		m_parentNode = m_ownerDocument->mapNode(theXercesNode.getParentNode());
#endif
	}

	return m_parentNode;
}

XalanNode*
XercesBridgeNavigator::getPreviousSibling(const DOM_Node&	theXercesNode) const
{
	if (m_previousSibling == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_previousSibling = m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
#else
		m_previousSibling = m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
#endif
	}

	return m_previousSibling;
}

XalanNode*
XercesBridgeNavigator::getNextSibling(const DOM_Node&	theXercesNode) const
{
	if (m_nextSibling == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_nextSibling = m_ownerDocument->mapNode(theXercesNode.getNextSibling());
#else
		m_nextSibling = m_ownerDocument->mapNode(theXercesNode.getNextSibling());
#endif
	}

	return m_nextSibling;
}

XalanNode*
XercesBridgeNavigator::getFirstChild(const DOM_Node&	theXercesNode) const
{
	if (m_firstChild == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_firstChild = m_ownerDocument->mapNode(theXercesNode.getFirstChild());
#else
		m_firstChild = m_ownerDocument->mapNode(theXercesNode.getFirstChild());
#endif
	}

	return m_firstChild;
}

XalanNode*
XercesBridgeNavigator::getLastChild(const DOM_Node&	theXercesNode) const
{
	if (m_lastChild == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_lastChild = m_ownerDocument->mapNode(theXercesNode.getLastChild());
#else
		m_lastChild = m_ownerDocument->mapNode(theXercesNode.getLastChild());
#endif
	}

	return m_lastChild;
}

XalanNode*
XercesBridgeNavigator::insertBefore(
			DOM_Node&		theXercesParent,
			XalanNode*		newChild,
			XalanNode*		refChild) const
{
	assert(newChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theNewChild = m_ownerDocument->mapNode(newChild);
	const DOM_Node	theRefChild = m_ownerDocument->mapNode(refChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.insertBefore(theNewChild, theRefChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == newChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return newChild;
}

XalanNode*
XercesBridgeNavigator::	replaceChild(
			DOM_Node&	theXercesParent,
			XalanNode*	newChild,
			XalanNode*	oldChild) const
{
	assert(newChild != 0);
	assert(oldChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theNewChild = m_ownerDocument->mapNode(newChild);
	const DOM_Node	theOldChild = m_ownerDocument->mapNode(oldChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.replaceChild(theNewChild, theOldChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == oldChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return oldChild;
}

XalanNode*
XercesBridgeNavigator::removeChild(
			DOM_Node&	theXercesParent,
			XalanNode*	oldChild) const
{
	assert(oldChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theOldChild = m_ownerDocument->mapNode(oldChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.removeChild(theOldChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == oldChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return oldChild;
}

XalanNode*
XercesBridgeNavigator::appendChild(
			DOM_Node&	theXercesParent,
			XalanNode*	newChild) const
{
	return insertBefore(theXercesParent, newChild, 0);
}

XalanElement*
XercesBridgeNavigator::getOwnerElement(const DOM_Attr&		theXercesAttr) const
{
	return m_ownerDocument->mapNode(theXercesAttr.getOwnerElement());
}

XalanNode*
XercesBridgeNavigator::cloneNode(
			const XalanNode*	theXalanNode,
			const DOM_Node&		theXercesNode,
			bool				deep) const
{
	return m_ownerDocument->internalCloneNode(theXalanNode, theXercesNode, deep);
}

XalanText*
XercesBridgeNavigator::splitText(
			DOM_Text&		theXercesText,
			unsigned int	offset) const
{
	XalanText*	theXalanText = 0;

	try
	{
		DOM_Text	theNewXercesText = theXercesText.splitText(offset);
		assert(theXercesText.isNull() == false);

		theXalanText = m_ownerDocument->createBridgeNode(theNewXercesText, 0, true);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return theXalanText;
}

const XalanDOMString&
XercesBridgeNavigator::getPooledString(const XalanDOMString&	theString) const
{
	return m_ownerDocument->getPooledString(theString);
}

const XalanDOMString&
XercesBridgeNavigator::	getPooledString(const XalanDOMChar*		theString) const
{
	return m_ownerDocument->getPooledString(theString);
}
<commit_msg>Return parent element if already know<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesBridgeNavigator.hpp"

#include <XalanDOM/XalanNode.hpp>

#include "XercesAttrBridge.hpp"
#include "XercesDocumentBridge.hpp"
#include "XercesTextBridge.hpp"
#include "XercesDOMException.hpp"

// I'm using this to distinguish between null nodes, which are valid, and
// an uninitialized cached node address.  This is probably bogus, and I'll
// probably just change this to 0, but this is experimental anyway...
#if defined(XALAN_OLD_STYLE_CASTS)
static XalanNode* const		invalidNodeAddress = (XalanNode*)1;
#else
static XalanNode* const		invalidNodeAddress = reinterpret_cast<XalanNode*>(1);
#endif

XercesBridgeNavigator::XercesBridgeNavigator(
			XercesDocumentBridge*	theOwnerDocument,
			bool					mappingMode) :
	m_ownerDocument(theOwnerDocument),
	m_parentNode(mappingMode == true ? invalidNodeAddress : 0),
	m_previousSibling(mappingMode == true ? invalidNodeAddress : 0),
	m_nextSibling(mappingMode == true ? invalidNodeAddress : 0),
	m_firstChild(mappingMode == true ? invalidNodeAddress : 0),
	m_lastChild(mappingMode == true ? invalidNodeAddress : 0),
	m_index(UINT_MAX)
{
}

XercesBridgeNavigator::XercesBridgeNavigator(const XercesBridgeNavigator&	theSource) :
	m_ownerDocument(theSource.m_ownerDocument),
	m_parentNode(theSource.m_parentNode),
	m_previousSibling(theSource.m_previousSibling),
	m_nextSibling(theSource.m_nextSibling),
	m_firstChild(theSource.m_firstChild),
	m_lastChild(theSource.m_lastChild),
	m_index(theSource.m_index)
{
}

XercesBridgeNavigator::~XercesBridgeNavigator()
{
}

XalanNode*
XercesBridgeNavigator::mapNode(const DOM_Node&		theXercesNode) const
{
	return m_ownerDocument->mapNode(theXercesNode);
}

XalanAttr*
XercesBridgeNavigator::mapNode(const DOM_Attr&		theXercesNode) const
{
	return m_ownerDocument->mapNode(theXercesNode);
}

DOM_Node
XercesBridgeNavigator::mapNode(const XalanNode*		theXalanNode) const
{
	return m_ownerDocument->mapNode(theXalanNode);
}

DOM_Attr
XercesBridgeNavigator::mapNode(const XalanAttr*		theXalanNode) const
{
	return m_ownerDocument->mapNode(theXalanNode);
}

XalanNode*
XercesBridgeNavigator::getParentNode(const DOM_Node&	theXercesNode) const
{
	if (m_parentNode == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_parentNode = m_ownerDocument->mapNode(theXercesNode.getParentNode());
#else
		m_parentNode = m_ownerDocument->mapNode(theXercesNode.getParentNode());
#endif
	}

	return m_parentNode;
}

XalanNode*
XercesBridgeNavigator::getPreviousSibling(const DOM_Node&	theXercesNode) const
{
	if (m_previousSibling == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_previousSibling = m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
#else
		m_previousSibling = m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
#endif
	}

	return m_previousSibling;
}

XalanNode*
XercesBridgeNavigator::getNextSibling(const DOM_Node&	theXercesNode) const
{
	if (m_nextSibling == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_nextSibling = m_ownerDocument->mapNode(theXercesNode.getNextSibling());
#else
		m_nextSibling = m_ownerDocument->mapNode(theXercesNode.getNextSibling());
#endif
	}

	return m_nextSibling;
}

XalanNode*
XercesBridgeNavigator::getFirstChild(const DOM_Node&	theXercesNode) const
{
	if (m_firstChild == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_firstChild = m_ownerDocument->mapNode(theXercesNode.getFirstChild());
#else
		m_firstChild = m_ownerDocument->mapNode(theXercesNode.getFirstChild());
#endif
	}

	return m_firstChild;
}

XalanNode*
XercesBridgeNavigator::getLastChild(const DOM_Node&	theXercesNode) const
{
	if (m_lastChild == invalidNodeAddress)
	{
#if defined(XALAN_NO_MUTABLE)
		((XercesBridgeNavigator*)this)->m_lastChild = m_ownerDocument->mapNode(theXercesNode.getLastChild());
#else
		m_lastChild = m_ownerDocument->mapNode(theXercesNode.getLastChild());
#endif
	}

	return m_lastChild;
}

XalanNode*
XercesBridgeNavigator::insertBefore(
			DOM_Node&		theXercesParent,
			XalanNode*		newChild,
			XalanNode*		refChild) const
{
	assert(newChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theNewChild = m_ownerDocument->mapNode(newChild);
	const DOM_Node	theRefChild = m_ownerDocument->mapNode(refChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.insertBefore(theNewChild, theRefChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == newChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return newChild;
}

XalanNode*
XercesBridgeNavigator::	replaceChild(
			DOM_Node&	theXercesParent,
			XalanNode*	newChild,
			XalanNode*	oldChild) const
{
	assert(newChild != 0);
	assert(oldChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theNewChild = m_ownerDocument->mapNode(newChild);
	const DOM_Node	theOldChild = m_ownerDocument->mapNode(oldChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.replaceChild(theNewChild, theOldChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == oldChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return oldChild;
}

XalanNode*
XercesBridgeNavigator::removeChild(
			DOM_Node&	theXercesParent,
			XalanNode*	oldChild) const
{
	assert(oldChild != 0);

	// Get the corresponding Xerces nodes...
	const DOM_Node	theOldChild = m_ownerDocument->mapNode(oldChild);

	try
	{
		const DOM_Node	theXercesResult =
			theXercesParent.removeChild(theOldChild);
		assert(m_ownerDocument->mapNode(theXercesResult) == oldChild);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return oldChild;
}

XalanNode*
XercesBridgeNavigator::appendChild(
			DOM_Node&	theXercesParent,
			XalanNode*	newChild) const
{
	return insertBefore(theXercesParent, newChild, 0);
}

XalanElement*
XercesBridgeNavigator::getOwnerElement(const DOM_Attr&	theXercesAttr) const
{
	if (m_parentNode != 0)
	{
		assert(m_parentNode->getNodeType() == XalanNode::ELEMENT_NODE);

#if defined(XALAN_OLD_STYLE_CASTS)
		return (XalanElement*)m_parentNode;
#else
		return static_cast<XalanElement*>(m_parentNode);
#endif
	}
	else
	{
		return m_ownerDocument->mapNode(theXercesAttr.getOwnerElement());
	}
}

XalanNode*
XercesBridgeNavigator::cloneNode(
			const XalanNode*	theXalanNode,
			const DOM_Node&		theXercesNode,
			bool				deep) const
{
	return m_ownerDocument->internalCloneNode(theXalanNode, theXercesNode, deep);
}

XalanText*
XercesBridgeNavigator::splitText(
			DOM_Text&		theXercesText,
			unsigned int	offset) const
{
	XalanText*	theXalanText = 0;

	try
	{
		DOM_Text	theNewXercesText = theXercesText.splitText(offset);
		assert(theXercesText.isNull() == false);

		theXalanText = m_ownerDocument->createBridgeNode(theNewXercesText, 0, true);
	}
	catch(const DOM_DOMException&	theException)
	{
		throw XercesDOMException(theException);
	}

	return theXalanText;
}

const XalanDOMString&
XercesBridgeNavigator::getPooledString(const XalanDOMString&	theString) const
{
	return m_ownerDocument->getPooledString(theString);
}

const XalanDOMString&
XercesBridgeNavigator::	getPooledString(const XalanDOMChar*		theString) const
{
	return m_ownerDocument->getPooledString(theString);
}
<|endoftext|>


<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "unittest/unittest_utils.hpp"

#include <stdlib.h>

#include "errors.hpp"
#include <boost/bind.hpp>

// These unit tests need to access some private methods.

#include "arch/timing.hpp"
#include "arch/runtime/starter.hpp"
#include "rdb_protocol/protocol.hpp"
#include "unittest/gtest.hpp"
#include "utils.hpp"

namespace unittest {

rdb_protocol_t::read_t make_sindex_read(
    counted_t<const ql::datum_t> key, const std::string &id) {
    using namespace rdb_protocol_details;
    datum_range_t rng(key, key_range_t::closed, key, key_range_t::closed);
    return rdb_protocol_t::read_t(
        rdb_protocol_t::rget_read_t(
            rdb_protocol_t::region_t::universe(),
            std::map<std::string, ql::wire_func_t>(),
            ql::batchspec_t::user(ql::batch_type_t::NORMAL,
                                  counted_t<const ql::datum_t>()),
            transform_t(),
            boost::optional<terminal_t>(),
            rdb_protocol_t::sindex_rangespec_t(
                id,
                rdb_protocol_t::region_t(rng.to_sindex_keyrange()),
                rng),
            sorting_t::UNORDERED),
        profile_bool_t::PROFILE);
}

serializer_filepath_t manual_serializer_filepath(const std::string &permanent_path,
                                                 const std::string &temporary_path) {

    return serializer_filepath_t(permanent_path, temporary_path);
}

static const char *const temp_file_create_suffix = ".create";

temp_file_t::temp_file_t() {
    for (;;) {
        char tmpl[] = "/tmp/rdb_unittest.XXXXXX";
        const int fd = mkstemp(tmpl);
        guarantee_err(fd != -1, "Couldn't create a temporary file");
        close(fd);

        // Check that both the permanent and temporary file paths are unused.
        const std::string tmpfilename = std::string(tmpl) + temp_file_create_suffix;
        if (::access(tmpfilename.c_str(), F_OK) == -1 && errno == ENOENT) {
            filename = tmpl;
            break;
        } else {
            const int unlink_res = ::unlink(tmpl);
            EXPECT_EQ(0, unlink_res);
        }
    }
}

temp_file_t::~temp_file_t() {
    // Unlink both possible locations of the file.
    const int res1 = ::unlink(name().temporary_path().c_str());
    EXPECT_TRUE(res1 == 0 || errno == ENOENT);
    const int res2 = ::unlink(name().permanent_path().c_str());
    EXPECT_TRUE(res2 == 0 || errno == ENOENT);
}

serializer_filepath_t temp_file_t::name() const {
    return manual_serializer_filepath(filename, filename + temp_file_create_suffix);
}

void let_stuff_happen() {
#ifdef VALGRIND
    nap(2000);
#else
    nap(100);
#endif
}

std::set<ip_address_t> get_unittest_addresses() {
    return get_local_ips(std::set<ip_address_t>(), false);
}

void run_in_thread_pool(const boost::function<void()>& fun, int num_workers) {
    ::run_in_thread_pool(fun, num_workers);
}

}  // namespace unittest
<commit_msg>Fixed more style problems.<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "unittest/unittest_utils.hpp"

#include <stdlib.h>

#include "errors.hpp"
#include <boost/bind.hpp>

// These unit tests need to access some private methods.

#include "arch/timing.hpp"
#include "arch/runtime/starter.hpp"
#include "rdb_protocol/protocol.hpp"
#include "unittest/gtest.hpp"
#include "utils.hpp"

namespace unittest {

rdb_protocol_t::read_t make_sindex_read(
    counted_t<const ql::datum_t> key, const std::string &id) {
    datum_range_t rng(key, key_range_t::closed, key, key_range_t::closed);
    return rdb_protocol_t::read_t(
        rdb_protocol_t::rget_read_t(
            rdb_protocol_t::region_t::universe(),
            std::map<std::string, ql::wire_func_t>(),
            ql::batchspec_t::user(ql::batch_type_t::NORMAL,
                                  counted_t<const ql::datum_t>()),
            rdb_protocol_details::transform_t(),
            boost::optional<rdb_protocol_details::terminal_t>(),
            rdb_protocol_t::sindex_rangespec_t(
                id,
                rdb_protocol_t::region_t(rng.to_sindex_keyrange()),
                rng),
            sorting_t::UNORDERED),
        profile_bool_t::PROFILE);
}

serializer_filepath_t manual_serializer_filepath(const std::string &permanent_path,
                                                 const std::string &temporary_path) {

    return serializer_filepath_t(permanent_path, temporary_path);
}

static const char *const temp_file_create_suffix = ".create";

temp_file_t::temp_file_t() {
    for (;;) {
        char tmpl[] = "/tmp/rdb_unittest.XXXXXX";
        const int fd = mkstemp(tmpl);
        guarantee_err(fd != -1, "Couldn't create a temporary file");
        close(fd);

        // Check that both the permanent and temporary file paths are unused.
        const std::string tmpfilename = std::string(tmpl) + temp_file_create_suffix;
        if (::access(tmpfilename.c_str(), F_OK) == -1 && errno == ENOENT) {
            filename = tmpl;
            break;
        } else {
            const int unlink_res = ::unlink(tmpl);
            EXPECT_EQ(0, unlink_res);
        }
    }
}

temp_file_t::~temp_file_t() {
    // Unlink both possible locations of the file.
    const int res1 = ::unlink(name().temporary_path().c_str());
    EXPECT_TRUE(res1 == 0 || errno == ENOENT);
    const int res2 = ::unlink(name().permanent_path().c_str());
    EXPECT_TRUE(res2 == 0 || errno == ENOENT);
}

serializer_filepath_t temp_file_t::name() const {
    return manual_serializer_filepath(filename, filename + temp_file_create_suffix);
}

void let_stuff_happen() {
#ifdef VALGRIND
    nap(2000);
#else
    nap(100);
#endif
}

std::set<ip_address_t> get_unittest_addresses() {
    return get_local_ips(std::set<ip_address_t>(), false);
}

void run_in_thread_pool(const boost::function<void()>& fun, int num_workers) {
    ::run_in_thread_pool(fun, num_workers);
}

}  // namespace unittest
<|endoftext|>