<commit_before>#include <remote_api.h>
#include <ttrss_api.h>
#include <json.h>

namespace newsbeuter {

ttrss_api::ttrss_api(configcontainer * c) : remote_api(c) {
}

ttrss_api::~ttrss_api() {
}

bool ttrss_api::authenticate() {
	sid = retrieve_sid();

	return sid != "";
}

std::string ttrss_api::retrieve_sid() {
	CURL * handle = curl_easy_init();
	const std::string location = cfg->get_configvalue("ttrss-url");
	char * user = curl_easy_escape(handle, cfg->get_configvalue("ttrss-login").c_str(), 0);
	char * pass = curl_easy_escape(handle, cfg->get_configvalue("ttrss-password").c_str(), 0);

	std::string login_url = utils::strprintf("%s/api/?op=login&user=%s&password=%s", location.c_str(), user, pass);

	curl_free(user);
	curl_free(pass);

	std::string result = utils::retrieve_url(login_url, cfg);

	std::string sid;

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) == 0) {
		struct json_object * content = json_object_object_get(reply, "content");
		struct json_object * session_id = json_object_object_get(content, "session_id");
		sid = json_object_get_string(session_id);
	}

	json_object_put(reply);

	LOG(LOG_DEBUG, "ttrss_api::retrieve_sid: result = '%s' sid = '%s'", result.c_str(), sid.c_str());

	return sid;
}

std::vector<tagged_feedurl> ttrss_api::get_subscribed_urls() {
	std::string cat_url = utils::strprintf("%s/api/?op=getCategories&sid=%s", cfg->get_configvalue("ttrss-url").c_str(), sid.c_str());
	std::string result = utils::retrieve_url(cat_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: reply = %s", result.c_str());

	std::vector<tagged_feedurl> feeds;

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) != 0)
		return feeds;

	struct json_object * content = json_object_object_get(reply, "content");

	if (json_object_get_type(content) != json_type_array)
		return feeds;

	struct array_list * categories = json_object_get_array(content);

	int catsize = array_list_length(categories);

	for (int i=0;i<catsize;i++) {
		struct json_object * cat = (struct json_object *)array_list_get_idx(categories, i);

		struct json_object * cat_id_obj = json_object_object_get(cat, "id");
		int cat_id = json_object_get_int(cat_id_obj);

		struct json_object * cat_title_obj = json_object_object_get(cat, "title");
		const char * cat_name = json_object_get_string(cat_title_obj);

		LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: id = %d title = %s", cat_id, cat_name);

		std::string feeds_url = utils::strprintf("%s/api/?op=getFeeds&cat_id=%d&sid=%s", cfg->get_configvalue("ttrss-url").c_str(), cat_id, sid.c_str());

		std::string feeds_data = utils::retrieve_url(feeds_url, cfg);

		LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: feeds_data = %s", feeds_data.c_str());

		struct json_object * feeds_reply = json_tokener_parse(feeds_data.c_str());

		struct json_object * feed_list_obj = json_object_object_get(feeds_reply, "content");
		struct array_list * feed_list = json_object_get_array(feed_list_obj);

		int feed_list_size = array_list_length(feed_list);

		for (int j=0;j<feed_list_size;j++) {
			struct json_object * feed = (struct json_object *)array_list_get_idx(feed_list, j);

			int feed_id = json_object_get_int(json_object_object_get(feed, "id"));
			const char * feed_title = json_object_get_string(json_object_object_get(feed, "title"));

			std::vector<std::string> tags;
			tags.push_back(std::string("~") + feed_title);
			tags.push_back(cat_name);
			feeds.push_back(tagged_feedurl(utils::strprintf("ttrss:%d", feed_id), tags));

			// TODO: cache feed_id -> feed_url (or feed_url -> feed_id ?)
		}

		json_object_put(feeds_reply);

	}

	json_object_put(reply);

	return feeds;
}

void ttrss_api::configure_handle(CURL * handle) {
	// TODO: implement
}

bool ttrss_api::mark_all_read(const std::string& feedurl) {

}

bool ttrss_api::mark_article_read(const std::string& guid, bool read) {

}

bool ttrss_api::update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid) {

}

rsspp::feed ttrss_api::fetch_feed(const std::string& id) {
	rsspp::feed f;

	std::string feed_url = utils::strprintf("%s/api/?op=getHeadlines&feed_id=%s&show_content=1&sid=%s",
		cfg->get_configvalue("ttrss-url").c_str(), id.c_str(), sid.c_str());
	std::string result = utils::retrieve_url(feed_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %s", result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());
	int rc;
	if ((rc=json_object_get_int(json_object_object_get(reply, "status"))) != 0) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: status = %d", rc);
		return f;
	}

	struct json_object * content = json_object_object_get(reply, "content");
	if (json_object_get_type(content) != json_type_array) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: content is not an array");
		return f;
	}

	struct array_list * items = json_object_get_array(content);
	int items_size = array_list_length(items);
	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %d items", items_size);

	for (int i=0;i<items_size;i++) {
		struct json_object * item_obj = (struct json_object *)array_list_get_idx(items, i);
		int id = json_object_get_int(json_object_object_get(item_obj, "id"));
		const char * title = json_object_get_string(json_object_object_get(item_obj, "title"));
		const char * link = json_object_get_string(json_object_object_get(item_obj, "link"));
		const char * content = json_object_get_string(json_object_object_get(item_obj, "content"));
		time_t updated = (time_t)json_object_get_int(json_object_object_get(item_obj, "updated"));

		rsspp::item item;

		if (title)
			item.title = title;

		if (link)
			item.link = link;

		if (content)
			item.content_encoded = content;

		item.guid = utils::strprintf("%d", id);

		char rfc822_date[128];
		strftime(rfc822_date, sizeof(rfc822_date), "%a, %d %b %Y %H:%M:%S %z", gmtime(&updated));
		item.pubDate = rfc822_date;

		f.items.push_back(item);
	}

	json_object_put(reply);
	return f;
}

}
<commit_msg>implemented "mark article read" and "mark all read".<commit_after>#include <remote_api.h>
#include <ttrss_api.h>
#include <cstring>
#include <json.h>

namespace newsbeuter {

ttrss_api::ttrss_api(configcontainer * c) : remote_api(c) {
}

ttrss_api::~ttrss_api() {
}

bool ttrss_api::authenticate() {
	sid = retrieve_sid();

	return sid != "";
}

std::string ttrss_api::retrieve_sid() {
	CURL * handle = curl_easy_init();
	const std::string location = cfg->get_configvalue("ttrss-url");
	char * user = curl_easy_escape(handle, cfg->get_configvalue("ttrss-login").c_str(), 0);
	char * pass = curl_easy_escape(handle, cfg->get_configvalue("ttrss-password").c_str(), 0);

	std::string login_url = utils::strprintf("%s/api/?op=login&user=%s&password=%s", location.c_str(), user, pass);

	curl_free(user);
	curl_free(pass);

	std::string result = utils::retrieve_url(login_url, cfg);

	std::string sid;

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) == 0) {
		struct json_object * content = json_object_object_get(reply, "content");
		struct json_object * session_id = json_object_object_get(content, "session_id");
		sid = json_object_get_string(session_id);
	}

	json_object_put(reply);

	LOG(LOG_DEBUG, "ttrss_api::retrieve_sid: result = '%s' sid = '%s'", result.c_str(), sid.c_str());

	return sid;
}

std::vector<tagged_feedurl> ttrss_api::get_subscribed_urls() {
	std::string cat_url = utils::strprintf("%s/api/?op=getCategories&sid=%s", cfg->get_configvalue("ttrss-url").c_str(), sid.c_str());
	std::string result = utils::retrieve_url(cat_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: reply = %s", result.c_str());

	std::vector<tagged_feedurl> feeds;

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) != 0)
		return feeds;

	struct json_object * content = json_object_object_get(reply, "content");

	if (json_object_get_type(content) != json_type_array)
		return feeds;

	struct array_list * categories = json_object_get_array(content);

	int catsize = array_list_length(categories);

	for (int i=0;i<catsize;i++) {
		struct json_object * cat = (struct json_object *)array_list_get_idx(categories, i);

		struct json_object * cat_id_obj = json_object_object_get(cat, "id");
		int cat_id = json_object_get_int(cat_id_obj);

		struct json_object * cat_title_obj = json_object_object_get(cat, "title");
		const char * cat_name = json_object_get_string(cat_title_obj);

		LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: id = %d title = %s", cat_id, cat_name);

		std::string feeds_url = utils::strprintf("%s/api/?op=getFeeds&cat_id=%d&sid=%s", cfg->get_configvalue("ttrss-url").c_str(), cat_id, sid.c_str());

		std::string feeds_data = utils::retrieve_url(feeds_url, cfg);

		LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: feeds_data = %s", feeds_data.c_str());

		struct json_object * feeds_reply = json_tokener_parse(feeds_data.c_str());

		struct json_object * feed_list_obj = json_object_object_get(feeds_reply, "content");
		struct array_list * feed_list = json_object_get_array(feed_list_obj);

		int feed_list_size = array_list_length(feed_list);

		for (int j=0;j<feed_list_size;j++) {
			struct json_object * feed = (struct json_object *)array_list_get_idx(feed_list, j);

			int feed_id = json_object_get_int(json_object_object_get(feed, "id"));
			const char * feed_title = json_object_get_string(json_object_object_get(feed, "title"));

			std::vector<std::string> tags;
			tags.push_back(std::string("~") + feed_title);
			tags.push_back(cat_name);
			feeds.push_back(tagged_feedurl(utils::strprintf("ttrss:%d", feed_id), tags));

			// TODO: cache feed_id -> feed_url (or feed_url -> feed_id ?)
		}

		json_object_put(feeds_reply);

	}

	json_object_put(reply);

	return feeds;
}

void ttrss_api::configure_handle(CURL * /*handle*/) {
	// nothing required
}

bool ttrss_api::mark_all_read(const std::string& feed_url) {
	std::string catchup_url = utils::strprintf("%s/api/?op=catchupFeed&feed_id=%s&sid=%s",
			cfg->get_configvalue("ttrss-url").c_str(), feed_url.substr(6,feed_url.length()-6).c_str(), sid.c_str());

	std::string result = utils::retrieve_url(catchup_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::mark_all_read: result = %s", result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) != 0) {
		json_object_put(reply);
		return false;
	}

	struct json_object * content = json_object_object_get(reply, "content");

	if (strcmp(json_object_get_string(json_object_object_get(content, "status")), "OK") != 0) {
		json_object_put(reply);
		return false;
	}

	json_object_put(reply);
	return true;
}

bool ttrss_api::mark_article_read(const std::string& guid, bool read) {
	std::string update_url = utils::strprintf("%s/api/?op=updateArticle&article_ids=%s&field=2&mode=%d&sid=%s",
			cfg->get_configvalue("ttrss-url").c_str(), guid.c_str(), read ? 0 : 1, sid.c_str());

	std::string result = utils::retrieve_url(update_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::mark_article_read: result = %s", result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());

	struct json_object * status = json_object_object_get(reply, "status");
	if (json_object_get_int(status) != 0) {
		json_object_put(reply);
		return false;
	}

	struct json_object * content = json_object_object_get(reply, "content");

	if (strcmp(json_object_get_string(json_object_object_get(content, "status")), "OK") != 0) {
		json_object_put(reply);
		return false;
	}

	json_object_put(reply);
	return true;
}

bool ttrss_api::update_article_flags(const std::string& /*oldflags*/, const std::string& /*newflags*/, const std::string& /*guid*/) {
	// TODO: is there a way to update flags such as "starred" or "published"?
	return true;
}

rsspp::feed ttrss_api::fetch_feed(const std::string& id) {
	rsspp::feed f;

	std::string feed_url = utils::strprintf("%s/api/?op=getHeadlines&feed_id=%s&show_content=1&sid=%s",
		cfg->get_configvalue("ttrss-url").c_str(), id.c_str(), sid.c_str());
	std::string result = utils::retrieve_url(feed_url, cfg);

	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %s", result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());
	int rc;
	if ((rc=json_object_get_int(json_object_object_get(reply, "status"))) != 0) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: status = %d", rc);
		return f;
	}

	struct json_object * content = json_object_object_get(reply, "content");
	if (json_object_get_type(content) != json_type_array) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: content is not an array");
		return f;
	}

	struct array_list * items = json_object_get_array(content);
	int items_size = array_list_length(items);
	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %d items", items_size);

	for (int i=0;i<items_size;i++) {
		struct json_object * item_obj = (struct json_object *)array_list_get_idx(items, i);
		int id = json_object_get_int(json_object_object_get(item_obj, "id"));
		const char * title = json_object_get_string(json_object_object_get(item_obj, "title"));
		const char * link = json_object_get_string(json_object_object_get(item_obj, "link"));
		const char * content = json_object_get_string(json_object_object_get(item_obj, "content"));
		time_t updated = (time_t)json_object_get_int(json_object_object_get(item_obj, "updated"));

		rsspp::item item;

		if (title)
			item.title = title;

		if (link)
			item.link = link;

		if (content)
			item.content_encoded = content;

		item.guid = utils::strprintf("%d", id);

		char rfc822_date[128];
		strftime(rfc822_date, sizeof(rfc822_date), "%a, %d %b %Y %H:%M:%S %z", gmtime(&updated));
		item.pubDate = rfc822_date;

		f.items.push_back(item);
	}

	json_object_put(reply);
	return f;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/intranet_redirect_detector.h"

#include "base/command_line.h"
#include "base/rand_util.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domain.h"
#include "net/url_request/url_request_status.h"

const size_t IntranetRedirectDetector::kNumCharsInHostnames = 10;

IntranetRedirectDetector::IntranetRedirectDetector()
    : redirect_origin_(g_browser_process->local_state()->GetString(
          prefs::kLastKnownIntranetRedirectOrigin)),
      ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)),
      in_sleep_(true),
      request_context_available_(Profile::GetDefaultRequestContext() != NULL) {
  registrar_.Add(this, NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE,
                 NotificationService::AllSources());

  // Because this function can be called during startup, when kicking off a URL
  // fetch can eat up 20 ms of time, we delay seven seconds, which is hopefully
  // long enough to be after startup, but still get results back quickly.
  // Ideally, instead of this timer, we'd do something like "check if the
  // browser is starting up, and if so, come back later", but there is currently
  // no function to do this.
  static const int kStartFetchDelayMS = 7000;
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      fetcher_factory_.NewRunnableMethod(
          &IntranetRedirectDetector::FinishSleep),
      kStartFetchDelayMS);

  net::NetworkChangeNotifier::AddObserver(this);
}

IntranetRedirectDetector::~IntranetRedirectDetector() {
  net::NetworkChangeNotifier::RemoveObserver(this);
  STLDeleteElements(&fetchers_);
}

// static
GURL IntranetRedirectDetector::RedirectOrigin() {
  const IntranetRedirectDetector* const detector =
      g_browser_process->intranet_redirect_detector();
  return detector ? detector->redirect_origin_ : GURL();
}

// static
void IntranetRedirectDetector::RegisterPrefs(PrefService* prefs) {
  prefs->RegisterStringPref(prefs::kLastKnownIntranetRedirectOrigin,
                            std::string());
}

void IntranetRedirectDetector::FinishSleep() {
  in_sleep_ = false;

  // If another fetch operation is still running, cancel it.
  STLDeleteElements(&fetchers_);
  resulting_origins_.clear();

  StartFetchesIfPossible();
}

void IntranetRedirectDetector::StartFetchesIfPossible() {
  // Bail if a fetch isn't appropriate right now.  This function will be called
  // again each time one of the preconditions changes, so we'll fetch
  // immediately once all of them are met.
  if (in_sleep_ || !request_context_available_)
    return;

  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kDisableBackgroundNetworking))
    return;

  DCHECK(fetchers_.empty() && resulting_origins_.empty());

  // Start three fetchers on random hostnames.
  for (size_t i = 0; i < 3; ++i) {
    std::string url_string("http://");
    for (size_t j = 0; j < kNumCharsInHostnames; ++j)
      url_string += ('a' + base::RandInt(0, 'z' - 'a'));
    GURL random_url(url_string + '/');
    URLFetcher* fetcher = new URLFetcher(random_url, URLFetcher::HEAD, this);
    // We don't want these fetches to affect existing state in the profile.
    fetcher->set_load_flags(net::LOAD_DISABLE_CACHE |
                            net::LOAD_DO_NOT_SAVE_COOKIES);
    fetcher->set_request_context(Profile::GetDefaultRequestContext());
    fetcher->Start();
    fetchers_.insert(fetcher);
  }
}

void IntranetRedirectDetector::OnURLFetchComplete(
    const URLFetcher* source,
    const GURL& url,
    const URLRequestStatus& status,
    int response_code,
    const ResponseCookies& cookies,
    const std::string& data) {
  // Delete the fetcher on this function's exit.
  Fetchers::iterator fetcher = fetchers_.find(const_cast<URLFetcher*>(source));
  DCHECK(fetcher != fetchers_.end());
  scoped_ptr<URLFetcher> clean_up_fetcher(*fetcher);
  fetchers_.erase(fetcher);

  // If any two fetches result in the same domain/host, we set the redirect
  // origin to that; otherwise we set it to nothing.
  if (!status.is_success() || (response_code != 200)) {
    if ((resulting_origins_.empty()) ||
        ((resulting_origins_.size() == 1) &&
         resulting_origins_.front().is_valid())) {
      resulting_origins_.push_back(GURL());
      return;
    }
    redirect_origin_ = GURL();
  } else {
    DCHECK(url.is_valid());
    GURL origin(url.GetOrigin());
    if (resulting_origins_.empty()) {
      resulting_origins_.push_back(origin);
      return;
    }
    if (net::RegistryControlledDomainService::SameDomainOrHost(
        resulting_origins_.front(), origin)) {
      redirect_origin_ = origin;
      if (!fetchers_.empty()) {
        // Cancel remaining fetch, we don't need it.
        DCHECK(fetchers_.size() == 1);
        delete (*fetchers_.begin());
        fetchers_.clear();
      }
    }
    if (resulting_origins_.size() == 1) {
      resulting_origins_.push_back(origin);
      return;
    }
    DCHECK(resulting_origins_.size() == 2);
    redirect_origin_ = net::RegistryControlledDomainService::SameDomainOrHost(
        resulting_origins_.back(), origin) ? origin : GURL();
  }

  g_browser_process->local_state()->SetString(
      prefs::kLastKnownIntranetRedirectOrigin, redirect_origin_.is_valid() ?
          redirect_origin_.spec() : std::string());
}

void IntranetRedirectDetector::Observe(NotificationType type,
                                       const NotificationSource& source,
                                       const NotificationDetails& details) {
  DCHECK_EQ(NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE, type.value);
  request_context_available_ = true;
  StartFetchesIfPossible();
}

void IntranetRedirectDetector::OnIPAddressChanged() {
  // If a request is already scheduled, do not scheduled yet another one.
  if (in_sleep_)
    return;

  // Since presumably many programs open connections after network changes,
  // delay this a little bit.
  in_sleep_ = true;
  static const int kNetworkSwitchDelayMS = 1000;
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      fetcher_factory_.NewRunnableMethod(
          &IntranetRedirectDetector::FinishSleep),
      kNetworkSwitchDelayMS);
}

IntranetRedirectHostResolverProc::IntranetRedirectHostResolverProc(
    net::HostResolverProc* previous)
    : net::HostResolverProc(previous) {
}

int IntranetRedirectHostResolverProc::Resolve(
    const std::string& host,
    net::AddressFamily address_family,
    net::HostResolverFlags host_resolver_flags,
    net::AddressList* addrlist,
    int* os_error) {
  // We'd love to just ask the IntranetRedirectDetector, but we may not be on
  // the same thread.  So just use the heuristic that any all-lowercase a-z
  // hostname with the right number of characters is likely from the detector
  // (and thus should be blocked).
  return ((host.length() == IntranetRedirectDetector::kNumCharsInHostnames) &&
      (host.find_first_not_of("abcdefghijklmnopqrstuvwxyz") ==
          std::string::npos)) ?
      net::ERR_NAME_NOT_RESOLVED :
      ResolveUsingPrevious(host, address_family, host_resolver_flags, addrlist,
                           os_error);
}
<commit_msg>Disable the proxy redirect check for Chrome Frame. This is the simplest way I could think of to disable this service for GCF but I'm open to other suggestions.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/intranet_redirect_detector.h"

#include "base/command_line.h"
#include "base/rand_util.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domain.h"
#include "net/url_request/url_request_status.h"

const size_t IntranetRedirectDetector::kNumCharsInHostnames = 10;

IntranetRedirectDetector::IntranetRedirectDetector()
    : redirect_origin_(g_browser_process->local_state()->GetString(
          prefs::kLastKnownIntranetRedirectOrigin)),
      ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)),
      in_sleep_(true),
      request_context_available_(Profile::GetDefaultRequestContext() != NULL) {
  registrar_.Add(this, NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE,
                 NotificationService::AllSources());

  // Because this function can be called during startup, when kicking off a URL
  // fetch can eat up 20 ms of time, we delay seven seconds, which is hopefully
  // long enough to be after startup, but still get results back quickly.
  // Ideally, instead of this timer, we'd do something like "check if the
  // browser is starting up, and if so, come back later", but there is currently
  // no function to do this.
  static const int kStartFetchDelayMS = 7000;
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      fetcher_factory_.NewRunnableMethod(
          &IntranetRedirectDetector::FinishSleep),
      kStartFetchDelayMS);

  net::NetworkChangeNotifier::AddObserver(this);
}

IntranetRedirectDetector::~IntranetRedirectDetector() {
  net::NetworkChangeNotifier::RemoveObserver(this);
  STLDeleteElements(&fetchers_);
}

// static
GURL IntranetRedirectDetector::RedirectOrigin() {
  const IntranetRedirectDetector* const detector =
      g_browser_process->intranet_redirect_detector();
  return detector ? detector->redirect_origin_ : GURL();
}

// static
void IntranetRedirectDetector::RegisterPrefs(PrefService* prefs) {
  prefs->RegisterStringPref(prefs::kLastKnownIntranetRedirectOrigin,
                            std::string());
}

void IntranetRedirectDetector::FinishSleep() {
  in_sleep_ = false;

  // If another fetch operation is still running, cancel it.
  STLDeleteElements(&fetchers_);
  resulting_origins_.clear();

  StartFetchesIfPossible();
}

void IntranetRedirectDetector::StartFetchesIfPossible() {
  // Bail if a fetch isn't appropriate right now.  This function will be called
  // again each time one of the preconditions changes, so we'll fetch
  // immediately once all of them are met.
  if (in_sleep_ || !request_context_available_)
    return;

  // The detector is not needed in Chrome Frame since we have no omnibox there.
  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
  if (cmd_line->HasSwitch(switches::kDisableBackgroundNetworking) ||
      cmd_line->HasSwitch(switches::kChromeFrame))
    return;

  DCHECK(fetchers_.empty() && resulting_origins_.empty());

  // Start three fetchers on random hostnames.
  for (size_t i = 0; i < 3; ++i) {
    std::string url_string("http://");
    for (size_t j = 0; j < kNumCharsInHostnames; ++j)
      url_string += ('a' + base::RandInt(0, 'z' - 'a'));
    GURL random_url(url_string + '/');
    URLFetcher* fetcher = new URLFetcher(random_url, URLFetcher::HEAD, this);
    // We don't want these fetches to affect existing state in the profile.
    fetcher->set_load_flags(net::LOAD_DISABLE_CACHE |
                            net::LOAD_DO_NOT_SAVE_COOKIES);
    fetcher->set_request_context(Profile::GetDefaultRequestContext());
    fetcher->Start();
    fetchers_.insert(fetcher);
  }
}

void IntranetRedirectDetector::OnURLFetchComplete(
    const URLFetcher* source,
    const GURL& url,
    const URLRequestStatus& status,
    int response_code,
    const ResponseCookies& cookies,
    const std::string& data) {
  // Delete the fetcher on this function's exit.
  Fetchers::iterator fetcher = fetchers_.find(const_cast<URLFetcher*>(source));
  DCHECK(fetcher != fetchers_.end());
  scoped_ptr<URLFetcher> clean_up_fetcher(*fetcher);
  fetchers_.erase(fetcher);

  // If any two fetches result in the same domain/host, we set the redirect
  // origin to that; otherwise we set it to nothing.
  if (!status.is_success() || (response_code != 200)) {
    if ((resulting_origins_.empty()) ||
        ((resulting_origins_.size() == 1) &&
         resulting_origins_.front().is_valid())) {
      resulting_origins_.push_back(GURL());
      return;
    }
    redirect_origin_ = GURL();
  } else {
    DCHECK(url.is_valid());
    GURL origin(url.GetOrigin());
    if (resulting_origins_.empty()) {
      resulting_origins_.push_back(origin);
      return;
    }
    if (net::RegistryControlledDomainService::SameDomainOrHost(
        resulting_origins_.front(), origin)) {
      redirect_origin_ = origin;
      if (!fetchers_.empty()) {
        // Cancel remaining fetch, we don't need it.
        DCHECK(fetchers_.size() == 1);
        delete (*fetchers_.begin());
        fetchers_.clear();
      }
    }
    if (resulting_origins_.size() == 1) {
      resulting_origins_.push_back(origin);
      return;
    }
    DCHECK(resulting_origins_.size() == 2);
    redirect_origin_ = net::RegistryControlledDomainService::SameDomainOrHost(
        resulting_origins_.back(), origin) ? origin : GURL();
  }

  g_browser_process->local_state()->SetString(
      prefs::kLastKnownIntranetRedirectOrigin, redirect_origin_.is_valid() ?
          redirect_origin_.spec() : std::string());
}

void IntranetRedirectDetector::Observe(NotificationType type,
                                       const NotificationSource& source,
                                       const NotificationDetails& details) {
  DCHECK_EQ(NotificationType::DEFAULT_REQUEST_CONTEXT_AVAILABLE, type.value);
  request_context_available_ = true;
  StartFetchesIfPossible();
}

void IntranetRedirectDetector::OnIPAddressChanged() {
  // If a request is already scheduled, do not scheduled yet another one.
  if (in_sleep_)
    return;

  // Since presumably many programs open connections after network changes,
  // delay this a little bit.
  in_sleep_ = true;
  static const int kNetworkSwitchDelayMS = 1000;
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
      fetcher_factory_.NewRunnableMethod(
          &IntranetRedirectDetector::FinishSleep),
      kNetworkSwitchDelayMS);
}

IntranetRedirectHostResolverProc::IntranetRedirectHostResolverProc(
    net::HostResolverProc* previous)
    : net::HostResolverProc(previous) {
}

int IntranetRedirectHostResolverProc::Resolve(
    const std::string& host,
    net::AddressFamily address_family,
    net::HostResolverFlags host_resolver_flags,
    net::AddressList* addrlist,
    int* os_error) {
  // We'd love to just ask the IntranetRedirectDetector, but we may not be on
  // the same thread.  So just use the heuristic that any all-lowercase a-z
  // hostname with the right number of characters is likely from the detector
  // (and thus should be blocked).
  return ((host.length() == IntranetRedirectDetector::kNumCharsInHostnames) &&
      (host.find_first_not_of("abcdefghijklmnopqrstuvwxyz") ==
          std::string::npos)) ?
      net::ERR_NAME_NOT_RESOLVED :
      ResolveUsingPrevious(host, address_family, host_resolver_flags, addrlist,
                           os_error);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

// Flaky, http://crbug.com/46601.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_Popup) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("popup/popup_main")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupFromInfobar) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
    switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("popup/popup_from_infobar")) << message_;
}
<commit_msg>Disable ExtensionApiTest.Popup. It's been timing out for the last 750+ runs.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"

// Times out. See http://crbug.com/46601.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_Popup) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("popup/popup_main")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupFromInfobar) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
    switches::kEnableExperimentalExtensionApis);

  ASSERT_TRUE(RunExtensionTest("popup/popup_from_infobar")) << message_;
}
<|endoftext|>


<commit_before><commit_msg>Plugin Power Saver: Allow Enterprise ASK policy users to manually play.<commit_after><|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "PlayerInfo.h"

/* system implementation headers */
#include <errno.h>
#include <string>

/* implementation-specific common headers */
#include "TextUtils.h"

WordFilter PlayerInfo::serverSpoofingFilter;
TimeKeeper PlayerInfo::now = TimeKeeper::getCurrent();

PlayerInfo::PlayerInfo(int _playerIndex) :
  playerIndex(_playerIndex), state(PlayerInLimbo), flag(-1),
  spamWarns(0), lastMsgTime(now), paused(false),
  pausedSince(TimeKeeper::getNullTime()), tracker(0)
{
  notResponding = false;
  memset(email, 0, EmailLen);
  memset(callSign, 0, CallSignLen);
  memset(token, 0, TokenLen);
}

void PlayerInfo::resetPlayer(bool ctf) {
  wasRabbit = false;

  lastupdate = now;
  lastmsg    = now;

  replayState = ReplayNone;

  playedEarly = false;

  restartOnBase = ctf;
}

void PlayerInfo::setRestartOnBase(bool on) {
  restartOnBase = on;
};

bool PlayerInfo::shouldRestartAtBase() {
  return restartOnBase;
};

void PlayerInfo::signingOn() {
  state = PlayerDead;
};

bool PlayerInfo::isAlive() {
  return state == PlayerAlive;
};

void PlayerInfo::setAlive() {
  state = PlayerAlive;
  flag = -1;
};

void PlayerInfo::setDead() {
  state = PlayerDead;
};

void *PlayerInfo::packUpdate(void *buf) {
  buf = nboPackUShort(buf, uint16_t(type));
  buf = nboPackUShort(buf, uint16_t(team));
  return buf;
};

void *PlayerInfo::packId(void *buf) {
  buf = nboPackString(buf, callSign, CallSignLen);
  buf = nboPackString(buf, email, EmailLen);
  return buf;
}

bool PlayerInfo::unpackEnter(void *buf, uint16_t &rejectCode, char *rejectMsg)
{
  // data: type, team, name, email
  uint16_t _type;
  int16_t _team;
  buf = nboUnpackUShort(buf, _type);
  buf = nboUnpackShort(buf, _team);
  type = PlayerType(_type);
  team = TeamColor(_team);
  buf = nboUnpackString(buf, callSign, CallSignLen);
  buf = nboUnpackString(buf, email, EmailLen);
  buf = nboUnpackString(buf, token, TokenLen);
  buf = nboUnpackString(buf, clientVersion, VersionLen);
  cleanEMail();

  // spoof filter holds "SERVER" for robust name comparisons
  if (serverSpoofingFilter.wordCount() == 0) {
    serverSpoofingFilter.addToFilter("SERVER", "");
  }

  if (!isCallSignReadable()) {
    DEBUG2("rejecting unreadable callsign: %s\n", callSign);
    rejectCode   = RejectBadCallsign;
    strcpy(rejectMsg, errorString.c_str());
    return false;
  }
  // no spoofing the server name
  if (serverSpoofingFilter.filter(callSign)) {
    rejectCode   = RejectRepeatCallsign;
    strcpy(rejectMsg, "The callsign specified is already in use.");
    return false;
  }
  if (!isEMailReadable()) {
    DEBUG2("rejecting unreadable player email: %s (%s)\n", callSign, email);
    rejectCode   = RejectBadEmail;
    strcpy(rejectMsg, "The e-mail was rejected.  Try a different e-mail.");
    return false;
  }
  return true;
};

const char *PlayerInfo::getCallSign() const {
  return callSign;
};

bool PlayerInfo::isCallSignReadable() {
  // callsign readability filter, make sure there are more alphanum than non
  // keep a count of alpha-numerics

  int callsignlen = (int)strlen(callSign);
  // reject less than 3 characters
  if (callsignlen < 3) {
    errorString = "Callsigns must be at least 3 characters.";
    return false;
  }

  // reject trailing space
  if (isspace(callSign[strlen(callSign) - 1])) {
    errorString = "Trailing spaces are not allowed in callsigns.";
    return false;
  }

  // start with true to reject leading space
  bool lastWasSpace = true;
  int alnumCount = 0;
  const char *sp = callSign;
  do {
    // reject sequential spaces
    if (lastWasSpace && isspace(*sp)) {
      errorString = "Leading or consecutive spaces are not allowed in callsigns.";
      return false;
    }

    // reject ' and " and any nonprintable
    if ((*sp == '\'') || (*sp == '"') || ((unsigned)*sp > 0x7f)
	|| !isprint(*sp)) {
      errorString = "Non-printable characters and quotes are not allowed in callsigns.";
      return false;
    }
    if (isspace(*sp)) {
      // only space is valid, not tab etc.
      if (*sp != ' ') {
	errorString = "Invalid whitespace in callsign.";
	return false;
      }
      lastWasSpace = true;
    } else {
      lastWasSpace = false;
      if (isalnum(*sp))
	alnumCount++;
    }
  } while (*++sp);
  return ((float)alnumCount / (float)callsignlen > 0.5f);
};

const char *PlayerInfo::getEMail() const {
  return email;
};

void PlayerInfo::cleanEMail() {
  // strip leading whitespace from email
  char *sp = email;
  char *tp = sp;
  while (isspace(*sp))
    sp++;

  // strip any non-printable characters and ' and " from email
  do {
    if (isprint(*sp) && (*sp != '\'') && (*sp != '"')) {
      *tp++ = *sp;
    }
  } while (*++sp);
  *tp = *sp;

  // strip trailing whitespace from email
  while (isspace(*--tp)) {
    *tp=0;
  }
};

bool PlayerInfo::isEMailReadable() {
  // email/"team" readability filter, make sure there are more
  // alphanum than non
  int emailAlnumCount = 0;
  char *sp = email;
  do {
    if (isalnum(*sp)) {
      emailAlnumCount++;
    }
  } while (*++sp);
  int emaillen = (int)strlen(email);
  return (emaillen <= 4) || (((float)emailAlnumCount / (float)emaillen) > 0.5);
};

const char *PlayerInfo::getToken() const {
  return token;
};

void PlayerInfo::clearToken() {
  token[0] = '\0';
};

void *PlayerInfo::packVirtualFlagCapture(void *buf) {
  buf = nboPackUShort(buf, uint16_t(int(team) - 1));
  buf = nboPackUShort(buf, uint16_t(1 + (int(team) % 4)));
  return buf;
};

bool PlayerInfo::isTeam(TeamColor _team) const {
  return team == _team;
};

bool PlayerInfo::isObserver() const {
  return team == ObserverTeam;
};

TeamColor PlayerInfo::getTeam() {
  return team;
};

void PlayerInfo::setTeam(TeamColor _team) {
  team = _team;
};

void PlayerInfo::wasARabbit() {
  team = RogueTeam;
  wasRabbit = true;
};

void PlayerInfo::wasNotARabbit() {
  wasRabbit = false;
};

void PlayerInfo::resetFlag() {
  flag = -1;
  lastFlagDropTime = now;
};

void PlayerInfo::setFlag(int _flag) {
  flag = _flag;
};

bool PlayerInfo::isFlagTransitSafe() {
  return now - lastFlagDropTime >= 2.0f;
};

const char *PlayerInfo::getClientVersion() {
  return clientVersion;
};

std::string PlayerInfo::getIdleStat() {
  std::string reply;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    reply = TextUtils::format("%-16s : %4ds", callSign,
				int(now - lastupdate));
    if (paused) {
      reply += TextUtils::format("  paused %4ds", int(now - pausedSince));
    }
  }
  return reply;
};

bool PlayerInfo::canBeRabbit(bool relaxing) {
  if (paused || notResponding || (team == ObserverTeam))
    return false;
  return relaxing ? (state > PlayerInLimbo) : (state == PlayerAlive);
};

void PlayerInfo::setPaused(bool _paused) {
  paused = _paused;
  pausedSince = now;
};

bool PlayerInfo::isTooMuchIdling(float kickThresh) {
  bool idling = false;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    int idletime = (int)(now - lastupdate);
    int pausetime = 0;
    if (paused && now - pausedSince > idletime)
      pausetime = (int)(now - pausedSince);
    idletime = idletime > pausetime ? idletime : pausetime;
    if (idletime
	> (now - lastmsg < kickThresh ? 3 * kickThresh : kickThresh)) {
      DEBUG1("Kicking player %s [%d] idle %d\n", callSign, playerIndex,
	     idletime);
      idling = true;
    }
  }
  return idling;
};

bool PlayerInfo::hasStartedToNotRespond() {
  float notRespondingTime = BZDB.eval(StateDatabase::BZDB_NOTRESPONDINGTIME);
  bool startingToNotRespond = false;
  if (state > PlayerInLimbo) {
    bool oldnr = notResponding;
    notResponding = (now - lastupdate) > notRespondingTime;
    if (!oldnr && notResponding)
      startingToNotRespond = true;
  }
  return startingToNotRespond;
}

void PlayerInfo::hasSent(char message[]) {
  lastmsg = now;
  DEBUG1("Player %s [%d]: %s\n", callSign, playerIndex, message);
};

bool PlayerInfo::hasPlayedEarly() {
  bool returnValue = playedEarly;
  playedEarly      = false;
  return returnValue;
};

void PlayerInfo::setPlayedEarly(bool early) {
  playedEarly = early;
};

void PlayerInfo::updateIdleTime() {
  lastupdate = now;
};

void	PlayerInfo::setReplayState(PlayerReplayState state) {
  replayState = state;
}

PlayerReplayState PlayerInfo::getReplayState()
{
  return replayState;
}

void PlayerInfo::setTrackerID(unsigned short int t)
{
  tracker = t;
}

unsigned short int PlayerInfo::trackerID()
{
  return tracker;
}

void PlayerInfo::setCurrentTime(TimeKeeper tm)
{
  now = tm;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>initialize clientVersion.  put back DEBUGn output of the rec'd version string<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "PlayerInfo.h"

/* system implementation headers */
#include <errno.h>
#include <string>

/* implementation-specific common headers */
#include "TextUtils.h"

WordFilter PlayerInfo::serverSpoofingFilter;
TimeKeeper PlayerInfo::now = TimeKeeper::getCurrent();

PlayerInfo::PlayerInfo(int _playerIndex) :
  playerIndex(_playerIndex), state(PlayerInLimbo), flag(-1),
  spamWarns(0), lastMsgTime(now), paused(false),
  pausedSince(TimeKeeper::getNullTime()), tracker(0)
{
  notResponding = false;
  memset(email, 0, EmailLen);
  memset(callSign, 0, CallSignLen);
  memset(token, 0, TokenLen);
  memset(clientVersion, 0, VersionLen);
}

void PlayerInfo::resetPlayer(bool ctf) {
  wasRabbit = false;

  lastupdate = now;
  lastmsg    = now;

  replayState = ReplayNone;

  playedEarly = false;

  restartOnBase = ctf;
}

void PlayerInfo::setRestartOnBase(bool on) {
  restartOnBase = on;
};

bool PlayerInfo::shouldRestartAtBase() {
  return restartOnBase;
};

void PlayerInfo::signingOn() {
  state = PlayerDead;
};

bool PlayerInfo::isAlive() {
  return state == PlayerAlive;
};

void PlayerInfo::setAlive() {
  state = PlayerAlive;
  flag = -1;
};

void PlayerInfo::setDead() {
  state = PlayerDead;
};

void *PlayerInfo::packUpdate(void *buf) {
  buf = nboPackUShort(buf, uint16_t(type));
  buf = nboPackUShort(buf, uint16_t(team));
  return buf;
};

void *PlayerInfo::packId(void *buf) {
  buf = nboPackString(buf, callSign, CallSignLen);
  buf = nboPackString(buf, email, EmailLen);
  return buf;
}

bool PlayerInfo::unpackEnter(void *buf, uint16_t &rejectCode, char *rejectMsg)
{
  // data: type, team, name, email
  uint16_t _type;
  int16_t _team;
  buf = nboUnpackUShort(buf, _type);
  buf = nboUnpackShort(buf, _team);
  type = PlayerType(_type);
  team = TeamColor(_team);
  buf = nboUnpackString(buf, callSign, CallSignLen);
  buf = nboUnpackString(buf, email, EmailLen);
  buf = nboUnpackString(buf, token, TokenLen);
  buf = nboUnpackString(buf, clientVersion, VersionLen);
  cleanEMail();

  DEBUG2("Player %s [%d] sent version string: %s\n",
	 callSign, playerIndex, clientVersion);

  // spoof filter holds "SERVER" for robust name comparisons
  if (serverSpoofingFilter.wordCount() == 0) {
    serverSpoofingFilter.addToFilter("SERVER", "");
  }

  if (!isCallSignReadable()) {
    DEBUG2("rejecting unreadable callsign: %s\n", callSign);
    rejectCode   = RejectBadCallsign;
    strcpy(rejectMsg, errorString.c_str());
    return false;
  }
  // no spoofing the server name
  if (serverSpoofingFilter.filter(callSign)) {
    rejectCode   = RejectRepeatCallsign;
    strcpy(rejectMsg, "The callsign specified is already in use.");
    return false;
  }
  if (!isEMailReadable()) {
    DEBUG2("rejecting unreadable player email: %s (%s)\n", callSign, email);
    rejectCode   = RejectBadEmail;
    strcpy(rejectMsg, "The e-mail was rejected.  Try a different e-mail.");
    return false;
  }
  return true;
};

const char *PlayerInfo::getCallSign() const {
  return callSign;
};

bool PlayerInfo::isCallSignReadable() {
  // callsign readability filter, make sure there are more alphanum than non
  // keep a count of alpha-numerics

  int callsignlen = (int)strlen(callSign);
  // reject less than 3 characters
  if (callsignlen < 3) {
    errorString = "Callsigns must be at least 3 characters.";
    return false;
  }

  // reject trailing space
  if (isspace(callSign[strlen(callSign) - 1])) {
    errorString = "Trailing spaces are not allowed in callsigns.";
    return false;
  }

  // start with true to reject leading space
  bool lastWasSpace = true;
  int alnumCount = 0;
  const char *sp = callSign;
  do {
    // reject sequential spaces
    if (lastWasSpace && isspace(*sp)) {
      errorString = "Leading or consecutive spaces are not allowed in callsigns.";
      return false;
    }

    // reject ' and " and any nonprintable
    if ((*sp == '\'') || (*sp == '"') || ((unsigned)*sp > 0x7f)
	|| !isprint(*sp)) {
      errorString = "Non-printable characters and quotes are not allowed in callsigns.";
      return false;
    }
    if (isspace(*sp)) {
      // only space is valid, not tab etc.
      if (*sp != ' ') {
	errorString = "Invalid whitespace in callsign.";
	return false;
      }
      lastWasSpace = true;
    } else {
      lastWasSpace = false;
      if (isalnum(*sp))
	alnumCount++;
    }
  } while (*++sp);
  return ((float)alnumCount / (float)callsignlen > 0.5f);
};

const char *PlayerInfo::getEMail() const {
  return email;
};

void PlayerInfo::cleanEMail() {
  // strip leading whitespace from email
  char *sp = email;
  char *tp = sp;
  while (isspace(*sp))
    sp++;

  // strip any non-printable characters and ' and " from email
  do {
    if (isprint(*sp) && (*sp != '\'') && (*sp != '"')) {
      *tp++ = *sp;
    }
  } while (*++sp);
  *tp = *sp;

  // strip trailing whitespace from email
  while (isspace(*--tp)) {
    *tp=0;
  }
};

bool PlayerInfo::isEMailReadable() {
  // email/"team" readability filter, make sure there are more
  // alphanum than non
  int emailAlnumCount = 0;
  char *sp = email;
  do {
    if (isalnum(*sp)) {
      emailAlnumCount++;
    }
  } while (*++sp);
  int emaillen = (int)strlen(email);
  return (emaillen <= 4) || (((float)emailAlnumCount / (float)emaillen) > 0.5);
};

const char *PlayerInfo::getToken() const {
  return token;
};

void PlayerInfo::clearToken() {
  token[0] = '\0';
};

void *PlayerInfo::packVirtualFlagCapture(void *buf) {
  buf = nboPackUShort(buf, uint16_t(int(team) - 1));
  buf = nboPackUShort(buf, uint16_t(1 + (int(team) % 4)));
  return buf;
};

bool PlayerInfo::isTeam(TeamColor _team) const {
  return team == _team;
};

bool PlayerInfo::isObserver() const {
  return team == ObserverTeam;
};

TeamColor PlayerInfo::getTeam() {
  return team;
};

void PlayerInfo::setTeam(TeamColor _team) {
  team = _team;
};

void PlayerInfo::wasARabbit() {
  team = RogueTeam;
  wasRabbit = true;
};

void PlayerInfo::wasNotARabbit() {
  wasRabbit = false;
};

void PlayerInfo::resetFlag() {
  flag = -1;
  lastFlagDropTime = now;
};

void PlayerInfo::setFlag(int _flag) {
  flag = _flag;
};

bool PlayerInfo::isFlagTransitSafe() {
  return now - lastFlagDropTime >= 2.0f;
};

const char *PlayerInfo::getClientVersion() {
  return clientVersion;
};

std::string PlayerInfo::getIdleStat() {
  std::string reply;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    reply = TextUtils::format("%-16s : %4ds", callSign,
				int(now - lastupdate));
    if (paused) {
      reply += TextUtils::format("  paused %4ds", int(now - pausedSince));
    }
  }
  return reply;
};

bool PlayerInfo::canBeRabbit(bool relaxing) {
  if (paused || notResponding || (team == ObserverTeam))
    return false;
  return relaxing ? (state > PlayerInLimbo) : (state == PlayerAlive);
};

void PlayerInfo::setPaused(bool _paused) {
  paused = _paused;
  pausedSince = now;
};

bool PlayerInfo::isTooMuchIdling(float kickThresh) {
  bool idling = false;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    int idletime = (int)(now - lastupdate);
    int pausetime = 0;
    if (paused && now - pausedSince > idletime)
      pausetime = (int)(now - pausedSince);
    idletime = idletime > pausetime ? idletime : pausetime;
    if (idletime
	> (now - lastmsg < kickThresh ? 3 * kickThresh : kickThresh)) {
      DEBUG1("Kicking player %s [%d] idle %d\n", callSign, playerIndex,
	     idletime);
      idling = true;
    }
  }
  return idling;
};

bool PlayerInfo::hasStartedToNotRespond() {
  float notRespondingTime = BZDB.eval(StateDatabase::BZDB_NOTRESPONDINGTIME);
  bool startingToNotRespond = false;
  if (state > PlayerInLimbo) {
    bool oldnr = notResponding;
    notResponding = (now - lastupdate) > notRespondingTime;
    if (!oldnr && notResponding)
      startingToNotRespond = true;
  }
  return startingToNotRespond;
}

void PlayerInfo::hasSent(char message[]) {
  lastmsg = now;
  DEBUG1("Player %s [%d]: %s\n", callSign, playerIndex, message);
};

bool PlayerInfo::hasPlayedEarly() {
  bool returnValue = playedEarly;
  playedEarly      = false;
  return returnValue;
};

void PlayerInfo::setPlayedEarly(bool early) {
  playedEarly = early;
};

void PlayerInfo::updateIdleTime() {
  lastupdate = now;
};

void	PlayerInfo::setReplayState(PlayerReplayState state) {
  replayState = state;
}

PlayerReplayState PlayerInfo::getReplayState()
{
  return replayState;
}

void PlayerInfo::setTrackerID(unsigned short int t)
{
  tracker = t;
}

unsigned short int PlayerInfo::trackerID()
{
  return tracker;
}

void PlayerInfo::setCurrentTime(TimeKeeper tm)
{
  now = tm;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include <cstdlib>

#include "connection.hpp"
#include "../common/assert.hpp"
#include "../common/message.hpp"
#include "../common/network/tcp_socket.hpp"

#include "rsg.pb.h"

namespace rsg
{
    thread_local Connection* connection = nullptr;
}

rsg::Connection::Connection()
{
    // Read RSG parameters from environment.
    const char * server_hostname = std::getenv("RSG_SERVER_HOSTNAME");
    RSG_ENFORCE(server_hostname != nullptr, "Invalid RSG connection initialization: RSG_SERVER_HOSTNAME is not set.");
    std::string hostname(server_hostname);

    const char * server_port = std::getenv("RSG_SERVER_PORT");
    RSG_ENFORCE(server_port != nullptr, "Invalid RSG connection initialization: RSG_SERVER_PORT is not set.");
    uint16_t port = 0;
    try
    {
        port = std::stoi(std::string(server_port));
    }
    catch (const rsg::Error & e)
    {
        throw rsg::Error("Invalid RSG connection initialization: RSG_SERVER_PORT ('%s') is not a valid port", server_port);
    }

    const char * initial_actor_id = nullptr;
    int actor_id = 0;
    try
    {
        initial_actor_id = std::getenv("RSG_INITIAL_ACTOR_ID");
        RSG_ENFORCE(initial_actor_id != nullptr, "Invalid RSG connection initialization: RSG_INITIAL_ACTOR_ID is not set.");
        try
        {
            actor_id = std::stoi(std::string(initial_actor_id));
        }
        catch(const std::exception & e)
        {
            throw rsg::Error("Invalid RSG connection initialization: RSG_INITIAL_ACTOR_ID ('%s') is not a valid actor id", initial_actor_id);
        }
    }
    catch (const rsg::Error & e)
    {
        fprintf(stdout, "Killing the server, as this process had no/invalid actor_id.\n");
        fflush(stdout);

        char kill_command[128];
        snprintf(kill_command, 128,
            "rsg kill --reason=\"could not connect: invalid actor_id '%s'\" -h %s -p %s",
            initial_actor_id, server_hostname, server_port);
        system(kill_command);

        throw;
    }

    // Connect to the server.
    _socket = new TcpSocket();
    _socket->connect(server_hostname, port);
    _socket->disable_nagle_algorithm();

    // Generate command.
    rsg::Command command;
    auto actor = new rsg::Actor();
    actor->set_id(actor_id);
    command.set_allocated_connect(actor);

    // Write message on socket.
    write_message(command, *_socket);

    // Read acknowledment.
    rsg::CommandAck command_ack;
    read_message(command_ack, *_socket);

    if (!command_ack.success())
        printf("connect failed\n");
}

rsg::Connection::~Connection()
{
    try
    {
        rsg::Decision decision;
        decision.set_quit(true);

        rsg::DecisionAck ack;
        write_message(decision, *_socket);
    }
    catch (const rsg::Error & e)
    {
        printf("Could not tell server that I want to quit: %s\n", e.what());
    }

    delete _socket;
    _socket = nullptr;
}

void rsg::Connection::send_decision(const rsg::Decision & decision, rsg::DecisionAck & decision_ack)
{
    write_message(decision, *_socket);
    read_message(decision_ack, *_socket);
}

void rsg::connect()
{
    RSG_ENFORCE(connection == nullptr, "Invalid rsg::connect() call: Already connected!");
    connection = new Connection();
}

static void autoconnect(void) __attribute__((constructor));
void autoconnect(void)
{
    if (std::getenv("RSG_AUTOCONNECT") != nullptr)
        rsg::connect();
}

void rsg::disconnect()
{
    delete rsg::connection;
    rsg::connection = nullptr;
}

static void autodisconnect(void) __attribute__((destructor));
void autodisconnect(void)
{
    rsg::disconnect();
}
<commit_msg>[code] remove system() warning<commit_after>#include <cstdlib>

#include "connection.hpp"
#include "../common/assert.hpp"
#include "../common/message.hpp"
#include "../common/network/tcp_socket.hpp"

#include "rsg.pb.h"

namespace rsg
{
    thread_local Connection* connection = nullptr;
}

rsg::Connection::Connection()
{
    // Read RSG parameters from environment.
    const char * server_hostname = std::getenv("RSG_SERVER_HOSTNAME");
    RSG_ENFORCE(server_hostname != nullptr, "Invalid RSG connection initialization: RSG_SERVER_HOSTNAME is not set.");
    std::string hostname(server_hostname);

    const char * server_port = std::getenv("RSG_SERVER_PORT");
    RSG_ENFORCE(server_port != nullptr, "Invalid RSG connection initialization: RSG_SERVER_PORT is not set.");
    uint16_t port = 0;
    try
    {
        port = std::stoi(std::string(server_port));
    }
    catch (const rsg::Error & e)
    {
        throw rsg::Error("Invalid RSG connection initialization: RSG_SERVER_PORT ('%s') is not a valid port", server_port);
    }

    const char * initial_actor_id = nullptr;
    int actor_id = 0;
    try
    {
        initial_actor_id = std::getenv("RSG_INITIAL_ACTOR_ID");
        RSG_ENFORCE(initial_actor_id != nullptr, "Invalid RSG connection initialization: RSG_INITIAL_ACTOR_ID is not set.");
        try
        {
            actor_id = std::stoi(std::string(initial_actor_id));
        }
        catch(const std::exception & e)
        {
            throw rsg::Error("Invalid RSG connection initialization: RSG_INITIAL_ACTOR_ID ('%s') is not a valid actor id", initial_actor_id);
        }
    }
    catch (const rsg::Error & e)
    {
        fprintf(stdout, "Killing the server, as this process had no/invalid actor_id.\n");
        fflush(stdout);

        char kill_command[128];
        snprintf(kill_command, 128,
            "rsg kill --reason=\"could not connect: invalid actor_id '%s'\" -h %s -p %s",
            initial_actor_id, server_hostname, server_port);
        int ret = system(kill_command);
        RSG_ENFORCE(ret != -1, "Could not kill server: Could not execute a `rsg` process.");
        RSG_ENFORCE(ret == 0 || ret == 1, "Could not kill server: `rsg kill` returned %d", ret);

        throw;
    }

    // Connect to the server.
    _socket = new TcpSocket();
    _socket->connect(server_hostname, port);
    _socket->disable_nagle_algorithm();

    // Generate command.
    rsg::Command command;
    auto actor = new rsg::Actor();
    actor->set_id(actor_id);
    command.set_allocated_connect(actor);

    // Write message on socket.
    write_message(command, *_socket);

    // Read acknowledment.
    rsg::CommandAck command_ack;
    read_message(command_ack, *_socket);

    if (!command_ack.success())
        printf("connect failed\n");
}

rsg::Connection::~Connection()
{
    try
    {
        rsg::Decision decision;
        decision.set_quit(true);

        rsg::DecisionAck ack;
        write_message(decision, *_socket);
    }
    catch (const rsg::Error & e)
    {
        printf("Could not tell server that I want to quit: %s\n", e.what());
    }

    delete _socket;
    _socket = nullptr;
}

void rsg::Connection::send_decision(const rsg::Decision & decision, rsg::DecisionAck & decision_ack)
{
    write_message(decision, *_socket);
    read_message(decision_ack, *_socket);
}

void rsg::connect()
{
    RSG_ENFORCE(connection == nullptr, "Invalid rsg::connect() call: Already connected!");
    connection = new Connection();
}

static void autoconnect(void) __attribute__((constructor));
void autoconnect(void)
{
    if (std::getenv("RSG_AUTOCONNECT") != nullptr)
        rsg::connect();
}

void rsg::disconnect()
{
    delete rsg::connection;
    rsg::connection = nullptr;
}

static void autodisconnect(void) __attribute__((destructor));
void autodisconnect(void)
{
    rsg::disconnect();
}
<|endoftext|>


<commit_before>// Copyright 2016 Annotator Team
#define Annotator_AnnotatorLib_Annotation_BODY

/************************************************************
 Annotation class body
 ************************************************************/

#include <assert.h>
#include <algorithm>
#include <cmath>
#include <iostream>
// include associated header file
#include "AnnotatorLib/Annotation.h"
#include "AnnotatorLib/Frame.h"
#include "AnnotatorLib/Object.h"

namespace AnnotatorLib {

////////////////// statics /////////////////////

unsigned long Annotation::genId(const std::shared_ptr<Frame> frame,
                                const std::shared_ptr<Object> obj) {
  // Cantor’s Pairing Function
  return (std::pow(frame->getId(), 2) + 3 * frame->getId() +
          2 * frame->getId() * obj->getId() + obj->getId() +
          std::pow(obj->getId(), 2)) /
         2;
}

//////////////// constructors ///////////////////

Annotation::Annotation(shared_ptr<Frame> frame, shared_ptr<Object> obj,
                       AnnotationType type)
    : Annotation(genId(frame, obj), frame, obj, type) {}

Annotation::Annotation(shared_ptr<Annotation> a, shared_ptr<Frame> frame,
                       bool isInterpolated)
    : Annotation(genId(frame, a->getObject()), frame, a->getObject(),
                 a->getType(), isInterpolated) {
  this->setPosition(a->getX(), a->getY(), a->getWidth(), a->getHeight());
}

Annotation::Annotation(unsigned long id, const shared_ptr<Frame> &frame,
                       const shared_ptr<Object> &obj, const AnnotationType type,
                       bool isInterpolated)
    : id(id),
      frame(frame),
      object(obj),
      type(type),
      is_temporary(isInterpolated) {}

//////////////// public methods ///////////////////

bool Annotation::operator>(const Annotation &right) const {
  return *this->frame > *right.frame;
}

bool Annotation::operator<(const Annotation &right) const {
  return *this->frame < *right.frame;
}

bool Annotation::operator<=(const Annotation &right) const {
  return *this->frame <= *right.frame;
}

bool Annotation::operator>=(const Annotation &right) const {
  return *this->frame >= *right.frame;
}

bool Annotation::operator==(const Annotation &right) const {
  return *this->frame == *right.frame;
}

bool Annotation::operator!=(const Annotation &right) const {
  return *this->frame != *right.frame;
}

unsigned long Annotation::getId() const { return id; }

std::vector<shared_ptr<Attribute>> const &Annotation::getAttributes() const {
  return attributes;
}

bool Annotation::addAttribute(shared_ptr<Attribute> attribute) {
  if (attribute &&
      std::find(attributes.begin(), attributes.end(), attribute) ==
          attributes.end()) {
    attributes.push_back(attribute);
    return true;
  }
  return false;
}

bool Annotation::removeAttribute(shared_ptr<Attribute> attribute) {
  std::vector<shared_ptr<Attribute>>::const_iterator position =
      std::find(attributes.begin(), attributes.end(), attribute);
  if (position != attributes.end()) {
    attributes.erase(position);
    return true;
  }
  return false;
}

shared_ptr<Frame> Annotation::getFrame() const { return frame; }

shared_ptr<Object> Annotation::getObject() const { return object; }

AnnotationType Annotation::getType() const { return this->type; }

void Annotation::setCenterPosition(float x, float y, float hradius,
                                   float vradius) {
  setX(x);
  setY(y);
  setHRadius(hradius);
  setVRadius(vradius);
}

float Annotation::getX() const { return x; }

void Annotation::setX(float x) { this->x = x; }

float Annotation::getY() const { return y; }

void Annotation::setY(float y) { this->y = y; }

float Annotation::getWidth() const { return width; }

void Annotation::setWidth(float width) {
  assert(width > 0);
  this->width = width;
}

float Annotation::getHeight() const { return height; }

void Annotation::setHeight(float height) {
  assert(height > 0);
  this->height = height;
}

float Annotation::getHRadius() const { return width / 2; }

void Annotation::setHRadius(float hradius) {
  assert(hradius > 0);
  if (hradius < 0) hradius *= -1;
  this->width = hradius * 2;
}

float Annotation::getVRadius() const { return height / 2; }

void Annotation::setVRadius(float vradius) {
  assert(vradius > 0);
  if (vradius < 0) vradius *= -1;
  this->height = vradius * 2;
}

float Annotation::getConfidenceScore() { return confidence; }

void Annotation::setConfidenceScore(float conf) {
  assert(conf >= 0.0f);
  assert(conf <= 1.0f);
  confidence = conf;
}

void Annotation::setSelf(weak_ptr<Annotation> self) { this->self_ = self; }

void Annotation::setNext(weak_ptr<Annotation> next) {
  assert(!next.lock() || *this->frame <= *next.lock()->getFrame());
  this->next = next;
}

shared_ptr<Annotation> Annotation::getNext() const {
  if (next.expired()) return shared_ptr<Annotation>(nullptr);
  return next.lock();
}

bool Annotation::hasNext() const {
  return (next.lock().get() != nullptr && next.lock().get() != this);
}

void Annotation::setPrevious(weak_ptr<Annotation> previous) {
  assert(!previous.lock() || *this->frame >= *previous.lock()->getFrame());
  this->previous = previous;
}

shared_ptr<Annotation> Annotation::getPrevious() const {
  if (previous.expired()) return shared_ptr<Annotation>(nullptr);
  return previous.lock();
}

shared_ptr<Annotation> Annotation::getFirst() {
  return object->getFirstAnnotation();
}

shared_ptr<Annotation> Annotation::getLast() {
  return object->getLastAnnotation();
}

bool Annotation::isLast() const {
  return !this->next.lock() || this->next.lock().get() == this;
}

bool Annotation::isFirst() const { return !this->previous.lock(); }

bool Annotation::isTemporary() const { return is_temporary; }

bool Annotation::isRegistered() const { return registered; }

bool Annotation::setRegistered(bool do_register) {
  if (isTemporary()) return false;
  if (do_register && !registered) {
    this->getObject()->addAnnotation(self_);
    this->getFrame()->addAnnotation(self_);
  }
  if (!do_register && registered) {
    this->getObject()->removeAnnotation(frame->getFrameNumber());
    this->getFrame()->removeAnnotation(id);
  }
  registered = do_register;
  return true;
}

void Annotation::setPosition(float x, float y) {
  this->x = x;
  this->y = y;
}

void Annotation::setPosition(float x, float y, float width, float height) {
  setX(x);
  setY(y);
  setWidth(width);
  setHeight(height);
}

//////////////// private static methods ///////////////////

void Annotation::registerAnnotation(const shared_ptr<Annotation> a, bool r) {
  a->setRegistered(r);
}

void Annotation::registerAnnotation(const shared_ptr<Annotation> a) {
  a->setRegistered(true);
}

void Annotation::unregisterAnnotation(const shared_ptr<Annotation> a) {
  a->setRegistered(false);
}

}  // End of namespace AnnotatorLib

/************************************************************
 End of Annotation class body
 ************************************************************/
<commit_msg>const_iterator to iterator to circumvent gvv4.8 bug<commit_after>// Copyright 2016 Annotator Team
#define Annotator_AnnotatorLib_Annotation_BODY

/************************************************************
 Annotation class body
 ************************************************************/

#include <assert.h>
#include <algorithm>
#include <cmath>
#include <iostream>
// include associated header file
#include "AnnotatorLib/Annotation.h"
#include "AnnotatorLib/Frame.h"
#include "AnnotatorLib/Object.h"

namespace AnnotatorLib {

////////////////// statics /////////////////////

unsigned long Annotation::genId(const std::shared_ptr<Frame> frame,
                                const std::shared_ptr<Object> obj) {
  // Cantor’s Pairing Function
  return (std::pow(frame->getId(), 2) + 3 * frame->getId() +
          2 * frame->getId() * obj->getId() + obj->getId() +
          std::pow(obj->getId(), 2)) /
         2;
}

//////////////// constructors ///////////////////

Annotation::Annotation(shared_ptr<Frame> frame, shared_ptr<Object> obj,
                       AnnotationType type)
    : Annotation(genId(frame, obj), frame, obj, type) {}

Annotation::Annotation(shared_ptr<Annotation> a, shared_ptr<Frame> frame,
                       bool isInterpolated)
    : Annotation(genId(frame, a->getObject()), frame, a->getObject(),
                 a->getType(), isInterpolated) {
  this->setPosition(a->getX(), a->getY(), a->getWidth(), a->getHeight());
}

Annotation::Annotation(unsigned long id, const shared_ptr<Frame> &frame,
                       const shared_ptr<Object> &obj, const AnnotationType type,
                       bool isInterpolated)
    : id(id),
      frame(frame),
      object(obj),
      type(type),
      is_temporary(isInterpolated) {}

//////////////// public methods ///////////////////

bool Annotation::operator>(const Annotation &right) const {
  return *this->frame > *right.frame;
}

bool Annotation::operator<(const Annotation &right) const {
  return *this->frame < *right.frame;
}

bool Annotation::operator<=(const Annotation &right) const {
  return *this->frame <= *right.frame;
}

bool Annotation::operator>=(const Annotation &right) const {
  return *this->frame >= *right.frame;
}

bool Annotation::operator==(const Annotation &right) const {
  return *this->frame == *right.frame;
}

bool Annotation::operator!=(const Annotation &right) const {
  return *this->frame != *right.frame;
}

unsigned long Annotation::getId() const { return id; }

std::vector<shared_ptr<Attribute>> const &Annotation::getAttributes() const {
  return attributes;
}

bool Annotation::addAttribute(shared_ptr<Attribute> attribute) {
  if (attribute &&
      std::find(attributes.begin(), attributes.end(), attribute) ==
          attributes.end()) {
    attributes.push_back(attribute);
    return true;
  }
  return false;
}

bool Annotation::removeAttribute(shared_ptr<Attribute> attribute) {
  std::vector<shared_ptr<Attribute>>::iterator position =
      std::find(attributes.begin(), attributes.end(), attribute);
  if (position != attributes.end()) {
    attributes.erase(position);
    return true;
  }
  return false;
}

shared_ptr<Frame> Annotation::getFrame() const { return frame; }

shared_ptr<Object> Annotation::getObject() const { return object; }

AnnotationType Annotation::getType() const { return this->type; }

void Annotation::setCenterPosition(float x, float y, float hradius,
                                   float vradius) {
  setX(x);
  setY(y);
  setHRadius(hradius);
  setVRadius(vradius);
}

float Annotation::getX() const { return x; }

void Annotation::setX(float x) { this->x = x; }

float Annotation::getY() const { return y; }

void Annotation::setY(float y) { this->y = y; }

float Annotation::getWidth() const { return width; }

void Annotation::setWidth(float width) {
  assert(width > 0);
  this->width = width;
}

float Annotation::getHeight() const { return height; }

void Annotation::setHeight(float height) {
  assert(height > 0);
  this->height = height;
}

float Annotation::getHRadius() const { return width / 2; }

void Annotation::setHRadius(float hradius) {
  assert(hradius > 0);
  if (hradius < 0) hradius *= -1;
  this->width = hradius * 2;
}

float Annotation::getVRadius() const { return height / 2; }

void Annotation::setVRadius(float vradius) {
  assert(vradius > 0);
  if (vradius < 0) vradius *= -1;
  this->height = vradius * 2;
}

float Annotation::getConfidenceScore() { return confidence; }

void Annotation::setConfidenceScore(float conf) {
  assert(conf >= 0.0f);
  assert(conf <= 1.0f);
  confidence = conf;
}

void Annotation::setSelf(weak_ptr<Annotation> self) { this->self_ = self; }

void Annotation::setNext(weak_ptr<Annotation> next) {
  assert(!next.lock() || *this->frame <= *next.lock()->getFrame());
  this->next = next;
}

shared_ptr<Annotation> Annotation::getNext() const {
  if (next.expired()) return shared_ptr<Annotation>(nullptr);
  return next.lock();
}

bool Annotation::hasNext() const {
  return (next.lock().get() != nullptr && next.lock().get() != this);
}

void Annotation::setPrevious(weak_ptr<Annotation> previous) {
  assert(!previous.lock() || *this->frame >= *previous.lock()->getFrame());
  this->previous = previous;
}

shared_ptr<Annotation> Annotation::getPrevious() const {
  if (previous.expired()) return shared_ptr<Annotation>(nullptr);
  return previous.lock();
}

shared_ptr<Annotation> Annotation::getFirst() {
  return object->getFirstAnnotation();
}

shared_ptr<Annotation> Annotation::getLast() {
  return object->getLastAnnotation();
}

bool Annotation::isLast() const {
  return !this->next.lock() || this->next.lock().get() == this;
}

bool Annotation::isFirst() const { return !this->previous.lock(); }

bool Annotation::isTemporary() const { return is_temporary; }

bool Annotation::isRegistered() const { return registered; }

bool Annotation::setRegistered(bool do_register) {
  if (isTemporary()) return false;
  if (do_register && !registered) {
    this->getObject()->addAnnotation(self_);
    this->getFrame()->addAnnotation(self_);
  }
  if (!do_register && registered) {
    this->getObject()->removeAnnotation(frame->getFrameNumber());
    this->getFrame()->removeAnnotation(id);
  }
  registered = do_register;
  return true;
}

void Annotation::setPosition(float x, float y) {
  this->x = x;
  this->y = y;
}

void Annotation::setPosition(float x, float y, float width, float height) {
  setX(x);
  setY(y);
  setWidth(width);
  setHeight(height);
}

//////////////// private static methods ///////////////////

void Annotation::registerAnnotation(const shared_ptr<Annotation> a, bool r) {
  a->setRegistered(r);
}

void Annotation::registerAnnotation(const shared_ptr<Annotation> a) {
  a->setRegistered(true);
}

void Annotation::unregisterAnnotation(const shared_ptr<Annotation> a) {
  a->setRegistered(false);
}

}  // End of namespace AnnotatorLib

/************************************************************
 End of Annotation class body
 ************************************************************/
<|endoftext|>


<commit_before>#include <util/text.h>
#include <util/vector.h>
#include <kernel/kstd.h>
#include <stdarg.h>

namespace util {

    void push_string(util::vector<char>& vec, const char* str) {
        //While the string is not over
        while(*str != '\0') {
            vec.push_back(*str);
            str++;
        }
    }

    char* vector_as_string(util::vector<char>& vec) {
        char* str = new char[vec.size()+1];
        for(unsigned int i = 0; i < vec.size(); i++) {
            str[i] = vec[i];
        }
        str[vec.size()] = '\0';
        return str;
    }

    char* vsformat(const char* fmt, va_list args) {
        vector<char> vec;
        //While we have some format characters
        while(*fmt != '\0') {
            //is it special?
            if(*fmt == '%') {
                //Advance it
                fmt++;
                char c = *fmt;
                if(c == '%') {
                    //Double % - just counts as one
                    vec.push_back(c);
                } else if (c == 'd') {
                    //print integer in decimal form
                    int x = va_arg(args, int);
                    push_string(vec, kstd::itoa(x).str);
                } else if (c == 'x') {
                    //hex
                    int x = va_arg(args, int);
                    push_string(vec, "0x");
                    push_string(vec, kstd::itoa(x,16).str);
                }
            } else {
                //no - just add it to the vector
                vec.push_back(*fmt);
            }
            //Advance
            fmt++;
        }
        //Now return the string represented in this vector
        return vector_as_string(vec);
    }

    char* format(const char* fmt, ...) {
        vector<char> vec;
        va_list args;
        va_start(args, fmt);
        //While we have some format characters
        char* res = vsformat(fmt, args);
        va_end(args);
        //Now return the string represented in this vector
        return res;
    }

    void printf(const char* fmt, ...) {
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::puts(str);
        delete str;
    }
    void logf(const char* fmt, ...){
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::log(str);
        delete str;
    }
    void panicf(const char* fmt, ...){
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::panic(str);
        delete str;
    }
};<commit_msg>Panic now fixed. Also moved out of any namespace<commit_after>#include <util/text.h>
#include <util/vector.h>
#include <kernel/kstd.h>
#include <stdarg.h>

namespace util {

    void push_string(util::vector<char>& vec, const char* str) {
        //While the string is not over
        while(*str != '\0') {
            vec.push_back(*str);
            str++;
        }
    }

    char* vector_as_string(util::vector<char>& vec) {
        char* str = new char[vec.size()+1];
        for(unsigned int i = 0; i < vec.size(); i++) {
            str[i] = vec[i];
        }
        str[vec.size()] = '\0';
        return str;
    }

    char* vsformat(const char* fmt, va_list args) {
        vector<char> vec;
        //While we have some format characters
        while(*fmt != '\0') {
            //is it special?
            if(*fmt == '%') {
                //Advance it
                fmt++;
                char c = *fmt;
                if(c == '%') {
                    //Double % - just counts as one
                    vec.push_back(c);
                } else if (c == 'd') {
                    //print integer in decimal form
                    int x = va_arg(args, int);
                    push_string(vec, kstd::itoa(x).str);
                } else if (c == 'x') {
                    //hex
                    int x = va_arg(args, int);
                    push_string(vec, "0x");
                    push_string(vec, kstd::itoa(x,16).str);
                } else if (c == 's') {
                    //String within a string
                    char* s = va_arg(args, char*);
                    push_string(vec, s);
                }
            } else {
                //no - just add it to the vector
                vec.push_back(*fmt);
            }
            //Advance
            fmt++;
        }
        //Now return the string represented in this vector
        return vector_as_string(vec);
    }

    char* format(const char* fmt, ...) {
        vector<char> vec;
        va_list args;
        va_start(args, fmt);
        //While we have some format characters
        char* res = vsformat(fmt, args);
        va_end(args);
        //Now return the string represented in this vector
        return res;
    }

    void printf(const char* fmt, ...) {
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::puts(str);
        delete str;
    }
    void logf(const char* fmt, ...){
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::log(str);
        delete str;
    }
    void panicf(const char* fmt, ...){
        va_list args;
        va_start(args, fmt);
        char* str = vsformat(fmt, args);
        va_end(args);

        kstd::panic(str);
        delete str;
    }
};<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <string>
#include <cstdlib>
#include <mutex>
#include <math.h>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include <nix/util/util.hpp>

using namespace std;

namespace nix {
namespace util {

// default id base (16 or 32)
const int    ID_BASE = 32;
// Base32hex alphabet (RFC 4648)
const char*  ID_ALPHABET = "0123456789abcdefghijklmnopqrstuv";
// Unit scaling, SI only, substitutions for micro and ohm...
const string  PREFIXES = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|u|n|p|f|a|z|y)";
const string  UNITS = "(m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L|Ohm|%|dB)";
const string  POWER = "(\\^[+-]?[1-9]\\d*)";

const map<string, double> PREFIX_FACTORS = {{"y", 1.0e-24}, {"z", 1.0e-21}, {"a", 1.0e-18}, {"f", 1.0e-15},
    {"p", 1.0e-12}, {"n",1.0e-9}, {"u", 1.0e-6}, {"m", 1.0e-3}, {"c", 1.0e-2}, {"d",1.0e-1}, {"da", 1.0e1}, {"h", 1.0e2},
    {"k", 1.0e3}, {"M",1.0e6}, {"G", 1.0e9}, {"T", 1.0e12}, {"P", 1.0e15}, {"E",1.0e18}, {"Z", 1.0e21}, {"Y", 1.0e24}};

string createId(string prefix, int length) {
    static std::once_flag rand_init;
    std::call_once(rand_init, []() { srand(static_cast<unsigned int>(time(0))); });

    string id;
    if (prefix.length() > 0) {
        id.append(prefix);
        id.append("_");
    }
    for (int i = 0; i < length; i++) {
        char c = ID_ALPHABET[(size_t) (((double) (rand())) / RAND_MAX * ID_BASE)];
        id.push_back(c);
    }
    return id;
}

string timeToStr(time_t time) {
    using namespace boost::posix_time;
    ptime timetmp = from_time_t(time);
    return to_iso_string(timetmp);
}

time_t strToTime(const string &time) {
    using namespace boost::posix_time;
    ptime timetmp(from_iso_string(time));
    ptime epoch(boost::gregorian::date(1970, 1, 1));
    return (timetmp - epoch).total_seconds();
}

time_t getTime() {
    return time(NULL);
}

void deblankString(std::string &str) {
    typedef std::string::value_type char_type;

    str.erase(std::remove_if(str.begin(),
                             str.end(),
                             [](char_type c) { return std::isblank(c); }),
              str.end());
}

std::string deblankString(const std::string &str) {
    std::string str_copy = str;
    deblankString(str_copy);
    return str_copy;
}

std::string unitSanitizer(const std::string &unit) {
     std::string new_unit = deblankString(unit);
     while (new_unit.find("mu") != string::npos) {
          size_t pos = new_unit.find("mu");
          new_unit = new_unit.replace(pos, 2, "u");

     }
     while (new_unit.find("µ") != string::npos) {
          size_t pos = new_unit.find("µ");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     return new_unit;
}

void splitUnit(const string &combinedUnit, string &prefix, string &unit, string &power) {
    boost::regex prefix_and_unit_and_power(PREFIXES + UNITS + POWER);
    boost::regex prefix_and_unit(PREFIXES + UNITS);
    boost::regex unit_and_power(UNITS + POWER);
    boost::regex unit_only(UNITS);
    boost::regex prefix_only(PREFIXES);

    if (boost::regex_match(combinedUnit, prefix_and_unit_and_power)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        string suffix = m.suffix();
        boost::regex_search(suffix, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, unit_and_power)) {
        prefix = "";
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, prefix_and_unit)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        unit = m.suffix();
        power = "";
    } else {
        unit = combinedUnit;
        prefix = "";
        power = "";
    }
}

void splitCompoundUnit(const std::string &compoundUnit, std::vector<std::string> &atomicUnits) {
    string s = compoundUnit;
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    boost::regex separator("(\\*|/)");
    boost::match_results<std::string::const_iterator> m;

    while (boost::regex_search(s, m, opt_prefix_and_unit_and_power) && (m.suffix().length() > 0)) {
        string suffix = m.suffix();
        atomicUnits.push_back(m[0]);
        s = suffix.substr(1);
    }
    atomicUnits.push_back(m[0]);
}

bool isSIUnit(const string &unit) {
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    return boost::regex_match(unit, opt_prefix_and_unit_and_power);
}

bool isCompoundSIUnit(const string &unit) {
    string atomic_unit = PREFIXES + "?" + UNITS + POWER + "?";
    boost::regex compound_unit("(" + atomic_unit + "(\\*|/))+"+ atomic_unit);
    return boost::regex_match(unit, compound_unit);
}

bool isScalable(const string &unitA, const string &unitB) {
    try {
        getSIScaling(unitA, unitB);
        return true;
    } catch (...) {
        return false;
    }
}

double getSIScaling(const string &originUnit, const string &destinationUnit) {
    double scaling = 1.0;
    if (isSIUnit(originUnit) && isSIUnit(destinationUnit)) {
        string org_unit, org_prefix, org_power;
        string dest_unit, dest_prefix, dest_power;
        splitUnit(originUnit, org_prefix, org_unit, org_power);
        splitUnit(destinationUnit, dest_prefix, dest_unit, dest_power);

        if (!(dest_unit == org_unit) || !(org_power == dest_power) ) {
            throw nix::InvalidUnit("Origin unit and/or destination units cannot be scaled!", "nix::util::getSIScaling");
        }
        if ((org_prefix == dest_prefix) && (org_power == dest_power)) {
            return scaling;
        }
        if (dest_prefix.empty() && !org_prefix.empty()) {
            scaling = PREFIX_FACTORS.at(org_prefix);
        } else if (org_prefix.empty() && !dest_prefix.empty()) {
            scaling = 1.0 / PREFIX_FACTORS.at(dest_prefix);
        } else if (!org_prefix.empty() && !dest_prefix.empty()) {
            scaling = PREFIX_FACTORS.at(org_prefix) / PREFIX_FACTORS.at(dest_prefix);
        }
        if (!org_power.empty()) {
            int power = std::stoi(org_power);
            scaling = pow(scaling, power);
        }
    } else {
        throw nix::InvalidUnit("Origin unit and/or destination unit are not valid!", "nix::util::getSIScaling");
    }
    return scaling;
}

} // namespace util
} // namespace nix
<commit_msg>move checks from util::getSIScaling to util::isScalable<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <string>
#include <cstdlib>
#include <mutex>
#include <math.h>

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
#include <nix/util/util.hpp>

using namespace std;

namespace nix {
namespace util {

// default id base (16 or 32)
const int    ID_BASE = 32;
// Base32hex alphabet (RFC 4648)
const char*  ID_ALPHABET = "0123456789abcdefghijklmnopqrstuv";
// Unit scaling, SI only, substitutions for micro and ohm...
const string  PREFIXES = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|u|n|p|f|a|z|y)";
const string  UNITS = "(m|g|s|A|K|mol|cd|Hz|N|Pa|J|W|C|V|F|S|Wb|T|H|lm|lx|Bq|Gy|Sv|kat|l|L|Ohm|%|dB)";
const string  POWER = "(\\^[+-]?[1-9]\\d*)";

const map<string, double> PREFIX_FACTORS = {{"y", 1.0e-24}, {"z", 1.0e-21}, {"a", 1.0e-18}, {"f", 1.0e-15},
    {"p", 1.0e-12}, {"n",1.0e-9}, {"u", 1.0e-6}, {"m", 1.0e-3}, {"c", 1.0e-2}, {"d",1.0e-1}, {"da", 1.0e1}, {"h", 1.0e2},
    {"k", 1.0e3}, {"M",1.0e6}, {"G", 1.0e9}, {"T", 1.0e12}, {"P", 1.0e15}, {"E",1.0e18}, {"Z", 1.0e21}, {"Y", 1.0e24}};

string createId(string prefix, int length) {
    static std::once_flag rand_init;
    std::call_once(rand_init, []() { srand(static_cast<unsigned int>(time(0))); });

    string id;
    if (prefix.length() > 0) {
        id.append(prefix);
        id.append("_");
    }
    for (int i = 0; i < length; i++) {
        char c = ID_ALPHABET[(size_t) (((double) (rand())) / RAND_MAX * ID_BASE)];
        id.push_back(c);
    }
    return id;
}

string timeToStr(time_t time) {
    using namespace boost::posix_time;
    ptime timetmp = from_time_t(time);
    return to_iso_string(timetmp);
}

time_t strToTime(const string &time) {
    using namespace boost::posix_time;
    ptime timetmp(from_iso_string(time));
    ptime epoch(boost::gregorian::date(1970, 1, 1));
    return (timetmp - epoch).total_seconds();
}

time_t getTime() {
    return time(NULL);
}

void deblankString(std::string &str) {
    typedef std::string::value_type char_type;

    str.erase(std::remove_if(str.begin(),
                             str.end(),
                             [](char_type c) { return std::isblank(c); }),
              str.end());
}

std::string deblankString(const std::string &str) {
    std::string str_copy = str;
    deblankString(str_copy);
    return str_copy;
}

std::string unitSanitizer(const std::string &unit) {
     std::string new_unit = deblankString(unit);
     while (new_unit.find("mu") != string::npos) {
          size_t pos = new_unit.find("mu");
          new_unit = new_unit.replace(pos, 2, "u");

     }
     while (new_unit.find("µ") != string::npos) {
          size_t pos = new_unit.find("µ");
          new_unit = new_unit.replace(pos, 2, "u");
     }
     return new_unit;
}

void splitUnit(const string &combinedUnit, string &prefix, string &unit, string &power) {
    boost::regex prefix_and_unit_and_power(PREFIXES + UNITS + POWER);
    boost::regex prefix_and_unit(PREFIXES + UNITS);
    boost::regex unit_and_power(UNITS + POWER);
    boost::regex unit_only(UNITS);
    boost::regex prefix_only(PREFIXES);

    if (boost::regex_match(combinedUnit, prefix_and_unit_and_power)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        string suffix = m.suffix();
        boost::regex_search(suffix, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, unit_and_power)) {
        prefix = "";
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, unit_only);
        unit = m[0];
        power = m.suffix();
        power = power.substr(1);
    } else if (boost::regex_match(combinedUnit, prefix_and_unit)) {
        boost::match_results<std::string::const_iterator> m;
        boost::regex_search(combinedUnit, m, prefix_only);
        prefix = m[0];
        unit = m.suffix();
        power = "";
    } else {
        unit = combinedUnit;
        prefix = "";
        power = "";
    }
}

void splitCompoundUnit(const std::string &compoundUnit, std::vector<std::string> &atomicUnits) {
    string s = compoundUnit;
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    boost::regex separator("(\\*|/)");
    boost::match_results<std::string::const_iterator> m;

    while (boost::regex_search(s, m, opt_prefix_and_unit_and_power) && (m.suffix().length() > 0)) {
        string suffix = m.suffix();
        atomicUnits.push_back(m[0]);
        s = suffix.substr(1);
    }
    atomicUnits.push_back(m[0]);
}

bool isSIUnit(const string &unit) {
    boost::regex opt_prefix_and_unit_and_power(PREFIXES + "?" + UNITS + POWER + "?");
    return boost::regex_match(unit, opt_prefix_and_unit_and_power);
}

bool isCompoundSIUnit(const string &unit) {
    string atomic_unit = PREFIXES + "?" + UNITS + POWER + "?";
    boost::regex compound_unit("(" + atomic_unit + "(\\*|/))+"+ atomic_unit);
    return boost::regex_match(unit, compound_unit);
}

bool isScalable(const string &unitA, const string &unitB) {
    if (!(isSIUnit(unitA) && isSIUnit(unitB))) {
        return false;
    }
    string a_unit, a_prefix, a_power;
    string b_unit, b_prefix, b_power;
    splitUnit(unitA, a_prefix, a_unit, a_power);
    splitUnit(unitB, b_prefix, b_unit, b_power);
    if (!(a_unit == b_unit) || !(a_power == b_power) ) {
        return false;
    }
    return true;
}

double getSIScaling(const string &originUnit, const string &destinationUnit) {
    double scaling = 1.0;
    if (!isScalable(originUnit, destinationUnit)) {
        throw nix::InvalidUnit("Origin unit and destination unit are not scalable versions of the same SI unit!",
                               "nix::util::getSIScaling");
    }

    string org_unit, org_prefix, org_power;
    string dest_unit, dest_prefix, dest_power;
    splitUnit(originUnit, org_prefix, org_unit, org_power);
    splitUnit(destinationUnit, dest_prefix, dest_unit, dest_power);

    if ((org_prefix == dest_prefix) && (org_power == dest_power)) {
        return scaling;
    }
    if (dest_prefix.empty() && !org_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix);
    } else if (org_prefix.empty() && !dest_prefix.empty()) {
        scaling = 1.0 / PREFIX_FACTORS.at(dest_prefix);
    } else if (!org_prefix.empty() && !dest_prefix.empty()) {
        scaling = PREFIX_FACTORS.at(org_prefix) / PREFIX_FACTORS.at(dest_prefix);
    }
    if (!org_power.empty()) {
        int power = std::stoi(org_power);
        scaling = pow(scaling, power);
    }
    return scaling;
}

} // namespace util
} // namespace nix
<|endoftext|>