<commit_before>/* httpparser.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of tntnet.

Tntnet 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.

Tntnet 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 tntnet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA
*/

#include <tnt/httpparser.h>
#include <tnt/httperror.h>
#include <tnt/httpheader.h>
#include <cxxtools/log.h>
#include <sstream>

#define SET_STATE(new_state)  state = &Parser::new_state

namespace tnt
{
  namespace
  {
    std::string chartoprint(char ch)
    {
      const static char hex[] = "0123456789abcdef";
      if (std::isprint(ch))
        return std::string(1, '\'') + ch + '\'';
      else
        return std::string("'\\x") + hex[(ch >> 4) & 0xf] + hex[ch & 0xf] + '\'';
    }
  }

  log_define("tntnet.httpmessage.parser")

  void HttpMessage::Parser::reset()
  {
    message.clear();
    SET_STATE(state_cmd0);
    httpCode = HTTP_OK;
    failedFlag = false;
    requestSize = 0;
    headerParser.reset();
  }

  bool HttpMessage::Parser::state_cmd0(char ch)
  {
    if (!std::isspace(ch))
    {
      message.method = ch;
      SET_STATE(state_cmd);
    }
    return false;
  }

  bool HttpMessage::Parser::state_cmd(char ch)
  {
    if (std::isspace(ch))
    {
      log_debug("method=" << message.method);
      SET_STATE(state_url0);
    }
    else
      message.method += ch;
    return false;
  }

  bool HttpMessage::Parser::state_url0(char ch)
  {
    if (!std::isspace(ch))
    {
      if (ch > ' ')
      {
        message.url = ch;
        SET_STATE(state_url);
      }
      else
      {
        log_warn("invalid character " << chartoprint(ch) << " in url");
        httpCode = HTTP_BAD_REQUEST;
        failedFlag = true;
      }
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_url(char ch)
  {
    if (ch == '?')
    {
      log_debug("url=" << message.url);
      SET_STATE(state_qparam);
    }
    else if (std::isspace(ch))
    {
      log_debug("url=" << message.url);
      SET_STATE(state_version);
    }
    else if (ch > ' ')
      message.url += ch;
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in url");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_qparam(char ch)
  {
    if (std::isspace(ch))
    {
      log_debug("queryString=" << message.queryString);
      SET_STATE(state_version);
    }
    else
      message.queryString += ch;
    return false;
  }

  bool HttpMessage::Parser::state_version(char ch)
  {
    if (ch == '/')
      SET_STATE(state_version_major);
    else if (ch == '\r')
    {
      log_warn("invalid character " << chartoprint(ch) << " in version");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_version_major(char ch)
  {
    if (ch == '.')
      SET_STATE(state_version_minor);
    else if (std::isdigit(ch))
      message.majorVersion = message.majorVersion * 10 + (ch - '0');
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in version-major");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_version_minor(char ch)
  {
    if (ch == '\n')
      SET_STATE(state_header);
    else if (std::isspace(ch))
      SET_STATE(state_end0);
    else if (std::isdigit(ch))
      message.minorVersion = message.minorVersion * 10 + (ch - '0');
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in version-minor");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_end0(char ch)
  {
    if (ch == '\n')
      SET_STATE(state_header);
    else if (!std::isspace(ch))
    {
      log_warn("invalid character " << chartoprint(ch) << " in end");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_header(char ch)
  {
    if (headerParser.parse(ch))
    {
      if (headerParser.failed())
      {
        httpCode = HTTP_BAD_REQUEST;
        failedFlag = true;
        return true;
      }

      std::string content_length_header = message.getHeader(httpheader::contentLength);
      if (!content_length_header.empty())
      {
        std::istringstream valuestream(content_length_header);
        valuestream >> bodySize;
        if (!valuestream)
          throw HttpError("400 missing Content-Length");

        message.contentSize = bodySize;
        if (bodySize == 0)
          return true;
        else
        {
          SET_STATE(state_body);
          return false;
        }
      }

      return true;
    }

    return false;
  }

  bool HttpMessage::Parser::state_body(char ch)
  {
    message.body += ch;
    return --bodySize == 0;
  }

  bool HttpMessage::Parser::post(bool ret)
  {
    if (++requestSize > maxRequestSize && maxRequestSize > 0)
    {
      log_warn("max request size " << maxRequestSize << " exceeded");
      httpCode = HTTP_REQUEST_ENTITY_TOO_LARGE;
      failedFlag = true;
      return true;
    }

    return ret;
  }
}
<commit_msg>accept simple, not quite conformant requests without http-version-part<commit_after>/* httpparser.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of tntnet.

Tntnet 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.

Tntnet 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 tntnet; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA
*/

#include <tnt/httpparser.h>
#include <tnt/httperror.h>
#include <tnt/httpheader.h>
#include <cxxtools/log.h>
#include <sstream>

#define SET_STATE(new_state)  state = &Parser::new_state

namespace tnt
{
  namespace
  {
    std::string chartoprint(char ch)
    {
      const static char hex[] = "0123456789abcdef";
      if (std::isprint(ch))
        return std::string(1, '\'') + ch + '\'';
      else
        return std::string("'\\x") + hex[(ch >> 4) & 0xf] + hex[ch & 0xf] + '\'';
    }
  }

  log_define("tntnet.httpmessage.parser")

  void HttpMessage::Parser::reset()
  {
    message.clear();
    SET_STATE(state_cmd0);
    httpCode = HTTP_OK;
    failedFlag = false;
    requestSize = 0;
    headerParser.reset();
  }

  bool HttpMessage::Parser::state_cmd0(char ch)
  {
    if (!std::isspace(ch))
    {
      message.method = ch;
      SET_STATE(state_cmd);
    }
    return false;
  }

  bool HttpMessage::Parser::state_cmd(char ch)
  {
    if (std::isspace(ch))
    {
      log_debug("method=" << message.method);
      SET_STATE(state_url0);
    }
    else
      message.method += ch;
    return false;
  }

  bool HttpMessage::Parser::state_url0(char ch)
  {
    if (!std::isspace(ch))
    {
      if (ch > ' ')
      {
        message.url = ch;
        SET_STATE(state_url);
      }
      else
      {
        log_warn("invalid character " << chartoprint(ch) << " in url");
        httpCode = HTTP_BAD_REQUEST;
        failedFlag = true;
      }
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_url(char ch)
  {
    if (ch == '?')
    {
      log_debug("url=" << message.url);
      SET_STATE(state_qparam);
    }
    else if (ch == '\r')
    {
      log_debug("url=" << message.url);
      SET_STATE(state_end0);
    }
    else if (ch == '\n')
    {
      log_debug("url=" << message.url);
      SET_STATE(state_header);
    }
    else if (ch == ' ' || ch == '\t')
    {
      log_debug("url=" << message.url);
      SET_STATE(state_version);
    }
    else if (ch > ' ')
      message.url += ch;
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in url");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_qparam(char ch)
  {
    if (std::isspace(ch))
    {
      log_debug("queryString=" << message.queryString);
      SET_STATE(state_version);
    }
    else
      message.queryString += ch;
    return false;
  }

  bool HttpMessage::Parser::state_version(char ch)
  {
    if (ch == '/')
      SET_STATE(state_version_major);
    else if (ch == '\r')
    {
      log_warn("invalid character " << chartoprint(ch) << " in version");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_version_major(char ch)
  {
    if (ch == '.')
      SET_STATE(state_version_minor);
    else if (std::isdigit(ch))
      message.majorVersion = message.majorVersion * 10 + (ch - '0');
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in version-major");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_version_minor(char ch)
  {
    if (ch == '\n')
      SET_STATE(state_header);
    else if (std::isspace(ch))
      SET_STATE(state_end0);
    else if (std::isdigit(ch))
      message.minorVersion = message.minorVersion * 10 + (ch - '0');
    else
    {
      log_warn("invalid character " << chartoprint(ch) << " in version-minor");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_end0(char ch)
  {
    if (ch == '\n')
      SET_STATE(state_header);
    else if (!std::isspace(ch))
    {
      log_warn("invalid character " << chartoprint(ch) << " in end");
      httpCode = HTTP_BAD_REQUEST;
      failedFlag = true;
    }
    return failedFlag;
  }

  bool HttpMessage::Parser::state_header(char ch)
  {
    if (headerParser.parse(ch))
    {
      if (headerParser.failed())
      {
        httpCode = HTTP_BAD_REQUEST;
        failedFlag = true;
        return true;
      }

      std::string content_length_header = message.getHeader(httpheader::contentLength);
      if (!content_length_header.empty())
      {
        std::istringstream valuestream(content_length_header);
        valuestream >> bodySize;
        if (!valuestream)
          throw HttpError("400 missing Content-Length");

        message.contentSize = bodySize;
        if (bodySize == 0)
          return true;
        else
        {
          SET_STATE(state_body);
          return false;
        }
      }

      return true;
    }

    return false;
  }

  bool HttpMessage::Parser::state_body(char ch)
  {
    message.body += ch;
    return --bodySize == 0;
  }

  bool HttpMessage::Parser::post(bool ret)
  {
    if (++requestSize > maxRequestSize && maxRequestSize > 0)
    {
      log_warn("max request size " << maxRequestSize << " exceeded");
      httpCode = HTTP_REQUEST_ENTITY_TOO_LARGE;
      failedFlag = true;
      return true;
    }

    return ret;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#include <iostream>
#include <Common/Colorful.hh>
#include <Setting/Setting.hh>
#include <Core/TadpoleVM.hh>
#include <GC/GC.hh>
#include <Builtin/Builtins.hh>

namespace Tadpole::Builtin {

void register_builtins(Core::TadpoleVM& vm) noexcept {
  // fn help() -> Nil
  vm.define_native("help", [](sz_t, Value::Value*) -> Value::Value {
        std::cout
          << Common::Colorful::fg::green << "Welcome To Tadpole! This is the help utility."
          << Common::Colorful::reset << std::endl << std::endl;

          std::cout << "print(...)        Prints the values to stdout stream" << std::endl;
          std::cout << "exit()            Exit the Tadpole terminal" << std::endl;
          std::cout << "time()            Return the current time in seconds since the Epoch" << std::endl;
          std::cout << "clock()           Return the CPU time since the start of the process" << std::endl;
          std::cout << "get_count()       Return number of objects tracked by GC" << std::endl;
          std::cout << "gc_threshold()    Return the current collection threshold" << std::endl;
          std::cout << "gc_threshold(n)   Sets the collection threshold" << std::endl;
          std::cout << "gc_collect()      Run a full collection" << std::endl;
          std::cout << "gc_isenabled()    Return true if automatic collection is enabled" << std::endl;
          std::cout << "gc_enable()       Enable automatic garbage collection" << std::endl;
          std::cout << "gc_disable()      Disable automatic garbage collection" << std::endl;
          std::cout << "test_isenabled()  Return true if `Unit-Test` is enabled" << std::endl;
          std::cout << "test_enable()     Enable `Unit-Test`" << std::endl;
          std::cout << "test_disable()    Disable `Unit-Test`" << std::endl;

          return nullptr;
      });

  // fn print(arg1: Value, arg2: Value, arg3: Value, ...) -> Nil
  vm.define_native("print", [](sz_t nargs, Value::Value* args) -> Value::Value {
        for (sz_t i = 0; i < nargs; ++i)
          std::cout << args[i] << " ";
        std::cout << std::endl;

        return nullptr;
      });

  // fn exit() -> Nil
  vm.define_native("exit", [&vm](sz_t, Value::Value*) -> Value::Value {
        vm.terminate();
        return nullptr;
      });

  // fn time() -> Numeric
  //
  // @returns
  //    Returns the current time in seconds since the Epoch.
  vm.define_native("time", [](sz_t, Value::Value*) -> Value::Value {
        return std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count() / 1000.0;
      });

  // fn clock() -> Numeric
  //
  // @returns
  //    Return the current processor time as a Numeric expressed in microseconds.
  vm.define_native("clock", [](sz_t, Value::Value*) -> Value::Value {
        return std::chrono::duration_cast<std::chrono::microseconds>(
            std::chrono::steady_clock::now().time_since_epoch()).count();
      });

  // fn gc_count() -> Numeric
  //
  // @returns
  //    Return the current collection counts.
  vm.define_native("gc_count", [](sz_t, Value::Value*) -> Value::Value {
        return GC::GC::get_instance().get_count();
      });

  // fn gc_threshold() -> Numeric
  //
  // @returns
  //    Returns the current collection threshold.
  //
  //
  // fn gc_threshold(threshold: Numeric) -> Numeric
  //
  // @args
  //    threshold: Numeric -> Number of collection threshold will be setted.
  //
  // @returns
  //    Returns the current collection threshold.
  vm.define_native("gc_threshold", [](sz_t nargs, Value::Value* args) -> Value::Value {
        if (nargs == 1 && args != nullptr && args[0].as_numeric())
          GC::GC::get_instance().set_threshold(args[0].as_integer<sz_t>());
        return GC::GC::get_instance().get_threshold();
      });

  // fn gc_collect() -> Nil
  vm.define_native("gc_collect", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().collect();
        return nullptr;
      });

  // fn gc_isenabled() -> Boolean
  //
  // @returns
  //    Returns `true` if automatic collection is enabled.
  vm.define_native("gc_isenabled", [](sz_t, Value::Value*) -> Value::Value {
        return GC::GC::get_instance().is_enabled();
      });

  // fn gc_enable() -> Nil
  //
  // Enable automatic garbage collection.
  vm.define_native("gc_enable", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().enable();
        return nullptr;
      });

  // fn gc_disable() -> Nil
  //
  // Disable automatic garbage collection.
  vm.define_native("gc_disable", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().disable();
        return nullptr;
      });

  // fn test_isenabled() -> Boolean
  //
  // @returns
  //    Returns `true` if `Unit-Test` is enabled.
  vm.define_native("test_isenabled", [](sz_t, Value::Value*) -> Value::Value {
        return Setting::Setting::get_instance().enabled_run_harness();
      });
}

}
<commit_msg>:construction: chore(builtin): updated the builtin implementation for more export functions<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#include <iostream>
#include <Common/Colorful.hh>
#include <Setting/Setting.hh>
#include <Core/TadpoleVM.hh>
#include <GC/GC.hh>
#include <Builtin/Builtins.hh>

namespace Tadpole::Builtin {

void register_builtins(Core::TadpoleVM& vm) noexcept {
  // fn help() -> Nil
  vm.define_native("help", [](sz_t, Value::Value*) -> Value::Value {
        std::cout
          << Common::Colorful::fg::lightcyan << "Welcome To Tadpole! This is the help utility."
          << Common::Colorful::reset << std::endl << std::endl;

          std::cout << "print(...)        Prints the values to stdout stream" << std::endl;
          std::cout << "exit()            Exit the Tadpole terminal" << std::endl;
          std::cout << "time()            Return the current time in seconds since the Epoch" << std::endl;
          std::cout << "clock()           Return the CPU time since the start of the process" << std::endl;
          std::cout << "gc_count()        Return number of objects tracked by GC" << std::endl;
          std::cout << "gc_threshold()    Return the current collection threshold" << std::endl;
          std::cout << "gc_threshold(n)   Sets the collection threshold" << std::endl;
          std::cout << "gc_collect()      Run a full collection" << std::endl;
          std::cout << "gc_isenabled()    Return true if automatic collection is enabled" << std::endl;
          std::cout << "gc_enable()       Enable automatic garbage collection" << std::endl;
          std::cout << "gc_disable()      Disable automatic garbage collection" << std::endl;
          std::cout << "test_isenabled()  Return true if `Unit-Test` is enabled" << std::endl;
          std::cout << "test_enable()     Enable `Unit-Test`" << std::endl;
          std::cout << "test_disable()    Disable `Unit-Test`" << std::endl;

          return nullptr;
      });

  // fn print(arg1: Value, arg2: Value, arg3: Value, ...) -> Nil
  vm.define_native("print", [](sz_t nargs, Value::Value* args) -> Value::Value {
        for (sz_t i = 0; i < nargs; ++i)
          std::cout << args[i] << " ";
        std::cout << std::endl;

        return nullptr;
      });

  // fn exit() -> Nil
  vm.define_native("exit", [&vm](sz_t, Value::Value*) -> Value::Value {
        vm.terminate();
        return nullptr;
      });

  // fn time() -> Numeric
  //
  // @returns
  //    Returns the current time in seconds since the Epoch.
  vm.define_native("time", [](sz_t, Value::Value*) -> Value::Value {
        return std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count() / 1000.0;
      });

  // fn clock() -> Numeric
  //
  // @returns
  //    Return the current processor time as a Numeric expressed in microseconds.
  vm.define_native("clock", [](sz_t, Value::Value*) -> Value::Value {
        return std::chrono::duration_cast<std::chrono::microseconds>(
            std::chrono::steady_clock::now().time_since_epoch()).count();
      });

  // fn gc_count() -> Numeric
  //
  // @returns
  //    Return the current collection counts.
  vm.define_native("gc_count", [](sz_t, Value::Value*) -> Value::Value {
        return GC::GC::get_instance().get_count();
      });

  // fn gc_threshold() -> Numeric
  //
  // @returns
  //    Returns the current collection threshold.
  //
  //
  // fn gc_threshold(threshold: Numeric) -> Numeric
  //
  // @args
  //    threshold: Numeric -> Number of collection threshold will be setted.
  //
  // @returns
  //    Returns the current collection threshold.
  vm.define_native("gc_threshold", [](sz_t nargs, Value::Value* args) -> Value::Value {
        if (nargs == 1 && args != nullptr && args[0].as_numeric())
          GC::GC::get_instance().set_threshold(args[0].as_integer<sz_t>());
        return GC::GC::get_instance().get_threshold();
      });

  // fn gc_collect() -> Nil
  vm.define_native("gc_collect", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().collect();
        return nullptr;
      });

  // fn gc_isenabled() -> Boolean
  //
  // @returns
  //    Returns `true` if automatic collection is enabled.
  vm.define_native("gc_isenabled", [](sz_t, Value::Value*) -> Value::Value {
        return GC::GC::get_instance().is_enabled();
      });

  // fn gc_enable() -> Nil
  //
  // Enable automatic garbage collection.
  vm.define_native("gc_enable", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().enable();
        return nullptr;
      });

  // fn gc_disable() -> Nil
  //
  // Disable automatic garbage collection.
  vm.define_native("gc_disable", [](sz_t, Value::Value*) -> Value::Value {
        GC::GC::get_instance().disable();
        return nullptr;
      });

  // fn test_isenabled() -> Boolean
  //
  // @returns
  //    Returns `true` if `Unit-Test` is enabled.
  vm.define_native("test_isenabled", [](sz_t, Value::Value*) -> Value::Value {
        return Setting::Setting::get_instance().enabled_run_harness();
      });

  // fn test_enable() -> Nil
  //
  // Enable run `Unit-Test`.
  vm.define_native("test_enable", [](sz_t, Value::Value*) -> Value::Value {
        Setting::Setting::get_instance().enable_run_harness();
        return nullptr;
      });
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#include <iostream>
#include <Common/Colorful.hh>
#include <Core/TadpoleVM.hh>
#include <GC/GC.hh>
#include <Builtin/Builtins.hh>

namespace Tadpole::Builtin {

void register_builtins(Core::TadpoleVM& vm) noexcept {
  // TODO:
}

}
<commit_msg>:construction: chore(built-in): updated the built-in implementation<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <chrono>
#include <iostream>
#include <Common/Colorful.hh>
#include <Core/TadpoleVM.hh>
#include <GC/GC.hh>
#include <Builtin/Builtins.hh>

namespace Tadpole::Builtin {

void register_builtins(Core::TadpoleVM& vm) noexcept {
  // fn help() -> Nil
  vm.define_native("help", [](sz_t, Value::Value*) -> Value::Value {
        std::cout
          << Common::Colorful::fg::green << "Welcome To Tadpole! This is the help utility."
          << Common::Colorful::reset << std::endl << std::endl;

          std::cout << "print(...)      Prints the values to stdout stream" << std::endl;
          std::cout << "exit()          Exit the Tadpole terminal" << std::endl;

          return nullptr;
      });

  // fn print(arg1: Value, arg2: Value, arg3: Value, ...) -> Nil
  vm.define_native("print", [](sz_t nargs, Value::Value* args) -> Value::Value {
        for (sz_t i = 0; i < nargs; ++i)
          std::cout << args[i] << " ";
        std::cout << std::endl;

        return nullptr;
      });
}

}
<|endoftext|>


<commit_before>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "file_manager.h"
#include "stringhelpers.h"
#include "encryption.h"
#include "exception.h"
#include <QDesktopServices>
#include <QFile>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QVariant>
#include <QMutex>
#include <QReadWriteLock>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlResult>
#include <QMap>
#include <QMessageBox>
#include <QByteArray>
#include <iostream>
using namespace GUtil;
using namespace GUtil::QtUtil;

// A class to keep track of our mutexes
class mutex_record_t
{
public:
    mutex_record_t()
    {
        count = 1;
        mut = new QReadWriteLock();
    }
    ~mutex_record_t(){ delete mut;}

    QReadWriteLock *mut;
    int count;
};

QMap<QString, mutex_record_t *> mutexes;
QReadWriteLock mutex_lock;

File_Manager::File_Manager(const QString &id, bool primary)
{
    my_id = id;
    file_location = get_file_loc(id);

    mutex_lock.lockForWrite();
    if(mutexes.contains(id))
    {
        mutexes.value(id)->mut->lockForWrite();

        mutexes[id]->count++;

        mutexes.value(id)->mut->unlock();
    }
    else
    {
        mutexes.insert(id, new mutex_record_t());
    }
    mutex_lock.unlock();

    if(primary)
    {
        if(QFile::exists(file_location))
            QFile::remove(file_location);

        QSqlDatabase::addDatabase("QSQLITE").setDatabaseName(file_location);
        reset();
    }
}

File_Manager::~File_Manager()
{

}

int File_Manager::addFile(const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = get_free_file_id(dbase);
    add_file(ret, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::addFile(int id, const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = add_file(id, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::add_file(int id, const QString &data, QSqlDatabase &dbase)
{
    if(has_file(id, dbase))
        remove_file(id, dbase);

    QSqlQuery q("INSERT INTO files (id, data) VALUES (:id, :data)", dbase);
    q.bindValue(":id", id);
    q.bindValue(":data", data, QSql::Binary);
    q.exec();

    return id;
}

void File_Manager::removeFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    remove_file(id, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::remove_file(int id, QSqlDatabase &dbase)
{
    // Remove each item one by one
    QSqlQuery q("DELETE FROM files WHERE id=:id");
    q.bindValue(":id", id);
    q.exec();
}

QString File_Manager::getFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT data, COUNT(data) FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();

    if(q.first() && (q.value(1).toInt() == 1))
    {
        QByteArray ba = q.value(0).toByteArray();
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        return QString::fromStdString(string(ba.constData(), ba.length()));
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    throw GUtil::Exception("File not found");
}

// Clear all files
void File_Manager::reset()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q(dbase);
    q.exec("DROP TABLE \"files\"");
    q.exec("CREATE TABLE \"files\" ("
               "\"id\" INTEGER NOT NULL,"
               "\"data\" BLOB NOT NULL)");
    q.exec("CREATE INDEX idx ON files(id)");
    dbase.close();

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::prep_database(QSqlDatabase &dbase)
{
    dbase = QSqlDatabase::database();
    if(!dbase.open())
    {
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        throw GUtil::Exception("Cannot open database");
    }
}

QString File_Manager::get_file_loc(const QString &id)
{
    return QDesktopServices::storageLocation(QDesktopServices::TempLocation)
            + QString("/%1.tempfile").arg(id);
}

QList<int> File_Manager::idList()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QList<int> ret;
    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT id FROM files");
    if(q.exec())
    {
        while(q.next())
        {
            ret.append(q.value(0).toInt());
        }
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::hasFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    bool ret = has_file(id, dbase);

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::has_file(int id, QSqlDatabase &dbase)
{
    QSqlQuery q("SELECT id FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();
    return q.first();
}

int File_Manager::get_free_file_id(QSqlDatabase &dbase)
{
    // You must already have a lock on the database before using this function!

    int max_id = 0;
    QSqlQuery q("SELECT COUNT(id),MAX(id) FROM files", dbase);
    q.exec();
    if(q.first())
    {
        if(q.value(0).toInt() > 0)
            max_id = q.value(1).toInt() + 1;
    }

    // Now just make sure the id isn't taken
    while(has_file(max_id, dbase))
        max_id++;

    return max_id;
}
<commit_msg>no need for iostream<commit_after>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "file_manager.h"
#include "stringhelpers.h"
#include "encryption.h"
#include "exception.h"
#include <QDesktopServices>
#include <QFile>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QVariant>
#include <QMutex>
#include <QReadWriteLock>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlResult>
#include <QMap>
#include <QMessageBox>
#include <QByteArray>
using namespace GUtil;
using namespace GUtil::QtUtil;

// A class to keep track of our mutexes
class mutex_record_t
{
public:
    mutex_record_t()
    {
        count = 1;
        mut = new QReadWriteLock();
    }
    ~mutex_record_t(){ delete mut;}

    QReadWriteLock *mut;
    int count;
};

QMap<QString, mutex_record_t *> mutexes;
QReadWriteLock mutex_lock;

File_Manager::File_Manager(const QString &id, bool primary)
{
    my_id = id;
    file_location = get_file_loc(id);

    mutex_lock.lockForWrite();
    if(mutexes.contains(id))
    {
        mutexes.value(id)->mut->lockForWrite();

        mutexes[id]->count++;

        mutexes.value(id)->mut->unlock();
    }
    else
    {
        mutexes.insert(id, new mutex_record_t());
    }
    mutex_lock.unlock();

    if(primary)
    {
        if(QFile::exists(file_location))
            QFile::remove(file_location);

        QSqlDatabase::addDatabase("QSQLITE").setDatabaseName(file_location);
        reset();
    }
}

File_Manager::~File_Manager()
{

}

int File_Manager::addFile(const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = get_free_file_id(dbase);
    add_file(ret, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::addFile(int id, const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = add_file(id, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::add_file(int id, const QString &data, QSqlDatabase &dbase)
{
    if(has_file(id, dbase))
        remove_file(id, dbase);

    QSqlQuery q("INSERT INTO files (id, data) VALUES (:id, :data)", dbase);
    q.bindValue(":id", id);
    q.bindValue(":data", data, QSql::Binary);
    q.exec();

    return id;
}

void File_Manager::removeFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    remove_file(id, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::remove_file(int id, QSqlDatabase &dbase)
{
    // Remove each item one by one
    QSqlQuery q("DELETE FROM files WHERE id=:id");
    q.bindValue(":id", id);
    q.exec();
}

QString File_Manager::getFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT data, COUNT(data) FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();

    if(q.first() && (q.value(1).toInt() == 1))
    {
        QByteArray ba = q.value(0).toByteArray();
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        return QString::fromStdString(string(ba.constData(), ba.length()));
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    throw GUtil::Exception("File not found");
}

// Clear all files
void File_Manager::reset()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q(dbase);
    q.exec("DROP TABLE \"files\"");
    q.exec("CREATE TABLE \"files\" ("
               "\"id\" INTEGER NOT NULL,"
               "\"data\" BLOB NOT NULL)");
    q.exec("CREATE INDEX idx ON files(id)");
    dbase.close();

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::prep_database(QSqlDatabase &dbase)
{
    dbase = QSqlDatabase::database();
    if(!dbase.open())
    {
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        throw GUtil::Exception("Cannot open database");
    }
}

QString File_Manager::get_file_loc(const QString &id)
{
    return QDesktopServices::storageLocation(QDesktopServices::TempLocation)
            + QString("/%1.tempfile").arg(id);
}

QList<int> File_Manager::idList()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QList<int> ret;
    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT id FROM files");
    if(q.exec())
    {
        while(q.next())
        {
            ret.append(q.value(0).toInt());
        }
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::hasFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    bool ret = has_file(id, dbase);

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::has_file(int id, QSqlDatabase &dbase)
{
    QSqlQuery q("SELECT id FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();
    return q.first();
}

int File_Manager::get_free_file_id(QSqlDatabase &dbase)
{
    // You must already have a lock on the database before using this function!

    int max_id = 0;
    QSqlQuery q("SELECT COUNT(id),MAX(id) FROM files", dbase);
    q.exec();
    if(q.first())
    {
        if(q.value(0).toInt() > 0)
            max_id = q.value(1).toInt() + 1;
    }

    // Now just make sure the id isn't taken
    while(has_file(max_id, dbase))
        max_id++;

    return max_id;
}
<|endoftext|>


<commit_before>// Lee-Kesler equation of state

#include "RedlichKwong.h"
#include <math.h>

namespace tpx {

    //--------------------------- member functions ------------------

    double RedlichKwong::up() {
	double u = -Pp()/Rho + hresid() + m_energy_offset;
        //cout << "up = " << u << endl;
        return u;
    }

    double RedlichKwong::hresid(){
        double hh = m_b * (Rho/m_mw);
	double hresid_mol_RT =  z() - 1.0
                             - (1.5*m_a/(m_b*8314.3*pow(T,1.5)))*log(1.0 + hh);
        return 8314.3*T*hresid_mol_RT/m_mw;
    }

    double RedlichKwong::sresid(){
        double hh = m_b * (Rho/m_mw);
        //cout << "hh = " << hh << endl;
	double sresid_mol_R =  log(z()*(1.0 - hh))
                             - (0.5*m_a/(m_b*8314.3*pow(T,1.5)))*log(1.0 + hh);
        double sp = 8314.3*sresid_mol_R/m_mw;
        //cout << "sresid = " << sp << endl;
        return sp;
    }

    double RedlichKwong::sp() {
	const double Pref = 101325.0;
	double rgas = 8314.3/m_mw;
        //cout << "P = " << Rho*rgas*T << endl;
        double ss = rgas*(log(Pref/(Rho*rgas*T)));
        double sr = sresid();
        double p = Pp();
	double s = rgas*(log(Pref/p)) + sr + m_entropy_offset;
        //cout << "sp = " << s << " " << ss << " " << sr << " " << m_entropy_offset << endl;
        return s;
    }

    double RedlichKwong::z() {
        return Pp()*m_mw/(Rho*8314.3*T);
    }

    double RedlichKwong::Pp() {
	double R = 8314.3;
        double V = m_mw/Rho;
        double pp = R*T/(V - m_b) - m_a/(sqrt(T)*V*(V+m_b));
        //cout << "molar V, T, P = " << V << " " << T << " " << pp << endl;
        return pp;
        //cout << "Rho, T, Pp = " << pp << endl;
    }

    double RedlichKwong::Psat(){
	double tt = m_tcrit/T;
        double lpr = -0.8734*tt*tt - 3.4522*tt + 4.2918;
	return m_pcrit*exp(lpr);
    }

    double RedlichKwong::ldens(){
        double c;
        int i;
        double sqt = sqrt(T);
        double v = m_b, vnew;
        double pp = Psat();
        double Rhsave = Rho;
        for (i = 0; i < 50; i++) {
            //pp = Pp();
            c = m_b*m_b + m_b*GasConstant*T/pp - m_a/(pp*sqt);
            vnew = (1.0/c)*(v*v*v - GasConstant*T*v*v/pp - m_a*m_b/(pp*sqt));
            v = vnew;
            //Rho = m_mw/v;
            //cout << "ldens Rho = " << Rho << "  " << z() << "  " << Pp() << endl;
        }
        Rho = Rhsave;
        //cout << "ldens: " << m_mw/vnew << endl;
        return m_mw/vnew;
    }

}
<commit_msg>eliminated use of pow<commit_after>// Lee-Kesler equation of state

#include "RedlichKwong.h"
#include <math.h>

namespace tpx {

    //--------------------------- member functions ------------------

    double RedlichKwong::up() {
	double u = -Pp()/Rho + hresid() + m_energy_offset;
        //cout << "up = " << u << endl;
        return u;
    }

    double RedlichKwong::hresid(){
        double hh = m_b * (Rho/m_mw);
	double hresid_mol_RT =  z() - 1.0
                                - (1.5*m_a/(m_b*8314.3*T*sqrt(T)))*log(1.0 + hh);
        return 8314.3*T*hresid_mol_RT/m_mw;
    }

    double RedlichKwong::sresid(){
        double hh = m_b * (Rho/m_mw);
        //cout << "hh = " << hh << endl;
	double sresid_mol_R =  log(z()*(1.0 - hh))
                               - (0.5*m_a/(m_b*8314.3*T*sqrt(T)))*log(1.0 + hh);
        double sp = 8314.3*sresid_mol_R/m_mw;
        //cout << "sresid = " << sp << endl;
        return sp;
    }

    double RedlichKwong::sp() {
	const double Pref = 101325.0;
	double rgas = 8314.3/m_mw;
        //cout << "P = " << Rho*rgas*T << endl;
        double ss = rgas*(log(Pref/(Rho*rgas*T)));
        double sr = sresid();
        double p = Pp();
	double s = rgas*(log(Pref/p)) + sr + m_entropy_offset;
        //cout << "sp = " << s << " " << ss << " " << sr << " " << m_entropy_offset << endl;
        return s;
    }

    double RedlichKwong::z() {
        return Pp()*m_mw/(Rho*8314.3*T);
    }

    double RedlichKwong::Pp() {
	double R = 8314.3;
        double V = m_mw/Rho;
        double pp = R*T/(V - m_b) - m_a/(sqrt(T)*V*(V+m_b));
        //cout << "molar V, T, P = " << V << " " << T << " " << pp << endl;
        return pp;
        //cout << "Rho, T, Pp = " << pp << endl;
    }

    double RedlichKwong::Psat(){
	double tt = m_tcrit/T;
        double lpr = -0.8734*tt*tt - 3.4522*tt + 4.2918;
	return m_pcrit*exp(lpr);
    }

    double RedlichKwong::ldens(){
        double c;
        int i;
        double sqt = sqrt(T);
        double v = m_b, vnew;
        double pp = Psat();
        double Rhsave = Rho;
        for (i = 0; i < 50; i++) {
            //pp = Pp();
            c = m_b*m_b + m_b*GasConstant*T/pp - m_a/(pp*sqt);
            vnew = (1.0/c)*(v*v*v - GasConstant*T*v*v/pp - m_a*m_b/(pp*sqt));
            v = vnew;
            //Rho = m_mw/v;
            //cout << "ldens Rho = " << Rho << "  " << z() << "  " << Pp() << endl;
        }
        Rho = Rhsave;
        //cout << "ldens: " << m_mw/vnew << endl;
        return m_mw/vnew;
    }

}
<|endoftext|>


<commit_before>// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
 *  Copyright 2010 ZXing authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zxing/common/BitArray.h>

using std::vector;
using zxing::BitArray;

int BitArray::makeArraySize(int size) {
  return (size + bitsPerWord-1) >> logBits;
}

BitArray::BitArray(int size_)
  : size(size_), bits(makeArraySize(size)) {}

BitArray::~BitArray() {
}

int BitArray::getSize() const {
  return size;
}

void BitArray::setBulk(int i, int newBits) {
  bits[i >> logBits] = newBits;
}

/*
  void BitArray::setRange(int start, int end) {
  if (end < start) {
  throw IllegalArgumentException("invalid call to BitArray::setRange");
  }
  if (end == start) {
  return;
  }
  end--; // will be easier to treat this as the last actually set bit -- inclusive
  int firstInt = start >> 5;
  int lastInt = end >> 5;
  for (int i = firstInt; i <= lastInt; i++) {
  int firstBit = i > firstInt ? 0 : start & 0x1F;
  int lastBit = i < lastInt ? 31 : end & 0x1F;
  int mask;
  if (firstBit == 0 && lastBit == 31) {
  mask = -1;
  } else {
  mask = 0;
  for (int j = firstBit; j <= lastBit; j++) {
  mask |= 1 << j;
  }
  }
  bits_[i] |= mask;
  }
  }
*/

void BitArray::clear() {
  int max = bits.size();
  for (int i = 0; i < max; i++) {
    bits[i] = 0;
  }
}

bool BitArray::isRange(int start, int end, bool value) {
  if (end < start) {
    throw IllegalArgumentException();
  }
  if (end == start) {
    return true; // empty range matches
  }
  end--; // will be easier to treat this as the last actually set bit -- inclusive
  int firstInt = start >> logBits;
  int lastInt = end >> logBits;
  for (int i = firstInt; i <= lastInt; i++) {
    int firstBit = i > firstInt ? 0 : start & bitsMask;
    int lastBit = i < lastInt ? (bitsPerWord-1) : end & bitsMask;
    int mask;
    if (firstBit == 0 && lastBit == (bitsPerWord-1)) {
      mask = -1;
    } else {
      mask = 0;
      for (int j = firstBit; j <= lastBit; j++) {
        mask |= 1 << j;
      }
    }

    // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
    // equals the mask, or we're looking for 0s and the masked portion is not all 0s
    if ((bits[i] & mask) != (value ? mask : 0)) {
      return false;
    }
  }
  return true;
}

vector<int>& BitArray::getBitArray() {
  return bits;
}

void BitArray::reverse() {
  vector<int> newBits(bits.size());
  int size = this->size;
  for (int i = 0; i < size; i++) {
    if (get(size - i - 1)) {
      newBits[i >> logBits] |= 1 << (i & bitsMask);
    }
  }
  bits = newBits;
}

/*
  BitArray::Reverse::Reverse(Ref<BitArray> array_) : array(array_) {
  array->reverse();
  }

  BitArray::Reverse::~Reverse() {
  array->reverse();
  }

  namespace {
  int numberOfTrailingZeros(int i) {
  // HD, Figure 5-14
  int y;
  if (i == 0) return 32;
  int n = 31;
  y = i <<16; if (y != 0) { n = n -16; i = y; }
  y = i << 8; if (y != 0) { n = n - 8; i = y; }
  y = i << 4; if (y != 0) { n = n - 4; i = y; }
  y = i << 2; if (y != 0) { n = n - 2; i = y; }
  return n - (((unsigned int)(i << 1)) >> 31);
  }
  }

  int BitArray::getNextSet(int from) {
  if (from >= size_) {
  return size_;
  }
  int bitsOffset = from >> 5;
  int currentBits = bits_[bitsOffset];
  // mask off lesser bits first
  currentBits &= ~((1 << (from & 0x1F)) - 1);
  while (currentBits == 0) {
  if (++bitsOffset == (int)bits_.size()) {
  return size_;
  }
  currentBits = bits_[bitsOffset];
  }
  int result = (bitsOffset << 5) + numberOfTrailingZeros(currentBits);
  return result > size_ ? size_ : result;
  }

  int BitArray::getNextUnset(int from) {
  if (from >= size_) {
  return size_;
  }
  int bitsOffset = from >> 5;
  int currentBits = ~bits_[bitsOffset];
  // mask off lesser bits first
  currentBits &= ~((1 << (from & 0x1F)) - 1);
  while (currentBits == 0) {
  if (++bitsOffset == (int)bits_.size()) {
  return size_;
  }
  currentBits = ~bits_[bitsOffset];
  }
  int result = (bitsOffset << 5) + numberOfTrailingZeros(currentBits);
  return result > size_ ? size_ : result;
  }
*/
<commit_msg>readd a couple of members not in tests<commit_after>// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
 *  Copyright 2010 ZXing authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zxing/common/BitArray.h>

using std::vector;
using zxing::BitArray;

int BitArray::makeArraySize(int size) {
  return (size + bitsPerWord-1) >> logBits;
}

BitArray::BitArray(int size_)
  : size(size_), bits(makeArraySize(size)) {}

BitArray::~BitArray() {
}

int BitArray::getSize() const {
  return size;
}

void BitArray::setBulk(int i, int newBits) {
  bits[i >> logBits] = newBits;
}

/*
  void BitArray::setRange(int start, int end) {
  if (end < start) {
  throw IllegalArgumentException("invalid call to BitArray::setRange");
  }
  if (end == start) {
  return;
  }
  end--; // will be easier to treat this as the last actually set bit -- inclusive
  int firstInt = start >> 5;
  int lastInt = end >> 5;
  for (int i = firstInt; i <= lastInt; i++) {
  int firstBit = i > firstInt ? 0 : start & 0x1F;
  int lastBit = i < lastInt ? 31 : end & 0x1F;
  int mask;
  if (firstBit == 0 && lastBit == 31) {
  mask = -1;
  } else {
  mask = 0;
  for (int j = firstBit; j <= lastBit; j++) {
  mask |= 1 << j;
  }
  }
  bits_[i] |= mask;
  }
  }
*/

void BitArray::clear() {
  int max = bits.size();
  for (int i = 0; i < max; i++) {
    bits[i] = 0;
  }
}

bool BitArray::isRange(int start, int end, bool value) {
  if (end < start) {
    throw IllegalArgumentException();
  }
  if (end == start) {
    return true; // empty range matches
  }
  end--; // will be easier to treat this as the last actually set bit -- inclusive
  int firstInt = start >> logBits;
  int lastInt = end >> logBits;
  for (int i = firstInt; i <= lastInt; i++) {
    int firstBit = i > firstInt ? 0 : start & bitsMask;
    int lastBit = i < lastInt ? (bitsPerWord-1) : end & bitsMask;
    int mask;
    if (firstBit == 0 && lastBit == (bitsPerWord-1)) {
      mask = -1;
    } else {
      mask = 0;
      for (int j = firstBit; j <= lastBit; j++) {
        mask |= 1 << j;
      }
    }

    // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
    // equals the mask, or we're looking for 0s and the masked portion is not all 0s
    if ((bits[i] & mask) != (value ? mask : 0)) {
      return false;
    }
  }
  return true;
}

vector<int>& BitArray::getBitArray() {
  return bits;
}

void BitArray::reverse() {
  vector<int> newBits(bits.size());
  int size = this->size;
  for (int i = 0; i < size; i++) {
    if (get(size - i - 1)) {
      newBits[i >> logBits] |= 1 << (i & bitsMask);
    }
  }
  bits = newBits;
}

BitArray::Reverse::Reverse(Ref<BitArray> array_) : array(array_) {
  array->reverse();
}

BitArray::Reverse::~Reverse() {
  array->reverse();
}

namespace {
  // N.B.: This only works for 32 bit ints ...
  int numberOfTrailingZeros(int i) {
    // HD, Figure 5-14
    int y;
    if (i == 0) return 32;
    int n = 31;
    y = i <<16; if (y != 0) { n = n -16; i = y; }
    y = i << 8; if (y != 0) { n = n - 8; i = y; }
    y = i << 4; if (y != 0) { n = n - 4; i = y; }
    y = i << 2; if (y != 0) { n = n - 2; i = y; }
    return n - (((unsigned int)(i << 1)) >> 31);
  }
}

int BitArray::getNextSet(int from) {
  if (from >= size) {
    return size;
  }
  int bitsOffset = from >> logBits;
  int currentBits = bits[bitsOffset];
  // mask off lesser bits first
  currentBits &= ~((1 << (from & bitsMask)) - 1);
  while (currentBits == 0) {
    if (++bitsOffset == (int)bits.size()) {
      return size;
    }
    currentBits = bits[bitsOffset];
  }
  int result = (bitsOffset << logBits) + numberOfTrailingZeros(currentBits);
  return result > size ? size : result;
}

int BitArray::getNextUnset(int from) {
  if (from >= size) {
    return size;
  }
  int bitsOffset = from >> logBits;
  int currentBits = ~bits[bitsOffset];
  // mask off lesser bits first
  currentBits &= ~((1 << (from & bitsMask)) - 1);
  while (currentBits == 0) {
    if (++bitsOffset == (int)bits.size()) {
      return size;
    }
    currentBits = ~bits[bitsOffset];
  }
  int result = (bitsOffset << logBits) + numberOfTrailingZeros(currentBits);
  return result > size ? size : result;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: externallock.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: pb $ $Date: 2002-05-30 13:13:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLKIT_HELPER_EXTERNALLOCK_HXX_
#include <toolkit/helper/externallock.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

// -----------------------------------------------------------------------------
//  class VCLExternalSolarLock
// -----------------------------------------------------------------------------
void VCLExternalSolarLock::acquire()
{
    Application::GetSolarMutex().acquire();
}
// -----------------------------------------------------------------------------
void VCLExternalSolarLock::release()
{
    Application::GetSolarMutex().release();
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.408); FILE MERGED 2005/09/05 16:58:18 rt 1.1.408.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: externallock.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:21:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLKIT_HELPER_EXTERNALLOCK_HXX_
#include <toolkit/helper/externallock.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

// -----------------------------------------------------------------------------
//  class VCLExternalSolarLock
// -----------------------------------------------------------------------------
void VCLExternalSolarLock::acquire()
{
    Application::GetSolarMutex().acquire();
}
// -----------------------------------------------------------------------------
void VCLExternalSolarLock::release()
{
    Application::GetSolarMutex().release();
}

<|endoftext|>


<commit_before>#include "xml_file_outline.hpp"
#include "xml_doc.hpp"
#include "xml_element.hpp"
#include <queue>
#include <string>

#include <QAction>
#include <QActionGroup>
#include <QDebug>
#include <QMenu>
#include <QPoint>
#include <QTreeWidgetItem>
#include <QWidget>

#include <libxml/tree.h>

static auto buildTreeFromXml( const XmlDoc &xml ) -> QTreeWidgetItem *;
static auto findXmlElement( QTreeWidgetItem *item, const XmlElement &element )
    -> QTreeWidgetItem *;

XmlFileOutline::XmlFileOutline( QWidget *parent ) : QTreeWidget{parent} {
    setContextMenuPolicy( Qt::CustomContextMenu );
    contextMenu( );
    connections( );
}

auto XmlFileOutline::clear( ) -> void { QTreeWidget::clear( ); }

auto XmlFileOutline::xml( const XmlDoc &xml ) -> void {
    addTopLevelItem( buildTreeFromXml( xml ) );
    if ( invisibleRootItem( )->child( 0 ) ) {
        expandItem( invisibleRootItem( )->child( 0 ) );
    }
}

void XmlFileOutline::itemClicked( const QModelIndex &idx ) {
    QTreeWidgetItem *target = itemFromIndex( idx );
    Qt::CheckState checkedState = target->checkState( 0 );
    switch ( checkedState ) {
    case Qt::Checked:
        checkSubtree( target );
        break;
    case Qt::Unchecked:
        uncheckSubtree( target );
        break;
    default:
        return;
    }
}

void XmlFileOutline::xPathResult( const XmlElement &element ) {
    qDebug( ) << "adding xpath result...\n";
    QTreeWidgetItem *root = invisibleRootItem( );
    QTreeWidgetItem *search = findXmlElement( root, element );
    //    if ( search ) {
    //        Qt::CheckState checkedState = search->checkState( 0 );
    //        switch ( checkedState ) {
    //        case Qt::Checked:
    //            break;
    //        case Qt::Unchecked:
    //            checkSubtree( search );
    //            break;
    //        default:
    //            // return;
    //        }
    //        search->setCheckState( 0, Qt::Checked );
    //    }
    if ( search ) {
        search->setCheckState( 0, Qt::Checked );
        itemClicked( indexFromItem( search, 0 ) );
    }
}

void XmlFileOutline::clearSelections( ) {
    qDebug( ) << "clearing all selections...\n";
    QTreeWidgetItem *root = invisibleRootItem( );
    std::queue<QTreeWidgetItem *> parents;
    parents.push( root );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        if ( child->checkState( 0 ) == Qt::Checked ) {
            child->setCheckState( 0, Qt::Unchecked );
            uncheckSubtree( child );
        } else {
            if ( child->child( 0 ) ) {
                parents.push( child->child( 0 ) );
            }
        }
    }
}

void XmlFileOutline::checkSubtree( QTreeWidgetItem *target ) {
    qDebug( ) << "checking subtree...\n";
    if ( target->isDisabled( ) == true ) {
        return;
    }
    std::queue<QTreeWidgetItem *> parents;
    parents.push( target );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        while ( child ) {
            if ( child->child( 0 ) ) {
                parents.push( child );
            }
            if ( child->checkState( 0 ) == Qt::Checked &&
                 child->isDisabled( ) == false ) {
                // deselect item
                qDebug( ) << "deselcting: " << child->text( 0 ) << "\n";
                QVariant childVar = child->data( 0, Qt::UserRole );
                XmlElement childElement = childVar.value<XmlElement>( );
                emit xmlItemDeselected( childElement );
            }
            child->setCheckState( 0, Qt::Checked );
            child->setDisabled( true );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    QVariant targetVar = target->data( 0, Qt::UserRole );
    XmlElement targetElement = targetVar.value<XmlElement>( );
    emit xmlItemSelected( targetElement );
}

auto XmlFileOutline::addSentiment( Sentiment sentiment ) -> void {
    QVariant elementVar = selectedItem_->data( 0, Qt::UserRole );
    XmlElement element = elementVar.value<XmlElement>( );
    // add attribute
    switch ( sentiment ) {
    case Sentiment::Positive:
        element.attribute( "sentiment", "positive" );
        break;
    case Sentiment::Neutral:
        element.attribute( "sentiment", "neutral" );
        break;
    case Sentiment::Negative:
        element.attribute( "sentiment", "negative" );
        break;
    }

    std::cerr << "DEBUG:" << std::endl;
    std::cerr << element.toString( ) << std::endl;
}

void XmlFileOutline::addPositiveSentiment( ) { addSentiment( Sentiment::Positive ); }

void XmlFileOutline::addNegativeSentiment( ) { addSentiment( Sentiment::Negative ); }

void XmlFileOutline::addNeutralSentiment( ) { addSentiment( Sentiment::Neutral ); }

void XmlFileOutline::customContextMenu( const QPoint &pos ) {
    QModelIndex idx = indexAt( pos );
    if ( idx.isValid( ) ) {
        selectedItem_ = itemFromIndex( idx );
        qDebug( ) << "selected item: " << selectedItem_->text( 0 );
        fileOutlineContextMenu_->exec( mapToGlobal( pos ) );
    }
}

void XmlFileOutline::uncheckSubtree( QTreeWidgetItem *target ) {
    qDebug( ) << "unchecking subtree...\n";
    std::queue<QTreeWidgetItem *> parents;
    parents.push( target );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        while ( child ) {
            if ( child->child( 0 ) ) {
                parents.push( child );
            }
            child->setDisabled( false );
            child->setCheckState( 0, Qt::Unchecked );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    QVariant targetVar = target->data( 0, Qt::UserRole );
    XmlElement targetElement = targetVar.value<XmlElement>( );
    emit xmlItemDeselected( targetElement );
}

auto XmlFileOutline::contextMenu( ) -> void {
    // removeEntryAction_ = new QAction{tr( "&Delete" ), this};
    // removeEntryAction_->setShortcut( QKeySequence::Delete );
    // removeEntryAction_->setIcon( QIcon::fromTheme( "remove" ) );
    // connect( removeEntryAction_, SIGNAL( triggered( ) ), SLOT( removeEntry( ) ) );
    semanticAction_ = new QAction{tr( "&Add Sentiment" ), this};
    semanticAction_->setShortcut( QKeySequence{Qt::CTRL + Qt::Key_I} );
    semanticAction_->setIcon( QIcon::fromTheme( "configure" ) );

    positiveSemanticAction_ = new QAction{tr( "Positive" ), this};
    positiveSemanticAction_->setIcon( QIcon::fromTheme( "add" ) );
    negativeSemanticAction_ = new QAction{tr( "Negative" ), this};
    negativeSemanticAction_->setIcon( QIcon::fromTheme( "edit-delete" ) );
    neutralSemanticAction_ = new QAction{tr( "Neutral" ), this};
    neutralSemanticAction_->setIcon( QIcon::fromTheme( "help" ) );
    neutralSemanticAction_->setChecked( true );

    QActionGroup *semanticGroup = new QActionGroup{this};
    semanticGroup->addAction( positiveSemanticAction_ );
    semanticGroup->addAction( negativeSemanticAction_ );
    semanticGroup->addAction( neutralSemanticAction_ );

    fileOutlineContextMenu_ = new QMenu{this};
    fileOutlineContextMenu_->addAction( positiveSemanticAction_ );
    fileOutlineContextMenu_->addAction( neutralSemanticAction_ );
    fileOutlineContextMenu_->addAction( negativeSemanticAction_ );
}

auto XmlFileOutline::connections( ) -> void {
    connect( this, &XmlFileOutline::clicked, this, &XmlFileOutline::itemClicked );
    connect( this, &XmlFileOutline::customContextMenuRequested, this,
             &XmlFileOutline::customContextMenu );
    connect( positiveSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addPositiveSentiment );
    connect( negativeSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addNegativeSentiment );
    connect( neutralSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addNeutralSentiment );
}

static auto buildTreeFromXml( const XmlDoc &xml ) -> QTreeWidgetItem * {
    auto root = xml.getRootElement( );
    QTreeWidgetItem *rootItem = new QTreeWidgetItem;
    rootItem->setText( 0, QString::fromUtf8( root.tags( ).first.c_str( ) ) );
    // Using QMetaType
    rootItem->setData( 0, Qt::UserRole, QVariant::fromValue( root ) );

    std::queue<QTreeWidgetItem *> parentItemQu;
    parentItemQu.push( rootItem );

    std::queue<XmlElement> parentElementQu;
    parentElementQu.push( root );

    while ( !parentElementQu.empty( ) && !parentItemQu.empty( ) ) {
        auto parentElement = parentElementQu.front( );
        parentElementQu.pop( );
        auto parentItem = parentItemQu.front( );
        parentItemQu.pop( );

        auto elementChildren = parentElement.children( );
        for ( auto childElement : elementChildren ) {
            // create childItems
            QTreeWidgetItem *childItem = new QTreeWidgetItem( parentItem );
            childItem->setText(
                0, QString::fromUtf8( childElement.tagsRegex( ).first.c_str( ) ) );
            childItem->setData( 0, Qt::UserRole, QVariant::fromValue( childElement ) );
            childItem->setCheckState( 0, Qt::Unchecked );
            childItem->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
            // breadth first creation (Elements only)
            if ( childElement.hasChild( ) ) {
                parentElementQu.push( childElement );
                parentItemQu.push( childItem );
            }
        }
    }
    return rootItem;
}

static auto findXmlElement( QTreeWidgetItem *item, const XmlElement &element )
    -> QTreeWidgetItem * {
    std::queue<QTreeWidgetItem *> parents;
    parents.push( item );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        QVariant parentData = parent->data( 0, Qt::UserRole );
        const XmlElement parentElement = parentData.value<XmlElement>( );
        if ( parentElement == element ) {
            return parent;
        }
        auto child = parent->child( 0 );
        while ( child ) {
            parents.push( child );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    return nullptr;
}
<commit_msg>removed header<commit_after>#include "xml_file_outline.hpp"
#include "xml_doc.hpp"
#include "xml_element.hpp"
#include <queue>
#include <string>

#include <QAction>
#include <QActionGroup>
#include <QDebug>
#include <QHeaderView>
#include <QMenu>
#include <QPoint>
#include <QTreeWidgetItem>
#include <QWidget>

#include <libxml/tree.h>

static auto buildTreeFromXml( const XmlDoc &xml ) -> QTreeWidgetItem *;
static auto findXmlElement( QTreeWidgetItem *item, const XmlElement &element )
    -> QTreeWidgetItem *;

XmlFileOutline::XmlFileOutline( QWidget *parent ) : QTreeWidget{parent} {
    setContextMenuPolicy( Qt::CustomContextMenu );
    header( )->close( );
    contextMenu( );
    connections( );
}

auto XmlFileOutline::clear( ) -> void { QTreeWidget::clear( ); }

auto XmlFileOutline::xml( const XmlDoc &xml ) -> void {
    addTopLevelItem( buildTreeFromXml( xml ) );
    if ( invisibleRootItem( )->child( 0 ) ) {
        expandItem( invisibleRootItem( )->child( 0 ) );
    }
}

void XmlFileOutline::itemClicked( const QModelIndex &idx ) {
    QTreeWidgetItem *target = itemFromIndex( idx );
    Qt::CheckState checkedState = target->checkState( 0 );
    switch ( checkedState ) {
    case Qt::Checked:
        checkSubtree( target );
        break;
    case Qt::Unchecked:
        uncheckSubtree( target );
        break;
    default:
        return;
    }
}

void XmlFileOutline::xPathResult( const XmlElement &element ) {
    qDebug( ) << "adding xpath result...\n";
    QTreeWidgetItem *root = invisibleRootItem( );
    QTreeWidgetItem *search = findXmlElement( root, element );
    //    if ( search ) {
    //        Qt::CheckState checkedState = search->checkState( 0 );
    //        switch ( checkedState ) {
    //        case Qt::Checked:
    //            break;
    //        case Qt::Unchecked:
    //            checkSubtree( search );
    //            break;
    //        default:
    //            // return;
    //        }
    //        search->setCheckState( 0, Qt::Checked );
    //    }
    if ( search ) {
        search->setCheckState( 0, Qt::Checked );
        itemClicked( indexFromItem( search, 0 ) );
    }
}

void XmlFileOutline::clearSelections( ) {
    qDebug( ) << "clearing all selections...\n";
    QTreeWidgetItem *root = invisibleRootItem( );
    std::queue<QTreeWidgetItem *> parents;
    parents.push( root );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        if ( child->checkState( 0 ) == Qt::Checked ) {
            child->setCheckState( 0, Qt::Unchecked );
            uncheckSubtree( child );
        } else {
            if ( child->child( 0 ) ) {
                parents.push( child->child( 0 ) );
            }
        }
    }
}

void XmlFileOutline::checkSubtree( QTreeWidgetItem *target ) {
    qDebug( ) << "checking subtree...\n";
    if ( target->isDisabled( ) == true ) {
        return;
    }
    std::queue<QTreeWidgetItem *> parents;
    parents.push( target );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        while ( child ) {
            if ( child->child( 0 ) ) {
                parents.push( child );
            }
            if ( child->checkState( 0 ) == Qt::Checked &&
                 child->isDisabled( ) == false ) {
                // deselect item
                qDebug( ) << "deselcting: " << child->text( 0 ) << "\n";
                QVariant childVar = child->data( 0, Qt::UserRole );
                XmlElement childElement = childVar.value<XmlElement>( );
                emit xmlItemDeselected( childElement );
            }
            child->setCheckState( 0, Qt::Checked );
            child->setDisabled( true );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    QVariant targetVar = target->data( 0, Qt::UserRole );
    XmlElement targetElement = targetVar.value<XmlElement>( );
    emit xmlItemSelected( targetElement );
}

auto XmlFileOutline::addSentiment( Sentiment sentiment ) -> void {
    QVariant elementVar = selectedItem_->data( 0, Qt::UserRole );
    XmlElement element = elementVar.value<XmlElement>( );
    // add attribute
    switch ( sentiment ) {
    case Sentiment::Positive:
        element.attribute( "sentiment", "positive" );
        break;
    case Sentiment::Neutral:
        element.attribute( "sentiment", "neutral" );
        break;
    case Sentiment::Negative:
        element.attribute( "sentiment", "negative" );
        break;
    }

    std::cerr << "DEBUG:" << std::endl;
    std::cerr << element.toString( ) << std::endl;
}

void XmlFileOutline::addPositiveSentiment( ) { addSentiment( Sentiment::Positive ); }

void XmlFileOutline::addNegativeSentiment( ) { addSentiment( Sentiment::Negative ); }

void XmlFileOutline::addNeutralSentiment( ) { addSentiment( Sentiment::Neutral ); }

void XmlFileOutline::customContextMenu( const QPoint &pos ) {
    QModelIndex idx = indexAt( pos );
    if ( idx.isValid( ) ) {
        selectedItem_ = itemFromIndex( idx );
        qDebug( ) << "selected item: " << selectedItem_->text( 0 );
        fileOutlineContextMenu_->exec( mapToGlobal( pos ) );
    }
}

void XmlFileOutline::uncheckSubtree( QTreeWidgetItem *target ) {
    qDebug( ) << "unchecking subtree...\n";
    std::queue<QTreeWidgetItem *> parents;
    parents.push( target );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        auto child = parent->child( 0 );
        while ( child ) {
            if ( child->child( 0 ) ) {
                parents.push( child );
            }
            child->setDisabled( false );
            child->setCheckState( 0, Qt::Unchecked );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    QVariant targetVar = target->data( 0, Qt::UserRole );
    XmlElement targetElement = targetVar.value<XmlElement>( );
    emit xmlItemDeselected( targetElement );
}

auto XmlFileOutline::contextMenu( ) -> void {
    // removeEntryAction_ = new QAction{tr( "&Delete" ), this};
    // removeEntryAction_->setShortcut( QKeySequence::Delete );
    // removeEntryAction_->setIcon( QIcon::fromTheme( "remove" ) );
    // connect( removeEntryAction_, SIGNAL( triggered( ) ), SLOT( removeEntry( ) ) );
    semanticAction_ = new QAction{tr( "&Add Sentiment" ), this};
    semanticAction_->setShortcut( QKeySequence{Qt::CTRL + Qt::Key_I} );
    semanticAction_->setIcon( QIcon::fromTheme( "configure" ) );

    positiveSemanticAction_ = new QAction{tr( "Positive" ), this};
    positiveSemanticAction_->setIcon( QIcon::fromTheme( "add" ) );
    negativeSemanticAction_ = new QAction{tr( "Negative" ), this};
    negativeSemanticAction_->setIcon( QIcon::fromTheme( "edit-delete" ) );
    neutralSemanticAction_ = new QAction{tr( "Neutral" ), this};
    neutralSemanticAction_->setIcon( QIcon::fromTheme( "help" ) );
    neutralSemanticAction_->setChecked( true );

    QActionGroup *semanticGroup = new QActionGroup{this};
    semanticGroup->addAction( positiveSemanticAction_ );
    semanticGroup->addAction( negativeSemanticAction_ );
    semanticGroup->addAction( neutralSemanticAction_ );

    fileOutlineContextMenu_ = new QMenu{this};
    fileOutlineContextMenu_->addAction( positiveSemanticAction_ );
    fileOutlineContextMenu_->addAction( neutralSemanticAction_ );
    fileOutlineContextMenu_->addAction( negativeSemanticAction_ );
}

auto XmlFileOutline::connections( ) -> void {
    connect( this, &XmlFileOutline::clicked, this, &XmlFileOutline::itemClicked );
    connect( this, &XmlFileOutline::customContextMenuRequested, this,
             &XmlFileOutline::customContextMenu );
    connect( positiveSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addPositiveSentiment );
    connect( negativeSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addNegativeSentiment );
    connect( neutralSemanticAction_, &QAction::triggered, this,
             &XmlFileOutline::addNeutralSentiment );
}

static auto buildTreeFromXml( const XmlDoc &xml ) -> QTreeWidgetItem * {
    auto root = xml.getRootElement( );
    QTreeWidgetItem *rootItem = new QTreeWidgetItem;
    rootItem->setText( 0, QString::fromUtf8( root.tags( ).first.c_str( ) ) );
    // Using QMetaType
    rootItem->setData( 0, Qt::UserRole, QVariant::fromValue( root ) );

    std::queue<QTreeWidgetItem *> parentItemQu;
    parentItemQu.push( rootItem );

    std::queue<XmlElement> parentElementQu;
    parentElementQu.push( root );

    while ( !parentElementQu.empty( ) && !parentItemQu.empty( ) ) {
        auto parentElement = parentElementQu.front( );
        parentElementQu.pop( );
        auto parentItem = parentItemQu.front( );
        parentItemQu.pop( );

        auto elementChildren = parentElement.children( );
        for ( auto childElement : elementChildren ) {
            // create childItems
            QTreeWidgetItem *childItem = new QTreeWidgetItem( parentItem );
            childItem->setText(
                0, QString::fromUtf8( childElement.tagsRegex( ).first.c_str( ) ) );
            childItem->setData( 0, Qt::UserRole, QVariant::fromValue( childElement ) );
            childItem->setCheckState( 0, Qt::Unchecked );
            childItem->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
            // breadth first creation (Elements only)
            if ( childElement.hasChild( ) ) {
                parentElementQu.push( childElement );
                parentItemQu.push( childItem );
            }
        }
    }
    return rootItem;
}

static auto findXmlElement( QTreeWidgetItem *item, const XmlElement &element )
    -> QTreeWidgetItem * {
    std::queue<QTreeWidgetItem *> parents;
    parents.push( item );
    while ( !parents.empty( ) ) {
        auto parent = parents.front( );
        parents.pop( );
        QVariant parentData = parent->data( 0, Qt::UserRole );
        const XmlElement parentElement = parentData.value<XmlElement>( );
        if ( parentElement == element ) {
            return parent;
        }
        auto child = parent->child( 0 );
        while ( child ) {
            parents.push( child );
            child = parent->child( parent->indexOfChild( child ) + 1 );
        }
    }
    return nullptr;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbGlROIActor.h"
#include "otbViewSettings.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/glew.h>

namespace otb
{

GlROIActor::GlROIActor()
  : m_UL(),
    m_LR(),
    m_Wkt(),
    m_Kwl(),
    m_Color(),
    m_Alpha(1.0),
    m_Fill(false),
    m_ViewportToImageTransform(),
    m_ImageToViewportTransform(),
    m_VpUL(),
    m_VpUR(),
    m_VpLL(),
    m_VpLR()
{
  m_Color.Fill(0);
  m_Color[0]=1.0;
}

GlROIActor::~GlROIActor()
{}

void GlROIActor::SetKwl(const ImageKeywordlistType & kwl)
{
  m_Kwl = kwl;
}

void GlROIActor::GetExtent(double & ulx, double & uly, double & lrx, double & lry) const
{
  //TODO: Fixme (should handle rotation as well)
  lrx = std::max(std::max(m_VpUL[0],m_VpUR[0]),std::max(m_VpLL[0],m_VpLR[0]));
  lry = std::max(std::max(m_VpUL[1],m_VpUR[1]),std::max(m_VpLL[1],m_VpLR[1]));
  ulx = std::min(std::min(m_VpUL[0],m_VpUR[0]),std::min(m_VpLL[0],m_VpLR[0]));
  uly = std::min(std::min(m_VpUL[1],m_VpUR[1]),std::min(m_VpLL[1],m_VpLR[1]));

}

void GlROIActor::ProcessViewSettings()
{
  // Is there anything to do ?
  ViewSettings::ConstPointer settings = this->GetSettings();

  if((m_ViewportToImageTransform.IsNull() || m_ImageToViewportTransform.IsNull()) || (settings->GetUseProjection() || settings->GetGeometryChanged()))
    {
    UpdateTransforms();

    PointType ur,ll;

    ur = m_UL;
    ur[0] = m_LR[0];

    ll = m_LR;
    ll[0] = m_UL[0];

    m_VpUL = m_ImageToViewportTransform->TransformPoint(m_UL);
    m_VpUR = m_ImageToViewportTransform->TransformPoint(ur);
    m_VpLL = m_ImageToViewportTransform->TransformPoint(ll);
    m_VpLR = m_ImageToViewportTransform->TransformPoint(m_LR);
    }
}

void GlROIActor::UpdateData()
{
  // Nothing to do here
}

void GlROIActor::Render()
{
  glColor3d(m_Color[0],m_Color[1],m_Color[2]);

  glBegin(GL_LINE_LOOP);
  glVertex2d(m_VpUL[0],m_VpUL[1]);
  glVertex2d(m_VpUR[0],m_VpUR[1]);
  glVertex2d(m_VpLR[0],m_VpLR[1]);
  glVertex2d(m_VpLL[0],m_VpLL[1]);
  glEnd();

  if(m_Fill)
    {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glColor4d(m_Color[0],m_Color[1],m_Color[2],m_Alpha);
    glBegin(GL_QUADS);
    glVertex2d(m_VpUL[0],m_VpUL[1]);
    glVertex2d(m_VpUR[0],m_VpUR[1]);
    glVertex2d(m_VpLR[0],m_VpLR[1]);
    glVertex2d(m_VpLL[0],m_VpLL[1]);
    glEnd();
    glDisable(GL_BLEND);
    }
}

void GlROIActor::UpdateTransforms()
{
  // Retrieve settings
  ViewSettings::ConstPointer settings = this->GetSettings();

  m_ViewportToImageTransform = RSTransformType::New();
  m_ImageToViewportTransform = RSTransformType::New();

  if(settings->GetUseProjection())
    {
    m_ViewportToImageTransform->SetInputProjectionRef(settings->GetWkt());
    m_ViewportToImageTransform->SetInputKeywordList(settings->GetKeywordList());
    m_ViewportToImageTransform->SetOutputProjectionRef(m_Wkt);
    m_ViewportToImageTransform->SetOutputKeywordList(m_Kwl);

    m_ImageToViewportTransform->SetOutputProjectionRef(settings->GetWkt());
    m_ImageToViewportTransform->SetOutputKeywordList(settings->GetKeywordList());
    m_ImageToViewportTransform->SetInputProjectionRef(m_Wkt);
    m_ImageToViewportTransform->SetInputKeywordList(m_Kwl);
    }
  m_ViewportToImageTransform->InstanciateTransform();
  m_ImageToViewportTransform->InstanciateTransform();
}

}
<commit_msg>ENH: Fixed initialization of otb::GlROIActor attributes.<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbGlROIActor.h"
#include "otbViewSettings.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/glew.h>

namespace otb
{

GlROIActor::GlROIActor()
  : m_UL(),
    m_LR(),
    m_Wkt(),
    m_Kwl(),
    m_Color(),
    m_Alpha(1.0),
    m_Fill(false),
    m_ViewportToImageTransform(),
    m_ImageToViewportTransform(),
    m_VpUL(),
    m_VpUR(),
    m_VpLL(),
    m_VpLR()
{
  m_UL.Fill( 0 );
  m_LR.Fill( 0 );

  m_Color.Fill(0);
  m_Color[0]=1.0;

  m_VpUL.Fill( 0 );
  m_VpUR.Fill( 0 );
  m_VpLL.Fill( 0 );
  m_VpLR.Fill( 0 );
}

GlROIActor::~GlROIActor()
{}

void GlROIActor::SetKwl(const ImageKeywordlistType & kwl)
{
  m_Kwl = kwl;
}

void GlROIActor::GetExtent(double & ulx, double & uly, double & lrx, double & lry) const
{
  //TODO: Fixme (should handle rotation as well)
  lrx = std::max(std::max(m_VpUL[0],m_VpUR[0]),std::max(m_VpLL[0],m_VpLR[0]));
  lry = std::max(std::max(m_VpUL[1],m_VpUR[1]),std::max(m_VpLL[1],m_VpLR[1]));
  ulx = std::min(std::min(m_VpUL[0],m_VpUR[0]),std::min(m_VpLL[0],m_VpLR[0]));
  uly = std::min(std::min(m_VpUL[1],m_VpUR[1]),std::min(m_VpLL[1],m_VpLR[1]));

}

void GlROIActor::ProcessViewSettings()
{
  // Is there anything to do ?
  ViewSettings::ConstPointer settings = this->GetSettings();

  if((m_ViewportToImageTransform.IsNull() || m_ImageToViewportTransform.IsNull()) || (settings->GetUseProjection() || settings->GetGeometryChanged()))
    {
    UpdateTransforms();

    PointType ur,ll;

    ur = m_UL;
    ur[0] = m_LR[0];

    ll = m_LR;
    ll[0] = m_UL[0];

    m_VpUL = m_ImageToViewportTransform->TransformPoint(m_UL);
    m_VpUR = m_ImageToViewportTransform->TransformPoint(ur);
    m_VpLL = m_ImageToViewportTransform->TransformPoint(ll);
    m_VpLR = m_ImageToViewportTransform->TransformPoint(m_LR);
    }
}

void GlROIActor::UpdateData()
{
  // Nothing to do here
}

void GlROIActor::Render()
{
  glColor3d(m_Color[0],m_Color[1],m_Color[2]);

  glBegin(GL_LINE_LOOP);
  glVertex2d(m_VpUL[0],m_VpUL[1]);
  glVertex2d(m_VpUR[0],m_VpUR[1]);
  glVertex2d(m_VpLR[0],m_VpLR[1]);
  glVertex2d(m_VpLL[0],m_VpLL[1]);
  glEnd();

  if(m_Fill)
    {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glColor4d(m_Color[0],m_Color[1],m_Color[2],m_Alpha);
    glBegin(GL_QUADS);
    glVertex2d(m_VpUL[0],m_VpUL[1]);
    glVertex2d(m_VpUR[0],m_VpUR[1]);
    glVertex2d(m_VpLR[0],m_VpLR[1]);
    glVertex2d(m_VpLL[0],m_VpLL[1]);
    glEnd();
    glDisable(GL_BLEND);
    }
}

void GlROIActor::UpdateTransforms()
{
  // Retrieve settings
  ViewSettings::ConstPointer settings = this->GetSettings();

  m_ViewportToImageTransform = RSTransformType::New();
  m_ImageToViewportTransform = RSTransformType::New();

  if(settings->GetUseProjection())
    {
    m_ViewportToImageTransform->SetInputProjectionRef(settings->GetWkt());
    m_ViewportToImageTransform->SetInputKeywordList(settings->GetKeywordList());
    m_ViewportToImageTransform->SetOutputProjectionRef(m_Wkt);
    m_ViewportToImageTransform->SetOutputKeywordList(m_Kwl);

    m_ImageToViewportTransform->SetOutputProjectionRef(settings->GetWkt());
    m_ImageToViewportTransform->SetOutputKeywordList(settings->GetKeywordList());
    m_ImageToViewportTransform->SetInputProjectionRef(m_Wkt);
    m_ImageToViewportTransform->SetInputKeywordList(m_Kwl);
    }
  m_ViewportToImageTransform->InstanciateTransform();
  m_ImageToViewportTransform->InstanciateTransform();
}

}
<|endoftext|>