<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "common.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "Analyzer.h"

using namespace fnord;
using namespace cm;

typedef Tuple<String, uint64_t, uint64_t> OutputRow;
typedef HashMap<String, cm::CTRCounter> CounterMap;

InternMap intern_map;

void indexJoinedQuery(
    const cm::JoinedQuery& query,
    const String& query_feature_name,
    mdb::MDB* featuredb,
    FeatureIndex* feature_index,
    FeatureID item_feature_id,
    ItemEligibility item_eligibility,
    Analyzer* analyzer,
    Language lang,
    CounterMap* counters) {
  auto fstr_opt = cm::extractAttr(query.attrs, query_feature_name);
  if (fstr_opt.isEmpty()) {
    return;
  }

  auto fstr = URI::urlDecode(fstr_opt.get());
  auto& global_counter = (*counters)[""];

  for (const auto& item : query.items) {
    if (!isItemEligible(item_eligibility, query, item)) {
      continue;
    }

    Option<String> ifstr_opt;

    try {
      auto txn = featuredb->startTransaction(true);

      ifstr_opt = feature_index->getFeature(
          item.item.docID(),
          item_feature_id,
          txn.get());

      txn->abort();
    } catch (const Exception& e) {
      fnord::logError("cm.ctrstatsbuild", e, "error");
    }

   if (ifstr_opt.isEmpty()) {
      continue;
    }

    Set<String> tokens;
    analyzer->extractTerms(lang, ifstr_opt.get(), &tokens);

    for (const auto& token : tokens) {
      Buffer counter_key;
      Buffer group_counter_key;
      void* tmp = intern_map.internString(fstr);
      counter_key.append(&tmp, sizeof(tmp));
      group_counter_key.append(&tmp, sizeof(tmp));
      tmp = intern_map.internString(token);
      counter_key.append(&tmp, sizeof(tmp));

      auto& counter = (*counters)[counter_key.toString()];
      auto& group_counter = (*counters)[group_counter_key.toString()];

      counter.num_views++;
      group_counter.num_views++;
      global_counter.num_views++;

      if (item.clicked) {
        counter.num_clicks++;
        group_counter.num_clicks++;
        global_counter.num_clicks++;
      }
    }
  }
}

/* write output table */
void writeOutputTable(
    const String& filename,
    const CounterMap& counters,
    uint64_t start_time,
    uint64_t end_time) {
  /* prepare output sstable schema */
  sstable::SSTableColumnSchema sstable_schema;
  sstable_schema.addColumn("num_views", 1, sstable::SSTableColumnType::UINT64);
  sstable_schema.addColumn("num_clicks", 2, sstable::SSTableColumnType::UINT64);
  sstable_schema.addColumn("num_clicked", 3, sstable::SSTableColumnType::UINT64);

  HashMap<String, String> out_hdr;
  out_hdr["start_time"] = StringUtil::toString(start_time);
  out_hdr["end_time"] = StringUtil::toString(end_time);
  auto outhdr_json = json::toJSONString(out_hdr);

  /* open output sstable */
  fnord::logInfo("cm.ctrstats", "Writing results to: $0", filename);
  auto sstable_writer = sstable::SSTableWriter::create(
      filename,
      sstable::IndexProvider{},
      outhdr_json.data(),
      outhdr_json.length());

  for (const auto& p : counters) {
    sstable::SSTableColumnWriter cols(&sstable_schema);
    cols.addUInt64Column(1, p.second.num_views);
    cols.addUInt64Column(2, p.second.num_clicks);
    cols.addUInt64Column(3, p.second.num_clicked);

    String key_str;
    switch (p.first.length()) {

      case 0: {
        key_str = "__GLOBAL";
        break;
      }

      case (sizeof(void*)): {
        key_str = intern_map.getString(((void**) p.first.c_str())[0]);
        break;
      }

      case (sizeof(void*) * 2): {
        key_str = intern_map.getString(((void**) p.first.c_str())[0]);
        key_str += "~";
        key_str += intern_map.getString(((void**) p.first.c_str())[1]);
        break;
      }

      default:
        RAISE(kRuntimeError, "invalid counter key");

    }

    sstable_writer->appendRow(key_str, cols);
  }

  sstable_schema.writeIndex(sstable_writer.get());
  sstable_writer->finalize();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "lang",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "language",
      "<lang>");

  flags.defineFlag(
      "conf",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      "./conf",
      "conf directory",
      "<path>");

  flags.defineFlag(
      "output_file",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "output file path",
      "<path>");

  flags.defineFlag(
      "query_feature",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "query feature",
      "<feature>");

  flags.defineFlag(
      "item_feature",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "item feature",
      "<feature>");

  flags.defineFlag(
      "featuredb_path",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "feature db path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  CounterMap counters;
  auto query_feature = flags.getString("query_feature");
  auto start_time = std::numeric_limits<uint64_t>::max();
  auto end_time = std::numeric_limits<uint64_t>::min();

  auto lang = languageFromString(flags.getString("lang"));
  cm::Analyzer analyzer(flags.getString("conf"));

  /* set up feature schema */
  cm::FeatureSchema feature_schema;
  feature_schema.registerFeature("shop_id", 1, 1);
  feature_schema.registerFeature("category1", 2, 1);
  feature_schema.registerFeature("category2", 3, 1);
  feature_schema.registerFeature("category3", 4, 1);
  feature_schema.registerFeature("title~de", 5, 2);

  /* open featuredb db */
  auto featuredb_path = flags.getString("featuredb_path");
  auto featuredb = mdb::MDB::open(featuredb_path, true);
  cm::FeatureIndex feature_index(&feature_schema);

  /* read input tables */
  auto sstables = flags.getArgv();
  for (int tbl_idx = 0; tbl_idx < sstables.size(); ++tbl_idx) {
    const auto& sstable = sstables[tbl_idx];
    fnord::logInfo("cm.ctrstats", "Importing sstable: $0", sstable);

    /* read sstable header */
    sstable::SSTableReader reader(File::openFile(sstable, File::O_READ));

    if (reader.bodySize() == 0) {
      fnord::logCritical("cm.ctrstats", "unfinished sstable: $0", sstable);
      exit(1);
    }

    /* read report header */
    auto hdr = json::parseJSON(reader.readHeader());

    auto tbl_start_time = json::JSONUtil::objectGetUInt64(
        hdr.begin(),
        hdr.end(),
        "start_time").get();

    auto tbl_end_time = json::JSONUtil::objectGetUInt64(
        hdr.begin(),
        hdr.end(),
        "end_time").get();

    if (tbl_start_time < start_time) {
      start_time = tbl_start_time;
    }

    if (tbl_end_time > end_time) {
      end_time = tbl_end_time;
    }

    /* get sstable cursor */
    auto cursor = reader.getCursor();
    auto body_size = reader.bodySize();
    int row_idx = 0;

    /* status line */
    util::SimpleRateLimitedFn status_line(kMicrosPerSecond, [&] () {
      fnord::logInfo(
          "cm.ctrstats",
          "[$1/$2] [$0%] Reading sstable... rows=$3",
          (size_t) ((cursor->position() / (double) body_size) * 100),
          tbl_idx + 1, sstables.size(), row_idx);
    });

    /* read sstable rows */
    for (; cursor->valid(); ++row_idx) {
      status_line.runMaybe();

      auto val = cursor->getDataBuffer();

      try {
        indexJoinedQuery(
            json::fromJSON<cm::JoinedQuery>(val),
            query_feature,
            featuredb.get(),
            &feature_index,
            feature_schema.featureID(flags.getString("item_feature")).get(),
            cm::ItemEligibility::DAWANDA_FIRST_EIGHT,
            &analyzer,
            lang,
            &counters);
      } catch (const Exception& e) {
        fnord::logWarning(
            "cm.ctrstats",
            e,
            "error while indexing query: $0",
            val.toString());
      }

      if (!cursor->next()) {
        break;
      }
    }

    status_line.runForce();
  }

  /* write output table */
  writeOutputTable(
      flags.getString("output_file"),
      counters,
      start_time,
      end_time);

  return 0;
}

<commit_msg>include fix<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "common.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include "Analyzer.h"

using namespace fnord;
using namespace cm;

typedef Tuple<String, uint64_t, uint64_t> OutputRow;
typedef HashMap<String, cm::CTRCounter> CounterMap;

InternMap intern_map;

void indexJoinedQuery(
    const cm::JoinedQuery& query,
    const String& query_feature_name,
    mdb::MDB* featuredb,
    FeatureIndex* feature_index,
    FeatureID item_feature_id,
    ItemEligibility item_eligibility,
    Analyzer* analyzer,
    Language lang,
    CounterMap* counters) {
  auto fstr_opt = cm::extractAttr(query.attrs, query_feature_name);
  if (fstr_opt.isEmpty()) {
    return;
  }

  auto fstr = URI::urlDecode(fstr_opt.get());
  auto& global_counter = (*counters)[""];

  for (const auto& item : query.items) {
    if (!isItemEligible(item_eligibility, query, item)) {
      continue;
    }

    Option<String> ifstr_opt;

    try {
      auto txn = featuredb->startTransaction(true);

      ifstr_opt = feature_index->getFeature(
          item.item.docID(),
          item_feature_id,
          txn.get());

      txn->abort();
    } catch (const Exception& e) {
      fnord::logError("cm.ctrstatsbuild", e, "error");
    }

   if (ifstr_opt.isEmpty()) {
      continue;
    }

    Set<String> tokens;
    analyzer->extractTerms(lang, ifstr_opt.get(), &tokens);

    for (const auto& token : tokens) {
      Buffer counter_key;
      Buffer group_counter_key;
      void* tmp = intern_map.internString(fstr);
      counter_key.append(&tmp, sizeof(tmp));
      group_counter_key.append(&tmp, sizeof(tmp));
      tmp = intern_map.internString(token);
      counter_key.append(&tmp, sizeof(tmp));

      auto& counter = (*counters)[counter_key.toString()];
      auto& group_counter = (*counters)[group_counter_key.toString()];

      counter.num_views++;
      group_counter.num_views++;
      global_counter.num_views++;

      if (item.clicked) {
        counter.num_clicks++;
        group_counter.num_clicks++;
        global_counter.num_clicks++;
      }
    }
  }
}

/* write output table */
void writeOutputTable(
    const String& filename,
    const CounterMap& counters,
    uint64_t start_time,
    uint64_t end_time) {
  /* prepare output sstable schema */
  sstable::SSTableColumnSchema sstable_schema;
  sstable_schema.addColumn("num_views", 1, sstable::SSTableColumnType::UINT64);
  sstable_schema.addColumn("num_clicks", 2, sstable::SSTableColumnType::UINT64);
  sstable_schema.addColumn("num_clicked", 3, sstable::SSTableColumnType::UINT64);

  HashMap<String, String> out_hdr;
  out_hdr["start_time"] = StringUtil::toString(start_time);
  out_hdr["end_time"] = StringUtil::toString(end_time);
  auto outhdr_json = json::toJSONString(out_hdr);

  /* open output sstable */
  fnord::logInfo("cm.ctrstats", "Writing results to: $0", filename);
  auto sstable_writer = sstable::SSTableWriter::create(
      filename,
      sstable::IndexProvider{},
      outhdr_json.data(),
      outhdr_json.length());

  for (const auto& p : counters) {
    sstable::SSTableColumnWriter cols(&sstable_schema);
    cols.addUInt64Column(1, p.second.num_views);
    cols.addUInt64Column(2, p.second.num_clicks);
    cols.addUInt64Column(3, p.second.num_clicked);

    String key_str;
    switch (p.first.length()) {

      case 0: {
        key_str = "__GLOBAL";
        break;
      }

      case (sizeof(void*)): {
        key_str = intern_map.getString(((void**) p.first.c_str())[0]);
        break;
      }

      case (sizeof(void*) * 2): {
        key_str = intern_map.getString(((void**) p.first.c_str())[0]);
        key_str += "~";
        key_str += intern_map.getString(((void**) p.first.c_str())[1]);
        break;
      }

      default:
        RAISE(kRuntimeError, "invalid counter key");

    }

    sstable_writer->appendRow(key_str, cols);
  }

  sstable_schema.writeIndex(sstable_writer.get());
  sstable_writer->finalize();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "lang",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "language",
      "<lang>");

  flags.defineFlag(
      "conf",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      "./conf",
      "conf directory",
      "<path>");

  flags.defineFlag(
      "output_file",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "output file path",
      "<path>");

  flags.defineFlag(
      "query_feature",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "query feature",
      "<feature>");

  flags.defineFlag(
      "item_feature",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "item feature",
      "<feature>");

  flags.defineFlag(
      "featuredb_path",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "feature db path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  CounterMap counters;
  auto query_feature = flags.getString("query_feature");
  auto start_time = std::numeric_limits<uint64_t>::max();
  auto end_time = std::numeric_limits<uint64_t>::min();

  auto lang = languageFromString(flags.getString("lang"));
  cm::Analyzer analyzer(flags.getString("conf"));

  /* set up feature schema */
  cm::FeatureSchema feature_schema;
  feature_schema.registerFeature("shop_id", 1, 1);
  feature_schema.registerFeature("category1", 2, 1);
  feature_schema.registerFeature("category2", 3, 1);
  feature_schema.registerFeature("category3", 4, 1);
  feature_schema.registerFeature("title~de", 5, 2);

  /* open featuredb db */
  auto featuredb_path = flags.getString("featuredb_path");
  auto featuredb = mdb::MDB::open(featuredb_path, true);
  cm::FeatureIndex feature_index(&feature_schema);

  /* read input tables */
  auto sstables = flags.getArgv();
  for (int tbl_idx = 0; tbl_idx < sstables.size(); ++tbl_idx) {
    const auto& sstable = sstables[tbl_idx];
    fnord::logInfo("cm.ctrstats", "Importing sstable: $0", sstable);

    /* read sstable header */
    sstable::SSTableReader reader(File::openFile(sstable, File::O_READ));

    if (reader.bodySize() == 0) {
      fnord::logCritical("cm.ctrstats", "unfinished sstable: $0", sstable);
      exit(1);
    }

    /* read report header */
    auto hdr = json::parseJSON(reader.readHeader());

    auto tbl_start_time = json::JSONUtil::objectGetUInt64(
        hdr.begin(),
        hdr.end(),
        "start_time").get();

    auto tbl_end_time = json::JSONUtil::objectGetUInt64(
        hdr.begin(),
        hdr.end(),
        "end_time").get();

    if (tbl_start_time < start_time) {
      start_time = tbl_start_time;
    }

    if (tbl_end_time > end_time) {
      end_time = tbl_end_time;
    }

    /* get sstable cursor */
    auto cursor = reader.getCursor();
    auto body_size = reader.bodySize();
    int row_idx = 0;

    /* status line */
    util::SimpleRateLimitedFn status_line(kMicrosPerSecond, [&] () {
      fnord::logInfo(
          "cm.ctrstats",
          "[$1/$2] [$0%] Reading sstable... rows=$3",
          (size_t) ((cursor->position() / (double) body_size) * 100),
          tbl_idx + 1, sstables.size(), row_idx);
    });

    /* read sstable rows */
    for (; cursor->valid(); ++row_idx) {
      status_line.runMaybe();

      auto val = cursor->getDataBuffer();

      try {
        indexJoinedQuery(
            json::fromJSON<cm::JoinedQuery>(val),
            query_feature,
            featuredb.get(),
            &feature_index,
            feature_schema.featureID(flags.getString("item_feature")).get(),
            cm::ItemEligibility::DAWANDA_FIRST_EIGHT,
            &analyzer,
            lang,
            &counters);
      } catch (const Exception& e) {
        fnord::logWarning(
            "cm.ctrstats",
            e,
            "error while indexing query: $0",
            val.toString());
      }

      if (!cursor->next()) {
        break;
      }
    }

    status_line.runForce();
  }

  /* write output table */
  writeOutputTable(
      flags.getString("output_file"),
      counters,
      start_time,
      end_time);

  return 0;
}

<|endoftext|>


<commit_before>/** \file logstream.hxx
 * Stream based logging mechanism.
 */

// Written by Bernie Bright, 1998
//
// Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifndef _LOGSTREAM_H
#define _LOGSTREAM_H

#include <simgear/compiler.h>

#ifdef _MSC_VER
#  include <windows.h>
#endif

#include <streambuf>
#include <ostream>

#include <simgear/debug/debug_types.h>

using std::streambuf;
using std::ostream;

//
// TODO:
//
// 1. Change output destination. Done.
// 2. Make logbuf thread safe.
// 3. Read environment for default debugClass and debugPriority.
//

/**
 * logbuf is an output-only streambuf with the ability to disable sets of
 * messages at runtime. Only messages with priority >= logbuf::logPriority
 * and debugClass == logbuf::logClass are output.
 */
#ifdef SG_NEED_STREAMBUF_HACK
class logbuf : public __streambuf
#else
class logbuf : public std::streambuf
#endif
{
public:
    // logbuf( streambuf* sb ) : sbuf(sb) {}
    /** Constructor */
    logbuf();

    /** Destructor */
    ~logbuf();

    /**
     * Is logging enabled?
     * @return true or false*/
    bool enabled() { return logging_enabled; }

    /**
     * Set the logging level of subsequent messages.
     * @param c debug class
     * @param p priority
     */
    void set_log_state( sgDebugClass c, sgDebugPriority p );

    bool would_log( sgDebugClass c, sgDebugPriority p ) const;

    /**
     * Set the global logging level.
     * @param c debug class
     * @param p priority
     */
    static void set_log_level( sgDebugClass c, sgDebugPriority p );

    /**
     * Set the allowed logging classes.
     * @param c All enabled logging classes anded together.
     */
    static void set_log_classes (sgDebugClass c);

    /**
     * Get the logging classes currently enabled.
     * @return All enabled debug logging anded together.
     */
    static sgDebugClass get_log_classes ();

    /**
     * Set the logging priority.
     * @param c The priority cutoff for logging messages.
     */
    static void set_log_priority (sgDebugPriority p);

    /**
     * Get the current logging priority.
     * @return The priority cutoff for logging messages.
     */
    static sgDebugPriority get_log_priority ();

    /**
     * Set the stream buffer
     * @param sb stream buffer
     */
    void set_sb( std::streambuf* sb );

#ifdef _MSC_VER
    static void has_no_console() { has_console = false; }
#endif

protected:

    /** sync/flush */
    inline virtual int sync();

    /** overflow */
    int_type overflow( int ch );
    // int xsputn( const char* s, istreamsize n );

private:

    // The streambuf used for actual output. Defaults to cerr.rdbuf().
    static std::streambuf* sbuf;

    static bool logging_enabled;
#ifdef _MSC_VER
    static bool has_console;
#endif
    static sgDebugClass logClass;
    static sgDebugPriority logPriority;

private:

    // Not defined.
    logbuf( const logbuf& );
    void operator= ( const logbuf& );
};

inline int
logbuf::sync()
{
	return sbuf->pubsync();
}

inline void
logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
{
    logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}

inline bool
logbuf::would_log( sgDebugClass c, sgDebugPriority p ) const
{
    return ((c & logClass) != 0 && p >= logPriority);
}

inline logbuf::int_type
logbuf::overflow( int c )
{
#ifdef _MSC_VER
    if ( logging_enabled ) {
        if ( !has_console ) {
            AllocConsole();
            freopen("conin$", "r", stdin);
            freopen("conout$", "w", stdout);
            freopen("conout$", "w", stderr);
            has_console = true;
        }
        return sbuf->sputc(c);
    }
    else
        return EOF == 0 ? 1: 0;
#else
    return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
#endif
}

/**
 * logstream manipulator for setting the log level of a message.
 */
struct loglevel
{
    loglevel( sgDebugClass c, sgDebugPriority p )
	: logClass(c), logPriority(p) {}

    sgDebugClass logClass;
    sgDebugPriority logPriority;
};

/**
 * A helper class that ensures a streambuf and ostream are constructed and
 * destroyed in the correct order.  The streambuf must be created before the
 * ostream but bases are constructed before members.  Thus, making this class
 * a private base of logstream, declared to the left of ostream, we ensure the
 * correct order of construction and destruction.
 */
struct logstream_base
{
    // logstream_base( streambuf* sb ) : lbuf(sb) {}
    logstream_base() {}

    logbuf lbuf;
};

/**
 * Class to manage the debug logging stream.
 */
class logstream : private logstream_base, public std::ostream
{
public:
    /**
     * The default is to send messages to cerr.
     * @param out output stream
     */
    logstream( std::ostream& out )
	// : logstream_base(out.rdbuf()),
	: logstream_base(),
	  std::ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}

    /**
     * Set the output stream
     * @param out output stream
     */
    void set_output( std::ostream& out ) { lbuf.set_sb( out.rdbuf() ); }

    /**
     * Set the global log class and priority level.
     * @param c debug class
     * @param p priority
     */
    void setLogLevels( sgDebugClass c, sgDebugPriority p );

    bool would_log(  sgDebugClass c, sgDebugPriority p ) const
    {
        return lbuf.would_log( c, p );
    };

    /**
     * Output operator to capture the debug level and priority of a message.
     * @param l log level
     */
    inline std::ostream& operator<< ( const loglevel& l );
    friend logstream& sglog();
    static logstream *initGlobalLogstream();
protected:
    static logstream *global_logstream;
};

inline std::ostream&
logstream::operator<< ( const loglevel& l )
{
    lbuf.set_log_state( l.logClass, l.logPriority );
    return *this;
}

/**
 * \relates logstream
 * Return the one and only logstream instance.
 * We use a function instead of a global object so we are assured that cerr
 * has been initialised.
 * @return current logstream
 */
inline logstream&
sglog()
{
    return *logstream::initGlobalLogstream();
}

/** \def SG_LOG(C,P,M)
 * Log a message.
 * @param C debug class
 * @param P priority
 * @param M message
 */
#ifdef FG_NDEBUG
# define SG_LOG(C,P,M)
#else
# define SG_LOG(C,P,M) do {                     \
	logstream& __tmplogstreamref(sglog());                      \
	if(__tmplogstreamref.would_log(C,P)) {                      \
        __tmplogstreamref << loglevel(C,P) << M << std::endl; } \
	} while(0)
#endif

#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)

#endif // _LOGSTREAM_H

<commit_msg>Make it compile with gcc-4.4.<commit_after>/** \file logstream.hxx
 * Stream based logging mechanism.
 */

// Written by Bernie Bright, 1998
//
// Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifndef _LOGSTREAM_H
#define _LOGSTREAM_H

#include <simgear/compiler.h>

#ifdef _MSC_VER
#  include <windows.h>
#endif

#include <streambuf>
#include <ostream>
#include <cstdio>

#include <simgear/debug/debug_types.h>

using std::streambuf;
using std::ostream;

//
// TODO:
//
// 1. Change output destination. Done.
// 2. Make logbuf thread safe.
// 3. Read environment for default debugClass and debugPriority.
//

/**
 * logbuf is an output-only streambuf with the ability to disable sets of
 * messages at runtime. Only messages with priority >= logbuf::logPriority
 * and debugClass == logbuf::logClass are output.
 */
#ifdef SG_NEED_STREAMBUF_HACK
class logbuf : public __streambuf
#else
class logbuf : public std::streambuf
#endif
{
public:
    // logbuf( streambuf* sb ) : sbuf(sb) {}
    /** Constructor */
    logbuf();

    /** Destructor */
    ~logbuf();

    /**
     * Is logging enabled?
     * @return true or false*/
    bool enabled() { return logging_enabled; }

    /**
     * Set the logging level of subsequent messages.
     * @param c debug class
     * @param p priority
     */
    void set_log_state( sgDebugClass c, sgDebugPriority p );

    bool would_log( sgDebugClass c, sgDebugPriority p ) const;

    /**
     * Set the global logging level.
     * @param c debug class
     * @param p priority
     */
    static void set_log_level( sgDebugClass c, sgDebugPriority p );

    /**
     * Set the allowed logging classes.
     * @param c All enabled logging classes anded together.
     */
    static void set_log_classes (sgDebugClass c);

    /**
     * Get the logging classes currently enabled.
     * @return All enabled debug logging anded together.
     */
    static sgDebugClass get_log_classes ();

    /**
     * Set the logging priority.
     * @param c The priority cutoff for logging messages.
     */
    static void set_log_priority (sgDebugPriority p);

    /**
     * Get the current logging priority.
     * @return The priority cutoff for logging messages.
     */
    static sgDebugPriority get_log_priority ();

    /**
     * Set the stream buffer
     * @param sb stream buffer
     */
    void set_sb( std::streambuf* sb );

#ifdef _MSC_VER
    static void has_no_console() { has_console = false; }
#endif

protected:

    /** sync/flush */
    inline virtual int sync();

    /** overflow */
    int_type overflow( int ch );
    // int xsputn( const char* s, istreamsize n );

private:

    // The streambuf used for actual output. Defaults to cerr.rdbuf().
    static std::streambuf* sbuf;

    static bool logging_enabled;
#ifdef _MSC_VER
    static bool has_console;
#endif
    static sgDebugClass logClass;
    static sgDebugPriority logPriority;

private:

    // Not defined.
    logbuf( const logbuf& );
    void operator= ( const logbuf& );
};

inline int
logbuf::sync()
{
	return sbuf->pubsync();
}

inline void
logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
{
    logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}

inline bool
logbuf::would_log( sgDebugClass c, sgDebugPriority p ) const
{
    return ((c & logClass) != 0 && p >= logPriority);
}

inline logbuf::int_type
logbuf::overflow( int c )
{
#ifdef _MSC_VER
    if ( logging_enabled ) {
        if ( !has_console ) {
            AllocConsole();
            freopen("conin$", "r", stdin);
            freopen("conout$", "w", stdout);
            freopen("conout$", "w", stderr);
            has_console = true;
        }
        return sbuf->sputc(c);
    }
    else
        return EOF == 0 ? 1: 0;
#else
    return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
#endif
}

/**
 * logstream manipulator for setting the log level of a message.
 */
struct loglevel
{
    loglevel( sgDebugClass c, sgDebugPriority p )
	: logClass(c), logPriority(p) {}

    sgDebugClass logClass;
    sgDebugPriority logPriority;
};

/**
 * A helper class that ensures a streambuf and ostream are constructed and
 * destroyed in the correct order.  The streambuf must be created before the
 * ostream but bases are constructed before members.  Thus, making this class
 * a private base of logstream, declared to the left of ostream, we ensure the
 * correct order of construction and destruction.
 */
struct logstream_base
{
    // logstream_base( streambuf* sb ) : lbuf(sb) {}
    logstream_base() {}

    logbuf lbuf;
};

/**
 * Class to manage the debug logging stream.
 */
class logstream : private logstream_base, public std::ostream
{
public:
    /**
     * The default is to send messages to cerr.
     * @param out output stream
     */
    logstream( std::ostream& out )
	// : logstream_base(out.rdbuf()),
	: logstream_base(),
	  std::ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}

    /**
     * Set the output stream
     * @param out output stream
     */
    void set_output( std::ostream& out ) { lbuf.set_sb( out.rdbuf() ); }

    /**
     * Set the global log class and priority level.
     * @param c debug class
     * @param p priority
     */
    void setLogLevels( sgDebugClass c, sgDebugPriority p );

    bool would_log(  sgDebugClass c, sgDebugPriority p ) const
    {
        return lbuf.would_log( c, p );
    };

    /**
     * Output operator to capture the debug level and priority of a message.
     * @param l log level
     */
    inline std::ostream& operator<< ( const loglevel& l );
    friend logstream& sglog();
    static logstream *initGlobalLogstream();
protected:
    static logstream *global_logstream;
};

inline std::ostream&
logstream::operator<< ( const loglevel& l )
{
    lbuf.set_log_state( l.logClass, l.logPriority );
    return *this;
}

/**
 * \relates logstream
 * Return the one and only logstream instance.
 * We use a function instead of a global object so we are assured that cerr
 * has been initialised.
 * @return current logstream
 */
inline logstream&
sglog()
{
    return *logstream::initGlobalLogstream();
}

/** \def SG_LOG(C,P,M)
 * Log a message.
 * @param C debug class
 * @param P priority
 * @param M message
 */
#ifdef FG_NDEBUG
# define SG_LOG(C,P,M)
#else
# define SG_LOG(C,P,M) do {                     \
	logstream& __tmplogstreamref(sglog());                      \
	if(__tmplogstreamref.would_log(C,P)) {                      \
        __tmplogstreamref << loglevel(C,P) << M << std::endl; } \
	} while(0)
#endif

#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)

#endif // _LOGSTREAM_H

<|endoftext|>


<commit_before>// Copyright (C) 2013  James Turner - zakalawe@mac.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#include <simgear/package/Package.hxx>

#include <cassert>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp>

#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>

#include <simgear/package/Catalog.hxx>
#include <simgear/package/Install.hxx>
#include <simgear/package/Root.hxx>

namespace simgear {

namespace pkg {

Package::Package(const SGPropertyNode* aProps, CatalogRef aCatalog) :
    m_catalog(aCatalog)
{
    initWithProps(aProps);
}

void Package::initWithProps(const SGPropertyNode* aProps)
{
    m_props = const_cast<SGPropertyNode*>(aProps);
// cache tag values
    BOOST_FOREACH(const SGPropertyNode* c, aProps->getChildren("tag")) {
      std::string t(c->getStringValue());
      m_tags.insert(boost::to_lower_copy(t));
    }
}

bool Package::matches(const SGPropertyNode* aFilter) const
{
    int nChildren = aFilter->nChildren();
    for (int i = 0; i < nChildren; i++) {
        const SGPropertyNode* c = aFilter->getChild(i);
        const std::string& filter_name = c->getNameString();

        if (strutils::starts_with(filter_name, "rating-")) {
            int minRating = c->getIntValue();
            std::string rname = c->getName() + 7;
            int ourRating = m_props->getChild("rating")->getIntValue(rname, 0);
            if (ourRating < minRating) {
                return false;
            }
        }
        else if (filter_name == "tag") {
            std::string tag(c->getStringValue());
            boost::to_lower(tag);
            if (m_tags.find(tag) == m_tags.end()) {
                return false;
            }
        }
        // substring search of name, description
        else if (filter_name == "name") {
          std::string n(c->getStringValue());
          boost::to_lower(n);
          size_t pos = boost::to_lower_copy(name()).find(n);
          if (pos == std::string::npos) {
            return false;
          }
        }
        else if (filter_name == "description") {
          std::string n(c->getStringValue());
          boost::to_lower(n);
          size_t pos = boost::to_lower_copy(description()).find(n);
          if (pos == std::string::npos) {
            return false;
          }
        }
        else
          SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term:" << filter_name);
    } // of filter props iteration

    return true;
}

bool Package::isInstalled() const
{
    // anything to check for? look for a valid revision file?
    return pathOnDisk().exists();
}

SGPath Package::pathOnDisk() const
{
    SGPath p(m_catalog->installRoot());
    p.append("Aircraft");
    p.append(id());
    return p;
}

InstallRef Package::install()
{
    InstallRef ins = existingInstall();
    if (ins) {
        return ins;
    }

  // start a new install
    ins = new Install(this, pathOnDisk());
    m_catalog->root()->scheduleToUpdate(ins);
    return ins;
}

InstallRef Package::existingInstall() const
{
    return m_catalog->installForPackage(const_cast<Package*>(this));
}

std::string Package::id() const
{
    return m_props->getStringValue("id");
}

std::string Package::qualifiedId() const
{
    return m_catalog->id() + "." + id();
}

std::string Package::md5() const
{
    return m_props->getStringValue("md5");
}

unsigned int Package::revision() const
{
    return m_props->getIntValue("revision");
}

std::string Package::name() const
{
    return m_props->getStringValue("name");
}

size_t Package::fileSizeBytes() const
{
    return m_props->getIntValue("file-size-bytes");
}

std::string Package::description() const
{
    return getLocalisedProp("decription");
}

SGPropertyNode* Package::properties() const
{
    return m_props.ptr();
}

string_list Package::thumbnailUrls() const
{
    string_list r;
    BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
        r.push_back(dl->getStringValue());
    }
    return r;
}

string_list Package::downloadUrls() const
{
    string_list r;
    BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
        r.push_back(dl->getStringValue());
    }
    return r;
}

std::string Package::getLocalisedProp(const std::string& aName) const
{
    return getLocalisedString(m_props, aName.c_str());
}

std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{
    std::string locale = m_catalog->root()->getLocale();
    if (aRoot->hasChild(locale)) {
        const SGPropertyNode* localeRoot = aRoot->getChild(locale.c_str());
        if (localeRoot->hasChild(aName)) {
            return localeRoot->getStringValue(aName);
        }
    }

    return aRoot->getStringValue(aName);
}

PackageList Package::dependencies() const
{
    PackageList result;

    BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
        std::string depName = dep->getStringValue("package");
        unsigned int rev = dep->getIntValue("revision", 0);

    // prefer local hangar package if possible, in case someone does something
    // silly with naming. Of course flightgear's aircraft search doesn't know
    // about hanagrs, so names still need to be unique.
        PackageRef depPkg = m_catalog->getPackageById(depName);
        if (!depPkg) {
            Root* rt = m_catalog->root();
            depPkg = rt->getPackageById(depName);
            if (!depPkg) {
                throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
            }
        }

        if (depPkg->revision() < rev) {
            throw sg_range_exception("Couldn't find suitable revision of " + depName);
        }

    // forbid recursive dependency graphs, we don't need that level
    // of complexity for aircraft resources
        assert(depPkg->dependencies() == PackageList());

        result.push_back(depPkg);
    }

    return result;
}

} // of namespace pkg

} // of namespace simgear
<commit_msg>Package: fix property type (description)<commit_after>// Copyright (C) 2013  James Turner - zakalawe@mac.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#include <simgear/package/Package.hxx>

#include <cassert>
#include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp>

#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>

#include <simgear/package/Catalog.hxx>
#include <simgear/package/Install.hxx>
#include <simgear/package/Root.hxx>

namespace simgear {

namespace pkg {

Package::Package(const SGPropertyNode* aProps, CatalogRef aCatalog) :
    m_catalog(aCatalog)
{
    initWithProps(aProps);
}

void Package::initWithProps(const SGPropertyNode* aProps)
{
    m_props = const_cast<SGPropertyNode*>(aProps);
// cache tag values
    BOOST_FOREACH(const SGPropertyNode* c, aProps->getChildren("tag")) {
      std::string t(c->getStringValue());
      m_tags.insert(boost::to_lower_copy(t));
    }
}

bool Package::matches(const SGPropertyNode* aFilter) const
{
    int nChildren = aFilter->nChildren();
    for (int i = 0; i < nChildren; i++) {
        const SGPropertyNode* c = aFilter->getChild(i);
        const std::string& filter_name = c->getNameString();

        if (strutils::starts_with(filter_name, "rating-")) {
            int minRating = c->getIntValue();
            std::string rname = c->getName() + 7;
            int ourRating = m_props->getChild("rating")->getIntValue(rname, 0);
            if (ourRating < minRating) {
                return false;
            }
        }
        else if (filter_name == "tag") {
            std::string tag(c->getStringValue());
            boost::to_lower(tag);
            if (m_tags.find(tag) == m_tags.end()) {
                return false;
            }
        }
        // substring search of name, description
        else if (filter_name == "name") {
          std::string n(c->getStringValue());
          boost::to_lower(n);
          size_t pos = boost::to_lower_copy(name()).find(n);
          if (pos == std::string::npos) {
            return false;
          }
        }
        else if (filter_name == "description") {
          std::string n(c->getStringValue());
          boost::to_lower(n);
          size_t pos = boost::to_lower_copy(description()).find(n);
          if (pos == std::string::npos) {
            return false;
          }
        }
        else
          SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term:" << filter_name);
    } // of filter props iteration

    return true;
}

bool Package::isInstalled() const
{
    // anything to check for? look for a valid revision file?
    return pathOnDisk().exists();
}

SGPath Package::pathOnDisk() const
{
    SGPath p(m_catalog->installRoot());
    p.append("Aircraft");
    p.append(id());
    return p;
}

InstallRef Package::install()
{
    InstallRef ins = existingInstall();
    if (ins) {
        return ins;
    }

  // start a new install
    ins = new Install(this, pathOnDisk());
    m_catalog->root()->scheduleToUpdate(ins);
    return ins;
}

InstallRef Package::existingInstall() const
{
    return m_catalog->installForPackage(const_cast<Package*>(this));
}

std::string Package::id() const
{
    return m_props->getStringValue("id");
}

std::string Package::qualifiedId() const
{
    return m_catalog->id() + "." + id();
}

std::string Package::md5() const
{
    return m_props->getStringValue("md5");
}

unsigned int Package::revision() const
{
    return m_props->getIntValue("revision");
}

std::string Package::name() const
{
    return m_props->getStringValue("name");
}

size_t Package::fileSizeBytes() const
{
    return m_props->getIntValue("file-size-bytes");
}

std::string Package::description() const
{
    return getLocalisedProp("description");
}

SGPropertyNode* Package::properties() const
{
    return m_props.ptr();
}

string_list Package::thumbnailUrls() const
{
    string_list r;
    BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
        r.push_back(dl->getStringValue());
    }
    return r;
}

string_list Package::downloadUrls() const
{
    string_list r;
    BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
        r.push_back(dl->getStringValue());
    }
    return r;
}

std::string Package::getLocalisedProp(const std::string& aName) const
{
    return getLocalisedString(m_props, aName.c_str());
}

std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{
    std::string locale = m_catalog->root()->getLocale();
    if (aRoot->hasChild(locale)) {
        const SGPropertyNode* localeRoot = aRoot->getChild(locale.c_str());
        if (localeRoot->hasChild(aName)) {
            return localeRoot->getStringValue(aName);
        }
    }

    return aRoot->getStringValue(aName);
}

PackageList Package::dependencies() const
{
    PackageList result;

    BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
        std::string depName = dep->getStringValue("package");
        unsigned int rev = dep->getIntValue("revision", 0);

    // prefer local hangar package if possible, in case someone does something
    // silly with naming. Of course flightgear's aircraft search doesn't know
    // about hanagrs, so names still need to be unique.
        PackageRef depPkg = m_catalog->getPackageById(depName);
        if (!depPkg) {
            Root* rt = m_catalog->root();
            depPkg = rt->getPackageById(depName);
            if (!depPkg) {
                throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
            }
        }

        if (depPkg->revision() < rev) {
            throw sg_range_exception("Couldn't find suitable revision of " + depName);
        }

    // forbid recursive dependency graphs, we don't need that level
    // of complexity for aircraft resources
        assert(depPkg->dependencies() == PackageList());

        result.push_back(depPkg);
    }

    return result;
}

} // of namespace pkg

} // of namespace simgear
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
//  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 of conditions 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 materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  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 OWNER 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 "Gaffer/Context.h"
#include "GafferImage/Clamp.h"

using namespace IECore;
using namespace Gaffer;

namespace GafferImage
{

IE_CORE_DEFINERUNTIMETYPED( Clamp );

size_t Clamp::g_firstPlugIndex = 0;

Clamp::Clamp( const std::string &name )
	:	ChannelDataProcessor( name )
{
	storeIndexOfNextChild( g_firstPlugIndex );

	addChild( new Color4fPlug( "minimum", Plug::In, Imath::Color4f(0.f, 0.f, 0.f, 0.f) ) );
	addChild( new Color4fPlug( "maximum", Plug::In, Imath::Color4f(1.f, 1.f, 1.f, 1.f) ) );
	addChild( new Color4fPlug( "minClampTo", Plug::In, Imath::Color4f(0.f, 0.f, 0.f, 0.f) ) );
	addChild( new Color4fPlug( "maxClampTo", Plug::In, Imath::Color4f(1.f, 1.f, 1.f, 1.f) ) );

	addChild( new BoolPlug( "minimumEnabled", Plug::In, true ) );
	addChild( new BoolPlug( "maximumEnabled", Plug::In, true ) );
	addChild( new BoolPlug( "minClampToEnabled", Plug::In, false ) );
	addChild( new BoolPlug( "maxClampToEnabled", Plug::In, false ) );
}

Clamp::~Clamp()
{
}

Gaffer::Color4fPlug *Clamp::minimumPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex );
}

const Gaffer::Color4fPlug *Clamp::minimumPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex );
}

Gaffer::Color4fPlug *Clamp::maximumPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+1 );
}

const Gaffer::Color4fPlug *Clamp::maximumPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+1 );
}

Gaffer::Color4fPlug *Clamp::minClampToPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+2 );
}

const Gaffer::Color4fPlug *Clamp::minClampToPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+2 );
}

Gaffer::Color4fPlug *Clamp::maxClampToPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+3 );
}

const Gaffer::Color4fPlug *Clamp::maxClampToPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+3 );
}

Gaffer::BoolPlug *Clamp::minimumEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+4 );
}

const Gaffer::BoolPlug *Clamp::minimumEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+4 );
}

Gaffer::BoolPlug *Clamp::maximumEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+5 );
}

const Gaffer::BoolPlug *Clamp::maximumEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+5 );
}

Gaffer::BoolPlug *Clamp::minClampToEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+6 );
}

const Gaffer::BoolPlug *Clamp::minClampToEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+6 );
}

Gaffer::BoolPlug *Clamp::maxClampToEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+7 );
}

const Gaffer::BoolPlug *Clamp::maxClampToEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+7 );
}

bool Clamp::channelEnabled( const std::string &channel ) const
{
	if ( !ChannelDataProcessor::channelEnabled( channel ) )
	{
		return false;
	}

	if (minimumEnabledPlug()->getValue() == false &&
		maximumEnabledPlug()->getValue() == false )
	{
		return false;
	}

	return true;
}

void Clamp::affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const
{
	ChannelDataProcessor::affects( input, outputs );

	if ( input->ancestor<Color4fPlug>() == minimumPlug() ||
		 input->ancestor<Color4fPlug>() == maximumPlug() ||
		 input->ancestor<Color4fPlug>() == minClampToPlug() ||
		 input->ancestor<Color4fPlug>() == maxClampToPlug()
	  )
	{
		outputs.push_back( outPlug()->channelDataPlug() );
		return;
	}

	if( input == inPlug()->channelDataPlug() ||
		input == minimumEnabledPlug() ||
		input == maximumEnabledPlug() ||
		input == minClampToEnabledPlug() ||
		input == maxClampToEnabledPlug()
	  )
	{
		outputs.push_back( outPlug()->channelDataPlug() );
		return;
	}

}

void Clamp::hashChannelDataPlug( const GafferImage::ImagePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	const std::string &channelName = context->get<std::string>( ImagePlug::channelNameContextName );

	ContextPtr tmpContext = new Context( *Context::current() );
	Context::Scope scopedContext( tmpContext );

	tmpContext->set( ImagePlug::channelNameContextName, channelName );
	inPlug()->channelDataPlug()->hash( h );

	minimumPlug()->hash( h );
	maximumPlug()->hash( h );
	minClampToPlug()->hash( h );
	maxClampToPlug()->hash( h );

	minimumEnabledPlug()->hash( h );
	maximumEnabledPlug()->hash( h );
	minClampToEnabledPlug()->hash( h );
	maxClampToEnabledPlug()->hash( h );
}

void Clamp::processChannelData( const Gaffer::Context *context, const ImagePlug *parent, const std::string &channel, FloatVectorDataPtr outData ) const
{
	const int dataWidth = ImagePlug::tileSize()*ImagePlug::tileSize();

	int channelIndex = ChannelMaskPlug::channelIndex( channel );
	const float minimum = minimumPlug()->getValue()[channelIndex];
	const float maximum = maximumPlug()->getValue()[channelIndex];
	const float minClampTo = minClampToPlug()->getValue()[channelIndex];
	const float maxClampTo = maxClampToPlug()->getValue()[channelIndex];
	const bool minimumEnabled = minimumEnabledPlug()->getValue();
	const bool maximumEnabled = maximumEnabledPlug()->getValue();
	const bool minClampToEnabled = minClampToEnabledPlug()->getValue();
	const bool maxClampToEnabled = maxClampToEnabledPlug()->getValue();

	float *outPtr = &(outData->writable()[0]);
	const float *END = outPtr + dataWidth;

	while (outPtr != END)
	{
		float colour = *outPtr;

		if ( minimumEnabled && colour < minimum ) colour = (minClampToEnabled ? minClampTo : minimum);
		if ( maximumEnabled && colour > maximum ) colour = (maxClampToEnabled ? maxClampTo : maximum);

		*outPtr++ = colour;
	}
}

} // namespace GafferImage

<commit_msg>Updating to use iterators, updating testing logic to be more clear<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
//  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 of conditions 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 materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  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 OWNER 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 "Gaffer/Context.h"
#include "GafferImage/Clamp.h"

using namespace IECore;
using namespace Gaffer;

namespace GafferImage
{

IE_CORE_DEFINERUNTIMETYPED( Clamp );

size_t Clamp::g_firstPlugIndex = 0;

Clamp::Clamp( const std::string &name )
	:	ChannelDataProcessor( name )
{
	storeIndexOfNextChild( g_firstPlugIndex );

	addChild( new Color4fPlug( "minimum", Plug::In, Imath::Color4f(0.f, 0.f, 0.f, 0.f) ) );
	addChild( new Color4fPlug( "maximum", Plug::In, Imath::Color4f(1.f, 1.f, 1.f, 1.f) ) );
	addChild( new Color4fPlug( "minClampTo", Plug::In, Imath::Color4f(0.f, 0.f, 0.f, 0.f) ) );
	addChild( new Color4fPlug( "maxClampTo", Plug::In, Imath::Color4f(1.f, 1.f, 1.f, 1.f) ) );

	addChild( new BoolPlug( "minimumEnabled", Plug::In, true ) );
	addChild( new BoolPlug( "maximumEnabled", Plug::In, true ) );
	addChild( new BoolPlug( "minClampToEnabled", Plug::In, false ) );
	addChild( new BoolPlug( "maxClampToEnabled", Plug::In, false ) );
}

Clamp::~Clamp()
{
}

Gaffer::Color4fPlug *Clamp::minimumPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex );
}

const Gaffer::Color4fPlug *Clamp::minimumPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex );
}

Gaffer::Color4fPlug *Clamp::maximumPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+1 );
}

const Gaffer::Color4fPlug *Clamp::maximumPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+1 );
}

Gaffer::Color4fPlug *Clamp::minClampToPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+2 );
}

const Gaffer::Color4fPlug *Clamp::minClampToPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+2 );
}

Gaffer::Color4fPlug *Clamp::maxClampToPlug()
{
	return getChild<Color4fPlug>( g_firstPlugIndex+3 );
}

const Gaffer::Color4fPlug *Clamp::maxClampToPlug() const
{
	return getChild<Color4fPlug>( g_firstPlugIndex+3 );
}

Gaffer::BoolPlug *Clamp::minimumEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+4 );
}

const Gaffer::BoolPlug *Clamp::minimumEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+4 );
}

Gaffer::BoolPlug *Clamp::maximumEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+5 );
}

const Gaffer::BoolPlug *Clamp::maximumEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+5 );
}

Gaffer::BoolPlug *Clamp::minClampToEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+6 );
}

const Gaffer::BoolPlug *Clamp::minClampToEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+6 );
}

Gaffer::BoolPlug *Clamp::maxClampToEnabledPlug()
{
	return getChild<BoolPlug>( g_firstPlugIndex+7 );
}

const Gaffer::BoolPlug *Clamp::maxClampToEnabledPlug() const
{
	return getChild<BoolPlug>( g_firstPlugIndex+7 );
}

bool Clamp::channelEnabled( const std::string &channel ) const
{
	if ( !ChannelDataProcessor::channelEnabled( channel ) )
	{
		return false;
	}

	if (minimumEnabledPlug()->getValue() == false &&
		maximumEnabledPlug()->getValue() == false )
	{
		return false;
	}

	return true;
}

void Clamp::affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const
{
	ChannelDataProcessor::affects( input, outputs );

	if ( input->ancestor<Color4fPlug>() == minimumPlug() ||
		 input->ancestor<Color4fPlug>() == maximumPlug() ||
		 input->ancestor<Color4fPlug>() == minClampToPlug() ||
		 input->ancestor<Color4fPlug>() == maxClampToPlug()
	  )
	{
		outputs.push_back( outPlug()->channelDataPlug() );
		return;
	}

	if( input == inPlug()->channelDataPlug() ||
		input == minimumEnabledPlug() ||
		input == maximumEnabledPlug() ||
		input == minClampToEnabledPlug() ||
		input == maxClampToEnabledPlug()
	  )
	{
		outputs.push_back( outPlug()->channelDataPlug() );
		return;
	}

}

void Clamp::hashChannelDataPlug( const GafferImage::ImagePlug *output, const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
	const std::string &channelName = context->get<std::string>( ImagePlug::channelNameContextName );

	ContextPtr tmpContext = new Context( *Context::current() );
	Context::Scope scopedContext( tmpContext );

	tmpContext->set( ImagePlug::channelNameContextName, channelName );
	inPlug()->channelDataPlug()->hash( h );

	minimumPlug()->hash( h );
	maximumPlug()->hash( h );
	minClampToPlug()->hash( h );
	maxClampToPlug()->hash( h );

	minimumEnabledPlug()->hash( h );
	maximumEnabledPlug()->hash( h );
	minClampToEnabledPlug()->hash( h );
	maxClampToEnabledPlug()->hash( h );
}

void Clamp::processChannelData( const Gaffer::Context *context, const ImagePlug *parent, const std::string &channel, FloatVectorDataPtr outData ) const
{
	int channelIndex = ChannelMaskPlug::channelIndex( channel );

	const float minimum = minimumPlug()->getValue()[channelIndex];
	const float maximum = maximumPlug()->getValue()[channelIndex];
	const float minClampTo = minClampToPlug()->getValue()[channelIndex];
	const float maxClampTo = maxClampToPlug()->getValue()[channelIndex];
	const bool minimumEnabled = minimumEnabledPlug()->getValue();
	const bool maximumEnabled = maximumEnabledPlug()->getValue();
	const bool minClampToEnabled = minClampToEnabledPlug()->getValue();
	const bool maxClampToEnabled = maxClampToEnabledPlug()->getValue();

	std::vector<float> &out = outData->writable();

	std::vector<float>::iterator outDataIterator;

	for (outDataIterator = out.begin(); outDataIterator != out.end(); ++outDataIterator)
	{

		if (minimumEnabled)
		{
			if (*outDataIterator < minimum)
			{
				if (minClampToEnabled)
				{
					*outDataIterator = minClampTo;
				}
				else
				{
					*outDataIterator = minimum;
				}
			}
		}

		if (maximumEnabled)
		{
			if (*outDataIterator > maximum)
			{
				if (maxClampToEnabled)
				{
					*outDataIterator = maxClampTo;
				}
				else
				{
					*outDataIterator = maximum;
				}
			}
		}

	}
}

} // namespace GafferImage

<|endoftext|>


<commit_before>// SALOME Session : implementation of Session.idl
//
// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// 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
//
// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
//
//
//
// File : SALOME_Session_Server.cxx
// Author : Paul RASCLE, EDF
// Module : SALOME

#include <Container_init_python.hxx>
#include "Utils_ORB_INIT.hxx"
#include "Utils_SINGLETON.hxx"
#include "SALOME_NamingService.hxx"
#include "SALOMETraceCollector.hxx"

#include "InquireServersQThread.h" // splash

#include <iostream>
#ifndef WNT
#include <unistd.h>
#endif

#include <qdir.h>
#include <qfile.h>
#include <qapplication.h>
#include <qwaitcondition.h>

#include "Utils_SALOME_Exception.hxx"
#include "Utils_CorbaException.hxx"
#include "SALOME_Event.hxx"

#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SALOME_Session)
#include CORBA_SERVER_HEADER(SALOMEDS)

#include <utilities.h>
#include "Session_Session_i.hxx"
#include "Session_ServerLauncher.hxx"

#include "SUIT_Tools.h"
#include "SUIT_Session.h"
#include "SUIT_Application.h"
#include "SUIT_MessageBox.h"
#include "SUIT_ResourceMgr.h"

#include "SUIT_ExceptionHandler.h"

extern "C" int HandleSignals( QApplication *theQApplication );

/*! - read arguments, define list of server to launch with their arguments.
 * - wait for naming service
 * - create and run a thread for launch of all servers
 *
*/

//! CORBA server for SALOME Session
/*!
 * SALOME_Session Server launches a SALOME session servant.
 * The servant registers to the Naming Service.
 * See SALOME_Session.idl for interface specification.
 *
 * Main services offered by the servant are:
 * - launch GUI
 * - stop Session ( must be idle )
 * - get session state
 */

PyObject* salome_shared_modules_module = 0;

void MessageOutput( QtMsgType type, const char* msg )
{
  switch ( type )
  {
  case QtDebugMsg:
    MESSAGE( "Debug: " << msg );
    break;
  case QtWarningMsg:
    MESSAGE( "Warning: " << msg );
    break;
  case QtFatalMsg:
    MESSAGE( "Fatal: " << msg );
    break;
  }
}

/* XPM */
static const char* pixmap_not_found_xpm[] = {
"16 16 3 1",
"       c None",
".      c #000000",
"+      c #A80000",
"                ",
"                ",
"    .     .     ",
"   .+.   .+.    ",
"  .+++. .+++.   ",
"   .+++.+++.    ",
"    .+++++.     ",
"     .+++.      ",
"    .+++++.     ",
"   .+++.+++.    ",
"  .+++. .+++.   ",
"   .+.   .+.    ",
"    .     .     ",
"                ",
"                ",
"                "};

QString salomeVersion()
{
  QString path( ::getenv( "GUI_ROOT_DIR" ) );
  if ( !path.isEmpty() )
    path += QDir::separator();
  path += QString( "bin/salome/VERSION" );

  QFile vf( path );
  if ( !vf.open( IO_ReadOnly ) )
    return QString::null;

  QString line;
  vf.readLine( line, 1024 );
  vf.close();

  if ( line.isEmpty() )
    return QString::null;

  while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
    line.remove( line.length() - 1, 1 );

  QString ver;
  int idx = line.findRev( ":" );
  if ( idx != -1 )
    ver = line.mid( idx + 1 ).stripWhiteSpace();

  return ver;
}

class SALOME_ResourceMgr : public SUIT_ResourceMgr
{
public:
  SALOME_ResourceMgr( const QString& app, const QString& resVarTemplate ) : SUIT_ResourceMgr( app, resVarTemplate )
  {
    setCurrentFormat( "xml" );
    setOption( "translators", QString( "%P_msg_%L.qm|%P_icons.qm|%P_images.qm" ) );
    setDefaultPixmap( QPixmap( pixmap_not_found_xpm ) );
  }
  static void initResourceMgr()
  {
    if ( myExtAppName.isNull() || myExtAppVersion.isNull() ) {
      SALOME_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
      resMgr.loadLanguage( "SalomeApp", "en" );

      myExtAppName = QObject::tr( "APP_NAME" ).stripWhiteSpace();
      if ( myExtAppName == "APP_NAME" || myExtAppName.lower() == "salome" )
        myExtAppName = "SalomeApp";
      myExtAppVersion = QObject::tr( "APP_VERSION" );
      if ( myExtAppVersion == "APP_VERSION" ) {
        if ( myExtAppName != "SalomeApp" )
          myExtAppVersion = "";
	else myExtAppVersion = salomeVersion();
      }
    }
  }
  QString version() const { return myExtAppVersion; }

protected:
  QString userFileName( const QString& appName ) const
  {
    if ( version().isNull()  ) return "";
    return SUIT_ResourceMgr::userFileName( myExtAppName );
  }

public:
  static QString myExtAppName;
  static QString myExtAppVersion;
};

QString SALOME_ResourceMgr::myExtAppName    = QString::null;
QString SALOME_ResourceMgr::myExtAppVersion = QString::null;

class SALOME_Session : public SUIT_Session
{
public:
  SALOME_Session() : SUIT_Session() {}
  virtual ~SALOME_Session() {}

protected:
  virtual SUIT_ResourceMgr* createResourceMgr( const QString& appName ) const
  {
    SALOME_ResourceMgr::initResourceMgr();
    SALOME_ResourceMgr* resMgr = new SALOME_ResourceMgr( appName, QString( "%1Config" ) );
    return resMgr;
  }
};

class SALOME_QApplication : public QApplication
{
public:
  SALOME_QApplication( int& argc, char** argv ) : QApplication( argc, argv ), myHandler ( 0 ) {}

  virtual bool notify( QObject* receiver, QEvent* e )
  {
    return myHandler ? myHandler->handle( receiver, e ) :
      QApplication::notify( receiver, e );
  }
  SUIT_ExceptionHandler* handler() const { return myHandler; }
  void setHandler( SUIT_ExceptionHandler* h ) { myHandler = h; }

private:
  SUIT_ExceptionHandler* myHandler;
};

// class which calls SALOME::Session::GetInterface() from another thread
// to avoid mutual lock ( if called from the same thread as main()
class GetInterfaceThread : public QThread
{
public:
  GetInterfaceThread( SALOME::Session_var s ) : session ( s ) {}
protected:
  virtual void run()
  {
    if ( !CORBA::is_nil( session ) )
      session->GetInterface();
    else
      printf( "\nFATAL ERROR: SALOME::Session object is nil! Can not display GUI\n\n" );
  }
private:
  SALOME::Session_var session;
};

// returns true if 'str' is found in argv
bool isFound( const char* str, int argc, char** argv )
{
  for ( int i = 1; i <= ( argc-1 ); i++ )
    if ( !strcmp( argv[i], str ) )
      return true;
  return false;
}

// ---------------------------- MAIN -----------------------
int main( int argc, char **argv )
{
  qInstallMsgHandler( MessageOutput );

  // QApplication should be create before all other operations
  // When uses QApplication::libraryPaths() ( example, QFile::encodeName() )
  // qApp used for detection of the executable dir path.
  SALOME_QApplication _qappl( argc, argv );
  ASSERT( QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) ) );

  QString path = QDir::convertSeparators( SUIT_Tools::addSlash( QString( ::getenv( "GUI_ROOT_DIR" ) ) ) + QString( "bin/salome" ) );
  _qappl.addLibraryPath( path );

  _qappl.setStyle( "salome" );

  int result = -1;

  CORBA::ORB_var orb;
  PortableServer::POA_var poa;

  SUIT_Session* aGUISession = 0;
  SALOME_NamingService* _NS = 0;
  GetInterfaceThread* guiThread = 0;
  Session_ServerLauncher* myServerLauncher = 0;

  try {

    // Python initialisation : only once

    int _argc = 1;
    char* _argv[] = {""};
    KERNEL_PYTHON::init_python( _argc,_argv );
    PyEval_RestoreThread( KERNEL_PYTHON::_gtstate );
    if ( !KERNEL_PYTHON::salome_shared_modules_module ) // import only once
      KERNEL_PYTHON::salome_shared_modules_module = PyImport_ImportModule( "salome_shared_modules" );
    if ( !KERNEL_PYTHON::salome_shared_modules_module )
    {
      INFOS( "salome_shared_modules_module == NULL" );
      PyErr_Print();
      PyErr_Clear();
    }
    PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );

    // Create ORB, get RootPOA object, NamingService, etc.
    ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
    ASSERT( SINGLETON_<ORB_INIT>::IsAlreadyExisting() );
    int orbArgc = 1;
    orb = init( orbArgc, argv );

    // Install SALOME thread event handler
    SALOME_Event::GetSessionThread();

    CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" );
    poa = PortableServer::POA::_narrow( obj );

    PortableServer::POAManager_var pman = poa->the_POAManager();
    pman->activate() ;
    INFOS( "pman->activate()" );

    _NS = new SALOME_NamingService( orb );

    result = 0;
  }
  catch ( SALOME_Exception& e ) {
    INFOS( "run(): SALOME::SALOME_Exception is caught: "<<e.what() );
  }
  catch ( CORBA::SystemException& e ) {
    INFOS( "Caught CORBA::SystemException." );
  }
  catch ( CORBA::Exception& e ) {
    INFOS( "Caught CORBA::Exception." );
    CORBA::Any tmp;
    tmp<<= e;
    CORBA::TypeCode_var tc = tmp.type();
    const char *p = tc->name();
    INFOS ( "run(): CORBA exception of the kind : "<<p<< " is caught" );
  }
  catch ( exception& e ) {
    INFOS( "run(): An exception has been caught: " <<e.what() );
  }
  catch (...) {
    INFOS( "Caught unknown exception." );
  }

  // CORBA Servant Launcher
  QMutex _GUIMutex;
  QWaitCondition _ServerLaunch, _SessionStarted;

  if ( !result )
  {
    _GUIMutex.lock();  // to block Launch server thread until wait( mutex )

    // Activate embedded CORBA servers: Registry, SALOMEDS, etc.
    myServerLauncher = new Session_ServerLauncher( argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch, &_SessionStarted );
    myServerLauncher->start();

    _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:

    // show splash screen if "SPLASH" parameter was passed ( default )
    if ( isFound( "SPLASH", argc, argv ) )
    {
      // create temporary resource manager just to load splash icon
      SALOME_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
      resMgr.loadLanguage( "SalomeApp", "en" );

      // create splash object: widget ( splash with progress bar ) and "pinging" thread
      InquireServersGUI splash;
      splash.setPixmap( resMgr.loadPixmap( "SalomeApp", QObject::tr( "ABOUT_SPLASH" ) ) );
      SUIT_Tools::centerWidget( &splash, _qappl.desktop() );

      _qappl.setMainWidget( &splash );
      QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) );
      splash.show(); // display splash with running progress bar
      _qappl.exec(); // wait untill splash closes ( progress runs till end or Cancel is pressed )

      result = splash.getExitStatus(); // 1 is error
    }
    else
      _SessionStarted.wait();
  }

  // call Session::GetInterface() if "GUI" parameter was passed ( default )
  if ( !result && isFound( "GUI", argc, argv ) )
  {
    CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" );
    SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
    ASSERT ( ! CORBA::is_nil( session ) );

    INFOS( "Session activated, Launch IAPP..." );
    guiThread = new GetInterfaceThread( session );
    guiThread->start();
  }

  if ( !result )
  {

    // GUI activation
    // Allow multiple activation/deactivation of GUI
    while ( true )
    {
      MESSAGE( "waiting wakeAll()" );
      _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:
      // atomic operation lock - unlock on mutex
      // unlock mutex: serverThread runs, calls _ServerLaunch->wakeAll()
      // this thread wakes up, and lock mutex

      _GUIMutex.unlock();

      // SUIT_Session creation
      aGUISession = new SALOME_Session();

      // Load SalomeApp dynamic library
      INFOS( "creation SUIT_Application" );
      SUIT_Application* aGUIApp = aGUISession->startApplication( "SalomeApp", 0, 0 );
      if ( aGUIApp )
      {
	_qappl.setHandler( aGUISession->handler() ); // after loading SalomeApp application
	                                             // aGUISession contains SalomeApp_ExceptionHandler
	// Run GUI loop
	MESSAGE( "run(): starting the main event loop" );
	result = _qappl.exec();

	if ( result == SUIT_Session::FROM_GUI ) // desktop is closed by user from GUI
	  break;
      }

      delete aGUISession;
      aGUISession = 0;

      // Prepare _GUIMutex for a new GUI activation
      _GUIMutex.lock();
    }
  }

  if ( myServerLauncher )
    myServerLauncher->KillAll(); // kill embedded servers

  delete aGUISession;
  delete guiThread;
  delete myServerLauncher;
  delete _NS;

  LocalTraceBufferPool *bp1 = LocalTraceBufferPool::instance();
  LocalTraceBufferPool::deleteInstance(bp1);

  return result;
}
<commit_msg>Load icon "about.png" from LightApp not SalomeApp<commit_after>// SALOME Session : implementation of Session.idl
//
// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// 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
//
// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
//
//
//
// File : SALOME_Session_Server.cxx
// Author : Paul RASCLE, EDF
// Module : SALOME

#include <Container_init_python.hxx>
#include "Utils_ORB_INIT.hxx"
#include "Utils_SINGLETON.hxx"
#include "SALOME_NamingService.hxx"
#include "SALOMETraceCollector.hxx"

#include "InquireServersQThread.h" // splash

#include <iostream>
#ifndef WNT
#include <unistd.h>
#endif

#include <qdir.h>
#include <qfile.h>
#include <qapplication.h>
#include <qwaitcondition.h>

#include "Utils_SALOME_Exception.hxx"
#include "Utils_CorbaException.hxx"
#include "SALOME_Event.hxx"

#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SALOME_Session)
#include CORBA_SERVER_HEADER(SALOMEDS)

#include <utilities.h>
#include "Session_Session_i.hxx"
#include "Session_ServerLauncher.hxx"

#include "SUIT_Tools.h"
#include "SUIT_Session.h"
#include "SUIT_Application.h"
#include "SUIT_MessageBox.h"
#include "SUIT_ResourceMgr.h"

#include "SUIT_ExceptionHandler.h"

extern "C" int HandleSignals( QApplication *theQApplication );

/*! - read arguments, define list of server to launch with their arguments.
 * - wait for naming service
 * - create and run a thread for launch of all servers
 *
*/

//! CORBA server for SALOME Session
/*!
 * SALOME_Session Server launches a SALOME session servant.
 * The servant registers to the Naming Service.
 * See SALOME_Session.idl for interface specification.
 *
 * Main services offered by the servant are:
 * - launch GUI
 * - stop Session ( must be idle )
 * - get session state
 */

PyObject* salome_shared_modules_module = 0;

void MessageOutput( QtMsgType type, const char* msg )
{
  switch ( type )
  {
  case QtDebugMsg:
    MESSAGE( "Debug: " << msg );
    break;
  case QtWarningMsg:
    MESSAGE( "Warning: " << msg );
    break;
  case QtFatalMsg:
    MESSAGE( "Fatal: " << msg );
    break;
  }
}

/* XPM */
static const char* pixmap_not_found_xpm[] = {
"16 16 3 1",
"       c None",
".      c #000000",
"+      c #A80000",
"                ",
"                ",
"    .     .     ",
"   .+.   .+.    ",
"  .+++. .+++.   ",
"   .+++.+++.    ",
"    .+++++.     ",
"     .+++.      ",
"    .+++++.     ",
"   .+++.+++.    ",
"  .+++. .+++.   ",
"   .+.   .+.    ",
"    .     .     ",
"                ",
"                ",
"                "};

QString salomeVersion()
{
  QString path( ::getenv( "GUI_ROOT_DIR" ) );
  if ( !path.isEmpty() )
    path += QDir::separator();
  path += QString( "bin/salome/VERSION" );

  QFile vf( path );
  if ( !vf.open( IO_ReadOnly ) )
    return QString::null;

  QString line;
  vf.readLine( line, 1024 );
  vf.close();

  if ( line.isEmpty() )
    return QString::null;

  while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) )
    line.remove( line.length() - 1, 1 );

  QString ver;
  int idx = line.findRev( ":" );
  if ( idx != -1 )
    ver = line.mid( idx + 1 ).stripWhiteSpace();

  return ver;
}

class SALOME_ResourceMgr : public SUIT_ResourceMgr
{
public:
  SALOME_ResourceMgr( const QString& app, const QString& resVarTemplate ) : SUIT_ResourceMgr( app, resVarTemplate )
  {
    setCurrentFormat( "xml" );
    setOption( "translators", QString( "%P_msg_%L.qm|%P_icons.qm|%P_images.qm" ) );
    setDefaultPixmap( QPixmap( pixmap_not_found_xpm ) );
  }
  static void initResourceMgr()
  {
    if ( myExtAppName.isNull() || myExtAppVersion.isNull() ) {
      SALOME_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
      resMgr.loadLanguage( "SalomeApp", "en" );

      myExtAppName = QObject::tr( "APP_NAME" ).stripWhiteSpace();
      if ( myExtAppName == "APP_NAME" || myExtAppName.lower() == "salome" )
        myExtAppName = "SalomeApp";
      myExtAppVersion = QObject::tr( "APP_VERSION" );
      if ( myExtAppVersion == "APP_VERSION" ) {
        if ( myExtAppName != "SalomeApp" )
          myExtAppVersion = "";
	else myExtAppVersion = salomeVersion();
      }
    }
  }
  QString version() const { return myExtAppVersion; }

protected:
  QString userFileName( const QString& appName ) const
  {
    if ( version().isNull()  ) return "";
    return SUIT_ResourceMgr::userFileName( myExtAppName );
  }

public:
  static QString myExtAppName;
  static QString myExtAppVersion;
};

QString SALOME_ResourceMgr::myExtAppName    = QString::null;
QString SALOME_ResourceMgr::myExtAppVersion = QString::null;

class SALOME_Session : public SUIT_Session
{
public:
  SALOME_Session() : SUIT_Session() {}
  virtual ~SALOME_Session() {}

protected:
  virtual SUIT_ResourceMgr* createResourceMgr( const QString& appName ) const
  {
    SALOME_ResourceMgr::initResourceMgr();
    SALOME_ResourceMgr* resMgr = new SALOME_ResourceMgr( appName, QString( "%1Config" ) );
    return resMgr;
  }
};

class SALOME_QApplication : public QApplication
{
public:
  SALOME_QApplication( int& argc, char** argv ) : QApplication( argc, argv ), myHandler ( 0 ) {}

  virtual bool notify( QObject* receiver, QEvent* e )
  {
    return myHandler ? myHandler->handle( receiver, e ) :
      QApplication::notify( receiver, e );
  }
  SUIT_ExceptionHandler* handler() const { return myHandler; }
  void setHandler( SUIT_ExceptionHandler* h ) { myHandler = h; }

private:
  SUIT_ExceptionHandler* myHandler;
};

// class which calls SALOME::Session::GetInterface() from another thread
// to avoid mutual lock ( if called from the same thread as main()
class GetInterfaceThread : public QThread
{
public:
  GetInterfaceThread( SALOME::Session_var s ) : session ( s ) {}
protected:
  virtual void run()
  {
    if ( !CORBA::is_nil( session ) )
      session->GetInterface();
    else
      printf( "\nFATAL ERROR: SALOME::Session object is nil! Can not display GUI\n\n" );
  }
private:
  SALOME::Session_var session;
};

// returns true if 'str' is found in argv
bool isFound( const char* str, int argc, char** argv )
{
  for ( int i = 1; i <= ( argc-1 ); i++ )
    if ( !strcmp( argv[i], str ) )
      return true;
  return false;
}

// ---------------------------- MAIN -----------------------
int main( int argc, char **argv )
{
  qInstallMsgHandler( MessageOutput );

  // QApplication should be create before all other operations
  // When uses QApplication::libraryPaths() ( example, QFile::encodeName() )
  // qApp used for detection of the executable dir path.
  SALOME_QApplication _qappl( argc, argv );
  ASSERT( QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) ) );

  QString path = QDir::convertSeparators( SUIT_Tools::addSlash( QString( ::getenv( "GUI_ROOT_DIR" ) ) ) + QString( "bin/salome" ) );
  _qappl.addLibraryPath( path );

  _qappl.setStyle( "salome" );

  int result = -1;

  CORBA::ORB_var orb;
  PortableServer::POA_var poa;

  SUIT_Session* aGUISession = 0;
  SALOME_NamingService* _NS = 0;
  GetInterfaceThread* guiThread = 0;
  Session_ServerLauncher* myServerLauncher = 0;

  try {

    // Python initialisation : only once

    int _argc = 1;
    char* _argv[] = {""};
    KERNEL_PYTHON::init_python( _argc,_argv );
    PyEval_RestoreThread( KERNEL_PYTHON::_gtstate );
    if ( !KERNEL_PYTHON::salome_shared_modules_module ) // import only once
      KERNEL_PYTHON::salome_shared_modules_module = PyImport_ImportModule( "salome_shared_modules" );
    if ( !KERNEL_PYTHON::salome_shared_modules_module )
    {
      INFOS( "salome_shared_modules_module == NULL" );
      PyErr_Print();
      PyErr_Clear();
    }
    PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );

    // Create ORB, get RootPOA object, NamingService, etc.
    ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
    ASSERT( SINGLETON_<ORB_INIT>::IsAlreadyExisting() );
    int orbArgc = 1;
    orb = init( orbArgc, argv );

    // Install SALOME thread event handler
    SALOME_Event::GetSessionThread();

    CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" );
    poa = PortableServer::POA::_narrow( obj );

    PortableServer::POAManager_var pman = poa->the_POAManager();
    pman->activate() ;
    INFOS( "pman->activate()" );

    _NS = new SALOME_NamingService( orb );

    result = 0;
  }
  catch ( SALOME_Exception& e ) {
    INFOS( "run(): SALOME::SALOME_Exception is caught: "<<e.what() );
  }
  catch ( CORBA::SystemException& e ) {
    INFOS( "Caught CORBA::SystemException." );
  }
  catch ( CORBA::Exception& e ) {
    INFOS( "Caught CORBA::Exception." );
    CORBA::Any tmp;
    tmp<<= e;
    CORBA::TypeCode_var tc = tmp.type();
    const char *p = tc->name();
    INFOS ( "run(): CORBA exception of the kind : "<<p<< " is caught" );
  }
  catch ( exception& e ) {
    INFOS( "run(): An exception has been caught: " <<e.what() );
  }
  catch (...) {
    INFOS( "Caught unknown exception." );
  }

  // CORBA Servant Launcher
  QMutex _GUIMutex;
  QWaitCondition _ServerLaunch, _SessionStarted;

  if ( !result )
  {
    _GUIMutex.lock();  // to block Launch server thread until wait( mutex )

    // Activate embedded CORBA servers: Registry, SALOMEDS, etc.
    myServerLauncher = new Session_ServerLauncher( argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch, &_SessionStarted );
    myServerLauncher->start();

    _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:

    // show splash screen if "SPLASH" parameter was passed ( default )
    if ( isFound( "SPLASH", argc, argv ) )
    {
      // create temporary resource manager just to load splash icon
      SUIT_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
      resMgr.setCurrentFormat( "xml" );
      resMgr.loadLanguage( "LightApp", "en" );

      // create splash object: widget ( splash with progress bar ) and "pinging" thread
      InquireServersGUI splash;
      splash.setPixmap( resMgr.loadPixmap( "LightApp", QObject::tr( "ABOUT_SPLASH" ) ) );
      SUIT_Tools::centerWidget( &splash, _qappl.desktop() );

      _qappl.setMainWidget( &splash );
      QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) );
      splash.show(); // display splash with running progress bar
      _qappl.exec(); // wait untill splash closes ( progress runs till end or Cancel is pressed )

      result = splash.getExitStatus(); // 1 is error
    }
    else
      _SessionStarted.wait();
  }

  // call Session::GetInterface() if "GUI" parameter was passed ( default )
  if ( !result && isFound( "GUI", argc, argv ) )
  {
    CORBA::Object_var obj = _NS->Resolve( "/Kernel/Session" );
    SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
    ASSERT ( ! CORBA::is_nil( session ) );

    INFOS( "Session activated, Launch IAPP..." );
    guiThread = new GetInterfaceThread( session );
    guiThread->start();
  }

  if ( !result )
  {

    // GUI activation
    // Allow multiple activation/deactivation of GUI
    while ( true )
    {
      MESSAGE( "waiting wakeAll()" );
      _ServerLaunch.wait( &_GUIMutex ); // to be reseased by Launch server thread when ready:
      // atomic operation lock - unlock on mutex
      // unlock mutex: serverThread runs, calls _ServerLaunch->wakeAll()
      // this thread wakes up, and lock mutex

      _GUIMutex.unlock();

      // SUIT_Session creation
      aGUISession = new SALOME_Session();

      // Load SalomeApp dynamic library
      INFOS( "creation SUIT_Application" );
      SUIT_Application* aGUIApp = aGUISession->startApplication( "SalomeApp", 0, 0 );
      if ( aGUIApp )
      {
	_qappl.setHandler( aGUISession->handler() ); // after loading SalomeApp application
	                                             // aGUISession contains SalomeApp_ExceptionHandler
	// Run GUI loop
	MESSAGE( "run(): starting the main event loop" );
	result = _qappl.exec();

	if ( result == SUIT_Session::FROM_GUI ) // desktop is closed by user from GUI
	  break;
      }

      delete aGUISession;
      aGUISession = 0;

      // Prepare _GUIMutex for a new GUI activation
      _GUIMutex.lock();
    }
  }

  if ( myServerLauncher )
    myServerLauncher->KillAll(); // kill embedded servers

  delete aGUISession;
  delete guiThread;
  delete myServerLauncher;
  delete _NS;

  LocalTraceBufferPool *bp1 = LocalTraceBufferPool::instance();
  LocalTraceBufferPool::deleteInstance(bp1);

  return result;
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////////
// This file is part of EasyRPG.
//
// EasyRPG is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// EasyRPG 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 EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#ifdef _WIN32
#  include <cstdio>
#  define WIN32_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#else
#  include <iconv.h>
#endif

#include <cstdlib>
#include <cstring>
#include <sstream>

#include "inireader.h"
#include "reader_util.h"

////////////////////////////////////////////////////////////
namespace ReaderUtil {
}

////////////////////////////////////////////////////////////
std::string ReaderUtil::CodepageToIconv(int codepage) {
	if (codepage == 0)
		return "";

	std::ostringstream out;
	out << "CP" << codepage;
	return out.str();
}

////////////////////////////////////////////////////////////
std::string ReaderUtil::GetEncoding() {
	INIReader ini("RPG_RT.ini");
	if (ini.ParseError() != -1) {
#if defined(GEKKO) || defined(PSP)
		std::string default_enc = "1252";
#else
		std::string default_enc = "";
#endif
		std::string encoding = ini.Get("EasyRpg", "Encoding", default_enc);

		if (!encoding.empty()) {
#ifdef _WIN32
			int codepage = atoi(encoding.c_str());
			if (codepage > 0) {
				// Looks like a valid codepage
				return encoding.c_str();
			}
#else
			std::string iconv_str = CodepageToIconv(atoi(encoding.c_str()));
			// Check at first if the ini value is a codepage
			if (!iconv_str.empty()) {
				// Looks like a valid codepage
				return iconv_str;
			}
#endif
		}
	}
	return "";
}

////////////////////////////////////////////////////////////
std::string ReaderUtil::Recode(const std::string& str_to_encode,
							   const std::string& src_enc,
							   const std::string& dst_enc) {
#ifdef _WIN32
	size_t strsize = str_to_encode.size();

	wchar_t* widechar = new wchar_t[strsize * 5 + 1];

	// To Utf16
	// Default codepage is 0, so we dont need a check here
	int res = MultiByteToWideChar(atoi(src_enc.c_str()), 0, str_to_encode.c_str(), strsize, widechar, strsize * 5 + 1);
	if (res == 0) {
		// Invalid codepage
		delete [] widechar;
		return str_to_encode;
	}
	widechar[res] = '\0';

	// Back to Utf8 ...
	char* utf8char = new char[strsize * 5 + 1];
	res = WideCharToMultiByte(atoi(dst_enc.c_str()), 0, widechar, res, utf8char, strsize * 5 + 1, NULL, NULL);
	utf8char[res] = '\0';

	// Result in str
	std::string str = std::string(utf8char, res);

	delete [] widechar;
	delete [] utf8char;

	return str;
#else
	iconv_t cd = iconv_open(dst_enc.c_str(), src_enc.c_str());
	if (cd == (iconv_t)-1)
		return str_to_encode;
	char *src = const_cast<char *>(str_to_encode.c_str());
	size_t src_left = str_to_encode.size();
	size_t dst_size = str_to_encode.size() * 5 + 10;
	char *dst = new char[dst_size];
	size_t dst_left = dst_size;
#  if defined(PSP) && defined(_LIBICONV_H)
	char const *p = src;
#  else
	char *p = src;
#  endif
	char *q = dst;
	size_t status = iconv(cd, &p, &src_left, &q, &dst_left);
	iconv_close(cd);
	if (status == (size_t) -1 || src_left > 0) {
		delete[] dst;
		return "";
	}
	*q++ = '\0';
	std::string result(dst);
	delete[] dst;
	return result;
#endif
}

<commit_msg>fix iconv()'s second argument type<commit_after>/////////////////////////////////////////////////////////////////////////////
// This file is part of EasyRPG.
//
// EasyRPG is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// EasyRPG 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 EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#ifdef _WIN32
#  include <cstdio>
#  define WIN32_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#else
#  include <iconv.h>
#endif

#include <cstdlib>
#include <cstring>
#include <sstream>
#include <vector>

#include "inireader.h"
#include "reader_util.h"

#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/remove_pointer.hpp>

////////////////////////////////////////////////////////////
namespace ReaderUtil {
}

////////////////////////////////////////////////////////////
std::string ReaderUtil::CodepageToIconv(int codepage) {
	if (codepage == 0)
		return "";

	std::ostringstream out;
	out << "CP" << codepage;
	return out.str();
}

////////////////////////////////////////////////////////////
std::string ReaderUtil::GetEncoding() {
	INIReader ini("RPG_RT.ini");
	if (ini.ParseError() != -1) {
#if defined(GEKKO) || defined(PSP)
		std::string default_enc = "1252";
#else
		std::string default_enc = "";
#endif
		std::string encoding = ini.Get("EasyRpg", "Encoding", default_enc);

		if (!encoding.empty()) {
#ifdef _WIN32
			int codepage = atoi(encoding.c_str());
			if (codepage > 0) {
				// Looks like a valid codepage
				return encoding.c_str();
			}
#else
			std::string iconv_str = CodepageToIconv(atoi(encoding.c_str()));
			// Check at first if the ini value is a codepage
			if (!iconv_str.empty()) {
				// Looks like a valid codepage
				return iconv_str;
			}
#endif
		}
	}
	return "";
}

////////////////////////////////////////////////////////////
#ifndef _WIN32
template<class F>
static std::string RunIconv(const std::string& str_to_encode,
                            const std::string& src_enc,
                            const std::string& dst_enc,
                            F const iconv_func) {
	iconv_t cd = iconv_open(dst_enc.c_str(), src_enc.c_str());
	if (cd == (iconv_t)-1) {
    return "";
  }

	size_t src_left = str_to_encode.size();
  std::vector<char> dst(str_to_encode.size() * 5 + 10);
	size_t dst_left = dst.size();

  typedef typename boost::remove_pointer<
    typename boost::function_traits<
      typename boost::remove_pointer<F>::type
      >::arg2_type
    >::type src_type;
  src_type p = (src_type)str_to_encode.c_str();
	char *q = &dst.front();

	size_t status = iconv_func(cd, &p, &src_left, &q, &dst_left);
	iconv_close(cd);
	if (status == (size_t) -1 || src_left > 0) {
		return "";
	}
	*q++ = '\0';
	return std::string(&dst.front());
}
#endif // not _WIN32

////////////////////////////////////////////////////////////
std::string ReaderUtil::Recode(const std::string& str_to_encode,
							   const std::string& src_enc,
							   const std::string& dst_enc) {
#ifdef _WIN32
	size_t strsize = str_to_encode.size();

	wchar_t* widechar = new wchar_t[strsize * 5 + 1];

	// To Utf16
	// Default codepage is 0, so we dont need a check here
	int res = MultiByteToWideChar(atoi(src_enc.c_str()), 0, str_to_encode.c_str(), strsize, widechar, strsize * 5 + 1);
	if (res == 0) {
		// Invalid codepage
		delete [] widechar;
		return str_to_encode;
	}
	widechar[res] = '\0';

	// Back to Utf8 ...
	char* utf8char = new char[strsize * 5 + 1];
	res = WideCharToMultiByte(atoi(dst_enc.c_str()), 0, widechar, res, utf8char, strsize * 5 + 1, NULL, NULL);
	utf8char[res] = '\0';

	// Result in str
	std::string str = std::string(utf8char, res);

	delete [] widechar;
	delete [] utf8char;

	return str;
#else
  return RunIconv(str_to_encode, src_enc, dst_enc, &::iconv);
#endif
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include "libxtreemfs/interrupt.h"

#include <boost/date_time.hpp>

namespace xtreemfs
{

  Interruptibilizer::query_function Interruptibilizer::f_ = NULL;

  void
  Interruptibilizer::Initialize(query_function f)
  {
    f_ = f;
  }

  bool
  Interruptibilizer::WasInterrupted()
  {
    return (f_ == NULL) ? false : static_cast<bool>(f_()); // TODO: NULL check still needed and usefull?
  }

  void
  Interruptibilizer::SleepInterruptible(int rel_time_in_ms)
  {
    assert(rel_time_in_ms >= 0);
    const int intervall_in_ms = 100;
    int runs = rel_time_in_ms / intervall_in_ms
        + ((rel_time_in_ms % intervall_in_ms) > 0 ? 1 : 0);

    for (int i = 0; i < runs && !Interruptibilizer::WasInterrupted(); ++i)
      {
        boost::this_thread::sleep(boost::posix_time::millisec(intervall_in_ms));
      }
  }

} // namespace xtreemfs
<commit_msg>client: Fix compilation error by including a more specific header file.<commit_after>/*
 * Copyright (c) 2012 by Matthias Noack, Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

#include "libxtreemfs/interrupt.h"

#include <boost/date_time/posix_time/posix_time_types.hpp>

namespace xtreemfs
{

  Interruptibilizer::query_function Interruptibilizer::f_ = NULL;

  void
  Interruptibilizer::Initialize(query_function f)
  {
    f_ = f;
  }

  bool
  Interruptibilizer::WasInterrupted()
  {
    return (f_ == NULL) ? false : static_cast<bool>(f_()); // TODO: NULL check still needed and usefull?
  }

  void
  Interruptibilizer::SleepInterruptible(int rel_time_in_ms)
  {
    assert(rel_time_in_ms >= 0);
    const int intervall_in_ms = 100;
    int runs = rel_time_in_ms / intervall_in_ms
        + ((rel_time_in_ms % intervall_in_ms) > 0 ? 1 : 0);

    for (int i = 0; i < runs && !Interruptibilizer::WasInterrupted(); ++i)
      {
        boost::this_thread::sleep(boost::posix_time::millisec(intervall_in_ms));
      }
  }

} // namespace xtreemfs
<|endoftext|>