<commit_before>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file object/lobby.cc
 ** \brief Creation of the Urbi object lobby.
 */

#include <boost/algorithm/string.hpp>

#include <libport/cassert>

#include <kernel/uconnection.hh>
#include <kernel/ughostconnection.hh>
#include <kernel/userver.hh>

#include <urbi/object/lobby.hh>
#include <urbi/object/object.hh>
#include <urbi/object/string.hh>
#include <object/symbols.hh>
#include <urbi/object/tag.hh>

#include <urbi/runner/raise.hh>
#include <runner/runner.hh>

namespace urbi
{
  namespace object
  {
    static rLobby
    lobby_lobby(rObject /*this*/, rLobby l)
    {
      return l;
    }

    Lobby::Lobby(connection_type* c)
      : connection_(c)
    {
      // Only the Lobby prototype is expected to have a null connection.
      aver(!proto || c);
      proto_add(proto ? rObject(proto) : Object::proto);

      if (c)
      {
        // Don't you DARE change this with a slot pointing to `this', as
        // it would be a circular reference to the lobby from itself,
        // making him un-reclaimable.
        boost::function1<rLobby, rObject> f(boost::bind(lobby_lobby, _1, this));
        slot_set(SYMBOL(lobby), make_primitive(f));

        // Initialize the connection tag used to reference local
        // variables.
        slot_set(SYMBOL(connectionTag), new Tag());
        tag_get()->name_set(libport::Symbol::fresh("Lobby"));
      }
    }

    Lobby::Lobby(rLobby)
      : connection_(0)
    {
      RAISE("`Lobby' objects cannot be cloned");
    }

    rLobby
    Lobby::create()
    {
      return
        (new kernel::UGhostConnection(*kernel::urbiserver, true))
        ->lobby_get();
    }

    Lobby::connection_type&
    Lobby::connection_get()
    {
      return *connection_;
    }

    const Lobby::connection_type&
    Lobby::connection_get() const
    {
      return *connection_;
    }

    void
    Lobby::disconnect()
    {
      connection_ = 0;
      call(SYMBOL(handleDisconnect));
    }

    static inline
    runner::Runner&
    runner()
    {
      return ::kernel::runner();
    }

    rLobby
    Lobby::lobby()
    {
      return runner().lobby_get();
    }

    void
    Lobby::quit()
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");
      if (&connection_get())
        connection_get().close();
    }

    void
    Lobby::send(const objects_type& args)
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");

      check_arg_count(args.size(), 1, 2);
      if (!connection_)
        return;
      // Second argument is the tag name.
      std::string tag;
      if (args.size() == 2)
      {
        const rString& name = args[1].unsafe_cast<String>();
        if (!name)
          runner::raise_argument_type_error(1, args[1], String::proto);
        tag = name->value_get();
      }
      const rString& rdata = args[0].unsafe_cast<String>();
      if (!rdata)
        runner::raise_argument_type_error(0, args[0], String::proto);
      const std::string data = rdata->value_get() + "\n";
      connection_->send(data.c_str(), data.length(), tag.c_str());
    }

    void
    Lobby::write(const std::string& data)
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");
      if (!connection_)
        return;
      connection_->send_queue(data.c_str(), data.size());
      connection_->flush();
    }

    void
    Lobby::receive(const std::string& s)
    {
      connection_->received(s);
    }

    void
    Lobby::initialize(CxxObject::Binder<Lobby>& bind)
    {
#define DECLARE(Name)                           \
      bind(SYMBOL(Name), &Lobby::Name)

      DECLARE(create);
      DECLARE(lobby);
      DECLARE(quit);
      DECLARE(receive);
      DECLARE(send);
      DECLARE(write);
#undef DECLARE

      bind(SYMBOL(instances), &Lobby::instances_get);
    }

    URBI_CXX_OBJECT_REGISTER(Lobby)
      : connection_(0)
    {}

  }; // namespace object
}
<commit_msg>factor.<commit_after>/*
 * Copyright (C) 2008-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file object/lobby.cc
 ** \brief Creation of the Urbi object lobby.
 */

#include <boost/algorithm/string.hpp>

#include <libport/cassert>

#include <kernel/uconnection.hh>
#include <kernel/ughostconnection.hh>
#include <kernel/userver.hh>

#include <urbi/object/lobby.hh>
#include <urbi/object/object.hh>
#include <urbi/object/string.hh>
#include <object/symbols.hh>
#include <urbi/object/tag.hh>

#include <urbi/runner/raise.hh>
#include <runner/runner.hh>

namespace urbi
{
  namespace object
  {
    static rLobby
    lobby_lobby(rObject /*this*/, rLobby l)
    {
      return l;
    }

    Lobby::Lobby(connection_type* c)
      : connection_(c)
    {
      // Only the Lobby prototype is expected to have a null connection.
      aver(!proto || c);
      proto_add(proto ? rObject(proto) : Object::proto);

      if (c)
      {
        // Don't you DARE change this with a slot pointing to `this', as
        // it would be a circular reference to the lobby from itself,
        // making him un-reclaimable.
        boost::function1<rLobby, rObject> f(boost::bind(lobby_lobby, _1, this));
        slot_set(SYMBOL(lobby), make_primitive(f));

        // Initialize the connection tag used to reference local
        // variables.
        slot_set(SYMBOL(connectionTag), new Tag());
        tag_get()->name_set(libport::Symbol::fresh("Lobby"));
      }
    }

    Lobby::Lobby(rLobby)
      : connection_(0)
    {
      RAISE("`Lobby' objects cannot be cloned");
    }

    rLobby
    Lobby::create()
    {
      return
        (new kernel::UGhostConnection(*kernel::urbiserver, true))
        ->lobby_get();
    }

    Lobby::connection_type&
    Lobby::connection_get()
    {
      return *connection_;
    }

    const Lobby::connection_type&
    Lobby::connection_get() const
    {
      return *connection_;
    }

    void
    Lobby::disconnect()
    {
      connection_ = 0;
      call(SYMBOL(handleDisconnect));
    }

    rLobby
    Lobby::lobby()
    {
      return ::kernel::runner().lobby_get();
    }

    void
    Lobby::quit()
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");
      if (&connection_get())
        connection_get().close();
    }

    void
    Lobby::send(const objects_type& args)
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");

      check_arg_count(args.size(), 1, 2);
      if (!connection_)
        return;
      // Second argument is the tag name.
      std::string tag;
      if (args.size() == 2)
      {
        const rString& name = args[1].unsafe_cast<String>();
        if (!name)
          runner::raise_argument_type_error(1, args[1], String::proto);
        tag = name->value_get();
      }
      const rString& rdata = args[0].unsafe_cast<String>();
      if (!rdata)
        runner::raise_argument_type_error(0, args[0], String::proto);
      const std::string data = rdata->value_get() + "\n";
      connection_->send(data.c_str(), data.length(), tag.c_str());
    }

    void
    Lobby::write(const std::string& data)
    {
      if (proto == this)
        RAISE("must be called on Lobby derivative");
      if (!connection_)
        return;
      connection_->send_queue(data.c_str(), data.size());
      connection_->flush();
    }

    void
    Lobby::receive(const std::string& s)
    {
      connection_->received(s);
    }

    void
    Lobby::initialize(CxxObject::Binder<Lobby>& bind)
    {
#define DECLARE(Name)                           \
      bind(SYMBOL(Name), &Lobby::Name)

      DECLARE(create);
      DECLARE(lobby);
      DECLARE(quit);
      DECLARE(receive);
      DECLARE(send);
      DECLARE(write);
#undef DECLARE

      bind(SYMBOL(instances), &Lobby::instances_get);
    }

    URBI_CXX_OBJECT_REGISTER(Lobby)
      : connection_(0)
    {}

  }; // namespace object
}
<|endoftext|>


<commit_before><commit_msg>fix some ons options' bugs<commit_after><|endoftext|>


<commit_before><commit_msg>reproduce fetch_neighbours crash<commit_after><|endoftext|>


<commit_before><commit_msg>Avoid concurrent access to the task manager task list.<commit_after><|endoftext|>


<commit_before>/**
* @version		GrPPI v0.2
* @copyright		Copyright (C) 2017 Universidad Carlos III de Madrid. All rights reserved.
* @license		GNU/GPL, see LICENSE.txt
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You have received a copy of the GNU General Public License in LICENSE.txt
* also available in <http://www.gnu.org/licenses/gpl.html>.
*
* See COPYRIGHT.txt for copyright notices and details.
*/
#include <atomic>

#include <gtest/gtest.h>

#include "pipeline.h"

#include "supported_executions.h"

using namespace std;
using namespace grppi;

template <typename T>
class pipeline_test : public ::testing::Test {
public:
  T execution_;

  // Variables
  int out;
  int counter;

  // Vectors
  vector<int> v{};

  // Invocation counter
  std::atomic<int> invocations_init{0};
  std::atomic<int> invocations_last{0};
  std::atomic<int> invocations_intermediate{0};

  void setup_two_stages_empty() {
  }

  void check_two_stages_empty() {
    ASSERT_EQ(1, invocations_init);
    ASSERT_EQ(0, invocations_last);
  }

  void setup_two_stages() {
    out = 0;
    counter = 2;
  }

  void check_two_stages() {
    ASSERT_EQ(2, invocations_init);
    ASSERT_EQ(1, invocations_last);
    EXPECT_EQ(1, this->out);
  }

  void setup_three_stages() {
    counter = 5;
    out = 0;
  }

  void check_three_stages() {
    ASSERT_EQ(5, invocations_init);
    ASSERT_EQ(4, invocations_last);
    ASSERT_EQ(4, invocations_intermediate);
    EXPECT_EQ(20, this->out);
  }

};

// Test for execution policies defined in supported_executions.h
TYPED_TEST_CASE(pipeline_test, executions);

TYPED_TEST(pipeline_test, static_two_stages_empty)
{
  this->setup_two_stages_empty();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        return optional<int>();
    },
    [this]( auto x ) {
      this->invocations_last++;
    }
  );

  this->check_two_stages_empty();
}

TYPED_TEST(pipeline_test, static_two_stages)
{
  this->setup_two_stages();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        this->counter--;
        if(this->counter  == 0){
          return optional<int>();
        }else{
          return optional<int>(this->counter);
        }
    },
    [this]( auto x ) {
      this->invocations_last++;
      this->out += x;
    }
  );
  this->check_two_stages();
}

TYPED_TEST(pipeline_test, static_three_stages)
{
  this->setup_three_stages();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        this->counter--;
        if(this->counter  == 0){
          return optional<int>();
        }else{
          return optional<int>(this->counter);
        }
    },
    [this]( auto x ) {
      this->invocations_intermediate++;
      return x*2;
    },
    [this]( auto y ) {
      this->invocations_last++;
      this->out += y;
    }
  );
  this->check_three_stages();
}
<commit_msg>Included composed pipeline+farm utest<commit_after>/**
* @version		GrPPI v0.2
* @copyright		Copyright (C) 2017 Universidad Carlos III de Madrid. All rights reserved.
* @license		GNU/GPL, see LICENSE.txt
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You have received a copy of the GNU General Public License in LICENSE.txt
* also available in <http://www.gnu.org/licenses/gpl.html>.
*
* See COPYRIGHT.txt for copyright notices and details.
*/
#include <atomic>

#include <gtest/gtest.h>

#include "pipeline.h"
#include "farm.h"

#include "supported_executions.h"

#include <iostream>
#include <numeric>

using namespace std;
using namespace grppi;

template <typename T>
class pipeline_test : public ::testing::Test {
public:
  T execution_;

  // Variables
  int out;
  int counter;

  // Vectors
  vector<int> v{};
  vector<vector<int> > v2{};

  // Invocation counter
  std::atomic<int> invocations_init{0};
  std::atomic<int> invocations_last{0};
  std::atomic<int> invocations_intermediate{0};

  void setup_two_stages_empty() {
  }

  void check_two_stages_empty() {
    ASSERT_EQ(1, invocations_init);
    ASSERT_EQ(0, invocations_last);
  }

  void setup_two_stages() {
    out = 0;
    counter = 2;
  }

  void check_two_stages() {
    ASSERT_EQ(2, invocations_init);
    ASSERT_EQ(1, invocations_last);
    EXPECT_EQ(1, this->out);
  }

  void setup_three_stages() {
    counter = 5;
    out = 0;
  }

  void check_three_stages() {
    ASSERT_EQ(5, invocations_init);
    ASSERT_EQ(4, invocations_last);
    ASSERT_EQ(4, invocations_intermediate);
    EXPECT_EQ(20, this->out);
  }

  void setup_composed() {
    counter = 5;
    out = 0;

  }

  void check_composed() {
    ASSERT_EQ(5, invocations_init);
    ASSERT_EQ(4, invocations_last);
    //ASSERT_EQ(4, invocations_intermediate);
    EXPECT_EQ(40, this->out);
  }

};

// Test for execution policies defined in supported_executions.h
TYPED_TEST_CASE(pipeline_test, executions);

TYPED_TEST(pipeline_test, static_two_stages_empty)
{
  this->setup_two_stages_empty();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        return optional<int>();
    },
    [this]( auto x ) {
      this->invocations_last++;
    }
  );

  this->check_two_stages_empty();
}

TYPED_TEST(pipeline_test, static_two_stages)
{
  this->setup_two_stages();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        this->counter--;
        if(this->counter  == 0){
          return optional<int>();
        }else{
          return optional<int>(this->counter);
        }
    },
    [this]( auto x ) {
      this->invocations_last++;
      this->out += x;
    }
  );
  this->check_two_stages();
}

TYPED_TEST(pipeline_test, static_three_stages)
{
  this->setup_three_stages();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        this->counter--;
        if(this->counter  == 0){
          return optional<int>();
        }else{
          return optional<int>(this->counter);
        }
    },
    [this]( auto x ) {
      this->invocations_intermediate++;
      return x*2;
    },
    [this]( auto y ) {
      this->invocations_last++;
      this->out += y;
    }
  );
  this->check_three_stages();
}

TYPED_TEST(pipeline_test, static_three_stages_composed)
{
  this->setup_composed();
    grppi::pipeline( this->execution_,
    [this]() {
        this->invocations_init++;
        this->counter--;
        std::vector<int> v(5);
        std::iota(begin(v), end(v), 0);

        if(this->counter  <= 0){
          return optional< std::vector<int> >();
        }else{
          return optional<std::vector<int>>(v);
        }
    },
    grppi::farm(this->execution_,
        [this](std::vector<int> v) {
          //this->invocations_intermediate++;
          int acumm = 0;
          for(int i = 0; i < v.size(); i++ ){
            acumm += v[i];
          }
          return acumm;
        }
    ),
    [this]( auto y ) {
      this->invocations_last++;
      this->out += y;
    }
  );

  this->check_composed();
}<|endoftext|>


<commit_before><commit_msg>implement new callbacks (api 9.69)<commit_after><|endoftext|>


<commit_before>#ifndef UTF8_STRING_HPP_INCLUDED
#define UTF8_STRING_HPP_INCLUDED

#include <string>
#include <iostream>

class UTF8string
{
    std::string utf8data;
    size_t utf8length;

    bool utf8_is_valid_() const;
    size_t utf8_length_() const;
    size_t utf8_codepoint_len_(size_t j) const;
    size_t utf8_bpos_at(const size_t cpos) const;

public:

    const static size_t npos = std::string::npos;

    UTF8string();
    UTF8string(const std::string &str);
    UTF8string(const UTF8string &u8str);

    const UTF8string& operator =(const char * str);
    const UTF8string& operator =(const std::string str);
    const UTF8string& operator =(const UTF8string u8str);
    const UTF8string& operator +=(const UTF8string u8str);
    const UTF8string& operator +=(const std::string str);
    const UTF8string& operator +=(const char * str);
    const UTF8string& operator +=(const char c);

    void utf8_clear();
    bool utf8_empty() const;
    std::string utf8_at(const size_t index) const;

    UTF8string utf8_substr(size_t pos = 0, size_t len = npos) const;
    size_t utf8_find(const UTF8string& str, size_t pos = 0) const;

    size_t utf8_size() const;
    size_t utf8_length() const;
    const char * utf8_str() const;

    std::string::iterator utf8_begin() noexcept;
    std::string::iterator utf8_end() noexcept;

    ~UTF8string() = default;
};

bool operator ==(const UTF8string &str1, const UTF8string &str2);
bool operator !=(const UTF8string &str1, const UTF8string &str2);
bool operator <=(const UTF8string &str1, const UTF8string &str2);
bool operator >=(const UTF8string &str1, const UTF8string &str2);
bool operator <(const UTF8string &str1, const UTF8string &str2);
bool operator >(const UTF8string &str1, const UTF8string &str2);

UTF8string operator +(const UTF8string &str1, const UTF8string &str2);
UTF8string operator +(const UTF8string &str1, const std::string &str2);
UTF8string operator +(const std::string &str1, const UTF8string &str2);
UTF8string operator +(const UTF8string &str1, const char * str2);
UTF8string operator +(const char * str1, const UTF8string &str2);

std::ostream & operator <<(std::ostream &os, const UTF8string &str);
std::istream & operator >>(std::istream &is, UTF8string &str);

#endif // UTF_STRING_HPP_INCLUDED
<commit_msg>Fixed a typo<commit_after>#ifndef UTF8_STRING_HPP_INCLUDED
#define UTF8_STRING_HPP_INCLUDED

#include <string>
#include <iostream>

class UTF8string
{
    std::string utf8data;
    size_t utf8length;

    bool utf8_is_valid_() const;
    size_t utf8_length_() const;
    size_t utf8_codepoint_len_(size_t j) const;
    size_t utf8_bpos_at(const size_t cpos) const;

public:

    const static size_t npos = std::string::npos;

    UTF8string();
    UTF8string(const std::string &str);
    UTF8string(const UTF8string &u8str);

    const UTF8string& operator =(const char * str);
    const UTF8string& operator =(const std::string str);
    const UTF8string& operator =(const UTF8string u8str);
    const UTF8string& operator +=(const UTF8string u8str);
    const UTF8string& operator +=(const std::string str);
    const UTF8string& operator +=(const char * str);
    const UTF8string& operator +=(const char c);

    void utf8_clear();
    bool utf8_empty() const;
    std::string utf8_at(const size_t index) const;

    UTF8string utf8_substr(size_t pos = 0, size_t len = npos) const;
    size_t utf8_find(const UTF8string& str, size_t pos = 0) const;

    size_t utf8_size() const;
    size_t utf8_length() const;
    const char * utf8_str() const;

    std::string::iterator utf8_begin() noexcept;
    std::string::iterator utf8_end() noexcept;

    ~UTF8string() = default;
};

bool operator ==(const UTF8string &str1, const UTF8string &str2);
bool operator !=(const UTF8string &str1, const UTF8string &str2);
bool operator <=(const UTF8string &str1, const UTF8string &str2);
bool operator >=(const UTF8string &str1, const UTF8string &str2);
bool operator <(const UTF8string &str1, const UTF8string &str2);
bool operator >(const UTF8string &str1, const UTF8string &str2);

UTF8string operator +(const UTF8string &str1, const UTF8string &str2);
UTF8string operator +(const UTF8string &str1, const std::string &str2);
UTF8string operator +(const std::string &str1, const UTF8string &str2);
UTF8string operator +(const UTF8string &str1, const char * str2);
UTF8string operator +(const char * str1, const UTF8string &str2);

std::ostream & operator <<(std::ostream &os, const UTF8string &str);
std::istream & operator >>(std::istream &is, UTF8string &str);

#endif // UTF8_STRING_HPP_INCLUDED
<|endoftext|>


<commit_before>/* Copyright 2015 Realm Inc - All Rights Reserved
 * Proprietary and Confidential
 */

#import "js_schema.hpp"
#import "object_store.hpp"

namespace realm {
    struct SchemaWrapper {
        Schema *schema;
        bool owned;
        ~SchemaWrapper() {
            if (owned) {
                delete schema;
            }
        }
    };
}

using namespace realm;

JSClassRef RJSSchemaClass() {
    static JSClassRef s_schemaClass = RJSCreateWrapperClass<SchemaWrapper *>("Schema");
    return s_schemaClass;
}

JSObjectRef RJSSchemaCreate(JSContextRef ctx, Schema &schema) {
    SchemaWrapper *wrapper = new SchemaWrapper();
    wrapper->schema = &schema;
    wrapper->owned = false;
    return RJSWrapObject(ctx, RJSSchemaClass(), wrapper);
}

static inline Property RJSParseProperty(JSContextRef ctx, JSValueRef propertyAttributes, std::string propertyName, ObjectDefaults &objectDefaults) {
    static JSStringRef defaultString = JSStringCreateWithUTF8CString("default");
    static JSStringRef typeString = JSStringCreateWithUTF8CString("type");
    static JSStringRef objectTypeString = JSStringCreateWithUTF8CString("objectType");
    static JSStringRef optionalString = JSStringCreateWithUTF8CString("optional");

    Property prop;
    prop.name = propertyName;

    JSObjectRef propertyObject = NULL;
    std::string type;

    if (JSValueIsObject(ctx, propertyAttributes)) {
        propertyObject = RJSValidatedValueToObject(ctx, propertyAttributes);
        type = RJSValidatedStringProperty(ctx, propertyObject, typeString);

        JSValueRef optionalValue = JSObjectGetProperty(ctx, propertyObject, optionalString, NULL);
        if (!JSValueIsUndefined(ctx, optionalValue)) {
            if (!JSValueIsBoolean(ctx, optionalValue)) {
                throw std::runtime_error("'optional' designation expected to be of type boolean");
            }
            prop.is_nullable = JSValueToBoolean(ctx, optionalValue);
        }
    }
    else {
        type = RJSValidatedStringForValue(ctx, propertyAttributes);
    }

    if (type == "bool") {
        prop.type = PropertyTypeBool;
    }
    else if (type == "int") {
        prop.type = PropertyTypeInt;
    }
    else if (type == "float") {
        prop.type = PropertyTypeFloat;
    }
    else if (type == "double") {
        prop.type = PropertyTypeDouble;
    }
    else if (type == "string") {
        prop.type = PropertyTypeString;
    }
    else if (type == "date") {
        prop.type = PropertyTypeDate;
    }
    else if (type == "data") {
        prop.type = PropertyTypeData;
    }
    else if (type == "list") {
        if (!propertyObject) {
            throw std::runtime_error("List property must specify 'objectType'");
        }
        prop.type = PropertyTypeArray;
        prop.object_type =  RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
    }
    else {
        prop.type = PropertyTypeObject;
        prop.is_nullable = true;

        // The type could either be 'object' or the name of another object type in the same schema.
        if (type == "object") {
            if (!propertyObject) {
                throw std::runtime_error("Object property must specify 'objectType'");
            }
            prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
        }
        else {
            prop.object_type = type;
        }
    }

    if (propertyObject) {
        JSValueRef defaultValue = RJSValidatedPropertyValue(ctx, propertyObject, defaultString);
        if (!JSValueIsUndefined(ctx, defaultValue)) {
            JSValueProtect(ctx, defaultValue);
            objectDefaults.emplace(prop.name, defaultValue);
        }
    }

    return prop;
}

static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef objectSchemaObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
    static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
    static JSStringRef prototypeString = JSStringCreateWithUTF8CString("prototype");
    JSObjectRef prototypeObject = NULL;
    JSValueRef prototypeValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, prototypeString);

    if (!JSValueIsUndefined(ctx, prototypeValue)) {
        prototypeObject = RJSValidatedValueToObject(ctx, prototypeValue);
        objectSchemaObject = RJSValidatedObjectProperty(ctx, prototypeObject, schemaString, "Realm object prototype must have a 'schema' property.");
    }
    else {
        JSValueRef subSchemaValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, schemaString);
        if (!JSValueIsUndefined(ctx, subSchemaValue)) {
            objectSchemaObject = RJSValidatedValueToObject(ctx, subSchemaValue);
        }
    }

    static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
    static JSStringRef propertiesString = JSStringCreateWithUTF8CString("properties");
    JSObjectRef propertiesObject = RJSValidatedObjectProperty(ctx, objectSchemaObject, propertiesString, "ObjectSchema must have a 'properties' object.");

    ObjectDefaults objectDefaults;
    ObjectSchema objectSchema;
    objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);

    JSPropertyNameArrayRef propertyNames = NULL;
    size_t propertyCount;

    if (RJSIsValueArray(ctx, propertiesObject)) {
        propertyCount = RJSValidatedListLength(ctx, propertiesObject);
    }
    else {
        propertyNames = JSObjectCopyPropertyNames(ctx, propertiesObject);
        propertyCount = JSPropertyNameArrayGetCount(propertyNames);
    }

    for (size_t i = 0; i < propertyCount; i++) {
        Property property;

        // Check if the properties were provided as an object.
        if (propertyNames) {
            JSStringRef propertyName = JSPropertyNameArrayGetNameAtIndex(propertyNames, i);
            JSValueRef propertyValue = RJSValidatedPropertyValue(ctx, propertiesObject, propertyName);
            property = RJSParseProperty(ctx, propertyValue, RJSStringForJSString(propertyName), objectDefaults);
        }
        else {
            JSObjectRef propertyObject = RJSValidatedObjectAtIndex(ctx, propertiesObject, (unsigned int)i);
            std::string propertyName = RJSValidatedStringProperty(ctx, propertyObject, nameString);
            property = RJSParseProperty(ctx, propertyObject, propertyName, objectDefaults);
        }

        objectSchema.properties.emplace_back(property);
    }

    if (propertyNames) {
        JSPropertyNameArrayRelease(propertyNames);
    }

    static JSStringRef primaryString = JSStringCreateWithUTF8CString("primaryKey");
    JSValueRef primaryValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, primaryString);
    if (!JSValueIsUndefined(ctx, primaryValue)) {
        objectSchema.primary_key = RJSValidatedStringForValue(ctx, primaryValue);
        Property *property = objectSchema.primary_key_property();
        if (!property) {
            throw std::runtime_error("Missing primary key property '" + objectSchema.primary_key + "'");
        }
        property->is_primary = true;
    }

    // store prototype
    if (prototypeObject) {
        JSValueProtect(ctx, prototypeObject);
        prototypes[objectSchema.name] = std::move(prototypeObject);
    }

    defaults.emplace(objectSchema.name, std::move(objectDefaults));

    return objectSchema;
}

realm::Schema RJSParseSchema(JSContextRef ctx, JSObjectRef jsonObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
    std::vector<ObjectSchema> schema;
    size_t length = RJSValidatedListLength(ctx, jsonObject);
    for (unsigned int i = 0; i < length; i++) {
        JSObjectRef jsonObjectSchema = RJSValidatedObjectAtIndex(ctx, jsonObject, i);
        ObjectSchema objectSchema = RJSParseObjectSchema(ctx, jsonObjectSchema, defaults, prototypes);
        schema.emplace_back(std::move(objectSchema));
     }

    return Schema(schema);
}

<commit_msg>Cleanup some code and comments to make it consistent<commit_after>/* Copyright 2015 Realm Inc - All Rights Reserved
 * Proprietary and Confidential
 */

#import "js_schema.hpp"
#import "object_store.hpp"

namespace realm {
    struct SchemaWrapper {
        Schema *schema;
        bool owned;
        ~SchemaWrapper() {
            if (owned) {
                delete schema;
            }
        }
    };
}

using namespace realm;

JSClassRef RJSSchemaClass() {
    static JSClassRef s_schemaClass = RJSCreateWrapperClass<SchemaWrapper *>("Schema");
    return s_schemaClass;
}

JSObjectRef RJSSchemaCreate(JSContextRef ctx, Schema &schema) {
    SchemaWrapper *wrapper = new SchemaWrapper();
    wrapper->schema = &schema;
    wrapper->owned = false;
    return RJSWrapObject(ctx, RJSSchemaClass(), wrapper);
}

static inline Property RJSParseProperty(JSContextRef ctx, JSValueRef propertyAttributes, std::string propertyName, ObjectDefaults &objectDefaults) {
    static JSStringRef defaultString = JSStringCreateWithUTF8CString("default");
    static JSStringRef typeString = JSStringCreateWithUTF8CString("type");
    static JSStringRef objectTypeString = JSStringCreateWithUTF8CString("objectType");
    static JSStringRef optionalString = JSStringCreateWithUTF8CString("optional");

    Property prop;
    prop.name = propertyName;

    JSObjectRef propertyObject = NULL;
    std::string type;

    if (JSValueIsObject(ctx, propertyAttributes)) {
        propertyObject = RJSValidatedValueToObject(ctx, propertyAttributes);
        type = RJSValidatedStringProperty(ctx, propertyObject, typeString);

        JSValueRef optionalValue = JSObjectGetProperty(ctx, propertyObject, optionalString, NULL);
        if (!JSValueIsUndefined(ctx, optionalValue)) {
            if (!JSValueIsBoolean(ctx, optionalValue)) {
                throw std::runtime_error("'optional' designation expected to be of type boolean");
            }
            prop.is_nullable = JSValueToBoolean(ctx, optionalValue);
        }
    }
    else {
        type = RJSValidatedStringForValue(ctx, propertyAttributes);
    }

    if (type == "bool") {
        prop.type = PropertyTypeBool;
    }
    else if (type == "int") {
        prop.type = PropertyTypeInt;
    }
    else if (type == "float") {
        prop.type = PropertyTypeFloat;
    }
    else if (type == "double") {
        prop.type = PropertyTypeDouble;
    }
    else if (type == "string") {
        prop.type = PropertyTypeString;
    }
    else if (type == "date") {
        prop.type = PropertyTypeDate;
    }
    else if (type == "data") {
        prop.type = PropertyTypeData;
    }
    else if (type == "list") {
        if (!propertyObject) {
            throw std::runtime_error("List property must specify 'objectType'");
        }
        prop.type = PropertyTypeArray;
        prop.object_type =  RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
    }
    else {
        prop.type = PropertyTypeObject;
        prop.is_nullable = true;

        // The type could either be 'object' or the name of another object type in the same schema.
        if (type == "object") {
            if (!propertyObject) {
                throw std::runtime_error("Object property must specify 'objectType'");
            }
            prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
        }
        else {
            prop.object_type = type;
        }
    }

    if (propertyObject) {
        JSValueRef defaultValue = RJSValidatedPropertyValue(ctx, propertyObject, defaultString);
        if (!JSValueIsUndefined(ctx, defaultValue)) {
            JSValueProtect(ctx, defaultValue);
            objectDefaults.emplace(prop.name, defaultValue);
        }
    }

    return prop;
}

static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef objectSchemaObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
    static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
    static JSStringRef primaryString = JSStringCreateWithUTF8CString("primaryKey");
    static JSStringRef prototypeString = JSStringCreateWithUTF8CString("prototype");
    static JSStringRef propertiesString = JSStringCreateWithUTF8CString("properties");
    static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");

    JSObjectRef prototypeObject = NULL;
    JSValueRef prototypeValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, prototypeString);

    if (!JSValueIsUndefined(ctx, prototypeValue)) {
        prototypeObject = RJSValidatedValueToObject(ctx, prototypeValue);
        objectSchemaObject = RJSValidatedObjectProperty(ctx, prototypeObject, schemaString, "Realm object prototype must have a 'schema' property.");
    }
    else {
        JSValueRef subSchemaValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, schemaString);
        if (!JSValueIsUndefined(ctx, subSchemaValue)) {
            objectSchemaObject = RJSValidatedValueToObject(ctx, subSchemaValue);
        }
    }

    ObjectDefaults objectDefaults;
    ObjectSchema objectSchema;
    objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);

    JSObjectRef propertiesObject = RJSValidatedObjectProperty(ctx, objectSchemaObject, propertiesString, "ObjectSchema must have a 'properties' object.");
    JSPropertyNameArrayRef propertyNames = NULL;
    size_t propertyCount;

    if (RJSIsValueArray(ctx, propertiesObject)) {
        propertyCount = RJSValidatedListLength(ctx, propertiesObject);
    }
    else {
        propertyNames = JSObjectCopyPropertyNames(ctx, propertiesObject);
        propertyCount = JSPropertyNameArrayGetCount(propertyNames);
    }

    for (size_t i = 0; i < propertyCount; i++) {
        Property property;

        // Check if the properties were provided as an object.
        if (propertyNames) {
            JSStringRef propertyName = JSPropertyNameArrayGetNameAtIndex(propertyNames, i);
            JSValueRef propertyValue = RJSValidatedPropertyValue(ctx, propertiesObject, propertyName);
            property = RJSParseProperty(ctx, propertyValue, RJSStringForJSString(propertyName), objectDefaults);
        }
        else {
            JSObjectRef propertyObject = RJSValidatedObjectAtIndex(ctx, propertiesObject, (unsigned int)i);
            std::string propertyName = RJSValidatedStringProperty(ctx, propertyObject, nameString);
            property = RJSParseProperty(ctx, propertyObject, propertyName, objectDefaults);
        }

        objectSchema.properties.emplace_back(property);
    }

    if (propertyNames) {
        JSPropertyNameArrayRelease(propertyNames);
    }

    JSValueRef primaryValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, primaryString);
    if (!JSValueIsUndefined(ctx, primaryValue)) {
        objectSchema.primary_key = RJSValidatedStringForValue(ctx, primaryValue);
        Property *property = objectSchema.primary_key_property();
        if (!property) {
            throw std::runtime_error("Missing primary key property '" + objectSchema.primary_key + "'");
        }
        property->is_primary = true;
    }

    // Store prototype so that objects of this type will have their prototype set to this prototype object.
    if (prototypeObject) {
        JSValueProtect(ctx, prototypeObject);
        prototypes[objectSchema.name] = std::move(prototypeObject);
    }

    defaults.emplace(objectSchema.name, std::move(objectDefaults));

    return objectSchema;
}

realm::Schema RJSParseSchema(JSContextRef ctx, JSObjectRef jsonObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
    std::vector<ObjectSchema> schema;
    size_t length = RJSValidatedListLength(ctx, jsonObject);
    for (unsigned int i = 0; i < length; i++) {
        JSObjectRef jsonObjectSchema = RJSValidatedObjectAtIndex(ctx, jsonObject, i);
        ObjectSchema objectSchema = RJSParseObjectSchema(ctx, jsonObjectSchema, defaults, prototypes);
        schema.emplace_back(std::move(objectSchema));
     }

    return Schema(schema);
}

<|endoftext|>


<commit_before>// ReaderWriterSPT.cxx -- Provide a paged database for flightgear scenery.
//
// Copyright (C) 2010 - 2011  Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include "ReaderWriterSPT.hxx"

#include <cassert>

#include <osg/CullFace>
#include <osg/PagedLOD>
#include <osg/Texture2D>

#include <osgDB/FileNameUtils>
#include <osgDB/ReadFile>

#include <simgear/scene/util/OsgMath.hxx>

#include "BucketBox.hxx"

namespace simgear {

ReaderWriterSPT::ReaderWriterSPT()
{
    supportsExtension("spt", "SimGear paged terrain meta database.");
}

ReaderWriterSPT::~ReaderWriterSPT()
{
}

const char*
ReaderWriterSPT::className() const
{
    return "simgear::ReaderWriterSPT";
}

osgDB::ReaderWriter::ReadResult
ReaderWriterSPT::readObject(const std::string& fileName, const osgDB::Options* options) const
{
    // We get called with different extensions. To make sure search continues,
    // we need to return FILE_NOT_HANDLED in this case.
    if (osgDB::getLowerCaseFileExtension(fileName) != "spt")
        return ReadResult(osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED);
    if (fileName != "state.spt")
        return ReadResult(osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND);

    osg::StateSet* stateSet = new osg::StateSet;
    stateSet->setAttributeAndModes(new osg::CullFace);

    std::string imageFileName = options->getPluginStringData("SimGear::FG_WORLD_TEXTURE");
    if (osg::Image* image = osgDB::readImageFile(imageFileName, options)) {
        osg::Texture2D* texture = new osg::Texture2D;
        texture->setImage(image);
        texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
        texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP);
        stateSet->setTextureAttributeAndModes(0, texture);
    }

    return stateSet;
}

osgDB::ReaderWriter::ReadResult
ReaderWriterSPT::readNode(const std::string& fileName, const osgDB::Options* options) const
{
    // The file name without path and without the spt extension
    std::string strippedFileName = osgDB::getStrippedName(fileName);
    if (strippedFileName == "earth")
        return createTree(BucketBox(0, -90, 360, 180), options, true);

    std::stringstream ss(strippedFileName);
    BucketBox bucketBox;
    ss >> bucketBox;
    if (ss.fail())
        return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;

    BucketBox bucketBoxList[2];
    unsigned bucketBoxListSize = bucketBox.periodicSplit(bucketBoxList);
    if (bucketBoxListSize == 0)
        return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;

    if (bucketBoxListSize == 1)
        return createTree(bucketBoxList[0], options, true);

    assert(bucketBoxListSize == 2);
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(createTree(bucketBoxList[0], options, true));
    group->addChild(createTree(bucketBoxList[1], options, true));
    return group.release();
}

osg::Node*
ReaderWriterSPT::createTree(const BucketBox& bucketBox, const osgDB::Options* options, bool topLevel) const
{
    if (bucketBox.getIsBucketSize()) {
        return createPagedLOD(bucketBox, options);
    } else if (!topLevel && bucketBox.getStartLevel() == 4) {
        // We want an other level of indirection for paging
        return createPagedLOD(bucketBox, options);
    } else {
        BucketBox bucketBoxList[100];
        unsigned numTiles = bucketBox.getSubDivision(bucketBoxList, 100);
        if (numTiles == 0)
            return 0;

        if (numTiles == 1)
            return createTree(bucketBoxList[0], options, false);

        osg::ref_ptr<osg::Group> group = new osg::Group;
        for (unsigned i = 0; i < numTiles; ++i) {
            osg::Node* node = createTree(bucketBoxList[i], options, false);
            if (!node)
                continue;
            group->addChild(node);
        }
        if (!group->getNumChildren())
            return 0;

        return group.release();
    }
}

osg::Node*
ReaderWriterSPT::createPagedLOD(const BucketBox& bucketBox, const osgDB::Options* options) const
{
    osg::PagedLOD* pagedLOD = new osg::PagedLOD;

    pagedLOD->setCenterMode(osg::PagedLOD::USER_DEFINED_CENTER);
    SGSpheref sphere = bucketBox.getBoundingSphere();
    pagedLOD->setCenter(toOsg(sphere.getCenter()));
    pagedLOD->setRadius(sphere.getRadius());

    osg::ref_ptr<osgDB::Options> localOptions;
    localOptions = static_cast<osgDB::Options*>(options->clone(osg::CopyOp()));
    pagedLOD->setDatabaseOptions(localOptions.get());

    float range;
    if (bucketBox.getIsBucketSize())
        range = 200e3;
    else
        range = 1e6;

    // Add the static sea level textured shell
    if (osg::Node* tile = createSeaLevelTile(bucketBox, options))
        pagedLOD->addChild(tile, range, std::numeric_limits<float>::max());

    // Add the paged file name that creates the subtrees on demand
    if (bucketBox.getIsBucketSize()) {
        std::string fileName;
        fileName = bucketBox.getBucket().gen_index_str() + std::string(".stg");
        pagedLOD->setFileName(pagedLOD->getNumChildren(), fileName);
    } else {
        std::stringstream ss;
        ss << bucketBox << ".spt";
        pagedLOD->setFileName(pagedLOD->getNumChildren(), ss.str());
    }
    pagedLOD->setRange(pagedLOD->getNumChildren(), 0.0, range);

    return pagedLOD;
}

osg::Node*
ReaderWriterSPT::createSeaLevelTile(const BucketBox& bucketBox, const osgDB::Options* options) const
{
    if (options->getPluginStringData("SimGear::FG_EARTH") != "ON")
        return 0;

    osg::Vec3Array* vertices = new osg::Vec3Array;
    osg::Vec3Array* normals = new osg::Vec3Array;
    osg::Vec2Array* texCoords = new osg::Vec2Array;

    unsigned widthLevel = bucketBox.getWidthLevel();
    unsigned heightLevel = bucketBox.getHeightLevel();

    unsigned incx = bucketBox.getWidthIncrement(widthLevel + 2);
    incx = std::min(incx, bucketBox.getSize(0));
    for (unsigned i = 0; incx != 0;) {
        unsigned incy = bucketBox.getHeightIncrement(heightLevel + 2);
        incy = std::min(incy, bucketBox.getSize(1));
        for (unsigned j = 0; incy != 0;) {
            SGVec3f v[6], n[6];
            SGVec2f t[6];
            unsigned num = bucketBox.getTileTriangles(i, j, incx, incy, v, n, t);
            for (unsigned k = 0; k < num; ++k) {
                vertices->push_back(toOsg(v[k]));
                normals->push_back(toOsg(n[k]));
                texCoords->push_back(toOsg(t[k]));
            }
            j += incy;
            incy = std::min(incy, bucketBox.getSize(1) - j);
        }
        i += incx;
        incx = std::min(incx, bucketBox.getSize(0) - i);
    }

    osg::Vec4Array* colors = new osg::Vec4Array;
    colors->push_back(osg::Vec4(1, 1, 1, 1));

    osg::Geometry* geometry = new osg::Geometry;
    geometry->setVertexArray(vertices);
    geometry->setNormalArray(normals);
    geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
    geometry->setColorArray(colors);
    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
    geometry->setTexCoordArray(0, texCoords);

    geometry->addPrimitiveSet(new osg::DrawArrays(osg::DrawArrays::TRIANGLES, 0, vertices->size()));

    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geometry);
    geode->setStateSet(getLowLODStateSet(options));

    return geode;
}

osg::StateSet*
ReaderWriterSPT::getLowLODStateSet(const osgDB::Options* options) const
{
    osg::ref_ptr<osgDB::Options> localOptions;
    localOptions = static_cast<osgDB::Options*>(options->clone(osg::CopyOp()));
    localOptions->setObjectCacheHint(osgDB::Options::CACHE_ALL);

    osg::ref_ptr<osg::Object> object = osgDB::readObjectFile("state.spt", localOptions.get());
    if (!dynamic_cast<osg::StateSet*>(object.get()))
        return 0;

    return static_cast<osg::StateSet*>(object.release());
}

} // namespace simgear

<commit_msg>spt: Make use of newly provided earth texture.<commit_after>// ReaderWriterSPT.cxx -- Provide a paged database for flightgear scenery.
//
// Copyright (C) 2010 - 2011  Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include "ReaderWriterSPT.hxx"

#include <cassert>

#include <osg/CullFace>
#include <osg/PagedLOD>
#include <osg/Texture2D>

#include <osgDB/FileNameUtils>
#include <osgDB/ReadFile>

#include <simgear/scene/util/OsgMath.hxx>

#include "BucketBox.hxx"

namespace simgear {

ReaderWriterSPT::ReaderWriterSPT()
{
    supportsExtension("spt", "SimGear paged terrain meta database.");
}

ReaderWriterSPT::~ReaderWriterSPT()
{
}

const char*
ReaderWriterSPT::className() const
{
    return "simgear::ReaderWriterSPT";
}

osgDB::ReaderWriter::ReadResult
ReaderWriterSPT::readObject(const std::string& fileName, const osgDB::Options* options) const
{
    // We get called with different extensions. To make sure search continues,
    // we need to return FILE_NOT_HANDLED in this case.
    if (osgDB::getLowerCaseFileExtension(fileName) != "spt")
        return ReadResult(osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED);
    if (fileName != "state.spt")
        return ReadResult(osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND);

    osg::StateSet* stateSet = new osg::StateSet;
    stateSet->setAttributeAndModes(new osg::CullFace);

    std::string imageFileName = options->getPluginStringData("SimGear::FG_WORLD_TEXTURE");
    if (imageFileName.empty()) {
        imageFileName = options->getPluginStringData("SimGear::FG_ROOT");
        imageFileName = osgDB::concatPaths(imageFileName, "Textures");
        imageFileName = osgDB::concatPaths(imageFileName, "Globe");
        imageFileName = osgDB::concatPaths(imageFileName, "world.topo.bathy.200407.3x4096x2048.png");
    }
    if (osg::Image* image = osgDB::readImageFile(imageFileName, options)) {
        osg::Texture2D* texture = new osg::Texture2D;
        texture->setImage(image);
        texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
        texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP);
        stateSet->setTextureAttributeAndModes(0, texture);
    }

    return stateSet;
}

osgDB::ReaderWriter::ReadResult
ReaderWriterSPT::readNode(const std::string& fileName, const osgDB::Options* options) const
{
    // The file name without path and without the spt extension
    std::string strippedFileName = osgDB::getStrippedName(fileName);
    if (strippedFileName == "earth")
        return createTree(BucketBox(0, -90, 360, 180), options, true);

    std::stringstream ss(strippedFileName);
    BucketBox bucketBox;
    ss >> bucketBox;
    if (ss.fail())
        return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;

    BucketBox bucketBoxList[2];
    unsigned bucketBoxListSize = bucketBox.periodicSplit(bucketBoxList);
    if (bucketBoxListSize == 0)
        return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;

    if (bucketBoxListSize == 1)
        return createTree(bucketBoxList[0], options, true);

    assert(bucketBoxListSize == 2);
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(createTree(bucketBoxList[0], options, true));
    group->addChild(createTree(bucketBoxList[1], options, true));
    return group.release();
}

osg::Node*
ReaderWriterSPT::createTree(const BucketBox& bucketBox, const osgDB::Options* options, bool topLevel) const
{
    if (bucketBox.getIsBucketSize()) {
        return createPagedLOD(bucketBox, options);
    } else if (!topLevel && bucketBox.getStartLevel() == 4) {
        // We want an other level of indirection for paging
        return createPagedLOD(bucketBox, options);
    } else {
        BucketBox bucketBoxList[100];
        unsigned numTiles = bucketBox.getSubDivision(bucketBoxList, 100);
        if (numTiles == 0)
            return 0;

        if (numTiles == 1)
            return createTree(bucketBoxList[0], options, false);

        osg::ref_ptr<osg::Group> group = new osg::Group;
        for (unsigned i = 0; i < numTiles; ++i) {
            osg::Node* node = createTree(bucketBoxList[i], options, false);
            if (!node)
                continue;
            group->addChild(node);
        }
        if (!group->getNumChildren())
            return 0;

        return group.release();
    }
}

osg::Node*
ReaderWriterSPT::createPagedLOD(const BucketBox& bucketBox, const osgDB::Options* options) const
{
    osg::PagedLOD* pagedLOD = new osg::PagedLOD;

    pagedLOD->setCenterMode(osg::PagedLOD::USER_DEFINED_CENTER);
    SGSpheref sphere = bucketBox.getBoundingSphere();
    pagedLOD->setCenter(toOsg(sphere.getCenter()));
    pagedLOD->setRadius(sphere.getRadius());

    osg::ref_ptr<osgDB::Options> localOptions;
    localOptions = static_cast<osgDB::Options*>(options->clone(osg::CopyOp()));
    pagedLOD->setDatabaseOptions(localOptions.get());

    float range;
    if (bucketBox.getIsBucketSize())
        range = 200e3;
    else
        range = 1e6;

    // Add the static sea level textured shell
    if (osg::Node* tile = createSeaLevelTile(bucketBox, options))
        pagedLOD->addChild(tile, range, std::numeric_limits<float>::max());

    // Add the paged file name that creates the subtrees on demand
    if (bucketBox.getIsBucketSize()) {
        std::string fileName;
        fileName = bucketBox.getBucket().gen_index_str() + std::string(".stg");
        pagedLOD->setFileName(pagedLOD->getNumChildren(), fileName);
    } else {
        std::stringstream ss;
        ss << bucketBox << ".spt";
        pagedLOD->setFileName(pagedLOD->getNumChildren(), ss.str());
    }
    pagedLOD->setRange(pagedLOD->getNumChildren(), 0.0, range);

    return pagedLOD;
}

osg::Node*
ReaderWriterSPT::createSeaLevelTile(const BucketBox& bucketBox, const osgDB::Options* options) const
{
    if (options->getPluginStringData("SimGear::FG_EARTH") != "ON")
        return 0;

    osg::Vec3Array* vertices = new osg::Vec3Array;
    osg::Vec3Array* normals = new osg::Vec3Array;
    osg::Vec2Array* texCoords = new osg::Vec2Array;

    unsigned widthLevel = bucketBox.getWidthLevel();
    unsigned heightLevel = bucketBox.getHeightLevel();

    unsigned incx = bucketBox.getWidthIncrement(widthLevel + 2);
    incx = std::min(incx, bucketBox.getSize(0));
    for (unsigned i = 0; incx != 0;) {
        unsigned incy = bucketBox.getHeightIncrement(heightLevel + 2);
        incy = std::min(incy, bucketBox.getSize(1));
        for (unsigned j = 0; incy != 0;) {
            SGVec3f v[6], n[6];
            SGVec2f t[6];
            unsigned num = bucketBox.getTileTriangles(i, j, incx, incy, v, n, t);
            for (unsigned k = 0; k < num; ++k) {
                vertices->push_back(toOsg(v[k]));
                normals->push_back(toOsg(n[k]));
                texCoords->push_back(toOsg(t[k]));
            }
            j += incy;
            incy = std::min(incy, bucketBox.getSize(1) - j);
        }
        i += incx;
        incx = std::min(incx, bucketBox.getSize(0) - i);
    }

    osg::Vec4Array* colors = new osg::Vec4Array;
    colors->push_back(osg::Vec4(1, 1, 1, 1));

    osg::Geometry* geometry = new osg::Geometry;
    geometry->setVertexArray(vertices);
    geometry->setNormalArray(normals);
    geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
    geometry->setColorArray(colors);
    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
    geometry->setTexCoordArray(0, texCoords);

    geometry->addPrimitiveSet(new osg::DrawArrays(osg::DrawArrays::TRIANGLES, 0, vertices->size()));

    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geometry);
    geode->setStateSet(getLowLODStateSet(options));

    return geode;
}

osg::StateSet*
ReaderWriterSPT::getLowLODStateSet(const osgDB::Options* options) const
{
    osg::ref_ptr<osgDB::Options> localOptions;
    localOptions = static_cast<osgDB::Options*>(options->clone(osg::CopyOp()));
    localOptions->setObjectCacheHint(osgDB::Options::CACHE_ALL);

    osg::ref_ptr<osg::Object> object = osgDB::readObjectFile("state.spt", localOptions.get());
    if (!dynamic_cast<osg::StateSet*>(object.get()))
        return 0;

    return static_cast<osg::StateSet*>(object.release());
}

} // namespace simgear

<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include "VecMatMath.hpp"

class Extrusion
{
public:
    Extrusion(std::vector<vec2> &points, int depth = 1);

    void draw();

    void setDepth(const int d);
    int getDepth() const;

private:
    std::vector<vec2> &points2d;
    int depth;
};
<commit_msg>Extrusion should be a drawable<commit_after>#pragma once

#include <vector>
#include "VecMatMath.hpp"
#include "Drawable.hpp"

class Extrusion : public Drawable
{
public:
    Extrusion(std::vector<vec2> &points, int depth = 1);

    void draw() override;

    void setDepth(const int d);
    int getDepth() const;

private:
    std::vector<vec2> &points2d;
    int depth;
};
<|endoftext|>


<commit_before>//===--------------------------- libunwind.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
//  Implements unw_* functions from <libunwind.h>
//
//===----------------------------------------------------------------------===//

#include <libunwind.h>

#include "libunwind_ext.h"
#include "config.h"

#include <stdlib.h>

#if !defined(__USING_SJLJ_EXCEPTIONS__)
#include "AddressSpace.hpp"
#include "UnwindCursor.hpp"

using namespace libunwind;

/// internal object to represent this processes address space
LocalAddressSpace LocalAddressSpace::sThisAddressSpace;

_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
    (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;

/// Create a cursor of a thread in this process given 'context' recorded by
/// __unw_getcontext().
_LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
                                       unw_context_t *context) {
  _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)",
                       static_cast<void *>(cursor),
                       static_cast<void *>(context));
#if defined(__i386__)
# define REGISTER_KIND Registers_x86
#elif defined(__x86_64__)
# define REGISTER_KIND Registers_x86_64
#elif defined(__powerpc64__)
# define REGISTER_KIND Registers_ppc64
#elif defined(__ppc__)
# define REGISTER_KIND Registers_ppc
#elif defined(__aarch64__)
# define REGISTER_KIND Registers_arm64
#elif defined(__arm__)
# define REGISTER_KIND Registers_arm
#elif defined(__or1k__)
# define REGISTER_KIND Registers_or1k
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
# define REGISTER_KIND Registers_mips_o32
#elif defined(__mips64)
# define REGISTER_KIND Registers_mips_newabi
#elif defined(__mips__)
# warning The MIPS architecture is not supported with this ABI and environment!
#elif defined(__sparc__)
# define REGISTER_KIND Registers_sparc
#else
# error Architecture not supported
#endif
  // Use "placement new" to allocate UnwindCursor in the cursor buffer.
  new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor))
      UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
          context, LocalAddressSpace::sThisAddressSpace);
#undef REGISTER_KIND
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->setInfoBasedOnIPRegister();

  return UNW_ESUCCESS;
}
_LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local)

/// Get value of specified register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                    unw_word_t *value) {
  _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)",
                       static_cast<void *>(cursor), regNum,
                       static_cast<void *>(value));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validReg(regNum)) {
    *value = co->getReg(regNum);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg)

/// Set value of specified register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                    unw_word_t value) {
  _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR
                       ")",
                       static_cast<void *>(cursor), regNum, value);
  typedef LocalAddressSpace::pint_t pint_t;
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validReg(regNum)) {
    co->setReg(regNum, (pint_t)value);
    // specical case altering IP to re-find info (being called by personality
    // function)
    if (regNum == UNW_REG_IP) {
      unw_proc_info_t info;
      // First, get the FDE for the old location and then update it.
      co->getInfo(&info);
      co->setInfoBasedOnIPRegister(false);
      // If the original call expects stack adjustment, perform this now.
      // Normal frame unwinding would have included the offset already in the
      // CFA computation.
      // Note: for PA-RISC and other platforms where the stack grows up,
      // this should actually be - info.gp. LLVM doesn't currently support
      // any such platforms and Clang doesn't export a macro for them.
      if (info.gp)
        co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp);
    }
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg)

/// Get value of specified float register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                      unw_fpreg_t *value) {
  _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)",
                       static_cast<void *>(cursor), regNum,
                       static_cast<void *>(value));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validFloatReg(regNum)) {
    *value = co->getFloatReg(regNum);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg)

/// Set value of specified float register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                      unw_fpreg_t value) {
#if defined(_LIBUNWIND_ARM_EHABI)
  _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)",
                       static_cast<void *>(cursor), regNum, value);
#else
  _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)",
                       static_cast<void *>(cursor), regNum, value);
#endif
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validFloatReg(regNum)) {
    co->setFloatReg(regNum, value);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg)

/// Move cursor to next frame.
_LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->step();
}
_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step)

/// Get unwind info at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
                                          unw_proc_info_t *info) {
  _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)",
                       static_cast<void *>(cursor), static_cast<void *>(info));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->getInfo(info);
  if (info->end_ip == 0)
    return UNW_ENOINFO;
  else
    return UNW_ESUCCESS;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info)

/// Resume execution at cursor position (aka longjump).
_LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->jumpto();
  return UNW_EUNSPEC;
}
_LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume)

/// Get name of function at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf,
                                          size_t bufLen, unw_word_t *offset) {
  _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)",
                       static_cast<void *>(cursor), static_cast<void *>(buf),
                       static_cast<unsigned long>(bufLen));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->getFunctionName(buf, bufLen, offset))
    return UNW_ESUCCESS;
  else
    return UNW_EUNSPEC;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name)

/// Checks if a register is a floating-point register.
_LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor,
                                     unw_regnum_t regNum) {
  _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)",
                       static_cast<void *>(cursor), regNum);
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->validFloatReg(regNum);
}
_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg)

/// Checks if a register is a floating-point register.
_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor,
                                            unw_regnum_t regNum) {
  _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)",
                       static_cast<void *>(cursor), regNum);
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->getRegisterName(regNum);
}
_LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname)

/// Checks if current frame is signal trampoline.
_LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)",
                       static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->isSignalFrame();
}
_LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame)

#ifdef __arm__
// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
_LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)",
                       static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->saveVFPAsX();
}
_LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_cfp_as_X)
#endif

#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
/// SPI: walks cached DWARF entries
_LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)(
    unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
  _LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)",
                       reinterpret_cast<void *>(func));
  DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
}
_LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache,
                      unw_iterate_dwarf_unwind_cache)

/// IPI: for __register_frame()
void __unw_add_dynamic_fde(unw_word_t fde) {
  CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
  CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
  const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE(
                           LocalAddressSpace::sThisAddressSpace,
                          (LocalAddressSpace::pint_t) fde, &fdeInfo, &cieInfo);
  if (message == NULL) {
    // dynamically registered FDEs don't have a mach_header group they are in.
    // Use fde as mh_group
    unw_word_t mh_group = fdeInfo.fdeStart;
    DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
                                          fdeInfo.pcStart, fdeInfo.pcEnd,
                                          fdeInfo.fdeStart);
  } else {
    _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message);
  }
}

/// IPI: for __deregister_frame()
void __unw_remove_dynamic_fde(unw_word_t fde) {
  // fde is own mh_group
  DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde);
}
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
#endif // !defined(__USING_SJLJ_EXCEPTIONS__)

// Add logging hooks in Debug builds only
#ifndef NDEBUG
#include <stdlib.h>

_LIBUNWIND_HIDDEN
bool logAPIs() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_APIS") != NULL);
    checked = true;
  }
  return log;
}

_LIBUNWIND_HIDDEN
bool logUnwinding() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL);
    checked = true;
  }
  return log;
}

_LIBUNWIND_HIDDEN
bool logDWARF() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL);
    checked = true;
  }
  return log;
}

#endif // NDEBUG

<commit_msg>[libunwind] Fix the typo in unw_save_vfp_as_X alias<commit_after>//===--------------------------- libunwind.cpp ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
//  Implements unw_* functions from <libunwind.h>
//
//===----------------------------------------------------------------------===//

#include <libunwind.h>

#include "libunwind_ext.h"
#include "config.h"

#include <stdlib.h>

#if !defined(__USING_SJLJ_EXCEPTIONS__)
#include "AddressSpace.hpp"
#include "UnwindCursor.hpp"

using namespace libunwind;

/// internal object to represent this processes address space
LocalAddressSpace LocalAddressSpace::sThisAddressSpace;

_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
    (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;

/// Create a cursor of a thread in this process given 'context' recorded by
/// __unw_getcontext().
_LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
                                       unw_context_t *context) {
  _LIBUNWIND_TRACE_API("__unw_init_local(cursor=%p, context=%p)",
                       static_cast<void *>(cursor),
                       static_cast<void *>(context));
#if defined(__i386__)
# define REGISTER_KIND Registers_x86
#elif defined(__x86_64__)
# define REGISTER_KIND Registers_x86_64
#elif defined(__powerpc64__)
# define REGISTER_KIND Registers_ppc64
#elif defined(__ppc__)
# define REGISTER_KIND Registers_ppc
#elif defined(__aarch64__)
# define REGISTER_KIND Registers_arm64
#elif defined(__arm__)
# define REGISTER_KIND Registers_arm
#elif defined(__or1k__)
# define REGISTER_KIND Registers_or1k
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
# define REGISTER_KIND Registers_mips_o32
#elif defined(__mips64)
# define REGISTER_KIND Registers_mips_newabi
#elif defined(__mips__)
# warning The MIPS architecture is not supported with this ABI and environment!
#elif defined(__sparc__)
# define REGISTER_KIND Registers_sparc
#else
# error Architecture not supported
#endif
  // Use "placement new" to allocate UnwindCursor in the cursor buffer.
  new (reinterpret_cast<UnwindCursor<LocalAddressSpace, REGISTER_KIND> *>(cursor))
      UnwindCursor<LocalAddressSpace, REGISTER_KIND>(
          context, LocalAddressSpace::sThisAddressSpace);
#undef REGISTER_KIND
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->setInfoBasedOnIPRegister();

  return UNW_ESUCCESS;
}
_LIBUNWIND_WEAK_ALIAS(__unw_init_local, unw_init_local)

/// Get value of specified register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                    unw_word_t *value) {
  _LIBUNWIND_TRACE_API("__unw_get_reg(cursor=%p, regNum=%d, &value=%p)",
                       static_cast<void *>(cursor), regNum,
                       static_cast<void *>(value));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validReg(regNum)) {
    *value = co->getReg(regNum);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg)

/// Set value of specified register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                    unw_word_t value) {
  _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR
                       ")",
                       static_cast<void *>(cursor), regNum, value);
  typedef LocalAddressSpace::pint_t pint_t;
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validReg(regNum)) {
    co->setReg(regNum, (pint_t)value);
    // specical case altering IP to re-find info (being called by personality
    // function)
    if (regNum == UNW_REG_IP) {
      unw_proc_info_t info;
      // First, get the FDE for the old location and then update it.
      co->getInfo(&info);
      co->setInfoBasedOnIPRegister(false);
      // If the original call expects stack adjustment, perform this now.
      // Normal frame unwinding would have included the offset already in the
      // CFA computation.
      // Note: for PA-RISC and other platforms where the stack grows up,
      // this should actually be - info.gp. LLVM doesn't currently support
      // any such platforms and Clang doesn't export a macro for them.
      if (info.gp)
        co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp);
    }
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_set_reg, unw_set_reg)

/// Get value of specified float register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                      unw_fpreg_t *value) {
  _LIBUNWIND_TRACE_API("__unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)",
                       static_cast<void *>(cursor), regNum,
                       static_cast<void *>(value));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validFloatReg(regNum)) {
    *value = co->getFloatReg(regNum);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_fpreg, unw_get_fpreg)

/// Set value of specified float register at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
                                      unw_fpreg_t value) {
#if defined(_LIBUNWIND_ARM_EHABI)
  _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)",
                       static_cast<void *>(cursor), regNum, value);
#else
  _LIBUNWIND_TRACE_API("__unw_set_fpreg(cursor=%p, regNum=%d, value=%g)",
                       static_cast<void *>(cursor), regNum, value);
#endif
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->validFloatReg(regNum)) {
    co->setFloatReg(regNum, value);
    return UNW_ESUCCESS;
  }
  return UNW_EBADREG;
}
_LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg)

/// Move cursor to next frame.
_LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->step();
}
_LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step)

/// Get unwind info at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor,
                                          unw_proc_info_t *info) {
  _LIBUNWIND_TRACE_API("__unw_get_proc_info(cursor=%p, &info=%p)",
                       static_cast<void *>(cursor), static_cast<void *>(info));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->getInfo(info);
  if (info->end_ip == 0)
    return UNW_ENOINFO;
  else
    return UNW_ESUCCESS;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_info, unw_get_proc_info)

/// Resume execution at cursor position (aka longjump).
_LIBUNWIND_HIDDEN int __unw_resume(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_resume(cursor=%p)", static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  co->jumpto();
  return UNW_EUNSPEC;
}
_LIBUNWIND_WEAK_ALIAS(__unw_resume, unw_resume)

/// Get name of function at cursor position in stack frame.
_LIBUNWIND_HIDDEN int __unw_get_proc_name(unw_cursor_t *cursor, char *buf,
                                          size_t bufLen, unw_word_t *offset) {
  _LIBUNWIND_TRACE_API("__unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)",
                       static_cast<void *>(cursor), static_cast<void *>(buf),
                       static_cast<unsigned long>(bufLen));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  if (co->getFunctionName(buf, bufLen, offset))
    return UNW_ESUCCESS;
  else
    return UNW_EUNSPEC;
}
_LIBUNWIND_WEAK_ALIAS(__unw_get_proc_name, unw_get_proc_name)

/// Checks if a register is a floating-point register.
_LIBUNWIND_HIDDEN int __unw_is_fpreg(unw_cursor_t *cursor,
                                     unw_regnum_t regNum) {
  _LIBUNWIND_TRACE_API("__unw_is_fpreg(cursor=%p, regNum=%d)",
                       static_cast<void *>(cursor), regNum);
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->validFloatReg(regNum);
}
_LIBUNWIND_WEAK_ALIAS(__unw_is_fpreg, unw_is_fpreg)

/// Checks if a register is a floating-point register.
_LIBUNWIND_HIDDEN const char *__unw_regname(unw_cursor_t *cursor,
                                            unw_regnum_t regNum) {
  _LIBUNWIND_TRACE_API("__unw_regname(cursor=%p, regNum=%d)",
                       static_cast<void *>(cursor), regNum);
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->getRegisterName(regNum);
}
_LIBUNWIND_WEAK_ALIAS(__unw_regname, unw_regname)

/// Checks if current frame is signal trampoline.
_LIBUNWIND_HIDDEN int __unw_is_signal_frame(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_is_signal_frame(cursor=%p)",
                       static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->isSignalFrame();
}
_LIBUNWIND_WEAK_ALIAS(__unw_is_signal_frame, unw_is_signal_frame)

#ifdef __arm__
// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
_LIBUNWIND_HIDDEN void __unw_save_vfp_as_X(unw_cursor_t *cursor) {
  _LIBUNWIND_TRACE_API("__unw_get_fpreg_save_vfp_as_X(cursor=%p)",
                       static_cast<void *>(cursor));
  AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
  return co->saveVFPAsX();
}
_LIBUNWIND_WEAK_ALIAS(__unw_save_vfp_as_X, unw_save_vfp_as_X)
#endif

#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
/// SPI: walks cached DWARF entries
_LIBUNWIND_HIDDEN void __unw_iterate_dwarf_unwind_cache(void (*func)(
    unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
  _LIBUNWIND_TRACE_API("__unw_iterate_dwarf_unwind_cache(func=%p)",
                       reinterpret_cast<void *>(func));
  DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
}
_LIBUNWIND_WEAK_ALIAS(__unw_iterate_dwarf_unwind_cache,
                      unw_iterate_dwarf_unwind_cache)

/// IPI: for __register_frame()
void __unw_add_dynamic_fde(unw_word_t fde) {
  CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
  CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
  const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE(
                           LocalAddressSpace::sThisAddressSpace,
                          (LocalAddressSpace::pint_t) fde, &fdeInfo, &cieInfo);
  if (message == NULL) {
    // dynamically registered FDEs don't have a mach_header group they are in.
    // Use fde as mh_group
    unw_word_t mh_group = fdeInfo.fdeStart;
    DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group,
                                          fdeInfo.pcStart, fdeInfo.pcEnd,
                                          fdeInfo.fdeStart);
  } else {
    _LIBUNWIND_DEBUG_LOG("__unw_add_dynamic_fde: bad fde: %s", message);
  }
}

/// IPI: for __deregister_frame()
void __unw_remove_dynamic_fde(unw_word_t fde) {
  // fde is own mh_group
  DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde);
}
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
#endif // !defined(__USING_SJLJ_EXCEPTIONS__)

// Add logging hooks in Debug builds only
#ifndef NDEBUG
#include <stdlib.h>

_LIBUNWIND_HIDDEN
bool logAPIs() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_APIS") != NULL);
    checked = true;
  }
  return log;
}

_LIBUNWIND_HIDDEN
bool logUnwinding() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL);
    checked = true;
  }
  return log;
}

_LIBUNWIND_HIDDEN
bool logDWARF() {
  // do manual lock to avoid use of _cxa_guard_acquire or initializers
  static bool checked = false;
  static bool log = false;
  if (!checked) {
    log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL);
    checked = true;
  }
  return log;
}

#endif // NDEBUG

<|endoftext|>


<commit_before>//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

#ifndef HAVE_GIPS /* [ */

#include "assert.h"

#include "mp/MpSipxDecoders.h"

#define LOCAL static
//#undef LOCAL
//#define LOCAL

/* ============================ CREATORS ================================== */

/* ============================ MANIPULATORS ============================== */

#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
#define QUANT_MASK      (0xf)           /* Quantization field mask. */
#define SEG_SHIFT       (4)             /* Left shift for segment number. */
#define SEG_MASK        (0x70)          /* Segment field mask. */

#define BIAS            (0x84)          /* Bias for linear code. */

LOCAL MpAudioSample hzm_ULaw2linear(uint8_t u)
{
   int L;
   int seg;

   u = ~u;
   seg = (u & 0x70) >> 4;
   L = ((0x0f & u) << 3) + BIAS;
   L = (L << seg);
   if (0x80 & u)
   {
      L = BIAS - L;
   }
   else
   {
      L = L - BIAS;
   }
   return L;
}

LOCAL int ULawToLinear(MpAudioSample *Dest, const unsigned char *Source, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = hzm_ULaw2linear(*Source);
      Dest++; Source++;
   }
   return samples;
}

/*
 * ALaw2Linear() - Convert an A-law value to 16-bit linear PCM
 *
 */
LOCAL MpAudioSample ALaw2Linear(uint8_t a_val)
{
   int t;
   int seg;

   a_val ^= 0x55;

   t = (a_val & QUANT_MASK) << 4;
   seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
   switch (seg)
   {
   case 0:
      t += 8;
      break;
   case 1:
      t += 0x108;
      break;
   default:
      t += 0x108;
      t <<= seg - 1;
   }
   return ((a_val & SIGN_BIT) ? t : -t);
}

LOCAL int ALawToLinear(MpAudioSample *Dest, const unsigned char *src, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = ALaw2Linear(*src);
      Dest++; src++;
   }
   return samples;
}

LOCAL int16_t seg_end[8] = {0x00FF, 0x01FF, 0x03FF, 0x07FF,
                            0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF};

LOCAL int search(MpAudioSample val, int16_t *table, int size)
{
   int             i;

   for (i = 0; i < size; i++)
   {
      if (val <= *table++)
      {
         return i;
      }
   }
   return size;
}

int G711A_Decoder(int numSamples,
                  const uint8_t* codBuff,
                  MpAudioSample* outBuff)
{
   ALawToLinear(outBuff, codBuff, numSamples);
   return 0;
}

int G711U_Decoder(int numSamples,
                  const uint8_t* codBuff,
                  MpAudioSample* outBuff)
{
   ULawToLinear(outBuff, codBuff, numSamples);
   return 0;
}

/*
 * Linear2ALaw() - Convert a 16-bit linear PCM value to 8-bit A-law
 *
 * Linear2ALaw() accepts an 16-bit integer and encodes it as A-law data.
 *
 *              Linear Input Code       Compressed Code
 *      ------------------------        ---------------
 *      0000000wxyza                    000wxyz
 *      0000001wxyza                    001wxyz
 *      000001wxyzab                    010wxyz
 *      00001wxyzabc                    011wxyz
 *      0001wxyzabcd                    100wxyz
 *      001wxyzabcde                    101wxyz
 *      01wxyzabcdef                    110wxyz
 *      1wxyzabcdefg                    111wxyz
 *
 * For further information see John C. Bellamy's Digital Telephony, 1982,
 * John Wiley & Sons, pps 98-111 and 472-476.
 */
LOCAL uint8_t Linear2ALaw(MpAudioSample pcm_val ///< 2's complement (16-bit range)
                          )
{
   int      mask;
   int      seg;
   uint8_t  aval;

   if (pcm_val >= 0)
   {
      mask = 0xD5;            /* sign (7th) bit = 1 */
   }
   else
   {
      mask = 0x55;            /* sign bit = 0 */
      pcm_val = -pcm_val - 8;
   }

   /* Convert the scaled magnitude to segment number. */
   seg = search(pcm_val, seg_end, 8);

   /* Combine the sign, segment, and quantization bits. */

   if (seg >= 8)           /* out of range, return maximum value. */
   {
      return (0x7F ^ mask);
   }
   else
   {
      aval = seg << SEG_SHIFT;
      if (seg < 2)
         aval |= (pcm_val >> 4) & QUANT_MASK;
      else
         aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
      return (aval ^ mask);
   }
}

LOCAL int LinearToALaw(uint8_t *Dest,const MpAudioSample *src, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = Linear2ALaw(*src);
      Dest++; src++;
   }
   return samples;
}

int G711A_Encoder(int numSamples,
                  const MpAudioSample* inBuff,
                  uint8_t* outBuf)
{
   LinearToALaw(outBuf, inBuff, numSamples);
   return 0;
}

LOCAL uint8_t hzm_Linear2ULaw(MpAudioSample L)
{
   int seg;
   uint8_t signmask;

   if (0 > L) {
      L = BIAS - L;
      signmask = 0x7f;
   } else {
      signmask = 0xff;
      L = BIAS + L;
   }
   if (L > 32767) L = 32767;
   if (0x7800 & L) {
      seg = (4<<4);
   } else {
      seg = 0;
      L = L << 4;
   }
   if (0x6000 & L) {
      seg += (2<<4);
   } else {
      L = L << 2;
   }
   if (0x4000 & L) {
      seg += (1<<4);
   } else {
      L = L << 1;
   }
   return ((seg | ((0x3C00 & L) >> 10)) ^ signmask);
}

LOCAL int LinearToULaw(uint8_t *Dest, const MpAudioSample *src, int samples)
{
   int i;

   for (i=0; i<samples; i++) {
      *Dest = hzm_Linear2ULaw(*src);
      Dest++; src++;
   }
   return samples;
}

int G711U_Encoder(int numSamples,
                  const MpAudioSample* inBuff,
                  uint8_t* outBuf)
{
   LinearToULaw(outBuf, inBuff, numSamples);
   return 0;
}
#endif /* NOT(HAVE_GIPS) ] */
<commit_msg>Fix build of MpSipxDecoders.cpp<commit_after>//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

#ifndef HAVE_GIPS /* [ */

#include "assert.h"

#include "mp/MpSipxDecoders.h"

#define LOCAL static
//#undef LOCAL
//#define LOCAL

/* ============================ CREATORS ================================== */

/* ============================ MANIPULATORS ============================== */

#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
#define QUANT_MASK      (0xf)           /* Quantization field mask. */
#define SEG_SHIFT       (4)             /* Left shift for segment number. */
#define SEG_MASK        (0x70)          /* Segment field mask. */

#define BIAS            (0x84)          /* Bias for linear code. */

LOCAL MpAudioSample hzm_ULaw2linear(uint8_t u)
{
   int L;
   int seg;

   u = ~u;
   seg = (u & 0x70) >> 4;
   L = ((0x0f & u) << 3) + BIAS;
   L = (L << seg);
   if (0x80 & u)
   {
      L = BIAS - L;
   }
   else
   {
      L = L - BIAS;
   }
   return L;
}

LOCAL int ULawToLinear(MpAudioSample *Dest, const uint8_t *Source, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = hzm_ULaw2linear(*Source);
      Dest++; Source++;
   }
   return samples;
}

/*
 * ALaw2Linear() - Convert an A-law value to 16-bit linear PCM
 *
 */
LOCAL MpAudioSample ALaw2Linear(uint8_t a_val)
{
   int t;
   int seg;

   a_val ^= 0x55;

   t = (a_val & QUANT_MASK) << 4;
   seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
   switch (seg)
   {
   case 0:
      t += 8;
      break;
   case 1:
      t += 0x108;
      break;
   default:
      t += 0x108;
      t <<= seg - 1;
   }
   return ((a_val & SIGN_BIT) ? t : -t);
}

LOCAL int ALawToLinear(MpAudioSample *Dest, const uint8_t *src, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = ALaw2Linear(*src);
      Dest++; src++;
   }
   return samples;
}

LOCAL int16_t seg_end[8] = {0x00FF, 0x01FF, 0x03FF, 0x07FF,
                            0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF};

LOCAL int search(MpAudioSample val, int16_t *table, int size)
{
   int             i;

   for (i = 0; i < size; i++)
   {
      if (val <= *table++)
      {
         return i;
      }
   }
   return size;
}

int G711A_Decoder(int numSamples,
                  const uint8_t* codBuff,
                  MpAudioSample* outBuff)
{
   ALawToLinear(outBuff, codBuff, numSamples);
   return 0;
}

int G711U_Decoder(int numSamples,
                  const uint8_t* codBuff,
                  MpAudioSample* outBuff)
{
   ULawToLinear(outBuff, codBuff, numSamples);
   return 0;
}

/*
 * Linear2ALaw() - Convert a 16-bit linear PCM value to 8-bit A-law
 *
 * Linear2ALaw() accepts an 16-bit integer and encodes it as A-law data.
 *
 *              Linear Input Code       Compressed Code
 *      ------------------------        ---------------
 *      0000000wxyza                    000wxyz
 *      0000001wxyza                    001wxyz
 *      000001wxyzab                    010wxyz
 *      00001wxyzabc                    011wxyz
 *      0001wxyzabcd                    100wxyz
 *      001wxyzabcde                    101wxyz
 *      01wxyzabcdef                    110wxyz
 *      1wxyzabcdefg                    111wxyz
 *
 * For further information see John C. Bellamy's Digital Telephony, 1982,
 * John Wiley & Sons, pps 98-111 and 472-476.
 */
LOCAL uint8_t Linear2ALaw(MpAudioSample pcm_val ///< 2's complement (16-bit range)
                          )
{
   int      mask;
   int      seg;
   uint8_t  aval;

   if (pcm_val >= 0)
   {
      mask = 0xD5;            /* sign (7th) bit = 1 */
   }
   else
   {
      mask = 0x55;            /* sign bit = 0 */
      pcm_val = -pcm_val - 8;
   }

   /* Convert the scaled magnitude to segment number. */
   seg = search(pcm_val, seg_end, 8);

   /* Combine the sign, segment, and quantization bits. */

   if (seg >= 8)           /* out of range, return maximum value. */
   {
      return (0x7F ^ mask);
   }
   else
   {
      aval = seg << SEG_SHIFT;
      if (seg < 2)
         aval |= (pcm_val >> 4) & QUANT_MASK;
      else
         aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
      return (aval ^ mask);
   }
}

LOCAL int LinearToALaw(uint8_t *Dest,const MpAudioSample *src, int samples)
{
   int i;

   for (i=0; i<samples; i++)
   {
      *Dest = Linear2ALaw(*src);
      Dest++; src++;
   }
   return samples;
}

int G711A_Encoder(int numSamples,
                  const MpAudioSample* inBuff,
                  uint8_t* outBuf)
{
   LinearToALaw(outBuf, inBuff, numSamples);
   return 0;
}

LOCAL uint8_t hzm_Linear2ULaw(MpAudioSample L)
{
   int seg;
   uint8_t signmask;

   if (0 > L) {
      L = BIAS - L;
      signmask = 0x7f;
   } else {
      signmask = 0xff;
      L = BIAS + L;
   }
   if (L > 32767) L = 32767;
   if (0x7800 & L) {
      seg = (4<<4);
   } else {
      seg = 0;
      L = L << 4;
   }
   if (0x6000 & L) {
      seg += (2<<4);
   } else {
      L = L << 2;
   }
   if (0x4000 & L) {
      seg += (1<<4);
   } else {
      L = L << 1;
   }
   return ((seg | ((0x3C00 & L) >> 10)) ^ signmask);
}

LOCAL int LinearToULaw(uint8_t *Dest, const MpAudioSample *src, int samples)
{
   int i;

   for (i=0; i<samples; i++) {
      *Dest = hzm_Linear2ULaw(*src);
      Dest++; src++;
   }
   return samples;
}

int G711U_Encoder(int numSamples,
                  const MpAudioSample* inBuff,
                  uint8_t* outBuf)
{
   LinearToULaw(outBuf, inBuff, numSamples);
   return 0;
}
#endif /* NOT(HAVE_GIPS) ] */
<|endoftext|>


<commit_before>#include "colordialogbutton.h"

#include <QColorDialog>
#include <QPainter>

ColorDialogButton::ColorDialogButton(QWidget *parent) :
    QPushButton(parent)
{
//    button = new QPushButton("Select Color", this);
    QColor base(0,0,0);
    __currentColor = base;

    connect(this, SIGNAL(clicked()), this, SLOT(selectNewColor()));

    this->setText(" ");
    this->setFlat(true);

    QRect *rect = new QRect(this->rect().topLeft(),this->rect().bottomRight());
    QRegion* region = new QRegion(*rect,QRegion::Rectangle);

    this->setMask(*region);
    update();
    setButtonColor(__currentColor);
}

void ColorDialogButton::paintEvent(QPaintEvent *aPaintEvent)
{

    qreal opacity(0.675);
    int roundness(40);
    QRect widget_rect = this->rect();

    QPainter painter(this);
    painter.save();

//    painter.setRenderHint(QPainter::Antialiasing,true);
//    painter.setRenderHint(QPainter::CompositionMode_Clear);

  // clip
    QPainterPath rounded_rect;
    rounded_rect.setFillRule(Qt::FillRule::);
    painter.setBackground(__currentColor);
    rounded_rect.addRoundRect(1, 1, widget_rect.width() - 2, widget_rect.height() - 2, roundness, roundness);

    painter.setClipPath(rounded_rect);

    // get clipping region
  QRegion maskregion = painter.clipRegion();

  // mask the widget
  setMask(maskregion);
  painter.setOpacity(opacity);

  // fill path with color
//  painter.fillPath(rounded_rect,QBrush());

  // restore painter
  painter.restore();

}

ColorDialogButton::~ColorDialogButton()
{
}

void ColorDialogButton::selectNewColor()
{
    QColor color = QColorDialog::getColor(Qt::green, this);
    if (color.isValid())
    {
//        colorLabel->setText(color.name());
//        colorLabel->setPalette(QPalette(color));
//        colorLabel->setAutoFillBackground(true);

        setButtonColor(color);
    }
    __currentColor = color;
    emit colorChanged(color);
}

void ColorDialogButton::clearLayout(QLayout *layout)
{
    QLayoutItem *item;
    while((item = layout->takeAt(0))) {
        if (item->layout()) {
            clearLayout(item->layout());
            delete item->layout();
        }
        if (item->widget()) {
            delete item->widget();
        }
        delete item;
    }
}

void ColorDialogButton::setButtonColor(QColor color)
{
    QPalette palette = this->palette();
    palette.setColor(QPalette::Active, QPalette::Button,color);
    palette.setColor(QPalette::Inactive, QPalette::Button, color);

    this->setPalette(palette);
    this->setAutoFillBackground( true );
}
<commit_msg>Degub<commit_after>#include "colordialogbutton.h"

#include <QColorDialog>
#include <QPainter>

ColorDialogButton::ColorDialogButton(QWidget *parent) :
    QPushButton(parent)
{
//    button = new QPushButton("Select Color", this);
    QColor base(0,0,0);
    __currentColor = base;

    connect(this, SIGNAL(clicked()), this, SLOT(selectNewColor()));

    this->setText(" ");
    this->setFlat(true);

    QRect *rect = new QRect(this->rect().topLeft(),this->rect().bottomRight());
    QRegion* region = new QRegion(*rect,QRegion::Rectangle);

    this->setMask(*region);
    update();
    setButtonColor(__currentColor);
}

void ColorDialogButton::paintEvent(QPaintEvent *aPaintEvent)
{

    qreal opacity(0.675);
    int roundness(40);
    QRect widget_rect = this->rect();

    QPainter painter(this);
    painter.save();

//    painter.setRenderHint(QPainter::Antialiasing,true);
//    painter.setRenderHint(QPainter::CompositionMode_Clear);

  // clip
    QPainterPath rounded_rect;

    painter.setBackground(__currentColor);
    rounded_rect.addRoundRect(1, 1, widget_rect.width() - 2, widget_rect.height() - 2, roundness, roundness);

    painter.setClipPath(rounded_rect);

    // get clipping region
  QRegion maskregion = painter.clipRegion();

  // mask the widget
  setMask(maskregion);
  painter.setOpacity(opacity);

  // fill path with color
//  painter.fillPath(rounded_rect,QBrush());

  // restore painter
  painter.restore();

}

ColorDialogButton::~ColorDialogButton()
{
}

void ColorDialogButton::selectNewColor()
{
    QColor color = QColorDialog::getColor(Qt::green, this);
    if (color.isValid())
    {
//        colorLabel->setText(color.name());
//        colorLabel->setPalette(QPalette(color));
//        colorLabel->setAutoFillBackground(true);

        setButtonColor(color);
    }
    __currentColor = color;
    emit colorChanged(color);
}

void ColorDialogButton::clearLayout(QLayout *layout)
{
    QLayoutItem *item;
    while((item = layout->takeAt(0))) {
        if (item->layout()) {
            clearLayout(item->layout());
            delete item->layout();
        }
        if (item->widget()) {
            delete item->widget();
        }
        delete item;
    }
}

void ColorDialogButton::setButtonColor(QColor color)
{
    QPalette palette = this->palette();
    palette.setColor(QPalette::Active, QPalette::Button,color);
    palette.setColor(QPalette::Inactive, QPalette::Button, color);

    this->setPalette(palette);
    this->setAutoFillBackground( true );
}
<|endoftext|>