<commit_before>/*
 * File:   TopologyOracle.hpp
 * Author: manuhalo
 *
 * Created on 25 giugno 2012, 10.36
 */

#ifndef TOPOLOGYORACLE_HPP
#define	TOPOLOGYORACLE_HPP

#include "Topology.hpp"
#include "SimTimeInterval.hpp"
#include "zipf_distribution.hpp"
#include <fstream>
#include "Cache.hpp"

// % of requests taking places at a give hour, starting from midnight
const double usrPctgByHour[] = {
  4, 2, 1.5, 1.5, 1, 0.5, 0.5, 1, 1, 1.5, 2, 2.5, 3, 4, 4.5, 4.5, 4, 4, 4, 6, 12, 15, 12, 8
//0  1   2    3   4   5    6   7  8   9   10  11 12 13  14   15  16 17 18 19  20  21  22  23
};
// weight of the days of the week when determining request scheduling (M->S)
const double dayWeights[] = {0.8, 0.9, 1, 0.8, 1.2, 1.3, 1.2};
//                            M    T   W   T    F    S    S

const double sessionLength[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
        1, 1, 1, 1, 1, 1, 1, 1}; // 50% linear zapping, 50% entire content

/* Switching to a linear session length, this will no longer be used
// average session length (percentage) for the 0-25% quartile (most popular)
const double sessionLength1Q[] = {0.18, 0.20, 0.23, 0.27, 0.30, 0.32, 0.39, 0.48, 0.57, 0.70};

// average session length (percentage) for the 25-50% quartile
const double sessionLength2Q[] = {0.19, 0.21, 0.29, 0.33, 0.36, 0.45, 0.54, 0.59, 0.63, 0.70};

// average session length (percentage) for the 50-75% quartile
const double sessionLength3Q[] = {0.20, 0.30, 0.35, 0.42, 0.49, 0.53, 0.57, 0.59, 0.63, 0.80};

// average session length (percentage) for the 75-100% quartile (least popular)
const double sessionLength4Q[] = {0.20, 0.30, 0.33, 0.37, 0.43, 0.49, 0.56, 0.60, 0.65, 0.81};
*/

typedef Cache<ContentElement*, Capacity, SimTime> ContentCache;
typedef std::map<ContentElement*, std::set<PonUser> > ContentMap;
typedef std::map<uint, ContentMap> AsidContentMap;
typedef std::map<PonUser, ContentCache> UserCacheMap;
typedef std::map<Vertex, ContentCache> LocalCacheMap;
typedef std::map<PonUser, SimTimeInterval*> UserViewMap;

struct FlowStats {
  std::vector<double> avgFlowDuration;
  std::vector<double> avgPeerFlowDuration;
  std::vector<double> avgCacheFlowDuration;
  std::vector<float> avgUserCacheOccupancy;
  std::vector<float> avgASCacheOccupancy;
  std::vector<uint> servedRequests;
  std::vector<uint> localRequests;
  std::vector<uint> completedRequests;
  std::vector<uint> fromASCache;
  std::vector<uint> fromPeers;
  std::vector<uint> fromCentralServer;
  std::vector<uint> congestionBlocked;
};

/* The TopologyOracle keeps track of what everyone is caching and uses that
 * information to match requesters to sources with the appropriate content.
 * Essentially it serves as a global tracker (in the BitTorrent sense).
 * We keep both a map of all the user caching a particular content (to fetch
 * potential sources quickly) and a map of what each individual user is caching
 * (to be able to simulate finite-size caching).
 */
class TopologyOracle{
protected:
  SimMode mode;   // VoD or IPTV
  uint contentNum; // # of contents in the catalog
  double avgContentLength; //average content length in minutes
  double devContentLength; // std deviation of content length
  double avgHoursPerUser; // hours of viewing per user per round
  uint bitrate; // bitrate of the encoded content in Mbps
  Topology* topo;
  AsidContentMap* asidContentMap; // keeps track of content available in each AS
  UserCacheMap* userCacheMap; // keeps track of content available at each user
  LocalCacheMap* localCacheMap; // keeps track of content available in each CDN cache
  uint ponCardinality; // users per PON
  CachePolicy policy; // cache content replacement policy
  uint maxCacheSize;
  uint maxLocCacheSize;
  FlowStats flowStats;
  bool reducedCaching; // if true, use only a single CDN in the core;
                       // if false, one CDN micro cache in each AS
  bool preCaching;  // if true, AS caches are pre-filled with popular content and never updated
  uint maxUploads;  // max number of concurrent uploads for the optimization problem
  /* the following map associates to each content the expected number of concurrent
   * uploads that the oracle expects at a given time. How to populate in a sensible
   * way is something I am still to figure out.
   */
  std::map<ContentElement*, double> contentRateMap;
public:
  TopologyOracle(Topology* topo, po::variables_map vm);
  ~TopologyOracle();
  bool serveRequest(Flow* flow, Scheduler* scheduler);
  void addToCache(PonUser user, ContentElement* content,
      Capacity sizeDownloaded, SimTime time);
  void clearUserCache();
  void clearLocalCache();
  std::set<PonUser> getSources(ContentElement* content, uint asid);
  void notifyCompletedFlow(Flow* flow, Scheduler* scheduler);
  void notifyEndRound(uint endingRound);
  // this is a hack and should be removed
  Topology* getTopology() {return topo;}
  void printStats(uint currentRound);
  void addContent(ContentElement* content);
  void removeContent(ContentElement* content);
  bool checkIfCached(PonUser user, ContentElement* content, Capacity sizeRequested);
  bool checkIfCached(Vertex lCache, ContentElement* content, Capacity sizeRequested);
  void getFromLocalCache(Vertex lCache, ContentElement* content, SimTime time);
  void removeFromCMap(ContentElement* content, PonUser user);
  /* optimizeCaching implements the optimal caching algorithm to minimize storage
   * space while keeping high level of locality, by ensuring that some minimal
   * number of replicas are always available. Replicas are determined based on
   * popularity estimation (to be implemented). the function should be called
   * before adding elements to the cache, as it determines whether or not the
   * new element is worth storing and which elements should be erased to make
   * space for it. It returns a pair of bool, the first of which tells whether
   * the optimization was successful (i.e., a valid solution was found), and the
   * second telling whether the requested element should be cached. The second
   * boolean value should only be taken into consideration if the first is true.
   */
  std::pair<bool, bool> optimizeCaching(PonUser user, ContentElement* content,
      Capacity sizeRequested);

  void takeSnapshot(SimTime time, uint round) const {
    this->topo->printTopology(time, round);
  }

  FlowStats getFlowStats() const {
    return this->flowStats;
  }
  // The next methods are virtualized so that VoD and IPTV can reimplement them

  /* generateUserViewMap() generates content requests for all the elements
   * of the catalog for the current round, then schedules those requests as flows
   * in the scheduler.
   */
  virtual void generateUserViewMap(Scheduler* scheduler) = 0;
  /* populateCatalog() instantiates the ContentElement that compose the catalog
   * and stores them in an appropriate data structure.
   */
  virtual void populateCatalog() = 0;
  /* updateCatalog() performs general maintenance on the catalog at the end of
   * a round (e.g. removing expired content, generating new one etc.)
   */
  virtual void updateCatalog(uint currentRound) = 0;
  /* generateNewRequest() is a legacy method that generates a single request for
   * a specific user. It's only used in the IPTV model and it's being kept
   * for "backward compatibility". It should be removed in the future.
   */
  virtual void generateNewRequest(PonUser user, SimTime time,
                                      Scheduler* scheduler) = 0;
  /* preCache() pushes the most popular content in the AS caches. It must be
   * ovveridden by the specialized classes as determining the most popular
   * elements of the catalog depends on the simulation mode
   */
  virtual void preCache() = 0;
};

#endif	/* TOPOLOGYORACLE_HPP */

<commit_msg>optimizeCaching() now requires the current simulation time to extrapolate the current hour for rate calculation purposes<commit_after>/*
 * File:   TopologyOracle.hpp
 * Author: manuhalo
 *
 * Created on 25 giugno 2012, 10.36
 */

#ifndef TOPOLOGYORACLE_HPP
#define	TOPOLOGYORACLE_HPP

#include "Topology.hpp"
#include "SimTimeInterval.hpp"
#include "zipf_distribution.hpp"
#include <fstream>
#include "Cache.hpp"

// % of requests taking places at a give hour, starting from midnight
const std::vector<double> usrPctgByHour = {
  4, 2, 1.5, 1.5, 1, 0.5, 0.5, 1, 1, 1.5, 2, 2.5, 3, 4, 4.5, 4.5, 4, 4, 4, 6, 12, 15, 12, 8
//0  1   2    3   4   5    6   7  8   9   10  11 12 13  14   15  16 17 18 19  20  21  22  23
};
// weight of the days of the week when determining request scheduling (M->S)
const double dayWeights[] = {0.8, 0.9, 1, 0.8, 1.2, 1.3, 1.2};
//                            M    T   W   T    F    S    S

const std::vector<double> sessionLength = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,
        1, 1, 1, 1, 1, 1, 1, 1}; // 50% linear zapping, 50% entire content

/* Switching to a linear session length, this will no longer be used
// average session length (percentage) for the 0-25% quartile (most popular)
const double sessionLength1Q[] = {0.18, 0.20, 0.23, 0.27, 0.30, 0.32, 0.39, 0.48, 0.57, 0.70};

// average session length (percentage) for the 25-50% quartile
const double sessionLength2Q[] = {0.19, 0.21, 0.29, 0.33, 0.36, 0.45, 0.54, 0.59, 0.63, 0.70};

// average session length (percentage) for the 50-75% quartile
const double sessionLength3Q[] = {0.20, 0.30, 0.35, 0.42, 0.49, 0.53, 0.57, 0.59, 0.63, 0.80};

// average session length (percentage) for the 75-100% quartile (least popular)
const double sessionLength4Q[] = {0.20, 0.30, 0.33, 0.37, 0.43, 0.49, 0.56, 0.60, 0.65, 0.81};
*/

typedef Cache<ContentElement*, Capacity, SimTime> ContentCache;
typedef std::map<ContentElement*, std::set<PonUser> > ContentMap;
typedef std::map<uint, ContentMap> AsidContentMap;
typedef std::map<PonUser, ContentCache> UserCacheMap;
typedef std::map<Vertex, ContentCache> LocalCacheMap;
typedef std::map<PonUser, SimTimeInterval*> UserViewMap;

struct FlowStats {
  std::vector<double> avgFlowDuration;
  std::vector<double> avgPeerFlowDuration;
  std::vector<double> avgCacheFlowDuration;
  std::vector<float> avgUserCacheOccupancy;
  std::vector<float> avgASCacheOccupancy;
  std::vector<uint> servedRequests;
  std::vector<uint> localRequests;
  std::vector<uint> completedRequests;
  std::vector<uint> fromASCache;
  std::vector<uint> fromPeers;
  std::vector<uint> fromCentralServer;
  std::vector<uint> congestionBlocked;
};

/* The TopologyOracle keeps track of what everyone is caching and uses that
 * information to match requesters to sources with the appropriate content.
 * Essentially it serves as a global tracker (in the BitTorrent sense).
 * We keep both a map of all the user caching a particular content (to fetch
 * potential sources quickly) and a map of what each individual user is caching
 * (to be able to simulate finite-size caching).
 */
class TopologyOracle{
protected:
  SimMode mode;   // VoD or IPTV
  uint contentNum; // # of contents in the catalog
  double avgContentLength; //average content length in minutes
  double devContentLength; // std deviation of content length
  double avgHoursPerUser; // hours of viewing per user per round
  double avgReqLength; //  derivative, but useful for the popularity estimation
  uint bitrate; // bitrate of the encoded content in Mbps
  Topology* topo;
  AsidContentMap* asidContentMap; // keeps track of content available in each AS
  UserCacheMap* userCacheMap; // keeps track of content available at each user
  LocalCacheMap* localCacheMap; // keeps track of content available in each CDN cache
  uint ponCardinality; // users per PON
  CachePolicy policy; // cache content replacement policy
  uint maxCacheSize;
  uint maxLocCacheSize;
  FlowStats flowStats;
  bool reducedCaching; // if true, use only a single CDN in the core;
                       // if false, one CDN micro cache in each AS
  bool preCaching;  // if true, AS caches are pre-filled with popular content and never updated
  uint maxUploads;  // max number of concurrent uploads for the optimization problem
  /* the following map associates to each content the expected number of concurrent
   * uploads that the oracle expects per user per day.
   */
  std::map<ContentElement*, double> contentRateMap;
public:
  TopologyOracle(Topology* topo, po::variables_map vm);
  ~TopologyOracle();
  bool serveRequest(Flow* flow, Scheduler* scheduler);
  void addToCache(PonUser user, ContentElement* content,
      Capacity sizeDownloaded, SimTime time);
  void clearUserCache();
  void clearLocalCache();
  std::set<PonUser> getSources(ContentElement* content, uint asid);
  void notifyCompletedFlow(Flow* flow, Scheduler* scheduler);
  void notifyEndRound(uint endingRound);
  // this is a hack and should be removed
  Topology* getTopology() {return topo;}
  void printStats(uint currentRound);
  void addContent(ContentElement* content);
  void removeContent(ContentElement* content);
  bool checkIfCached(PonUser user, ContentElement* content, Capacity sizeRequested);
  bool checkIfCached(Vertex lCache, ContentElement* content, Capacity sizeRequested);
  void getFromLocalCache(Vertex lCache, ContentElement* content, SimTime time);
  void removeFromCMap(ContentElement* content, PonUser user);
  /* optimizeCaching implements the optimal caching algorithm to minimize storage
   * space while keeping high level of locality, by ensuring that some minimal
   * number of replicas are always available. Replicas are determined based on
   * popularity estimation (to be implemented). the function should be called
   * before adding elements to the cache, as it determines whether or not the
   * new element is worth storing and which elements should be erased to make
   * space for it. It returns a pair of bool, the first of which tells whether
   * the optimization was successful (i.e., a valid solution was found), and the
   * second telling whether the requested element should be cached. The second
   * boolean value should only be taken into consideration if the first is true.
   */
  std::pair<bool, bool> optimizeCaching(PonUser user, ContentElement* content,
      Capacity sizeRequested, SimTime time);

  void takeSnapshot(SimTime time, uint round) const {
    this->topo->printTopology(time, round);
  }

  FlowStats getFlowStats() const {
    return this->flowStats;
  }
  // The next methods are virtualized so that VoD and IPTV can reimplement them

  /* generateUserViewMap() generates content requests for all the elements
   * of the catalog for the current round, then schedules those requests as flows
   * in the scheduler.
   */
  virtual void generateUserViewMap(Scheduler* scheduler) = 0;
  /* populateCatalog() instantiates the ContentElement that compose the catalog
   * and stores them in an appropriate data structure.
   */
  virtual void populateCatalog() = 0;
  /* updateCatalog() performs general maintenance on the catalog at the end of
   * a round (e.g. removing expired content, generating new one etc.)
   */
  virtual void updateCatalog(uint currentRound) = 0;
  /* generateNewRequest() is a legacy method that generates a single request for
   * a specific user. It's only used in the IPTV model and it's being kept
   * for "backward compatibility". It should be removed in the future.
   */
  virtual void generateNewRequest(PonUser user, SimTime time,
                                      Scheduler* scheduler) = 0;
  /* preCache() pushes the most popular content in the AS caches. It must be
   * ovveridden by the specialized classes as determining the most popular
   * elements of the catalog depends on the simulation mode
   */
  virtual void preCache() = 0;
};

#endif	/* TOPOLOGYORACLE_HPP */

<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/CQCopasiApplication.cpp,v $
//   $Revision: 1.1 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2012/02/22 16:28:45 $
// End CVS Header

// Copyright (C) 2011 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include <QFileOpenEvent>
#include <QString>

#include "CQCopasiApplication.h"
#include "copasiui3window.h"
#include "listviews.h"

CQCopasiApplication::CQCopasiApplication(int & argc, char ** argv):
    QApplication(argc, argv),
    mpMainWindow(NULL),
    mFile(),
    mStarting(true)
{}

CQCopasiApplication::~CQCopasiApplication()
{}

// virtual
bool CQCopasiApplication::event(QEvent * pEvent)
{
  switch (pEvent->type())
    {
      case QEvent::FileOpen:

        if (mStarting)
          {
            mFile = static_cast<QFileOpenEvent *>(pEvent)->file();
          }
        else
          {
            mpMainWindow->slotFileOpen(mFile);
          }

        pEvent->accept();
        return true;

        break;

      default:
        break;
    }

  return QApplication::event(pEvent);
}

void CQCopasiApplication::setMainWindow(CopasiUI3Window * pMainWindow)
{
  mpMainWindow = pMainWindow;

  processEvents();

  mpMainWindow->openInitialDocument(mFile);
  mStarting = false;
}
<commit_msg>- the file open event on mac needs to open new files (otherwise whenever another file is double clicked, the first file will be reloaded)<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/UI/CQCopasiApplication.cpp,v $
//   $Revision: 1.1 $
//   $Name:  $
//   $Author: shoops $
//   $Date: 2012/02/22 16:28:45 $
// End CVS Header

// Copyright (C) 2011 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include <QFileOpenEvent>
#include <QString>

#include "CQCopasiApplication.h"
#include "copasiui3window.h"
#include "listviews.h"

CQCopasiApplication::CQCopasiApplication(int & argc, char ** argv):
    QApplication(argc, argv),
    mpMainWindow(NULL),
    mFile(),
    mStarting(true)
{}

CQCopasiApplication::~CQCopasiApplication()
{}

// virtual
bool CQCopasiApplication::event(QEvent * pEvent)
{
  switch (pEvent->type())
    {
      case QEvent::FileOpen:

        if (mStarting)
          {
            mFile = static_cast<QFileOpenEvent *>(pEvent)->file();
          }
        else
          {
            // need to take the new file, otherwise whenever the application
            // is open we will re-open the first file that was supposed to be
            // opened.
            mFile = static_cast<QFileOpenEvent *>(pEvent)->file();
            mpMainWindow->slotFileOpen(mFile);
          }

        pEvent->accept();
        return true;

        break;

      default:
        break;
    }

  return QApplication::event(pEvent);
}

void CQCopasiApplication::setMainWindow(CopasiUI3Window * pMainWindow)
{
  mpMainWindow = pMainWindow;

  processEvents();

  mpMainWindow->openInitialDocument(mFile);
  mStarting = false;
}
<|endoftext|>


<commit_before>/*************************************************************************/
/*  translation_loader_po.cpp                                            */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "translation_loader_po.h"

#include "core/os/file_access.h"
#include "core/translation.h"

RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
	enum Status {

		STATUS_NONE,
		STATUS_READING_ID,
		STATUS_READING_STRING,
	};

	Status status = STATUS_NONE;

	String msg_id;
	String msg_str;
	String config;

	if (r_error) {
		*r_error = ERR_FILE_CORRUPT;
	}

	Ref<Translation> translation = Ref<Translation>(memnew(Translation));
	int line = 1;
	bool skip_this = false;
	bool skip_next = false;
	bool is_eof = false;

	while (!is_eof) {
		String l = f->get_line().strip_edges();
		is_eof = f->eof_reached();

		// If we reached last line and it's not a content line, break, otherwise let processing that last loop
		if (is_eof && l.empty()) {
			if (status == STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
			} else {
				break;
			}
		}

		if (l.begins_with("msgid")) {
			if (status == STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
			}

			if (msg_id != "") {
				if (!skip_this) {
					translation->add_message(msg_id, msg_str);
				}
			} else if (config == "") {
				config = msg_str;
			}

			l = l.substr(5, l.length()).strip_edges();
			status = STATUS_READING_ID;
			msg_id = "";
			msg_str = "";
			skip_this = skip_next;
			skip_next = false;
		}

		if (l.begins_with("msgstr")) {
			if (status != STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
			}

			l = l.substr(6, l.length()).strip_edges();
			status = STATUS_READING_STRING;
		}

		if (l == "" || l.begins_with("#")) {
			if (l.find("fuzzy") != -1) {
				skip_next = true;
			}
			line++;
			continue; //nothing to read or comment
		}

		ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), f->get_path() + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");

		l = l.substr(1, l.length());
		// Find final quote, ignoring escaped ones (\").
		// The escape_next logic is necessary to properly parse things like \\"
		// where the blackslash is the one being escaped, not the quote.
		int end_pos = -1;
		bool escape_next = false;
		for (int i = 0; i < l.length(); i++) {
			if (l[i] == '\\' && !escape_next) {
				escape_next = true;
				continue;
			}

			if (l[i] == '"' && !escape_next) {
				end_pos = i;
				break;
			}

			escape_next = false;
		}

		ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), f->get_path() + ":" + itos(line) + ": Expected '\"' at end of message while parsing file.");

		l = l.substr(0, end_pos);
		l = l.c_unescape();

		if (status == STATUS_READING_ID) {
			msg_id += l;
		} else {
			msg_str += l;
		}

		line++;
	}

	f->close();
	memdelete(f);

	if (status == STATUS_READING_STRING) {
		if (msg_id != "") {
			if (!skip_this) {
				translation->add_message(msg_id, msg_str);
			}
		} else if (config == "") {
			config = msg_str;
		}
	}

	ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + f->get_path() + ".");

	Vector<String> configs = config.split("\n");
	for (int i = 0; i < configs.size(); i++) {
		String c = configs[i].strip_edges();
		int p = c.find(":");
		if (p == -1) {
			continue;
		}
		String prop = c.substr(0, p).strip_edges();
		String value = c.substr(p + 1, c.length()).strip_edges();

		if (prop == "X-Language" || prop == "Language") {
			translation->set_locale(value);
		}
	}

	if (r_error) {
		*r_error = OK;
	}

	return translation;
}

RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
	if (r_error) {
		*r_error = ERR_CANT_OPEN;
	}

	FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
	ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");

	return load_translation(f, r_error);
}

void TranslationLoaderPO::get_recognized_extensions(List<String> *p_extensions) const {
	p_extensions->push_back("po");
	//p_extensions->push_back("mo"); //mo in the future...
}

bool TranslationLoaderPO::handles_type(const String &p_type) const {
	return (p_type == "Translation");
}

String TranslationLoaderPO::get_resource_type(const String &p_path) const {
	if (p_path.get_extension().to_lower() == "po") {
		return "Translation";
	}
	return "";
}
<commit_msg>PO loader: Fix unclosed files and error messages<commit_after>/*************************************************************************/
/*  translation_loader_po.cpp                                            */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "translation_loader_po.h"

#include "core/os/file_access.h"
#include "core/translation.h"

RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
	enum Status {
		STATUS_NONE,
		STATUS_READING_ID,
		STATUS_READING_STRING,
	};

	Status status = STATUS_NONE;

	String msg_id;
	String msg_str;
	String config;

	if (r_error) {
		*r_error = ERR_FILE_CORRUPT;
	}

	Ref<Translation> translation = Ref<Translation>(memnew(Translation));
	int line = 1;
	bool skip_this = false;
	bool skip_next = false;
	bool is_eof = false;
	const String path = f->get_path();

	while (!is_eof) {
		String l = f->get_line().strip_edges();
		is_eof = f->eof_reached();

		// If we reached last line and it's not a content line, break, otherwise let processing that last loop
		if (is_eof && l.empty()) {
			if (status == STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), "Unexpected EOF while reading 'msgid' at: " + path + ":" + itos(line));
			} else {
				break;
			}
		}

		if (l.begins_with("msgid")) {
			if (status == STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line));
			}

			if (msg_id != "") {
				if (!skip_this) {
					translation->add_message(msg_id, msg_str);
				}
			} else if (config == "") {
				config = msg_str;
			}

			l = l.substr(5, l.length()).strip_edges();
			status = STATUS_READING_ID;
			msg_id = "";
			msg_str = "";
			skip_this = skip_next;
			skip_next = false;
		}

		if (l.begins_with("msgstr")) {
			if (status != STATUS_READING_ID) {
				memdelete(f);
				ERR_FAIL_V_MSG(RES(), "Unexpected 'msgstr', was expecting 'msgid' while parsing: " + path + ":" + itos(line));
			}

			l = l.substr(6, l.length()).strip_edges();
			status = STATUS_READING_STRING;
		}

		if (l == "" || l.begins_with("#")) {
			if (l.find("fuzzy") != -1) {
				skip_next = true;
			}
			line++;
			continue; //nothing to read or comment
		}

		if (!l.begins_with("\"") || status == STATUS_NONE) {
			memdelete(f);
			ERR_FAIL_V_MSG(RES(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line));
		}

		l = l.substr(1, l.length());
		// Find final quote, ignoring escaped ones (\").
		// The escape_next logic is necessary to properly parse things like \\"
		// where the blackslash is the one being escaped, not the quote.
		int end_pos = -1;
		bool escape_next = false;
		for (int i = 0; i < l.length(); i++) {
			if (l[i] == '\\' && !escape_next) {
				escape_next = true;
				continue;
			}

			if (l[i] == '"' && !escape_next) {
				end_pos = i;
				break;
			}

			escape_next = false;
		}

		if (end_pos == -1) {
			memdelete(f);
			ERR_FAIL_V_MSG(RES(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line));
		}

		l = l.substr(0, end_pos);
		l = l.c_unescape();

		if (status == STATUS_READING_ID) {
			msg_id += l;
		} else {
			msg_str += l;
		}

		line++;
	}

	memdelete(f);

	if (status == STATUS_READING_STRING) {
		if (msg_id != "") {
			if (!skip_this) {
				translation->add_message(msg_id, msg_str);
			}
		} else if (config == "") {
			config = msg_str;
		}
	}

	ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + path + ".");

	Vector<String> configs = config.split("\n");
	for (int i = 0; i < configs.size(); i++) {
		String c = configs[i].strip_edges();
		int p = c.find(":");
		if (p == -1) {
			continue;
		}
		String prop = c.substr(0, p).strip_edges();
		String value = c.substr(p + 1, c.length()).strip_edges();

		if (prop == "X-Language" || prop == "Language") {
			translation->set_locale(value);
		}
	}

	if (r_error) {
		*r_error = OK;
	}

	return translation;
}

RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
	if (r_error) {
		*r_error = ERR_CANT_OPEN;
	}

	FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
	ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");

	return load_translation(f, r_error);
}

void TranslationLoaderPO::get_recognized_extensions(List<String> *p_extensions) const {
	p_extensions->push_back("po");
}

bool TranslationLoaderPO::handles_type(const String &p_type) const {
	return (p_type == "Translation");
}

String TranslationLoaderPO::get_resource_type(const String &p_path) const {
	if (p_path.get_extension().to_lower() == "po") {
		return "Translation";
	}
	return "";
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "accumulatormap.h"
#include "accumulators.h"
#include "main.h"
#include "txdb.h"
#include "libzerocoin/Denominations.h"

using namespace libzerocoin;
using namespace std;

AccumulatorMap::AccumulatorMap()
{
    //construct accumulators for all denominations
    for (auto& denom : zerocoinDenomList) {
        unique_ptr<Accumulator> uptr(new Accumulator(Params().Zerocoin_Params(), denom));
        mapAccumulators.insert(make_pair(denom, std::move(uptr)));
    }
}

void AccumulatorMap::Reset()
{
    mapAccumulators.clear();
    for (auto& denom : zerocoinDenomList) {
        unique_ptr<Accumulator> uptr(new Accumulator(Params().Zerocoin_Params(), denom));
        mapAccumulators.insert(make_pair(denom, std::move(uptr)));
    }
}

bool AccumulatorMap::Load(uint256 nCheckpoint)
{
    for (auto& denom : zerocoinDenomList) {
        uint32_t nChecksum = ParseChecksum(nCheckpoint, denom);

        CBigNum bnValue;
        if (!zerocoinDB->ReadAccumulatorValue(nChecksum, bnValue)) {
            LogPrintf("%s : cannot find checksum %d", __func__, nChecksum);
            return false;
        }

        mapAccumulators.at(denom)->setValue(bnValue);
    }
    return true;
}

bool AccumulatorMap::Accumulate(PublicCoin pubCoin, bool fSkipValidation)
{
    CoinDenomination denom = pubCoin.getDenomination();
    if (denom == CoinDenomination::ZQ_ERROR)
        return false;

    if (fSkipValidation)
        mapAccumulators.at(denom)->increment(pubCoin.getValue());
    else
        mapAccumulators.at(denom)->accumulate(pubCoin);
    return true;
}

CBigNum AccumulatorMap::GetValue(CoinDenomination denom)
{
    if (denom == CoinDenomination::ZQ_ERROR)
        return CBigNum(0);
    return mapAccumulators.at(denom)->getValue();
}

uint256 AccumulatorMap::GetCheckpoint()
{
    uint256 nCheckpoint;

    //Prevent possible overflows from future changes to the list and forgetting to update this code
    assert(zerocoinDenomList.size() == 8);
    for (auto& denom : zerocoinDenomList) {
        CBigNum bnValue = mapAccumulators.at(denom)->getValue();
        uint32_t nCheckSum = GetChecksum(bnValue);
        nCheckpoint = nCheckpoint << 32 | nCheckSum;
    }

    return nCheckpoint;
}

<commit_msg>Add comments to accumulatormap.cpp.<commit_after>// Copyright (c) 2017 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "accumulatormap.h"
#include "accumulators.h"
#include "main.h"
#include "txdb.h"
#include "libzerocoin/Denominations.h"

using namespace libzerocoin;
using namespace std;

//Construct accumulators for all denominations
AccumulatorMap::AccumulatorMap()
{
    for (auto& denom : zerocoinDenomList) {
        unique_ptr<Accumulator> uptr(new Accumulator(Params().Zerocoin_Params(), denom));
        mapAccumulators.insert(make_pair(denom, std::move(uptr)));
    }
}

//Reset each accumulator to its default state
void AccumulatorMap::Reset()
{
    mapAccumulators.clear();
    for (auto& denom : zerocoinDenomList) {
        unique_ptr<Accumulator> uptr(new Accumulator(Params().Zerocoin_Params(), denom));
        mapAccumulators.insert(make_pair(denom, std::move(uptr)));
    }
}

//Load a checkpoint containing 8 32bit checksums of accumulator values.
bool AccumulatorMap::Load(uint256 nCheckpoint)
{
    for (auto& denom : zerocoinDenomList) {
        uint32_t nChecksum = ParseChecksum(nCheckpoint, denom);

        CBigNum bnValue;
        if (!zerocoinDB->ReadAccumulatorValue(nChecksum, bnValue)) {
            LogPrintf("%s : cannot find checksum %d", __func__, nChecksum);
            return false;
        }

        mapAccumulators.at(denom)->setValue(bnValue);
    }
    return true;
}

//Add a zerocoin to the accumulator of its denomination.
bool AccumulatorMap::Accumulate(PublicCoin pubCoin, bool fSkipValidation)
{
    CoinDenomination denom = pubCoin.getDenomination();
    if (denom == CoinDenomination::ZQ_ERROR)
        return false;

    if (fSkipValidation)
        mapAccumulators.at(denom)->increment(pubCoin.getValue());
    else
        mapAccumulators.at(denom)->accumulate(pubCoin);
    return true;
}

//Get the value of a specific accumulator
CBigNum AccumulatorMap::GetValue(CoinDenomination denom)
{
    if (denom == CoinDenomination::ZQ_ERROR)
        return CBigNum(0);
    return mapAccumulators.at(denom)->getValue();
}

//Calculate a 32bit checksum of each accumulator value. Concatenate checksums into uint256
uint256 AccumulatorMap::GetCheckpoint()
{
    uint256 nCheckpoint;

    //Prevent possible overflows from future changes to the list and forgetting to update this code
    assert(zerocoinDenomList.size() == 8);
    for (auto& denom : zerocoinDenomList) {
        CBigNum bnValue = mapAccumulators.at(denom)->getValue();
        uint32_t nCheckSum = GetChecksum(bnValue);
        nCheckpoint = nCheckpoint << 32 | nCheckSum;
    }

    return nCheckpoint;
}

<|endoftext|>


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

#include "ODDataBarReader.h"

#include "ODDataBarCommon.h"
#include "BarcodeFormat.h"
#include "Result.h"
#include "GTIN.h"
#include "TextDecoder.h"

#include <sstream>
#include <iomanip>
#include <unordered_set>

namespace ZXing::OneD {

using namespace DataBar;

DataBarReader::DataBarReader(const DecodeHints&) {}
DataBarReader::~DataBarReader() = default;

static bool IsCharacterPair(PatternView v, int modsLeft, int modsRight)
{
	float modSizeRef = ModSizeFinder(v);
	return IsCharacter(LeftChar(v), modsLeft, modSizeRef) && IsCharacter(RightChar(v), modsRight, modSizeRef);
}

static bool IsLeftPair(const PatternView& v)
{
	return IsFinder(v[8], v[9], v[10], v[11], v[12]) && IsGuard(v[-1], v[11]) && IsCharacterPair(v, 16, 15);
}

static bool IsRightPair(const PatternView& v)
{
	return IsFinder(v[12], v[11], v[10], v[9], v[8]) && IsGuard(v[9], v[21]) && IsCharacterPair(v, 15, 16);
}

static Character ReadDataCharacter(const PatternView& view, bool outsideChar, bool rightPair)
{
	constexpr int OUTSIDE_EVEN_TOTAL_SUBSET[] = {1, 10, 34, 70, 126};
	constexpr int INSIDE_ODD_TOTAL_SUBSET[]   = {4, 20, 48, 81};
	constexpr int OUTSIDE_GSUM[]              = {0, 161, 961, 2015, 2715};
	constexpr int INSIDE_GSUM[]               = {0, 336, 1036, 1516};
	constexpr int OUTSIDE_ODD_WIDEST[]        = {8, 6, 4, 3, 1};
	constexpr int INSIDE_ODD_WIDEST[]         = {2, 4, 6, 8};

	Array4I oddPattern = {}, evnPattern = {};
	if (!ReadDataCharacterRaw(view, outsideChar ? 16 : 15, outsideChar == rightPair, oddPattern, evnPattern))
		return {};

	auto calcChecksumPortion = [](const Array4I& counts) {
		int res = 0;
		for (auto it = counts.rbegin(); it != counts.rend(); ++it)
			res = 9 * res + *it;
		return res;
	};

	int checksumPortion = calcChecksumPortion(oddPattern) + 3 * calcChecksumPortion(evnPattern);

	if (outsideChar) {
		int oddSum = Reduce(oddPattern);
		assert((oddSum & 1) == 0 && oddSum <= 12 && oddSum >= 4); // checked in ReadDataCharacterRaw
		int group = (12 - oddSum) / 2;
		int oddWidest = OUTSIDE_ODD_WIDEST[group];
		int evnWidest = 9 - oddWidest;
		int vOdd = GetValue(oddPattern, oddWidest, false);
		int vEvn = GetValue(evnPattern, evnWidest, true);
		int tEvn = OUTSIDE_EVEN_TOTAL_SUBSET[group];
		int gSum = OUTSIDE_GSUM[group];
		return {vOdd * tEvn + vEvn + gSum, checksumPortion};
	} else {
		int evnSum = Reduce(evnPattern);
		assert((evnSum & 1) == 0 && evnSum <= 12 && evnSum >= 4); // checked in ReadDataCharacterRaw
		int group = (10 - evnSum) / 2;
		int oddWidest = INSIDE_ODD_WIDEST[group];
		int evnWidest = 9 - oddWidest;
		int vOdd = GetValue(oddPattern, oddWidest, true);
		int vEvn = GetValue(evnPattern, evnWidest, false);
		int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];
		int gSum = INSIDE_GSUM[group];
		return {vEvn * tOdd + vOdd + gSum, checksumPortion};
	}
}

int ParseFinderPattern(const PatternView& view, bool reversed)
{
	static constexpr std::array<FixedPattern<5, 15>, 10> FINDER_PATTERNS = {{
		{3, 8, 2, 1, 1},
		{3, 5, 5, 1, 1},
		{3, 3, 7, 1, 1},
		{3, 1, 9, 1, 1},
		{2, 7, 4, 1, 1},
		{2, 5, 6, 1, 1},
		{2, 3, 8, 1, 1},
		{1, 5, 7, 1, 1},
		{1, 3, 9, 1, 1},
	}};

	// TODO: c++20 constexpr inversion from FIND_PATTERN?
	static constexpr std::array<FixedPattern<5, 15>, 10> REVERSED_FINDER_PATTERNS = {{
		{1, 1, 2, 8, 3}, {1, 1, 5, 5, 3}, {1, 1, 7, 3, 3}, {1, 1, 9, 1, 3}, {1, 1, 4, 7, 2},
		{1, 1, 6, 5, 2}, {1, 1, 8, 3, 2}, {1, 1, 7, 5, 1}, {1, 1, 9, 3, 1},
	}};

	return ParseFinderPattern(view, reversed, FINDER_PATTERNS, REVERSED_FINDER_PATTERNS);
}

static Pair ReadPair(const PatternView& view, bool rightPair)
{
	if (int pattern = ParseFinderPattern(Finder(view), rightPair))
		if (auto outside = ReadDataCharacter(rightPair ? RightChar(view) : LeftChar(view), true, rightPair))
			if (auto inside = ReadDataCharacter(rightPair ? LeftChar(view) : RightChar(view), false, rightPair)) {
				// include left and right guards
				int xStart = view.pixelsInFront() - (rightPair ? 0 : view[-1] + std::min(view[-2], view[-1]));
				int xStop  = view.pixelsTillEnd() + (rightPair ? view[FULL_PAIR_SIZE] + view[FULL_PAIR_SIZE + 1] : 0);
				return {outside, inside, pattern, xStart, xStop};
			}

	return {};
}

static bool ChecksumIsValid(Pair leftPair, Pair rightPair)
{
	auto checksum = [](Pair p) { return p.left.checksum + 4 * p.right.checksum; };
	int a = (checksum(leftPair) + 16 * checksum(rightPair)) % 79;
	int b = 9 * (std::abs(leftPair.finder) - 1) + (std::abs(rightPair.finder) - 1);
	if (b > 72)
		b--;
	if (b > 8)
		b--;
	return a == b;
}

static std::string ConstructText(Pair leftPair, Pair rightPair)
{
	auto value = [](Pair p) { return 1597 * p.left.value + p.right.value; };
	auto res = 4537077LL * value(leftPair) + value(rightPair);
	std::ostringstream txt;
	txt << std::setw(13) << std::setfill('0') << res;
	txt << GTIN::ComputeCheckDigit(txt.str());
	return txt.str();
}

struct State : public RowReader::DecodingState
{
	std::unordered_set<Pair, PairHash> leftPairs;
	std::unordered_set<Pair, PairHash> rightPairs;
};

Result DataBarReader::decodePattern(int rowNumber, const PatternView& view,
									std::unique_ptr<RowReader::DecodingState>& state) const
{
#if 0 // non-stacked version
	auto next = view.subView(-1, PAIR_SIZE);
	// yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern)
	while (next.shift(2)) {
		if (IsLeftPair(next)) {
			if (auto leftPair = ReadPair(next, false); leftPair && next.skipSymbol() && IsRightPair(next)) {
				if (auto rightPair = ReadPair(next, true); rightPair && CheckChecksum(leftPair, rightPair)) {
					return {ConstructText(leftPair, rightPair), rowNumber, leftPair.xStart, rightPair.xStop,
							BarcodeFormat::DataBar};
				}
			}
		}
	}
#else
	if (!state)
		state.reset(new State);
	auto* prevState = static_cast<State*>(state.get());

	auto next = view.subView(0, FULL_PAIR_SIZE + 2); // +2 reflects the guard pattern on the right
	// yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern)
	while (next.shift(1)) {
		if (IsLeftPair(next)) {
			if (auto leftPair = ReadPair(next, false)) {
				leftPair.y = rowNumber;
				prevState->leftPairs.insert(leftPair);
				next.shift(FULL_PAIR_SIZE - 1);
			}
		}

		if (next.shift(1) && IsRightPair(next)) {
			if (auto rightPair = ReadPair(next, true)) {
				rightPair.y = rowNumber;
				prevState->rightPairs.insert(rightPair);
			}
		}
	}

	for (const auto& leftPair : prevState->leftPairs)
		for (const auto& rightPair : prevState->rightPairs)
			if (ChecksumIsValid(leftPair, rightPair))
				return {TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)),
						EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar};
#endif

	return Result(DecodeStatus::NotFound);
}

} // namespace ZXing::OneD
<commit_msg>DataBar: add recent out-of-bounds fix also to disabled non-stacked codepath<commit_after>/*
* Copyright 2016 Nu-book Inc.
* Copyright 2016 ZXing authors
* Copyright 2020 Axel Waggershauser
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "ODDataBarReader.h"

#include "ODDataBarCommon.h"
#include "BarcodeFormat.h"
#include "Result.h"
#include "GTIN.h"
#include "TextDecoder.h"

#include <sstream>
#include <iomanip>
#include <unordered_set>

namespace ZXing::OneD {

using namespace DataBar;

DataBarReader::DataBarReader(const DecodeHints&) {}
DataBarReader::~DataBarReader() = default;

static bool IsCharacterPair(PatternView v, int modsLeft, int modsRight)
{
	float modSizeRef = ModSizeFinder(v);
	return IsCharacter(LeftChar(v), modsLeft, modSizeRef) && IsCharacter(RightChar(v), modsRight, modSizeRef);
}

static bool IsLeftPair(const PatternView& v)
{
	return IsFinder(v[8], v[9], v[10], v[11], v[12]) && IsGuard(v[-1], v[11]) && IsCharacterPair(v, 16, 15);
}

static bool IsRightPair(const PatternView& v)
{
	return IsFinder(v[12], v[11], v[10], v[9], v[8]) && IsGuard(v[9], v[21]) && IsCharacterPair(v, 15, 16);
}

static Character ReadDataCharacter(const PatternView& view, bool outsideChar, bool rightPair)
{
	constexpr int OUTSIDE_EVEN_TOTAL_SUBSET[] = {1, 10, 34, 70, 126};
	constexpr int INSIDE_ODD_TOTAL_SUBSET[]   = {4, 20, 48, 81};
	constexpr int OUTSIDE_GSUM[]              = {0, 161, 961, 2015, 2715};
	constexpr int INSIDE_GSUM[]               = {0, 336, 1036, 1516};
	constexpr int OUTSIDE_ODD_WIDEST[]        = {8, 6, 4, 3, 1};
	constexpr int INSIDE_ODD_WIDEST[]         = {2, 4, 6, 8};

	Array4I oddPattern = {}, evnPattern = {};
	if (!ReadDataCharacterRaw(view, outsideChar ? 16 : 15, outsideChar == rightPair, oddPattern, evnPattern))
		return {};

	auto calcChecksumPortion = [](const Array4I& counts) {
		int res = 0;
		for (auto it = counts.rbegin(); it != counts.rend(); ++it)
			res = 9 * res + *it;
		return res;
	};

	int checksumPortion = calcChecksumPortion(oddPattern) + 3 * calcChecksumPortion(evnPattern);

	if (outsideChar) {
		int oddSum = Reduce(oddPattern);
		assert((oddSum & 1) == 0 && oddSum <= 12 && oddSum >= 4); // checked in ReadDataCharacterRaw
		int group = (12 - oddSum) / 2;
		int oddWidest = OUTSIDE_ODD_WIDEST[group];
		int evnWidest = 9 - oddWidest;
		int vOdd = GetValue(oddPattern, oddWidest, false);
		int vEvn = GetValue(evnPattern, evnWidest, true);
		int tEvn = OUTSIDE_EVEN_TOTAL_SUBSET[group];
		int gSum = OUTSIDE_GSUM[group];
		return {vOdd * tEvn + vEvn + gSum, checksumPortion};
	} else {
		int evnSum = Reduce(evnPattern);
		assert((evnSum & 1) == 0 && evnSum <= 12 && evnSum >= 4); // checked in ReadDataCharacterRaw
		int group = (10 - evnSum) / 2;
		int oddWidest = INSIDE_ODD_WIDEST[group];
		int evnWidest = 9 - oddWidest;
		int vOdd = GetValue(oddPattern, oddWidest, true);
		int vEvn = GetValue(evnPattern, evnWidest, false);
		int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];
		int gSum = INSIDE_GSUM[group];
		return {vEvn * tOdd + vOdd + gSum, checksumPortion};
	}
}

int ParseFinderPattern(const PatternView& view, bool reversed)
{
	static constexpr std::array<FixedPattern<5, 15>, 10> FINDER_PATTERNS = {{
		{3, 8, 2, 1, 1},
		{3, 5, 5, 1, 1},
		{3, 3, 7, 1, 1},
		{3, 1, 9, 1, 1},
		{2, 7, 4, 1, 1},
		{2, 5, 6, 1, 1},
		{2, 3, 8, 1, 1},
		{1, 5, 7, 1, 1},
		{1, 3, 9, 1, 1},
	}};

	// TODO: c++20 constexpr inversion from FIND_PATTERN?
	static constexpr std::array<FixedPattern<5, 15>, 10> REVERSED_FINDER_PATTERNS = {{
		{1, 1, 2, 8, 3}, {1, 1, 5, 5, 3}, {1, 1, 7, 3, 3}, {1, 1, 9, 1, 3}, {1, 1, 4, 7, 2},
		{1, 1, 6, 5, 2}, {1, 1, 8, 3, 2}, {1, 1, 7, 5, 1}, {1, 1, 9, 3, 1},
	}};

	return ParseFinderPattern(view, reversed, FINDER_PATTERNS, REVERSED_FINDER_PATTERNS);
}

static Pair ReadPair(const PatternView& view, bool rightPair)
{
	if (int pattern = ParseFinderPattern(Finder(view), rightPair))
		if (auto outside = ReadDataCharacter(rightPair ? RightChar(view) : LeftChar(view), true, rightPair))
			if (auto inside = ReadDataCharacter(rightPair ? LeftChar(view) : RightChar(view), false, rightPair)) {
				// include left and right guards
				int xStart = view.pixelsInFront() - (rightPair ? 0 : view[-1] + std::min(view[-2], view[-1]));
				int xStop  = view.pixelsTillEnd() + (rightPair ? view[FULL_PAIR_SIZE] + view[FULL_PAIR_SIZE + 1] : 0);
				return {outside, inside, pattern, xStart, xStop};
			}

	return {};
}

static bool ChecksumIsValid(Pair leftPair, Pair rightPair)
{
	auto checksum = [](Pair p) { return p.left.checksum + 4 * p.right.checksum; };
	int a = (checksum(leftPair) + 16 * checksum(rightPair)) % 79;
	int b = 9 * (std::abs(leftPair.finder) - 1) + (std::abs(rightPair.finder) - 1);
	if (b > 72)
		b--;
	if (b > 8)
		b--;
	return a == b;
}

static std::string ConstructText(Pair leftPair, Pair rightPair)
{
	auto value = [](Pair p) { return 1597 * p.left.value + p.right.value; };
	auto res = 4537077LL * value(leftPair) + value(rightPair);
	std::ostringstream txt;
	txt << std::setw(13) << std::setfill('0') << res;
	txt << GTIN::ComputeCheckDigit(txt.str());
	return txt.str();
}

struct State : public RowReader::DecodingState
{
	std::unordered_set<Pair, PairHash> leftPairs;
	std::unordered_set<Pair, PairHash> rightPairs;
};

Result DataBarReader::decodePattern(int rowNumber, const PatternView& view,
									std::unique_ptr<RowReader::DecodingState>& state) const
{
#if 0 // non-stacked version
	auto next = view.subView(-1, FULL_PAIR_SIZE + 2);
	// yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern)
	while (next.shift(2)) {
		if (IsLeftPair(next)) {
			if (auto leftPair = ReadPair(next, false); leftPair && next.shift(FULL_PAIR_SIZE) && IsRightPair(next)) {
				if (auto rightPair = ReadPair(next, true); rightPair && ChecksumIsValid(leftPair, rightPair)) {
					return {ConstructText(leftPair, rightPair), rowNumber, leftPair.xStart, rightPair.xStop,
							BarcodeFormat::DataBar};
				}
			}
		}
	}
#else
	if (!state)
		state.reset(new State);
	auto* prevState = static_cast<State*>(state.get());

	auto next = view.subView(0, FULL_PAIR_SIZE + 2); // +2 reflects the guard pattern on the right
	// yes: the first view we test is at index 1 (black bar at 0 would be the guard pattern)
	while (next.shift(1)) {
		if (IsLeftPair(next)) {
			if (auto leftPair = ReadPair(next, false)) {
				leftPair.y = rowNumber;
				prevState->leftPairs.insert(leftPair);
				next.shift(FULL_PAIR_SIZE - 1);
			}
		}

		if (next.shift(1) && IsRightPair(next)) {
			if (auto rightPair = ReadPair(next, true)) {
				rightPair.y = rowNumber;
				prevState->rightPairs.insert(rightPair);
			}
		}
	}

	for (const auto& leftPair : prevState->leftPairs)
		for (const auto& rightPair : prevState->rightPairs)
			if (ChecksumIsValid(leftPair, rightPair))
				return {TextDecoder::FromLatin1(ConstructText(leftPair, rightPair)),
						EstimatePosition(leftPair, rightPair), BarcodeFormat::DataBar};
#endif

	return Result(DecodeStatus::NotFound);
}

} // namespace ZXing::OneD
<|endoftext|>


<commit_before>#ifdef WIN32
	#include <intrin.h>
	#include <windows.h>
#endif
#include "glresource.hpp"
#include "event.hpp"

#if !defined(WIN32) && !defined(ANDROID)
	#include <GL/glx.h>
	#include "glxext.h"
#endif

namespace rs {
	namespace {
		bool g_bglfuncInit = false;
	}
	#define GLGETPROC(name) SDL_GL_GetProcAddress(BOOST_PP_STRINGIZE(name))
	#if defined(_WIN32)
		namespace {
			using SetSwapInterval_t = bool APIENTRY (*)(int);
			SetSwapInterval_t g_setswapinterval = nullptr;
		}
		void LoadGLAux() {
			g_setswapinterval = (SetSwapInterval_t)GLGETPROC(wglSwapIntervalEXT);
		}
	#else
		namespace {
			#ifdef __ANDROID__
				using SetSwapInterval_t = void GL_APIENTRY (*)(int);
			#else
				using SetSwapInterval_t = void APIENTRY (*)(int);
			#endif
			SetSwapInterval_t g_setswapinterval = nullptr;
		}
		void LoadGLAux() {
			// EXTかSGIのどちらかが存在する事を期待
			try {
				g_setswapinterval = (SetSwapInterval_t)GLGETPROC(glXSwapIntervalSGI);
			} catch(const std::runtime_error& e) {
				g_setswapinterval = (SetSwapInterval_t)GLGETPROC(glXSwapIntervalEXT);
			}
		}
	#endif
	bool GLWrap::isGLFuncLoaded() {
		return g_bglfuncInit;
	}
	void IGL_Draw::setSwapInterval(int n) {
		g_setswapinterval(n);
	}
	void IGL_OtherSingle::setSwapInterval(int n) {
		GLW.getDrawHandler().postExec([=](){
			IGL_Draw().setSwapInterval(n);
		});
	}

	// OpenGL関数ロード
	// FuncNameで読み込めなければFuncNameARBとFuncNameEXTで試す
	#define GLDEFINE(...)
	#define DEF_GLMETHOD(ret_type, num, name, args, argnames) \
		GLWrap::name = nullptr; \
		GLWrap::name = (typename GLWrap::t_##name) GLGETPROC(name); \
		if(GLWrap::name == nullptr) GLWrap::name = (typename GLWrap::t_##name)GLGETPROC(BOOST_PP_CAT(name,ARB)); \
		if(GLWrap::name == nullptr) GLWrap::name = (typename GLWrap::t_##name)GLGETPROC(BOOST_PP_CAT(name,EXT)); \
		Assert(Warn, GLWrap::name != nullptr, "could not load OpenGL function: %1%", #name)
		void GLWrap::loadGLFunc() {
			// 各種API関数
			#ifndef ANDROID
				#ifdef ANDROID
					#include "android_gl.inc"
				#elif defined(WIN32)
					#include "mingw_gl.inc"
				#else
					#include "linux_gl.inc"
				#endif
			#endif
			// その他OS依存なAPI関数
			LoadGLAux();
			g_bglfuncInit = true;
		}
	#undef DEF_GLMETHOD
	#undef GLDEFINE
	// ---------------------- GLShader ----------------------
	void GLShader::_initShader() {
		_idSh = GL.glCreateShader(c_glShFlag[_flag]);

		const auto* pStr = _source.c_str();
		GL.glShaderSource(_idSh, 1, &pStr, nullptr);
		GL.glCompileShader(_idSh);

		// エラーが無かったか確認
		GLint compiled;
		GL.glGetShaderiv(_idSh, GL_COMPILE_STATUS, &compiled);
		AssertT(Throw, compiled==GL_TRUE, (GLE_ShaderError)(const std::string&)(GLuint), _source, _idSh)
	}

	GLShader::GLShader() {}
	GLShader::GLShader(ShType flag, const std::string& src): _idSh(0), _flag(flag), _source(src) {
		_initShader();
	}
	GLShader::~GLShader() {
		onDeviceLost();
	}
	bool GLShader::isEmpty() const {
		return _source.empty();
	}
	int GLShader::getShaderID() const {
		return _idSh;
	}
	void GLShader::onDeviceLost() {
		if(_idSh!=0) {
			GL.glDeleteShader(_idSh);
			_idSh = 0;
		}
	}
	void GLShader::onDeviceReset() {
		if(!isEmpty() && _idSh==0)
			_initShader();
	}
	ShType GLShader::getShaderType() const {
		return _flag;
	}

	// ---------------------- draw::Program ----------------------
	namespace draw {
		Program::Program(HProg hProg):
			Token(hProg), _idProg(hProg.ref()->getProgramID()) {}
		void Program::exec() {
			GL.glUseProgram(_idProg);
		}
	}

	// ---------------------- GLProgram ----------------------
	void GLProgram::_setShader(HSh hSh) {
		if(hSh)
			_shader[hSh.ref()->getShaderType()] = hSh;
	}
	void GLProgram::_initProgram() {
		_idProg = GL.glCreateProgram();
		for(int i=0 ; i<static_cast<int>(ShType::NUM_SHTYPE) ; i++) {
			auto& sh = _shader[i];
			// Geometryシェーダー以外は必須
			if(sh.valid()) {
				GL.glAttachShader(_idProg, sh.cref()->getShaderID());
				GLEC_ChkP(Trap)
			} else {
				AssertT(Trap, i==ShType::GEOMETRY, (GLE_Error)(const char*), "missing shader elements (vertex or fragment)")
			}
		}

		GL.glLinkProgram(_idProg);
		// エラーが無いかチェック
		int ib;
		GL.glGetProgramiv(_idProg, GL_LINK_STATUS, &ib);
		AssertT(Throw, ib==GL_TRUE, (GLE_ProgramError)(GLuint), _idProg)
	}
	GLProgram::~GLProgram() {
		if(mgr_gl.isInDtor()) {
			for(auto& p : _shader)
				p.setNull();
		}
		onDeviceLost();
	}
	void GLProgram::onDeviceLost() {
		if(_idProg != 0) {
			// ShaderはProgramをDeleteすれば自動的にdetachされる
			GL.glDeleteProgram(_idProg);
			_idProg = 0;
		}
	}
	void GLProgram::onDeviceReset() {
		if(_idProg == 0) {
			// 先にshaderがresetされてないかもしれないので、ここでしておく
			for(auto& s : _shader) {
				if(s)
					s.cref()->onDeviceReset();
			}
			_initProgram();
		}
	}
	const HLSh& GLProgram::getShader(ShType type) const {
		return _shader[(int)type];
	}
	OPGLint GLProgram::getUniformID(const std::string& name) const {
		GLint id = GL.glGetUniformLocation(getProgramID(), name.c_str());
		AssertTP(Warn, id>=0, (GLE_ParamNotFound)(const std::string&), name)
		return id>=0 ? OPGLint(id) : OPGLint(spn::none);
	}
	OPGLint GLProgram::getAttribID(const std::string& name) const {
		GLint id = GL.glGetAttribLocation(getProgramID(), name.c_str());
		AssertT(Warn, id>=0, (GLE_ParamNotFound)(const std::string&), name)
		return id>=0 ? OPGLint(id) : OPGLint(spn::none);
	}
	GLuint GLProgram::getProgramID() const {
		return _idProg;
	}
	int GLProgram::_getNumParam(GLenum flag) const {
		int iv;
		GL.glGetProgramiv(getProgramID(), flag, &iv);
		return iv;
	}
	int GLProgram::getNActiveAttribute() const {
		return _getNumParam(GL_ACTIVE_ATTRIBUTES);
	}
	int GLProgram::getNActiveUniform() const {
		return _getNumParam(GL_ACTIVE_UNIFORMS);
	}
	GLParamInfo GLProgram::_getActiveParam(int n, InfoF infoF) const {
		GLchar buff[128];
		GLsizei len;
		GLint sz;
		GLenum typ;
		(GL.*infoF)(getProgramID(), n, countof(buff), &len, &sz, &typ, buff);
		GLParamInfo ret = *GLFormat::QueryGLSLInfo(typ);
		ret.name = buff;
		return std::move(ret);
	}
	GLParamInfo GLProgram::getActiveAttribute(int n) const {
		return _getActiveParam(n, &IGL::glGetActiveAttrib);
	}
	GLParamInfo GLProgram::getActiveUniform(int n) const {
		return _getActiveParam(n, &IGL::glGetActiveUniform);
	}
	void GLProgram::use() const {
		GL.glUseProgram(getProgramID());
	}
	// ------------------ GLParamInfo ------------------
	GLParamInfo::GLParamInfo(const GLSLFormatDesc& desc): GLSLFormatDesc(desc) {}
}

<commit_msg>GLProgram: getUniform/AttribIDではエラーチェックをしないように変更<commit_after>#ifdef WIN32
	#include <intrin.h>
	#include <windows.h>
#endif
#include "glresource.hpp"
#include "event.hpp"

#if !defined(WIN32) && !defined(ANDROID)
	#include <GL/glx.h>
	#include "glxext.h"
#endif

namespace rs {
	namespace {
		bool g_bglfuncInit = false;
	}
	#define GLGETPROC(name) SDL_GL_GetProcAddress(BOOST_PP_STRINGIZE(name))
	#if defined(_WIN32)
		namespace {
			using SetSwapInterval_t = bool APIENTRY (*)(int);
			SetSwapInterval_t g_setswapinterval = nullptr;
		}
		void LoadGLAux() {
			g_setswapinterval = (SetSwapInterval_t)GLGETPROC(wglSwapIntervalEXT);
		}
	#else
		namespace {
			#ifdef __ANDROID__
				using SetSwapInterval_t = void GL_APIENTRY (*)(int);
			#else
				using SetSwapInterval_t = void APIENTRY (*)(int);
			#endif
			SetSwapInterval_t g_setswapinterval = nullptr;
		}
		void LoadGLAux() {
			// EXTかSGIのどちらかが存在する事を期待
			try {
				g_setswapinterval = (SetSwapInterval_t)GLGETPROC(glXSwapIntervalSGI);
			} catch(const std::runtime_error& e) {
				g_setswapinterval = (SetSwapInterval_t)GLGETPROC(glXSwapIntervalEXT);
			}
		}
	#endif
	bool GLWrap::isGLFuncLoaded() {
		return g_bglfuncInit;
	}
	void IGL_Draw::setSwapInterval(int n) {
		g_setswapinterval(n);
	}
	void IGL_OtherSingle::setSwapInterval(int n) {
		GLW.getDrawHandler().postExec([=](){
			IGL_Draw().setSwapInterval(n);
		});
	}

	// OpenGL関数ロード
	// FuncNameで読み込めなければFuncNameARBとFuncNameEXTで試す
	#define GLDEFINE(...)
	#define DEF_GLMETHOD(ret_type, num, name, args, argnames) \
		GLWrap::name = nullptr; \
		GLWrap::name = (typename GLWrap::t_##name) GLGETPROC(name); \
		if(GLWrap::name == nullptr) GLWrap::name = (typename GLWrap::t_##name)GLGETPROC(BOOST_PP_CAT(name,ARB)); \
		if(GLWrap::name == nullptr) GLWrap::name = (typename GLWrap::t_##name)GLGETPROC(BOOST_PP_CAT(name,EXT)); \
		Assert(Warn, GLWrap::name != nullptr, "could not load OpenGL function: %1%", #name)
		void GLWrap::loadGLFunc() {
			// 各種API関数
			#ifndef ANDROID
				#ifdef ANDROID
					#include "android_gl.inc"
				#elif defined(WIN32)
					#include "mingw_gl.inc"
				#else
					#include "linux_gl.inc"
				#endif
			#endif
			// その他OS依存なAPI関数
			LoadGLAux();
			g_bglfuncInit = true;
		}
	#undef DEF_GLMETHOD
	#undef GLDEFINE
	// ---------------------- GLShader ----------------------
	void GLShader::_initShader() {
		_idSh = GL.glCreateShader(c_glShFlag[_flag]);

		const auto* pStr = _source.c_str();
		GL.glShaderSource(_idSh, 1, &pStr, nullptr);
		GL.glCompileShader(_idSh);

		// エラーが無かったか確認
		GLint compiled;
		GL.glGetShaderiv(_idSh, GL_COMPILE_STATUS, &compiled);
		AssertT(Throw, compiled==GL_TRUE, (GLE_ShaderError)(const std::string&)(GLuint), _source, _idSh)
	}

	GLShader::GLShader() {}
	GLShader::GLShader(ShType flag, const std::string& src): _idSh(0), _flag(flag), _source(src) {
		_initShader();
	}
	GLShader::~GLShader() {
		onDeviceLost();
	}
	bool GLShader::isEmpty() const {
		return _source.empty();
	}
	int GLShader::getShaderID() const {
		return _idSh;
	}
	void GLShader::onDeviceLost() {
		if(_idSh!=0) {
			GL.glDeleteShader(_idSh);
			_idSh = 0;
		}
	}
	void GLShader::onDeviceReset() {
		if(!isEmpty() && _idSh==0)
			_initShader();
	}
	ShType GLShader::getShaderType() const {
		return _flag;
	}

	// ---------------------- draw::Program ----------------------
	namespace draw {
		Program::Program(HProg hProg):
			Token(hProg), _idProg(hProg.ref()->getProgramID()) {}
		void Program::exec() {
			GL.glUseProgram(_idProg);
		}
	}

	// ---------------------- GLProgram ----------------------
	void GLProgram::_setShader(HSh hSh) {
		if(hSh)
			_shader[hSh.ref()->getShaderType()] = hSh;
	}
	void GLProgram::_initProgram() {
		_idProg = GL.glCreateProgram();
		for(int i=0 ; i<static_cast<int>(ShType::NUM_SHTYPE) ; i++) {
			auto& sh = _shader[i];
			// Geometryシェーダー以外は必須
			if(sh.valid()) {
				GL.glAttachShader(_idProg, sh.cref()->getShaderID());
				GLEC_ChkP(Trap)
			} else {
				AssertT(Trap, i==ShType::GEOMETRY, (GLE_Error)(const char*), "missing shader elements (vertex or fragment)")
			}
		}

		GL.glLinkProgram(_idProg);
		// エラーが無いかチェック
		int ib;
		GL.glGetProgramiv(_idProg, GL_LINK_STATUS, &ib);
		AssertT(Throw, ib==GL_TRUE, (GLE_ProgramError)(GLuint), _idProg)
	}
	GLProgram::~GLProgram() {
		if(mgr_gl.isInDtor()) {
			for(auto& p : _shader)
				p.setNull();
		}
		onDeviceLost();
	}
	void GLProgram::onDeviceLost() {
		if(_idProg != 0) {
			// ShaderはProgramをDeleteすれば自動的にdetachされる
			GL.glDeleteProgram(_idProg);
			_idProg = 0;
		}
	}
	void GLProgram::onDeviceReset() {
		if(_idProg == 0) {
			// 先にshaderがresetされてないかもしれないので、ここでしておく
			for(auto& s : _shader) {
				if(s)
					s.cref()->onDeviceReset();
			}
			_initProgram();
		}
	}
	const HLSh& GLProgram::getShader(ShType type) const {
		return _shader[(int)type];
	}
	OPGLint GLProgram::getUniformID(const std::string& name) const {
		GLint id = GL.glGetUniformLocation_NC(getProgramID(), name.c_str());
		AssertTP(Warn, id>=0, (GLE_ParamNotFound)(const std::string&), name)
		return id>=0 ? OPGLint(id) : OPGLint(spn::none);
	}
	OPGLint GLProgram::getAttribID(const std::string& name) const {
		GLint id = GL.glGetAttribLocation_NC(getProgramID(), name.c_str());
		AssertT(Warn, id>=0, (GLE_ParamNotFound)(const std::string&), name)
		return id>=0 ? OPGLint(id) : OPGLint(spn::none);
	}
	GLuint GLProgram::getProgramID() const {
		return _idProg;
	}
	int GLProgram::_getNumParam(GLenum flag) const {
		int iv;
		GL.glGetProgramiv(getProgramID(), flag, &iv);
		return iv;
	}
	int GLProgram::getNActiveAttribute() const {
		return _getNumParam(GL_ACTIVE_ATTRIBUTES);
	}
	int GLProgram::getNActiveUniform() const {
		return _getNumParam(GL_ACTIVE_UNIFORMS);
	}
	GLParamInfo GLProgram::_getActiveParam(int n, InfoF infoF) const {
		GLchar buff[128];
		GLsizei len;
		GLint sz;
		GLenum typ;
		(GL.*infoF)(getProgramID(), n, countof(buff), &len, &sz, &typ, buff);
		GLParamInfo ret = *GLFormat::QueryGLSLInfo(typ);
		ret.name = buff;
		return std::move(ret);
	}
	GLParamInfo GLProgram::getActiveAttribute(int n) const {
		return _getActiveParam(n, &IGL::glGetActiveAttrib);
	}
	GLParamInfo GLProgram::getActiveUniform(int n) const {
		return _getActiveParam(n, &IGL::glGetActiveUniform);
	}
	void GLProgram::use() const {
		GL.glUseProgram(getProgramID());
	}
	// ------------------ GLParamInfo ------------------
	GLParamInfo::GLParamInfo(const GLSLFormatDesc& desc): GLSLFormatDesc(desc) {}
}

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkSurface.h"
#include "SkCanvas.h"

static void drawContents(SkSurface* surface, SkColor fillC) {
    SkSize size = SkSize::Make(surface->width(), surface->height());
    SkAutoTUnref<SkCanvas> canvas(surface->newCanvas());

    SkScalar stroke = size.fWidth / 10;
    SkScalar radius = (size.fWidth - stroke) / 2;

    SkPaint paint;

    paint.setAntiAlias(true);
    paint.setColor(fillC);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(stroke);
    paint.setColor(SK_ColorBLACK);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
}

static void test_surface(SkCanvas* canvas, SkSurface* surf) {
    drawContents(surf, SK_ColorRED);
    SkImage* imgR = surf->newImageShapshot();

    drawContents(surf, SK_ColorGREEN);
    SkImage* imgG = surf->newImageShapshot();

    drawContents(surf, SK_ColorBLUE);

    imgR->draw(canvas, 0, 0, NULL);
    imgG->draw(canvas, 0, 80, NULL);
    surf->draw(canvas, 0, 160, NULL);

    imgG->unref();
    imgR->unref();
}

class ImageGM : public skiagm::GM {
    void*   fBuffer;
    size_t  fBufferSize;
    SkSize  fSize;
    enum {
        W = 64,
        H = 64,
        RB = W * 4 + 8,
    };
public:
    ImageGM() {
        fBufferSize = RB * H;
        fBuffer = sk_malloc_throw(fBufferSize);
        fSize.set(SkIntToScalar(W), SkIntToScalar(H));
    }

    virtual ~ImageGM() {
        sk_free(fBuffer);
    }

protected:
    virtual SkString onShortName() {
        return SkString("image");
    }

    virtual SkISize onISize() {
        return SkISize::Make(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) {
        // since we draw into this directly, we need to start fresh
        sk_bzero(fBuffer, fBufferSize);

        SkImage::Info info;

        info.fWidth = W;
        info.fHeight = H;
        info.fColorType = SkImage::kPMColor_ColorType;
        info.fAlphaType = SkImage::kPremul_AlphaType;
        SkAutoTUnref<SkSurface> surf0(SkSurface::NewRasterDirect(info, NULL, fBuffer, RB));
        SkAutoTUnref<SkSurface> surf1(SkSurface::NewRaster(info, NULL));
        SkAutoTUnref<SkSurface> surf2(SkSurface::NewPicture(info.fWidth, info.fHeight));

        test_surface(canvas, surf0);
        canvas->translate(80, 0);
        test_surface(canvas, surf1);
        canvas->translate(80, 0);
        test_surface(canvas, surf2);
    }

private:
    typedef skiagm::GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static skiagm::GM* MyFactory(void*) { return new ImageGM; }
static skiagm::GMRegistry reg(MyFactory);

<commit_msg>update to surface.getCanvas()<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkSurface.h"
#include "SkCanvas.h"

static void drawContents(SkSurface* surface, SkColor fillC) {
    SkSize size = SkSize::Make(surface->width(), surface->height());
    SkCanvas* canvas = surface->getCanvas();

    SkScalar stroke = size.fWidth / 10;
    SkScalar radius = (size.fWidth - stroke) / 2;

    SkPaint paint;

    paint.setAntiAlias(true);
    paint.setColor(fillC);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(stroke);
    paint.setColor(SK_ColorBLACK);
    canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
}

static void test_surface(SkCanvas* canvas, SkSurface* surf) {
    drawContents(surf, SK_ColorRED);
    SkImage* imgR = surf->newImageShapshot();

    drawContents(surf, SK_ColorGREEN);
    SkImage* imgG = surf->newImageShapshot();

    drawContents(surf, SK_ColorBLUE);

    SkPaint paint;
//    paint.setFilterBitmap(true);
//    paint.setAlpha(0x80);

    imgR->draw(canvas, 0, 0, &paint);
    imgG->draw(canvas, 0, 80, &paint);
    surf->draw(canvas, 0, 160, &paint);

    imgG->unref();
    imgR->unref();
}

class ImageGM : public skiagm::GM {
    void*   fBuffer;
    size_t  fBufferSize;
    SkSize  fSize;
    enum {
        W = 64,
        H = 64,
        RB = W * 4 + 8,
    };
public:
    ImageGM() {
        fBufferSize = RB * H;
        fBuffer = sk_malloc_throw(fBufferSize);
        fSize.set(SkIntToScalar(W), SkIntToScalar(H));
    }

    virtual ~ImageGM() {
        sk_free(fBuffer);
    }

protected:
    virtual SkString onShortName() {
        return SkString("image");
    }

    virtual SkISize onISize() {
        return SkISize::Make(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) {
        canvas->translate(10, 10);
        canvas->scale(2, 2);

        // since we draw into this directly, we need to start fresh
        sk_bzero(fBuffer, fBufferSize);

        SkImage::Info info;

        info.fWidth = W;
        info.fHeight = H;
        info.fColorType = SkImage::kPMColor_ColorType;
        info.fAlphaType = SkImage::kPremul_AlphaType;
        SkAutoTUnref<SkSurface> surf0(SkSurface::NewRasterDirect(info, NULL, fBuffer, RB));
        SkAutoTUnref<SkSurface> surf1(SkSurface::NewRaster(info, NULL));
        SkAutoTUnref<SkSurface> surf2(SkSurface::NewPicture(info.fWidth, info.fHeight));

        test_surface(canvas, surf0);
        canvas->translate(80, 0);
        test_surface(canvas, surf1);
        canvas->translate(80, 0);
        test_surface(canvas, surf2);
    }

private:
    typedef skiagm::GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static skiagm::GM* MyFactory(void*) { return new ImageGM; }
static skiagm::GMRegistry reg(MyFactory);

<|endoftext|>


<commit_before>/*
 * File:   newsimpletest.cpp
 * Author: msk
 *
 * Created on Feb 4, 2013, 2:33:58 PM
 */

#include <stdlib.h>
#include <iostream>

/*
 * Simple C++ Test Suite
 */

void hazelcast::client::IMap::remove(K key);

void testRemove() {
    K key;
    hazelcast::client::IMap iMap;
    iMap.remove(key);
    if (true /*check result*/) {
        std::cout << "%TEST_FAILED% time=0 testname=testRemove (newsimpletest) message=error message sample" << std::endl;
    }
}

int main(int argc, char** argv) {
    std::cout << "%SUITE_STARTING% newsimpletest" << std::endl;
    std::cout << "%SUITE_STARTED%" << std::endl;

    std::cout << "%TEST_STARTED% testRemove (newsimpletest)" << std::endl;
    testRemove();
    std::cout << "%TEST_FINISHED% time=0 testRemove (newsimpletest)" << std::endl;

    std::cout << "%SUITE_FINISHED% time=0" << std::endl;

    return (EXIT_SUCCESS);
}

<commit_msg>cleanup<commit_after><|endoftext|>


<commit_before>/*
Library EDK - How to use Extensible Development Kit
Copyright (C) 2013 Eduardo Moura Sales Martins
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, 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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
email: edimartin@gmail.com.br

AV: Walmor M. de Souza 392 Casa
Gravatai RS Brazil 94065100
*/

//Include the Window
#include "edk/Window.h"
//Include the View to render Graphics
#include "edk/ViewGU2D.h"
//Include the FontMap render
#include "edk/fonts/FontMap.h"

class RenderView: public edk::ViewGU2D{
public:
    RenderView(){}
    ~RenderView(){}
    void load(edk::rectf32){
        this->camera.position.x = 7;
        this->camera.position.y = -0.5f;
        this->camera.setSize(16.f,10.f);
        //create the message
        text.createStringMap("Hello EDK World");
    }
    void unload(){
        //remove the message
        text.deleteMap();
    }
    //render the scene in the vew
    void drawScene(edk::rectf32){
        //draw the message
        text.draw();
    }
private:
    edk::fonts::FontMap text;
};

int main(){
    edk::Window win;
    //create the window with the buttons
    win.createWindow(800,600,"EDK HELLO WORLD",EDK_WINDOW_BUTTONS);
    //set the background color fo the window
    win.cleanColor = edk::color3ui8(0,0,0);

    //Create a view to draw the scene
    RenderView view;
    view.backgroundColor = edk::color4f32(1,1,1,1); //set the viewColor
    view.frame.origin = edk::vec2f32(50,50);        //set the view position inside the Window View
    view.frame.size = edk::size2f32(700,500);       //set the size of the View

    //add the view in the Window
    win.addSubview(&view);

    //Loop
    while(win.isOpened()){
        //Clean the Windows
        win.clean();
        //load the Window Events
        win.loadEvents();
        //update the Views with the events pre-loaded
        win.updateViews();

        //check if click to close de Window
        if(win.eventButtonClose()){
            //close the window
            win.closeWindow();
        }
        //test if release the ESC key
        if(win.eventGetKeyReleaseSize()){
            for(edk::uint32 i=0u;i<win.eventGetKeyReleaseSize();i++){
                if(win.eventGetKeyRelease(i) == edk::key::escape){
                    //close Window
                    win.closeWindow();
                }
            }
        }
        //draw the View's
        win.drawView();
        //render the scene
        win.render();
    }
    //remove the view from window
    win.removeSubview(&view);
    return 0;
}

<commit_msg>Forgot to set the text color to be showed.<commit_after>/*
Library EDK - How to use Extensible Development Kit
Copyright (C) 2013 Eduardo Moura Sales Martins
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, 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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
email: edimartin@gmail.com.br

AV: Walmor M. de Souza 392 Casa
Gravatai RS Brazil 94065100
*/

//Include the Window
#include "edk/Window.h"
//Include the View to render Graphics
#include "edk/ViewGU2D.h"
//Include the FontMap render
#include "edk/fonts/FontMap.h"

class RenderView: public edk::ViewGU2D{
public:
    RenderView(){}
    ~RenderView(){}
    void load(edk::rectf32){
        this->camera.position.x = 7;
        this->camera.position.y = -0.5f;
        this->camera.setSize(16.f,10.f);
        //create the message
        text.createStringMap("Hello EDK World");
        text.setColor(0.f,0.f,0.f,1.f);
    }
    void unload(){
        //remove the message
        text.deleteMap();
    }
    //render the scene in the vew
    void drawScene(edk::rectf32){
        //draw the message
        text.draw();
    }
private:
    edk::fonts::FontMap text;
};

int main(){
    edk::Window win;
    //create the window with the buttons
    win.createWindow(800,600,"EDK HELLO WORLD",EDK_WINDOW_BUTTONS);
    //set the background color fo the window
    win.cleanColor = edk::color3ui8(0,0,0);

    //Create a view to draw the scene
    RenderView view;
    view.backgroundColor = edk::color4f32(1,1,1,1); //set the viewColor
    view.frame.origin = edk::vec2f32(50,50);        //set the view position inside the Window View
    view.frame.size = edk::size2f32(700,500);       //set the size of the View

    //add the view in the Window
    win.addSubview(&view);

    //Loop
    while(win.isOpened()){
        //Clean the Windows
        win.clean();
        //load the Window Events
        win.loadEvents();
        //update the Views with the events pre-loaded
        win.updateViews();

        //check if click to close de Window
        if(win.eventButtonClose()){
            //close the window
            win.closeWindow();
        }
        //test if release the ESC key
        if(win.eventGetKeyReleaseSize()){
            for(edk::uint32 i=0u;i<win.eventGetKeyReleaseSize();i++){
                if(win.eventGetKeyRelease(i) == edk::key::escape){
                    //close Window
                    win.closeWindow();
                }
            }
        }
        //draw the View's
        win.drawView();
        //render the scene
        win.render();
    }
    //remove the view from window
    win.removeSubview(&view);
    return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attrlistimpl.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 12:03:33 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <cppuhelper/implbase2.hxx>

namespace sax_expatwrap
{

struct AttributeListImpl_impl;

class AttributeListImpl :
    public WeakImplHelper2< XAttributeList, XCloneable >
{
public:
    AttributeListImpl();
    AttributeListImpl( const AttributeListImpl & );
    ~AttributeListImpl();

public:
    virtual sal_Int16 SAL_CALL getLength(void) throw(RuntimeException);
    virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw(RuntimeException);
    virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw(RuntimeException);
    virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw(RuntimeException);
    virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw(RuntimeException);
    virtual OUString SAL_CALL getValueByName(const OUString& aName) throw( RuntimeException);

public:
    virtual Reference< XCloneable >  SAL_CALL createClone() throw(RuntimeException);

public:
    void addAttribute( const OUString &sName , const OUString &sType , const OUString &sValue );
    void clear();
    void removeAttribute( const OUString &sName );
    void setAttributeList( const Reference<  XAttributeList > & );

private:
    struct AttributeListImpl_impl *m_pImpl;
};

}
<commit_msg>INTEGRATION: CWS custommeta (1.3.48); FILE MERGED 2007/12/07 13:40:15 mst 1.3.48.1: - sax/source/expatwrap/attrlistimpl.{hxx,cxx}:   rename class AttributeListImpl to AttributeList, in preparation for export<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attrlistimpl.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-26 14:40:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SAX_ATTRLISTIMPL_HXX
#define _SAX_ATTRLISTIMPL_HXX

#include "sal/config.h"
//#include "sax/saxdllapi.h"

#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>

namespace sax_expatwrap
{

struct AttributeList_impl;

//FIXME
class /*SAX_DLLPUBLIC*/ AttributeList :
    public ::cppu::WeakImplHelper2<
                ::com::sun::star::xml::sax::XAttributeList,
                ::com::sun::star::util::XCloneable >
{
public:
    AttributeList();
    AttributeList( const AttributeList & );
    virtual ~AttributeList();

    void addAttribute( const ::rtl::OUString &sName ,
        const ::rtl::OUString &sType , const ::rtl::OUString &sValue );
    void clear();
    void removeAttribute( const ::rtl::OUString &sName );
    void setAttributeList( const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList > & );

public:
    // XAttributeList
    virtual sal_Int16 SAL_CALL getLength(void)
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getNameByIndex(sal_Int16 i)
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTypeByIndex(sal_Int16 i)
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getTypeByName(const ::rtl::OUString& aName)
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getValueByIndex(sal_Int16 i)
        throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getValueByName(const ::rtl::OUString& aName)
        throw( ::com::sun::star::uno::RuntimeException);

    // XCloneable
    virtual ::com::sun::star::uno::Reference< XCloneable > SAL_CALL
        createClone()   throw(::com::sun::star::uno::RuntimeException);

private:
    struct AttributeList_impl *m_pImpl;
};

}

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: listenercalls.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 14:41:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include <com/sun/star/util/XModifyListener.hpp>
#include <tools/debug.hxx>

#include "listenercalls.hxx"

using namespace com::sun::star;

//------------------------------------------------------------------------

ScUnoListenerCalls::ScUnoListenerCalls()
{
}

ScUnoListenerCalls::~ScUnoListenerCalls()
{
    DBG_ASSERT( aEntries.empty(), "unhandled listener calls remaining" );
}

void ScUnoListenerCalls::Add( const uno::Reference<util::XModifyListener>& rListener,
                                const lang::EventObject& rEvent )
{
    if ( rListener.is() )
        aEntries.push_back( ScUnoListenerEntry( rListener, rEvent ) );
}

void ScUnoListenerCalls::ExecuteAndClear()
{
    //  Execute all stored calls and remove them from the list.
    //  During each modified() call, Add may be called again.
    //  These new calls are executed here, too.

    if (!aEntries.empty())
    {
        std::list<ScUnoListenerEntry>::iterator aItr(aEntries.begin());
        std::list<ScUnoListenerEntry>::iterator aEndItr(aEntries.end());
        while ( aItr != aEndItr )
        {
            ScUnoListenerEntry aEntry = *aItr;
            try
            {
                aEntry.xListener->modified( aEntry.aEvent );
            }
            catch ( uno::RuntimeException )
            {
                // the listener is an external object and may throw a RuntimeException
                // for reasons we don't know
            }

            //  New calls that are added during the modified() call are appended to the end
            //  of aEntries, so the loop will catch them, too (as long as erase happens
            //  after modified).

            aItr = aEntries.erase(aItr);
        }
    }
}

<commit_msg>INTEGRATION: CWS changefileheader (1.5.492); FILE MERGED 2008/03/31 17:19:34 rt 1.5.492.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: listenercalls.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include <com/sun/star/util/XModifyListener.hpp>
#include <tools/debug.hxx>

#include "listenercalls.hxx"

using namespace com::sun::star;

//------------------------------------------------------------------------

ScUnoListenerCalls::ScUnoListenerCalls()
{
}

ScUnoListenerCalls::~ScUnoListenerCalls()
{
    DBG_ASSERT( aEntries.empty(), "unhandled listener calls remaining" );
}

void ScUnoListenerCalls::Add( const uno::Reference<util::XModifyListener>& rListener,
                                const lang::EventObject& rEvent )
{
    if ( rListener.is() )
        aEntries.push_back( ScUnoListenerEntry( rListener, rEvent ) );
}

void ScUnoListenerCalls::ExecuteAndClear()
{
    //  Execute all stored calls and remove them from the list.
    //  During each modified() call, Add may be called again.
    //  These new calls are executed here, too.

    if (!aEntries.empty())
    {
        std::list<ScUnoListenerEntry>::iterator aItr(aEntries.begin());
        std::list<ScUnoListenerEntry>::iterator aEndItr(aEntries.end());
        while ( aItr != aEndItr )
        {
            ScUnoListenerEntry aEntry = *aItr;
            try
            {
                aEntry.xListener->modified( aEntry.aEvent );
            }
            catch ( uno::RuntimeException )
            {
                // the listener is an external object and may throw a RuntimeException
                // for reasons we don't know
            }

            //  New calls that are added during the modified() call are appended to the end
            //  of aEntries, so the loop will catch them, too (as long as erase happens
            //  after modified).

            aItr = aEntries.erase(aItr);
        }
    }
}

<|endoftext|>