<commit_before>#include <cybozu/test.hpp>
#include <cybozu/zlib.hpp>
#include <cybozu/file.hpp>
#include <cybozu/stream.hpp>
#include <cybozu/serializer.hpp>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

CYBOZU_TEST_AUTO(test1_deflate)
{
	typedef cybozu::ZlibCompressorT<std::stringstream> Compressor;
	typedef cybozu::ZlibDecompressorT<std::stringstream> Decompressor;
	const std::string in = "this is a pen";

	std::stringstream os;
	{
		Compressor comp(os);
		comp.write(in.c_str(), in.size());
		comp.flush();
	}
	const std::string enc = os.str();

	const char encTbl[] = "\x78\x9c\x2b\xc9\xc8\x2c\x56\x00\xa2\x44\x85\x82\xd4\x3c\x00\x21\x0c\x04\x99";

	const std::string encOk(encTbl, encTbl + sizeof(encTbl) - 1);
	CYBOZU_TEST_EQUAL(enc, encOk);

	std::stringstream is;
	is << encOk;

	{
		Decompressor dec(is);
		char buf[2048];
		std::string out;
		for (;;) {
			size_t size = dec.read(buf, sizeof(buf));
			if (size == 0) break;
			out.append(buf, buf + size);
		}
		CYBOZU_TEST_EQUAL(in, out);
	}
}

CYBOZU_TEST_AUTO(test2_deflate)
{
	typedef cybozu::ZlibCompressorT<std::stringstream, 1> Compressor;
	typedef cybozu::ZlibDecompressorT<std::stringstream, 1> Decompressor;
	const std::string in = "this is a pen";

	std::stringstream os;
	{
		Compressor comp(os);
		for (size_t i = 0; i < in.size(); i++) {
			comp.write(&in[i], 1);
		}
		comp.flush();
	}
	const std::string enc = os.str();

	const char encTbl[] = "\x78\x9c\x2b\xc9\xc8\x2c\x56\x00\xa2\x44\x85\x82\xd4\x3c\x00\x21\x0c\x04\x99";

	const std::string encOk(encTbl, encTbl + sizeof(encTbl) - 1);
	CYBOZU_TEST_EQUAL(enc, encOk);

	std::stringstream is;
	is << encOk;

	{
		Decompressor dec(is);
		char buf[2048];
		std::string out;
		for (;;) {
			size_t size = dec.read(buf, sizeof(buf));
			if (size == 0) break;
			out.append(buf, buf + size);
		}
		CYBOZU_TEST_EQUAL(in, out);
	}
}

CYBOZU_TEST_AUTO(enc_and_dec)
{
	std::string body = "From: cybozu\r\n"
				 "To: cybozu\r\n"
				 "\r\n"
				 "hello with zlib compressed\r\n"
				 ".\r\n";
	std::stringstream ss;
	cybozu::ZlibCompressorT<std::stringstream> comp(ss);
	comp.write(&body[0], body.size());
	comp.flush();

	std::string enc = ss.str();

	cybozu::StringInputStream ims(enc);

	cybozu::ZlibDecompressorT<cybozu::StringInputStream> dec(ims);
	char buf[4096];
	size_t size = dec.read(buf, sizeof(buf));
	std::string decStr(buf, buf + size);
	CYBOZU_TEST_EQUAL(body, decStr);
}

CYBOZU_TEST_AUTO(output_gzip1)
{
	std::string str = "Only a test, test, test, test, test, test, test, test!\n";
	std::stringstream ss;
	cybozu::ZlibCompressorT<std::stringstream> comp(ss, true);
	comp.write(&str[0], str.size());
	comp.flush();
	std::string enc = ss.str();

	{
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, str);
	}

	{
		cybozu::StringInputStream is(enc);
		cybozu::ZlibDecompressorT<cybozu::StringInputStream> dec(is, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, str);
	}
}

#ifdef _MSC_VER
	#pragma warning(disable : 4309)
#endif

CYBOZU_TEST_AUTO(output_gzip2)
{
	const uint8_t textBufTbl[] = {
		0x23, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x20, 0x3C, 0x73, 0x74, 0x64, 0x69, 0x6F, 0x2E,
		0x68, 0x3E, 0x0A, 0x0A, 0x69, 0x6E, 0x74, 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x0A, 0x7B,
		0x0A, 0x09, 0x70, 0x75, 0x74, 0x73, 0x28, 0x22, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x22, 0x29, 0x3B,
		0x0A, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x30, 0x3B, 0x0A, 0x7D, 0x0A, 0x0A,
	};

	const uint8_t encBufTbl[] = {
		0x1F, 0x8B, 0x08, 0x08, 0xA4, 0x7E, 0x20, 0x4B, 0x00, 0x03, 0x74, 0x2E, 0x63, 0x70, 0x70, 0x00,
		0x53, 0xCE, 0xCC, 0x4B, 0xCE, 0x29, 0x4D, 0x49, 0x55, 0xB0, 0x29, 0x2E, 0x49, 0xC9, 0xCC, 0xD7,
		0xCB, 0xB0, 0xE3, 0xE2, 0xCA, 0xCC, 0x2B, 0x51, 0xC8, 0x4D, 0xCC, 0xCC, 0xD3, 0xD0, 0xE4, 0xAA,
		0xE6, 0xE2, 0x2C, 0x28, 0x2D, 0x29, 0xD6, 0x50, 0xCA, 0x48, 0xCD, 0xC9, 0xC9, 0x57, 0xD2, 0xB4,
		0xE6, 0xE2, 0x2C, 0x4A, 0x2D, 0x29, 0x2D, 0xCA, 0x53, 0x30, 0xB0, 0xE6, 0xAA, 0xE5, 0xE2, 0x02,
		0x00, 0x48, 0xAB, 0x48, 0x61, 0x3F, 0x00, 0x00, 0x00,
	};
	const char *const textBuf = cybozu::cast<const char*>(textBufTbl);
	const char *const encBuf = cybozu::cast<const char*>(encBufTbl);
	const std::string text(textBuf, textBuf + sizeof(textBufTbl));

	{
		std::stringstream ss;
		ss.write(encBuf, sizeof(encBufTbl));
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, text);
	}
}

CYBOZU_TEST_AUTO(serializer)
{
	typedef std::map<int, double> Map;
	Map m, mm;
	for (int i = 0; i < 100; i++) {
		m[i * i] = (i + i * i) / 3.42;
	}
	std::stringstream ss;

	{
		cybozu::ZlibCompressorT<std::stringstream> enc(ss);
		cybozu::save(ss, m);
	}
	{
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss);
		cybozu::load(mm, ss);
	}
	CYBOZU_TEST_EQUAL(m.size(), mm.size());
	for (Map::const_iterator i = m.begin(), ie = m.end(), j = mm.begin(); i != ie; ++i, ++j) {
		CYBOZU_TEST_EQUAL(i->first, j->first);
		CYBOZU_TEST_EQUAL(i->second, j->second);
	}
}<commit_msg>fix to use zlib<commit_after>#include <cybozu/test.hpp>
#include <cybozu/zlib.hpp>
#include <cybozu/file.hpp>
#include <cybozu/stream.hpp>
#include <cybozu/serializer.hpp>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

CYBOZU_TEST_AUTO(test1_deflate)
{
	typedef cybozu::ZlibCompressorT<std::stringstream> Compressor;
	typedef cybozu::ZlibDecompressorT<std::stringstream> Decompressor;
	const std::string in = "this is a pen";

	std::stringstream os;
	{
		Compressor comp(os);
		comp.write(in.c_str(), in.size());
		comp.flush();
	}
	const std::string enc = os.str();

	const char encTbl[] = "\x78\x9c\x2b\xc9\xc8\x2c\x56\x00\xa2\x44\x85\x82\xd4\x3c\x00\x21\x0c\x04\x99";

	const std::string encOk(encTbl, encTbl + sizeof(encTbl) - 1);
	CYBOZU_TEST_EQUAL(enc, encOk);

	std::stringstream is;
	is << encOk;

	{
		Decompressor dec(is);
		char buf[2048];
		std::string out;
		for (;;) {
			size_t size = dec.read(buf, sizeof(buf));
			if (size == 0) break;
			out.append(buf, buf + size);
		}
		CYBOZU_TEST_EQUAL(in, out);
	}
}

CYBOZU_TEST_AUTO(test2_deflate)
{
	typedef cybozu::ZlibCompressorT<std::stringstream, 1> Compressor;
	typedef cybozu::ZlibDecompressorT<std::stringstream, 1> Decompressor;
	const std::string in = "this is a pen";

	std::stringstream os;
	{
		Compressor comp(os);
		for (size_t i = 0; i < in.size(); i++) {
			comp.write(&in[i], 1);
		}
		comp.flush();
	}
	const std::string enc = os.str();

	const char encTbl[] = "\x78\x9c\x2b\xc9\xc8\x2c\x56\x00\xa2\x44\x85\x82\xd4\x3c\x00\x21\x0c\x04\x99";

	const std::string encOk(encTbl, encTbl + sizeof(encTbl) - 1);
	CYBOZU_TEST_EQUAL(enc, encOk);

	std::stringstream is;
	is << encOk;

	{
		Decompressor dec(is);
		char buf[2048];
		std::string out;
		for (;;) {
			size_t size = dec.read(buf, sizeof(buf));
			if (size == 0) break;
			out.append(buf, buf + size);
		}
		CYBOZU_TEST_EQUAL(in, out);
	}
}

CYBOZU_TEST_AUTO(enc_and_dec)
{
	std::string body = "From: cybozu\r\n"
				 "To: cybozu\r\n"
				 "\r\n"
				 "hello with zlib compressed\r\n"
				 ".\r\n";
	std::stringstream ss;
	cybozu::ZlibCompressorT<std::stringstream> comp(ss);
	comp.write(&body[0], body.size());
	comp.flush();

	std::string enc = ss.str();

	cybozu::StringInputStream ims(enc);

	cybozu::ZlibDecompressorT<cybozu::StringInputStream> dec(ims);
	char buf[4096];
	size_t size = dec.read(buf, sizeof(buf));
	std::string decStr(buf, buf + size);
	CYBOZU_TEST_EQUAL(body, decStr);
}

CYBOZU_TEST_AUTO(output_gzip1)
{
	std::string str = "Only a test, test, test, test, test, test, test, test!\n";
	std::stringstream ss;
	cybozu::ZlibCompressorT<std::stringstream> comp(ss, true);
	comp.write(&str[0], str.size());
	comp.flush();
	std::string enc = ss.str();

	{
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, str);
	}

	{
		cybozu::StringInputStream is(enc);
		cybozu::ZlibDecompressorT<cybozu::StringInputStream> dec(is, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, str);
	}
}

#ifdef _MSC_VER
	#pragma warning(disable : 4309)
#endif

CYBOZU_TEST_AUTO(output_gzip2)
{
	const uint8_t textBufTbl[] = {
		0x23, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x65, 0x20, 0x3C, 0x73, 0x74, 0x64, 0x69, 0x6F, 0x2E,
		0x68, 0x3E, 0x0A, 0x0A, 0x69, 0x6E, 0x74, 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x0A, 0x7B,
		0x0A, 0x09, 0x70, 0x75, 0x74, 0x73, 0x28, 0x22, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x22, 0x29, 0x3B,
		0x0A, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x30, 0x3B, 0x0A, 0x7D, 0x0A, 0x0A,
	};

	const uint8_t encBufTbl[] = {
		0x1F, 0x8B, 0x08, 0x08, 0xA4, 0x7E, 0x20, 0x4B, 0x00, 0x03, 0x74, 0x2E, 0x63, 0x70, 0x70, 0x00,
		0x53, 0xCE, 0xCC, 0x4B, 0xCE, 0x29, 0x4D, 0x49, 0x55, 0xB0, 0x29, 0x2E, 0x49, 0xC9, 0xCC, 0xD7,
		0xCB, 0xB0, 0xE3, 0xE2, 0xCA, 0xCC, 0x2B, 0x51, 0xC8, 0x4D, 0xCC, 0xCC, 0xD3, 0xD0, 0xE4, 0xAA,
		0xE6, 0xE2, 0x2C, 0x28, 0x2D, 0x29, 0xD6, 0x50, 0xCA, 0x48, 0xCD, 0xC9, 0xC9, 0x57, 0xD2, 0xB4,
		0xE6, 0xE2, 0x2C, 0x4A, 0x2D, 0x29, 0x2D, 0xCA, 0x53, 0x30, 0xB0, 0xE6, 0xAA, 0xE5, 0xE2, 0x02,
		0x00, 0x48, 0xAB, 0x48, 0x61, 0x3F, 0x00, 0x00, 0x00,
	};
	const char *const textBuf = cybozu::cast<const char*>(textBufTbl);
	const char *const encBuf = cybozu::cast<const char*>(encBufTbl);
	const std::string text(textBuf, textBuf + sizeof(textBufTbl));

	{
		std::stringstream ss;
		ss.write(encBuf, sizeof(encBufTbl));
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss, true);
		char buf[4096];
		size_t size = dec.read(buf, sizeof(buf));
		std::string decStr(buf, buf + size);
		CYBOZU_TEST_EQUAL(decStr, text);
	}
}

CYBOZU_TEST_AUTO(serializer)
{
	typedef std::map<int, double> Map;
	Map m, mm;
	for (int i = 0; i < 100; i++) {
		m[i * i] = (i + i * i) / 3.42;
	}
	std::stringstream ss;

	{
		cybozu::ZlibCompressorT<std::stringstream> enc(ss);
		cybozu::save(enc, m);
	}
	{
		cybozu::ZlibDecompressorT<std::stringstream> dec(ss);
		cybozu::load(mm, dec);
	}
	CYBOZU_TEST_EQUAL(m.size(), mm.size());
	for (Map::const_iterator i = m.begin(), ie = m.end(), j = mm.begin(); i != ie; ++i, ++j) {
		CYBOZU_TEST_EQUAL(i->first, j->first);
		CYBOZU_TEST_EQUAL(i->second, j->second);
	}
}<|endoftext|>


<commit_before>// Copyright 2013 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 "content/child/npapi/np_channel_base.h"

#include "base/auto_reset.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_local.h"
#include "ipc/ipc_sync_message.h"

#if defined(OS_POSIX)
#include "ipc/ipc_channel_posix.h"
#endif

namespace content {

namespace {

typedef base::hash_map<std::string, scoped_refptr<NPChannelBase> > ChannelMap;

struct ChannelGlobals {
  ChannelMap channel_map;
  scoped_refptr<NPChannelBase> current_channel;
};

#if defined(OS_ANDROID)
// Workaround for http://crbug.com/298179 - NPChannelBase is only intended
// for use on one thread per process. Using TLS to store the globals removes the
// worst thread hostility in this class, especially needed for webview which
// runs in single-process mode. TODO(joth): Make a complete fix, most likely
// as part of addressing http://crbug.com/258510.
base::LazyInstance<base::ThreadLocalPointer<ChannelGlobals> >::Leaky
    g_channels_tls_ptr = LAZY_INSTANCE_INITIALIZER;

ChannelGlobals* GetChannelGlobals() {
  ChannelGlobals* globals = g_channels_tls_ptr.Get().Get();
  if (!globals) {
    globals = new ChannelGlobals;
    g_channels_tls_ptr.Get().Set(globals);
  }
  return globals;
}

#else

base::LazyInstance<ChannelGlobals>::Leaky g_channels_globals =
    LAZY_INSTANCE_INITIALIZER;

ChannelGlobals* GetChannelGlobals() { return g_channels_globals.Pointer(); }

#endif  // OS_ANDROID

ChannelMap* GetChannelMap() {
  return &GetChannelGlobals()->channel_map;
}

}  // namespace

NPChannelBase* NPChannelBase::GetChannel(
    const IPC::ChannelHandle& channel_handle, IPC::Channel::Mode mode,
    ChannelFactory factory, base::MessageLoopProxy* ipc_message_loop,
    bool create_pipe_now, base::WaitableEvent* shutdown_event) {
  scoped_refptr<NPChannelBase> channel;
  std::string channel_key = channel_handle.name;
  ChannelMap::const_iterator iter = GetChannelMap()->find(channel_key);
  if (iter == GetChannelMap()->end()) {
    channel = factory();
  } else {
    channel = iter->second;
  }

  DCHECK(channel.get() != NULL);

  if (!channel->channel_valid()) {
    channel->channel_handle_ = channel_handle;
    if (mode & IPC::Channel::MODE_SERVER_FLAG) {
      channel->channel_handle_.name =
          IPC::Channel::GenerateVerifiedChannelID(channel_key);
    }
    channel->mode_ = mode;
    if (channel->Init(ipc_message_loop, create_pipe_now, shutdown_event)) {
      (*GetChannelMap())[channel_key] = channel;
    } else {
      channel = NULL;
    }
  }

  return channel.get();
}

void NPChannelBase::Broadcast(IPC::Message* message) {
  for (ChannelMap::iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end();
       ++iter) {
    iter->second->Send(new IPC::Message(*message));
  }
  delete message;
}

NPChannelBase::NPChannelBase()
    : mode_(IPC::Channel::MODE_NONE),
      non_npobject_count_(0),
      peer_pid_(0),
      in_remove_route_(false),
      default_owner_(NULL),
      channel_valid_(false),
      in_unblock_dispatch_(0),
      send_unblocking_only_during_unblock_dispatch_(false) {
}

NPChannelBase::~NPChannelBase() {
  // TODO(wez): Establish why these would ever be non-empty at teardown.
  //DCHECK(npobject_listeners_.empty());
  //DCHECK(proxy_map_.empty());
  //DCHECK(stub_map_.empty());
  DCHECK(owner_to_route_.empty());
  DCHECK(route_to_owner_.empty());
}

NPChannelBase* NPChannelBase::GetCurrentChannel() {
  return GetChannelGlobals()->current_channel.get();
}

void NPChannelBase::CleanupChannels() {
  // Make a copy of the references as we can't iterate the map since items will
  // be removed from it as we clean them up.
  std::vector<scoped_refptr<NPChannelBase> > channels;
  for (ChannelMap::const_iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end();
       ++iter) {
    channels.push_back(iter->second);
  }

  for (size_t i = 0; i < channels.size(); ++i)
    channels[i]->CleanUp();

  // This will clean up channels added to the map for which subsequent
  // AddRoute wasn't called
  GetChannelMap()->clear();
}

NPObjectBase* NPChannelBase::GetNPObjectListenerForRoute(int route_id) {
  ListenerMap::iterator iter = npobject_listeners_.find(route_id);
  if (iter == npobject_listeners_.end()) {
    DLOG(WARNING) << "Invalid route id passed in:" << route_id;
    return NULL;
  }
  return iter->second;
}

base::WaitableEvent* NPChannelBase::GetModalDialogEvent(int render_view_id) {
  return NULL;
}

bool NPChannelBase::Init(base::MessageLoopProxy* ipc_message_loop,
                         bool create_pipe_now,
                         base::WaitableEvent* shutdown_event) {
#if defined(OS_POSIX)
  // Attempting to initialize with an invalid channel handle.
  // See http://crbug.com/97285 for details.
  if (mode_ == IPC::Channel::MODE_CLIENT && -1 == channel_handle_.socket.fd)
    return false;
#endif

  channel_.reset(new IPC::SyncChannel(
      channel_handle_, mode_, this, ipc_message_loop, create_pipe_now,
      shutdown_event));

#if defined(OS_POSIX)
  // Check the validity of fd for bug investigation.  Remove after fixed.
  // See crbug.com/97285 for details.
  if (mode_ == IPC::Channel::MODE_SERVER)
    CHECK_NE(-1, channel_->GetClientFileDescriptor());
#endif

  channel_valid_ = true;
  return true;
}

bool NPChannelBase::Send(IPC::Message* message) {
  if (!channel_) {
    VLOG(1) << "Channel is NULL; dropping message";
    delete message;
    return false;
  }

  if (send_unblocking_only_during_unblock_dispatch_ &&
      in_unblock_dispatch_ == 0 &&
      message->is_sync()) {
    message->set_unblock(false);
  }

  return channel_->Send(message);
}

int NPChannelBase::Count() {
  return static_cast<int>(GetChannelMap()->size());
}

bool NPChannelBase::OnMessageReceived(const IPC::Message& message) {
  // Push this channel as the current channel being processed. This also forms
  // a stack of scoped_refptr avoiding ourselves (or any instance higher
  // up the callstack) from being deleted while processing a message.
  base::AutoReset<scoped_refptr<NPChannelBase> > keep_alive(
      &GetChannelGlobals()->current_channel, this);

  bool handled;
  if (message.should_unblock())
    in_unblock_dispatch_++;
  if (message.routing_id() == MSG_ROUTING_CONTROL) {
    handled = OnControlMessageReceived(message);
  } else {
    handled = router_.RouteMessage(message);
    if (!handled && message.is_sync()) {
      // The listener has gone away, so we must respond or else the caller will
      // hang waiting for a reply.
      IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
      reply->set_reply_error();
      Send(reply);
    }
  }
  if (message.should_unblock())
    in_unblock_dispatch_--;

  return handled;
}

void NPChannelBase::OnChannelConnected(int32 peer_pid) {
  peer_pid_ = peer_pid;
}

void NPChannelBase::AddRoute(int route_id,
                             IPC::Listener* listener,
                             NPObjectBase* npobject) {
  if (npobject) {
    npobject_listeners_[route_id] = npobject;
  } else {
    non_npobject_count_++;
  }

  router_.AddRoute(route_id, listener);
}

void NPChannelBase::RemoveRoute(int route_id) {
  router_.RemoveRoute(route_id);

  ListenerMap::iterator iter = npobject_listeners_.find(route_id);
  if (iter != npobject_listeners_.end()) {
    // This was an NPObject proxy or stub, it's not involved in the refcounting.

    // If this RemoveRoute call from the NPObject is a result of us calling
    // OnChannelError below, don't call erase() here because that'll corrupt
    // the iterator below.
    if (in_remove_route_) {
      iter->second = NULL;
    } else {
      npobject_listeners_.erase(iter);
    }

    return;
  }

  non_npobject_count_--;
  DCHECK(non_npobject_count_ >= 0);

  if (!non_npobject_count_) {
    base::AutoReset<bool> auto_reset_in_remove_route(&in_remove_route_, true);
    for (ListenerMap::iterator npobj_iter = npobject_listeners_.begin();
         npobj_iter != npobject_listeners_.end(); ++npobj_iter) {
      if (npobj_iter->second) {
        npobj_iter->second->GetChannelListener()->OnChannelError();
      }
    }

    for (ChannelMap::iterator iter = GetChannelMap()->begin();
         iter != GetChannelMap()->end(); ++iter) {
      if (iter->second.get() == this) {
        GetChannelMap()->erase(iter);
        return;
      }
    }

    NOTREACHED();
  }
}

bool NPChannelBase::OnControlMessageReceived(const IPC::Message& msg) {
  NOTREACHED() <<
      "should override in subclass if you care about control messages";
  return false;
}

void NPChannelBase::OnChannelError() {
  channel_valid_ = false;

  // TODO(shess): http://crbug.com/97285
  // Once an error is seen on a channel, remap the channel to prevent
  // it from being vended again.  Keep the channel in the map so
  // RemoveRoute() can clean things up correctly.
  for (ChannelMap::iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end(); ++iter) {
    if (iter->second.get() == this) {
      // Insert new element before invalidating |iter|.
      (*GetChannelMap())[iter->first + "-error"] = iter->second;
      GetChannelMap()->erase(iter);
      break;
    }
  }
}

void NPChannelBase::AddMappingForNPObjectProxy(int route_id,
                                               NPObject* object) {
  proxy_map_[route_id] = object;
}

void NPChannelBase::RemoveMappingForNPObjectProxy(int route_id) {
  proxy_map_.erase(route_id);
}

void NPChannelBase::AddMappingForNPObjectStub(int route_id,
                                              NPObject* object) {
  DCHECK(object != NULL);
  stub_map_[object] = route_id;
}

void NPChannelBase::RemoveMappingForNPObjectStub(int route_id,
                                                 NPObject* object) {
  DCHECK(object != NULL);
  stub_map_.erase(object);
}

void NPChannelBase::AddMappingForNPObjectOwner(int route_id,
                                               struct _NPP* owner) {
  DCHECK(owner != NULL);
  route_to_owner_[route_id] = owner;
  owner_to_route_[owner] = route_id;
}

void NPChannelBase::SetDefaultNPObjectOwner(struct _NPP* owner) {
  DCHECK(owner != NULL);
  default_owner_ = owner;
}

void NPChannelBase::RemoveMappingForNPObjectOwner(int route_id) {
  DCHECK(route_to_owner_.find(route_id) != route_to_owner_.end());
  owner_to_route_.erase(route_to_owner_[route_id]);
  route_to_owner_.erase(route_id);
}

NPObject* NPChannelBase::GetExistingNPObjectProxy(int route_id) {
  ProxyMap::iterator iter = proxy_map_.find(route_id);
  return iter != proxy_map_.end() ? iter->second : NULL;
}

int NPChannelBase::GetExistingRouteForNPObjectStub(NPObject* npobject) {
  StubMap::iterator iter = stub_map_.find(npobject);
  return iter != stub_map_.end() ? iter->second : MSG_ROUTING_NONE;
}

NPP NPChannelBase::GetExistingNPObjectOwner(int route_id) {
  RouteToOwnerMap::iterator iter = route_to_owner_.find(route_id);
  return iter != route_to_owner_.end() ? iter->second : default_owner_;
}

int NPChannelBase::GetExistingRouteForNPObjectOwner(NPP owner) {
  OwnerToRouteMap::iterator iter = owner_to_route_.find(owner);
  return iter != owner_to_route_.end() ? iter->second : MSG_ROUTING_NONE;
}

}  // namespace content
<commit_msg>Fix a fd leak in NPChannelBase on Posix<commit_after>// Copyright 2013 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 "content/child/npapi/np_channel_base.h"

#include "base/auto_reset.h"
#include "base/containers/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_local.h"
#include "ipc/ipc_sync_message.h"

#if defined(OS_POSIX)
#include "base/file_util.h"
#include "ipc/ipc_channel_posix.h"
#endif

namespace content {

namespace {

typedef base::hash_map<std::string, scoped_refptr<NPChannelBase> > ChannelMap;

struct ChannelGlobals {
  ChannelMap channel_map;
  scoped_refptr<NPChannelBase> current_channel;
};

#if defined(OS_ANDROID)
// Workaround for http://crbug.com/298179 - NPChannelBase is only intended
// for use on one thread per process. Using TLS to store the globals removes the
// worst thread hostility in this class, especially needed for webview which
// runs in single-process mode. TODO(joth): Make a complete fix, most likely
// as part of addressing http://crbug.com/258510.
base::LazyInstance<base::ThreadLocalPointer<ChannelGlobals> >::Leaky
    g_channels_tls_ptr = LAZY_INSTANCE_INITIALIZER;

ChannelGlobals* GetChannelGlobals() {
  ChannelGlobals* globals = g_channels_tls_ptr.Get().Get();
  if (!globals) {
    globals = new ChannelGlobals;
    g_channels_tls_ptr.Get().Set(globals);
  }
  return globals;
}

#else

base::LazyInstance<ChannelGlobals>::Leaky g_channels_globals =
    LAZY_INSTANCE_INITIALIZER;

ChannelGlobals* GetChannelGlobals() { return g_channels_globals.Pointer(); }

#endif  // OS_ANDROID

ChannelMap* GetChannelMap() {
  return &GetChannelGlobals()->channel_map;
}

}  // namespace

NPChannelBase* NPChannelBase::GetChannel(
    const IPC::ChannelHandle& channel_handle, IPC::Channel::Mode mode,
    ChannelFactory factory, base::MessageLoopProxy* ipc_message_loop,
    bool create_pipe_now, base::WaitableEvent* shutdown_event) {
#if defined(OS_POSIX)
  // On POSIX the channel_handle conveys an FD (socket) which is duped by the
  // kernel during the IPC message exchange (via the SCM_RIGHTS mechanism).
  // Ensure we do not leak this FD.
  int fd = channel_handle.socket.auto_close ? channel_handle.socket.fd : -1;
  file_util::ScopedFD auto_close_fd(&fd);
#endif

  scoped_refptr<NPChannelBase> channel;
  std::string channel_key = channel_handle.name;
  ChannelMap::const_iterator iter = GetChannelMap()->find(channel_key);
  if (iter == GetChannelMap()->end()) {
    channel = factory();
  } else {
    channel = iter->second;
  }

  DCHECK(channel.get() != NULL);

  if (!channel->channel_valid()) {
    channel->channel_handle_ = channel_handle;
#if defined(OS_POSIX)
    ignore_result(auto_close_fd.release());
#endif
    if (mode & IPC::Channel::MODE_SERVER_FLAG) {
      channel->channel_handle_.name =
          IPC::Channel::GenerateVerifiedChannelID(channel_key);
    }
    channel->mode_ = mode;
    if (channel->Init(ipc_message_loop, create_pipe_now, shutdown_event)) {
      (*GetChannelMap())[channel_key] = channel;
    } else {
      channel = NULL;
    }
  }

  return channel.get();
}

void NPChannelBase::Broadcast(IPC::Message* message) {
  for (ChannelMap::iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end();
       ++iter) {
    iter->second->Send(new IPC::Message(*message));
  }
  delete message;
}

NPChannelBase::NPChannelBase()
    : mode_(IPC::Channel::MODE_NONE),
      non_npobject_count_(0),
      peer_pid_(0),
      in_remove_route_(false),
      default_owner_(NULL),
      channel_valid_(false),
      in_unblock_dispatch_(0),
      send_unblocking_only_during_unblock_dispatch_(false) {
}

NPChannelBase::~NPChannelBase() {
  // TODO(wez): Establish why these would ever be non-empty at teardown.
  //DCHECK(npobject_listeners_.empty());
  //DCHECK(proxy_map_.empty());
  //DCHECK(stub_map_.empty());
  DCHECK(owner_to_route_.empty());
  DCHECK(route_to_owner_.empty());
}

NPChannelBase* NPChannelBase::GetCurrentChannel() {
  return GetChannelGlobals()->current_channel.get();
}

void NPChannelBase::CleanupChannels() {
  // Make a copy of the references as we can't iterate the map since items will
  // be removed from it as we clean them up.
  std::vector<scoped_refptr<NPChannelBase> > channels;
  for (ChannelMap::const_iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end();
       ++iter) {
    channels.push_back(iter->second);
  }

  for (size_t i = 0; i < channels.size(); ++i)
    channels[i]->CleanUp();

  // This will clean up channels added to the map for which subsequent
  // AddRoute wasn't called
  GetChannelMap()->clear();
}

NPObjectBase* NPChannelBase::GetNPObjectListenerForRoute(int route_id) {
  ListenerMap::iterator iter = npobject_listeners_.find(route_id);
  if (iter == npobject_listeners_.end()) {
    DLOG(WARNING) << "Invalid route id passed in:" << route_id;
    return NULL;
  }
  return iter->second;
}

base::WaitableEvent* NPChannelBase::GetModalDialogEvent(int render_view_id) {
  return NULL;
}

bool NPChannelBase::Init(base::MessageLoopProxy* ipc_message_loop,
                         bool create_pipe_now,
                         base::WaitableEvent* shutdown_event) {
#if defined(OS_POSIX)
  // Attempting to initialize with an invalid channel handle.
  // See http://crbug.com/97285 for details.
  if (mode_ == IPC::Channel::MODE_CLIENT && -1 == channel_handle_.socket.fd)
    return false;
#endif

  channel_.reset(new IPC::SyncChannel(
      channel_handle_, mode_, this, ipc_message_loop, create_pipe_now,
      shutdown_event));

#if defined(OS_POSIX)
  // Check the validity of fd for bug investigation.  Remove after fixed.
  // See crbug.com/97285 for details.
  if (mode_ == IPC::Channel::MODE_SERVER)
    CHECK_NE(-1, channel_->GetClientFileDescriptor());
#endif

  channel_valid_ = true;
  return true;
}

bool NPChannelBase::Send(IPC::Message* message) {
  if (!channel_) {
    VLOG(1) << "Channel is NULL; dropping message";
    delete message;
    return false;
  }

  if (send_unblocking_only_during_unblock_dispatch_ &&
      in_unblock_dispatch_ == 0 &&
      message->is_sync()) {
    message->set_unblock(false);
  }

  return channel_->Send(message);
}

int NPChannelBase::Count() {
  return static_cast<int>(GetChannelMap()->size());
}

bool NPChannelBase::OnMessageReceived(const IPC::Message& message) {
  // Push this channel as the current channel being processed. This also forms
  // a stack of scoped_refptr avoiding ourselves (or any instance higher
  // up the callstack) from being deleted while processing a message.
  base::AutoReset<scoped_refptr<NPChannelBase> > keep_alive(
      &GetChannelGlobals()->current_channel, this);

  bool handled;
  if (message.should_unblock())
    in_unblock_dispatch_++;
  if (message.routing_id() == MSG_ROUTING_CONTROL) {
    handled = OnControlMessageReceived(message);
  } else {
    handled = router_.RouteMessage(message);
    if (!handled && message.is_sync()) {
      // The listener has gone away, so we must respond or else the caller will
      // hang waiting for a reply.
      IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
      reply->set_reply_error();
      Send(reply);
    }
  }
  if (message.should_unblock())
    in_unblock_dispatch_--;

  return handled;
}

void NPChannelBase::OnChannelConnected(int32 peer_pid) {
  peer_pid_ = peer_pid;
}

void NPChannelBase::AddRoute(int route_id,
                             IPC::Listener* listener,
                             NPObjectBase* npobject) {
  if (npobject) {
    npobject_listeners_[route_id] = npobject;
  } else {
    non_npobject_count_++;
  }

  router_.AddRoute(route_id, listener);
}

void NPChannelBase::RemoveRoute(int route_id) {
  router_.RemoveRoute(route_id);

  ListenerMap::iterator iter = npobject_listeners_.find(route_id);
  if (iter != npobject_listeners_.end()) {
    // This was an NPObject proxy or stub, it's not involved in the refcounting.

    // If this RemoveRoute call from the NPObject is a result of us calling
    // OnChannelError below, don't call erase() here because that'll corrupt
    // the iterator below.
    if (in_remove_route_) {
      iter->second = NULL;
    } else {
      npobject_listeners_.erase(iter);
    }

    return;
  }

  non_npobject_count_--;
  DCHECK(non_npobject_count_ >= 0);

  if (!non_npobject_count_) {
    base::AutoReset<bool> auto_reset_in_remove_route(&in_remove_route_, true);
    for (ListenerMap::iterator npobj_iter = npobject_listeners_.begin();
         npobj_iter != npobject_listeners_.end(); ++npobj_iter) {
      if (npobj_iter->second) {
        npobj_iter->second->GetChannelListener()->OnChannelError();
      }
    }

    for (ChannelMap::iterator iter = GetChannelMap()->begin();
         iter != GetChannelMap()->end(); ++iter) {
      if (iter->second.get() == this) {
        GetChannelMap()->erase(iter);
        return;
      }
    }

    NOTREACHED();
  }
}

bool NPChannelBase::OnControlMessageReceived(const IPC::Message& msg) {
  NOTREACHED() <<
      "should override in subclass if you care about control messages";
  return false;
}

void NPChannelBase::OnChannelError() {
  channel_valid_ = false;

  // TODO(shess): http://crbug.com/97285
  // Once an error is seen on a channel, remap the channel to prevent
  // it from being vended again.  Keep the channel in the map so
  // RemoveRoute() can clean things up correctly.
  for (ChannelMap::iterator iter = GetChannelMap()->begin();
       iter != GetChannelMap()->end(); ++iter) {
    if (iter->second.get() == this) {
      // Insert new element before invalidating |iter|.
      (*GetChannelMap())[iter->first + "-error"] = iter->second;
      GetChannelMap()->erase(iter);
      break;
    }
  }
}

void NPChannelBase::AddMappingForNPObjectProxy(int route_id,
                                               NPObject* object) {
  proxy_map_[route_id] = object;
}

void NPChannelBase::RemoveMappingForNPObjectProxy(int route_id) {
  proxy_map_.erase(route_id);
}

void NPChannelBase::AddMappingForNPObjectStub(int route_id,
                                              NPObject* object) {
  DCHECK(object != NULL);
  stub_map_[object] = route_id;
}

void NPChannelBase::RemoveMappingForNPObjectStub(int route_id,
                                                 NPObject* object) {
  DCHECK(object != NULL);
  stub_map_.erase(object);
}

void NPChannelBase::AddMappingForNPObjectOwner(int route_id,
                                               struct _NPP* owner) {
  DCHECK(owner != NULL);
  route_to_owner_[route_id] = owner;
  owner_to_route_[owner] = route_id;
}

void NPChannelBase::SetDefaultNPObjectOwner(struct _NPP* owner) {
  DCHECK(owner != NULL);
  default_owner_ = owner;
}

void NPChannelBase::RemoveMappingForNPObjectOwner(int route_id) {
  DCHECK(route_to_owner_.find(route_id) != route_to_owner_.end());
  owner_to_route_.erase(route_to_owner_[route_id]);
  route_to_owner_.erase(route_id);
}

NPObject* NPChannelBase::GetExistingNPObjectProxy(int route_id) {
  ProxyMap::iterator iter = proxy_map_.find(route_id);
  return iter != proxy_map_.end() ? iter->second : NULL;
}

int NPChannelBase::GetExistingRouteForNPObjectStub(NPObject* npobject) {
  StubMap::iterator iter = stub_map_.find(npobject);
  return iter != stub_map_.end() ? iter->second : MSG_ROUTING_NONE;
}

NPP NPChannelBase::GetExistingNPObjectOwner(int route_id) {
  RouteToOwnerMap::iterator iter = route_to_owner_.find(route_id);
  return iter != route_to_owner_.end() ? iter->second : default_owner_;
}

int NPChannelBase::GetExistingRouteForNPObjectOwner(NPP owner) {
  OwnerToRouteMap::iterator iter = owner_to_route_.find(owner);
  return iter != owner_to_route_.end() ? iter->second : MSG_ROUTING_NONE;
}

}  // namespace content
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "content/common/swapped_out_messages.h"

#include "content/common/content_client.h"
#include "content/common/view_messages.h"

namespace content {

bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) {
  // We filter out most IPC messages when swapped out.  However, some are
  // important (e.g., ACKs) for keeping the browser and renderer state
  // consistent in case we later return to the same renderer.
  switch (msg->type()) {
    // Handled by RenderWidget.
    case ViewHostMsg_HandleInputEvent_ACK::ID:
    case ViewHostMsg_PaintAtSize_ACK::ID:
    case ViewHostMsg_UpdateRect::ID:
    // Handled by RenderView.
    case ViewHostMsg_RenderViewGone::ID:
    case ViewHostMsg_ShouldClose_ACK::ID:
    case ViewHostMsg_SwapOut_ACK::ID:
    case ViewHostMsg_ClosePage_ACK::ID:
      return true;
    default:
      break;
  }

  // Check with the embedder as well.
  ContentClient* client = GetContentClient();
  return client->CanSendWhileSwappedOut(msg);
}

bool SwappedOutMessages::CanHandleWhileSwappedOut(
    const IPC::Message& msg) {
  // Any message the renderer is allowed to send while swapped out should
  // be handled by the browser.
  if (CanSendWhileSwappedOut(&msg))
    return true;

  // We drop most other messages that arrive from a swapped out renderer.
  // However, some are important (e.g., ACKs) for keeping the browser and
  // renderer state consistent in case we later return to the renderer.
  switch (msg.type()) {
    // Sends an ACK.
    case ViewHostMsg_ShowView::ID:
    // Sends an ACK.
    case ViewHostMsg_ShowWidget::ID:
    // Sends an ACK.
    case ViewHostMsg_ShowFullscreenWidget::ID:
    // Updates browser state.
    case ViewHostMsg_RenderViewReady::ID:
    // Updates the previous navigation entry.
    case ViewHostMsg_UpdateState::ID:
    // Sends an ACK.
    case ViewHostMsg_UpdateTargetURL::ID:
    // We allow closing even if we are in the process of swapping out.
    case ViewHostMsg_Close::ID:
    // Sends an ACK.
    case ViewHostMsg_RequestMove::ID:
    // Suppresses dialog and sends an ACK.
    case ViewHostMsg_RunJavaScriptMessage::ID:
    // Suppresses dialog and sends an ACK.
    case ViewHostMsg_RunBeforeUnloadConfirm::ID:
    // Sends an ACK.
    case ViewHostMsg_AccessibilityNotifications::ID:
      return true;
    default:
      break;
  }

  // Check with the embedder as well.
  ContentClient* client = GetContentClient();
  return client->CanHandleWhileSwappedOut(msg);
}

}  // namespace content
<commit_msg>Ensure that plugins can be destroyed in swapped out RenderViews.<commit_after>// Copyright (c) 2011 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 "content/common/swapped_out_messages.h"

#include "content/common/content_client.h"
#include "content/common/view_messages.h"

namespace content {

bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) {
  // We filter out most IPC messages when swapped out.  However, some are
  // important (e.g., ACKs) for keeping the browser and renderer state
  // consistent in case we later return to the same renderer.
  switch (msg->type()) {
    // Handled by RenderWidget.
    case ViewHostMsg_HandleInputEvent_ACK::ID:
    case ViewHostMsg_PaintAtSize_ACK::ID:
    case ViewHostMsg_UpdateRect::ID:
    // Handled by RenderView.
    case ViewHostMsg_RenderViewGone::ID:
    case ViewHostMsg_ShouldClose_ACK::ID:
    case ViewHostMsg_SwapOut_ACK::ID:
    case ViewHostMsg_ClosePage_ACK::ID:
      return true;
    default:
      break;
  }

  // Check with the embedder as well.
  ContentClient* client = GetContentClient();
  return client->CanSendWhileSwappedOut(msg);
}

bool SwappedOutMessages::CanHandleWhileSwappedOut(
    const IPC::Message& msg) {
  // Any message the renderer is allowed to send while swapped out should
  // be handled by the browser.
  if (CanSendWhileSwappedOut(&msg))
    return true;

  // We drop most other messages that arrive from a swapped out renderer.
  // However, some are important (e.g., ACKs) for keeping the browser and
  // renderer state consistent in case we later return to the renderer.
  switch (msg.type()) {
    // Sends an ACK.
    case ViewHostMsg_ShowView::ID:
    // Sends an ACK.
    case ViewHostMsg_ShowWidget::ID:
    // Sends an ACK.
    case ViewHostMsg_ShowFullscreenWidget::ID:
    // Updates browser state.
    case ViewHostMsg_RenderViewReady::ID:
    // Updates the previous navigation entry.
    case ViewHostMsg_UpdateState::ID:
    // Sends an ACK.
    case ViewHostMsg_UpdateTargetURL::ID:
    // We allow closing even if we are in the process of swapping out.
    case ViewHostMsg_Close::ID:
    // Sends an ACK.
    case ViewHostMsg_RequestMove::ID:
    // Suppresses dialog and sends an ACK.
    case ViewHostMsg_RunJavaScriptMessage::ID:
    // Suppresses dialog and sends an ACK.
    case ViewHostMsg_RunBeforeUnloadConfirm::ID:
    // Sends an ACK.
    case ViewHostMsg_AccessibilityNotifications::ID:
#if defined(USE_X11)
    // Synchronous message when leaving a page with plugin.
    case ViewHostMsg_DestroyPluginContainer::ID:
#endif
      return true;
    default:
      break;
  }

  // Check with the embedder as well.
  ContentClient* client = GetContentClient();
  return client->CanHandleWhileSwappedOut(msg);
}

}  // namespace content
<|endoftext|>


<commit_before>#include "kernel.h"
#include "ilwisdata.h"
#include "domain.h"
#include "range.h"
#include "datadefinition.h"
#include "columndefinition.h"
#include "connectorinterface.h"
#include "table.h"
#include "basetable.h"

using namespace Ilwis;

BaseTable::BaseTable() : Table(), _rows(0), _columns(0), _dataloaded(false)
{
}

BaseTable::BaseTable(const Resource& resource) : Table(resource), _rows(0), _columns(0),_dataloaded(false) {

}

BaseTable::~BaseTable()
{
}

quint32 BaseTable::records() const
{
    return _rows;
}

quint32 BaseTable::columns() const
{
    return _columns;
}

void BaseTable::records(quint32 r)
{
    _rows = r;
}

bool BaseTable::createTable()
{
    if (!isValid()) {
        kernel()->issues()->log(TR("Not created, Table %1 already exists").arg(name()), IssueObject::itWarning);
        return false;
    }
    if ( _columnDefinitionsByName.size() ==  0) {
        kernel()->issues()->log(TR("Trying to create table %1 with zero columns").arg(name()));
        return false;
    }
    return true;
}

bool BaseTable::addColumn(const ColumnDefinition& def){
    if ( _columnDefinitionsByName.contains(def.name())) {
        kernel()->issues()->log(TR("Adding duplicate column %1").arg(name()),IssueObject::itWarning);
        return false;
    }
    _columnDefinitionsByName[def.name()] = def;
    _columnDefinitionsByIndex[def.id()] = _columnDefinitionsByName[def.name()];
    _columns = _columnDefinitionsByName.size();

    return true;
}

bool BaseTable::addColumn(const QString &name, const IDomain& domain)
{
    if ( _columnDefinitionsByName.contains(name)) {
        kernel()->issues()->log(TR("Adding duplicate column %1").arg(name),IssueObject::itWarning);
        return false;
    }
    _columnDefinitionsByName[name] = ColumnDefinition(name, domain,_columnDefinitionsByName.size());
    _columnDefinitionsByIndex[_columnDefinitionsByName[name].id()] = _columnDefinitionsByName[name];
    _columns = _columnDefinitionsByName.size();

    return true;
}

bool BaseTable::addColumn(const QString &name, const QString &domainname)
{
    IDomain dom;
    if(!dom.prepare(domainname))
        return false;
    return addColumn(name, dom);
}

IlwisTypes BaseTable::ilwisType() const
{
    return itTABLE;
}

ColumnDefinition BaseTable::columndefinition(const QString &nme) const
{
    auto iter = _columnDefinitionsByName.find(nme);
    if ( iter != _columnDefinitionsByName.end())
        return iter.value();
    return ColumnDefinition();
}

ColumnDefinition BaseTable::columndefinition(quint32 index) const
{
    auto iter = _columnDefinitionsByIndex.find(index);
    if ( iter != _columnDefinitionsByIndex.end())
        return iter.value();
    return ColumnDefinition();
}

bool BaseTable::prepare()
{
    if (!IlwisObject::prepare())
        return false;

    return true;
}

bool BaseTable::isValid() const
{
    return _rows != 0 && _columns != 0;
}

ColumnDefinition &BaseTable::columndefinition(quint32 index)
{
    return _columnDefinitionsByIndex[index]    ;
}

bool  BaseTable::initLoad() {
    if ( !this->isValid()) {
        kernel()->issues()->log(TR(ERR_NO_INITIALIZED_1).arg("table"));
        return false;
    }
    if (!_dataloaded) {
        _dataloaded = true; // to prevent other inits to pass through here
        if (! connector()->loadBinaryData(this)) {
            kernel()->issues()->log(TR(ERR_COULD_NOT_LOAD_2).arg("table", name()));
             _dataloaded = false;
            return false;
        }
    }
    return true;
}

quint32 BaseTable::columnIndex(const QString &nme) const
{
    auto iter = _columnDefinitionsByName.find(nme);
    if ( iter == _columnDefinitionsByName.end()) {
        //kernel()->issues()->log(TR(ERR_COLUMN_MISSING_2).arg(nme).arg(name()),IssueObject::itWarning);
        return iUNDEF;
    }
    return iter.value().id();
}

<commit_msg>added guard<commit_after>#include "kernel.h"
#include "ilwisdata.h"
#include "domain.h"
#include "range.h"
#include "datadefinition.h"
#include "columndefinition.h"
#include "connectorinterface.h"
#include "table.h"
#include "basetable.h"

using namespace Ilwis;

BaseTable::BaseTable() : Table(), _rows(0), _columns(0), _dataloaded(false)
{
}

BaseTable::BaseTable(const Resource& resource) : Table(resource), _rows(0), _columns(0),_dataloaded(false) {

}

BaseTable::~BaseTable()
{
}

quint32 BaseTable::records() const
{
    return _rows;
}

quint32 BaseTable::columns() const
{
    return _columns;
}

void BaseTable::records(quint32 r)
{
    _rows = r;
}

bool BaseTable::createTable()
{
    if (!isValid()) {
        kernel()->issues()->log(TR("Not created, Table %1 already exists").arg(name()), IssueObject::itWarning);
        return false;
    }
    if ( _columnDefinitionsByName.size() ==  0) {
        kernel()->issues()->log(TR("Trying to create table %1 with zero columns").arg(name()));
        return false;
    }
    return true;
}

bool BaseTable::addColumn(const ColumnDefinition& def){
    if ( _columnDefinitionsByName.contains(def.name())) {
        kernel()->issues()->log(TR("Adding duplicate column %1").arg(name()),IssueObject::itWarning);
        return false;
    }
    _columnDefinitionsByName[def.name()] = def;
    _columnDefinitionsByIndex[def.id()] = _columnDefinitionsByName[def.name()];
    _columns = _columnDefinitionsByName.size();

    return true;
}

bool BaseTable::addColumn(const QString &name, const IDomain& domain)
{
    if ( _columnDefinitionsByName.contains(name)) {
        kernel()->issues()->log(TR("Adding duplicate column %1").arg(name),IssueObject::itWarning);
        return false;
    }
    _columnDefinitionsByName[name] = ColumnDefinition(name, domain,_columnDefinitionsByName.size());
    _columnDefinitionsByIndex[_columnDefinitionsByName[name].id()] = _columnDefinitionsByName[name];
    _columns = _columnDefinitionsByName.size();

    return true;
}

bool BaseTable::addColumn(const QString &name, const QString &domainname)
{
    IDomain dom;
    if(!dom.prepare(domainname))
        return false;
    return addColumn(name, dom);
}

IlwisTypes BaseTable::ilwisType() const
{
    return itTABLE;
}

ColumnDefinition BaseTable::columndefinition(const QString &nme) const
{
    auto iter = _columnDefinitionsByName.find(nme);
    if ( iter != _columnDefinitionsByName.end())
        return iter.value();
    return ColumnDefinition();
}

ColumnDefinition BaseTable::columndefinition(quint32 index) const
{
    auto iter = _columnDefinitionsByIndex.find(index);
    if ( iter != _columnDefinitionsByIndex.end())
        return iter.value();
    return ColumnDefinition();
}

bool BaseTable::prepare()
{
    if (!IlwisObject::prepare())
        return false;

    return true;
}

bool BaseTable::isValid() const
{
    return _rows != 0 && _columns != 0;
}

ColumnDefinition &BaseTable::columndefinition(quint32 index)
{
    return _columnDefinitionsByIndex[index]    ;
}

bool  BaseTable::initLoad() {
    if ( !this->isValid()) {
        kernel()->issues()->log(TR(ERR_NO_INITIALIZED_1).arg("table"));
        return false;
    }
    if (!_dataloaded) {
        _dataloaded = true; // to prevent other inits to pass through here
        if (!connector().isNull() && ! connector()->loadBinaryData(this)) {
            kernel()->issues()->log(TR(ERR_COULD_NOT_LOAD_2).arg("table", name()));
             _dataloaded = false;
            return false;
        }
    }
    return true;
}

quint32 BaseTable::columnIndex(const QString &nme) const
{
    auto iter = _columnDefinitionsByName.find(nme);
    if ( iter == _columnDefinitionsByName.end()) {
        //kernel()->issues()->log(TR(ERR_COLUMN_MISSING_2).arg(nme).arg(name()),IssueObject::itWarning);
        return iUNDEF;
    }
    return iter.value().id();
}

<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "content/renderer/p2p/port_allocator.h"

#include "base/bind.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "content/renderer/p2p/host_address_request.h"
#include "jingle/glue/utils.h"
#include "net/base/ip_endpoint.h"
#include "ppapi/c/dev/ppb_transport_dev.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"

using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebURLLoader;
using WebKit::WebURLLoaderOptions;
using WebKit::WebURLRequest;
using WebKit::WebURLResponse;

namespace content {

namespace {

// URL used to create a relay session.
const char kCreateRelaySessionURL[] = "/create_session";

// Number of times we will try to request relay session.
const int kRelaySessionRetries = 3;

// Manimum relay server size we would try to parse.
const int kMaximumRelayResponseSize = 102400;

bool ParsePortNumber(
    const std::string& string, int* value) {
  if (!base::StringToInt(string, value) || *value <= 0 || *value >= 65536) {
    LOG(ERROR) << "Received invalid port number from relay server: " << string;
    return false;
  }
  return true;
}

}  // namespace

P2PPortAllocator::P2PPortAllocator(
    WebKit::WebFrame* web_frame,
    P2PSocketDispatcher* socket_dispatcher,
    talk_base::NetworkManager* network_manager,
    talk_base::PacketSocketFactory* socket_factory,
    const webkit_glue::P2PTransport::Config& config)
    : cricket::BasicPortAllocator(network_manager, socket_factory),
      web_frame_(web_frame),
      socket_dispatcher_(socket_dispatcher),
      config_(config) {
  uint32 flags = 0;
  if (config_.disable_tcp_transport)
    flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
  set_flags(flags);
}

P2PPortAllocator::~P2PPortAllocator() {
}

cricket::PortAllocatorSession* P2PPortAllocator::CreateSession(
    const std::string& name,
    const std::string& session_type) {
  return new P2PPortAllocatorSession(this, name, session_type);
}

P2PPortAllocatorSession::P2PPortAllocatorSession(
    P2PPortAllocator* allocator,
    const std::string& name,
    const std::string& session_type)
    : cricket::BasicPortAllocatorSession(allocator, name, session_type),
      allocator_(allocator),
      relay_session_attempts_(0),
      relay_udp_port_(0),
      relay_tcp_port_(0),
      relay_ssltcp_port_(0) {
}

P2PPortAllocatorSession::~P2PPortAllocatorSession() {
  if (stun_address_request_)
    stun_address_request_->Cancel();
}

void P2PPortAllocatorSession::didReceiveData(
    WebURLLoader* loader, const char* data,
    int data_length, int encoded_data_length) {
  DCHECK_EQ(loader, relay_session_request_.get());
  if (static_cast<int>(relay_session_response_.size()) + data_length >
      kMaximumRelayResponseSize) {
    LOG(ERROR) << "Response received from the server is too big.";
    loader->cancel();
    return;
  }
  relay_session_response_.append(data, data + data_length);
}

void P2PPortAllocatorSession::didFinishLoading(WebURLLoader* loader,
                                               double finish_time) {
  ParseRelayResponse();
}

void P2PPortAllocatorSession::didFail(WebKit::WebURLLoader* loader,
                                      const WebKit::WebURLError& error) {
  DCHECK_EQ(loader, relay_session_request_.get());
  DCHECK_NE(error.reason, 0);

  LOG(ERROR) << "Relay session request failed.";

  // Retry the request.
  AllocateRelaySession();
}

void P2PPortAllocatorSession::GetPortConfigurations() {
  // Add an empty configuration synchronously, so a local connection
  // can be started immediately.
  ConfigReady(new cricket::PortConfiguration(
      talk_base::SocketAddress(), "", "", ""));

  ResolveStunServerAddress();
  AllocateRelaySession();
}

void P2PPortAllocatorSession::ResolveStunServerAddress() {
 if (allocator_->config_.stun_server.empty())
   return;

 DCHECK(!stun_address_request_);
 stun_address_request_ =
     new P2PHostAddressRequest(allocator_->socket_dispatcher_);
 stun_address_request_->Request(allocator_->config_.stun_server, base::Bind(
     &P2PPortAllocatorSession::OnStunServerAddress,
     base::Unretained(this)));
}

void P2PPortAllocatorSession::OnStunServerAddress(
    const net::IPAddressNumber& address) {
  if (address.empty()) {
    LOG(ERROR) << "Failed to resolve STUN server address "
               << allocator_->config_.stun_server;
    return;
  }

  if (!jingle_glue::IPEndPointToSocketAddress(
          net::IPEndPoint(address, allocator_->config_.stun_server_port),
          &stun_server_address_)) {
    return;
  }

  AddConfig();
}

void P2PPortAllocatorSession::AllocateRelaySession() {
  if (allocator_->config_.relay_server.empty())
    return;

  if (!allocator_->config_.legacy_relay) {
    NOTIMPLEMENTED() << " TURN support is not implemented yet.";
    return;
  }

  if (relay_session_attempts_ > kRelaySessionRetries)
    return;
  relay_session_attempts_++;

  relay_session_response_.clear();

  WebURLLoaderOptions options;
  options.allowCredentials = false;
  options.crossOriginRequestPolicy =
      WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
  relay_session_request_.reset(
      allocator_->web_frame_->createAssociatedURLLoader(options));
  if (!relay_session_request_.get()) {
    LOG(ERROR) << "Failed to create URL loader.";
    return;
  }

  WebURLRequest request;
  request.initialize();
  request.setURL(WebURL(GURL(
      "https://" + allocator_->config_.relay_server + kCreateRelaySessionURL)));
  request.setAllowStoredCredentials(false);
  request.setCachePolicy(WebURLRequest::ReloadIgnoringCacheData);
  request.setHTTPMethod("GET");
  request.addHTTPHeaderField(
      WebString::fromUTF8("X-Talk-Google-Relay-Auth"),
      WebString::fromUTF8(allocator_->config_.relay_password));
  request.addHTTPHeaderField(
      WebString::fromUTF8("X-Google-Relay-Auth"),
      WebString::fromUTF8(allocator_->config_.relay_password));
  request.addHTTPHeaderField(WebString::fromUTF8("X-Session-Type"),
                             WebString::fromUTF8(session_type()));
  request.addHTTPHeaderField(WebString::fromUTF8("X-Stream-Type"),
                             WebString::fromUTF8(name()));

  relay_session_request_->loadAsynchronously(request, this);
}

void P2PPortAllocatorSession::ParseRelayResponse() {
  std::vector<std::pair<std::string, std::string> > value_pairs;
  if (!base::SplitStringIntoKeyValuePairs(relay_session_response_, '=', '\n',
                                          &value_pairs)) {
    LOG(ERROR) << "Received invalid response from relay server";
    return;
  }

  relay_username_.clear();
  relay_password_.clear();
  relay_ip_.Clear();
  relay_udp_port_ = 0;
  relay_tcp_port_ = 0;
  relay_ssltcp_port_ = 0;

  for (std::vector<std::pair<std::string, std::string> >::iterator
           it = value_pairs.begin();
       it != value_pairs.end(); ++it) {
    std::string key;
    std::string value;
    TrimWhitespaceASCII(it->first, TRIM_ALL, &key);
    TrimWhitespaceASCII(it->second, TRIM_ALL, &value);

    if (key == "username") {
      relay_username_ = value;
    } else if (key == "password") {
      relay_password_ = value;
    } else if (key == "relay.ip") {
      relay_ip_.SetIP(value);
      if (relay_ip_.ip() == 0) {
        LOG(ERROR) << "Received unresolved relay server address: " << value;
        return;
      }
    } else if (key == "relay.udp_port") {
      if (!ParsePortNumber(value, &relay_udp_port_))
        return;
    } else if (key == "relay.tcp_port") {
      if (!ParsePortNumber(value, &relay_tcp_port_))
        return;
    } else if (key == "relay.ssltcp_port") {
      if (!ParsePortNumber(value, &relay_ssltcp_port_))
        return;
    }
  }

  AddConfig();
}

void P2PPortAllocatorSession::AddConfig() {
  cricket::PortConfiguration* config =
      new cricket::PortConfiguration(stun_server_address_,
                                     relay_username_, relay_password_, "");

  cricket::PortConfiguration::PortList ports;
  if (relay_ip_.ip() != 0) {
    if (relay_udp_port_ > 0) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_udp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_UDP));
    }
    if (relay_tcp_port_ > 0 && !allocator_->config_.disable_tcp_transport) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_tcp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_TCP));
    }
    if (relay_ssltcp_port_ > 0 && !allocator_->config_.disable_tcp_transport) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_ssltcp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_SSLTCP));
    }
  }
  config->AddRelay(ports, 0.0f);
  ConfigReady(config);
}

}  // namespace content
<commit_msg>Allow cross-origin requests for relay http requests made in Transport API.<commit_after>// Copyright (c) 2011 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 "content/renderer/p2p/port_allocator.h"

#include "base/bind.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "content/renderer/p2p/host_address_request.h"
#include "jingle/glue/utils.h"
#include "net/base/ip_endpoint.h"
#include "ppapi/c/dev/ppb_transport_dev.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"

using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebURLLoader;
using WebKit::WebURLLoaderOptions;
using WebKit::WebURLRequest;
using WebKit::WebURLResponse;

namespace content {

namespace {

// URL used to create a relay session.
const char kCreateRelaySessionURL[] = "/create_session";

// Number of times we will try to request relay session.
const int kRelaySessionRetries = 3;

// Manimum relay server size we would try to parse.
const int kMaximumRelayResponseSize = 102400;

bool ParsePortNumber(
    const std::string& string, int* value) {
  if (!base::StringToInt(string, value) || *value <= 0 || *value >= 65536) {
    LOG(ERROR) << "Received invalid port number from relay server: " << string;
    return false;
  }
  return true;
}

}  // namespace

P2PPortAllocator::P2PPortAllocator(
    WebKit::WebFrame* web_frame,
    P2PSocketDispatcher* socket_dispatcher,
    talk_base::NetworkManager* network_manager,
    talk_base::PacketSocketFactory* socket_factory,
    const webkit_glue::P2PTransport::Config& config)
    : cricket::BasicPortAllocator(network_manager, socket_factory),
      web_frame_(web_frame),
      socket_dispatcher_(socket_dispatcher),
      config_(config) {
  uint32 flags = 0;
  if (config_.disable_tcp_transport)
    flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
  set_flags(flags);
}

P2PPortAllocator::~P2PPortAllocator() {
}

cricket::PortAllocatorSession* P2PPortAllocator::CreateSession(
    const std::string& name,
    const std::string& session_type) {
  return new P2PPortAllocatorSession(this, name, session_type);
}

P2PPortAllocatorSession::P2PPortAllocatorSession(
    P2PPortAllocator* allocator,
    const std::string& name,
    const std::string& session_type)
    : cricket::BasicPortAllocatorSession(allocator, name, session_type),
      allocator_(allocator),
      relay_session_attempts_(0),
      relay_udp_port_(0),
      relay_tcp_port_(0),
      relay_ssltcp_port_(0) {
}

P2PPortAllocatorSession::~P2PPortAllocatorSession() {
  if (stun_address_request_)
    stun_address_request_->Cancel();
}

void P2PPortAllocatorSession::didReceiveData(
    WebURLLoader* loader, const char* data,
    int data_length, int encoded_data_length) {
  DCHECK_EQ(loader, relay_session_request_.get());
  if (static_cast<int>(relay_session_response_.size()) + data_length >
      kMaximumRelayResponseSize) {
    LOG(ERROR) << "Response received from the server is too big.";
    loader->cancel();
    return;
  }
  relay_session_response_.append(data, data + data_length);
}

void P2PPortAllocatorSession::didFinishLoading(WebURLLoader* loader,
                                               double finish_time) {
  ParseRelayResponse();
}

void P2PPortAllocatorSession::didFail(WebKit::WebURLLoader* loader,
                                      const WebKit::WebURLError& error) {
  DCHECK_EQ(loader, relay_session_request_.get());
  DCHECK_NE(error.reason, 0);

  LOG(ERROR) << "Relay session request failed.";

  // Retry the request.
  AllocateRelaySession();
}

void P2PPortAllocatorSession::GetPortConfigurations() {
  // Add an empty configuration synchronously, so a local connection
  // can be started immediately.
  ConfigReady(new cricket::PortConfiguration(
      talk_base::SocketAddress(), "", "", ""));

  ResolveStunServerAddress();
  AllocateRelaySession();
}

void P2PPortAllocatorSession::ResolveStunServerAddress() {
 if (allocator_->config_.stun_server.empty())
   return;

 DCHECK(!stun_address_request_);
 stun_address_request_ =
     new P2PHostAddressRequest(allocator_->socket_dispatcher_);
 stun_address_request_->Request(allocator_->config_.stun_server, base::Bind(
     &P2PPortAllocatorSession::OnStunServerAddress,
     base::Unretained(this)));
}

void P2PPortAllocatorSession::OnStunServerAddress(
    const net::IPAddressNumber& address) {
  if (address.empty()) {
    LOG(ERROR) << "Failed to resolve STUN server address "
               << allocator_->config_.stun_server;
    return;
  }

  if (!jingle_glue::IPEndPointToSocketAddress(
          net::IPEndPoint(address, allocator_->config_.stun_server_port),
          &stun_server_address_)) {
    return;
  }

  AddConfig();
}

void P2PPortAllocatorSession::AllocateRelaySession() {
  if (allocator_->config_.relay_server.empty())
    return;

  if (!allocator_->config_.legacy_relay) {
    NOTIMPLEMENTED() << " TURN support is not implemented yet.";
    return;
  }

  if (relay_session_attempts_ > kRelaySessionRetries)
    return;
  relay_session_attempts_++;

  relay_session_response_.clear();

  WebURLLoaderOptions options;
  options.allowCredentials = false;

  // TODO(sergeyu): Set to CrossOriginRequestPolicyUseAccessControl
  // when this code can be used by untrusted plugins.
  // See http://crbug.com/104195 .
  options.crossOriginRequestPolicy =
      WebURLLoaderOptions::CrossOriginRequestPolicyAllow;

  relay_session_request_.reset(
      allocator_->web_frame_->createAssociatedURLLoader(options));
  if (!relay_session_request_.get()) {
    LOG(ERROR) << "Failed to create URL loader.";
    return;
  }

  WebURLRequest request;
  request.initialize();
  request.setURL(WebURL(GURL(
      "https://" + allocator_->config_.relay_server + kCreateRelaySessionURL)));
  request.setAllowStoredCredentials(false);
  request.setCachePolicy(WebURLRequest::ReloadIgnoringCacheData);
  request.setHTTPMethod("GET");
  request.addHTTPHeaderField(
      WebString::fromUTF8("X-Talk-Google-Relay-Auth"),
      WebString::fromUTF8(allocator_->config_.relay_password));
  request.addHTTPHeaderField(
      WebString::fromUTF8("X-Google-Relay-Auth"),
      WebString::fromUTF8(allocator_->config_.relay_password));
  request.addHTTPHeaderField(WebString::fromUTF8("X-Session-Type"),
                             WebString::fromUTF8(session_type()));
  request.addHTTPHeaderField(WebString::fromUTF8("X-Stream-Type"),
                             WebString::fromUTF8(name()));

  relay_session_request_->loadAsynchronously(request, this);
}

void P2PPortAllocatorSession::ParseRelayResponse() {
  std::vector<std::pair<std::string, std::string> > value_pairs;
  if (!base::SplitStringIntoKeyValuePairs(relay_session_response_, '=', '\n',
                                          &value_pairs)) {
    LOG(ERROR) << "Received invalid response from relay server";
    return;
  }

  relay_username_.clear();
  relay_password_.clear();
  relay_ip_.Clear();
  relay_udp_port_ = 0;
  relay_tcp_port_ = 0;
  relay_ssltcp_port_ = 0;

  for (std::vector<std::pair<std::string, std::string> >::iterator
           it = value_pairs.begin();
       it != value_pairs.end(); ++it) {
    std::string key;
    std::string value;
    TrimWhitespaceASCII(it->first, TRIM_ALL, &key);
    TrimWhitespaceASCII(it->second, TRIM_ALL, &value);

    if (key == "username") {
      relay_username_ = value;
    } else if (key == "password") {
      relay_password_ = value;
    } else if (key == "relay.ip") {
      relay_ip_.SetIP(value);
      if (relay_ip_.ip() == 0) {
        LOG(ERROR) << "Received unresolved relay server address: " << value;
        return;
      }
    } else if (key == "relay.udp_port") {
      if (!ParsePortNumber(value, &relay_udp_port_))
        return;
    } else if (key == "relay.tcp_port") {
      if (!ParsePortNumber(value, &relay_tcp_port_))
        return;
    } else if (key == "relay.ssltcp_port") {
      if (!ParsePortNumber(value, &relay_ssltcp_port_))
        return;
    }
  }

  AddConfig();
}

void P2PPortAllocatorSession::AddConfig() {
  cricket::PortConfiguration* config =
      new cricket::PortConfiguration(stun_server_address_,
                                     relay_username_, relay_password_, "");

  cricket::PortConfiguration::PortList ports;
  if (relay_ip_.ip() != 0) {
    if (relay_udp_port_ > 0) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_udp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_UDP));
    }
    if (relay_tcp_port_ > 0 && !allocator_->config_.disable_tcp_transport) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_tcp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_TCP));
    }
    if (relay_ssltcp_port_ > 0 && !allocator_->config_.disable_tcp_transport) {
      talk_base::SocketAddress address(relay_ip_.ip(), relay_ssltcp_port_);
      ports.push_back(cricket::ProtocolAddress(address, cricket::PROTO_SSLTCP));
    }
  }
  config->AddRelay(ports, 0.0f);
  ConfigReady(config);
}

}  // namespace content
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen
// =============================================================================
//
// Irrlicht-based GUI driver for the HMMWV9 model. This class implements the
// functionality required by its base ChDriver class using keyboard inputs.
// As an Irrlicht event receiver, its OnEvent() callback is used to keep track
// and update the current driver inputs. As such it does not need to override
// the default no-op Update() virtual method.
//
// In addition, this class provides additional Irrlicht support for the HMMWV9
// model:
//  - implements a custom camera (which follows the vehicle)
//  - provides support for rendering links, force elements, displaying stats,
//    etc.  Its DrawAll() method must be invoked every time the Irrlicht scene
//    is redrawn, after the call to ChIrrAppInterface::DrawAll().
//
// =============================================================================

#include "HMMWV9_IrrGuiDriver.h"

using namespace chrono;
using namespace irr;

namespace hmmwv9 {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
HMMWV9_IrrGuiDriver::HMMWV9_IrrGuiDriver(ChIrrApp&              app,
                                         const HMMWV9_Vehicle&  car,
                                         int                    tlc_X,
                                         int                    tlc_Y)
: m_app(app),
  m_car(car),
  m_terrainHeight(0)
{
  app.SetUserEventReceiver(this);

  gui::IGUIStaticText* text_inputs = app.GetIGUIEnvironment()->addStaticText(
    L"", core::rect<s32>(tlc_X, tlc_Y, tlc_X + 200, tlc_Y + 75), true, false, 0, -1, true);

  text_inputs->setBackgroundColor(video::SColor(255, 200, 200, 200));

  m_text_throttle = app.GetIGUIEnvironment()->addStaticText(
    L"Throttle: 0",
    core::rect<s32>(10, 10, 150, 25), false, false, text_inputs);

  m_text_steering = app.GetIGUIEnvironment()->addStaticText(
    L"Steering: 0",
    core::rect<s32>(10, 30, 150, 45), false, false, text_inputs);

  m_text_speed = app.GetIGUIEnvironment()->addStaticText(
    L"Speed: 0",
    core::rect<s32>(10, 50, 150, 65), false, false, text_inputs);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
bool HMMWV9_IrrGuiDriver::OnEvent(const SEvent& event)
{
  // user hit a key, while not holding it down
  if (event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
  {
    char msg[100];

    switch (event.KeyInput.Key) {
    case KEY_KEY_A:
      setSteering(m_steering - 0.1);
      sprintf(msg, "Steering: %+.2f", m_steering);
      m_text_steering->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_D:
      setSteering(m_steering + 0.1);
      sprintf(msg, "Steering: %+.2f", m_steering);
      m_text_steering->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_W:
      setThrottle(m_throttle + 0.1);
      sprintf(msg, "Throttle: %+.2f", m_throttle*100.);
      m_text_throttle->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_S:
      setThrottle(m_throttle - 0.1);
      sprintf(msg, "Throttle: %+.2f", m_throttle*100.);
      m_text_throttle->setText(core::stringw(msg).c_str());
      return true;

    case KEY_DOWN:
      m_cam_multiplier *= 1.01;
      return true;
    case KEY_UP:
      m_cam_multiplier /= 1.01;
    }
  }

  return false;

}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void HMMWV9_IrrGuiDriver::CreateCamera(const chrono::ChVector<>& cam_offset)
{
  m_cam_multiplier = 1;
  m_cam_offset = cam_offset;

  m_app.GetSceneManager()->addCameraSceneNode(
    m_app.GetSceneManager()->getRootSceneNode(),
    core::vector3df(0, 0, 0), core::vector3df(0, 0, 0));

  m_app.GetSceneManager()->getActiveCamera()->setUpVector(core::vector3df(0, 0, 1));

  updateCamera();
}

void HMMWV9_IrrGuiDriver::updateCamera()
{
  const ChVector<>& car_pos = m_car.GetChassisPos();
  ChVector<>        cam_pos = m_car.GetChassis()->GetCoord().TrasformLocalToParent(m_cam_multiplier * m_cam_offset);

  scene::ICameraSceneNode *camera = m_app.GetSceneManager()->getActiveCamera();

  camera->setPosition(core::vector3df((f32)cam_pos.x, (f32)cam_pos.y, (f32)cam_pos.z));
  camera->setTarget(core::vector3df((f32)car_pos.x, (f32)car_pos.y, (f32)car_pos.z));
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void HMMWV9_IrrGuiDriver::DrawAll()
{
  updateCamera();

  renderGrid();

  m_app.DrawAll();

  renderSprings();
  renderLinks();
  renderStats();
}

void HMMWV9_IrrGuiDriver::renderSprings()
{
  std::list<chrono::ChLink*>::iterator ilink = m_app.GetSystem()->Get_linklist()->begin();
  for (; ilink != m_app.GetSystem()->Get_linklist()->end(); ++ilink) {
    if (ChLinkSpring* link = dynamic_cast<ChLinkSpring*>(*ilink)) {
      ChIrrTools::drawSpring(m_app.GetVideoDriver(), 0.05,
        link->GetEndPoint1Abs(),
        link->GetEndPoint2Abs(),
        video::SColor(255, 150, 20, 20), 80, 15, true);
    }
  }
}

void HMMWV9_IrrGuiDriver::renderLinks()
{
  std::list<chrono::ChLink*>::iterator ilink = m_app.GetSystem()->Get_linklist()->begin();
  for (; ilink != m_app.GetSystem()->Get_linklist()->end(); ++ilink) {
    if (ChLinkDistance* link = dynamic_cast<ChLinkDistance*>(*ilink)) {
      ChIrrTools::drawSegment(m_app.GetVideoDriver(),
        link->GetEndPoint1Abs(),
        link->GetEndPoint2Abs(),
        video::SColor(255, 0, 20, 0), true);
    }
  }
}

void HMMWV9_IrrGuiDriver::renderGrid()
{
  ChCoordsys<> gridCsys(ChVector<>(0, 0, m_terrainHeight + 0.02),
    chrono::Q_from_AngAxis(-CH_C_PI_2, VECT_Z));

  ChIrrTools::drawGrid(m_app.GetVideoDriver(),
    0.5, 0.5, 100, 100,
    gridCsys,
    video::SColor(255, 80, 130, 255),
    true);
}

void HMMWV9_IrrGuiDriver::renderStats()
{
  char msg[100];
  sprintf(msg, "Speed: %+.2f", m_car.GetVehicleSpeed());
  m_text_speed->setText(core::stringw(msg).c_str());
}

} // end namespace hmmwv9
<commit_msg>Fix comment.<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen
// =============================================================================
//
// Irrlicht-based GUI driver for the HMMWV9 model. This class implements the
// functionality required by its base ChDriver class using keyboard inputs.
// As an Irrlicht event receiver, its OnEvent() callback is used to keep track
// and update the current driver inputs. As such it does not need to override
// the default no-op Update() virtual method.
//
// In addition, this class provides additional Irrlicht support for the HMMWV9
// model:
//  - implements a custom camera (which follows the vehicle)
//  - provides support for rendering links, force elements, displaying stats,
//    etc.  In order to render these elements, call the its DrawAll() method
//    instead of ChIrrAppInterface::DrawAll().
//
// =============================================================================

#include "HMMWV9_IrrGuiDriver.h"

using namespace chrono;
using namespace irr;

namespace hmmwv9 {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
HMMWV9_IrrGuiDriver::HMMWV9_IrrGuiDriver(ChIrrApp&              app,
                                         const HMMWV9_Vehicle&  car,
                                         int                    tlc_X,
                                         int                    tlc_Y)
: m_app(app),
  m_car(car),
  m_terrainHeight(0)
{
  app.SetUserEventReceiver(this);

  gui::IGUIStaticText* text_inputs = app.GetIGUIEnvironment()->addStaticText(
    L"", core::rect<s32>(tlc_X, tlc_Y, tlc_X + 200, tlc_Y + 75), true, false, 0, -1, true);

  text_inputs->setBackgroundColor(video::SColor(255, 200, 200, 200));

  m_text_throttle = app.GetIGUIEnvironment()->addStaticText(
    L"Throttle: 0",
    core::rect<s32>(10, 10, 150, 25), false, false, text_inputs);

  m_text_steering = app.GetIGUIEnvironment()->addStaticText(
    L"Steering: 0",
    core::rect<s32>(10, 30, 150, 45), false, false, text_inputs);

  m_text_speed = app.GetIGUIEnvironment()->addStaticText(
    L"Speed: 0",
    core::rect<s32>(10, 50, 150, 65), false, false, text_inputs);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
bool HMMWV9_IrrGuiDriver::OnEvent(const SEvent& event)
{
  // user hit a key, while not holding it down
  if (event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
  {
    char msg[100];

    switch (event.KeyInput.Key) {
    case KEY_KEY_A:
      setSteering(m_steering - 0.1);
      sprintf(msg, "Steering: %+.2f", m_steering);
      m_text_steering->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_D:
      setSteering(m_steering + 0.1);
      sprintf(msg, "Steering: %+.2f", m_steering);
      m_text_steering->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_W:
      setThrottle(m_throttle + 0.1);
      sprintf(msg, "Throttle: %+.2f", m_throttle*100.);
      m_text_throttle->setText(core::stringw(msg).c_str());
      return true;
    case KEY_KEY_S:
      setThrottle(m_throttle - 0.1);
      sprintf(msg, "Throttle: %+.2f", m_throttle*100.);
      m_text_throttle->setText(core::stringw(msg).c_str());
      return true;

    case KEY_DOWN:
      m_cam_multiplier *= 1.01;
      return true;
    case KEY_UP:
      m_cam_multiplier /= 1.01;
    }
  }

  return false;

}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void HMMWV9_IrrGuiDriver::CreateCamera(const chrono::ChVector<>& cam_offset)
{
  m_cam_multiplier = 1;
  m_cam_offset = cam_offset;

  m_app.GetSceneManager()->addCameraSceneNode(
    m_app.GetSceneManager()->getRootSceneNode(),
    core::vector3df(0, 0, 0), core::vector3df(0, 0, 0));

  m_app.GetSceneManager()->getActiveCamera()->setUpVector(core::vector3df(0, 0, 1));

  updateCamera();
}

void HMMWV9_IrrGuiDriver::updateCamera()
{
  const ChVector<>& car_pos = m_car.GetChassisPos();
  ChVector<>        cam_pos = m_car.GetChassis()->GetCoord().TrasformLocalToParent(m_cam_multiplier * m_cam_offset);

  scene::ICameraSceneNode *camera = m_app.GetSceneManager()->getActiveCamera();

  camera->setPosition(core::vector3df((f32)cam_pos.x, (f32)cam_pos.y, (f32)cam_pos.z));
  camera->setTarget(core::vector3df((f32)car_pos.x, (f32)car_pos.y, (f32)car_pos.z));
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void HMMWV9_IrrGuiDriver::DrawAll()
{
  updateCamera();

  renderGrid();

  m_app.DrawAll();

  renderSprings();
  renderLinks();
  renderStats();
}

void HMMWV9_IrrGuiDriver::renderSprings()
{
  std::list<chrono::ChLink*>::iterator ilink = m_app.GetSystem()->Get_linklist()->begin();
  for (; ilink != m_app.GetSystem()->Get_linklist()->end(); ++ilink) {
    if (ChLinkSpring* link = dynamic_cast<ChLinkSpring*>(*ilink)) {
      ChIrrTools::drawSpring(m_app.GetVideoDriver(), 0.05,
        link->GetEndPoint1Abs(),
        link->GetEndPoint2Abs(),
        video::SColor(255, 150, 20, 20), 80, 15, true);
    }
  }
}

void HMMWV9_IrrGuiDriver::renderLinks()
{
  std::list<chrono::ChLink*>::iterator ilink = m_app.GetSystem()->Get_linklist()->begin();
  for (; ilink != m_app.GetSystem()->Get_linklist()->end(); ++ilink) {
    if (ChLinkDistance* link = dynamic_cast<ChLinkDistance*>(*ilink)) {
      ChIrrTools::drawSegment(m_app.GetVideoDriver(),
        link->GetEndPoint1Abs(),
        link->GetEndPoint2Abs(),
        video::SColor(255, 0, 20, 0), true);
    }
  }
}

void HMMWV9_IrrGuiDriver::renderGrid()
{
  ChCoordsys<> gridCsys(ChVector<>(0, 0, m_terrainHeight + 0.02),
    chrono::Q_from_AngAxis(-CH_C_PI_2, VECT_Z));

  ChIrrTools::drawGrid(m_app.GetVideoDriver(),
    0.5, 0.5, 100, 100,
    gridCsys,
    video::SColor(255, 80, 130, 255),
    true);
}

void HMMWV9_IrrGuiDriver::renderStats()
{
  char msg[100];
  sprintf(msg, "Speed: %+.2f", m_car.GetVehicleSpeed());
  m_text_speed->setText(core::stringw(msg).c_str());
}

} // end namespace hmmwv9
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 * $Log$
 * Revision 1.10  2003/12/17 00:18:38  cargilld
 * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data.
 *
 * Revision 1.9  2003/10/01 16:32:41  neilg
 * improve handling of out of memory conditions, bug #23415.  Thanks to David Cargill.
 *
 * Revision 1.8  2003/10/01 00:27:12  knoaman
 * Performance: call a static method to check the validity of URI instead of
 * creating/deleting local objects.
 *
 * Revision 1.7  2003/09/30 21:31:30  peiyongz
 * Implementation of Serialization/Deserialization
 *
 * Revision 1.6  2003/05/18 14:02:07  knoaman
 * Memory manager implementation: pass per instance manager.
 *
 * Revision 1.5  2003/05/16 06:01:57  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/05/15 18:53:26  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.3  2002/12/18 14:17:55  gareth
 * Fix to bug #13438. When you eant a vector that calls delete[] on its members you should use RefArrayVectorOf.
 *
 * Revision 1.2  2002/11/04 14:53:27  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:40  peiyongz
 * sane_include
 *
 * Revision 1.10  2001/10/10 14:18:26  peiyongz
 * no message
 *
 * Revision 1.9  2001/10/09 20:53:58  peiyongz
 * init(): take 1 arg.
 *
 * Revision 1.8  2001/10/02 18:59:29  peiyongz
 * Invalid_Facet_Tag to display the tag name
 *
 * Revision 1.7  2001/09/24 15:33:15  peiyongz
 * DTV Reorganization: virtual methods moved to *.cpp
 *
 * Revision 1.6  2001/09/19 18:49:17  peiyongz
 * DTV reorganization: move inline to class declaration to avoid inline
 * function interdependency.
 *
 * Revision 1.5  2001/09/18 20:38:03  peiyongz
 * DTV reorganization: inherit from AbstractStringValidator.
 *
 * Revision 1.4  2001/08/21 18:42:53  peiyongz
 * Bugzilla# 2816: cleanUp() declared with external linkage and called
 *                          before defined as inline
 *
 * Revision 1.3  2001/08/14 22:11:56  peiyongz
 * new exception message added
 *
 * Revision 1.2  2001/08/10 16:21:19  peiyongz
 * use XMLUri instead of XMLURL
 *
 * Revision 1.1  2001/08/01 18:49:16  peiyongz
 * AnyRUIDatatypeValidator
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
//http://www.template.com
//
static const XMLCh BASE_URI[] =
{
    chLatin_h, chLatin_t, chLatin_t, chLatin_p,
    chColon, chForwardSlash, chForwardSlash,
    chLatin_w, chLatin_w, chLatin_w, chPeriod,
    chLatin_t, chLatin_e, chLatin_m, chLatin_p, chLatin_l,
    chLatin_a, chLatin_t, chLatin_e, chPeriod,
    chLatin_c, chLatin_o, chLatin_m, chNull
};

// ---------------------------------------------------------------------------
//  Constructors and Destructor
// ---------------------------------------------------------------------------
AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager)
:AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager)
{}

AnyURIDatatypeValidator::~AnyURIDatatypeValidator()
{
}

AnyURIDatatypeValidator::AnyURIDatatypeValidator(
                          DatatypeValidator*            const baseValidator
                        , RefHashTableOf<KVStringPair>* const facets
                        , RefArrayVectorOf<XMLCh>*      const enums
                        , const int                           finalSet
                        , MemoryManager* const manager)
:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager)
{
    try
    {
        init(enums, manager);
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch (...)
    {
        throw;
    }
}

DatatypeValidator* AnyURIDatatypeValidator::newInstance(
                                      RefHashTableOf<KVStringPair>* const facets
                                    , RefArrayVectorOf<XMLCh>*           const enums
                                    , const int                           finalSet
                                    , MemoryManager* const manager)
{
    return (DatatypeValidator*) new (manager) AnyURIDatatypeValidator(this, facets, enums, finalSet, manager);
}

// ---------------------------------------------------------------------------
//  Utilities
// ---------------------------------------------------------------------------

void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content
                                              , MemoryManager* const manager)
{

    // check 3.2.17.c0 must: URI (rfc 2396/2723)
    try
    {
        // Support for relative URLs
        // According to Java 1.1: URLs may also be specified with a
        // String and the URL object that it is related to.
        //
        if (XMLString::stringLen(content))
        {
              if (!XMLUri::isValidURI(true, content))
                ThrowXMLwithMemMgr1(InvalidDatatypeValueException
                    , XMLExcepts::VALUE_URI_Malformed
                    , content
                    , manager);
        }
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch (...)
    {
        ThrowXMLwithMemMgr1(InvalidDatatypeValueException
                , XMLExcepts::VALUE_URI_Malformed
                , content
                , manager);
    }

}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator)

void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng)
{
    AbstractStringValidator::serialize(serEng);
}

XERCES_CPP_NAMESPACE_END

/**
  * End of file AnyURIDatatypeValidator.cpp
  */
<commit_msg>remove unused static member<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2004 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 * $Log$
 * Revision 1.11  2004/01/12 23:02:18  neilg
 * remove unused static member
 *
 * Revision 1.10  2003/12/17 00:18:38  cargilld
 * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data.
 *
 * Revision 1.9  2003/10/01 16:32:41  neilg
 * improve handling of out of memory conditions, bug #23415.  Thanks to David Cargill.
 *
 * Revision 1.8  2003/10/01 00:27:12  knoaman
 * Performance: call a static method to check the validity of URI instead of
 * creating/deleting local objects.
 *
 * Revision 1.7  2003/09/30 21:31:30  peiyongz
 * Implementation of Serialization/Deserialization
 *
 * Revision 1.6  2003/05/18 14:02:07  knoaman
 * Memory manager implementation: pass per instance manager.
 *
 * Revision 1.5  2003/05/16 06:01:57  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.4  2003/05/15 18:53:26  knoaman
 * Partial implementation of the configurable memory manager.
 *
 * Revision 1.3  2002/12/18 14:17:55  gareth
 * Fix to bug #13438. When you eant a vector that calls delete[] on its members you should use RefArrayVectorOf.
 *
 * Revision 1.2  2002/11/04 14:53:27  tng
 * C++ Namespace Support.
 *
 * Revision 1.1.1.1  2002/02/01 22:22:40  peiyongz
 * sane_include
 *
 * Revision 1.10  2001/10/10 14:18:26  peiyongz
 * no message
 *
 * Revision 1.9  2001/10/09 20:53:58  peiyongz
 * init(): take 1 arg.
 *
 * Revision 1.8  2001/10/02 18:59:29  peiyongz
 * Invalid_Facet_Tag to display the tag name
 *
 * Revision 1.7  2001/09/24 15:33:15  peiyongz
 * DTV Reorganization: virtual methods moved to *.cpp
 *
 * Revision 1.6  2001/09/19 18:49:17  peiyongz
 * DTV reorganization: move inline to class declaration to avoid inline
 * function interdependency.
 *
 * Revision 1.5  2001/09/18 20:38:03  peiyongz
 * DTV reorganization: inherit from AbstractStringValidator.
 *
 * Revision 1.4  2001/08/21 18:42:53  peiyongz
 * Bugzilla# 2816: cleanUp() declared with external linkage and called
 *                          before defined as inline
 *
 * Revision 1.3  2001/08/14 22:11:56  peiyongz
 * new exception message added
 *
 * Revision 1.2  2001/08/10 16:21:19  peiyongz
 * use XMLUri instead of XMLURL
 *
 * Revision 1.1  2001/08/01 18:49:16  peiyongz
 * AnyRUIDatatypeValidator
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Constructors and Destructor
// ---------------------------------------------------------------------------
AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager)
:AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager)
{}

AnyURIDatatypeValidator::~AnyURIDatatypeValidator()
{
}

AnyURIDatatypeValidator::AnyURIDatatypeValidator(
                          DatatypeValidator*            const baseValidator
                        , RefHashTableOf<KVStringPair>* const facets
                        , RefArrayVectorOf<XMLCh>*      const enums
                        , const int                           finalSet
                        , MemoryManager* const manager)
:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager)
{
    try
    {
        init(enums, manager);
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch (...)
    {
        throw;
    }
}

DatatypeValidator* AnyURIDatatypeValidator::newInstance(
                                      RefHashTableOf<KVStringPair>* const facets
                                    , RefArrayVectorOf<XMLCh>*           const enums
                                    , const int                           finalSet
                                    , MemoryManager* const manager)
{
    return (DatatypeValidator*) new (manager) AnyURIDatatypeValidator(this, facets, enums, finalSet, manager);
}

// ---------------------------------------------------------------------------
//  Utilities
// ---------------------------------------------------------------------------

void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content
                                              , MemoryManager* const manager)
{

    // check 3.2.17.c0 must: URI (rfc 2396/2723)
    try
    {
        // Support for relative URLs
        // According to Java 1.1: URLs may also be specified with a
        // String and the URL object that it is related to.
        //
        if (XMLString::stringLen(content))
        {
              if (!XMLUri::isValidURI(true, content))
                ThrowXMLwithMemMgr1(InvalidDatatypeValueException
                    , XMLExcepts::VALUE_URI_Malformed
                    , content
                    , manager);
        }
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch (...)
    {
        ThrowXMLwithMemMgr1(InvalidDatatypeValueException
                , XMLExcepts::VALUE_URI_Malformed
                , content
                , manager);
    }

}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator)

void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng)
{
    AbstractStringValidator::serialize(serEng);
}

XERCES_CPP_NAMESPACE_END

/**
  * End of file AnyURIDatatypeValidator.cpp
  */
<|endoftext|>