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

#include "content/browser/accessibility/browser_accessibility_manager.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/accessibility_messages.h"

namespace content {

BrowserAccessibility* BrowserAccessibilityFactory::Create() {
  return BrowserAccessibility::Create();
}

#if !defined(OS_MACOSX) && \
    !defined(OS_WIN) && \
    !defined(TOOLKIT_GTK)
// We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK,
// and Win. For any other platform, instantiate the base class.
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManager(src, delegate, factory);
}
#endif

BrowserAccessibilityManager::BrowserAccessibilityManager(
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : delegate_(delegate),
      factory_(factory),
      root_(NULL),
      focus_(NULL),
      osk_state_(OSK_ALLOWED) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(src);
  if (!UpdateNodes(nodes))
    return;
  if (!focus_)
    SetFocus(root_, false);
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  if (root_)
    root_->Destroy();
}

BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
  return root_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromRendererID(
    int32 renderer_id) {
  base::hash_map<int32, BrowserAccessibility*>::iterator iter =
      renderer_id_map_.find(renderer_id);
  if (iter != renderer_id_map_.end())
    return iter->second;
  return NULL;
}

void BrowserAccessibilityManager::GotFocus(bool touch_event_context) {
  if (!touch_event_context)
    osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED;

  if (!focus_)
    return;

  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

void BrowserAccessibilityManager::WasHidden() {
  osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_HIDDEN;
}

void BrowserAccessibilityManager::GotMouseDown() {
  osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

bool BrowserAccessibilityManager::IsOSKAllowed(const gfx::Rect& bounds) {
  if (!delegate_ || !delegate_->HasFocus())
    return false;

  gfx::Point touch_point = delegate_->GetLastTouchEventLocation();
  return bounds.Contains(touch_point);
}

void BrowserAccessibilityManager::RemoveNode(BrowserAccessibility* node) {
  if (node == focus_)
    SetFocus(root_, false);
  int renderer_id = node->renderer_id();
  renderer_id_map_.erase(renderer_id);
}

void BrowserAccessibilityManager::OnAccessibilityNotifications(
    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
  for (uint32 index = 0; index < params.size(); index++) {
    const AccessibilityHostMsg_NotificationParams& param = params[index];

    // Update nodes that changed.
    if (!UpdateNodes(param.nodes))
      return;

    // Find the node corresponding to the id that's the target of the
    // notification (which may not be the root of the update tree).
    BrowserAccessibility* node = GetFromRendererID(param.id);
    if (!node)
      continue;

    int notification_type = param.notification_type;
    if (notification_type == AccessibilityNotificationFocusChanged ||
        notification_type == AccessibilityNotificationBlur) {
      SetFocus(node, false);

      if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
          osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
        osk_state_ = OSK_ALLOWED;

      // Don't send a native focus event if the window itself doesn't
      // have focus.
      if (delegate_ && !delegate_->HasFocus())
        continue;
    }

    // Send the notification event to the operating system.
    NotifyAccessibilityEvent(notification_type, node);

    // Set initial focus when a page is loaded.
    if (notification_type == AccessibilityNotificationLoadComplete) {
      if (!focus_)
        SetFocus(root_, false);
      if (!delegate_ || delegate_->HasFocus())
        NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
    }
  }
}

BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
    BrowserAccessibility* root) {
  if (focus_ && (!root || focus_->IsDescendantOf(root)))
    return focus_;

  return NULL;
}

void BrowserAccessibilityManager::SetFocus(
    BrowserAccessibility* node, bool notify) {
  if (focus_ != node)
    focus_ = node;

  if (notify && node && delegate_)
    delegate_->SetAccessibilityFocus(node->renderer_id());
}

void BrowserAccessibilityManager::DoDefaultAction(
    const BrowserAccessibility& node) {
  if (delegate_)
    delegate_->AccessibilityDoDefaultAction(node.renderer_id());
}

void BrowserAccessibilityManager::ScrollToMakeVisible(
    const BrowserAccessibility& node, gfx::Rect subfocus) {
  if (delegate_) {
    delegate_->AccessibilityScrollToMakeVisible(node.renderer_id(), subfocus);
  }
}

void BrowserAccessibilityManager::ScrollToPoint(
    const BrowserAccessibility& node, gfx::Point point) {
  if (delegate_) {
    delegate_->AccessibilityScrollToPoint(node.renderer_id(), point);
  }
}

void BrowserAccessibilityManager::SetTextSelection(
    const BrowserAccessibility& node, int start_offset, int end_offset) {
  if (delegate_) {
    delegate_->AccessibilitySetTextSelection(
        node.renderer_id(), start_offset, end_offset);
  }
}

gfx::Rect BrowserAccessibilityManager::GetViewBounds() {
  if (delegate_)
    return delegate_->GetViewBounds();
  return gfx::Rect();
}

void BrowserAccessibilityManager::UpdateNodesForTesting(
    const AccessibilityNodeData& node1,
    const AccessibilityNodeData& node2 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node3 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node4 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node5 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node6 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node7 /* = AccessibilityNodeData() */) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(node1);
  if (node2.id != AccessibilityNodeData().id)
    nodes.push_back(node2);
  if (node3.id != AccessibilityNodeData().id)
    nodes.push_back(node3);
  if (node4.id != AccessibilityNodeData().id)
    nodes.push_back(node4);
  if (node5.id != AccessibilityNodeData().id)
    nodes.push_back(node5);
  if (node6.id != AccessibilityNodeData().id)
    nodes.push_back(node6);
  if (node7.id != AccessibilityNodeData().id)
    nodes.push_back(node7);
  UpdateNodes(nodes);
}

bool BrowserAccessibilityManager::UpdateNodes(
    const std::vector<AccessibilityNodeData>& nodes) {
  bool success = true;

  // First, update all of the nodes in the tree.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    if (!UpdateNode(nodes[i]))
      success = false;
  }

  // In a second pass, call PostInitialize on each one - this must
  // be called after all of each node's children are initialized too.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    BrowserAccessibility* instance = GetFromRendererID(nodes[i].id);
    if (instance) {
      instance->PostInitialize();
    } else {
      success = false;
    }
  }

  if (!success) {
    // A bad accessibility tree could lead to memory corruption.
    // Ask the delegate to crash the renderer, or if not available,
    // crash the browser.
    if (delegate_)
      delegate_->FatalAccessibilityTreeError();
    else
      CHECK(false);
  }

  return success;
}

BrowserAccessibility* BrowserAccessibilityManager::CreateNode(
    BrowserAccessibility* parent,
    int32 renderer_id,
    int32 index_in_parent) {
  BrowserAccessibility* node = factory_->Create();
  node->InitializeTreeStructure(
      this, parent, renderer_id, index_in_parent);
  AddNodeToMap(node);
  return node;
}

void BrowserAccessibilityManager::AddNodeToMap(BrowserAccessibility* node) {
  renderer_id_map_[node->renderer_id()] = node;
}

bool BrowserAccessibilityManager::UpdateNode(const AccessibilityNodeData& src) {
  // This method updates one node in the tree based on serialized data
  // received from the renderer.

  // Create a set of child ids in |src| for fast lookup. If a duplicate id is
  // found, exit now with a fatal error before changing anything else.
  std::set<int32> new_child_ids;
  for (size_t i = 0; i < src.child_ids.size(); ++i) {
    if (new_child_ids.find(src.child_ids[i]) != new_child_ids.end())
      return false;
    new_child_ids.insert(src.child_ids[i]);
  }

  // Look up the node by id. If it's not found, then either the root
  // of the tree is being swapped, or we're out of sync with the renderer
  // and this is a serious error.
  BrowserAccessibility* instance = GetFromRendererID(src.id);
  if (!instance) {
    if (src.role != AccessibilityNodeData::ROLE_ROOT_WEB_AREA)
      return false;
    instance = CreateNode(NULL, src.id, 0);
  }

  // Update all of the node-specific data, like its role, state, name, etc.
  instance->InitializeData(src);

  //
  // Update the children in three steps:
  //
  // 1. Iterate over the old children and delete nodes that are no longer
  //    in the tree.
  // 2. Build up a vector of new children, reusing children that haven't
  //    changed (but may have been reordered) and adding new empty
  //    objects for new children.
  // 3. Swap in the new children vector for the old one.

  // Delete any previous children of this instance that are no longer
  // children first. We make a deletion-only pass first to prevent a
  // node that's being reparented from being the child of both its old
  // parent and new parent, which could lead to a double-free.
  // If a node is reparented, the renderer will always send us a fresh
  // copy of the node.
  const std::vector<BrowserAccessibility*>& old_children = instance->children();
  for (size_t i = 0; i < old_children.size(); ++i) {
    int old_id = old_children[i]->renderer_id();
    if (new_child_ids.find(old_id) == new_child_ids.end())
      old_children[i]->Destroy();
  }

  // Now build a vector of new children, reusing objects that were already
  // children of this node before.
  std::vector<BrowserAccessibility*> new_children;
  bool success = true;
  for (size_t i = 0; i < src.child_ids.size(); i++) {
    int32 child_renderer_id = src.child_ids[i];
    int32 index_in_parent = static_cast<int32>(i);
    BrowserAccessibility* child = GetFromRendererID(child_renderer_id);
    if (child) {
      if (child->parent() != instance) {
        // This is a serious error - nodes should never be reparented.
        // If this case occurs, continue so this node isn't left in an
        // inconsistent state, but return failure at the end.
        success = false;
        continue;
      }
      child->UpdateParent(instance, index_in_parent);
    } else {
      child = CreateNode(instance, child_renderer_id, index_in_parent);
    }
    new_children.push_back(child);
  }

  // Finally, swap in the new children vector for the old.
  instance->SwapChildren(new_children);

  // Handle the case where this node is the new root of the tree.
  if (src.role == AccessibilityNodeData::ROLE_ROOT_WEB_AREA &&
      (!root_ || root_->renderer_id() != src.id)) {
    if (root_)
      root_->Destroy();
    if (focus_ == root_)
      focus_ = instance;
    root_ = instance;
  }

  // Keep track of what node is focused.
  if ((src.state >> AccessibilityNodeData::STATE_FOCUSED) & 1)
    SetFocus(instance, false);

  return success;
}

}  // namespace content
<commit_msg>Fix overzealous runtime assertion in BrowserAccessibilityManager.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/accessibility/browser_accessibility_manager.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/accessibility_messages.h"

namespace content {

BrowserAccessibility* BrowserAccessibilityFactory::Create() {
  return BrowserAccessibility::Create();
}

#if !defined(OS_MACOSX) && \
    !defined(OS_WIN) && \
    !defined(TOOLKIT_GTK)
// We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK,
// and Win. For any other platform, instantiate the base class.
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManager(src, delegate, factory);
}
#endif

BrowserAccessibilityManager::BrowserAccessibilityManager(
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : delegate_(delegate),
      factory_(factory),
      root_(NULL),
      focus_(NULL),
      osk_state_(OSK_ALLOWED) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(src);
  if (!UpdateNodes(nodes))
    return;
  if (!focus_)
    SetFocus(root_, false);
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  if (root_)
    root_->Destroy();
}

BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
  return root_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromRendererID(
    int32 renderer_id) {
  base::hash_map<int32, BrowserAccessibility*>::iterator iter =
      renderer_id_map_.find(renderer_id);
  if (iter != renderer_id_map_.end())
    return iter->second;
  return NULL;
}

void BrowserAccessibilityManager::GotFocus(bool touch_event_context) {
  if (!touch_event_context)
    osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED;

  if (!focus_)
    return;

  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

void BrowserAccessibilityManager::WasHidden() {
  osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_HIDDEN;
}

void BrowserAccessibilityManager::GotMouseDown() {
  osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

bool BrowserAccessibilityManager::IsOSKAllowed(const gfx::Rect& bounds) {
  if (!delegate_ || !delegate_->HasFocus())
    return false;

  gfx::Point touch_point = delegate_->GetLastTouchEventLocation();
  return bounds.Contains(touch_point);
}

void BrowserAccessibilityManager::RemoveNode(BrowserAccessibility* node) {
  if (node == focus_)
    SetFocus(root_, false);
  int renderer_id = node->renderer_id();
  renderer_id_map_.erase(renderer_id);
}

void BrowserAccessibilityManager::OnAccessibilityNotifications(
    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
  for (uint32 index = 0; index < params.size(); index++) {
    const AccessibilityHostMsg_NotificationParams& param = params[index];

    // Update nodes that changed.
    if (!UpdateNodes(param.nodes))
      return;

    // Find the node corresponding to the id that's the target of the
    // notification (which may not be the root of the update tree).
    BrowserAccessibility* node = GetFromRendererID(param.id);
    if (!node)
      continue;

    int notification_type = param.notification_type;
    if (notification_type == AccessibilityNotificationFocusChanged ||
        notification_type == AccessibilityNotificationBlur) {
      SetFocus(node, false);

      if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
          osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
        osk_state_ = OSK_ALLOWED;

      // Don't send a native focus event if the window itself doesn't
      // have focus.
      if (delegate_ && !delegate_->HasFocus())
        continue;
    }

    // Send the notification event to the operating system.
    NotifyAccessibilityEvent(notification_type, node);

    // Set initial focus when a page is loaded.
    if (notification_type == AccessibilityNotificationLoadComplete) {
      if (!focus_)
        SetFocus(root_, false);
      if (!delegate_ || delegate_->HasFocus())
        NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
    }
  }
}

BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
    BrowserAccessibility* root) {
  if (focus_ && (!root || focus_->IsDescendantOf(root)))
    return focus_;

  return NULL;
}

void BrowserAccessibilityManager::SetFocus(
    BrowserAccessibility* node, bool notify) {
  if (focus_ != node)
    focus_ = node;

  if (notify && node && delegate_)
    delegate_->SetAccessibilityFocus(node->renderer_id());
}

void BrowserAccessibilityManager::DoDefaultAction(
    const BrowserAccessibility& node) {
  if (delegate_)
    delegate_->AccessibilityDoDefaultAction(node.renderer_id());
}

void BrowserAccessibilityManager::ScrollToMakeVisible(
    const BrowserAccessibility& node, gfx::Rect subfocus) {
  if (delegate_) {
    delegate_->AccessibilityScrollToMakeVisible(node.renderer_id(), subfocus);
  }
}

void BrowserAccessibilityManager::ScrollToPoint(
    const BrowserAccessibility& node, gfx::Point point) {
  if (delegate_) {
    delegate_->AccessibilityScrollToPoint(node.renderer_id(), point);
  }
}

void BrowserAccessibilityManager::SetTextSelection(
    const BrowserAccessibility& node, int start_offset, int end_offset) {
  if (delegate_) {
    delegate_->AccessibilitySetTextSelection(
        node.renderer_id(), start_offset, end_offset);
  }
}

gfx::Rect BrowserAccessibilityManager::GetViewBounds() {
  if (delegate_)
    return delegate_->GetViewBounds();
  return gfx::Rect();
}

void BrowserAccessibilityManager::UpdateNodesForTesting(
    const AccessibilityNodeData& node1,
    const AccessibilityNodeData& node2 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node3 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node4 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node5 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node6 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node7 /* = AccessibilityNodeData() */) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(node1);
  if (node2.id != AccessibilityNodeData().id)
    nodes.push_back(node2);
  if (node3.id != AccessibilityNodeData().id)
    nodes.push_back(node3);
  if (node4.id != AccessibilityNodeData().id)
    nodes.push_back(node4);
  if (node5.id != AccessibilityNodeData().id)
    nodes.push_back(node5);
  if (node6.id != AccessibilityNodeData().id)
    nodes.push_back(node6);
  if (node7.id != AccessibilityNodeData().id)
    nodes.push_back(node7);
  UpdateNodes(nodes);
}

bool BrowserAccessibilityManager::UpdateNodes(
    const std::vector<AccessibilityNodeData>& nodes) {
  bool success = true;

  // First, update all of the nodes in the tree.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    if (!UpdateNode(nodes[i]))
      success = false;
  }

  // In a second pass, call PostInitialize on each one - this must
  // be called after all of each node's children are initialized too.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    // Note: it's not a bug for nodes[i].id to not be found in the tree.
    // Consider this example:
    // Before:
    // A
    //   B
    //     C
    //   D
    //     E
    //       F
    // After:
    // A
    //   B
    //     C
    //       F
    //   D
    // In this example, F is being reparented. The renderer scans the tree
    // in order. If can't update "C" to add "F" as a child, when "F" is still
    // a child of "E". So it first updates "E", to remove "F" as a child.
    // Later, it ends up deleting "E". So when we get here, "E" was updated as
    // part of this sequence but it no longer exists in the final tree, so
    // there's nothing to postinitialize.
    BrowserAccessibility* instance = GetFromRendererID(nodes[i].id);
    if (instance)
      instance->PostInitialize();
  }

  if (!success) {
    // A bad accessibility tree could lead to memory corruption.
    // Ask the delegate to crash the renderer, or if not available,
    // crash the browser.
    if (delegate_)
      delegate_->FatalAccessibilityTreeError();
    else
      CHECK(false);
  }

  return success;
}

BrowserAccessibility* BrowserAccessibilityManager::CreateNode(
    BrowserAccessibility* parent,
    int32 renderer_id,
    int32 index_in_parent) {
  BrowserAccessibility* node = factory_->Create();
  node->InitializeTreeStructure(
      this, parent, renderer_id, index_in_parent);
  AddNodeToMap(node);
  return node;
}

void BrowserAccessibilityManager::AddNodeToMap(BrowserAccessibility* node) {
  renderer_id_map_[node->renderer_id()] = node;
}

bool BrowserAccessibilityManager::UpdateNode(const AccessibilityNodeData& src) {
  // This method updates one node in the tree based on serialized data
  // received from the renderer.

  // Create a set of child ids in |src| for fast lookup. If a duplicate id is
  // found, exit now with a fatal error before changing anything else.
  std::set<int32> new_child_ids;
  for (size_t i = 0; i < src.child_ids.size(); ++i) {
    if (new_child_ids.find(src.child_ids[i]) != new_child_ids.end())
      return false;
    new_child_ids.insert(src.child_ids[i]);
  }

  // Look up the node by id. If it's not found, then either the root
  // of the tree is being swapped, or we're out of sync with the renderer
  // and this is a serious error.
  BrowserAccessibility* instance = GetFromRendererID(src.id);
  if (!instance) {
    if (src.role != AccessibilityNodeData::ROLE_ROOT_WEB_AREA)
      return false;
    instance = CreateNode(NULL, src.id, 0);
  }

  // Update all of the node-specific data, like its role, state, name, etc.
  instance->InitializeData(src);

  //
  // Update the children in three steps:
  //
  // 1. Iterate over the old children and delete nodes that are no longer
  //    in the tree.
  // 2. Build up a vector of new children, reusing children that haven't
  //    changed (but may have been reordered) and adding new empty
  //    objects for new children.
  // 3. Swap in the new children vector for the old one.

  // Delete any previous children of this instance that are no longer
  // children first. We make a deletion-only pass first to prevent a
  // node that's being reparented from being the child of both its old
  // parent and new parent, which could lead to a double-free.
  // If a node is reparented, the renderer will always send us a fresh
  // copy of the node.
  const std::vector<BrowserAccessibility*>& old_children = instance->children();
  for (size_t i = 0; i < old_children.size(); ++i) {
    int old_id = old_children[i]->renderer_id();
    if (new_child_ids.find(old_id) == new_child_ids.end())
      old_children[i]->Destroy();
  }

  // Now build a vector of new children, reusing objects that were already
  // children of this node before.
  std::vector<BrowserAccessibility*> new_children;
  bool success = true;
  for (size_t i = 0; i < src.child_ids.size(); i++) {
    int32 child_renderer_id = src.child_ids[i];
    int32 index_in_parent = static_cast<int32>(i);
    BrowserAccessibility* child = GetFromRendererID(child_renderer_id);
    if (child) {
      if (child->parent() != instance) {
        // This is a serious error - nodes should never be reparented.
        // If this case occurs, continue so this node isn't left in an
        // inconsistent state, but return failure at the end.
        success = false;
        continue;
      }
      child->UpdateParent(instance, index_in_parent);
    } else {
      child = CreateNode(instance, child_renderer_id, index_in_parent);
    }
    new_children.push_back(child);
  }

  // Finally, swap in the new children vector for the old.
  instance->SwapChildren(new_children);

  // Handle the case where this node is the new root of the tree.
  if (src.role == AccessibilityNodeData::ROLE_ROOT_WEB_AREA &&
      (!root_ || root_->renderer_id() != src.id)) {
    if (root_)
      root_->Destroy();
    if (focus_ == root_)
      focus_ = instance;
    root_ = instance;
  }

  // Keep track of what node is focused.
  if ((src.state >> AccessibilityNodeData::STATE_FOCUSED) & 1)
    SetFocus(instance, false);

  return success;
}

}  // namespace content
<|endoftext|>


<commit_before>#ifndef ITER_REVERSE_HPP_
#define ITER_REVERSE_HPP_

#include "iterbase.hpp"

#include <utility>
#include <iterator>

namespace iter {
  template <typename Container>
  class Reverser;

  template <typename Container>
  Reverser<Container> reversed(Container&&);

  template <typename Container>
  class Reverser {
   private:
    Container container;
    friend Reverser reversed<Container>(Container&&);

    Reverser(Container&& in_container)
        : container(std::forward<Container>(in_container)) {}

   public:
    class Iterator : public std::iterator<std::input_iterator_tag,
                         iterator_traits_deref<Container>> {
     private:
      reverse_iterator_type<Container> sub_iter;

     public:
      Iterator(reverse_iterator_type<Container>&& iter)
          : sub_iter{std::move(iter)} {}

      reverse_iterator_deref<Container> operator*() {
        return *this->sub_iter;
      }

      reverse_iterator_arrow<Container> operator->() {
        return apply_arrow(this->sub_iter);
      }

      Iterator& operator++() {
        ++this->sub_iter;
        return *this;
      }

      Iterator operator++(int) {
        auto ret = *this;
        ++*this;
        return ret;
      }

      bool operator!=(const Iterator& other) const {
        return this->sub_iter != other.sub_iter;
      }

      bool operator==(const Iterator& other) const {
        return !(*this != other);
      }
    };

    Iterator begin() {
      return {this->container.rbegin()};
    }

    Iterator end() {
      return {this->container.rend()};
    }
  };

  template <typename Container>
  Reverser<Container> reversed(Container&& container) {
    return {std::forward<Container>(container)};
  }

  //
  // specialization for statically allocated arrays
  //
  template <typename T, std::size_t N>
  Reverser<T[N]> reversed(T(&)[N]);

  template <typename T, std::size_t N>
  class Reverser<T[N]> {
   private:
    T* array;
    friend Reverser reversed<T, N>(T(&)[N]);

    // Value constructor for use only in the reversed function
    Reverser(T* in_array) : array{in_array} {}

   public:
    Reverser(const Reverser&) = default;
    class Iterator : public std::iterator<std::input_iterator_tag, T> {
     private:
      T* sub_iter;

     public:
      Iterator(T* iter) : sub_iter{iter} {}

      T& operator*() {
        return *(this->sub_iter - 1);
      }

      T* operator->() {
        return (this->sub_iter - 1);
      }

      Iterator& operator++() {
        --this->sub_iter;
        return *this;
      }

      Iterator operator++(int) {
        auto ret = *this;
        ++*this;
        return ret;
      }

      bool operator!=(const Iterator& other) const {
        return this->sub_iter != other.sub_iter;
      }

      bool operator==(const Iterator& other) const {
        return !(*this != other);
      }
    };

    Iterator begin() {
      return {this->array + N};
    }

    Iterator end() {
      return {this->array};
    }
  };

  template <typename T, std::size_t N>
  Reverser<T[N]> reversed(T(&array)[N]) {
    return {array};
  }
}

#endif
<commit_msg>moves Reverser into impl { }<commit_after>#ifndef ITER_REVERSE_HPP_
#define ITER_REVERSE_HPP_

#include "iterbase.hpp"

#include <utility>
#include <iterator>

namespace iter {
  namespace impl {
    template <typename Container>
    class Reverser;

    template <typename T, std::size_t N>
    class Reverser<T[N]>;
  }

  template <typename Container>
  impl::Reverser<Container> reversed(Container&&);

  template <typename T, std::size_t N>
  impl::Reverser<T[N]> reversed(T(&)[N]);
}

template <typename Container>
class iter::impl::Reverser {
 private:
  Container container;
  friend Reverser iter::reversed<Container>(Container&&);

  Reverser(Container&& in_container)
      : container(std::forward<Container>(in_container)) {}

 public:
  class Iterator : public std::iterator<std::input_iterator_tag,
                       iterator_traits_deref<Container>> {
   private:
    reverse_iterator_type<Container> sub_iter;

   public:
    Iterator(reverse_iterator_type<Container>&& iter)
        : sub_iter{std::move(iter)} {}

    reverse_iterator_deref<Container> operator*() {
      return *this->sub_iter;
    }

    reverse_iterator_arrow<Container> operator->() {
      return apply_arrow(this->sub_iter);
    }

    Iterator& operator++() {
      ++this->sub_iter;
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {this->container.rbegin()};
  }

  Iterator end() {
    return {this->container.rend()};
  }
};

template <typename Container>
iter::impl::Reverser<Container> iter::reversed(Container&& container) {
  return {std::forward<Container>(container)};
}

// specialization for statically allocated arrays

template <typename T, std::size_t N>
class iter::impl::Reverser<T[N]> {
 private:
  T* array;
  friend Reverser iter::reversed<T, N>(T(&)[N]);

  // Value constructor for use only in the reversed function
  Reverser(T* in_array) : array{in_array} {}

 public:
  Reverser(const Reverser&) = default;
  class Iterator : public std::iterator<std::input_iterator_tag, T> {
   private:
    T* sub_iter;

   public:
    Iterator(T* iter) : sub_iter{iter} {}

    T& operator*() {
      return *(this->sub_iter - 1);
    }

    T* operator->() {
      return (this->sub_iter - 1);
    }

    Iterator& operator++() {
      --this->sub_iter;
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {this->array + N};
  }

  Iterator end() {
    return {this->array};
  }
};

template <typename T, std::size_t N>
iter::impl::Reverser<T[N]> iter::reversed(T(&array)[N]) {
  return {array};
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlg_View3D.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 17:38:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "dlg_View3D.hxx"
#include "dlg_View3D.hrc"
#include "Strings.hrc"
#include "TabPages.hrc"
#include "ResId.hxx"
#include "NoWarningThisInCTOR.hxx"
#include "tp_3D_SceneGeometry.hxx"
#include "tp_3D_SceneAppearance.hxx"
#include "tp_3D_SceneIllumination.hxx"
#include "ChartModelHelper.hxx"
#include "macros.hxx"
#include "Pseudo3DHelper.hxx"
#include "ControllerLockGuard.hxx"

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

// for RET_OK
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

//-----------------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

// static
USHORT View3DDialog::m_nLastPageId = 0;

View3DDialog::View3DDialog(Window* pParent, const uno::Reference< frame::XModel > & xChartModel, XColorTable* pColorTable )
    : TabDialog(pParent,SchResId(DLG_3D_VIEW))
    , m_aTabControl(this,SchResId(TABCTRL))
    , m_aBtnOK(this,SchResId(BTN_OK))
    , m_aBtnCancel(this,SchResId(BTN_CANCEL))
    , m_aBtnHelp(this,SchResId(BTN_HELP))
    , m_pGeometry(0)
    , m_pAppearance(0)
    , m_pIllumination(0)
    , m_aControllerLocker(xChartModel)
{
    FreeResource();

    uno::Reference< beans::XPropertySet > xSceneProperties( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
    m_pGeometry   = new ThreeD_SceneGeometry_TabPage(&m_aTabControl,xSceneProperties,m_aControllerLocker);
    m_pAppearance = new ThreeD_SceneAppearance_TabPage(&m_aTabControl,xChartModel,m_aControllerLocker);
    m_pIllumination = new ThreeD_SceneIllumination_TabPage(&m_aTabControl,xSceneProperties,xChartModel,pColorTable);

    m_aTabControl.InsertPage( TP_3D_SCENEGEOMETRY, String(SchResId(STR_PAGE_PERSPECTIVE)) );
    m_aTabControl.InsertPage( TP_3D_SCENEAPPEARANCE, String(SchResId(STR_PAGE_APPEARANCE)) );
    m_aTabControl.InsertPage( TP_3D_SCENEILLUMINATION, String(SchResId(STR_PAGE_ILLUMINATION)) );

    m_aTabControl.SetTabPage( TP_3D_SCENEGEOMETRY, m_pGeometry );
    m_aTabControl.SetTabPage( TP_3D_SCENEAPPEARANCE, m_pAppearance );
    m_aTabControl.SetTabPage( TP_3D_SCENEILLUMINATION, m_pIllumination );

    m_aTabControl.SelectTabPage( m_nLastPageId );
}

View3DDialog::~View3DDialog()
{
    delete m_pGeometry;
    delete m_pAppearance;
    delete m_pIllumination;

    m_nLastPageId = m_aTabControl.GetCurPageId();
}

short View3DDialog::Execute()
{
    short nResult = TabDialog::Execute();
    if( nResult == RET_OK )
    {
        if( m_pGeometry )
            m_pGeometry->commitPendingChanges();
        if( m_pAppearance )
            m_pAppearance->commitPendingChanges();
        if( m_pIllumination )
            m_pIllumination->commitPendingChanges();
    }
    return nResult;
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS chart06 (1.2.8); FILE MERGED 2007/06/11 09:43:32 iha 1.2.8.1: removed superfluous include<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlg_View3D.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-03 13:38:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "dlg_View3D.hxx"
#include "dlg_View3D.hrc"
#include "Strings.hrc"
#include "TabPages.hrc"
#include "ResId.hxx"
#include "NoWarningThisInCTOR.hxx"
#include "tp_3D_SceneGeometry.hxx"
#include "tp_3D_SceneAppearance.hxx"
#include "tp_3D_SceneIllumination.hxx"
#include "ChartModelHelper.hxx"
#include "macros.hxx"
#include "ControllerLockGuard.hxx"

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

// for RET_OK
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

//-----------------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

// static
USHORT View3DDialog::m_nLastPageId = 0;

View3DDialog::View3DDialog(Window* pParent, const uno::Reference< frame::XModel > & xChartModel, XColorTable* pColorTable )
    : TabDialog(pParent,SchResId(DLG_3D_VIEW))
    , m_aTabControl(this,SchResId(TABCTRL))
    , m_aBtnOK(this,SchResId(BTN_OK))
    , m_aBtnCancel(this,SchResId(BTN_CANCEL))
    , m_aBtnHelp(this,SchResId(BTN_HELP))
    , m_pGeometry(0)
    , m_pAppearance(0)
    , m_pIllumination(0)
    , m_aControllerLocker(xChartModel)
{
    FreeResource();

    uno::Reference< beans::XPropertySet > xSceneProperties( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
    m_pGeometry   = new ThreeD_SceneGeometry_TabPage(&m_aTabControl,xSceneProperties,m_aControllerLocker);
    m_pAppearance = new ThreeD_SceneAppearance_TabPage(&m_aTabControl,xChartModel,m_aControllerLocker);
    m_pIllumination = new ThreeD_SceneIllumination_TabPage(&m_aTabControl,xSceneProperties,xChartModel,pColorTable);

    m_aTabControl.InsertPage( TP_3D_SCENEGEOMETRY, String(SchResId(STR_PAGE_PERSPECTIVE)) );
    m_aTabControl.InsertPage( TP_3D_SCENEAPPEARANCE, String(SchResId(STR_PAGE_APPEARANCE)) );
    m_aTabControl.InsertPage( TP_3D_SCENEILLUMINATION, String(SchResId(STR_PAGE_ILLUMINATION)) );

    m_aTabControl.SetTabPage( TP_3D_SCENEGEOMETRY, m_pGeometry );
    m_aTabControl.SetTabPage( TP_3D_SCENEAPPEARANCE, m_pAppearance );
    m_aTabControl.SetTabPage( TP_3D_SCENEILLUMINATION, m_pIllumination );

    m_aTabControl.SelectTabPage( m_nLastPageId );
}

View3DDialog::~View3DDialog()
{
    delete m_pGeometry;
    delete m_pAppearance;
    delete m_pIllumination;

    m_nLastPageId = m_aTabControl.GetCurPageId();
}

short View3DDialog::Execute()
{
    short nResult = TabDialog::Execute();
    if( nResult == RET_OK )
    {
        if( m_pGeometry )
            m_pGeometry->commitPendingChanges();
        if( m_pAppearance )
            m_pAppearance->commitPendingChanges();
        if( m_pIllumination )
            m_pIllumination->commitPendingChanges();
    }
    return nResult;
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012
 * Alessio Sclocco <a.sclocco@vu.nl>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <string>
#include <limits>
using std::string;
using std::numeric_limits;

#ifndef OBSERVATION_HPP
#define OBSERVATION_HPP

namespace AstroData {

template< typename T > class Observation {
public:
								Observation(string name, string dataType);
								~Observation();

	inline	void				setPadding(unsigned int pad);

	// General observation parameters
	inline	void 				setNrSeconds(unsigned int seconds);
	inline 	void 				setNrStations(unsigned int nrStations);
	inline 	void 				setNrBeams(unsigned int beams);
			void 				setNrSamplesPerSecond(unsigned int samples);
			void 				setNrChannels(unsigned int channels);

	// Frequency parameters
	inline 	void 				setMinFreq(float freq);
	inline 	void 				setMaxFreq(float freq);
	inline 	void 				setChannelBandwidth(float bandwidth);

	// Statistical properties
	inline 	void 				setMinValue(T value);
	inline 	void 				setMaxValue(T value);
	inline 	void 				setAverage(unsigned int channel, double avg);
	inline 	void 				setVariance(unsigned int channel, double var);
	inline 	void 				setStdDev(unsigned int channel, double dev);

	// Dispersion measures
			void 				setNrDMs(unsigned int dms);
	inline 	void 				setFirstDM(float dm);
	inline 	void 				setDMStep(float step);

	// Periods
			void 				setNrPeriods(unsigned int periods);
			void 				setNrBins(unsigned int bins);
	inline 	void 				setFirstPeriod(unsigned int period);
	inline 	void 				setPeriodStep(unsigned int step);

	inline 	string 				getName() const;
	inline 	string 				getDataType() const;
	inline 	unsigned int 		getPadding() const;

	// General observation parameters
	inline 	unsigned int 		getNrSeconds() const;
	inline 	unsigned int 		getNrStations() const;
	inline 	unsigned int 		getNrBeams() const;
	inline 	unsigned int 		getNrSamplesPerSecond() const;
	inline 	float 				getSamplingRate() const;
	inline 	unsigned int 		getNrSamplesPerPaddedSecond() const;
	inline 	unsigned int 		getNrChannels() const;
	inline 	unsigned int 		getNrPaddedChannels() const;

	// Frequency parameters
	inline 	float 				getMinFreq() const;
	inline 	float 				getMaxFreq() const;
	inline 	float 				getChannelBandwidth() const;

	// Statistical properties
	inline 	T 					getMinValue() const;
	inline 	T 					getMaxValue() const;
	inline 	double 				getAverage(unsigned int channel) const;
	inline 	double 				getVariance(unsigned int channel) const;
	inline 	double 				getStdDev(unsigned int channel) const;

	// Dispersion measures
	inline 	unsigned int 		getNrDMs() const;
	inline 	unsigned int 		getNrPaddedDMs() const;
	inline 	float 				getFirstDM() const;
	inline 	float 				getDMStep() const;

	// Periods
	inline 	unsigned int 		getNrPeriods() const;
	inline 	unsigned int 		getNrPaddedPeriods() const;
	inline 	unsigned int 		getNrBins() const;
	inline 	unsigned int 		getNrPaddedBins() const;
	inline 	unsigned int 		getFirstPeriod() const;
	inline 	unsigned int 		getPeriodStep() const;

private:
			string 				name;
			string 				dataType;
			unsigned int 		padding;

			unsigned int 		nrSeconds;
			unsigned int 		nrStations;
			unsigned int 		nrBeams;
			unsigned int 		nrSamplesPerSecond;
			float 				samplingRate;
			unsigned int 		nrSamplesPerPaddedSecond;
			unsigned int 		nrChannels;
			unsigned int 		nrPaddedChannels;

			float 				minFreq;
			float				maxFreq;
			float 				channelBandwidth;

			T 					minValue;
			T 					maxValue;
			double *			average;
			double *			variance;
			double *			stdDev;

			unsigned int 		nrDMs;
			unsigned int 		nrPaddedDMs;
			float 				firstDM;
			float 				DMStep;

			unsigned int 		nrPeriods;
			unsigned int 		nrPaddedPeriods;
			unsigned int 		nrBins;
			unsigned int 		nrPaddedBins;
			unsigned int 		firstPeriod;
			unsigned int 		periodStep;
};

// Implementation

template< typename T > Observation< T >::Observation(string name, string dataType) : name(name), dataType(dataType), padding(1), nrSeconds(0), nrStations(0), nrBeams(0), nrSamplesPerSecond(0), samplingRate(0.0f), nrSamplesPerPaddedSecond(0), nrChannels(0), nrPaddedChannels(0), minFreq(0.0f), maxFreq(0.0f), channelBandwidth(0.0f), minValue(numeric_limits< T >::max()), maxValue(numeric_limits< T >::min()), average(0), variance(0), stdDev(0), nrDMs(0), nrPaddedDMs(0), firstDM(0.0f), DMStep(0.0f), nrPeriods(0), nrPaddedPeriods(0), nrBins(0), nrPaddedBins(0), firstPeriod(0), periodStep(0) {}

template< typename T > Observation< T >::~Observation() {
	delete [] average;
	delete [] variance;
	delete [] stdDev;
}

template< typename T > inline void Observation< T >::setPadding(unsigned int pad) {
	padding = pad;
}

template< typename T > inline void Observation< T >::setNrSeconds(unsigned int seconds) {
	nrSeconds = seconds;
}

template< typename T > inline void Observation< T >::setNrStations(unsigned int stations) {
	nrStations = stations;
}

template< typename T > inline void Observation< T >::setNrBeams(unsigned int beams) {
	nrBeams = beams;
}

template< typename T > void Observation< T >::setNrSamplesPerSecond(unsigned int samples) {
	nrSamplesPerSecond = samples;
	samplingRate = 1.0f / samples;
	if ( (nrSamplesPerSecond % padding) == 0 ) {
		nrSamplesPerPaddedSecond = nrSamplesPerSecond;
	}
	else {
		nrSamplesPerPaddedSecond = nrSamplesPerSecond + (padding - (nrSamplesPerSecond % padding));
	}
}

template< typename T > void Observation< T >::setNrChannels(unsigned int channels) {
	nrChannels = channels;

	average = new double [channels];
	variance = new double [channels];
	stdDev = new double [channels];

	if ( (nrChannels % padding) == 0 ) {
		nrPaddedChannels = nrChannels;
	}
	else {
		nrPaddedChannels = nrChannels + (padding - (nrChannels % padding));
	}
}

template< typename T > inline void Observation< T >::setMinFreq(float freq) {
	minFreq = freq;
}

template< typename T > inline void Observation< T >::setMaxFreq(float freq) {
	maxFreq = freq;
}

template< typename T > inline void Observation< T >::setChannelBandwidth(float bandwidth) {
	channelBandwidth = bandwidth;
}

template< typename T > inline void Observation< T >::setMinValue(T value) {
	minValue = value;
}

template< typename T > inline void Observation< T >::setMaxValue(T value) {
	maxValue = value;
}

template< typename T > inline void Observation< T >::setAverage(unsigned int channel, double avg) {
	average[channel] = avg;
}

template< typename T > inline void Observation< T >::setVariance(unsigned int channel, double var) {
	variance[channel] = var;
}

template< typename T > inline void Observation< T >::setStdDev(unsigned int channel, double dev) {
	stdDev[channel] = dev;
}

template< typename T > void Observation< T >::setNrDMs(unsigned int dms) {
	nrDMs = dms;

	if ( (nrDMs % padding) == 0 ) {
		nrPaddedDMs = nrDMs;
	}
	else {
		nrPaddedDMs = nrDMs + (padding - (nrDMs % padding));
	}
}

template< typename T > inline void Observation< T >::setFirstDM(float dm) {
	firstDM = dm;
}

template< typename T > inline void Observation< T >::setDMStep(float step) {
	DMStep = step;
}

template< typename T > void Observation< T >::setNrPeriods(unsigned int periods) {
	nrPeriods = periods;

	if ( (nrPeriods % padding) == 0 ) {
		nrPaddedPeriods = nrPeriods;
	}
	else {
		nrPaddedPeriods = nrPeriods + (padding - (nrPeriods % padding));
	}
}

template< typename T > void Observation< T >::setNrBins(unsigned int bins) {
	nrBins = bins;

	if ( (nrBins % padding) == 0 ) {
		nrPaddedBins = nrBins;
	}
	else {
		nrPaddedBins = nrBins + (padding - (nrBins % padding));
	}
}

template< typename T > inline void Observation< T >::setFirstPeriod(unsigned int period) {
	firstPeriod = period;
}

template< typename T > inline void Observation< T >::setPeriodStep(unsigned int step) {
	periodStep = step;
}

template< typename T > inline string Observation< T >::getName() const {
	return name;
}

template< typename T > inline string Observation< T >::getDataType() const {
	return dataType;
}

template< typename T > inline unsigned int Observation< T >::getPadding() const {
	return padding;
}

template< typename T > inline unsigned int Observation< T >::getNrSeconds() const {
	return nrSeconds;
}

template< typename T > inline unsigned int Observation< T >::getNrStations() const {
	return nrStations;
}

template< typename T > inline unsigned int Observation< T >::getNrBeams() const {
	return nrBeams;
}

template< typename T > inline unsigned int Observation< T >::getNrSamplesPerSecond() const {
	return nrSamplesPerSecond;
}

template< typename T > inline float Observation< T >::getSamplingRate() const {
	return samplingRate;
}

template< typename T > inline unsigned int Observation< T >::getNrSamplesPerPaddedSecond() const {
	return nrSamplesPerPaddedSecond;
}

template< typename T > inline unsigned int Observation< T >::getNrChannels() const {
	return nrChannels;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedChannels() const {
	return nrPaddedChannels;
}

template< typename T > inline float Observation< T >::getMinFreq() const {
	return minFreq;
}

template< typename T > inline float Observation< T >::getMaxFreq() const {
	return maxFreq;
}

template< typename T > inline float Observation< T >::getChannelBandwidth() const {
	return channelBandwidth;
}

template< typename T > inline T Observation< T >::getMinValue() const {
	return minValue;
}

template< typename T > inline T Observation< T >::getMaxValue() const {
	return maxValue;
}

template< typename T > inline double Observation< T >::getAverage(unsigned int channel) const {
	return average[channel];
}

template< typename T > inline double Observation< T >::getVariance(unsigned int channel) const {
	return variance[channel];
}

template< typename T > inline double Observation< T >::getStdDev(unsigned int channel) const {
	return stdDev[channel];
}

template< typename T > inline unsigned int Observation< T >::getNrDMs() const {
	return nrDMs;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedDMs() const {
	return nrPaddedDMs;
}

template< typename T > inline float Observation< T >::getFirstDM() const {
	return firstDM;
}

template< typename T > inline float Observation< T >::getDMStep() const {
	return DMStep;
}

template< typename T > inline unsigned int Observation< T >::getNrPeriods() const {
	return nrPeriods;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedPeriods() const {
	return nrPaddedPeriods;
}

template< typename T > inline unsigned int Observation< T >::getNrBins() const {
	return nrBins;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedBins() const {
	return nrPaddedBins;
}

template< typename T > inline unsigned int Observation< T >::getFirstPeriod() const {
	return firstPeriod;
}

template< typename T > inline unsigned int Observation< T >::getPeriodStep() const {
	return periodStep;
}

} // AstroData

#endif // OBSERVATION_HPP
<commit_msg>Just changed the licensing format.<commit_after>//
// Copyright (C) 2012
// Alessio Sclocco <a.sclocco@vu.nl>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include <string>
#include <limits>
using std::string;
using std::numeric_limits;

#ifndef OBSERVATION_HPP
#define OBSERVATION_HPP

namespace AstroData {

template< typename T > class Observation {
public:
								Observation(string name, string dataType);
								~Observation();

	inline	void				setPadding(unsigned int pad);

	// General observation parameters
	inline	void 				setNrSeconds(unsigned int seconds);
	inline 	void 				setNrStations(unsigned int nrStations);
	inline 	void 				setNrBeams(unsigned int beams);
			void 				setNrSamplesPerSecond(unsigned int samples);
			void 				setNrChannels(unsigned int channels);

	// Frequency parameters
	inline 	void 				setMinFreq(float freq);
	inline 	void 				setMaxFreq(float freq);
	inline 	void 				setChannelBandwidth(float bandwidth);

	// Statistical properties
	inline 	void 				setMinValue(T value);
	inline 	void 				setMaxValue(T value);
	inline 	void 				setAverage(unsigned int channel, double avg);
	inline 	void 				setVariance(unsigned int channel, double var);
	inline 	void 				setStdDev(unsigned int channel, double dev);

	// Dispersion measures
			void 				setNrDMs(unsigned int dms);
	inline 	void 				setFirstDM(float dm);
	inline 	void 				setDMStep(float step);

	// Periods
			void 				setNrPeriods(unsigned int periods);
			void 				setNrBins(unsigned int bins);
	inline 	void 				setFirstPeriod(unsigned int period);
	inline 	void 				setPeriodStep(unsigned int step);

	inline 	string 				getName() const;
	inline 	string 				getDataType() const;
	inline 	unsigned int 		getPadding() const;

	// General observation parameters
	inline 	unsigned int 		getNrSeconds() const;
	inline 	unsigned int 		getNrStations() const;
	inline 	unsigned int 		getNrBeams() const;
	inline 	unsigned int 		getNrSamplesPerSecond() const;
	inline 	float 				getSamplingRate() const;
	inline 	unsigned int 		getNrSamplesPerPaddedSecond() const;
	inline 	unsigned int 		getNrChannels() const;
	inline 	unsigned int 		getNrPaddedChannels() const;

	// Frequency parameters
	inline 	float 				getMinFreq() const;
	inline 	float 				getMaxFreq() const;
	inline 	float 				getChannelBandwidth() const;

	// Statistical properties
	inline 	T 					getMinValue() const;
	inline 	T 					getMaxValue() const;
	inline 	double 				getAverage(unsigned int channel) const;
	inline 	double 				getVariance(unsigned int channel) const;
	inline 	double 				getStdDev(unsigned int channel) const;

	// Dispersion measures
	inline 	unsigned int 		getNrDMs() const;
	inline 	unsigned int 		getNrPaddedDMs() const;
	inline 	float 				getFirstDM() const;
	inline 	float 				getDMStep() const;

	// Periods
	inline 	unsigned int 		getNrPeriods() const;
	inline 	unsigned int 		getNrPaddedPeriods() const;
	inline 	unsigned int 		getNrBins() const;
	inline 	unsigned int 		getNrPaddedBins() const;
	inline 	unsigned int 		getFirstPeriod() const;
	inline 	unsigned int 		getPeriodStep() const;

private:
			string 				name;
			string 				dataType;
			unsigned int 		padding;

			unsigned int 		nrSeconds;
			unsigned int 		nrStations;
			unsigned int 		nrBeams;
			unsigned int 		nrSamplesPerSecond;
			float 				samplingRate;
			unsigned int 		nrSamplesPerPaddedSecond;
			unsigned int 		nrChannels;
			unsigned int 		nrPaddedChannels;

			float 				minFreq;
			float				maxFreq;
			float 				channelBandwidth;

			T 					minValue;
			T 					maxValue;
			double *			average;
			double *			variance;
			double *			stdDev;

			unsigned int 		nrDMs;
			unsigned int 		nrPaddedDMs;
			float 				firstDM;
			float 				DMStep;

			unsigned int 		nrPeriods;
			unsigned int 		nrPaddedPeriods;
			unsigned int 		nrBins;
			unsigned int 		nrPaddedBins;
			unsigned int 		firstPeriod;
			unsigned int 		periodStep;
};

// Implementation

template< typename T > Observation< T >::Observation(string name, string dataType) : name(name), dataType(dataType), padding(1), nrSeconds(0), nrStations(0), nrBeams(0), nrSamplesPerSecond(0), samplingRate(0.0f), nrSamplesPerPaddedSecond(0), nrChannels(0), nrPaddedChannels(0), minFreq(0.0f), maxFreq(0.0f), channelBandwidth(0.0f), minValue(numeric_limits< T >::max()), maxValue(numeric_limits< T >::min()), average(0), variance(0), stdDev(0), nrDMs(0), nrPaddedDMs(0), firstDM(0.0f), DMStep(0.0f), nrPeriods(0), nrPaddedPeriods(0), nrBins(0), nrPaddedBins(0), firstPeriod(0), periodStep(0) {}

template< typename T > Observation< T >::~Observation() {
	delete [] average;
	delete [] variance;
	delete [] stdDev;
}

template< typename T > inline void Observation< T >::setPadding(unsigned int pad) {
	padding = pad;
}

template< typename T > inline void Observation< T >::setNrSeconds(unsigned int seconds) {
	nrSeconds = seconds;
}

template< typename T > inline void Observation< T >::setNrStations(unsigned int stations) {
	nrStations = stations;
}

template< typename T > inline void Observation< T >::setNrBeams(unsigned int beams) {
	nrBeams = beams;
}

template< typename T > void Observation< T >::setNrSamplesPerSecond(unsigned int samples) {
	nrSamplesPerSecond = samples;
	samplingRate = 1.0f / samples;
	if ( (nrSamplesPerSecond % padding) == 0 ) {
		nrSamplesPerPaddedSecond = nrSamplesPerSecond;
	}
	else {
		nrSamplesPerPaddedSecond = nrSamplesPerSecond + (padding - (nrSamplesPerSecond % padding));
	}
}

template< typename T > void Observation< T >::setNrChannels(unsigned int channels) {
	nrChannels = channels;

	average = new double [channels];
	variance = new double [channels];
	stdDev = new double [channels];

	if ( (nrChannels % padding) == 0 ) {
		nrPaddedChannels = nrChannels;
	}
	else {
		nrPaddedChannels = nrChannels + (padding - (nrChannels % padding));
	}
}

template< typename T > inline void Observation< T >::setMinFreq(float freq) {
	minFreq = freq;
}

template< typename T > inline void Observation< T >::setMaxFreq(float freq) {
	maxFreq = freq;
}

template< typename T > inline void Observation< T >::setChannelBandwidth(float bandwidth) {
	channelBandwidth = bandwidth;
}

template< typename T > inline void Observation< T >::setMinValue(T value) {
	minValue = value;
}

template< typename T > inline void Observation< T >::setMaxValue(T value) {
	maxValue = value;
}

template< typename T > inline void Observation< T >::setAverage(unsigned int channel, double avg) {
	average[channel] = avg;
}

template< typename T > inline void Observation< T >::setVariance(unsigned int channel, double var) {
	variance[channel] = var;
}

template< typename T > inline void Observation< T >::setStdDev(unsigned int channel, double dev) {
	stdDev[channel] = dev;
}

template< typename T > void Observation< T >::setNrDMs(unsigned int dms) {
	nrDMs = dms;

	if ( (nrDMs % padding) == 0 ) {
		nrPaddedDMs = nrDMs;
	}
	else {
		nrPaddedDMs = nrDMs + (padding - (nrDMs % padding));
	}
}

template< typename T > inline void Observation< T >::setFirstDM(float dm) {
	firstDM = dm;
}

template< typename T > inline void Observation< T >::setDMStep(float step) {
	DMStep = step;
}

template< typename T > void Observation< T >::setNrPeriods(unsigned int periods) {
	nrPeriods = periods;

	if ( (nrPeriods % padding) == 0 ) {
		nrPaddedPeriods = nrPeriods;
	}
	else {
		nrPaddedPeriods = nrPeriods + (padding - (nrPeriods % padding));
	}
}

template< typename T > void Observation< T >::setNrBins(unsigned int bins) {
	nrBins = bins;

	if ( (nrBins % padding) == 0 ) {
		nrPaddedBins = nrBins;
	}
	else {
		nrPaddedBins = nrBins + (padding - (nrBins % padding));
	}
}

template< typename T > inline void Observation< T >::setFirstPeriod(unsigned int period) {
	firstPeriod = period;
}

template< typename T > inline void Observation< T >::setPeriodStep(unsigned int step) {
	periodStep = step;
}

template< typename T > inline string Observation< T >::getName() const {
	return name;
}

template< typename T > inline string Observation< T >::getDataType() const {
	return dataType;
}

template< typename T > inline unsigned int Observation< T >::getPadding() const {
	return padding;
}

template< typename T > inline unsigned int Observation< T >::getNrSeconds() const {
	return nrSeconds;
}

template< typename T > inline unsigned int Observation< T >::getNrStations() const {
	return nrStations;
}

template< typename T > inline unsigned int Observation< T >::getNrBeams() const {
	return nrBeams;
}

template< typename T > inline unsigned int Observation< T >::getNrSamplesPerSecond() const {
	return nrSamplesPerSecond;
}

template< typename T > inline float Observation< T >::getSamplingRate() const {
	return samplingRate;
}

template< typename T > inline unsigned int Observation< T >::getNrSamplesPerPaddedSecond() const {
	return nrSamplesPerPaddedSecond;
}

template< typename T > inline unsigned int Observation< T >::getNrChannels() const {
	return nrChannels;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedChannels() const {
	return nrPaddedChannels;
}

template< typename T > inline float Observation< T >::getMinFreq() const {
	return minFreq;
}

template< typename T > inline float Observation< T >::getMaxFreq() const {
	return maxFreq;
}

template< typename T > inline float Observation< T >::getChannelBandwidth() const {
	return channelBandwidth;
}

template< typename T > inline T Observation< T >::getMinValue() const {
	return minValue;
}

template< typename T > inline T Observation< T >::getMaxValue() const {
	return maxValue;
}

template< typename T > inline double Observation< T >::getAverage(unsigned int channel) const {
	return average[channel];
}

template< typename T > inline double Observation< T >::getVariance(unsigned int channel) const {
	return variance[channel];
}

template< typename T > inline double Observation< T >::getStdDev(unsigned int channel) const {
	return stdDev[channel];
}

template< typename T > inline unsigned int Observation< T >::getNrDMs() const {
	return nrDMs;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedDMs() const {
	return nrPaddedDMs;
}

template< typename T > inline float Observation< T >::getFirstDM() const {
	return firstDM;
}

template< typename T > inline float Observation< T >::getDMStep() const {
	return DMStep;
}

template< typename T > inline unsigned int Observation< T >::getNrPeriods() const {
	return nrPeriods;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedPeriods() const {
	return nrPaddedPeriods;
}

template< typename T > inline unsigned int Observation< T >::getNrBins() const {
	return nrBins;
}

template< typename T > inline unsigned int Observation< T >::getNrPaddedBins() const {
	return nrPaddedBins;
}

template< typename T > inline unsigned int Observation< T >::getFirstPeriod() const {
	return firstPeriod;
}

template< typename T > inline unsigned int Observation< T >::getPeriodStep() const {
	return periodStep;
}

} // AstroData

#endif // OBSERVATION_HPP
<|endoftext|>


<commit_before>#include "application.hpp"

#include <iostream>

#include "messageBus\receiver.hpp"

//Include states
#include "modules/states/state.hpp"
#include "modules/states/intro.hpp"
#include "modules/states/menu.hpp"
#include "modules/states/game.hpp"

namespace aw
{

	Application::Application() :
		m_settings(m_messageBus), m_windowHandler(m_messageBus)
	{
		//Init Statemachine
		m_stateMachine.addState("intro", std::unique_ptr<State>(new Intro(m_stateMachine)));
		m_stateMachine.addState("menu", std::unique_ptr<State>(new Menu(m_stateMachine, m_messageBus)));
		m_stateMachine.addState("game", std::unique_ptr<State>(new Game(m_stateMachine, m_messageBus)));

		//Set intro as active State
		m_stateMachine.changeActiveState("menu");

		//Load settings afterwards, because it will send informations to the states
		//Sound, window settings
		m_settings.load();
	}

	int Application::run()
	{
		while (m_windowHandler.getWindow().isOpen())
		{
			//Update the frameTimer
			m_frameTime = m_frameTimer.restart();

			//Check for Events (Will send them to the MessageBus)
			m_windowHandler.checkEventQueue();

			//Update active State
			m_stateMachine.update(m_frameTime);

			//Clear the rendertarget
			m_windowHandler.getWindow().clear();

			//Draw active State
			m_stateMachine.render(m_windowHandler.getWindow());

			//Display frame
			m_windowHandler.getWindow().display();
		}

		m_settings.save();
		std::cin.get();
		return 0;
	}

}<commit_msg>Revert std::cin<commit_after>#include "application.hpp"

#include <iostream>

#include "messageBus\receiver.hpp"

//Include states
#include "modules/states/state.hpp"
#include "modules/states/intro.hpp"
#include "modules/states/menu.hpp"
#include "modules/states/game.hpp"

namespace aw
{

	Application::Application() :
		m_settings(m_messageBus), m_windowHandler(m_messageBus)
	{
		//Init Statemachine
		m_stateMachine.addState("intro", std::unique_ptr<State>(new Intro(m_stateMachine)));
		m_stateMachine.addState("menu", std::unique_ptr<State>(new Menu(m_stateMachine, m_messageBus)));
		m_stateMachine.addState("game", std::unique_ptr<State>(new Game(m_stateMachine, m_messageBus)));

		//Set intro as active State
		m_stateMachine.changeActiveState("menu");

		//Load settings afterwards, because it will send informations to the states
		//Sound, window settings
		m_settings.load();
	}

	int Application::run()
	{
		while (m_windowHandler.getWindow().isOpen())
		{
			//Update the frameTimer
			m_frameTime = m_frameTimer.restart();

			//Check for Events (Will send them to the MessageBus)
			m_windowHandler.checkEventQueue();

			//Update active State
			m_stateMachine.update(m_frameTime);

			//Clear the rendertarget
			m_windowHandler.getWindow().clear();

			//Draw active State
			m_stateMachine.render(m_windowHandler.getWindow());

			//Display frame
			m_windowHandler.getWindow().display();
		}

		m_settings.save();

		return 0;
	}

}<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>
#include <thread>

char field[20][40];
struct point { int x = 0, y = 0; } start, dest, current, goal;

int main() { //sramim se.
    int q, e, r, t, steps;
    std::cout << "Unesite a.x, a.y, b.x, b.y s razmacima izmedu brojeva (a 0-19, b 0-39): ";
    std::cin >> q >> e >> r >> t; //sanitize input??
    start = { q,e };
    dest = { r,t };
    current = start;
    field[5][1] = '*'; field[5][2] = '*'; field[5][3] = '*'; field[5][4] = '*';

    for(;;) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        system("CLS");
        if (current.x == goal.x && current.y == goal.y) break;
        if (current.x != goal.x && field[current.x + 1][current.y] != '*')      current.x++;
        else if (current.y != goal.y && field[current.x][current.y + 1] != '*') current.y++;
        steps++;

        for (int i = 0; i < 20; ++i) {//fill array
            for (int j = 0; j < 40; ++j) {
                if (field[i][j] == 'B') goal = { i,j };
                if (i == start.x && j == start.y)                 field[i][j] = 'A';
                else if (i == dest.x  && j == dest.y)             field[i][j] = 'B';
                else if (i == 0 || j == 0 || i == 19 || j == 39)  field[i][j] = '*';
                else {
                    if (field[i][j] != 'x' && field[i][j] != '*') field[i][j] = '-';
                    field[current.x][current.y] = 'x';
                }
            }
        }
        for (int i = 0; i < 20; ++i) {
            for (int j = 0; j < 40; ++j) std::cout << field[i][j];
            std::cout << "\n";
        }
    }
    std::cout << "done in: " << steps << " steps." << "\n";
    return 0;
}
<commit_msg>Update Source.cpp<commit_after>#include <iostream>
#include <chrono>
#include <thread>

char field[20][40];
struct point { int x = 0, y = 0; } start, dest, current, goal;

int main() { //sramim se.
    int q, e, r, t, steps;
    std::cout << "Unesite a.x, a.y, b.x, b.y s razmacima izmedu brojeva (a 0-19, b 0-39): ";
    std::cin >> q >> e >> r >> t; //sanitize input??
    start = { q,e };
    dest = { r,t };
    current = start;
    field[5][1] = '*'; field[5][2] = '*'; field[5][3] = '*'; field[5][4] = '*';

    for(;;) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        system("CLS");
        if (current.x != goal.x && field[current.x + 1][current.y] != '*')      current.x++;
        else if (current.y != goal.y && field[current.x][current.y + 1] != '*') current.y++;
        steps++;

        for (int i = 0; i < 20; ++i) {//fill array
            for (int j = 0; j < 40; ++j) {
                if (field[i][j] == 'B') goal = { i,j };
                if (i == start.x && j == start.y)                 field[i][j] = 'A';
                else if (i == dest.x  && j == dest.y)             field[i][j] = 'B';
                else if (i == 0 || j == 0 || i == 19 || j == 39)  field[i][j] = '*';
                else {
                    if (field[i][j] != 'x' && field[i][j] != '*') field[i][j] = '-';
                    field[current.x][current.y] = 'x';
                }
            }
        }
        for (int i = 0; i < 20; ++i) {
            for (int j = 0; j < 40; ++j) std::cout << field[i][j];
            std::cout << "\n";
        }
    if (current.x == goal.x && current.y == goal.y) break;
    }
    std::cout << "done in: " << steps << " steps." << "\n";
    return 0;
}
<|endoftext|>


<commit_before>#ifndef EMULATOR_H
#define EMULATOR_H

#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <LIBGPU.H>

#define CTR_RUNNING (0)
#define CTR_STOPPED (1)

#define CTR_MODE_TO_FFFF (0)
#define CTR_MODE_TO_TARG (1)

#define CTR_CLOCK_SYS (0)
#define CTR_CLOCK_PIXEL (1)
#define CTR_HORIZ_RETRACE (1)

#define CTR_CLOCK_SYS_ONE (0)
#define CTR_CLOCK_SYS_ONE_EIGHTH (1)

struct MMTEXTURE;

typedef struct
{
	uint16_t Value;
	uint16_t _pad1;

	union
	{
		struct
		{
			uint32_t _pad2 : 2;
			uint32_t IsStopped : 1;
			uint32_t _pad3 : 1;
			uint32_t TargetMode : 1;
			uint32_t IRQ1 : 1;
			uint32_t _pad4 : 1;
			uint32_t IRQ2 : 1;
			uint32_t _pad5 : 1;
			uint32_t Clock : 1;
			uint32_t Division : 1;
			uint32_t _pad6 : 21;
		};
		uint32_t I2;
	};
	union
	{
		struct
		{
			uint16_t Target;
			uint16_t _pad7;
		};
		uint32_t I3;
	};
} SysCounter;

extern SysCounter counters[3];

extern void Emulator_Init(char* windowName, int screen_width, int screen_height);
extern void Emulator_InitialiseGL();
extern void Emulator_BeginScene();
extern void Emulator_EndScene();
extern void Emulator_SaveVRAM(int width, int height);
extern void Emulator_SaveVRAM2(int width, int height);
extern void Emulator_ShutDown();
extern void Emulator_SwapWindow();
extern void Emulator_GenerateAndBindTpage(unsigned short tpage, unsigned short clut, int semiTransparent);
extern void Emulator_DestroyLastVRAMTexture();
extern void Emulator_DestroyFrameBuffer(GLuint& fbo);
extern void Emulator_GenerateFrameBuffer(GLuint& fbo);
extern void Emulator_GenerateFrameBufferTexture();
extern void Emulator_DeleteFrameBufferTexture();
extern void Emulator_GenerateAndBindNullWhite();
extern void Emulator_CheckTextureIntersection(RECT16* rect);
extern void Emulator_SetBlendMode(int mode);
extern void Emulator_UpdateInput();
extern void Emulator_CounterLoop();
#if GLTEST
extern void Emulator_TestDrawVertices(short* vptr, MMTEXTURE* tex);
#endif

#endif

<commit_msg>Update EMULATOR.H<commit_after>#ifndef EMULATOR_H
#define EMULATOR_H

#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <LIBGPU.H>

#define CTR_RUNNING (0)
#define CTR_STOPPED (1)

#define CTR_MODE_TO_FFFF (0)
#define CTR_MODE_TO_TARG (1)

#define CTR_CLOCK_SYS (0)
#define CTR_CLOCK_PIXEL (1)
#define CTR_HORIZ_RETRACE (1)

#define CTR_CLOCK_SYS_ONE (0)
#define CTR_CLOCK_SYS_ONE_EIGHTH (1)

struct MMTEXTURE;

typedef struct
{
	uint16_t Value;
	uint16_t _pad1;

	union
	{
		struct
		{
			uint32_t _pad2 : 2;
			uint32_t IsStopped : 1;
			uint32_t _pad3 : 1;
			uint32_t TargetMode : 1;
			uint32_t IRQ1 : 1;
			uint32_t _pad4 : 1;
			uint32_t IRQ2 : 1;
			uint32_t _pad5 : 1;
			uint32_t Clock : 1;
			uint32_t Division : 1;
			uint32_t _pad6 : 21;
		};
		uint32_t I2;
	};
	union
	{
		struct
		{
			uint16_t Target;
			uint16_t _pad7;
		};
		uint32_t I3;
	};
} SysCounter;

extern SysCounter counters[3];

extern void Emulator_Init(char* windowName, int screen_width, int screen_height);
extern void Emulator_InitialiseGL();
extern void Emulator_BeginScene();
extern void Emulator_EndScene();
extern void Emulator_SaveVRAM(int width, int height);
extern void Emulator_SaveVRAM2(int width, int height);
extern void Emulator_ShutDown();
extern void Emulator_SwapWindow();
extern void Emulator_GenerateAndBindTpage(unsigned short tpage, unsigned short clut, int semiTransparent);
extern void Emulator_DestroyLastVRAMTexture();
extern void Emulator_DestroyFrameBuffer(GLuint& fbo);
extern void Emulator_GenerateFrameBuffer(GLuint& fbo);
extern void Emulator_GenerateFrameBufferTexture();
extern void Emulator_DeleteFrameBufferTexture();
extern void Emulator_GenerateAndBindNullWhite();
extern void Emulator_CheckTextureIntersection(RECT16* rect);
extern void Emulator_SetBlendMode(int mode);
extern void Emulator_UpdateInput();
extern void Emulator_CounterLoop();
#if GLTEST
extern void Emulator_TestDrawVertices(short* vptr, MMTEXTURE* tex);
#endif

extern char* Emulator_MapVirtualMemory(void* address, unsigned int size);
extern int Emulator_InitialiseGameVariables();

#endif

<|endoftext|>


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

#include "helpers/memenv/memenv.h"

#include <string.h>

#include <limits>
#include <map>
#include <string>
#include <vector>

#include "leveldb/env.h"
#include "leveldb/status.h"
#include "port/port.h"
#include "port/thread_annotations.h"
#include "util/mutexlock.h"

namespace leveldb {

namespace {

class FileState {
 public:
  // FileStates are reference counted. The initial reference count is zero
  // and the caller must call Ref() at least once.
  FileState() : refs_(0), size_(0) {}

  // Increase the reference count.
  void Ref() {
    MutexLock lock(&refs_mutex_);
    ++refs_;
  }

  // Decrease the reference count. Delete if this is the last reference.
  void Unref() {
    bool do_delete = false;

    {
      MutexLock lock(&refs_mutex_);
      --refs_;
      assert(refs_ >= 0);
      if (refs_ <= 0) {
        do_delete = true;
      }
    }

    if (do_delete) {
      delete this;
    }
  }

  uint64_t Size() const {
    MutexLock lock(&blocks_mutex_);
    return size_;
  }

  void Truncate() {
    MutexLock lock(&blocks_mutex_);
    for (char*& block : blocks_) {
      delete[] block;
    }
    blocks_.clear();
    size_ = 0;
  }

  Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const {
    MutexLock lock(&blocks_mutex_);
    if (offset > size_) {
      return Status::IOError("Offset greater than file size.");
    }
    const uint64_t available = size_ - offset;
    if (n > available) {
      n = static_cast<size_t>(available);
    }
    if (n == 0) {
      *result = Slice();
      return Status::OK();
    }

    assert(offset / kBlockSize <= std::numeric_limits<size_t>::max());
    size_t block = static_cast<size_t>(offset / kBlockSize);
    size_t block_offset = offset % kBlockSize;

    if (n <= kBlockSize - block_offset) {
      // The requested bytes are all in the first block.
      *result = Slice(blocks_[block] + block_offset, n);
      return Status::OK();
    }

    size_t bytes_to_copy = n;
    char* dst = scratch;

    while (bytes_to_copy > 0) {
      size_t avail = kBlockSize - block_offset;
      if (avail > bytes_to_copy) {
        avail = bytes_to_copy;
      }
      memcpy(dst, blocks_[block] + block_offset, avail);

      bytes_to_copy -= avail;
      dst += avail;
      block++;
      block_offset = 0;
    }

    *result = Slice(scratch, n);
    return Status::OK();
  }

  Status Append(const Slice& data) {
    const char* src = data.data();
    size_t src_len = data.size();

    MutexLock lock(&blocks_mutex_);
    while (src_len > 0) {
      size_t avail;
      size_t offset = size_ % kBlockSize;

      if (offset != 0) {
        // There is some room in the last block.
        avail = kBlockSize - offset;
      } else {
        // No room in the last block; push new one.
        blocks_.push_back(new char[kBlockSize]);
        avail = kBlockSize;
      }

      if (avail > src_len) {
        avail = src_len;
      }
      memcpy(blocks_.back() + offset, src, avail);
      src_len -= avail;
      src += avail;
      size_ += avail;
    }

    return Status::OK();
  }

 private:
  // Private since only Unref() should be used to delete it.
  ~FileState() {
    Truncate();
  }

  // No copying allowed.
  FileState(const FileState&);
  void operator=(const FileState&);

  port::Mutex refs_mutex_;
  int refs_ GUARDED_BY(refs_mutex_);

  mutable port::Mutex blocks_mutex_;
  std::vector<char*> blocks_ GUARDED_BY(blocks_mutex_);
  uint64_t size_ GUARDED_BY(blocks_mutex_);

  enum { kBlockSize = 8 * 1024 };
};

class SequentialFileImpl : public SequentialFile {
 public:
  explicit SequentialFileImpl(FileState* file) : file_(file), pos_(0) {
    file_->Ref();
  }

  ~SequentialFileImpl() {
    file_->Unref();
  }

  virtual Status Read(size_t n, Slice* result, char* scratch) {
    Status s = file_->Read(pos_, n, result, scratch);
    if (s.ok()) {
      pos_ += result->size();
    }
    return s;
  }

  virtual Status Skip(uint64_t n) {
    if (pos_ > file_->Size()) {
      return Status::IOError("pos_ > file_->Size()");
    }
    const uint64_t available = file_->Size() - pos_;
    if (n > available) {
      n = available;
    }
    pos_ += n;
    return Status::OK();
  }

 private:
  FileState* file_;
  uint64_t pos_;
};

class RandomAccessFileImpl : public RandomAccessFile {
 public:
  explicit RandomAccessFileImpl(FileState* file) : file_(file) {
    file_->Ref();
  }

  ~RandomAccessFileImpl() {
    file_->Unref();
  }

  virtual Status Read(uint64_t offset, size_t n, Slice* result,
                      char* scratch) const {
    return file_->Read(offset, n, result, scratch);
  }

 private:
  FileState* file_;
};

class WritableFileImpl : public WritableFile {
 public:
  WritableFileImpl(FileState* file) : file_(file) {
    file_->Ref();
  }

  ~WritableFileImpl() {
    file_->Unref();
  }

  virtual Status Append(const Slice& data) {
    return file_->Append(data);
  }

  virtual Status Close() { return Status::OK(); }
  virtual Status Flush() { return Status::OK(); }
  virtual Status Sync() { return Status::OK(); }

 private:
  FileState* file_;
};

class NoOpLogger : public Logger {
 public:
  virtual void Logv(const char* format, va_list ap) { }
};

class InMemoryEnv : public EnvWrapper {
 public:
  explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }

  virtual ~InMemoryEnv() {
    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
      i->second->Unref();
    }
  }

  // Partial implementation of the Env interface.
  virtual Status NewSequentialFile(const std::string& fname,
                                   SequentialFile** result) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      *result = nullptr;
      return Status::IOError(fname, "File not found");
    }

    *result = new SequentialFileImpl(file_map_[fname]);
    return Status::OK();
  }

  virtual Status NewRandomAccessFile(const std::string& fname,
                                     RandomAccessFile** result) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      *result = nullptr;
      return Status::IOError(fname, "File not found");
    }

    *result = new RandomAccessFileImpl(file_map_[fname]);
    return Status::OK();
  }

  virtual Status NewWritableFile(const std::string& fname,
                                 WritableFile** result) {
    MutexLock lock(&mutex_);
    FileSystem::iterator it = file_map_.find(fname);

    FileState* file;
    if (it == file_map_.end()) {
      // File is not currently open.
      file = new FileState();
      file->Ref();
      file_map_[fname] = file;
    } else {
      file = it->second;
      file->Truncate();
    }

    *result = new WritableFileImpl(file);
    return Status::OK();
  }

  virtual Status NewAppendableFile(const std::string& fname,
                                   WritableFile** result) {
    MutexLock lock(&mutex_);
    FileState** sptr = &file_map_[fname];
    FileState* file = *sptr;
    if (file == nullptr) {
      file = new FileState();
      file->Ref();
    }
    *result = new WritableFileImpl(file);
    return Status::OK();
  }

  virtual bool FileExists(const std::string& fname) {
    MutexLock lock(&mutex_);
    return file_map_.find(fname) != file_map_.end();
  }

  virtual Status GetChildren(const std::string& dir,
                             std::vector<std::string>* result) {
    MutexLock lock(&mutex_);
    result->clear();

    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
      const std::string& filename = i->first;

      if (filename.size() >= dir.size() + 1 && filename[dir.size()] == '/' &&
          Slice(filename).starts_with(Slice(dir))) {
        result->push_back(filename.substr(dir.size() + 1));
      }
    }

    return Status::OK();
  }

  void DeleteFileInternal(const std::string& fname)
      EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
    if (file_map_.find(fname) == file_map_.end()) {
      return;
    }

    file_map_[fname]->Unref();
    file_map_.erase(fname);
  }

  virtual Status DeleteFile(const std::string& fname) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      return Status::IOError(fname, "File not found");
    }

    DeleteFileInternal(fname);
    return Status::OK();
  }

  virtual Status CreateDir(const std::string& dirname) {
    return Status::OK();
  }

  virtual Status DeleteDir(const std::string& dirname) {
    return Status::OK();
  }

  virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      return Status::IOError(fname, "File not found");
    }

    *file_size = file_map_[fname]->Size();
    return Status::OK();
  }

  virtual Status RenameFile(const std::string& src,
                            const std::string& target) {
    MutexLock lock(&mutex_);
    if (file_map_.find(src) == file_map_.end()) {
      return Status::IOError(src, "File not found");
    }

    DeleteFileInternal(target);
    file_map_[target] = file_map_[src];
    file_map_.erase(src);
    return Status::OK();
  }

  virtual Status LockFile(const std::string& fname, FileLock** lock) {
    *lock = new FileLock;
    return Status::OK();
  }

  virtual Status UnlockFile(FileLock* lock) {
    delete lock;
    return Status::OK();
  }

  virtual Status GetTestDirectory(std::string* path) {
    *path = "/test";
    return Status::OK();
  }

  virtual Status NewLogger(const std::string& fname, Logger** result) {
    *result = new NoOpLogger;
    return Status::OK();
  }

 private:
  // Map from filenames to FileState objects, representing a simple file system.
  typedef std::map<std::string, FileState*> FileSystem;
  port::Mutex mutex_;
  FileSystem file_map_ GUARDED_BY(mutex_);
};

}  // namespace

Env* NewMemEnv(Env* base_env) {
  return new InMemoryEnv(base_env);
}

}  // namespace leveldb
<commit_msg>Always copy bytes to scratch buffer when reading w/MemEnv.<commit_after>// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "helpers/memenv/memenv.h"

#include <string.h>

#include <limits>
#include <map>
#include <string>
#include <vector>

#include "leveldb/env.h"
#include "leveldb/status.h"
#include "port/port.h"
#include "port/thread_annotations.h"
#include "util/mutexlock.h"

namespace leveldb {

namespace {

class FileState {
 public:
  // FileStates are reference counted. The initial reference count is zero
  // and the caller must call Ref() at least once.
  FileState() : refs_(0), size_(0) {}

  // Increase the reference count.
  void Ref() {
    MutexLock lock(&refs_mutex_);
    ++refs_;
  }

  // Decrease the reference count. Delete if this is the last reference.
  void Unref() {
    bool do_delete = false;

    {
      MutexLock lock(&refs_mutex_);
      --refs_;
      assert(refs_ >= 0);
      if (refs_ <= 0) {
        do_delete = true;
      }
    }

    if (do_delete) {
      delete this;
    }
  }

  uint64_t Size() const {
    MutexLock lock(&blocks_mutex_);
    return size_;
  }

  void Truncate() {
    MutexLock lock(&blocks_mutex_);
    for (char*& block : blocks_) {
      delete[] block;
    }
    blocks_.clear();
    size_ = 0;
  }

  Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const {
    MutexLock lock(&blocks_mutex_);
    if (offset > size_) {
      return Status::IOError("Offset greater than file size.");
    }
    const uint64_t available = size_ - offset;
    if (n > available) {
      n = static_cast<size_t>(available);
    }
    if (n == 0) {
      *result = Slice();
      return Status::OK();
    }

    assert(offset / kBlockSize <= std::numeric_limits<size_t>::max());
    size_t block = static_cast<size_t>(offset / kBlockSize);
    size_t block_offset = offset % kBlockSize;
    size_t bytes_to_copy = n;
    char* dst = scratch;

    while (bytes_to_copy > 0) {
      size_t avail = kBlockSize - block_offset;
      if (avail > bytes_to_copy) {
        avail = bytes_to_copy;
      }
      memcpy(dst, blocks_[block] + block_offset, avail);

      bytes_to_copy -= avail;
      dst += avail;
      block++;
      block_offset = 0;
    }

    *result = Slice(scratch, n);
    return Status::OK();
  }

  Status Append(const Slice& data) {
    const char* src = data.data();
    size_t src_len = data.size();

    MutexLock lock(&blocks_mutex_);
    while (src_len > 0) {
      size_t avail;
      size_t offset = size_ % kBlockSize;

      if (offset != 0) {
        // There is some room in the last block.
        avail = kBlockSize - offset;
      } else {
        // No room in the last block; push new one.
        blocks_.push_back(new char[kBlockSize]);
        avail = kBlockSize;
      }

      if (avail > src_len) {
        avail = src_len;
      }
      memcpy(blocks_.back() + offset, src, avail);
      src_len -= avail;
      src += avail;
      size_ += avail;
    }

    return Status::OK();
  }

 private:
  // Private since only Unref() should be used to delete it.
  ~FileState() {
    Truncate();
  }

  // No copying allowed.
  FileState(const FileState&);
  void operator=(const FileState&);

  port::Mutex refs_mutex_;
  int refs_ GUARDED_BY(refs_mutex_);

  mutable port::Mutex blocks_mutex_;
  std::vector<char*> blocks_ GUARDED_BY(blocks_mutex_);
  uint64_t size_ GUARDED_BY(blocks_mutex_);

  enum { kBlockSize = 8 * 1024 };
};

class SequentialFileImpl : public SequentialFile {
 public:
  explicit SequentialFileImpl(FileState* file) : file_(file), pos_(0) {
    file_->Ref();
  }

  ~SequentialFileImpl() {
    file_->Unref();
  }

  virtual Status Read(size_t n, Slice* result, char* scratch) {
    Status s = file_->Read(pos_, n, result, scratch);
    if (s.ok()) {
      pos_ += result->size();
    }
    return s;
  }

  virtual Status Skip(uint64_t n) {
    if (pos_ > file_->Size()) {
      return Status::IOError("pos_ > file_->Size()");
    }
    const uint64_t available = file_->Size() - pos_;
    if (n > available) {
      n = available;
    }
    pos_ += n;
    return Status::OK();
  }

 private:
  FileState* file_;
  uint64_t pos_;
};

class RandomAccessFileImpl : public RandomAccessFile {
 public:
  explicit RandomAccessFileImpl(FileState* file) : file_(file) {
    file_->Ref();
  }

  ~RandomAccessFileImpl() {
    file_->Unref();
  }

  virtual Status Read(uint64_t offset, size_t n, Slice* result,
                      char* scratch) const {
    return file_->Read(offset, n, result, scratch);
  }

 private:
  FileState* file_;
};

class WritableFileImpl : public WritableFile {
 public:
  WritableFileImpl(FileState* file) : file_(file) {
    file_->Ref();
  }

  ~WritableFileImpl() {
    file_->Unref();
  }

  virtual Status Append(const Slice& data) {
    return file_->Append(data);
  }

  virtual Status Close() { return Status::OK(); }
  virtual Status Flush() { return Status::OK(); }
  virtual Status Sync() { return Status::OK(); }

 private:
  FileState* file_;
};

class NoOpLogger : public Logger {
 public:
  virtual void Logv(const char* format, va_list ap) { }
};

class InMemoryEnv : public EnvWrapper {
 public:
  explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }

  virtual ~InMemoryEnv() {
    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
      i->second->Unref();
    }
  }

  // Partial implementation of the Env interface.
  virtual Status NewSequentialFile(const std::string& fname,
                                   SequentialFile** result) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      *result = nullptr;
      return Status::IOError(fname, "File not found");
    }

    *result = new SequentialFileImpl(file_map_[fname]);
    return Status::OK();
  }

  virtual Status NewRandomAccessFile(const std::string& fname,
                                     RandomAccessFile** result) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      *result = nullptr;
      return Status::IOError(fname, "File not found");
    }

    *result = new RandomAccessFileImpl(file_map_[fname]);
    return Status::OK();
  }

  virtual Status NewWritableFile(const std::string& fname,
                                 WritableFile** result) {
    MutexLock lock(&mutex_);
    FileSystem::iterator it = file_map_.find(fname);

    FileState* file;
    if (it == file_map_.end()) {
      // File is not currently open.
      file = new FileState();
      file->Ref();
      file_map_[fname] = file;
    } else {
      file = it->second;
      file->Truncate();
    }

    *result = new WritableFileImpl(file);
    return Status::OK();
  }

  virtual Status NewAppendableFile(const std::string& fname,
                                   WritableFile** result) {
    MutexLock lock(&mutex_);
    FileState** sptr = &file_map_[fname];
    FileState* file = *sptr;
    if (file == nullptr) {
      file = new FileState();
      file->Ref();
    }
    *result = new WritableFileImpl(file);
    return Status::OK();
  }

  virtual bool FileExists(const std::string& fname) {
    MutexLock lock(&mutex_);
    return file_map_.find(fname) != file_map_.end();
  }

  virtual Status GetChildren(const std::string& dir,
                             std::vector<std::string>* result) {
    MutexLock lock(&mutex_);
    result->clear();

    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
      const std::string& filename = i->first;

      if (filename.size() >= dir.size() + 1 && filename[dir.size()] == '/' &&
          Slice(filename).starts_with(Slice(dir))) {
        result->push_back(filename.substr(dir.size() + 1));
      }
    }

    return Status::OK();
  }

  void DeleteFileInternal(const std::string& fname)
      EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
    if (file_map_.find(fname) == file_map_.end()) {
      return;
    }

    file_map_[fname]->Unref();
    file_map_.erase(fname);
  }

  virtual Status DeleteFile(const std::string& fname) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      return Status::IOError(fname, "File not found");
    }

    DeleteFileInternal(fname);
    return Status::OK();
  }

  virtual Status CreateDir(const std::string& dirname) {
    return Status::OK();
  }

  virtual Status DeleteDir(const std::string& dirname) {
    return Status::OK();
  }

  virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) {
    MutexLock lock(&mutex_);
    if (file_map_.find(fname) == file_map_.end()) {
      return Status::IOError(fname, "File not found");
    }

    *file_size = file_map_[fname]->Size();
    return Status::OK();
  }

  virtual Status RenameFile(const std::string& src,
                            const std::string& target) {
    MutexLock lock(&mutex_);
    if (file_map_.find(src) == file_map_.end()) {
      return Status::IOError(src, "File not found");
    }

    DeleteFileInternal(target);
    file_map_[target] = file_map_[src];
    file_map_.erase(src);
    return Status::OK();
  }

  virtual Status LockFile(const std::string& fname, FileLock** lock) {
    *lock = new FileLock;
    return Status::OK();
  }

  virtual Status UnlockFile(FileLock* lock) {
    delete lock;
    return Status::OK();
  }

  virtual Status GetTestDirectory(std::string* path) {
    *path = "/test";
    return Status::OK();
  }

  virtual Status NewLogger(const std::string& fname, Logger** result) {
    *result = new NoOpLogger;
    return Status::OK();
  }

 private:
  // Map from filenames to FileState objects, representing a simple file system.
  typedef std::map<std::string, FileState*> FileSystem;
  port::Mutex mutex_;
  FileSystem file_map_ GUARDED_BY(mutex_);
};

}  // namespace

Env* NewMemEnv(Env* base_env) {
  return new InMemoryEnv(base_env);
}

}  // namespace leveldb
<|endoftext|>