<commit_before>// Copyright (c) 2009 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 "chrome/renderer/notification_provider.h"

#include "base/task.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/render_thread.h"
#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNotificationPermissionCallback.h"

using WebKit::WebNotification;
using WebKit::WebNotificationPresenter;
using WebKit::WebNotificationPermissionCallback;
using WebKit::WebString;

NotificationProvider::NotificationProvider(RenderView* view)
    : view_(view) {
}

bool NotificationProvider::show(const WebNotification& notification) {
  int notification_id = manager_.RegisterNotification(notification);
  if (notification.isHTML())
    return ShowHTML(notification, notification_id);
  else
    return ShowText(notification, notification_id);
}

void NotificationProvider::cancel(const WebNotification& notification) {
  int id;
  bool id_found = manager_.GetId(notification, id);
  // Won't be found if the notification has already been closed by the user.
  if (id_found)
    Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id));
}

void NotificationProvider::objectDestroyed(
    const WebNotification& notification) {
  int id;
  bool id_found = manager_.GetId(notification, id);
  // Won't be found if the notification has already been closed by the user.
  if (id_found)
    manager_.UnregisterNotification(id);
}

WebNotificationPresenter::Permission NotificationProvider::checkPermission(
    const WebString& origin) {
  int permission;
  Send(new ViewHostMsg_CheckNotificationPermission(view_->routing_id(),
                                                   GURL(origin), &permission));
  return static_cast<WebNotificationPresenter::Permission>(permission);
}

void NotificationProvider::requestPermission(
    const WebString& origin, WebNotificationPermissionCallback* callback) {
  // We only request permission in response to a user gesture.
  if (!view_->webview()->mainFrame()->isProcessingUserGesture())
    return;

  int id = manager_.RegisterPermissionRequest(callback);

  Send(new ViewHostMsg_RequestNotificationPermission(view_->routing_id(),
                                                     GURL(origin), id));
}

bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
    IPC_MESSAGE_HANDLER(ViewMsg_PostDisplayToNotificationObject, OnDisplay);
    IPC_MESSAGE_HANDLER(ViewMsg_PostErrorToNotificationObject, OnError);
    IPC_MESSAGE_HANDLER(ViewMsg_PostCloseToNotificationObject, OnClose);
    IPC_MESSAGE_HANDLER(ViewMsg_PermissionRequestDone,
                        OnPermissionRequestComplete);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool NotificationProvider::ShowHTML(const WebNotification& notification,
                                    int id) {
  // Disallow HTML notifications from non-HTTP schemes.
  GURL url = notification.url();
  if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme))
    return false;

  DCHECK(notification.isHTML());
  return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
              GURL(view_->webview()->mainFrame()->url()).GetOrigin(),
              notification.url(), id));
}

bool NotificationProvider::ShowText(const WebNotification& notification,
                                    int id) {
  DCHECK(!notification.isHTML());
  return Send(new ViewHostMsg_ShowDesktopNotificationText(view_->routing_id(),
              GURL(view_->webview()->mainFrame()->url()).GetOrigin(),
              GURL(notification.icon()),
              notification.title(), notification.body(), id));
}

void NotificationProvider::OnDisplay(int id) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before it was actually displayed to the user.
  if (found)
    notification.dispatchDisplayEvent();
}

void NotificationProvider::OnError(int id, const WebString& message) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before the error occurred.
  if (found)
    notification.dispatchErrorEvent(message);
}

void NotificationProvider::OnClose(int id, bool by_user) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before the associated toast was closed by the user.
  if (found)
    notification.dispatchCloseEvent(by_user);
  manager_.UnregisterNotification(id);
}

void NotificationProvider::OnPermissionRequestComplete(int id) {
  WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
  DCHECK(callback);
  callback->permissionRequestComplete();
  manager_.OnPermissionRequestComplete(id);
}

bool NotificationProvider::Send(IPC::Message* message) {
  return RenderThread::current()->Send(message);
}
<commit_msg>Allow chrome-extension scheme in notification.<commit_after>// Copyright (c) 2009 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 "chrome/renderer/notification_provider.h"

#include "base/task.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/render_thread.h"
#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNotificationPermissionCallback.h"

using WebKit::WebNotification;
using WebKit::WebNotificationPresenter;
using WebKit::WebNotificationPermissionCallback;
using WebKit::WebString;

NotificationProvider::NotificationProvider(RenderView* view)
    : view_(view) {
}

bool NotificationProvider::show(const WebNotification& notification) {
  int notification_id = manager_.RegisterNotification(notification);
  if (notification.isHTML())
    return ShowHTML(notification, notification_id);
  else
    return ShowText(notification, notification_id);
}

void NotificationProvider::cancel(const WebNotification& notification) {
  int id;
  bool id_found = manager_.GetId(notification, id);
  // Won't be found if the notification has already been closed by the user.
  if (id_found)
    Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id));
}

void NotificationProvider::objectDestroyed(
    const WebNotification& notification) {
  int id;
  bool id_found = manager_.GetId(notification, id);
  // Won't be found if the notification has already been closed by the user.
  if (id_found)
    manager_.UnregisterNotification(id);
}

WebNotificationPresenter::Permission NotificationProvider::checkPermission(
    const WebString& origin) {
  int permission;
  Send(new ViewHostMsg_CheckNotificationPermission(view_->routing_id(),
                                                   GURL(origin), &permission));
  return static_cast<WebNotificationPresenter::Permission>(permission);
}

void NotificationProvider::requestPermission(
    const WebString& origin, WebNotificationPermissionCallback* callback) {
  // We only request permission in response to a user gesture.
  if (!view_->webview()->mainFrame()->isProcessingUserGesture())
    return;

  int id = manager_.RegisterPermissionRequest(callback);

  Send(new ViewHostMsg_RequestNotificationPermission(view_->routing_id(),
                                                     GURL(origin), id));
}

bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
    IPC_MESSAGE_HANDLER(ViewMsg_PostDisplayToNotificationObject, OnDisplay);
    IPC_MESSAGE_HANDLER(ViewMsg_PostErrorToNotificationObject, OnError);
    IPC_MESSAGE_HANDLER(ViewMsg_PostCloseToNotificationObject, OnClose);
    IPC_MESSAGE_HANDLER(ViewMsg_PermissionRequestDone,
                        OnPermissionRequestComplete);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool NotificationProvider::ShowHTML(const WebNotification& notification,
                                    int id) {
  // Disallow HTML notifications from non-HTTP schemes.
  GURL url = notification.url();
  if (!url.SchemeIs(chrome::kHttpScheme) &&
      !url.SchemeIs(chrome::kHttpsScheme) &&
      !url.SchemeIs(chrome::kExtensionScheme))
    return false;

  DCHECK(notification.isHTML());
  return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
              GURL(view_->webview()->mainFrame()->url()).GetOrigin(),
              notification.url(), id));
}

bool NotificationProvider::ShowText(const WebNotification& notification,
                                    int id) {
  DCHECK(!notification.isHTML());
  return Send(new ViewHostMsg_ShowDesktopNotificationText(view_->routing_id(),
              GURL(view_->webview()->mainFrame()->url()).GetOrigin(),
              GURL(notification.icon()),
              notification.title(), notification.body(), id));
}

void NotificationProvider::OnDisplay(int id) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before it was actually displayed to the user.
  if (found)
    notification.dispatchDisplayEvent();
}

void NotificationProvider::OnError(int id, const WebString& message) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before the error occurred.
  if (found)
    notification.dispatchErrorEvent(message);
}

void NotificationProvider::OnClose(int id, bool by_user) {
  WebNotification notification;
  bool found = manager_.GetNotification(id, &notification);
  // |found| may be false if the WebNotification went out of scope in
  // the page before the associated toast was closed by the user.
  if (found)
    notification.dispatchCloseEvent(by_user);
  manager_.UnregisterNotification(id);
}

void NotificationProvider::OnPermissionRequestComplete(int id) {
  WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
  DCHECK(callback);
  callback->permissionRequestComplete();
  manager_.OnPermissionRequestComplete(id);
}

bool NotificationProvider::Send(IPC::Message* message) {
  return RenderThread::current()->Send(message);
}
<|endoftext|>


<commit_before>// Filename: drawableRegion.cxx
// Created by:  drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "drawableRegion.h"

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::Destructor
//       Access: Public, Virtual
//  Description:
////////////////////////////////////////////////////////////////////
DrawableRegion::
~DrawableRegion() {
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_clear_active
//       Access: Published, Virtual
//  Description: Sets the clear-active flag for any bitplane.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_clear_active(int n, bool clear_active) {
  nassertv((n >= 0)&&(n < RTP_COUNT));
  _clear_active[n] = clear_active;
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_clear_active
//       Access: Published, Virtual
//  Description: Gets the clear-active flag for any bitplane.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
get_clear_active(int n) const {
  nassertr((n >= 0)&&(n < RTP_COUNT), false);
  return _clear_active[n];
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_clear_value
//       Access: Published, Virtual
//  Description: Sets the clear value for any bitplane.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_clear_value(int n, const Colorf &clear_value) {
  nassertv((n >= 0) && (n < RTP_COUNT));
  _clear_value[n] = clear_value;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_clear_value
//       Access: Published, Virtual
//  Description: Returns the clear value for any bitplane.
////////////////////////////////////////////////////////////////////
const Colorf &DrawableRegion::
get_clear_value(int n) const {
  static Colorf blank(0.5,0.5,0.5,0.0);
  nassertr((n >= 0) && (n < RTP_COUNT), blank);
  return _clear_value[n];
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::disable_clears
//       Access: Published, Virtual
//  Description: Disables both the color and depth clear.  See
//               set_clear_color_active and set_clear_depth_active.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
disable_clears() {
  for (int i = 0; i < RTP_COUNT; ++i) {
    _clear_active[i] = false;
  }
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::is_any_clear_active
//       Access: Published, Virtual
//  Description: Returns true if any of the clear types (so far there
//               are just color or depth) have been set active, or
//               false if none of them are active and there is no need
//               to clear.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
is_any_clear_active() const {
  for (int i = 0; i < RTP_COUNT; ++i) {
    if (get_clear_active(i)) {
      return true;
    }
  }
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_pixel_zoom
//       Access: Published, Virtual
//  Description: Sets the amount by which the pixels of the region are
//               scaled internally when filling the image interally.
//               Setting this number larger makes the pixels blockier,
//               but may make the rendering faster, particularly for
//               software renderers.  Setting this number to 2.0
//               reduces the number of pixels that have to be filled
//               by the renderer by a factor of 2.0.  It doesn't make
//               sense to set this lower than 1.0.
//
//               It is possible to set this on either individual
//               DisplayRegions or on overall GraphicsWindows, but you
//               will get better performance for setting it on the
//               window rather than its individual DisplayRegions.
//               Also, you may not set it on a DisplayRegion that
//               doesn't have both clear_color() and clear_depth()
//               enabled.
//
//               This property is only supported on renderers for
//               which it is particularly useful--currently, this is
//               the tinydisplay software renderer.  Other kinds of
//               renderers allow you to set this property, but ignore
//               it.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_pixel_zoom(float pixel_zoom) {
  _pixel_zoom = pixel_zoom;
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::supports_pixel_zoom
//       Access: Published, Virtual
//  Description: Returns true if a call to set_pixel_zoom() will be
//               respected, false if it will be ignored.  If this
//               returns false, then get_pixel_factor() will always
//               return 1.0, regardless of what value you specify for
//               set_pixel_zoom().
//
//               This may return false if the underlying renderer
//               doesn't support pixel zooming, or if you have called
//               this on a DisplayRegion that doesn't have both
//               set_clear_color() and set_clear_depth() enabled.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
supports_pixel_zoom() const {
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_renderbuffer_type
//       Access: Static, Published
//  Description: Returns the RenderBuffer::Type that corresponds
//               to a RenderTexturePlane.
////////////////////////////////////////////////////////////////////
int DrawableRegion::
get_renderbuffer_type(int rtp) {
  switch(rtp) {
  case RTP_stencil:        return RenderBuffer::T_stencil;
  case RTP_depth:          return RenderBuffer::T_depth;
  case RTP_depth_stencil:  return RenderBuffer::T_depth;
  case RTP_color:          return RenderBuffer::T_color;
  case RTP_aux_rgba_0:     return RenderBuffer::T_aux_rgba_0;
  case RTP_aux_rgba_1:     return RenderBuffer::T_aux_rgba_1;
  case RTP_aux_rgba_2:     return RenderBuffer::T_aux_rgba_2;
  case RTP_aux_rgba_3:     return RenderBuffer::T_aux_rgba_3;
  case RTP_aux_hrgba_0:    return RenderBuffer::T_aux_hrgba_0;
  case RTP_aux_hrgba_1:    return RenderBuffer::T_aux_hrgba_1;
  case RTP_aux_hrgba_2:    return RenderBuffer::T_aux_hrgba_2;
  case RTP_aux_hrgba_3:    return RenderBuffer::T_aux_hrgba_3;
  case RTP_aux_float_0:    return RenderBuffer::T_aux_float_0;
  case RTP_aux_float_1:    return RenderBuffer::T_aux_float_1;
  case RTP_aux_float_2:    return RenderBuffer::T_aux_float_2;
  case RTP_aux_float_3:    return RenderBuffer::T_aux_float_3;
  default:
    display_cat.error() << "DrawableRegion::get_renderbuffer_type unexpected case!\n";
    return 0;
  };
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::pixel_factor_changed
//       Access: Published, Virtual
//  Description: Called internally when the pixel factor changes.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
pixel_factor_changed() {
}
<commit_msg>fix comment<commit_after>// Filename: drawableRegion.cxx
// Created by:  drose (11Jul02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University.  All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license.  You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

#include "drawableRegion.h"

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::Destructor
//       Access: Public, Virtual
//  Description:
////////////////////////////////////////////////////////////////////
DrawableRegion::
~DrawableRegion() {
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_clear_active
//       Access: Published, Virtual
//  Description: Sets the clear-active flag for any bitplane.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_clear_active(int n, bool clear_active) {
  nassertv((n >= 0)&&(n < RTP_COUNT));
  _clear_active[n] = clear_active;
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_clear_active
//       Access: Published, Virtual
//  Description: Gets the clear-active flag for any bitplane.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
get_clear_active(int n) const {
  nassertr((n >= 0)&&(n < RTP_COUNT), false);
  return _clear_active[n];
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_clear_value
//       Access: Published, Virtual
//  Description: Sets the clear value for any bitplane.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_clear_value(int n, const Colorf &clear_value) {
  nassertv((n >= 0) && (n < RTP_COUNT));
  _clear_value[n] = clear_value;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_clear_value
//       Access: Published, Virtual
//  Description: Returns the clear value for any bitplane.
////////////////////////////////////////////////////////////////////
const Colorf &DrawableRegion::
get_clear_value(int n) const {
  static Colorf blank(0.5,0.5,0.5,0.0);
  nassertr((n >= 0) && (n < RTP_COUNT), blank);
  return _clear_value[n];
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::disable_clears
//       Access: Published, Virtual
//  Description: Disables both the color and depth clear.  See
//               set_clear_color_active and set_clear_depth_active.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
disable_clears() {
  for (int i = 0; i < RTP_COUNT; ++i) {
    _clear_active[i] = false;
  }
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::is_any_clear_active
//       Access: Published, Virtual
//  Description: Returns true if any of the clear types (so far there
//               are just color or depth) have been set active, or
//               false if none of them are active and there is no need
//               to clear.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
is_any_clear_active() const {
  for (int i = 0; i < RTP_COUNT; ++i) {
    if (get_clear_active(i)) {
      return true;
    }
  }
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::set_pixel_zoom
//       Access: Published, Virtual
//  Description: Sets the amount by which the pixels of the region are
//               scaled internally when filling the image interally.
//               Setting this number larger makes the pixels blockier,
//               but may make the rendering faster, particularly for
//               software renderers.  Setting this number to 2.0
//               reduces the number of pixels that have to be filled
//               by the renderer by a factor of 2.0.  It doesn't make
//               sense to set this lower than 1.0.
//
//               It is possible to set this on either individual
//               DisplayRegions or on overall GraphicsWindows, but you
//               will get better performance for setting it on the
//               window rather than its individual DisplayRegions.
//               Also, you may not set it on a DisplayRegion that
//               doesn't have both clear_color() and clear_depth()
//               enabled.
//
//               This property is only supported on renderers for
//               which it is particularly useful--currently, this is
//               the tinydisplay software renderer.  Other kinds of
//               renderers allow you to set this property, but ignore
//               it.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
set_pixel_zoom(float pixel_zoom) {
  _pixel_zoom = pixel_zoom;
  update_pixel_factor();
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::supports_pixel_zoom
//       Access: Published, Virtual
//  Description: Returns true if a call to set_pixel_zoom() will be
//               respected, false if it will be ignored.  If this
//               returns false, then get_pixel_factor() will always
//               return 1.0, regardless of what value you specify for
//               set_pixel_zoom().
//
//               This may return false if the underlying renderer
//               doesn't support pixel zooming, or if you have called
//               this on a DisplayRegion that doesn't have both
//               set_clear_color() and set_clear_depth() enabled.
////////////////////////////////////////////////////////////////////
bool DrawableRegion::
supports_pixel_zoom() const {
  return false;
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::get_renderbuffer_type
//       Access: Static, Published
//  Description: Returns the RenderBuffer::Type that corresponds
//               to a RenderTexturePlane.
////////////////////////////////////////////////////////////////////
int DrawableRegion::
get_renderbuffer_type(int rtp) {
  switch(rtp) {
  case RTP_stencil:        return RenderBuffer::T_stencil;
  case RTP_depth:          return RenderBuffer::T_depth;
  case RTP_depth_stencil:  return RenderBuffer::T_depth;
  case RTP_color:          return RenderBuffer::T_color;
  case RTP_aux_rgba_0:     return RenderBuffer::T_aux_rgba_0;
  case RTP_aux_rgba_1:     return RenderBuffer::T_aux_rgba_1;
  case RTP_aux_rgba_2:     return RenderBuffer::T_aux_rgba_2;
  case RTP_aux_rgba_3:     return RenderBuffer::T_aux_rgba_3;
  case RTP_aux_hrgba_0:    return RenderBuffer::T_aux_hrgba_0;
  case RTP_aux_hrgba_1:    return RenderBuffer::T_aux_hrgba_1;
  case RTP_aux_hrgba_2:    return RenderBuffer::T_aux_hrgba_2;
  case RTP_aux_hrgba_3:    return RenderBuffer::T_aux_hrgba_3;
  case RTP_aux_float_0:    return RenderBuffer::T_aux_float_0;
  case RTP_aux_float_1:    return RenderBuffer::T_aux_float_1;
  case RTP_aux_float_2:    return RenderBuffer::T_aux_float_2;
  case RTP_aux_float_3:    return RenderBuffer::T_aux_float_3;
  default:
    display_cat.error() << "DrawableRegion::get_renderbuffer_type unexpected case!\n";
    return 0;
  };
}

////////////////////////////////////////////////////////////////////
//     Function: DrawableRegion::pixel_factor_changed
//       Access: Protected, Virtual
//  Description: Called internally when the pixel factor changes.
////////////////////////////////////////////////////////////////////
void DrawableRegion::
pixel_factor_changed() {
}
<|endoftext|>


<commit_before>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * See the LICENSE.PROPRIETARY file in the top-level directory for licensing information.
 */

#include "alternator/server.hh"
#include "log.hh"
#include <seastar/http/function_handlers.hh>
#include <seastar/json/json_elements.hh>
#include <seastarx.hh>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "error.hh"

static logging::logger slogger("alternator-server");

using namespace httpd;

namespace alternator {

static constexpr auto TARGET = "X-Amz-Target";

inline std::vector<sstring> split(const sstring& text, const char* separator) {
    if (text == "") {
        return std::vector<sstring>();
    }
    std::vector<sstring> tokens;
    return boost::split(tokens, text, boost::is_any_of(separator));
}

// DynamoDB HTTP error responses are structured as follows
// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html
// Our handlers throw an exception to report an error. If the exception
// is of type alternator::api_error, it unwrapped and properly reported to
// the user directly. Other exceptions are unexpected, and reported as
// Internal Server Error.
class api_handler : public handler_base {
public:
    api_handler(const future_json_function& _handle) : _f_handle(
         [_handle](std::unique_ptr<request> req, std::unique_ptr<reply> rep) {
         return seastar::futurize_apply(_handle, std::move(req)).then_wrapped([rep = std::move(rep)](future<json::json_return_type> resf) mutable {
             if (resf.failed()) {
                 // Exceptions of type api_error are wrapped as JSON and
                 // returned to the client as expected. Other types of
                 // exceptions are unexpected, and returned to the user
                 // as an internal server error:
                 api_error ret;
                 try {
                     resf.get();
                 } catch (api_error &ae) {
                     ret = ae;
                 } catch (...) {
                     ret = api_error(
                             "Internal Server Error",
                             format("Internal server error: {}", std::current_exception()),
                             reply::status_type::internal_server_error);
                 }
                 // FIXME: what is this version number?
                 rep->_content += "{\"__type\":\"com.amazonaws.dynamodb.v20120810#" + ret._type + "\"," +
                         "\"message\":\"" + ret._msg + "\"}";
                 rep->_status = ret._http_code;
                 slogger.trace("api_handler error case: {}", rep->_content);
                 return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
             }
             slogger.trace("api_handler success case");
             auto res = resf.get0();
             if (res._body_writer) {
                 rep->write_body("json", std::move(res._body_writer));
             } else {
                 rep->_content += res._res;
             }
             return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
         });
    }), _type("json") { }

    api_handler(const api_handler&) = default;
    future<std::unique_ptr<reply>> handle(const sstring& path,
            std::unique_ptr<request> req, std::unique_ptr<reply> rep) override {
        return _f_handle(std::move(req), std::move(rep)).then(
                [this](std::unique_ptr<reply> rep) {
                    rep->done(_type);
                    return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
                });
    }

protected:
    future_handler_function _f_handle;
    sstring _type;
};

void server::set_routes(routes& r) {
    using alternator_callback = std::function<future<json::json_return_type>(executor&, std::unique_ptr<request>)>;
    std::unordered_map<std::string, alternator_callback> routes{
        {"CreateTable", [] (executor& e, std::unique_ptr<request> req) { return e.create_table(req->content); }},
        {"DescribeTable", [] (executor& e, std::unique_ptr<request> req) { return e.describe_table(req->content); }},
        {"DeleteTable", [] (executor& e, std::unique_ptr<request> req) { return e.delete_table(req->content); }},
        {"PutItem", [] (executor& e, std::unique_ptr<request> req) { return e.put_item(req->content); }},
        {"UpdateItem", [] (executor& e, std::unique_ptr<request> req) { return e.update_item(req->content); }},
        {"GetItem", [] (executor& e, std::unique_ptr<request> req) { return e.get_item(req->content); }},
        {"DeleteItem", [] (executor& e, std::unique_ptr<request> req) { return e.delete_item(req->content); }},
        {"ListTables", [] (executor& e, std::unique_ptr<request> req) { return e.list_tables(req->content); }},
        {"Scan", [] (executor& e, std::unique_ptr<request> req) { return e.scan(req->content); }},
        {"DescribeEndpoints", [] (executor& e, std::unique_ptr<request> req) { return e.describe_endpoints(req->content, req->get_header("Host")); }},
        {"BatchWriteItem", [] (executor& e, std::unique_ptr<request> req) { return e.batch_write_item(req->content); }},
        {"BatchGetItem", [] (executor& e, std::unique_ptr<request> req) { return e.batch_get_item(req->content); }},
        {"Query", [] (executor& e, std::unique_ptr<request> req) { return e.query(req->content); }},
    };

    api_handler* handler = new api_handler([this, routes = std::move(routes)](std::unique_ptr<request> req) -> future<json::json_return_type> {
        _executor.local()._stats.total_operations++;
        slogger.trace("Raw request: {} ({})", req->content, req->content_length);
        sstring target = req->get_header(TARGET);
        std::vector<sstring> split_target = split(target, ".");
        //NOTICE(sarna): Target consists of Dynamo API version folllowed by a dot '.' and operation type (e.g. CreateTable)
        sstring op = split_target.empty() ? sstring() : split_target.back();

        slogger.trace("Request type: {}", op);
        auto callback_it = routes.find(op);
        if (callback_it == routes.end()) {
            _executor.local()._stats.unsupported_operations++;
            throw api_error("UnknownOperationException",
                    format("Unsupported operation {}", op));
        }
        return callback_it->second(_executor.local(), std::move(req));
    });

    r.add(operation_type::POST, url("/"), handler);
}

future<> server::init(uint16_t port) {
    return _executor.invoke_on_all([] (executor& e) {
        return e.start();
    }).then([this] {
        return _control.start();
    }).then([this] {
        return _control.set_routes(std::bind(&server::set_routes, this, std::placeholders::_1));
    }).then([this, port] {
        return _control.listen(port);
    }).then([port] {
        slogger.info("Alternator HTTP server listening on port {}", port);
    }).handle_exception([port] (std::exception_ptr e) {
        slogger.warn("Failed to set up Alternator HTTP server on port {}: {}", port, e);
    });
}

}

<commit_msg>alternator: add handling rapidjson errors in the server<commit_after>/*
 * Copyright 2019 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * See the LICENSE.PROPRIETARY file in the top-level directory for licensing information.
 */

#include "alternator/server.hh"
#include "log.hh"
#include <seastar/http/function_handlers.hh>
#include <seastar/json/json_elements.hh>
#include <seastarx.hh>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "error.hh"
#include "rjson.hh"

static logging::logger slogger("alternator-server");

using namespace httpd;

namespace alternator {

static constexpr auto TARGET = "X-Amz-Target";

inline std::vector<sstring> split(const sstring& text, const char* separator) {
    if (text == "") {
        return std::vector<sstring>();
    }
    std::vector<sstring> tokens;
    return boost::split(tokens, text, boost::is_any_of(separator));
}

// DynamoDB HTTP error responses are structured as follows
// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html
// Our handlers throw an exception to report an error. If the exception
// is of type alternator::api_error, it unwrapped and properly reported to
// the user directly. Other exceptions are unexpected, and reported as
// Internal Server Error.
class api_handler : public handler_base {
public:
    api_handler(const future_json_function& _handle) : _f_handle(
         [_handle](std::unique_ptr<request> req, std::unique_ptr<reply> rep) {
         return seastar::futurize_apply(_handle, std::move(req)).then_wrapped([rep = std::move(rep)](future<json::json_return_type> resf) mutable {
             if (resf.failed()) {
                 // Exceptions of type api_error are wrapped as JSON and
                 // returned to the client as expected. Other types of
                 // exceptions are unexpected, and returned to the user
                 // as an internal server error:
                 api_error ret;
                 try {
                     resf.get();
                 } catch (api_error &ae) {
                     ret = ae;
                 } catch (rjson::error & re) {
                     ret = api_error("ValidationException", re.what());
                 } catch (...) {
                     ret = api_error(
                             "Internal Server Error",
                             format("Internal server error: {}", std::current_exception()),
                             reply::status_type::internal_server_error);
                 }
                 // FIXME: what is this version number?
                 rep->_content += "{\"__type\":\"com.amazonaws.dynamodb.v20120810#" + ret._type + "\"," +
                         "\"message\":\"" + ret._msg + "\"}";
                 rep->_status = ret._http_code;
                 slogger.trace("api_handler error case: {}", rep->_content);
                 return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
             }
             slogger.trace("api_handler success case");
             auto res = resf.get0();
             if (res._body_writer) {
                 rep->write_body("json", std::move(res._body_writer));
             } else {
                 rep->_content += res._res;
             }
             return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
         });
    }), _type("json") { }

    api_handler(const api_handler&) = default;
    future<std::unique_ptr<reply>> handle(const sstring& path,
            std::unique_ptr<request> req, std::unique_ptr<reply> rep) override {
        return _f_handle(std::move(req), std::move(rep)).then(
                [this](std::unique_ptr<reply> rep) {
                    rep->done(_type);
                    return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
                });
    }

protected:
    future_handler_function _f_handle;
    sstring _type;
};

void server::set_routes(routes& r) {
    using alternator_callback = std::function<future<json::json_return_type>(executor&, std::unique_ptr<request>)>;
    std::unordered_map<std::string, alternator_callback> routes{
        {"CreateTable", [] (executor& e, std::unique_ptr<request> req) { return e.create_table(req->content); }},
        {"DescribeTable", [] (executor& e, std::unique_ptr<request> req) { return e.describe_table(req->content); }},
        {"DeleteTable", [] (executor& e, std::unique_ptr<request> req) { return e.delete_table(req->content); }},
        {"PutItem", [] (executor& e, std::unique_ptr<request> req) { return e.put_item(req->content); }},
        {"UpdateItem", [] (executor& e, std::unique_ptr<request> req) { return e.update_item(req->content); }},
        {"GetItem", [] (executor& e, std::unique_ptr<request> req) { return e.get_item(req->content); }},
        {"DeleteItem", [] (executor& e, std::unique_ptr<request> req) { return e.delete_item(req->content); }},
        {"ListTables", [] (executor& e, std::unique_ptr<request> req) { return e.list_tables(req->content); }},
        {"Scan", [] (executor& e, std::unique_ptr<request> req) { return e.scan(req->content); }},
        {"DescribeEndpoints", [] (executor& e, std::unique_ptr<request> req) { return e.describe_endpoints(req->content, req->get_header("Host")); }},
        {"BatchWriteItem", [] (executor& e, std::unique_ptr<request> req) { return e.batch_write_item(req->content); }},
        {"BatchGetItem", [] (executor& e, std::unique_ptr<request> req) { return e.batch_get_item(req->content); }},
        {"Query", [] (executor& e, std::unique_ptr<request> req) { return e.query(req->content); }},
    };

    api_handler* handler = new api_handler([this, routes = std::move(routes)](std::unique_ptr<request> req) -> future<json::json_return_type> {
        _executor.local()._stats.total_operations++;
        slogger.trace("Raw request: {} ({})", req->content, req->content_length);
        sstring target = req->get_header(TARGET);
        std::vector<sstring> split_target = split(target, ".");
        //NOTICE(sarna): Target consists of Dynamo API version folllowed by a dot '.' and operation type (e.g. CreateTable)
        sstring op = split_target.empty() ? sstring() : split_target.back();

        slogger.trace("Request type: {}", op);
        auto callback_it = routes.find(op);
        if (callback_it == routes.end()) {
            _executor.local()._stats.unsupported_operations++;
            throw api_error("UnknownOperationException",
                    format("Unsupported operation {}", op));
        }
        return callback_it->second(_executor.local(), std::move(req));
    });

    r.add(operation_type::POST, url("/"), handler);
}

future<> server::init(uint16_t port) {
    return _executor.invoke_on_all([] (executor& e) {
        return e.start();
    }).then([this] {
        return _control.start();
    }).then([this] {
        return _control.set_routes(std::bind(&server::set_routes, this, std::placeholders::_1));
    }).then([this, port] {
        return _control.listen(port);
    }).then([port] {
        slogger.info("Alternator HTTP server listening on port {}", port);
    }).handle_exception([port] (std::exception_ptr e) {
        slogger.warn("Failed to set up Alternator HTTP server on port {}: {}", port, e);
    });
}

}

<|endoftext|>


<commit_before>/******************************************************************/
/* drawpanel.cpp - fonctions des classes du type WinEDA_DrawPanel */
/******************************************************************/

#ifdef __GNUG__
#pragma implementation
#endif

#include "fctsys.h"
#include "common.h"

/* defines locaux */
#define CURSOR_SIZE 12  /* taille de la croix du curseur PCB */

/*******************************************************/
/* Class BASE_SCREEN: classe de gestion d'un affichage */
/*******************************************************/
BASE_SCREEN::BASE_SCREEN( int idscreen, KICAD_T aType ) :
    EDA_BaseStruct( aType )
{
    EEDrawList = NULL;   /* Schematic items list */
    m_Type     = idscreen;
    m_ZoomList = NULL;
    m_GridList = NULL;
    m_UndoList = NULL;
    m_RedoList = NULL;
    m_UndoRedoCountMax = 1;
    m_FirstRedraw = TRUE;
    InitDatas();
}

/******************************/
BASE_SCREEN::~BASE_SCREEN()
/******************************/
{
    if( m_ZoomList )
        free( m_ZoomList );
    if( m_GridList )
        free( m_GridList );
    ClearUndoRedoList();
}

/*******************************/
void BASE_SCREEN::InitDatas()
/*******************************/
{
    m_SheetNumber = m_NumberOfSheet = 1;    /* gestion hierarchie: Root: SheetNumber = 1 */
    m_Zoom            = 32;
    m_Grid            = wxSize( 50, 50 );   /* pas de la grille */
    m_UserGrid        = g_UserGrid;         /* pas de la grille "utilisateur" */
    m_UserGridIsON    = FALSE;
    m_UserGridUnit    = g_UserGrid_Unit;
    m_Diviseur_Grille = 1;
    m_Center          = TRUE;

    /* offsets pour tracer le circuit sur l'ecran */
    switch( m_Type ) // Init taille sheet par defaut
    {
    case SCHEMATIC_FRAME:
        m_Center = FALSE;
        m_CurrentSheet = &g_Sheet_A4;
        break;

    default:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        m_CurrentSheet = &g_Sheet_A4;
        break;

    case GERBER_FRAME:
        m_CurrentSheet = &g_Sheet_GERBER;
        break;
    }

    if( m_Center )
    {
        m_Curseur.x = m_Curseur.y = 0;
        m_DrawOrg.x = -ReturnPageSize().x / 2;
        m_DrawOrg.y = -ReturnPageSize().y / 2;
    }
    else
    {
        m_DrawOrg.x = m_DrawOrg.y = 0;
        m_Curseur.x = ReturnPageSize().x / 2;
        m_Curseur.y = ReturnPageSize().y / 2;
    }

    // DrawOrg est rendu multiple du zoom min :
    m_DrawOrg.x -= m_DrawOrg.x % 256;
    m_DrawOrg.y -= m_DrawOrg.y % 256;

    m_O_Curseur = m_Curseur;

    SetCurItem( NULL );

    /* indicateurs divers */
    m_FlagRefreshReq = 0;               /* indique que l'ecran doit redessine */
    m_FlagModified   = 0;               // indique modif du PCB,utilise pour eviter une sortie sans sauvegarde
    m_FlagSave = 1;                     // indique sauvegarde auto faite
}

/******************************************************************/
wxPoint BASE_SCREEN::CursorRealPosition( const wxPoint& ScreenPos )
/******************************************************************/
{
    wxPoint curpos;

    curpos.x = ScreenPos.x* GetZoom();

    curpos.y = ScreenPos.y* GetZoom();

    curpos.x += m_DrawOrg.x;
    curpos.y += m_DrawOrg.y;

    return curpos;
}

/***************************************/
int BASE_SCREEN::GetInternalUnits()
/***************************************/
{
    switch( m_Type )
    {
    default:
    case SCHEMATIC_FRAME:
        return EESCHEMA_INTERNAL_UNIT;
        break;

    case GERBER_FRAME:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        return PCB_INTERNAL_UNIT;
    }
}

/*****************************************/
wxSize BASE_SCREEN::ReturnPageSize()
/*****************************************/

/* Retourne en unites internes la taille de la feuille de dessin
 *  (la taille de la feuille est connue en 1/1000 ")
 */
{
    wxSize PageSize;

    switch( m_Type )
    {
    default:
    case SCHEMATIC_FRAME:
        PageSize = m_CurrentSheet->m_Size;
        break;

    case GERBER_FRAME:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        PageSize.x = m_CurrentSheet->m_Size.x * (PCB_INTERNAL_UNIT / 1000);
        PageSize.y = m_CurrentSheet->m_Size.y * (PCB_INTERNAL_UNIT / 1000);
        break;
    }

    return PageSize;
}

/********************************************/
void BASE_SCREEN::SetZoomList( int* zoomlist )
/********************************************/

/* init liste des zoom (NULL terminated)
 */
{
    int ii, nbitems, * zoom;

    // Decompte des items
    for( nbitems = 1, zoom = zoomlist;  ; zoom++, nbitems++ )
    {
        if( *zoom == 0 )
            break;
    }

    // Init liste
    if( m_ZoomList )
        free( m_ZoomList );
    m_ZoomList = (int*) MyZMalloc( nbitems * sizeof( int) );

    for( ii = 0, zoom = zoomlist; ii < nbitems; zoom++, ii++ )
    {
        m_ZoomList[ii] = *zoom;
    }
}

/***********************************/
void BASE_SCREEN::SetFirstZoom()
/***********************************/
/* ajuste le coeff de zoom a 1*/
{
    m_Zoom = 1;
}

/****************************/
int BASE_SCREEN::GetZoom()
/****************************/
/* retourne le coeff de zoom */
{
    return m_Zoom;
}

/***********************************/
void BASE_SCREEN::SetZoom( int coeff )
/***********************************/
/* ajuste le coeff de zoom a coeff */
{
    m_Zoom = coeff;
    if( m_Zoom < 1 )
        m_Zoom = 1;
}

/********************************/
void BASE_SCREEN::SetNextZoom()
/********************************/

/* Selectionne le prochain coeff de zoom
 */
{
    m_Zoom *= 2;

    if( m_ZoomList == NULL )
        return;

    int ii, zoom_max = 512;
    for( ii = 0; m_ZoomList[ii] != 0; ii++ )
        zoom_max = m_ZoomList[ii];

    if( m_Zoom > zoom_max )
        m_Zoom = zoom_max;
}

/*************************************/
void BASE_SCREEN::SetPreviousZoom()
/*************************************/

/* Selectionne le precedent coeff de zoom
 */
{
    m_Zoom /= 2;
    if( m_Zoom < 1 )
        m_Zoom = 1;
}

/**********************************/
void BASE_SCREEN::SetLastZoom()
/**********************************/

/* ajuste le coeff de zoom au max
 */
{
    if( m_ZoomList == NULL )
        return;
    int ii;
    for( ii = 0; m_ZoomList[ii] != 0; ii++ )
        m_Zoom = m_ZoomList[ii];
}

/********************************************/
void BASE_SCREEN::SetGridList( wxSize* gridlist )
/********************************************/

/* init liste des zoom (NULL terminated)
 */
{
    int     ii, nbitems;
    wxSize* grid;

    // Decompte des items
    for( nbitems = 0, grid = gridlist;  ; grid++, nbitems++ )
    {
        if( (grid->x <= 0) || (grid->y <= 0) )
            break;
    }

    // Init liste
    if( m_GridList )
        free( m_GridList );
    m_GridList = (wxSize*) MyZMalloc( nbitems * sizeof(wxSize) );

    for( ii = 0, grid = gridlist; ii < nbitems; grid++, ii++ )
    {
        m_GridList[ii] = *grid;
    }
}

/**********************************************/
void BASE_SCREEN::SetGrid( const wxSize& size )
/**********************************************/
{
    if( m_GridList == NULL )
        return;

    if( (size.x <= 0) || (size.y <= 0) )
    {
        m_UserGrid     = g_UserGrid;
        m_UserGridIsON = TRUE;
    }
    else
    {
        m_Grid = size;
        m_UserGridIsON = FALSE;
    }
}

/*********************************/
wxSize BASE_SCREEN::GetGrid()
/*********************************/
{
    wxSize grid = m_Grid;
    double xx, scale;

    if( m_GridList == NULL )
        return wxSize( 1, 1 );

    if( m_UserGridIsON || m_Grid.x < 0 || m_Grid.y < 0 )
    {
        if( m_UserGridUnit == INCHES )
            scale = 10000;
        else
            scale = 10000 / 25.4;
        xx     = m_UserGrid.x * scale;
        grid.x = (int) (xx + 0.5);
        xx     = m_UserGrid.y * scale;
        grid.y = (int) (xx + 0.5);
    }
    return grid;
}

/*********************************/
void BASE_SCREEN::SetNextGrid()
/*********************************/

/* Selectionne la prochaine grille
 */
{
    int ii;

    if( m_GridList == NULL )
        return;

    for( ii = 0; ; ii++ )
    {
        if( m_GridList[ii].x <= 0 )
            break;
        if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
            break;
    }

    if( (m_GridList[ii].x > 0) && (ii > 0) )
        m_Grid = m_GridList[ii - 1];
}

/*************************************/
void BASE_SCREEN::SetPreviousGrid()
/*************************************/

/* Selectionne le precedent coeff de grille
 */
{
    int ii;

    if( m_GridList == NULL )
        return;

    for( ii = 0; ; ii++ )
    {
        if( m_GridList[ii].x <= 0 )
            break;
        if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
            break;
    }

    if( (m_GridList[ii].x > 0) && (m_GridList[ii + 1].x > 0) )
        m_Grid = m_GridList[ii + 1];
}

/**********************************/
void BASE_SCREEN::SetFirstGrid()
/**********************************/

/* ajuste le coeff de grille a 1
 */
{
    if( m_GridList == NULL )
        return;

    int ii = 0;
    while( m_GridList[ii].x > 0 )
        ii++;

    m_Grid = m_GridList[ii - 1];
}

/**********************************/
void BASE_SCREEN::SetLastGrid()
/**********************************/

/* ajuste le coeff de grille au max
 */
{
    if( m_GridList == NULL )
        return;
    m_Grid = m_GridList[0];
}

/*****************************************/
void BASE_SCREEN::ClearUndoRedoList()
/*****************************************/

/* free the undo and the redo lists
 */
{
    EDA_BaseStruct* nextitem;

    while( m_UndoList )
    {
        nextitem = m_UndoList->Pnext;
        delete m_UndoList;
        m_UndoList = nextitem;
    }

    while( m_RedoList )
    {
        nextitem = m_RedoList->Pnext;
        delete m_RedoList;
        m_RedoList = nextitem;
    }
}

/***********************************************************/
void BASE_SCREEN::AddItemToUndoList( EDA_BaseStruct* newitem )
/************************************************************/

/* Put newitem in head of undo list
 *  Deletes olds items if > count max.
 */
{
    int             ii;
    EDA_BaseStruct* item, * nextitem;

    if( newitem == NULL )
        return;

    newitem->Pnext = m_UndoList;
    m_UndoList = newitem;

    /* Free first items, if count max reached */
    for( ii = 0, item = m_UndoList; ii < m_UndoRedoCountMax; ii++ )
    {
        if( item->Pnext == NULL )
            return;
        item = item->Pnext;
    }

    if( item == NULL )
        return;

    nextitem    = item->Pnext;
    item->Pnext = NULL; // Set end of chain

    // Delete the extra  items
    for( item = nextitem; item != NULL; item = nextitem )
    {
        nextitem = item->Pnext;
        delete item;
    }
}

/***********************************************************/
void BASE_SCREEN::AddItemToRedoList( EDA_BaseStruct* newitem )
/***********************************************************/
{
    int             ii;
    EDA_BaseStruct* item, * nextitem;

    if( newitem == NULL )
        return;

    newitem->Pnext = m_RedoList;
    m_RedoList = newitem;
    /* Free first items, if count max reached */
    for( ii = 0, item = m_RedoList; ii < m_UndoRedoCountMax; ii++ )
    {
        if( item->Pnext == NULL )
            break;
        item = item->Pnext;
    }

    if( item == NULL )
        return;

    nextitem    = item->Pnext;
    item->Pnext = NULL; // Set end of chain

    // Delete the extra items
    for( item = nextitem; item != NULL; item = nextitem )
    {
        nextitem = item->Pnext;
        delete item;
    }
}

/*****************************************************/
EDA_BaseStruct* BASE_SCREEN::GetItemFromUndoList()
/*****************************************************/
{
    EDA_BaseStruct* item = m_UndoList;

    if( item )
        m_UndoList = item->Pnext;
    return item;
}

/******************************************************/
EDA_BaseStruct* BASE_SCREEN::GetItemFromRedoList()
/******************************************************/
{
    EDA_BaseStruct* item = m_RedoList;

    if( item )
        m_RedoList = item->Pnext;
    return item;
}

void BASE_SCREEN::SetCurItem( EDA_BaseStruct* aCurItem )
{

#if defined(DEBUG)
    printf( "SetCurItem(%p)\n", aCurItem );
#endif

    m_CurrentItem = aCurItem;
}
<commit_msg>comment out debug printf<commit_after>/******************************************************************/
/* drawpanel.cpp - fonctions des classes du type WinEDA_DrawPanel */
/******************************************************************/

#ifdef __GNUG__
#pragma implementation
#endif

#include "fctsys.h"
#include "common.h"

/* defines locaux */
#define CURSOR_SIZE 12  /* taille de la croix du curseur PCB */

/*******************************************************/
/* Class BASE_SCREEN: classe de gestion d'un affichage */
/*******************************************************/
BASE_SCREEN::BASE_SCREEN( int idscreen, KICAD_T aType ) :
    EDA_BaseStruct( aType )
{
    EEDrawList = NULL;   /* Schematic items list */
    m_Type     = idscreen;
    m_ZoomList = NULL;
    m_GridList = NULL;
    m_UndoList = NULL;
    m_RedoList = NULL;
    m_UndoRedoCountMax = 1;
    m_FirstRedraw = TRUE;
    InitDatas();
}

/******************************/
BASE_SCREEN::~BASE_SCREEN()
/******************************/
{
    if( m_ZoomList )
        free( m_ZoomList );
    if( m_GridList )
        free( m_GridList );
    ClearUndoRedoList();
}

/*******************************/
void BASE_SCREEN::InitDatas()
/*******************************/
{
    m_SheetNumber = m_NumberOfSheet = 1;    /* gestion hierarchie: Root: SheetNumber = 1 */
    m_Zoom            = 32;
    m_Grid            = wxSize( 50, 50 );   /* pas de la grille */
    m_UserGrid        = g_UserGrid;         /* pas de la grille "utilisateur" */
    m_UserGridIsON    = FALSE;
    m_UserGridUnit    = g_UserGrid_Unit;
    m_Diviseur_Grille = 1;
    m_Center          = TRUE;

    /* offsets pour tracer le circuit sur l'ecran */
    switch( m_Type ) // Init taille sheet par defaut
    {
    case SCHEMATIC_FRAME:
        m_Center = FALSE;
        m_CurrentSheet = &g_Sheet_A4;
        break;

    default:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        m_CurrentSheet = &g_Sheet_A4;
        break;

    case GERBER_FRAME:
        m_CurrentSheet = &g_Sheet_GERBER;
        break;
    }

    if( m_Center )
    {
        m_Curseur.x = m_Curseur.y = 0;
        m_DrawOrg.x = -ReturnPageSize().x / 2;
        m_DrawOrg.y = -ReturnPageSize().y / 2;
    }
    else
    {
        m_DrawOrg.x = m_DrawOrg.y = 0;
        m_Curseur.x = ReturnPageSize().x / 2;
        m_Curseur.y = ReturnPageSize().y / 2;
    }

    // DrawOrg est rendu multiple du zoom min :
    m_DrawOrg.x -= m_DrawOrg.x % 256;
    m_DrawOrg.y -= m_DrawOrg.y % 256;

    m_O_Curseur = m_Curseur;

    SetCurItem( NULL );

    /* indicateurs divers */
    m_FlagRefreshReq = 0;               /* indique que l'ecran doit redessine */
    m_FlagModified   = 0;               // indique modif du PCB,utilise pour eviter une sortie sans sauvegarde
    m_FlagSave = 1;                     // indique sauvegarde auto faite
}

/******************************************************************/
wxPoint BASE_SCREEN::CursorRealPosition( const wxPoint& ScreenPos )
/******************************************************************/
{
    wxPoint curpos;

    curpos.x = ScreenPos.x* GetZoom();

    curpos.y = ScreenPos.y* GetZoom();

    curpos.x += m_DrawOrg.x;
    curpos.y += m_DrawOrg.y;

    return curpos;
}

/***************************************/
int BASE_SCREEN::GetInternalUnits()
/***************************************/
{
    switch( m_Type )
    {
    default:
    case SCHEMATIC_FRAME:
        return EESCHEMA_INTERNAL_UNIT;
        break;

    case GERBER_FRAME:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        return PCB_INTERNAL_UNIT;
    }
}

/*****************************************/
wxSize BASE_SCREEN::ReturnPageSize()
/*****************************************/

/* Retourne en unites internes la taille de la feuille de dessin
 *  (la taille de la feuille est connue en 1/1000 ")
 */
{
    wxSize PageSize;

    switch( m_Type )
    {
    default:
    case SCHEMATIC_FRAME:
        PageSize = m_CurrentSheet->m_Size;
        break;

    case GERBER_FRAME:
    case CVPCB_DISPLAY_FRAME:
    case MODULE_EDITOR_FRAME:
    case PCB_FRAME:
        PageSize.x = m_CurrentSheet->m_Size.x * (PCB_INTERNAL_UNIT / 1000);
        PageSize.y = m_CurrentSheet->m_Size.y * (PCB_INTERNAL_UNIT / 1000);
        break;
    }

    return PageSize;
}

/********************************************/
void BASE_SCREEN::SetZoomList( int* zoomlist )
/********************************************/

/* init liste des zoom (NULL terminated)
 */
{
    int ii, nbitems, * zoom;

    // Decompte des items
    for( nbitems = 1, zoom = zoomlist;  ; zoom++, nbitems++ )
    {
        if( *zoom == 0 )
            break;
    }

    // Init liste
    if( m_ZoomList )
        free( m_ZoomList );
    m_ZoomList = (int*) MyZMalloc( nbitems * sizeof( int) );

    for( ii = 0, zoom = zoomlist; ii < nbitems; zoom++, ii++ )
    {
        m_ZoomList[ii] = *zoom;
    }
}

/***********************************/
void BASE_SCREEN::SetFirstZoom()
/***********************************/
/* ajuste le coeff de zoom a 1*/
{
    m_Zoom = 1;
}

/****************************/
int BASE_SCREEN::GetZoom()
/****************************/
/* retourne le coeff de zoom */
{
    return m_Zoom;
}

/***********************************/
void BASE_SCREEN::SetZoom( int coeff )
/***********************************/
/* ajuste le coeff de zoom a coeff */
{
    m_Zoom = coeff;
    if( m_Zoom < 1 )
        m_Zoom = 1;
}

/********************************/
void BASE_SCREEN::SetNextZoom()
/********************************/

/* Selectionne le prochain coeff de zoom
 */
{
    m_Zoom *= 2;

    if( m_ZoomList == NULL )
        return;

    int ii, zoom_max = 512;
    for( ii = 0; m_ZoomList[ii] != 0; ii++ )
        zoom_max = m_ZoomList[ii];

    if( m_Zoom > zoom_max )
        m_Zoom = zoom_max;
}

/*************************************/
void BASE_SCREEN::SetPreviousZoom()
/*************************************/

/* Selectionne le precedent coeff de zoom
 */
{
    m_Zoom /= 2;
    if( m_Zoom < 1 )
        m_Zoom = 1;
}

/**********************************/
void BASE_SCREEN::SetLastZoom()
/**********************************/

/* ajuste le coeff de zoom au max
 */
{
    if( m_ZoomList == NULL )
        return;
    int ii;
    for( ii = 0; m_ZoomList[ii] != 0; ii++ )
        m_Zoom = m_ZoomList[ii];
}

/********************************************/
void BASE_SCREEN::SetGridList( wxSize* gridlist )
/********************************************/

/* init liste des zoom (NULL terminated)
 */
{
    int     ii, nbitems;
    wxSize* grid;

    // Decompte des items
    for( nbitems = 0, grid = gridlist;  ; grid++, nbitems++ )
    {
        if( (grid->x <= 0) || (grid->y <= 0) )
            break;
    }

    // Init liste
    if( m_GridList )
        free( m_GridList );
    m_GridList = (wxSize*) MyZMalloc( nbitems * sizeof(wxSize) );

    for( ii = 0, grid = gridlist; ii < nbitems; grid++, ii++ )
    {
        m_GridList[ii] = *grid;
    }
}

/**********************************************/
void BASE_SCREEN::SetGrid( const wxSize& size )
/**********************************************/
{
    if( m_GridList == NULL )
        return;

    if( (size.x <= 0) || (size.y <= 0) )
    {
        m_UserGrid     = g_UserGrid;
        m_UserGridIsON = TRUE;
    }
    else
    {
        m_Grid = size;
        m_UserGridIsON = FALSE;
    }
}

/*********************************/
wxSize BASE_SCREEN::GetGrid()
/*********************************/
{
    wxSize grid = m_Grid;
    double xx, scale;

    if( m_GridList == NULL )
        return wxSize( 1, 1 );

    if( m_UserGridIsON || m_Grid.x < 0 || m_Grid.y < 0 )
    {
        if( m_UserGridUnit == INCHES )
            scale = 10000;
        else
            scale = 10000 / 25.4;
        xx     = m_UserGrid.x * scale;
        grid.x = (int) (xx + 0.5);
        xx     = m_UserGrid.y * scale;
        grid.y = (int) (xx + 0.5);
    }
    return grid;
}

/*********************************/
void BASE_SCREEN::SetNextGrid()
/*********************************/

/* Selectionne la prochaine grille
 */
{
    int ii;

    if( m_GridList == NULL )
        return;

    for( ii = 0; ; ii++ )
    {
        if( m_GridList[ii].x <= 0 )
            break;
        if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
            break;
    }

    if( (m_GridList[ii].x > 0) && (ii > 0) )
        m_Grid = m_GridList[ii - 1];
}

/*************************************/
void BASE_SCREEN::SetPreviousGrid()
/*************************************/

/* Selectionne le precedent coeff de grille
 */
{
    int ii;

    if( m_GridList == NULL )
        return;

    for( ii = 0; ; ii++ )
    {
        if( m_GridList[ii].x <= 0 )
            break;
        if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
            break;
    }

    if( (m_GridList[ii].x > 0) && (m_GridList[ii + 1].x > 0) )
        m_Grid = m_GridList[ii + 1];
}

/**********************************/
void BASE_SCREEN::SetFirstGrid()
/**********************************/

/* ajuste le coeff de grille a 1
 */
{
    if( m_GridList == NULL )
        return;

    int ii = 0;
    while( m_GridList[ii].x > 0 )
        ii++;

    m_Grid = m_GridList[ii - 1];
}

/**********************************/
void BASE_SCREEN::SetLastGrid()
/**********************************/

/* ajuste le coeff de grille au max
 */
{
    if( m_GridList == NULL )
        return;
    m_Grid = m_GridList[0];
}

/*****************************************/
void BASE_SCREEN::ClearUndoRedoList()
/*****************************************/

/* free the undo and the redo lists
 */
{
    EDA_BaseStruct* nextitem;

    while( m_UndoList )
    {
        nextitem = m_UndoList->Pnext;
        delete m_UndoList;
        m_UndoList = nextitem;
    }

    while( m_RedoList )
    {
        nextitem = m_RedoList->Pnext;
        delete m_RedoList;
        m_RedoList = nextitem;
    }
}

/***********************************************************/
void BASE_SCREEN::AddItemToUndoList( EDA_BaseStruct* newitem )
/************************************************************/

/* Put newitem in head of undo list
 *  Deletes olds items if > count max.
 */
{
    int             ii;
    EDA_BaseStruct* item, * nextitem;

    if( newitem == NULL )
        return;

    newitem->Pnext = m_UndoList;
    m_UndoList = newitem;

    /* Free first items, if count max reached */
    for( ii = 0, item = m_UndoList; ii < m_UndoRedoCountMax; ii++ )
    {
        if( item->Pnext == NULL )
            return;
        item = item->Pnext;
    }

    if( item == NULL )
        return;

    nextitem    = item->Pnext;
    item->Pnext = NULL; // Set end of chain

    // Delete the extra  items
    for( item = nextitem; item != NULL; item = nextitem )
    {
        nextitem = item->Pnext;
        delete item;
    }
}

/***********************************************************/
void BASE_SCREEN::AddItemToRedoList( EDA_BaseStruct* newitem )
/***********************************************************/
{
    int             ii;
    EDA_BaseStruct* item, * nextitem;

    if( newitem == NULL )
        return;

    newitem->Pnext = m_RedoList;
    m_RedoList = newitem;
    /* Free first items, if count max reached */
    for( ii = 0, item = m_RedoList; ii < m_UndoRedoCountMax; ii++ )
    {
        if( item->Pnext == NULL )
            break;
        item = item->Pnext;
    }

    if( item == NULL )
        return;

    nextitem    = item->Pnext;
    item->Pnext = NULL; // Set end of chain

    // Delete the extra items
    for( item = nextitem; item != NULL; item = nextitem )
    {
        nextitem = item->Pnext;
        delete item;
    }
}

/*****************************************************/
EDA_BaseStruct* BASE_SCREEN::GetItemFromUndoList()
/*****************************************************/
{
    EDA_BaseStruct* item = m_UndoList;

    if( item )
        m_UndoList = item->Pnext;
    return item;
}

/******************************************************/
EDA_BaseStruct* BASE_SCREEN::GetItemFromRedoList()
/******************************************************/
{
    EDA_BaseStruct* item = m_RedoList;

    if( item )
        m_RedoList = item->Pnext;
    return item;
}

void BASE_SCREEN::SetCurItem( EDA_BaseStruct* aCurItem )
{

#if 0 && defined(DEBUG)
    printf( "SetCurItem(%p)\n", aCurItem );
#endif

    m_CurrentItem = aCurItem;
}
<|endoftext|>


<commit_before>#include <archie/alias.hpp>
#include <vector>
#include <array>
#include <catch.hpp>
namespace {
using namespace archie;

TEST_CASE("alias", "[alias]") {
  SECTION("ref") {
    int x = 0;
    int y = 1;
    auto a = alias(x);
    REQUIRE(unwrap(a) == 0);
    a = 2;
    REQUIRE(x == 2);
    a = rebind(y);
    a = 3;
    REQUIRE(x == 2);
    REQUIRE(y == 3);
  }
  SECTION("const ref") {
    const int x = 0;
    const int y = 1;
    auto a = alias(x);
    auto b = alias(x);
    REQUIRE(unwrap(a) == 0);
    a = rebind(y);
    REQUIRE(unwrap(a) == 1);
    a = rebind(b);
    REQUIRE(unwrap(a) == 0);
  }
  SECTION("sorting") {
    std::array<int, 3> array = {{3, 1, 2}};
    std::vector<alias_t<int>> vec;
    vec.emplace_back(array[1]);
    vec.emplace_back(array[2]);
    vec.emplace_back(array[0]);
    std::sort(std::begin(vec), std::end(vec));
    REQUIRE(unwrap(vec[0]) == 3);
    REQUIRE(unwrap(vec[1]) == 1);
    REQUIRE(unwrap(vec[2]) == 2);
    REQUIRE(array[0] == 3);
    REQUIRE(array[1] == 1);
    REQUIRE(array[2] == 2);
    std::sort(std::begin(vec), std::end(vec),
              [](auto const& lhs, auto const& rhs) { return unwrap(lhs) < unwrap(rhs); });
    REQUIRE(unwrap(vec[0]) == 1);
    REQUIRE(unwrap(vec[1]) == 2);
    REQUIRE(unwrap(vec[2]) == 3);
    REQUIRE(array[0] == 3);
    REQUIRE(array[1] == 1);
    REQUIRE(array[2] == 2);
  }
  SECTION("cross-const") {
    const int ci = 1;
    int i = 2;
    auto ca = alias(ci);
    REQUIRE(unwrap(ca) == 1);
    ca = rebind(i);
    REQUIRE(unwrap(ca) == 2);
  }
  SECTION("function arg") {
    int x = 10;
    int y = 12;
    auto foo = [](alias_t<int> a, alias_t<int> b) {
      if (unwrap(a) < unwrap(b)) {
        auto tmp = a;
        a = rebind(b);
        b = rebind(tmp);
      }
      a = 42;
      b = 7;
    };
    foo(ref(x), ref(y));
    REQUIRE(x == 7);
    REQUIRE(y == 42);
  }
  SECTION("assign") {
    auto x = 1u;
    auto y = 2u;
    auto a = alias(x);
    REQUIRE(unwrap(a) == 1u);
    a = y;
    REQUIRE(unwrap(a) == 2u);
    REQUIRE(x == 2u);
    a = x;
    REQUIRE(unwrap(a) == 2u);
    a = std::move(x);
    REQUIRE(unwrap(a) == 2u);
  }
  SECTION("cross-ctor") {
    struct A {
      int x = 1;
    };
    struct B : A {
      int y = 2;
    };
    B x;
    alias_t<A> const a(x);
    REQUIRE((*a).x == 1);
    alias_t<A> b(alias(x));
    REQUIRE(a->x == 1);
  }
  SECTION("deref") {
    struct Pos {
      int x, y;
    };
    Pos p, q;
    auto als = alias(p);
    als->x = 1;
    als->y = 2;
    REQUIRE(p.x == 1);
    REQUIRE(p.y == 2);
    auto other = alias(p);
    REQUIRE(als == other);
    REQUIRE_FALSE(als != other);
    auto aq = alias(q);
    REQUIRE(std::addressof(p) > std::addressof(q));
    REQUIRE(als > aq);
    REQUIRE(als >= other);
    REQUIRE(als >= aq);
    REQUIRE(aq < als);
    REQUIRE(other <= als);
    REQUIRE(aq <= als);
  }
}
}
<commit_msg>fix alias test<commit_after>#include <archie/alias.hpp>
#include <vector>
#include <array>
#include <catch.hpp>
namespace {
using namespace archie;

TEST_CASE("alias", "[alias]") {
  SECTION("ref") {
    int x = 0;
    int y = 1;
    auto a = alias(x);
    REQUIRE(unwrap(a) == 0);
    a = 2;
    REQUIRE(x == 2);
    a = rebind(y);
    a = 3;
    REQUIRE(x == 2);
    REQUIRE(y == 3);
  }
  SECTION("const ref") {
    const int x = 0;
    const int y = 1;
    auto a = alias(x);
    auto b = alias(x);
    REQUIRE(unwrap(a) == 0);
    a = rebind(y);
    REQUIRE(unwrap(a) == 1);
    a = rebind(b);
    REQUIRE(unwrap(a) == 0);
  }
  SECTION("sorting") {
    std::array<int, 3> array = {{3, 1, 2}};
    std::vector<alias_t<int>> vec;
    vec.emplace_back(array[1]);
    vec.emplace_back(array[2]);
    vec.emplace_back(array[0]);
    std::sort(std::begin(vec), std::end(vec));
    REQUIRE(unwrap(vec[0]) == 3);
    REQUIRE(unwrap(vec[1]) == 1);
    REQUIRE(unwrap(vec[2]) == 2);
    REQUIRE(array[0] == 3);
    REQUIRE(array[1] == 1);
    REQUIRE(array[2] == 2);
    std::sort(std::begin(vec), std::end(vec),
              [](auto const& lhs, auto const& rhs) { return unwrap(lhs) < unwrap(rhs); });
    REQUIRE(unwrap(vec[0]) == 1);
    REQUIRE(unwrap(vec[1]) == 2);
    REQUIRE(unwrap(vec[2]) == 3);
    REQUIRE(array[0] == 3);
    REQUIRE(array[1] == 1);
    REQUIRE(array[2] == 2);
  }
  SECTION("cross-const") {
    const int ci = 1;
    int i = 2;
    auto ca = alias(ci);
    REQUIRE(unwrap(ca) == 1);
    ca = rebind(i);
    REQUIRE(unwrap(ca) == 2);
  }
  SECTION("function arg") {
    int x = 10;
    int y = 12;
    auto foo = [](alias_t<int> a, alias_t<int> b) {
      if (unwrap(a) < unwrap(b)) {
        auto tmp = a;
        a = rebind(b);
        b = rebind(tmp);
      }
      a = 42;
      b = 7;
    };
    foo(ref(x), ref(y));
    REQUIRE(x == 7);
    REQUIRE(y == 42);
  }
  SECTION("assign") {
    auto x = 1u;
    auto y = 2u;
    auto a = alias(x);
    REQUIRE(unwrap(a) == 1u);
    a = y;
    REQUIRE(unwrap(a) == 2u);
    REQUIRE(x == 2u);
    a = x;
    REQUIRE(unwrap(a) == 2u);
    a = std::move(x);
    REQUIRE(unwrap(a) == 2u);
  }
  SECTION("cross-ctor") {
    struct A {
      int x = 1;
    };
    struct B : A {
      int y = 2;
    };
    B x;
    alias_t<A> const a(x);
    REQUIRE((*a).x == 1);
    alias_t<A> b(alias(x));
    REQUIRE(a->x == 1);
  }
  SECTION("deref") {
    struct Pos {
      int x, y;
    };
    Pos p, q;
    auto als = alias(p);
    als->x = 1;
    als->y = 2;
    REQUIRE(p.x == 1);
    REQUIRE(p.y == 2);
    auto other = alias(p);
    REQUIRE(als == other);
    REQUIRE_FALSE(als != other);
    auto aq = alias(q);
    if (std::addressof(p) > std::addressof(q)) {
      REQUIRE(als > aq);
      REQUIRE(als >= other);
      REQUIRE(als >= aq);
      REQUIRE(aq < als);
      REQUIRE(other <= als);
      REQUIRE(aq <= als);
    }
  }
}
}
<|endoftext|>


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

#include "ngraph/runtime/dynamic/dynamic_backend.hpp"
#include "ngraph/graph_util.hpp"
#include "ngraph/pass/manager.hpp"
#include "ngraph/pass/shape_relevance.hpp"
#include "ngraph/specialize_shapes.hpp"
#include "ngraph/util.hpp"

using namespace std;
using namespace ngraph;

runtime::dynamic::DynamicBackend::DynamicBackend(shared_ptr<runtime::Backend> wrapped_backend)
    : m_wrapped_backend(std::move(wrapped_backend))
{
}

shared_ptr<runtime::Tensor>
    runtime::dynamic::DynamicBackend::create_tensor(const element::Type& type, const Shape& shape)
{
    return m_wrapped_backend->create_tensor(type, shape);
}

shared_ptr<runtime::Tensor> runtime::dynamic::DynamicBackend::create_tensor(
    const element::Type& type, const Shape& shape, void* memory_pointer)
{
    return m_wrapped_backend->create_tensor(type, shape, memory_pointer);
}

std::shared_ptr<runtime::Tensor>
    runtime::dynamic::DynamicBackend::create_dynamic_tensor(const element::Type& type,
                                                            const PartialShape& shape)
{
    return make_shared<DynamicTensor>(type, shape, m_wrapped_backend);
}

shared_ptr<runtime::Executable>
    runtime::dynamic::DynamicBackend::compile(shared_ptr<Function> function,
                                              bool enable_performance_collection)
{
    return make_shared<runtime::dynamic::DynamicExecutable>(
        function, m_wrapped_backend, enable_performance_collection);
}

runtime::dynamic::DynamicExecutable::DynamicExecutable(shared_ptr<Function> wrapped_function,
                                                       shared_ptr<runtime::Backend> wrapped_backend,
                                                       bool enable_performance_collection)
    : m_wrapped_function(wrapped_function)
    , m_wrapped_backend(wrapped_backend)
    , m_enable_performance_collection(enable_performance_collection)
{
    pass::Manager passes;
    passes.register_pass<pass::ShapeRelevance>();
    passes.run_passes(m_wrapped_function);

    set_parameters_and_results(*wrapped_function);
}

bool runtime::dynamic::DynamicExecutable::call(
    const std::vector<std::shared_ptr<runtime::Tensor>>& outputs,
    const std::vector<std::shared_ptr<runtime::Tensor>>& inputs)
{
    // TODO: Get cached executable out if it exists.
    // We will cache on:
    // (1) all shapes;
    // (2) all values of shape-relevant input tensors.

    std::vector<std::shared_ptr<runtime::Tensor>> wrapped_inputs;
    std::vector<element::Type> arg_element_types;
    std::vector<PartialShape> arg_shapes;

    for (auto& input : inputs)
    {
        if (auto dynamic_tensor = std::dynamic_pointer_cast<runtime::dynamic::DynamicTensor>(input))
        {
            NGRAPH_CHECK(dynamic_tensor->has_storage());
            arg_element_types.push_back(dynamic_tensor->get_wrapped_tensor()->get_element_type());
            arg_shapes.push_back(dynamic_tensor->get_wrapped_tensor()->get_shape());
            wrapped_inputs.push_back(dynamic_tensor->get_wrapped_tensor());
        }
        else
        {
            arg_element_types.push_back(input->get_element_type());
            arg_shapes.push_back(input->get_shape());
            wrapped_inputs.push_back(input);
        }
    }

    // TODO: specialize_shapes needs to fill in values of shape-relevant params.
    auto clone = specialize_shapes(m_wrapped_function, arg_element_types, arg_shapes);
    // TODO: run constant folding and de-dynification on clone.
    const ResultVector& results = clone->get_results();
    NGRAPH_CHECK(results.size() == outputs.size());

    std::vector<std::shared_ptr<runtime::Tensor>> wrapped_outputs;

    auto results_it = results.begin();

    for (auto& output : outputs)
    {
        if (auto dynamic_tensor =
                std::dynamic_pointer_cast<runtime::dynamic::DynamicTensor>(output))
        {
            dynamic_tensor->make_storage((*results_it)->get_output_element_type(0),
                                         (*results_it)->get_output_shape(0));
            wrapped_outputs.push_back(dynamic_tensor->get_wrapped_tensor());
        }
        else
        {
            wrapped_outputs.push_back(output);
        }
    }

    // TODO: Put compiled executable in the cache.
    auto compiled_executable = m_wrapped_backend->compile(clone, m_enable_performance_collection);
    auto result = compiled_executable->call(wrapped_outputs, wrapped_inputs);

    return result;
}

runtime::dynamic::DynamicTensor::DynamicTensor(
    const element::Type& element_type,
    const PartialShape& shape,
    const std::shared_ptr<runtime::Backend>& wrapped_backend)
    : Tensor(make_shared<descriptor::Tensor>(element_type, shape, "wrapped_dynamic"))
    , m_wrapped_tensor(nullptr)
    , m_wrapped_backend(wrapped_backend)
{
}

const element::Type& runtime::dynamic::DynamicTensor::get_element_type() const
{
    if (m_wrapped_tensor == nullptr)
    {
        return m_descriptor->get_element_type();
    }
    else
    {
        return m_wrapped_tensor->get_element_type();
    }
}

const ngraph::Shape& runtime::dynamic::DynamicTensor::get_shape() const
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "asked for shape of a dynamic tensor with no allocated storage");
    return m_wrapped_tensor->get_shape();
}

void runtime::dynamic::DynamicTensor::write(const void* p, size_t offset, size_t n)
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to write to a dynamic tensor with no allocated storage");
    m_wrapped_tensor->write(p, offset, n);
}

void runtime::dynamic::DynamicTensor::read(void* p, size_t offset, size_t n) const
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to read from a dynamic tensor with no allocated storage");
    m_wrapped_tensor->read(p, offset, n);
}

void runtime::dynamic::DynamicTensor::copy_from(const ngraph::runtime::Tensor& source)
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to copy_from to a dynamic tensor with no allocated storage");
    m_wrapped_tensor->copy_from(source);
}

bool runtime::dynamic::DynamicTensor::has_storage() const
{
    return m_wrapped_tensor != nullptr;
}

void runtime::dynamic::DynamicTensor::release_storage()
{
    m_wrapped_tensor = nullptr;
}

void runtime::dynamic::DynamicTensor::make_storage(const element::Type& element_type,
                                                   const Shape& shape)
{
    NGRAPH_CHECK(element_type.is_static(), "make_storage requires a static element type");
    NGRAPH_CHECK(get_element_type().is_dynamic() || get_element_type() == element_type,
                 "tried to make storage with element type ",
                 element_type,
                 " which is incompatible with dynamic tensor element_type ",
                 get_element_type());
    NGRAPH_CHECK(get_partial_shape().relaxes(shape),
                 "tried to make storage with shape ",
                 shape,
                 " which is incompatible with dynamic tensor shape ",
                 get_partial_shape());
    m_wrapped_tensor = m_wrapped_backend->create_tensor(element_type, shape);
}

const std::shared_ptr<ngraph::runtime::Tensor>&
    runtime::dynamic::DynamicTensor::get_wrapped_tensor() const
{
    return m_wrapped_tensor;
}
<commit_msg>Address Klocwork issue. Fix bug? (#2915)<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include "ngraph/runtime/dynamic/dynamic_backend.hpp"
#include "ngraph/graph_util.hpp"
#include "ngraph/pass/manager.hpp"
#include "ngraph/pass/shape_relevance.hpp"
#include "ngraph/specialize_shapes.hpp"
#include "ngraph/util.hpp"

using namespace std;
using namespace ngraph;

runtime::dynamic::DynamicBackend::DynamicBackend(shared_ptr<runtime::Backend> wrapped_backend)
    : m_wrapped_backend(std::move(wrapped_backend))
{
}

shared_ptr<runtime::Tensor>
    runtime::dynamic::DynamicBackend::create_tensor(const element::Type& type, const Shape& shape)
{
    return m_wrapped_backend->create_tensor(type, shape);
}

shared_ptr<runtime::Tensor> runtime::dynamic::DynamicBackend::create_tensor(
    const element::Type& type, const Shape& shape, void* memory_pointer)
{
    return m_wrapped_backend->create_tensor(type, shape, memory_pointer);
}

std::shared_ptr<runtime::Tensor>
    runtime::dynamic::DynamicBackend::create_dynamic_tensor(const element::Type& type,
                                                            const PartialShape& shape)
{
    return make_shared<DynamicTensor>(type, shape, m_wrapped_backend);
}

shared_ptr<runtime::Executable>
    runtime::dynamic::DynamicBackend::compile(shared_ptr<Function> function,
                                              bool enable_performance_collection)
{
    return make_shared<runtime::dynamic::DynamicExecutable>(
        function, m_wrapped_backend, enable_performance_collection);
}

runtime::dynamic::DynamicExecutable::DynamicExecutable(shared_ptr<Function> wrapped_function,
                                                       shared_ptr<runtime::Backend> wrapped_backend,
                                                       bool enable_performance_collection)
    : m_wrapped_function(wrapped_function)
    , m_wrapped_backend(wrapped_backend)
    , m_enable_performance_collection(enable_performance_collection)
{
    pass::Manager passes;
    passes.register_pass<pass::ShapeRelevance>();
    passes.run_passes(m_wrapped_function);

    set_parameters_and_results(*wrapped_function);
}

bool runtime::dynamic::DynamicExecutable::call(
    const std::vector<std::shared_ptr<runtime::Tensor>>& outputs,
    const std::vector<std::shared_ptr<runtime::Tensor>>& inputs)
{
    // TODO: Get cached executable out if it exists.
    // We will cache on:
    // (1) all shapes;
    // (2) all values of shape-relevant input tensors.

    std::vector<std::shared_ptr<runtime::Tensor>> wrapped_inputs;
    std::vector<element::Type> arg_element_types;
    std::vector<PartialShape> arg_shapes;

    for (auto& input : inputs)
    {
        if (auto dynamic_tensor = std::dynamic_pointer_cast<runtime::dynamic::DynamicTensor>(input))
        {
            NGRAPH_CHECK(dynamic_tensor->has_storage());
            arg_element_types.push_back(dynamic_tensor->get_wrapped_tensor()->get_element_type());
            arg_shapes.push_back(dynamic_tensor->get_wrapped_tensor()->get_shape());
            wrapped_inputs.push_back(dynamic_tensor->get_wrapped_tensor());
        }
        else
        {
            arg_element_types.push_back(input->get_element_type());
            arg_shapes.push_back(input->get_shape());
            wrapped_inputs.push_back(input);
        }
    }

    // TODO: specialize_shapes needs to fill in values of shape-relevant params.
    auto clone = specialize_shapes(m_wrapped_function, arg_element_types, arg_shapes);
    // TODO: run constant folding and de-dynification on clone.
    const ResultVector& results = clone->get_results();
    NGRAPH_CHECK(results.size() == outputs.size());

    std::vector<std::shared_ptr<runtime::Tensor>> wrapped_outputs;

    for (size_t i = 0; i < outputs.size(); i++)
    {
        if (auto dynamic_tensor =
                std::dynamic_pointer_cast<runtime::dynamic::DynamicTensor>(outputs[i]))
        {
            dynamic_tensor->make_storage(results[i]->get_output_element_type(0),
                                         results[i]->get_output_shape(0));
            wrapped_outputs.push_back(dynamic_tensor->get_wrapped_tensor());
        }
        else
        {
            wrapped_outputs.push_back(outputs[i]);
        }
    }

    // TODO: Put compiled executable in the cache.
    auto compiled_executable = m_wrapped_backend->compile(clone, m_enable_performance_collection);
    auto result = compiled_executable->call(wrapped_outputs, wrapped_inputs);

    return result;
}

runtime::dynamic::DynamicTensor::DynamicTensor(
    const element::Type& element_type,
    const PartialShape& shape,
    const std::shared_ptr<runtime::Backend>& wrapped_backend)
    : Tensor(make_shared<descriptor::Tensor>(element_type, shape, "wrapped_dynamic"))
    , m_wrapped_tensor(nullptr)
    , m_wrapped_backend(wrapped_backend)
{
}

const element::Type& runtime::dynamic::DynamicTensor::get_element_type() const
{
    if (m_wrapped_tensor == nullptr)
    {
        return m_descriptor->get_element_type();
    }
    else
    {
        return m_wrapped_tensor->get_element_type();
    }
}

const ngraph::Shape& runtime::dynamic::DynamicTensor::get_shape() const
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "asked for shape of a dynamic tensor with no allocated storage");
    return m_wrapped_tensor->get_shape();
}

void runtime::dynamic::DynamicTensor::write(const void* p, size_t offset, size_t n)
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to write to a dynamic tensor with no allocated storage");
    m_wrapped_tensor->write(p, offset, n);
}

void runtime::dynamic::DynamicTensor::read(void* p, size_t offset, size_t n) const
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to read from a dynamic tensor with no allocated storage");
    m_wrapped_tensor->read(p, offset, n);
}

void runtime::dynamic::DynamicTensor::copy_from(const ngraph::runtime::Tensor& source)
{
    NGRAPH_CHECK(m_wrapped_tensor != nullptr,
                 "tried to copy_from to a dynamic tensor with no allocated storage");
    m_wrapped_tensor->copy_from(source);
}

bool runtime::dynamic::DynamicTensor::has_storage() const
{
    return m_wrapped_tensor != nullptr;
}

void runtime::dynamic::DynamicTensor::release_storage()
{
    m_wrapped_tensor = nullptr;
}

void runtime::dynamic::DynamicTensor::make_storage(const element::Type& element_type,
                                                   const Shape& shape)
{
    NGRAPH_CHECK(element_type.is_static(), "make_storage requires a static element type");
    NGRAPH_CHECK(get_element_type().is_dynamic() || get_element_type() == element_type,
                 "tried to make storage with element type ",
                 element_type,
                 " which is incompatible with dynamic tensor element_type ",
                 get_element_type());
    NGRAPH_CHECK(get_partial_shape().relaxes(shape),
                 "tried to make storage with shape ",
                 shape,
                 " which is incompatible with dynamic tensor shape ",
                 get_partial_shape());
    m_wrapped_tensor = m_wrapped_backend->create_tensor(element_type, shape);
}

const std::shared_ptr<ngraph::runtime::Tensor>&
    runtime::dynamic::DynamicTensor::get_wrapped_tensor() const
{
    return m_wrapped_tensor;
}
<|endoftext|>