<commit_before>#include "coverage.h"
#include "featurecoverage.h"
#include "feature.h"
#include "featureiterator.h"
#include "drawingcolor.h"
#include "drawerfactory.h"
#include "rootdrawer.h"
#include "table.h"
#include "range.h"
#include "itemrange.h"
#include "colorrange.h"
#include "colorlookup.h"
#include "representation.h"
#include "attributevisualproperties.h"
#include "featurelayerdrawer.h"
#include "tesselation/ilwistesselator.h"
#include "openglhelper.h"

using namespace Ilwis;
using namespace Geodrawer;

REGISTER_DRAWER(FeatureLayerDrawer)

FeatureLayerDrawer::FeatureLayerDrawer(DrawerInterface *parentDrawer, RootDrawer *rootdrawer) : LayerDrawer("FeatureLayerDrawer", parentDrawer, rootdrawer)
{
}

DrawerInterface *FeatureLayerDrawer::create(DrawerInterface *parentDrawer, RootDrawer *rootdrawer)
{
    return new FeatureLayerDrawer(parentDrawer, rootdrawer)    ;
}

bool FeatureLayerDrawer::prepare(DrawerInterface::PreparationType prepType, const IOOptions &options, QOpenGLContext *openglContext)
{
    if(!LayerDrawer::prepare(prepType, options, openglContext))
        return false;

    if ( hasType(prepType, DrawerInterface::ptGEOMETRY) && !isPrepared(DrawerInterface::ptGEOMETRY)){
        std::vector<VertexPosition> vertices;
        std::vector<VertexColor> colors;

        _indices = std::vector<VertexIndex>();

        IFeatureCoverage features = coverage().as<FeatureCoverage>();
        if ( !features.isValid()){
            return ERROR2(ERR_COULDNT_CREATE_OBJECT_FOR_2,"FeatureCoverage", TR("Visualization"));
        }
        AttributeVisualProperties attr = visualAttribute(activeAttribute());
        //int columnIndex = features->attributeDefinitions().columnIndex(activeAttribute());
        for(const SPFeatureI& feature : features){
            quint32 noOfVertices = OpenGLHelper::getVertices(rootDrawer()->coordinateSystem(), features->coordinateSystem(), feature->geometry(), feature->featureid(), vertices, _indices, _boundaryIndex);
            for(int i =0; i < noOfVertices; ++i){
               QColor clr = attr.value2color(feature(activeAttribute()));
               colors.push_back(VertexColor(clr.redF(), clr.greenF(), clr.blueF(), 1.0));
            }

        }

        if(!initGeometry(openglContext, vertices, colors))
            return false;

        _prepared |= DrawerInterface::ptGEOMETRY;

    }

    return true;
}

void FeatureLayerDrawer::unprepare(DrawerInterface::PreparationType prepType)
{
    LayerDrawer::unprepare(prepType);

    if ( hasType(prepType, DrawerInterface::ptGEOMETRY))    {
        _prepared &= ~ ptGEOMETRY;
    }
}

void FeatureLayerDrawer::setActiveVisualAttribute(const QString &attr)
{
    IFeatureCoverage features = coverage().as<FeatureCoverage>();
    if ( features.isValid())    {
        if ( features->attributeDefinitions().columnIndex(attr) != iUNDEF){

            IRepresentation newrpr = Representation::defaultRepresentation(features->attributeDefinitions().columndefinition(attr).datadef().domain());
            if ( newrpr.isValid()){
                LayerDrawer::setActiveVisualAttribute(attr);
            }
        }
    }
}

void FeatureLayerDrawer::coverage(const ICoverage &cov)
{
    LayerDrawer::coverage(cov);
    setActiveVisualAttribute(sUNDEF);
    IFeatureCoverage features = coverage().as<FeatureCoverage>();

    for(int i = 0; i < features->attributeDefinitions().definitionCount(); ++i){
        IlwisTypes attrType = features->attributeDefinitions().columndefinition(i).datadef().domain()->ilwisType();
        if ( hasType(attrType, itNUMERICDOMAIN | itITEMDOMAIN)){
            AttributeVisualProperties props(features->attributeDefinitions().columndefinition(i).datadef().domain());
            if ( attrType == itNUMERICDOMAIN){
                SPNumericRange numrange = features->attributeDefinitions().columndefinition(i).datadef().range<NumericRange>();
                props.actualRange(NumericRange(numrange->min(), numrange->max(), numrange->resolution()));
            }
            visualAttribute(features->attributeDefinitions().columndefinition(i).name(), props);
            // try to find a reasonable default for the activeattribute
            if ( activeAttribute() == sUNDEF){
                if ( features->attributeDefinitions().columnIndex(FEATUREVALUECOLUMN) != iUNDEF){
                    setActiveVisualAttribute(FEATUREVALUECOLUMN);
                }else if ( features->attributeDefinitions().columnIndex(COVERAGEKEYCOLUMN) != iUNDEF){
                    setActiveVisualAttribute(COVERAGEKEYCOLUMN);
                }
                else if ( hasType(features->attributeDefinitions().columndefinition(i).datadef().domain()->ilwisType(), itNUMERICDOMAIN)){
                    setActiveVisualAttribute(features->attributeDefinitions().columndefinition(i).name());
                }
            }
        }
    }
}

ICoverage FeatureLayerDrawer::coverage() const
{
    return SpatialDataDrawer::coverage();
}

bool FeatureLayerDrawer::draw(QOpenGLContext *openglContext, const IOOptions&) {
    if ( !openglContext){
        return ERROR2(QString("%1 : %2"),TR("Drawing failed"),TR("Invalid OpenGL context passed"));
    }

    if ( !isActive())
        return false;

    if (!isPrepared()){
        return false;
    }

    _shaders.bind();

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER,_vboPosition);

    int vertexLocation = _shaders.attributeLocation("position");
    openglContext->functions()->glVertexAttribPointer(vertexLocation,3,GL_FLOAT,FALSE,0,0);
    openglContext->functions()->glEnableVertexAttribArray(vertexLocation);

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER,_vboColor);

    int colorLocation = _shaders.attributeLocation("vertexColor");
    openglContext->functions()->glVertexAttribPointer(colorLocation,4,GL_FLOAT,FALSE,0, 0);
    openglContext->functions()->glEnableVertexAttribArray(colorLocation);

    for(int i =0; i < _indices.size(); ++i){
        if ( _indices[i]._geomtype == itLINE){
            glDrawArrays(GL_LINE_STRIP,_indices[i]._start,_indices[i]._count);
        } else if ( _indices[i]._geomtype == itPOLYGON ){
            glDrawArrays(GL_TRIANGLE_FAN,_indices[i]._start,_indices[i]._count);
        }
    }

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER, 0);
    openglContext->functions()->glDisableVertexAttribArray(colorLocation);
    openglContext->functions()->glDisableVertexAttribArray(vertexLocation);

    _shaders.release();

    return true;
}
<commit_msg>item domain is setting properties for the attributevizualization<commit_after>#include "coverage.h"
#include "featurecoverage.h"
#include "feature.h"
#include "featureiterator.h"
#include "drawingcolor.h"
#include "drawerfactory.h"
#include "rootdrawer.h"
#include "table.h"
#include "range.h"
#include "itemrange.h"
#include "colorrange.h"
#include "colorlookup.h"
#include "representation.h"
#include "attributevisualproperties.h"
#include "featurelayerdrawer.h"
#include "tesselation/ilwistesselator.h"
#include "openglhelper.h"

using namespace Ilwis;
using namespace Geodrawer;

REGISTER_DRAWER(FeatureLayerDrawer)

FeatureLayerDrawer::FeatureLayerDrawer(DrawerInterface *parentDrawer, RootDrawer *rootdrawer) : LayerDrawer("FeatureLayerDrawer", parentDrawer, rootdrawer)
{
}

DrawerInterface *FeatureLayerDrawer::create(DrawerInterface *parentDrawer, RootDrawer *rootdrawer)
{
    return new FeatureLayerDrawer(parentDrawer, rootdrawer)    ;
}

bool FeatureLayerDrawer::prepare(DrawerInterface::PreparationType prepType, const IOOptions &options, QOpenGLContext *openglContext)
{
    if(!LayerDrawer::prepare(prepType, options, openglContext))
        return false;

    if ( hasType(prepType, DrawerInterface::ptGEOMETRY) && !isPrepared(DrawerInterface::ptGEOMETRY)){
        std::vector<VertexPosition> vertices;
        std::vector<VertexColor> colors;

        _indices = std::vector<VertexIndex>();

        IFeatureCoverage features = coverage().as<FeatureCoverage>();
        if ( !features.isValid()){
            return ERROR2(ERR_COULDNT_CREATE_OBJECT_FOR_2,"FeatureCoverage", TR("Visualization"));
        }
        AttributeVisualProperties attr = visualAttribute(activeAttribute());
        //int columnIndex = features->attributeDefinitions().columnIndex(activeAttribute());
        for(const SPFeatureI& feature : features){
            quint32 noOfVertices = OpenGLHelper::getVertices(rootDrawer()->coordinateSystem(), features->coordinateSystem(), feature->geometry(), feature->featureid(), vertices, _indices, _boundaryIndex);
            for(int i =0; i < noOfVertices; ++i){
               QColor clr = attr.value2color(feature(activeAttribute()));
               colors.push_back(VertexColor(clr.redF(), clr.greenF(), clr.blueF(), 1.0));
            }

        }

        if(!initGeometry(openglContext, vertices, colors))
            return false;

        _prepared |= DrawerInterface::ptGEOMETRY;

    }

    return true;
}

void FeatureLayerDrawer::unprepare(DrawerInterface::PreparationType prepType)
{
    LayerDrawer::unprepare(prepType);

    if ( hasType(prepType, DrawerInterface::ptGEOMETRY))    {
        _prepared &= ~ ptGEOMETRY;
    }
}

void FeatureLayerDrawer::setActiveVisualAttribute(const QString &attr)
{
    IFeatureCoverage features = coverage().as<FeatureCoverage>();
    if ( features.isValid())    {
        if ( features->attributeDefinitions().columnIndex(attr) != iUNDEF){

            IRepresentation newrpr = Representation::defaultRepresentation(features->attributeDefinitions().columndefinition(attr).datadef().domain());
            if ( newrpr.isValid()){
                LayerDrawer::setActiveVisualAttribute(attr);
            }
        }
    }
}

void FeatureLayerDrawer::coverage(const ICoverage &cov)
{
    LayerDrawer::coverage(cov);
    setActiveVisualAttribute(sUNDEF);
    IFeatureCoverage features = coverage().as<FeatureCoverage>();

    for(int i = 0; i < features->attributeDefinitions().definitionCount(); ++i){
        IlwisTypes attrType = features->attributeDefinitions().columndefinition(i).datadef().domain()->ilwisType();
        if ( hasType(attrType, itNUMERICDOMAIN | itITEMDOMAIN)){
            AttributeVisualProperties props(features->attributeDefinitions().columndefinition(i).datadef().domain());
            if ( attrType == itNUMERICDOMAIN){
                SPNumericRange numrange = features->attributeDefinitions().columndefinition(i).datadef().range<NumericRange>();
                props.actualRange(NumericRange(numrange->min(), numrange->max(), numrange->resolution()));
            } else if ( attrType == itITEMDOMAIN){
                int count = features->attributeDefinitions().columndefinition(i).datadef().domain()->range<>()->count();
                props.actualRange(NumericRange(0, count - 1,1));
            }
            visualAttribute(features->attributeDefinitions().columndefinition(i).name(), props);
            // try to find a reasonable default for the activeattribute
            if ( activeAttribute() == sUNDEF){
                if ( features->attributeDefinitions().columnIndex(FEATUREVALUECOLUMN) != iUNDEF){
                    setActiveVisualAttribute(FEATUREVALUECOLUMN);
                }else if ( features->attributeDefinitions().columnIndex(COVERAGEKEYCOLUMN) != iUNDEF){
                    setActiveVisualAttribute(COVERAGEKEYCOLUMN);
                }
                else if ( hasType(features->attributeDefinitions().columndefinition(i).datadef().domain()->ilwisType(), itNUMERICDOMAIN)){
                    setActiveVisualAttribute(features->attributeDefinitions().columndefinition(i).name());
                }
            }
        }
    }
}

ICoverage FeatureLayerDrawer::coverage() const
{
    return SpatialDataDrawer::coverage();
}

bool FeatureLayerDrawer::draw(QOpenGLContext *openglContext, const IOOptions&) {
    if ( !openglContext){
        return ERROR2(QString("%1 : %2"),TR("Drawing failed"),TR("Invalid OpenGL context passed"));
    }

    if ( !isActive())
        return false;

    if (!isPrepared()){
        return false;
    }

    _shaders.bind();

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER,_vboPosition);

    int vertexLocation = _shaders.attributeLocation("position");
    openglContext->functions()->glVertexAttribPointer(vertexLocation,3,GL_FLOAT,FALSE,0,0);
    openglContext->functions()->glEnableVertexAttribArray(vertexLocation);

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER,_vboColor);

    int colorLocation = _shaders.attributeLocation("vertexColor");
    openglContext->functions()->glVertexAttribPointer(colorLocation,4,GL_FLOAT,FALSE,0, 0);
    openglContext->functions()->glEnableVertexAttribArray(colorLocation);

    for(int i =0; i < _indices.size(); ++i){
        if ( _indices[i]._geomtype == itLINE){
            glDrawArrays(GL_LINE_STRIP,_indices[i]._start,_indices[i]._count);
        } else if ( _indices[i]._geomtype == itPOLYGON ){
            glDrawArrays(GL_TRIANGLE_FAN,_indices[i]._start,_indices[i]._count);
        }
    }

    openglContext->functions()->glBindBuffer(GL_ARRAY_BUFFER, 0);
    openglContext->functions()->glDisableVertexAttribArray(colorLocation);
    openglContext->functions()->glDisableVertexAttribArray(vertexLocation);

    _shaders.release();

    return true;
}
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/context.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/local_root_scope.hpp"
#include "flusspferd/spidermonkey/context.hpp"
#include "flusspferd/spidermonkey/value.hpp"
#include "flusspferd/spidermonkey/object.hpp"
#include "flusspferd/spidermonkey/runtime.hpp"
#include "flusspferd/current_context_scope.hpp"
#include <boost/unordered_map.hpp>
#include <cstring>
#include <cstdio>
#include <js/jsapi.h>

#ifndef FLUSSPFERD_STACKCHUNKSIZE
#define FLUSSPFERD_STACKCHUNKSIZE 8192
#endif

using namespace flusspferd;

namespace {
  static JSClass global_class = {
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
  };
}

struct context::context_private {
  typedef boost::shared_ptr<root_object> root_object_ptr;
  boost::unordered_map<std::string, root_object_ptr> prototypes;
  boost::unordered_map<std::string, root_object_ptr> constructors;
};

class context::impl {
public:
  impl()
    : context(JS_NewContext(Impl::get_runtime(),
                            FLUSSPFERD_STACKCHUNKSIZE)),
      destroy(true)
  {
    if(!context)
      throw exception("Could not create Spidermonkey Context");

    uint32 options = JS_GetOptions(context);

    options |= JSOPTION_VAROBJFIX;
    options |= JSOPTION_STRICT;
    options |= JSOPTION_DONT_REPORT_UNCAUGHT;
    options &= ~JSOPTION_XML;

    JS_SetVersion(context, JSVersion(JS_VERSION));
    JS_SetOptions(context, options);

#ifdef JS_THREADSAFE
    JS_BeginRequest(context);
#endif

    JSObject *global_ = JS_NewObject(context, &global_class, 0x0, 0x0);
    if(!global_)
      throw exception("Could not create Global Object");

    // Set it so that it doesn't get GCd (play it safe)
    JS_SetGlobalObject(context, global_);

    if(!JS_InitStandardClasses(context, global_))
      throw exception("Could not initialize Global Object");

    JS_DeleteProperty(context, global_, "XML");

    // Set the global object as an empty object which has its proto as the
    // 'true' global object with the std classes on it
    JSObject *pub_global = JS_NewObject(context, &global_class, global_, NULL);
    if(!global_)
      throw exception("Could not create Global Shim Object");

    JS_SetGlobalObject(context, pub_global);

    JS_SetContextPrivate(context, static_cast<void*>(new context_private));
  }

  explicit impl(JSContext *context)
    : context(context), destroy(false)
  { }

  ~impl() {
    if (destroy) {
      {
        current_context_scope scope(Impl::wrap_context(context));
        delete get_private();
        JS_DestroyContext(context);
      }
    }
  }

  bool is_valid() {
    return context;
  }

  context_private *get_private() {
    return static_cast<context_private*>(JS_GetContextPrivate(context));
  }

  JSContext *context;
  bool destroy;
};

struct context::detail {
  JSContext *c;
  detail(JSContext *ct) : c(ct) { }

  static JSContext *get(context &co) {
    return co.p->context;
  }
};

JSContext *Impl::get_context(context &co) {
  return context::detail::get(co);
}

context Impl::wrap_context(JSContext *c) {
  return context(c);
}

context::context()
{ }
context::context(context::detail const &d)
  : p(new impl(d.c))
{
  if (!p->is_valid())
    p.reset();
}
context::~context() { }

context context::create() {
  context c;
  c.p.reset(new impl);
  return c;
}

bool context::is_valid() const {
  return p;
}

object context::global() {
  JSObject *o = JS_GetGlobalObject(p->context);
  if (!o) {
    throw exception("No global object");
  }
  return Impl::wrap_object(o);
}

object context::scope_chain() {
  JSObject *o = JS_GetScopeChain(p->context);
  if (!o) {
    // Weird! In Spidermonkey 1.7, sometimes it seems like JS_GetScopeChain
    // returns NULL without setting an error.
    // In that case, we simply return the global object. It caused a problem.
    if (JS_IsExceptionPending(p->context))
      throw exception("No scope chain");
    else
      return this->global();
  }
  return Impl::wrap_object(o);
}

void context::add_prototype(std::string const &name, object const &proto) {
  p->get_private()->prototypes[name] =
    context_private::root_object_ptr(new root_object(proto));
}

object context::prototype(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->prototypes[name];
  return ptr ? *ptr : object();
}

void context::add_constructor(std::string const &name, object const &ctor) {
  p->get_private()->constructors[name] =
    context_private::root_object_ptr(new root_object(ctor));
}

object context::constructor(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->constructors[name];
  return ptr ? *ptr : object();
}

void context::gc() {
  JS_GC(p->context);
}

void context::set_thread() {
  assert(JS_SetContextThread(p->context) == 0);
}

void context::clear_thread() {
  //assert(
  JS_ClearContextThread(p->context);
  // == js_GetCurrentThread(p->context->runtime)->id);
}
<commit_msg>core: Report warnings from spidermonkey<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/context.hpp"
#include "flusspferd/object.hpp"
#include "flusspferd/exception.hpp"
#include "flusspferd/local_root_scope.hpp"
#include "flusspferd/spidermonkey/context.hpp"
#include "flusspferd/spidermonkey/value.hpp"
#include "flusspferd/spidermonkey/object.hpp"
#include "flusspferd/spidermonkey/runtime.hpp"
#include "flusspferd/current_context_scope.hpp"
#include <boost/unordered_map.hpp>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <js/jsapi.h>

#ifndef FLUSSPFERD_STACKCHUNKSIZE
#define FLUSSPFERD_STACKCHUNKSIZE 8192
#endif

using namespace flusspferd;

namespace {
  static JSClass global_class = {
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
  };
}

struct context::context_private {
  typedef boost::shared_ptr<root_object> root_object_ptr;
  boost::unordered_map<std::string, root_object_ptr> prototypes;
  boost::unordered_map<std::string, root_object_ptr> constructors;
};

class context::impl {
public:
  impl()
    : context(JS_NewContext(Impl::get_runtime(),
                            FLUSSPFERD_STACKCHUNKSIZE)),
      destroy(true)
  {
    if(!context)
      throw exception("Could not create Spidermonkey Context");

    uint32 options = JS_GetOptions(context);

    options |= JSOPTION_VAROBJFIX;
    options |= JSOPTION_STRICT;
    options |= JSOPTION_DONT_REPORT_UNCAUGHT;
    options &= ~JSOPTION_XML;

    JS_SetVersion(context, JSVersion(JS_VERSION));
    JS_SetOptions(context, options);

#ifdef JS_THREADSAFE
    JS_BeginRequest(context);
#endif

    JS_SetErrorReporter(context, spidermonkey_error_reporter);

    JSObject *global_ = JS_NewObject(context, &global_class, 0x0, 0x0);
    if(!global_)
      throw exception("Could not create Global Object");

    // Set it so that it doesn't get GCd (play it safe)
    JS_SetGlobalObject(context, global_);

    if(!JS_InitStandardClasses(context, global_))
      throw exception("Could not initialize Global Object");

    JS_DeleteProperty(context, global_, "XML");

    // Set the global object as an empty object which has its proto as the
    // 'true' global object with the std classes on it
    JSObject *pub_global = JS_NewObject(context, &global_class, global_, NULL);
    if(!global_)
      throw exception("Could not create Global Shim Object");

    JS_SetGlobalObject(context, pub_global);

    JS_SetContextPrivate(context, static_cast<void*>(new context_private));
  }

  explicit impl(JSContext *context)
    : context(context), destroy(false)
  { }

  ~impl() {
    if (destroy) {
      {
        current_context_scope scope(Impl::wrap_context(context));
        delete get_private();
        JS_DestroyContext(context);
      }
    }
  }

  bool is_valid() {
    return context;
  }

  context_private *get_private() {
    return static_cast<context_private*>(JS_GetContextPrivate(context));
  }

  static void spidermonkey_error_reporter(JSContext *cx, char const *message, JSErrorReport *report) {

    if (!report || JSREPORT_IS_EXCEPTION(report->flags)) {
      return;
    }

    std::cerr << (JSREPORT_IS_STRICT(report->flags) ? "Strict warning: " : "Warning: ")
              << message;

    if (report->filename) {
      std::cerr << " at " << report->filename;

      if (report->lineno) {
        std::cerr << ":" << report->lineno;
      }
    }
    std::cerr << std::endl;

  }

  JSContext *context;
  bool destroy;
};

struct context::detail {
  JSContext *c;
  detail(JSContext *ct) : c(ct) { }

  static JSContext *get(context &co) {
    return co.p->context;
  }
};

JSContext *Impl::get_context(context &co) {
  return context::detail::get(co);
}

context Impl::wrap_context(JSContext *c) {
  return context(c);
}

context::context()
{ }
context::context(context::detail const &d)
  : p(new impl(d.c))
{
  if (!p->is_valid())
    p.reset();
}
context::~context() { }

context context::create() {
  context c;
  c.p.reset(new impl);
  return c;
}

bool context::is_valid() const {
  return p;
}

object context::global() {
  JSObject *o = JS_GetGlobalObject(p->context);
  if (!o) {
    throw exception("No global object");
  }
  return Impl::wrap_object(o);
}

object context::scope_chain() {
  JSObject *o = JS_GetScopeChain(p->context);
  if (!o) {
    // Weird! In Spidermonkey 1.7, sometimes it seems like JS_GetScopeChain
    // returns NULL without setting an error.
    // In that case, we simply return the global object. It caused a problem.
    if (JS_IsExceptionPending(p->context))
      throw exception("No scope chain");
    else
      return this->global();
  }
  return Impl::wrap_object(o);
}

void context::add_prototype(std::string const &name, object const &proto) {
  p->get_private()->prototypes[name] =
    context_private::root_object_ptr(new root_object(proto));
}

object context::prototype(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->prototypes[name];
  return ptr ? *ptr : object();
}

void context::add_constructor(std::string const &name, object const &ctor) {
  p->get_private()->constructors[name] =
    context_private::root_object_ptr(new root_object(ctor));
}

object context::constructor(std::string const &name) const {
  context_private::root_object_ptr ptr = p->get_private()->constructors[name];
  return ptr ? *ptr : object();
}

void context::gc() {
  JS_GC(p->context);
}

void context::set_thread() {
  assert(JS_SetContextThread(p->context) == 0);
}

void context::clear_thread() {
  //assert(
  JS_ClearContextThread(p->context);
  // == js_GetCurrentThread(p->context->runtime)->id);
}
<|endoftext|>


<commit_before>
#pragma GCC diagnostic ignored "-Wconversion"
#include <libdevcrypto/SHA3.h>
#include <libevm/FeeStructure.h>
#include <libevm/ExtVMFace.h>

#include "Utils.h"

extern "C"
{
	#ifdef _MSC_VER
		#define EXPORT __declspec(dllexport)
	#else
		#define EXPORT
	#endif

	using namespace dev;
	using namespace dev::eth;
	using jit::i256;

	EXPORT void env_sload(ExtVMFace* _env, i256* _index, i256* o_value)
	{
		auto index = llvm2eth(*_index);
		auto value = _env->store(index); // Interface uses native endianness
		*o_value = eth2llvm(value);
	}

	EXPORT void env_sstore(ExtVMFace* _env, i256* _index, i256* _value)
	{
		auto index = llvm2eth(*_index);
		auto value = llvm2eth(*_value);

		if (value == 0 && _env->store(index) != 0)	// If delete
			_env->sub.refunds += c_sstoreRefundGas;	// Increase refund counter

		_env->setStore(index, value);	// Interface uses native endianness
	}

	EXPORT void env_balance(ExtVMFace* _env, h256* _address, i256* o_value)
	{
		auto u = _env->balance(right160(*_address));
		*o_value = eth2llvm(u);
	}

	EXPORT void env_blockhash(ExtVMFace* _env, i256* _number, h256* o_hash)
	{
		*o_hash = _env->blockhash(llvm2eth(*_number));
	}

	EXPORT void env_create(ExtVMFace* _env, int64_t* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address)
	{
		auto endowment = llvm2eth(*_endowment);
		if (_env->balance(_env->myAddress) >= endowment && _env->depth < 1024)
		{
			_env->subBalance(endowment);
			u256 gas = *io_gas;
			h256 address(_env->create(endowment, gas, {_initBeg, _initSize}, {}), h256::AlignRight);
			*io_gas = static_cast<int64_t>(gas);
			*o_address = address;
		}
		else
			*o_address = {};
	}

	EXPORT bool env_call(ExtVMFace* _env, int64_t* io_gas, h256* _receiveAddress, i256* _value, byte* _inBeg, uint64_t _inSize, byte* _outBeg, uint64_t _outSize, h256* _codeAddress)
	{
		auto value = llvm2eth(*_value);
		if (_env->balance(_env->myAddress) >= value && _env->depth < 1024)
		{
			_env->subBalance(value);
			auto receiveAddress = right160(*_receiveAddress);
			auto inRef = bytesConstRef{_inBeg, _inSize};
			auto outRef = bytesRef{_outBeg, _outSize};
			auto codeAddress = right160(*_codeAddress);
			u256 gas = *io_gas;
			auto ret = _env->call(receiveAddress, value, inRef, gas, outRef, {}, {}, codeAddress);
			*io_gas = static_cast<int64_t>(gas);
			return ret;
		}

		return false;
	}

	EXPORT void env_sha3(byte* _begin, uint64_t _size, h256* o_hash)
	{
		auto hash = sha3({_begin, _size});
		*o_hash = hash;
	}

	EXPORT byte const* env_extcode(ExtVMFace* _env, h256* _addr256, uint64_t* o_size)
	{
		auto addr = right160(*_addr256);
		auto& code = _env->codeAt(addr);
		*o_size = code.size();
		return code.data();
	}

	EXPORT void env_log(ExtVMFace* _env, byte* _beg, uint64_t _size, h256* _topic1, h256* _topic2, h256* _topic3, h256* _topic4)
	{
		dev::h256s topics;

		if (_topic1)
			topics.push_back(*_topic1);

		if (_topic2)
			topics.push_back(*_topic2);

		if (_topic3)
			topics.push_back(*_topic3);

		if (_topic4)
			topics.push_back(*_topic4);

		_env->log(std::move(topics), {_beg, _size});
	}
}

<commit_msg>fix evmjit build<commit_after>
#pragma GCC diagnostic ignored "-Wconversion"
#include <libdevcrypto/SHA3.h>
#include <libethcore/Params.h>
#include <libevm/ExtVMFace.h>

#include "Utils.h"

extern "C"
{
	#ifdef _MSC_VER
		#define EXPORT __declspec(dllexport)
	#else
		#define EXPORT
	#endif

	using namespace dev;
	using namespace dev::eth;
	using jit::i256;

	EXPORT void env_sload(ExtVMFace* _env, i256* _index, i256* o_value)
	{
		auto index = llvm2eth(*_index);
		auto value = _env->store(index); // Interface uses native endianness
		*o_value = eth2llvm(value);
	}

	EXPORT void env_sstore(ExtVMFace* _env, i256* _index, i256* _value)
	{
		auto index = llvm2eth(*_index);
		auto value = llvm2eth(*_value);

		if (value == 0 && _env->store(index) != 0)	// If delete
			_env->sub.refunds += c_sstoreRefundGas;	// Increase refund counter

		_env->setStore(index, value);	// Interface uses native endianness
	}

	EXPORT void env_balance(ExtVMFace* _env, h256* _address, i256* o_value)
	{
		auto u = _env->balance(right160(*_address));
		*o_value = eth2llvm(u);
	}

	EXPORT void env_blockhash(ExtVMFace* _env, i256* _number, h256* o_hash)
	{
		*o_hash = _env->blockhash(llvm2eth(*_number));
	}

	EXPORT void env_create(ExtVMFace* _env, int64_t* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address)
	{
		auto endowment = llvm2eth(*_endowment);
		if (_env->balance(_env->myAddress) >= endowment && _env->depth < 1024)
		{
			_env->subBalance(endowment);
			u256 gas = *io_gas;
			h256 address(_env->create(endowment, gas, {_initBeg, _initSize}, {}), h256::AlignRight);
			*io_gas = static_cast<int64_t>(gas);
			*o_address = address;
		}
		else
			*o_address = {};
	}

	EXPORT bool env_call(ExtVMFace* _env, int64_t* io_gas, h256* _receiveAddress, i256* _value, byte* _inBeg, uint64_t _inSize, byte* _outBeg, uint64_t _outSize, h256* _codeAddress)
	{
		auto value = llvm2eth(*_value);
		if (_env->balance(_env->myAddress) >= value && _env->depth < 1024)
		{
			_env->subBalance(value);
			auto receiveAddress = right160(*_receiveAddress);
			auto inRef = bytesConstRef{_inBeg, _inSize};
			auto outRef = bytesRef{_outBeg, _outSize};
			auto codeAddress = right160(*_codeAddress);
			u256 gas = *io_gas;
			auto ret = _env->call(receiveAddress, value, inRef, gas, outRef, {}, {}, codeAddress);
			*io_gas = static_cast<int64_t>(gas);
			return ret;
		}

		return false;
	}

	EXPORT void env_sha3(byte* _begin, uint64_t _size, h256* o_hash)
	{
		auto hash = sha3({_begin, _size});
		*o_hash = hash;
	}

	EXPORT byte const* env_extcode(ExtVMFace* _env, h256* _addr256, uint64_t* o_size)
	{
		auto addr = right160(*_addr256);
		auto& code = _env->codeAt(addr);
		*o_size = code.size();
		return code.data();
	}

	EXPORT void env_log(ExtVMFace* _env, byte* _beg, uint64_t _size, h256* _topic1, h256* _topic2, h256* _topic3, h256* _topic4)
	{
		dev::h256s topics;

		if (_topic1)
			topics.push_back(*_topic1);

		if (_topic2)
			topics.push_back(*_topic2);

		if (_topic3)
			topics.push_back(*_topic3);

		if (_topic4)
			topics.push_back(*_topic4);

		_env->log(std::move(topics), {_beg, _size});
	}
}

<|endoftext|>


<commit_before>#include "problemes.h"
#include "combinatoire.h"
#include "utilitaires.h"
#include "chiffres.h"
#include "timer.h"

typedef unsigned long long nombre;

namespace {
    nombre g(nombre n, nombre m) {
        nombre c = combinatoire::coefficient_binomial(n, m);
        nombre k = 0;
        while (c % 2 == 0) {
            ++k;
            c >>= 1;
        }

        return k;
    }

    nombre F(nombre n) {
        size_t m = n + 1;
        size_t resultat = 0;
        for (size_t f = 2; f <= m; f *= 2) {
            resultat += (m % f != 0);
        }

        return resultat;
    }

    nombre S(nombre N) {
        // size_t resultat = 0;
        // for (size_t m = 2; m <= N + 1; ++m) {
        //     for (size_t f = 2; f <= m; f *= 2) {
        //         resultat += (m % f != 0);
        //     }
        // }
        //
        // return resultat;

        size_t L = N + 1;
        size_t resultat = 0;
        for (size_t f = 2; f < L; f *= 2) {
            resultat += L - (L / f + (f - 1));
        }

        return resultat;
    }
}

ENREGISTRER_PROBLEME(704, "Eulercoin") {
    // Define g(n, m) to be the largest integer k such that 2^k divides (n, m). For example,
    // (12 5) = 792 = 2^3 x 3² x 11, hence g(12, 5).
    //
    // Then define F(n) = { max(g(n, m) : 0 <= m <= n }. F(10) = 3 and F(100) = 6.
    //
    // Let S(N) = Sum_n=1..N F(n). You are given that S(100) = 389 and S(10'000'000) = 203222840.
    //
    // Find S(10^16).
    std::cout << "g(12, 5) = " << g(12, 5) << std::endl;
    std::cout << "F(10) = " << F(10) << std::endl;
    std::cout << "F(100) = " << F(100) << std::endl;
    std::cout << "S(100) = " << S(100) << std::endl;
    std::cout << "S(10'000'000) = " << S(10'000'000) << std::endl;

    // for (size_t n = 0; n < 30; ++n) {
    //     std::cout << n << '\t';
    //     std::cout << std::string(30 - n, ' ');
    //     for (size_t p = 0; p <= n; ++p) {
    //         std::cout << g(n, p) << ' ';
    //     }
    //     nombre ligne = n;
    //     auto c = chiffres::extraire_chiffres(ligne, 2);
    //     std::cout << std::string(30 - n, ' ')
    //               << F(n) << " "
    //               << " ("
    //               << std::count(c.begin(), c.end(), 0) << ", "
    //               << std::count(c.begin(), c.end(), 1) << ')'
    //               << "\t" << c << std::endl;
    // }

    size_t resultat = S(puissance::puissance<size_t>(10, 16u));
    return std::to_string(resultat);
}
<commit_msg>Update probleme704.cpp<commit_after>#include "problemes.h"
#include "combinatoire.h"
#include "utilitaires.h"
#include "chiffres.h"
#include "timer.h"

typedef unsigned long long nombre;

namespace {
    nombre g(nombre n, nombre m) {
        nombre c = combinatoire::coefficient_binomial(n, m);
        nombre k = 0;
        while (c % 2 == 0) {
            ++k;
            c >>= 1u;
        }

        return k;
    }

    nombre F(nombre n) {
        size_t m = n + 1;
        size_t resultat = 0;
        for (size_t f = 2; f <= m; f *= 2) {
            resultat += (m % f != 0);
        }

        return resultat;
    }

    nombre S(nombre N) {
        // size_t resultat = 0;
        // for (size_t m = 2; m <= N + 1; ++m) {
        //     for (size_t f = 2; f <= m; f *= 2) {
        //         resultat += (m % f != 0);
        //     }
        // }
        //
        // return resultat;

        size_t L = N + 1;
        size_t resultat = 0;
        for (size_t f = 2; f < L; f *= 2) {
            resultat += L - (L / f + (f - 1));
        }

        return resultat;
    }
}

ENREGISTRER_PROBLEME(704, "Eulercoin") {
    // Define g(n, m) to be the largest integer k such that 2^k divides (n, m). For example,
    // (12 5) = 792 = 2^3 x 3² x 11, hence g(12, 5).
    //
    // Then define F(n) = { max(g(n, m) : 0 <= m <= n }. F(10) = 3 and F(100) = 6.
    //
    // Let S(N) = Sum_n=1..N F(n). You are given that S(100) = 389 and S(10'000'000) = 203222840.
    //
    // Find S(10^16).
    std::cout << "g(12, 5) = " << g(12, 5) << std::endl;
    std::cout << "F(10) = " << F(10) << std::endl;
    std::cout << "F(100) = " << F(100) << std::endl;
    std::cout << "S(100) = " << S(100) << std::endl;
    std::cout << "S(10'000'000) = " << S(10'000'000) << std::endl;

    // for (size_t n = 0; n < 30; ++n) {
    //     std::cout << n << '\t';
    //     std::cout << std::string(30 - n, ' ');
    //     for (size_t p = 0; p <= n; ++p) {
    //         std::cout << g(n, p) << ' ';
    //     }
    //     nombre ligne = n;
    //     auto c = chiffres::extraire_chiffres(ligne, 2);
    //     std::cout << std::string(30 - n, ' ')
    //               << F(n) << " "
    //               << " ("
    //               << std::count(c.begin(), c.end(), 0) << ", "
    //               << std::count(c.begin(), c.end(), 1) << ')'
    //               << "\t" << c << std::endl;
    // }

    size_t resultat = S(puissance::puissance<size_t>(10, 16u));
    return std::to_string(resultat);
}
<|endoftext|>


<commit_before>#ifndef BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED
#define BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED

namespace BoostBuildProjectManager {
namespace Constants {

char const PROJECT_CONTEXT[] = "BoostBuildProjectManager.ProjectContext";
char const PROJECT_ID[]      = "BoostBuildProjectManager.BoostBuildProject";

char const MIMETYPE_PROJECT[] = "text/x-boostbuild-project";
char const MIMETYPE_JAMFILE[] = "application/vnd.boostbuild.v2";
char const MIMETYPE_FILES[]   = "application/vnd.boostbuild.files";

} // namespace Constants
} // namespace BoostBuildProjectManager

#endif // BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED
<commit_msg>Tweak mimetype for Jamfile.v2.files<commit_after>#ifndef BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED
#define BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED

namespace BoostBuildProjectManager {
namespace Constants {

char const PROJECT_CONTEXT[] = "BoostBuildProjectManager.ProjectContext";
char const PROJECT_ID[]      = "BoostBuildProjectManager.BoostBuildProject";

char const MIMETYPE_PROJECT[] = "text/x-boostbuild-project";
char const MIMETYPE_JAMFILE[] = "application/vnd.boostbuild.v2";
char const MIMETYPE_FILES[]   = "application/vnd.qtcreator.boostbuild.files";

} // namespace Constants
} // namespace BoostBuildProjectManager

#endif // BBPROJECTMANAGERCONSTANTS_HPP_INCLUDED
<|endoftext|>


<commit_before>/**
 * @file
 * @author Jason Lingle
 * @date 2012.02.06
 * @brief Implementation of the GameAdvertiser class
 */

#include <cstring>
#include <iostream>
#include <vector>

#include "game_advertiser.hxx"
#include "antenna.hxx"
#include "tuner.hxx"
#include "abuhops.hxx"
#include "io.hxx"

using namespace std;

static const byte trigger[] = {'A', 'b', 'e', 'n', 'd', 's', 'u', 'c', 'h'};

GameAdvertiser::GameAdvertiser(Tuner* tuner_,
                               bool v6_,
                               Uint32 overseerid_,
                               byte peerCount_,
                               bool passwordProtected_,
                               const char* gameMode_,
                               bool isInternet_)
: tuner(tuner_), v6(v6_),
  overseerid(overseerid_),
  peerCount(peerCount_),
  passwordProtected(passwordProtected_),
  isInternet(isInternet_)
{
  setGameMode(gameMode_);
  if (!isInternet)
    tuner->trigger(trigger, sizeof(trigger), this);
}

GameAdvertiser::~GameAdvertiser() {
  if (!isInternet)
    tuner->untrigger(trigger, sizeof(trigger));
}

void GameAdvertiser::setOverseerId(Uint32 oid) {
  overseerid = oid;
  postIfNeeded();
}

void GameAdvertiser::setPeerCount(byte cnt) {
  peerCount = cnt;
  postIfNeeded();
}

void GameAdvertiser::setGameMode(const char* mode) {
  strncpy(gameMode, mode, 4);
  postIfNeeded();
}

void GameAdvertiser::process(const Antenna::endpoint& source,
                             Antenna* antenna, Tuner* tuner,
                             const byte* data, unsigned len)
noth {
  //Ignore if it is the wrong protocol, or this is an Internet game
  if (v6 == (source.protocol() == asio::ip::udp::v6()) && !isInternet) {
    //OK
    byte pack[] = {
      'A', 'b', 'e', 'n', 'd', 's', 'p', 'i', 'e', 'l',
      (byte)(overseerid >> 24),
      (byte)(overseerid >> 16),
      (byte)(overseerid >>  8),
      (byte)(overseerid >>  0),
      peerCount, passwordProtected,
      (byte)gameMode[0], (byte)gameMode[1],
      (byte)gameMode[2], (byte)gameMode[3],
    };
    try {
      antenna->send(source, pack, sizeof(pack));
    } catch (asio::system_error e) {
      cerr << "Warning: Unable to respond to Abendsuch from " << source
           << ": " << e.what() << endl;
    }
  }
}

void GameAdvertiser::postIfNeeded() {
  if (isInternet) {
    vector<byte> pack(10 + 4 + 2 + 2*(v6? 8*2+2 : 4+2) + 4);
    memcpy(&pack[0], "Abendspiel", 10);
    byte* dst = &pack[10];
    io::write(dst, overseerid);
    io::write(dst, peerCount);
    io::write(dst, (byte)v6);
    if (v6) {
      GlobalID& gid(*antenna.getGlobalID6());
      io::a6fromhbo(dst, gid.la6);
      dst += 2*8;
      io::write(dst, gid.lport);
      io::a6fromhbo(dst, gid.ia6);
      dst += 2*8;
      io::write(dst, gid.iport);
    } else {
      GlobalID& gid(*antenna.getGlobalID4());
      memcpy(dst, gid.la4, 4);
      dst += 4;
      io::write(dst, gid.lport);
      memcpy(dst, gid.ia4, 4);
      dst += 4;
      io::write(dst, gid.iport);
    }

    memcpy(dst, gameMode, sizeof(gameMode));

    abuhops::post(v6, &pack[0], pack.size());
  }
}
<commit_msg>Fix byte order of OID in Abendspiel LAN packets.<commit_after>/**
 * @file
 * @author Jason Lingle
 * @date 2012.02.06
 * @brief Implementation of the GameAdvertiser class
 */

#include <cstring>
#include <iostream>
#include <vector>

#include "game_advertiser.hxx"
#include "antenna.hxx"
#include "tuner.hxx"
#include "abuhops.hxx"
#include "io.hxx"

using namespace std;

static const byte trigger[] = {'A', 'b', 'e', 'n', 'd', 's', 'u', 'c', 'h'};

GameAdvertiser::GameAdvertiser(Tuner* tuner_,
                               bool v6_,
                               Uint32 overseerid_,
                               byte peerCount_,
                               bool passwordProtected_,
                               const char* gameMode_,
                               bool isInternet_)
: tuner(tuner_), v6(v6_),
  overseerid(overseerid_),
  peerCount(peerCount_),
  passwordProtected(passwordProtected_),
  isInternet(isInternet_)
{
  setGameMode(gameMode_);
  if (!isInternet)
    tuner->trigger(trigger, sizeof(trigger), this);
}

GameAdvertiser::~GameAdvertiser() {
  if (!isInternet)
    tuner->untrigger(trigger, sizeof(trigger));
}

void GameAdvertiser::setOverseerId(Uint32 oid) {
  overseerid = oid;
  postIfNeeded();
}

void GameAdvertiser::setPeerCount(byte cnt) {
  peerCount = cnt;
  postIfNeeded();
}

void GameAdvertiser::setGameMode(const char* mode) {
  strncpy(gameMode, mode, 4);
  postIfNeeded();
}

void GameAdvertiser::process(const Antenna::endpoint& source,
                             Antenna* antenna, Tuner* tuner,
                             const byte* data, unsigned len)
noth {
  //Ignore if it is the wrong protocol, or this is an Internet game
  if (v6 == (source.protocol() == asio::ip::udp::v6()) && !isInternet) {
    //OK
    byte pack[] = {
      'A', 'b', 'e', 'n', 'd', 's', 'p', 'i', 'e', 'l',
      (byte)(overseerid >>  0),
      (byte)(overseerid >>  8),
      (byte)(overseerid >> 16),
      (byte)(overseerid >> 24),
      peerCount, passwordProtected,
      (byte)gameMode[0], (byte)gameMode[1],
      (byte)gameMode[2], (byte)gameMode[3],
    };
    try {
      antenna->send(source, pack, sizeof(pack));
    } catch (asio::system_error e) {
      cerr << "Warning: Unable to respond to Abendsuch from " << source
           << ": " << e.what() << endl;
    }
  }
}

void GameAdvertiser::postIfNeeded() {
  if (isInternet) {
    vector<byte> pack(10 + 4 + 2 + 2*(v6? 8*2+2 : 4+2) + 4);
    memcpy(&pack[0], "Abendspiel", 10);
    byte* dst = &pack[10];
    io::write(dst, overseerid);
    io::write(dst, peerCount);
    io::write(dst, (byte)v6);
    if (v6) {
      GlobalID& gid(*antenna.getGlobalID6());
      io::a6fromhbo(dst, gid.la6);
      dst += 2*8;
      io::write(dst, gid.lport);
      io::a6fromhbo(dst, gid.ia6);
      dst += 2*8;
      io::write(dst, gid.iport);
    } else {
      GlobalID& gid(*antenna.getGlobalID4());
      memcpy(dst, gid.la4, 4);
      dst += 4;
      io::write(dst, gid.lport);
      memcpy(dst, gid.ia4, 4);
      dst += 4;
      io::write(dst, gid.iport);
    }

    memcpy(dst, gameMode, sizeof(gameMode));

    abuhops::post(v6, &pack[0], pack.size());
  }
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2017 Realm Inc.
//
// 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 "sync/sync_permission.hpp"

#include "impl/notification_wrapper.hpp"
#include "impl/object_accessor_impl.hpp"
#include "object_schema.hpp"
#include "property.hpp"

#include "sync/sync_config.hpp"
#include "sync/sync_manager.hpp"
#include "sync/sync_session.hpp"
#include "sync/sync_user.hpp"
#include "util/event_loop_signal.hpp"
#include "util/uuid.hpp"

#include <realm/query_expression.hpp>

using namespace realm;
using namespace std::chrono;

// MARK: - Utility

namespace {

// Make a handler that extracts either an exception pointer, or the string value
// of the property with the specified name.
Permissions::AsyncOperationHandler make_handler_extracting_property(std::string property,
                                                                    Permissions::PermissionOfferCallback callback)
{
    return [property=std::move(property),
            callback=std::move(callback)](Object* object, std::exception_ptr exception) {
        if (exception) {
            callback(none, exception);
        } else {
            CppContext context;
            auto token = any_cast<std::string>(object->get_property_value<util::Any>(context, property));
            callback(util::make_optional<std::string>(std::move(token)), nullptr);
        }
    };
}

AccessLevel extract_access_level(Object& permission, CppContext& context)
{
    auto may_manage = permission.get_property_value<util::Any>(context, "mayManage");
    if (may_manage.has_value() && any_cast<bool>(may_manage))
        return AccessLevel::Admin;

    auto may_write = permission.get_property_value<util::Any>(context, "mayWrite");
    if (may_write.has_value() && any_cast<bool>(may_write))
        return AccessLevel::Write;

    auto may_read = permission.get_property_value<util::Any>(context, "mayRead");
    if (may_read.has_value() && any_cast<bool>(may_read))
        return AccessLevel::Read;

    return AccessLevel::None;
}

/// Turn a system time point value into the 64-bit integer representing ns since the Unix epoch.
int64_t ns_since_unix_epoch(const system_clock::time_point& point)
{
    tm unix_epoch{};
    unix_epoch.tm_year = 70;
    time_t epoch_time = mktime(&unix_epoch);
    auto epoch_point = system_clock::from_time_t(epoch_time);
    return duration_cast<nanoseconds>(point - epoch_point).count();
}

} // anonymous namespace

// MARK: - Permission

Permission::Permission(Object& permission)
{
    CppContext context;
    path = any_cast<std::string>(permission.get_property_value<util::Any>(context, "path"));
    access = extract_access_level(permission, context);
    condition = Condition(any_cast<std::string>(permission.get_property_value<util::Any>(context, "userId")));
    updated_at = any_cast<Timestamp>(permission.get_property_value<util::Any>(context, "updatedAt"));
}

Permission::Permission(std::string path, AccessLevel access, Condition condition, Timestamp updated_at)
: path(std::move(path))
, access(access)
, condition(std::move(condition))
, updated_at(std::move(updated_at))
{ }

std::string Permission::description_for_access_level(AccessLevel level)
{
    switch (level) {
        case AccessLevel::None: return "none";
        case AccessLevel::Read: return "read";
        case AccessLevel::Write: return "write";
        case AccessLevel::Admin: return "admin";
    }
    REALM_UNREACHABLE();
}

bool Permission::paths_are_equivalent(std::string path_1, std::string path_2,
                                      const std::string& user_id_1, const std::string& user_id_2)
{
    REALM_ASSERT_DEBUG(path_1.length() > 0);
    REALM_ASSERT_DEBUG(path_2.length() > 0);
    if (path_1 == path_2) {
        // If both paths are identical and contain `/~/`, the user IDs must match.
        return (path_1.find("/~/") == std::string::npos) || (user_id_1 == user_id_2);
    }
    // Make substitutions for the first `/~/` in the string.
    size_t index = path_1.find("/~/");
    if (index != std::string::npos)
        path_1.replace(index + 1, 1, user_id_1);

    index = path_2.find("/~/");
    if (index != std::string::npos)
        path_2.replace(index + 1, 1, user_id_2);

    return path_1 == path_2;
}

// MARK: - Permissions

void Permissions::get_permissions(std::shared_ptr<SyncUser> user,
                                  PermissionResultsCallback callback,
                                  const ConfigMaker& make_config)
{
    auto realm = Permissions::permission_realm(user, make_config);
    auto table = ObjectStore::table_for_object_type(realm->read_group(), "Permission");
    auto results = std::make_shared<_impl::NotificationWrapper<Results>>(std::move(realm), *table);

    // `get_permissions` works by temporarily adding an async notifier to the permission Realm.
    // This notifier will run the `async` callback until the Realm contains permissions or
    // an error happens. When either of these two things happen, the notifier will be
    // unregistered by nulling out the `results_wrapper` container.
    auto async = [results, callback=std::move(callback)](CollectionChangeSet, std::exception_ptr ex) mutable {
        if (ex) {
            callback(Results(), ex);
            results.reset();
            return;
        }
        if (results->size() > 0) {
            // We monitor the raw results. The presence of a `__management` Realm indicates
            // that the permissions have been downloaded (hence, we wait until size > 0).
            TableRef table = ObjectStore::table_for_object_type(results->get_realm()->read_group(), "Permission");
            size_t col_idx = table->get_descriptor()->get_column_index("path");
            auto query = !(table->column<StringData>(col_idx).ends_with("/__permission")
                           || table->column<StringData>(col_idx).ends_with("/__management"));
            // Call the callback with our new permissions object. This object will exclude the
            // private Realms.
            callback(results->filter(std::move(query)), nullptr);
            results.reset();
        }
    };
    results->add_notification_callback(std::move(async));
}

void Permissions::set_permission(std::shared_ptr<SyncUser> user,
                                 Permission permission,
                                 PermissionChangeCallback callback,
                                 const ConfigMaker& make_config)
{
    auto props = AnyDict{
        {"userId", permission.condition.user_id},
        {"realmUrl", user->server_url() + permission.path},
        {"mayRead", permission.access != AccessLevel::None},
        {"mayWrite", permission.access == AccessLevel::Write || permission.access == AccessLevel::Admin},
        {"mayManage", permission.access == AccessLevel::Admin},
    };
    if (permission.condition.type == Permission::Condition::Type::KeyValue) {
        props.insert({"metadataKey", permission.condition.key_value.first});
        props.insert({"metadataValue", permission.condition.key_value.second});
    }
    auto cb = [callback=std::move(callback)](Object*, std::exception_ptr exception) {
        callback(exception);
    };
    perform_async_operation("PermissionChange", std::move(user), std::move(cb), std::move(props), make_config);
}

void Permissions::delete_permission(std::shared_ptr<SyncUser> user,
                                    Permission permission,
                                    PermissionChangeCallback callback,
                                    const ConfigMaker& make_config)
{
    permission.access = AccessLevel::None;
    set_permission(std::move(user), std::move(permission), std::move(callback), make_config);
}

void Permissions::make_offer(std::shared_ptr<SyncUser> user,
                             PermissionOffer offer,
                             PermissionOfferCallback callback,
                             const ConfigMaker& make_config)
{
    auto props = AnyDict{
        {"expiresAt", std::move(offer.expiration)},
        {"userId", user->identity()},
        {"realmUrl", user->server_url() + offer.path},
        {"mayRead", offer.access != AccessLevel::None},
        {"mayWrite", offer.access == AccessLevel::Write || offer.access == AccessLevel::Admin},
        {"mayManage", offer.access == AccessLevel::Admin},
    };
    perform_async_operation("PermissionOffer",
                            std::move(user),
                            make_handler_extracting_property("token", std::move(callback)),
                            std::move(props),
                            make_config);
}

void Permissions::accept_offer(std::shared_ptr<SyncUser> user,
                               const std::string& token,
                               PermissionOfferCallback callback,
                               const ConfigMaker& make_config)
{
    perform_async_operation("PermissionOfferResponse",
                            std::move(user),
                            make_handler_extracting_property("realmUrl", std::move(callback)),
                            AnyDict{ {"token", token} },
                            make_config);
}

void Permissions::perform_async_operation(const std::string& object_type,
                                          std::shared_ptr<SyncUser> user,
                                          AsyncOperationHandler handler,
                                          AnyDict additional_props,
                                          const ConfigMaker& make_config)
{;
    auto realm = Permissions::management_realm(std::move(user), make_config);
    CppContext context;

    // Get the current time.
    int64_t ns_since_epoch = ns_since_unix_epoch(system_clock::now());
    int64_t s_arg = ns_since_epoch / (int64_t)Timestamp::nanoseconds_per_second;
    int32_t ns_arg = ns_since_epoch % Timestamp::nanoseconds_per_second;

    auto props = AnyDict{
        {"id", util::uuid_string()},
        {"createdAt", Timestamp(s_arg, ns_arg)},
        {"updatedAt", Timestamp(s_arg, ns_arg)},
    };
    props.insert(additional_props.begin(), additional_props.end());

    // Write the permission object.
    realm->begin_transaction();
    auto raw = Object::create<util::Any>(context, realm, *realm->schema().find(object_type), std::move(props), false);
    auto object = std::make_shared<_impl::NotificationWrapper<Object>>(std::move(raw));
    realm->commit_transaction();

    // Observe the permission object until the permission change has been processed or failed.
    // The notifier is automatically unregistered upon the completion of the permission
    // change, one way or another.
    auto block = [object, handler=std::move(handler)](CollectionChangeSet, std::exception_ptr ex) mutable {
        if (ex) {
            handler(nullptr, ex);
            object.reset();
            return;
        }

        CppContext context;
        auto status_code = object->get_property_value<util::Any>(context, "statusCode");
        if (!status_code.has_value()) {
            // Continue waiting for the sync server to complete the operation.
            return;
        }

        // Determine whether an error happened or not.
        if (auto code = any_cast<long long>(status_code)) {
            // The permission change failed because an error was returned from the server.
            auto status = object->get_property_value<util::Any>(context, "statusMessage");
            std::string error_str = (status.has_value()
                                     ? any_cast<std::string>(status)
                                     : util::format("Error code: %1", code));
            handler(nullptr, std::make_exception_ptr(PermissionActionException(error_str, code)));
        }
        else {
            handler(object.get(), nullptr);
        }
        object.reset();
    };
    object->add_notification_callback(std::move(block));
}

SharedRealm Permissions::management_realm(std::shared_ptr<SyncUser> user, const ConfigMaker& make_config)
{
    // FIXME: maybe we should cache the management Realm on the user, so we don't need to open it every time.
    const auto realm_url = util::format("realm%1/~/__management", user->server_url().substr(4));
    Realm::Config config = make_config(user, std::move(realm_url));
    config.sync_config->stop_policy = SyncSessionStopPolicy::Immediately;
    config.schema = Schema{
        {"PermissionChange", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"userId",            PropertyType::String},
            Property{"metadataKey",       PropertyType::String|PropertyType::Nullable},
            Property{"metadataValue",     PropertyType::String|PropertyType::Nullable},
            Property{"metadataNameSpace", PropertyType::String|PropertyType::Nullable},
            Property{"realmUrl",          PropertyType::String},
            Property{"mayRead",           PropertyType::Bool|PropertyType::Nullable},
            Property{"mayWrite",          PropertyType::Bool|PropertyType::Nullable},
            Property{"mayManage",         PropertyType::Bool|PropertyType::Nullable},
        }},
        {"PermissionOffer", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"expiresAt",         PropertyType::Date|PropertyType::Nullable},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"token",             PropertyType::String|PropertyType::Nullable},
            Property{"realmUrl",          PropertyType::String},
            Property{"mayRead",           PropertyType::Bool},
            Property{"mayWrite",          PropertyType::Bool},
            Property{"mayManage",         PropertyType::Bool},
        }},
        {"PermissionOfferResponse", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"token",             PropertyType::String},
            Property{"realmUrl",          PropertyType::String|PropertyType::Nullable},
        }},
    };
    config.schema_version = 0;
    auto shared_realm = Realm::get_shared_realm(std::move(config));
    user->register_management_session(config.path);
    return shared_realm;
}

SharedRealm Permissions::permission_realm(std::shared_ptr<SyncUser> user, const ConfigMaker& make_config)
{
    // FIXME: maybe we should cache the permission Realm on the user, so we don't need to open it every time.
    const auto realm_url = util::format("realm%1/~/__permission", user->server_url().substr(4));
    Realm::Config config = make_config(user, std::move(realm_url));
    config.sync_config->stop_policy = SyncSessionStopPolicy::Immediately;
    config.schema = Schema{
        {"Permission", {
            {"updatedAt", PropertyType::Date},
            {"userId", PropertyType::String},
            {"path", PropertyType::String},
            {"mayRead", PropertyType::Bool},
            {"mayWrite", PropertyType::Bool},
            {"mayManage", PropertyType::Bool},
        }}
    };
    config.schema_version = 0;
    auto shared_realm = Realm::get_shared_realm(std::move(config));
    user->register_permission_session(config.path);
    return shared_realm;
}
<commit_msg>Fix two use-after-move issues flagged in sync-related code<commit_after>////////////////////////////////////////////////////////////////////////////
//
// Copyright 2017 Realm Inc.
//
// 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 "sync/sync_permission.hpp"

#include "impl/notification_wrapper.hpp"
#include "impl/object_accessor_impl.hpp"
#include "object_schema.hpp"
#include "property.hpp"

#include "sync/sync_config.hpp"
#include "sync/sync_manager.hpp"
#include "sync/sync_session.hpp"
#include "sync/sync_user.hpp"
#include "util/event_loop_signal.hpp"
#include "util/uuid.hpp"

#include <realm/query_expression.hpp>

using namespace realm;
using namespace std::chrono;

// MARK: - Utility

namespace {

// Make a handler that extracts either an exception pointer, or the string value
// of the property with the specified name.
Permissions::AsyncOperationHandler make_handler_extracting_property(std::string property,
                                                                    Permissions::PermissionOfferCallback callback)
{
    return [property=std::move(property),
            callback=std::move(callback)](Object* object, std::exception_ptr exception) {
        if (exception) {
            callback(none, exception);
        } else {
            CppContext context;
            auto token = any_cast<std::string>(object->get_property_value<util::Any>(context, property));
            callback(util::make_optional<std::string>(std::move(token)), nullptr);
        }
    };
}

AccessLevel extract_access_level(Object& permission, CppContext& context)
{
    auto may_manage = permission.get_property_value<util::Any>(context, "mayManage");
    if (may_manage.has_value() && any_cast<bool>(may_manage))
        return AccessLevel::Admin;

    auto may_write = permission.get_property_value<util::Any>(context, "mayWrite");
    if (may_write.has_value() && any_cast<bool>(may_write))
        return AccessLevel::Write;

    auto may_read = permission.get_property_value<util::Any>(context, "mayRead");
    if (may_read.has_value() && any_cast<bool>(may_read))
        return AccessLevel::Read;

    return AccessLevel::None;
}

/// Turn a system time point value into the 64-bit integer representing ns since the Unix epoch.
int64_t ns_since_unix_epoch(const system_clock::time_point& point)
{
    tm unix_epoch{};
    unix_epoch.tm_year = 70;
    time_t epoch_time = mktime(&unix_epoch);
    auto epoch_point = system_clock::from_time_t(epoch_time);
    return duration_cast<nanoseconds>(point - epoch_point).count();
}

} // anonymous namespace

// MARK: - Permission

Permission::Permission(Object& permission)
{
    CppContext context;
    path = any_cast<std::string>(permission.get_property_value<util::Any>(context, "path"));
    access = extract_access_level(permission, context);
    condition = Condition(any_cast<std::string>(permission.get_property_value<util::Any>(context, "userId")));
    updated_at = any_cast<Timestamp>(permission.get_property_value<util::Any>(context, "updatedAt"));
}

Permission::Permission(std::string path, AccessLevel access, Condition condition, Timestamp updated_at)
: path(std::move(path))
, access(access)
, condition(std::move(condition))
, updated_at(std::move(updated_at))
{ }

std::string Permission::description_for_access_level(AccessLevel level)
{
    switch (level) {
        case AccessLevel::None: return "none";
        case AccessLevel::Read: return "read";
        case AccessLevel::Write: return "write";
        case AccessLevel::Admin: return "admin";
    }
    REALM_UNREACHABLE();
}

bool Permission::paths_are_equivalent(std::string path_1, std::string path_2,
                                      const std::string& user_id_1, const std::string& user_id_2)
{
    REALM_ASSERT_DEBUG(path_1.length() > 0);
    REALM_ASSERT_DEBUG(path_2.length() > 0);
    if (path_1 == path_2) {
        // If both paths are identical and contain `/~/`, the user IDs must match.
        return (path_1.find("/~/") == std::string::npos) || (user_id_1 == user_id_2);
    }
    // Make substitutions for the first `/~/` in the string.
    size_t index = path_1.find("/~/");
    if (index != std::string::npos)
        path_1.replace(index + 1, 1, user_id_1);

    index = path_2.find("/~/");
    if (index != std::string::npos)
        path_2.replace(index + 1, 1, user_id_2);

    return path_1 == path_2;
}

// MARK: - Permissions

void Permissions::get_permissions(std::shared_ptr<SyncUser> user,
                                  PermissionResultsCallback callback,
                                  const ConfigMaker& make_config)
{
    auto realm = Permissions::permission_realm(user, make_config);
    auto table = ObjectStore::table_for_object_type(realm->read_group(), "Permission");
    auto results = std::make_shared<_impl::NotificationWrapper<Results>>(std::move(realm), *table);

    // `get_permissions` works by temporarily adding an async notifier to the permission Realm.
    // This notifier will run the `async` callback until the Realm contains permissions or
    // an error happens. When either of these two things happen, the notifier will be
    // unregistered by nulling out the `results_wrapper` container.
    auto async = [results, callback=std::move(callback)](CollectionChangeSet, std::exception_ptr ex) mutable {
        if (ex) {
            callback(Results(), ex);
            results.reset();
            return;
        }
        if (results->size() > 0) {
            // We monitor the raw results. The presence of a `__management` Realm indicates
            // that the permissions have been downloaded (hence, we wait until size > 0).
            TableRef table = ObjectStore::table_for_object_type(results->get_realm()->read_group(), "Permission");
            size_t col_idx = table->get_descriptor()->get_column_index("path");
            auto query = !(table->column<StringData>(col_idx).ends_with("/__permission")
                           || table->column<StringData>(col_idx).ends_with("/__management"));
            // Call the callback with our new permissions object. This object will exclude the
            // private Realms.
            callback(results->filter(std::move(query)), nullptr);
            results.reset();
        }
    };
    results->add_notification_callback(std::move(async));
}

void Permissions::set_permission(std::shared_ptr<SyncUser> user,
                                 Permission permission,
                                 PermissionChangeCallback callback,
                                 const ConfigMaker& make_config)
{
    auto props = AnyDict{
        {"userId", permission.condition.user_id},
        {"realmUrl", user->server_url() + permission.path},
        {"mayRead", permission.access != AccessLevel::None},
        {"mayWrite", permission.access == AccessLevel::Write || permission.access == AccessLevel::Admin},
        {"mayManage", permission.access == AccessLevel::Admin},
    };
    if (permission.condition.type == Permission::Condition::Type::KeyValue) {
        props.insert({"metadataKey", permission.condition.key_value.first});
        props.insert({"metadataValue", permission.condition.key_value.second});
    }
    auto cb = [callback=std::move(callback)](Object*, std::exception_ptr exception) {
        callback(exception);
    };
    perform_async_operation("PermissionChange", std::move(user), std::move(cb), std::move(props), make_config);
}

void Permissions::delete_permission(std::shared_ptr<SyncUser> user,
                                    Permission permission,
                                    PermissionChangeCallback callback,
                                    const ConfigMaker& make_config)
{
    permission.access = AccessLevel::None;
    set_permission(std::move(user), std::move(permission), std::move(callback), make_config);
}

void Permissions::make_offer(std::shared_ptr<SyncUser> user,
                             PermissionOffer offer,
                             PermissionOfferCallback callback,
                             const ConfigMaker& make_config)
{
    auto props = AnyDict{
        {"expiresAt", std::move(offer.expiration)},
        {"userId", user->identity()},
        {"realmUrl", user->server_url() + offer.path},
        {"mayRead", offer.access != AccessLevel::None},
        {"mayWrite", offer.access == AccessLevel::Write || offer.access == AccessLevel::Admin},
        {"mayManage", offer.access == AccessLevel::Admin},
    };
    perform_async_operation("PermissionOffer",
                            std::move(user),
                            make_handler_extracting_property("token", std::move(callback)),
                            std::move(props),
                            make_config);
}

void Permissions::accept_offer(std::shared_ptr<SyncUser> user,
                               const std::string& token,
                               PermissionOfferCallback callback,
                               const ConfigMaker& make_config)
{
    perform_async_operation("PermissionOfferResponse",
                            std::move(user),
                            make_handler_extracting_property("realmUrl", std::move(callback)),
                            AnyDict{ {"token", token} },
                            make_config);
}

void Permissions::perform_async_operation(const std::string& object_type,
                                          std::shared_ptr<SyncUser> user,
                                          AsyncOperationHandler handler,
                                          AnyDict additional_props,
                                          const ConfigMaker& make_config)
{;
    auto realm = Permissions::management_realm(std::move(user), make_config);
    CppContext context;

    // Get the current time.
    int64_t ns_since_epoch = ns_since_unix_epoch(system_clock::now());
    int64_t s_arg = ns_since_epoch / (int64_t)Timestamp::nanoseconds_per_second;
    int32_t ns_arg = ns_since_epoch % Timestamp::nanoseconds_per_second;

    auto props = AnyDict{
        {"id", util::uuid_string()},
        {"createdAt", Timestamp(s_arg, ns_arg)},
        {"updatedAt", Timestamp(s_arg, ns_arg)},
    };
    props.insert(additional_props.begin(), additional_props.end());

    // Write the permission object.
    realm->begin_transaction();
    auto raw = Object::create<util::Any>(context, realm, *realm->schema().find(object_type), std::move(props), false);
    auto object = std::make_shared<_impl::NotificationWrapper<Object>>(std::move(raw));
    realm->commit_transaction();

    // Observe the permission object until the permission change has been processed or failed.
    // The notifier is automatically unregistered upon the completion of the permission
    // change, one way or another.
    auto block = [object, handler=std::move(handler)](CollectionChangeSet, std::exception_ptr ex) mutable {
        if (ex) {
            handler(nullptr, ex);
            object.reset();
            return;
        }

        CppContext context;
        auto status_code = object->get_property_value<util::Any>(context, "statusCode");
        if (!status_code.has_value()) {
            // Continue waiting for the sync server to complete the operation.
            return;
        }

        // Determine whether an error happened or not.
        if (auto code = any_cast<long long>(status_code)) {
            // The permission change failed because an error was returned from the server.
            auto status = object->get_property_value<util::Any>(context, "statusMessage");
            std::string error_str = (status.has_value()
                                     ? any_cast<std::string>(status)
                                     : util::format("Error code: %1", code));
            handler(nullptr, std::make_exception_ptr(PermissionActionException(error_str, code)));
        }
        else {
            handler(object.get(), nullptr);
        }
        object.reset();
    };
    object->add_notification_callback(std::move(block));
}

SharedRealm Permissions::management_realm(std::shared_ptr<SyncUser> user, const ConfigMaker& make_config)
{
    // FIXME: maybe we should cache the management Realm on the user, so we don't need to open it every time.
    const auto realm_url = util::format("realm%1/~/__management", user->server_url().substr(4));
    Realm::Config config = make_config(user, std::move(realm_url));
    config.sync_config->stop_policy = SyncSessionStopPolicy::Immediately;
    config.schema = Schema{
        {"PermissionChange", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"userId",            PropertyType::String},
            Property{"metadataKey",       PropertyType::String|PropertyType::Nullable},
            Property{"metadataValue",     PropertyType::String|PropertyType::Nullable},
            Property{"metadataNameSpace", PropertyType::String|PropertyType::Nullable},
            Property{"realmUrl",          PropertyType::String},
            Property{"mayRead",           PropertyType::Bool|PropertyType::Nullable},
            Property{"mayWrite",          PropertyType::Bool|PropertyType::Nullable},
            Property{"mayManage",         PropertyType::Bool|PropertyType::Nullable},
        }},
        {"PermissionOffer", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"expiresAt",         PropertyType::Date|PropertyType::Nullable},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"token",             PropertyType::String|PropertyType::Nullable},
            Property{"realmUrl",          PropertyType::String},
            Property{"mayRead",           PropertyType::Bool},
            Property{"mayWrite",          PropertyType::Bool},
            Property{"mayManage",         PropertyType::Bool},
        }},
        {"PermissionOfferResponse", {
            Property{"id",                PropertyType::String, Property::IsPrimary{true}},
            Property{"createdAt",         PropertyType::Date},
            Property{"updatedAt",         PropertyType::Date},
            Property{"statusCode",        PropertyType::Int|PropertyType::Nullable},
            Property{"statusMessage",     PropertyType::String|PropertyType::Nullable},
            Property{"token",             PropertyType::String},
            Property{"realmUrl",          PropertyType::String|PropertyType::Nullable},
        }},
    };
    config.schema_version = 0;
    auto shared_realm = Realm::get_shared_realm(std::move(config));
    user->register_management_session(shared_realm->config().path);
    return shared_realm;
}

SharedRealm Permissions::permission_realm(std::shared_ptr<SyncUser> user, const ConfigMaker& make_config)
{
    // FIXME: maybe we should cache the permission Realm on the user, so we don't need to open it every time.
    const auto realm_url = util::format("realm%1/~/__permission", user->server_url().substr(4));
    Realm::Config config = make_config(user, std::move(realm_url));
    config.sync_config->stop_policy = SyncSessionStopPolicy::Immediately;
    config.schema = Schema{
        {"Permission", {
            {"updatedAt", PropertyType::Date},
            {"userId", PropertyType::String},
            {"path", PropertyType::String},
            {"mayRead", PropertyType::Bool},
            {"mayWrite", PropertyType::Bool},
            {"mayManage", PropertyType::Bool},
        }}
    };
    config.schema_version = 0;
    auto shared_realm = Realm::get_shared_realm(std::move(config));
    user->register_permission_session(shared_realm->config().path);
    return shared_realm;
}
<|endoftext|>


<commit_before>#include "attributesmodel.h"

#include <QBrush>

#include <model/devisersettings.h>
#include <model/deviserattribute.h>

AttributesModel::AttributesModel(
    QObject * parent,
    QList<DeviserAttribute*>* data)
  : QAbstractTableModel(parent)
  , mData(data)
{

}

int
AttributesModel::rowCount(const QModelIndex &) const
{
  return mData->count();
}

int
AttributesModel::columnCount(const QModelIndex &) const
{
  return 6;
}

Qt::ItemFlags
AttributesModel::flags(const QModelIndex &index) const
{
  if (!index.isValid())
    return Qt::ItemIsEnabled;
  return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}

QVariant
AttributesModel::data(const QModelIndex &index, int role) const
{
  if (role == Qt::ToolTipRole)
  {
    switch(index.column())
    {
    case NAME:
      return "The name of the attribute/element to be used by code generation.  The XML output may use a different name (see XML Name). This field is required.";
    case TYPE:
      return "The type of the attribute/element. Allowed values are: SId, SIdRef, string, bool, double, int, unsigned int, IDREF, UnitSId, UnitSIdRef, enum, element, lo_element, inline_lo_element. This field is required.";
    case REQUIRED:
      return "States whether the attribute or element is mandatory. This should be true if the attribute/element is mandatory; false if not.";
    case ELEMENT:
      return "This field provides additional information depending on the Type of the attribute/element. It may be the name of the element, enumeration or object being referenced. This field is required for attributes of type SIdRef, array, enum, element, lo_element, inline_lo_element, vector.";
    case ABSTRACT:
      return "States whether this element is a base class. This should be true if the element is a base class and therefore not instantiated directly; false if not.";
    case XMLName:
      return "The name of the attribute/element as used by the XML output. If blank, this defaults to the Name given.";
    default:
      return QVariant();
    }
  }

  if (role == Qt::BackgroundRole)
  {
    switch(index.column())
    {
    case TYPE:
    case NAME:
      if (index.data().toString().isEmpty())
        return QBrush(DeviserSettings::getInstance()->getValidationColor());
      else
        return QVariant();

    case ELEMENT:
    {
      QString element = index.data().toString();
      if (!element.isEmpty())
        return QVariant();

      QString type = index.model()->index(index.row(), TYPE).data().toString();
      if (type == "element"
          || type == "inline_lo_element"
          || type == "lo_element"
          || type == "enum"
          || type == "array"
          || type == "vector"
          || type == "SIdRef"
          || type == "IDREF"
          )
        return QBrush(DeviserSettings::getInstance()->getValidationColor());
      else
        return QVariant();
    }
    default:
      return QVariant();
    }

  }

  if (role != Qt::DisplayRole &&
      role != Qt::EditRole ) return QVariant();

  const DeviserAttribute* attr = (*mData)[index.row()];

  switch(index.column())
  {
  case NAME:
    return attr->getName();
  case TYPE:
    return attr->getType();
  case REQUIRED:
    return attr->getRequired();
  case ELEMENT:
    return attr->getElement();
  case ABSTRACT:
    return attr->getAbstract();
  case XMLName:
    return attr->getXMLName();
  default:
    return QVariant();
  }

}

bool
AttributesModel::setData(const QModelIndex &index,
                         const QVariant &value, int role /*= Qt::EditRole*/)
{
  if (role != Qt::DisplayRole && role != Qt::EditRole) return false;
  DeviserAttribute* attr = (*mData)[index.row()];
  if (attr == NULL) return false;

  switch(index.column())
  {
  case NAME:
    attr->setName(value.toString());
    return true;
  case TYPE:
    attr->setType(value.toString());
    return true;
  case REQUIRED:
    attr->setRequired(value.toBool());
    return true;
  case ELEMENT:
    attr->setElement(value.toString());
    return true;
  case ABSTRACT:
    attr->setAbstract(value.toBool());
    return true;
  case XMLName:
    attr->setXMLName(value.toString());
    return true;
  default:
    return false;
  }

}

QVariant
AttributesModel::headerData(int section,
                            Qt::Orientation orientation,
                            int role) const
{
  if (orientation != Qt::Horizontal) return QVariant();

  if (role != Qt::DisplayRole) return QVariant();

  switch(section)
  {
  case NAME:
    return "Name";
  case TYPE:
    return "Type";
  case REQUIRED:
    return "Required";
  case ELEMENT:
    return "Element";
  case ABSTRACT:
    return "isBaseClass";
  case XMLName:
    return "XML name";
  default:
    return QVariant();
  }

}

void AttributesModel::beginAdding()
{
  beginInsertRows(QModelIndex(),mData->count(),mData->count());
}

void AttributesModel::endAdding()
{
  endInsertRows();
}

void
AttributesModel::addAttribute(DeviserAttribute* attr)
{
  beginInsertRows(QModelIndex(),mData->count(),mData->count());
  mData->append(attr);
  endInsertRows();
}

DeviserAttribute*
AttributesModel::getAttribute(int row)
{
  if (row < 0 || row >= mData->count())
    return NULL;
  return (*mData)[row];
}

DeviserAttribute*
AttributesModel::removeAttribute(int row)
{
  beginRemoveRows(QModelIndex(),row,row);
  DeviserAttribute* result = getAttribute(row);
  mData->removeAt(row);
  endRemoveRows();
  result->deleteLater();
  return result;
}

<commit_msg>IDREF does not need element<commit_after>#include "attributesmodel.h"

#include <QBrush>

#include <model/devisersettings.h>
#include <model/deviserattribute.h>

AttributesModel::AttributesModel(
    QObject * parent,
    QList<DeviserAttribute*>* data)
  : QAbstractTableModel(parent)
  , mData(data)
{

}

int
AttributesModel::rowCount(const QModelIndex &) const
{
  return mData->count();
}

int
AttributesModel::columnCount(const QModelIndex &) const
{
  return 6;
}

Qt::ItemFlags
AttributesModel::flags(const QModelIndex &index) const
{
  if (!index.isValid())
    return Qt::ItemIsEnabled;
  return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}

QVariant
AttributesModel::data(const QModelIndex &index, int role) const
{
  if (role == Qt::ToolTipRole)
  {
    switch(index.column())
    {
    case NAME:
      return "The name of the attribute/element to be used by code generation.  The XML output may use a different name (see XML Name). This field is required.";
    case TYPE:
      return "The type of the attribute/element. Allowed values are: SId, SIdRef, string, bool, double, int, unsigned int, IDREF, UnitSId, UnitSIdRef, enum, element, lo_element, inline_lo_element. This field is required.";
    case REQUIRED:
      return "States whether the attribute or element is mandatory. This should be true if the attribute/element is mandatory; false if not.";
    case ELEMENT:
      return "This field provides additional information depending on the Type of the attribute/element. It may be the name of the element, enumeration or object being referenced. This field is required for attributes of type SIdRef, array, enum, element, lo_element, inline_lo_element, vector.";
    case ABSTRACT:
      return "States whether this element is a base class. This should be true if the element is a base class and therefore not instantiated directly; false if not.";
    case XMLName:
      return "The name of the attribute/element as used by the XML output. If blank, this defaults to the Name given.";
    default:
      return QVariant();
    }
  }

  if (role == Qt::BackgroundRole)
  {
    switch(index.column())
    {
    case TYPE:
    case NAME:
      if (index.data().toString().isEmpty())
        return QBrush(DeviserSettings::getInstance()->getValidationColor());
      else
        return QVariant();

    case ELEMENT:
    {
      QString element = index.data().toString();
      if (!element.isEmpty())
        return QVariant();

      QString type = index.model()->index(index.row(), TYPE).data().toString();
      if (type == "element"
          || type == "inline_lo_element"
          || type == "lo_element"
          || type == "enum"
          || type == "array"
          || type == "vector"
          || type == "SIdRef"
//     || type == "IDREF"
          )
        return QBrush(DeviserSettings::getInstance()->getValidationColor());
      else
        return QVariant();
    }
    default:
      return QVariant();
    }

  }

  if (role != Qt::DisplayRole &&
      role != Qt::EditRole ) return QVariant();

  const DeviserAttribute* attr = (*mData)[index.row()];

  switch(index.column())
  {
  case NAME:
    return attr->getName();
  case TYPE:
    return attr->getType();
  case REQUIRED:
    return attr->getRequired();
  case ELEMENT:
    return attr->getElement();
  case ABSTRACT:
    return attr->getAbstract();
  case XMLName:
    return attr->getXMLName();
  default:
    return QVariant();
  }

}

bool
AttributesModel::setData(const QModelIndex &index,
                         const QVariant &value, int role /*= Qt::EditRole*/)
{
  if (role != Qt::DisplayRole && role != Qt::EditRole) return false;
  DeviserAttribute* attr = (*mData)[index.row()];
  if (attr == NULL) return false;

  switch(index.column())
  {
  case NAME:
    attr->setName(value.toString());
    return true;
  case TYPE:
    attr->setType(value.toString());
    return true;
  case REQUIRED:
    attr->setRequired(value.toBool());
    return true;
  case ELEMENT:
    attr->setElement(value.toString());
    return true;
  case ABSTRACT:
    attr->setAbstract(value.toBool());
    return true;
  case XMLName:
    attr->setXMLName(value.toString());
    return true;
  default:
    return false;
  }

}

QVariant
AttributesModel::headerData(int section,
                            Qt::Orientation orientation,
                            int role) const
{
  if (orientation != Qt::Horizontal) return QVariant();

  if (role != Qt::DisplayRole) return QVariant();

  switch(section)
  {
  case NAME:
    return "Name";
  case TYPE:
    return "Type";
  case REQUIRED:
    return "Required";
  case ELEMENT:
    return "Element";
  case ABSTRACT:
    return "isBaseClass";
  case XMLName:
    return "XML name";
  default:
    return QVariant();
  }

}

void AttributesModel::beginAdding()
{
  beginInsertRows(QModelIndex(),mData->count(),mData->count());
}

void AttributesModel::endAdding()
{
  endInsertRows();
}

void
AttributesModel::addAttribute(DeviserAttribute* attr)
{
  beginInsertRows(QModelIndex(),mData->count(),mData->count());
  mData->append(attr);
  endInsertRows();
}

DeviserAttribute*
AttributesModel::getAttribute(int row)
{
  if (row < 0 || row >= mData->count())
    return NULL;
  return (*mData)[row];
}

DeviserAttribute*
AttributesModel::removeAttribute(int row)
{
  beginRemoveRows(QModelIndex(),row,row);
  DeviserAttribute* result = getAttribute(row);
  mData->removeAt(row);
  endRemoveRows();
  result->deleteLater();
  return result;
}

<|endoftext|>


<commit_before>template <int num_rotors>
void RocketSystem<num_rotors>::init() {
  getAccelerometer()->init();
  getGyroscope()->init();
}

template <int num_rotors>
void RocketSystem<num_rotors>::update() {
  // Poll the IMU
  accelerometer_reading_t accel_reading = getAccelerometer()->readAccel();
  gyroscope_reading_t gyro_reading = getGyroscope()->readGyro();

  // Update the attitude estimate
  attitude_estimate_t estimate = getAttitudeEstimator()->update(accel_reading, gyro_reading);

  // Poll for controller input
  controller_input_t input = getInputSource()->read();

  // Run the controllers
  angular_position_setpoint_t angular_setpoint = {
    .pitch_pos_sp = input.pitch_sp,
    .roll_pos_sp = input.roll_sp,
    .yaw_pos_sp = input.yaw_sp,
    .throttle_sp = input.throttle_sp
  };

  actuator_setpoint_t actuator_setpoint = runController(estimate, angular_setpoint);

  // Update motor outputs
  getMotorMapper()->run(actuator_setpoint);
}
<commit_msg>Fix missed roll/pitch/yaw change in `RocketSystem`.<commit_after>template <int num_rotors>
void RocketSystem<num_rotors>::init() {
  getAccelerometer()->init();
  getGyroscope()->init();
}

template <int num_rotors>
void RocketSystem<num_rotors>::update() {
  // Poll the IMU
  accelerometer_reading_t accel_reading = getAccelerometer()->readAccel();
  gyroscope_reading_t gyro_reading = getGyroscope()->readGyro();

  // Update the attitude estimate
  attitude_estimate_t estimate = getAttitudeEstimator()->update(accel_reading, gyro_reading);

  // Poll for controller input
  controller_input_t input = getInputSource()->read();

  // Run the controllers
  angular_position_setpoint_t angular_setpoint = {
    .roll_pos_sp = input.roll_sp,
    .pitch_pos_sp = input.pitch_sp,
    .yaw_pos_sp = input.yaw_sp,
    .throttle_sp = input.throttle_sp
  };

  actuator_setpoint_t actuator_setpoint = runController(estimate, angular_setpoint);

  // Update motor outputs
  getMotorMapper()->run(actuator_setpoint);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tp_LegendPosition.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 16:32:27 $
 *
 *  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 "tp_LegendPosition.hxx"

#include "ResId.hxx"
#include "TabPages.hrc"
#include "SchSfxItemIds.hxx"

//#include "schattr.hxx"
#ifndef _SVX_CHRTITEM_HXX //autogen
#include <svx/chrtitem.hxx>
#endif
/*
#include "schresid.hxx"
#include "chtmodel.hxx"
#include "attrib.hxx"
#include "attrib.hrc"
*/
//.............................................................................
namespace chart
{
//.............................................................................

SchLegendPosTabPage::SchLegendPosTabPage(Window* pWindow,
                                         const SfxItemSet& rInAttrs) :
    SfxTabPage(pWindow, SchResId(TP_LEGEND_POS), rInAttrs),
    aGrpLegend(this, SchResId(GRP_LEGEND)),
    aRbtLeft(this, SchResId(RBT_LEFT)),
    aRbtTop(this, SchResId(RBT_TOP)),
    aRbtBottom(this, SchResId(RBT_BOTTOM)),
    aRbtRight(this, SchResId(RBT_RIGHT))
{
    FreeResource();
}

SchLegendPosTabPage::~SchLegendPosTabPage()
{
}

SfxTabPage* SchLegendPosTabPage::Create(Window* pWindow,
                                        const SfxItemSet& rOutAttrs)
{
    return new SchLegendPosTabPage(pWindow, rOutAttrs);
}

BOOL SchLegendPosTabPage::FillItemSet(SfxItemSet& rOutAttrs)
{
    SvxChartLegendPos ePos;

    if (aRbtLeft.IsChecked())
        ePos = CHLEGEND_LEFT;
    else if (aRbtTop.IsChecked())
        ePos = CHLEGEND_TOP;
    else if (aRbtRight.IsChecked())
        ePos = CHLEGEND_RIGHT;
    else if (aRbtBottom.IsChecked())
        ePos = CHLEGEND_BOTTOM;
    else
        ePos = CHLEGEND_NONE;

    rOutAttrs.Put(SvxChartLegendPosItem(ePos, SCHATTR_LEGEND_POS));

    return TRUE;
}

void SchLegendPosTabPage::Reset(const SfxItemSet& rInAttrs)
{
    SvxChartLegendPos ePos = CHLEGEND_NONE;

    const SfxPoolItem* pPoolItem = NULL;
    if( rInAttrs.GetItemState( SCHATTR_LEGEND_POS,
                               TRUE, &pPoolItem ) != SFX_ITEM_SET )
        pPoolItem = &(rInAttrs.GetPool()->GetDefaultItem( SCHATTR_LEGEND_POS ));

    if( pPoolItem )
        ePos = ((const SvxChartLegendPosItem*)pPoolItem)->GetValue();

    switch( ePos )
    {
        case CHLEGEND_LEFT:
            aRbtLeft.Check(TRUE);
            break;
        case CHLEGEND_TOP:
            aRbtTop.Check(TRUE);
            break;
        case CHLEGEND_RIGHT:
            aRbtRight.Check(TRUE);
            break;
        case CHLEGEND_BOTTOM:
            aRbtBottom.Check(TRUE);
            break;
        default:
            break;
    }
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS chart2mst3 (1.2.4); FILE MERGED 2007/05/14 20:03:23 bm 1.2.4.7: RESYNC: (1.4-1.6); FILE MERGED 2006/10/18 17:04:43 bm 1.2.4.6: RESYNC: (1.3-1.4); FILE MERGED 2006/02/20 14:45:45 iha 1.2.4.5: move SchItemPool from controller to view lib -> ChartItemPool 2006/01/06 20:27:26 iha 1.2.4.4: added legendposition to wizard and restructured legend postiion control classes 2005/10/07 11:19:40 bm 1.2.4.3: RESYNC: (1.2-1.3); FILE MERGED 2004/09/07 10:04:17 bm 1.2.4.2: fixed order of members to fit order in dialog 2004/06/01 18:52:40 iha 1.2.4.1: no warnings+cleanup<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tp_LegendPosition.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 17:45:52 $
 *
 *  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 "tp_LegendPosition.hxx"
#include "ResId.hxx"
#include "TabPages.hrc"
#include "res_LegendPosition.hxx"
#include "chartview/ChartSfxItemIds.hxx"
#include "NoWarningThisInCTOR.hxx"

#ifndef _SVX_CHRTITEM_HXX
#include <svx/chrtitem.hxx>
#endif

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

SchLegendPosTabPage::SchLegendPosTabPage(Window* pWindow,
                                         const SfxItemSet& rInAttrs)
    : SfxTabPage( pWindow, SchResId(TP_LEGEND_POS), rInAttrs )
    , aGrpLegend( this, SchResId(GRP_LEGEND) )
    , m_apLegendPositionResources( new LegendPositionResources(this) )
{
    FreeResource();
}

SchLegendPosTabPage::~SchLegendPosTabPage()
{
}

SfxTabPage* SchLegendPosTabPage::Create(Window* pWindow,
                                        const SfxItemSet& rOutAttrs)
{
    return new SchLegendPosTabPage(pWindow, rOutAttrs);
}

BOOL SchLegendPosTabPage::FillItemSet(SfxItemSet& rOutAttrs)
{
    m_apLegendPositionResources->writeToItemSet(rOutAttrs);
    return TRUE;
}

void SchLegendPosTabPage::Reset(const SfxItemSet& rInAttrs)
{
    m_apLegendPositionResources->initFromItemSet(rInAttrs);
}

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