<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/lexical_cast.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <vector>
#include <map>
#include <utility>
#include <numeric>
#include <cstdio>

#include "libtorrent/peer_connection.hpp"
#include "libtorrent/bt_peer_connection.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/extensions.hpp"
#include "libtorrent/extensions/smart_ban.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/aux_/session_impl.hpp"

namespace libtorrent { namespace
{

	struct smart_ban_plugin : torrent_plugin, boost::enable_shared_from_this<smart_ban_plugin>
	{
		smart_ban_plugin(torrent& t)
			: m_torrent(t)
			, m_salt(rand())
		{
		}

		void on_piece_pass(int p)
		{
#ifdef TORRENT_LOGGING
			(*m_torrent.session().m_logger) << time_now_string() << " PIECE PASS [ p: " << p
				<< " | block_crc_size: " << m_block_crc.size() << " ]\n";
#endif
			// has this piece failed earlier? If it has, go through the
			// CRCs from the time it failed and ban the peers that
			// sent bad blocks
			std::map<piece_block, block_entry>::iterator i = m_block_crc.lower_bound(piece_block(p, 0));
			if (i == m_block_crc.end() || i->first.piece_index != p) return;

			int size = m_torrent.torrent_file().piece_size(p);
			peer_request r = {p, 0, (std::min)(16*1024, size)};
			piece_block pb(p, 0);
			while (size > 0)
			{
				if (i->first.block_index == pb.block_index)
				{
					m_torrent.filesystem().async_read(r, bind(&smart_ban_plugin::on_read_ok_block
						, shared_from_this(), *i, _1, _2));
					m_block_crc.erase(i++);
				}
				else
				{
					TORRENT_ASSERT(i->first.block_index > pb.block_index);
				}

				if (i == m_block_crc.end() || i->first.piece_index != p)
					break;

				r.start += 16*1024;
				size -= 16*1024;
				r.length = (std::min)(16*1024, size);
				++pb.block_index;
			}

#ifndef NDEBUG
			// make sure we actually removed all the entries for piece 'p'
			i = m_block_crc.lower_bound(piece_block(p, 0));
			TORRENT_ASSERT(i == m_block_crc.end() || i->first.piece_index != p);
#endif

			if (m_torrent.is_seed())
			{
				std::map<piece_block, block_entry>().swap(m_block_crc);
				return;
			}
		}

		void on_piece_failed(int p)
		{
			// The piece failed the hash check. Record
			// the CRC and origin peer of every block

			std::vector<void*> downloaders;
			m_torrent.picker().get_downloaders(downloaders, p);

			int size = m_torrent.torrent_file().piece_size(p);
			peer_request r = {p, 0, (std::min)(16*1024, size)};
			piece_block pb(p, 0);
			for (std::vector<void*>::iterator i = downloaders.begin()
				, end(downloaders.end()); i != end; ++i)
			{
				if (*i != 0)
				{
					m_torrent.filesystem().async_read(r, bind(&smart_ban_plugin::on_read_failed_block
						, shared_from_this(), pb, (policy::peer*)*i, _1, _2));
				}

				r.start += 16*1024;
				size -= 16*1024;
				r.length = (std::min)(16*1024, size);
				++pb.block_index;
			}
			TORRENT_ASSERT(size <= 0);
		}

	private:

		// this entry ties a specific block CRC to
		// a peer.
		struct block_entry
		{
			policy::peer* peer;
			unsigned long crc;
		};

		void on_read_failed_block(piece_block b, policy::peer* p, int ret, disk_io_job const& j)
		{
			TORRENT_ASSERT(p);
			// ignore read errors
			if (ret != j.buffer_size) return;

			adler32_crc crc;
			crc.update(j.buffer, j.buffer_size);
			crc.update((char const*)&m_salt, sizeof(m_salt));

			block_entry e = {p, crc.final()};

			// since this callback is called directory from the disk io
			// thread, the session mutex is not locked when we get here
			aux::session_impl::mutex_t::scoped_lock l(m_torrent.session().m_mutex);

			std::map<piece_block, block_entry>::iterator i = m_block_crc.lower_bound(b);
			if (i != m_block_crc.end() && i->first == b && i->second.peer == p)
			{
				// this peer has sent us this block before
				if (i->second.crc != e.crc)
				{
					// this time the crc of the block is different
					// from the first time it sent it
					// at least one of them must be bad

					if (p == 0) return;
					if (!m_torrent.get_policy().has_peer(p)) return;

#ifdef TORRENT_LOGGING
					char const* client = "-";
					peer_info info;
					if (p->connection)
					{
						p->connection->get_peer_info(info);
						client = info.client.c_str();
					}
					(*m_torrent.session().m_logger) << time_now_string() << " BANNING PEER [ p: " << b.piece_index
						<< " | b: " << b.block_index
						<< " | c: " << client
						<< " | crc1: " << i->second.crc
						<< " | crc2: " << e.crc
						<< " | ip: " << p->ip << " ]\n";
#endif
					p->banned = true;
					if (p->connection) p->connection->disconnect("banning peer for sending bad data");
				}
				// we already have this exact entry in the map
				// we don't have to insert it
				return;
			}

			m_block_crc.insert(i, std::make_pair(b, e));

#ifdef TORRENT_LOGGING
			char const* client = "-";
			peer_info info;
			if (p->connection)
			{
				p->connection->get_peer_info(info);
				client = info.client.c_str();
			}
			(*m_torrent.session().m_logger) << time_now_string() << " STORE BLOCK CRC [ p: " << b.piece_index
				<< " | b: " << b.block_index
				<< " | c: " << client
				<< " | crc: " << e.crc
				<< " | ip: " << p->ip << " ]\n";
#endif
		}

		void on_read_ok_block(std::pair<piece_block, block_entry> b, int ret, disk_io_job const& j)
		{
			// since this callback is called directory from the disk io
			// thread, the session mutex is not locked when we get here
			aux::session_impl::mutex_t::scoped_lock l(m_torrent.session().m_mutex);

			// ignore read errors
			if (ret != j.buffer_size) return;

			adler32_crc crc;
			crc.update(j.buffer, j.buffer_size);
			crc.update((char const*)&m_salt, sizeof(m_salt));
			unsigned long ok_crc = crc.final();

			if (b.second.crc == ok_crc) return;

			policy::peer* p = b.second.peer;

			if (p == 0) return;
			if (!m_torrent.get_policy().has_peer(p)) return;

#ifdef TORRENT_LOGGING
			char const* client = "-";
			peer_info info;
			if (p->connection)
			{
				p->connection->get_peer_info(info);
				client = info.client.c_str();
			}
			(*m_torrent.session().m_logger) << time_now_string() << " BANNING PEER [ p: " << b.first.piece_index
				<< " | b: " << b.first.block_index
				<< " | c: " << client
				<< " | ok_crc: " << ok_crc
				<< " | bad_crc: " << b.second.crc
				<< " | ip: " << p->ip << " ]\n";
#endif
			p->banned = true;
			if (p->connection) p->connection->disconnect("banning peer for sending bad data");
		}

		torrent& m_torrent;

		// This table maps a piece_block (piece and block index
		// pair) to a peer and the block CRC. The CRC is calculated
		// from the data in the block + the salt
		std::map<piece_block, block_entry> m_block_crc;

		// This salt is a random value used to calculate the block CRCs
		// Since the CRC function that is used is not a one way function
		// the salt is required to avoid attacks where bad data is sent
		// that is forged to match the CRC of the good data.
		int m_salt;
	};

} }

namespace libtorrent
{

	boost::shared_ptr<torrent_plugin> create_smart_ban_plugin(torrent* t, void*)
	{
		return boost::shared_ptr<torrent_plugin>(new smart_ban_plugin(*t));
	}

}

<commit_msg>fix smart ban assert when closing a torrent with a failing piece<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/lexical_cast.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <vector>
#include <map>
#include <utility>
#include <numeric>
#include <cstdio>

#include "libtorrent/peer_connection.hpp"
#include "libtorrent/bt_peer_connection.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/extensions.hpp"
#include "libtorrent/extensions/smart_ban.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/aux_/session_impl.hpp"

namespace libtorrent { namespace
{

	struct smart_ban_plugin : torrent_plugin, boost::enable_shared_from_this<smart_ban_plugin>
	{
		smart_ban_plugin(torrent& t)
			: m_torrent(t)
			, m_salt(rand())
		{
		}

		void on_piece_pass(int p)
		{
#ifdef TORRENT_LOGGING
			(*m_torrent.session().m_logger) << time_now_string() << " PIECE PASS [ p: " << p
				<< " | block_crc_size: " << m_block_crc.size() << " ]\n";
#endif
			// has this piece failed earlier? If it has, go through the
			// CRCs from the time it failed and ban the peers that
			// sent bad blocks
			std::map<piece_block, block_entry>::iterator i = m_block_crc.lower_bound(piece_block(p, 0));
			if (i == m_block_crc.end() || i->first.piece_index != p) return;

			int size = m_torrent.torrent_file().piece_size(p);
			peer_request r = {p, 0, (std::min)(16*1024, size)};
			piece_block pb(p, 0);
			while (size > 0)
			{
				if (i->first.block_index == pb.block_index)
				{
					m_torrent.filesystem().async_read(r, bind(&smart_ban_plugin::on_read_ok_block
						, shared_from_this(), *i, _1, _2));
					m_block_crc.erase(i++);
				}
				else
				{
					TORRENT_ASSERT(i->first.block_index > pb.block_index);
				}

				if (i == m_block_crc.end() || i->first.piece_index != p)
					break;

				r.start += 16*1024;
				size -= 16*1024;
				r.length = (std::min)(16*1024, size);
				++pb.block_index;
			}

#ifndef NDEBUG
			// make sure we actually removed all the entries for piece 'p'
			i = m_block_crc.lower_bound(piece_block(p, 0));
			TORRENT_ASSERT(i == m_block_crc.end() || i->first.piece_index != p);
#endif

			if (m_torrent.is_seed())
			{
				std::map<piece_block, block_entry>().swap(m_block_crc);
				return;
			}
		}

		void on_piece_failed(int p)
		{
			// The piece failed the hash check. Record
			// the CRC and origin peer of every block

			// if the torrent is aborted, no point in starting
			// a bunch of read operations on it
			if (m_torrent.is_aborted()) return;

			std::vector<void*> downloaders;
			m_torrent.picker().get_downloaders(downloaders, p);

			int size = m_torrent.torrent_file().piece_size(p);
			peer_request r = {p, 0, (std::min)(16*1024, size)};
			piece_block pb(p, 0);
			for (std::vector<void*>::iterator i = downloaders.begin()
				, end(downloaders.end()); i != end; ++i)
			{
				if (*i != 0)
				{
					m_torrent.filesystem().async_read(r, bind(&smart_ban_plugin::on_read_failed_block
						, shared_from_this(), pb, (policy::peer*)*i, _1, _2));
				}

				r.start += 16*1024;
				size -= 16*1024;
				r.length = (std::min)(16*1024, size);
				++pb.block_index;
			}
			TORRENT_ASSERT(size <= 0);
		}

	private:

		// this entry ties a specific block CRC to
		// a peer.
		struct block_entry
		{
			policy::peer* peer;
			unsigned long crc;
		};

		void on_read_failed_block(piece_block b, policy::peer* p, int ret, disk_io_job const& j)
		{
			TORRENT_ASSERT(p);
			// ignore read errors
			if (ret != j.buffer_size) return;

			adler32_crc crc;
			crc.update(j.buffer, j.buffer_size);
			crc.update((char const*)&m_salt, sizeof(m_salt));

			block_entry e = {p, crc.final()};

			// since this callback is called directory from the disk io
			// thread, the session mutex is not locked when we get here
			aux::session_impl::mutex_t::scoped_lock l(m_torrent.session().m_mutex);

			std::map<piece_block, block_entry>::iterator i = m_block_crc.lower_bound(b);
			if (i != m_block_crc.end() && i->first == b && i->second.peer == p)
			{
				// this peer has sent us this block before
				if (i->second.crc != e.crc)
				{
					// this time the crc of the block is different
					// from the first time it sent it
					// at least one of them must be bad

					if (p == 0) return;
					if (!m_torrent.get_policy().has_peer(p)) return;

#ifdef TORRENT_LOGGING
					char const* client = "-";
					peer_info info;
					if (p->connection)
					{
						p->connection->get_peer_info(info);
						client = info.client.c_str();
					}
					(*m_torrent.session().m_logger) << time_now_string() << " BANNING PEER [ p: " << b.piece_index
						<< " | b: " << b.block_index
						<< " | c: " << client
						<< " | crc1: " << i->second.crc
						<< " | crc2: " << e.crc
						<< " | ip: " << p->ip << " ]\n";
#endif
					p->banned = true;
					if (p->connection) p->connection->disconnect("banning peer for sending bad data");
				}
				// we already have this exact entry in the map
				// we don't have to insert it
				return;
			}

			m_block_crc.insert(i, std::make_pair(b, e));

#ifdef TORRENT_LOGGING
			char const* client = "-";
			peer_info info;
			if (p->connection)
			{
				p->connection->get_peer_info(info);
				client = info.client.c_str();
			}
			(*m_torrent.session().m_logger) << time_now_string() << " STORE BLOCK CRC [ p: " << b.piece_index
				<< " | b: " << b.block_index
				<< " | c: " << client
				<< " | crc: " << e.crc
				<< " | ip: " << p->ip << " ]\n";
#endif
		}

		void on_read_ok_block(std::pair<piece_block, block_entry> b, int ret, disk_io_job const& j)
		{
			// since this callback is called directory from the disk io
			// thread, the session mutex is not locked when we get here
			aux::session_impl::mutex_t::scoped_lock l(m_torrent.session().m_mutex);

			// ignore read errors
			if (ret != j.buffer_size) return;

			adler32_crc crc;
			crc.update(j.buffer, j.buffer_size);
			crc.update((char const*)&m_salt, sizeof(m_salt));
			unsigned long ok_crc = crc.final();

			if (b.second.crc == ok_crc) return;

			policy::peer* p = b.second.peer;

			if (p == 0) return;
			if (!m_torrent.get_policy().has_peer(p)) return;

#ifdef TORRENT_LOGGING
			char const* client = "-";
			peer_info info;
			if (p->connection)
			{
				p->connection->get_peer_info(info);
				client = info.client.c_str();
			}
			(*m_torrent.session().m_logger) << time_now_string() << " BANNING PEER [ p: " << b.first.piece_index
				<< " | b: " << b.first.block_index
				<< " | c: " << client
				<< " | ok_crc: " << ok_crc
				<< " | bad_crc: " << b.second.crc
				<< " | ip: " << p->ip << " ]\n";
#endif
			p->banned = true;
			if (p->connection) p->connection->disconnect("banning peer for sending bad data");
		}

		torrent& m_torrent;

		// This table maps a piece_block (piece and block index
		// pair) to a peer and the block CRC. The CRC is calculated
		// from the data in the block + the salt
		std::map<piece_block, block_entry> m_block_crc;

		// This salt is a random value used to calculate the block CRCs
		// Since the CRC function that is used is not a one way function
		// the salt is required to avoid attacks where bad data is sent
		// that is forged to match the CRC of the good data.
		int m_salt;
	};

} }

namespace libtorrent
{

	boost::shared_ptr<torrent_plugin> create_smart_ban_plugin(torrent* t, void*)
	{
		return boost::shared_ptr<torrent_plugin>(new smart_ban_plugin(*t));
	}

}

<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "ui/gfx/native_theme_aura.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "grit/gfx_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skbitmap_operations.h"

namespace {

const SkColor kMenuBackgroundColor = SkColorSetRGB(0xED, 0xED, 0xED);

// Theme colors returned by GetSystemColor().
const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128);
// Dialogs:
const SkColor kDialogBackgroundColor = SK_ColorWHITE;
// FocusableBorder:
const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE);
const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9);
// TextButton:
const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xDE, 0xDE, 0xDE);
const SkColor kTextButtonEnabledColor = SkColorSetRGB(0x44, 0x44, 0x44);
const SkColor kTextButtonDisabledColor = SkColorSetRGB(0x99, 0x99, 0x99);
const SkColor kTextButtonHighlightColor = SkColorSetRGB(0, 0, 0);
const SkColor kTextButtonHoverColor = kTextButtonEnabledColor;
// MenuItem:
const SkColor kEnabledMenuItemForegroundColor = SK_ColorBLACK;
const SkColor kDisabledMenuItemForegroundColor =
    SkColorSetRGB(0x80, 0x80, 0x80);
const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(0xDC, 0xE4, 0xFA);
// Textfield:
const SkColor kTextfieldDefaultColor = SK_ColorBLACK;
const SkColor kTextfieldDefaultBackground = SK_ColorWHITE;
const SkColor kTextfieldSelectionColor = SK_ColorWHITE;
const SkColor kTextfieldSelectionBackgroundFocused =
    SkColorSetRGB(0x1D, 0x90, 0xFF);
const SkColor kTextfieldSelectionBackgroundUnfocused = SK_ColorLTGRAY;

}  // namespace

namespace gfx {

// static
const NativeTheme* NativeTheme::instance() {
  return NativeThemeAura::instance();
}

// static
const NativeThemeAura* NativeThemeAura::instance() {
  CR_DEFINE_STATIC_LOCAL(NativeThemeAura, s_native_theme, ());
  return &s_native_theme;
}

NativeThemeAura::NativeThemeAura() {
}

NativeThemeAura::~NativeThemeAura() {
}

SkColor NativeThemeAura::GetSystemColor(ColorId color_id) const {
  // This implementation returns hardcoded colors.
  switch (color_id) {

    // Dialogs
    case kColorId_DialogBackground:
      return kDialogBackgroundColor;

    // FocusableBorder
    case kColorId_FocusedBorderColor:
      return kFocusedBorderColor;
    case kColorId_UnfocusedBorderColor:
      return kUnfocusedBorderColor;

    // TextButton
    case kColorId_TextButtonBackgroundColor:
      return kTextButtonBackgroundColor;
    case kColorId_TextButtonEnabledColor:
      return kTextButtonEnabledColor;
    case kColorId_TextButtonDisabledColor:
      return kTextButtonDisabledColor;
    case kColorId_TextButtonHighlightColor:
      return kTextButtonHighlightColor;
    case kColorId_TextButtonHoverColor:
      return kTextButtonHoverColor;

    // MenuItem
    case kColorId_EnabledMenuItemForegroundColor:
      return kEnabledMenuItemForegroundColor;
    case kColorId_DisabledMenuItemForegroundColor:
      return kDisabledMenuItemForegroundColor;
    case kColorId_FocusedMenuItemBackgroundColor:
      return kFocusedMenuItemBackgroundColor;

    // Textfield
    case kColorId_TextfieldDefaultColor:
      return kTextfieldDefaultColor;
    case kColorId_TextfieldDefaultBackground:
      return kTextfieldDefaultBackground;
    case kColorId_TextfieldSelectionColor:
      return kTextfieldSelectionColor;
    case kColorId_TextfieldSelectionBackgroundFocused:
      return kTextfieldSelectionBackgroundFocused;
    case kColorId_TextfieldSelectionBackgroundUnfocused:
      return kTextfieldSelectionBackgroundUnfocused;

    default:
      NOTREACHED() << "Invalid color_id: " << color_id;
      break;
  }

  // Return InvalidColor
  return kInvalidColorIdColor;
}

void NativeThemeAura::PaintMenuPopupBackground(
    SkCanvas* canvas,
    State state,
    const gfx::Rect& rect,
    const MenuListExtraParams& menu_list) const {
  canvas->drawColor(kMenuBackgroundColor, SkXfermode::kSrc_Mode);
}

void NativeThemeAura::PaintScrollbarTrack(
    SkCanvas* canvas,
    Part part,
    State state,
    const ScrollbarTrackExtraParams& extra_params,
    const gfx::Rect& rect) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  if (part == kScrollbarVerticalTrack) {
    SkBitmap* background = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND);
    SkBitmap* border_up = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP);
    SkBitmap* border_down =
        rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN);
    // Draw track background.
    DrawBitmapInt(
        canvas, *background,
        0, 0, background->width(), 1,
        rect.x(), rect.y(), rect.width(), rect.height());
    // Draw up button lower border.
    canvas->drawBitmap(*border_up, extra_params.track_x, extra_params.track_y);
    // Draw down button upper border.
    canvas->drawBitmap(
        *border_down,
        extra_params.track_x,
        extra_params.track_y + extra_params.track_height - border_down->height()
        );
  } else {
    SkBitmap* background =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND);
    SkBitmap* border_left =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP);
    SkBitmap* border_right =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN);
    // Draw track background.
    DrawBitmapInt(
        canvas, *background,
        0, 0, 1, background->height(),
        rect.x(), rect.y(), rect.width(), rect.height());
    // Draw left button right border.
    canvas->drawBitmap(*border_left,extra_params.track_x, extra_params.track_y);
    // Draw right button left border.
    canvas->drawBitmap(
        *border_right,
        extra_params.track_x + extra_params.track_width - border_right->width(),
        extra_params.track_y);
  }
}

void NativeThemeAura::PaintArrowButton(SkCanvas* canvas,
    const gfx::Rect& rect, Part part, State state) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  int resource_id =
      (part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ?
          IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN;
  if (state == kHovered)
    resource_id++;
  else if (state == kPressed)
    resource_id += 2;
  SkBitmap* bitmap;
  if (part == kScrollbarUpArrow || part == kScrollbarDownArrow)
    bitmap = rb.GetBitmapNamed(resource_id);
  else
    bitmap = GetHorizontalBitmapNamed(resource_id);
  DrawBitmapInt(canvas, *bitmap,
      0, 0, bitmap->width(), bitmap->height(),
      rect.x(), rect.y(), rect.width(), rect.height());
}

void NativeThemeAura::PaintScrollbarThumb(SkCanvas* canvas,
    Part part, State state, const gfx::Rect& rect) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  int resource_id = IDR_SCROLL_THUMB;
  if (state == kHovered)
    resource_id++;
  else if (state == kPressed)
    resource_id += 2;
  if (part == kScrollbarVerticalThumb) {
    SkBitmap* bitmap = rb.GetBitmapNamed(resource_id);
    // Top
    DrawBitmapInt(
        canvas, *bitmap,
        0, 1, bitmap->width(), 5,
        rect.x(), rect.y(), rect.width(), 5);
    // Middle
    DrawBitmapInt(
        canvas, *bitmap,
        0, 7, bitmap->width(), 1,
        rect.x(), rect.y() + 5, rect.width(), rect.height() - 10);
    // Bottom
    DrawBitmapInt(
        canvas, *bitmap,
        0, 8, bitmap->width(), 5,
        rect.x(), rect.y() + rect.height() - 5, rect.width(), 5);
  } else {
    SkBitmap* bitmap = GetHorizontalBitmapNamed(resource_id);
    // Left
    DrawBitmapInt(
        canvas, *bitmap,
        1, 0, 5, bitmap->height(),
        rect.x(), rect.y(), 5, rect.height());
    // Middle
    DrawBitmapInt(
        canvas, *bitmap,
        7, 0, 1, bitmap->height(),
        rect.x() + 5, rect.y(), rect.width() - 10, rect.height());
    // Right
    DrawBitmapInt(
        canvas, *bitmap,
        8, 0, 5, bitmap->height(),
        rect.x() + rect.width() - 5, rect.y(), 5, rect.height());
  }
}

SkBitmap* NativeThemeAura::GetHorizontalBitmapNamed(int resource_id) const {
  SkImageMap::const_iterator found = horizontal_bitmaps_.find(resource_id);
  if (found != horizontal_bitmaps_.end())
    return found->second;

  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  SkBitmap* vertical_bitmap = rb.GetBitmapNamed(resource_id);

  if (vertical_bitmap) {
    SkBitmap transposed_bitmap =
        SkBitmapOperations::CreateTransposedBtmap(*vertical_bitmap);
    SkBitmap* horizontal_bitmap = new SkBitmap(transposed_bitmap);

    horizontal_bitmaps_[resource_id] = horizontal_bitmap;
    return horizontal_bitmap;
  }
  return NULL;
}

}  // namespace gfx
<commit_msg>Update menu color to match mocks on Aura<commit_after>// Copyright (c) 2012 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 "ui/gfx/native_theme_aura.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "grit/gfx_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skbitmap_operations.h"

namespace {

const SkColor kMenuBackgroundColor = SK_ColorWHITE;

// Theme colors returned by GetSystemColor().
const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128);
// Dialogs:
const SkColor kDialogBackgroundColor = SK_ColorWHITE;
// FocusableBorder:
const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE);
const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9);
// TextButton:
const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xDE, 0xDE, 0xDE);
const SkColor kTextButtonEnabledColor = SkColorSetRGB(0x44, 0x44, 0x44);
const SkColor kTextButtonDisabledColor = SkColorSetRGB(0x99, 0x99, 0x99);
const SkColor kTextButtonHighlightColor = SkColorSetRGB(0, 0, 0);
const SkColor kTextButtonHoverColor = kTextButtonEnabledColor;
// MenuItem:
const SkColor kEnabledMenuItemForegroundColor = SK_ColorBLACK;
const SkColor kDisabledMenuItemForegroundColor =
    SkColorSetRGB(0x80, 0x80, 0x80);
const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(0xF1, 0xF1, 0xF1);
// Textfield:
const SkColor kTextfieldDefaultColor = SK_ColorBLACK;
const SkColor kTextfieldDefaultBackground = SK_ColorWHITE;
const SkColor kTextfieldSelectionColor = SK_ColorWHITE;
const SkColor kTextfieldSelectionBackgroundFocused =
    SkColorSetRGB(0x1D, 0x90, 0xFF);
const SkColor kTextfieldSelectionBackgroundUnfocused = SK_ColorLTGRAY;

}  // namespace

namespace gfx {

// static
const NativeTheme* NativeTheme::instance() {
  return NativeThemeAura::instance();
}

// static
const NativeThemeAura* NativeThemeAura::instance() {
  CR_DEFINE_STATIC_LOCAL(NativeThemeAura, s_native_theme, ());
  return &s_native_theme;
}

NativeThemeAura::NativeThemeAura() {
}

NativeThemeAura::~NativeThemeAura() {
}

SkColor NativeThemeAura::GetSystemColor(ColorId color_id) const {
  // This implementation returns hardcoded colors.
  switch (color_id) {

    // Dialogs
    case kColorId_DialogBackground:
      return kDialogBackgroundColor;

    // FocusableBorder
    case kColorId_FocusedBorderColor:
      return kFocusedBorderColor;
    case kColorId_UnfocusedBorderColor:
      return kUnfocusedBorderColor;

    // TextButton
    case kColorId_TextButtonBackgroundColor:
      return kTextButtonBackgroundColor;
    case kColorId_TextButtonEnabledColor:
      return kTextButtonEnabledColor;
    case kColorId_TextButtonDisabledColor:
      return kTextButtonDisabledColor;
    case kColorId_TextButtonHighlightColor:
      return kTextButtonHighlightColor;
    case kColorId_TextButtonHoverColor:
      return kTextButtonHoverColor;

    // MenuItem
    case kColorId_EnabledMenuItemForegroundColor:
      return kEnabledMenuItemForegroundColor;
    case kColorId_DisabledMenuItemForegroundColor:
      return kDisabledMenuItemForegroundColor;
    case kColorId_FocusedMenuItemBackgroundColor:
      return kFocusedMenuItemBackgroundColor;

    // Textfield
    case kColorId_TextfieldDefaultColor:
      return kTextfieldDefaultColor;
    case kColorId_TextfieldDefaultBackground:
      return kTextfieldDefaultBackground;
    case kColorId_TextfieldSelectionColor:
      return kTextfieldSelectionColor;
    case kColorId_TextfieldSelectionBackgroundFocused:
      return kTextfieldSelectionBackgroundFocused;
    case kColorId_TextfieldSelectionBackgroundUnfocused:
      return kTextfieldSelectionBackgroundUnfocused;

    default:
      NOTREACHED() << "Invalid color_id: " << color_id;
      break;
  }

  // Return InvalidColor
  return kInvalidColorIdColor;
}

void NativeThemeAura::PaintMenuPopupBackground(
    SkCanvas* canvas,
    State state,
    const gfx::Rect& rect,
    const MenuListExtraParams& menu_list) const {
  canvas->drawColor(kMenuBackgroundColor, SkXfermode::kSrc_Mode);
}

void NativeThemeAura::PaintScrollbarTrack(
    SkCanvas* canvas,
    Part part,
    State state,
    const ScrollbarTrackExtraParams& extra_params,
    const gfx::Rect& rect) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  if (part == kScrollbarVerticalTrack) {
    SkBitmap* background = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND);
    SkBitmap* border_up = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP);
    SkBitmap* border_down =
        rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN);
    // Draw track background.
    DrawBitmapInt(
        canvas, *background,
        0, 0, background->width(), 1,
        rect.x(), rect.y(), rect.width(), rect.height());
    // Draw up button lower border.
    canvas->drawBitmap(*border_up, extra_params.track_x, extra_params.track_y);
    // Draw down button upper border.
    canvas->drawBitmap(
        *border_down,
        extra_params.track_x,
        extra_params.track_y + extra_params.track_height - border_down->height()
        );
  } else {
    SkBitmap* background =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND);
    SkBitmap* border_left =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP);
    SkBitmap* border_right =
        GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN);
    // Draw track background.
    DrawBitmapInt(
        canvas, *background,
        0, 0, 1, background->height(),
        rect.x(), rect.y(), rect.width(), rect.height());
    // Draw left button right border.
    canvas->drawBitmap(*border_left,extra_params.track_x, extra_params.track_y);
    // Draw right button left border.
    canvas->drawBitmap(
        *border_right,
        extra_params.track_x + extra_params.track_width - border_right->width(),
        extra_params.track_y);
  }
}

void NativeThemeAura::PaintArrowButton(SkCanvas* canvas,
    const gfx::Rect& rect, Part part, State state) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  int resource_id =
      (part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ?
          IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN;
  if (state == kHovered)
    resource_id++;
  else if (state == kPressed)
    resource_id += 2;
  SkBitmap* bitmap;
  if (part == kScrollbarUpArrow || part == kScrollbarDownArrow)
    bitmap = rb.GetBitmapNamed(resource_id);
  else
    bitmap = GetHorizontalBitmapNamed(resource_id);
  DrawBitmapInt(canvas, *bitmap,
      0, 0, bitmap->width(), bitmap->height(),
      rect.x(), rect.y(), rect.width(), rect.height());
}

void NativeThemeAura::PaintScrollbarThumb(SkCanvas* canvas,
    Part part, State state, const gfx::Rect& rect) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  int resource_id = IDR_SCROLL_THUMB;
  if (state == kHovered)
    resource_id++;
  else if (state == kPressed)
    resource_id += 2;
  if (part == kScrollbarVerticalThumb) {
    SkBitmap* bitmap = rb.GetBitmapNamed(resource_id);
    // Top
    DrawBitmapInt(
        canvas, *bitmap,
        0, 1, bitmap->width(), 5,
        rect.x(), rect.y(), rect.width(), 5);
    // Middle
    DrawBitmapInt(
        canvas, *bitmap,
        0, 7, bitmap->width(), 1,
        rect.x(), rect.y() + 5, rect.width(), rect.height() - 10);
    // Bottom
    DrawBitmapInt(
        canvas, *bitmap,
        0, 8, bitmap->width(), 5,
        rect.x(), rect.y() + rect.height() - 5, rect.width(), 5);
  } else {
    SkBitmap* bitmap = GetHorizontalBitmapNamed(resource_id);
    // Left
    DrawBitmapInt(
        canvas, *bitmap,
        1, 0, 5, bitmap->height(),
        rect.x(), rect.y(), 5, rect.height());
    // Middle
    DrawBitmapInt(
        canvas, *bitmap,
        7, 0, 1, bitmap->height(),
        rect.x() + 5, rect.y(), rect.width() - 10, rect.height());
    // Right
    DrawBitmapInt(
        canvas, *bitmap,
        8, 0, 5, bitmap->height(),
        rect.x() + rect.width() - 5, rect.y(), 5, rect.height());
  }
}

SkBitmap* NativeThemeAura::GetHorizontalBitmapNamed(int resource_id) const {
  SkImageMap::const_iterator found = horizontal_bitmaps_.find(resource_id);
  if (found != horizontal_bitmaps_.end())
    return found->second;

  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  SkBitmap* vertical_bitmap = rb.GetBitmapNamed(resource_id);

  if (vertical_bitmap) {
    SkBitmap transposed_bitmap =
        SkBitmapOperations::CreateTransposedBtmap(*vertical_bitmap);
    SkBitmap* horizontal_bitmap = new SkBitmap(transposed_bitmap);

    horizontal_bitmaps_[resource_id] = horizontal_bitmap;
    return horizontal_bitmap;
  }
  return NULL;
}

}  // namespace gfx
<|endoftext|>


<commit_before>#include "spectests.h"

namespace Test {
	namespace Spec {
		// 2.1
		TEST SeqScalars()
        {
            return "  not written yet";
        }

		// 2.2
		TEST MappingScalarsToScalars()
        {
            return "  not written yet";
        }

		// 2.3
		TEST MappingScalarsToSequences()
        {
            return "  not written yet";
        }

		// 2.4
		TEST SequenceOfMappings()
        {
            return "  not written yet";
        }

		// 2.5
		TEST SequenceOfSequences()
        {
            return "  not written yet";
        }

		// 2.6
		TEST MappingOfMappings()
        {
            return "  not written yet";
        }

		// 2.7
		TEST TwoDocumentsInAStream()
        {
            return "  not written yet";
        }

		// 2.8
		TEST PlayByPlayFeed()
        {
            return "  not written yet";
        }

		// 2.9
		TEST SingleDocumentWithTwoComments()
        {
            return "  not written yet";
        }

		// 2.10
		TEST SimpleAnchor()
        {
            return "  not written yet";
        }

		// 2.11
		TEST MappingBetweenSequences()
        {
            return "  not written yet";
        }

		// 2.12
		TEST CompactNestedMapping()
        {
            return "  not written yet";
        }

		// 2.13
		TEST InLiteralsNewlinesArePreserved()
        {
            return "  not written yet";
        }

		// 2.14
		TEST InFoldedScalarsNewlinesBecomeSpaces()
        {
            return "  not written yet";
        }

		// 2.15
		TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
        {
            return "  not written yet";
        }

		// 2.16
		TEST IndentationDeterminesScope()
        {
            return "  not written yet";
        }

		// 2.17
		TEST QuotedScalars()
        {
            return "  not written yet";
        }

		// 2.18
		TEST MultiLineFlowScalars()
        {
            return "  not written yet";
        }

		// TODO: 2.19 - 2.22 schema tags

		// 2.23
		TEST VariousExplicitTags()
        {
            return "  not written yet";
        }

		// 2.24
		TEST GlobalTags()
        {
            return "  not written yet";
        }

		// 2.25
		TEST UnorderedSets()
        {
            return "  not written yet";
        }

		// 2.26
		TEST OrderedMappings()
        {
            return "  not written yet";
        }

		// 2.27
		TEST Invoice()
        {
            return "  not written yet";
        }

		// 2.28
		TEST LogFile()
        {
            return "  not written yet";
        }

		// TODO: 5.1 - 5.2 BOM

		// 5.3
		TEST BlockStructureIndicators()
        {
            return "  not written yet";
        }

		// 5.4
		TEST FlowStructureIndicators()
        {
            return "  not written yet";
        }

		// 5.5
		TEST CommentIndicator()
        {
            return "  not written yet";
        }

		// 5.6
		TEST NodePropertyIndicators()
        {
            return "  not written yet";
        }

		// 5.7
		TEST BlockScalarIndicators()
        {
            return "  not written yet";
        }

		// 5.8
		TEST QuotedScalarIndicators()
        {
            return "  not written yet";
        }

		// TODO: 5.9 directive
		// TODO: 5.10 reserved indicator

		// 5.11
		TEST LineBreakCharacters()
        {
            return "  not written yet";
        }

		// 5.12
		TEST TabsAndSpaces()
        {
            return "  not written yet";
        }

		// 5.13
		TEST EscapedCharacters()
        {
            return "  not written yet";
        }

		// 5.14
		TEST InvalidEscapedCharacters()
        {
            return "  not written yet";
        }

		// 6.1
		TEST IndentationSpaces()
        {
            return "  not written yet";
        }

		// 6.2
		TEST IndentationIndicators()
        {
            return "  not written yet";
        }

		// 6.3
		TEST SeparationSpaces()
        {
            return "  not written yet";
        }

		// 6.4
		TEST LinePrefixes()
        {
            return "  not written yet";
        }

		// 6.5
		TEST EmptyLines()
        {
            return "  not written yet";
        }

		// 6.6
		TEST LineFolding()
        {
            return "  not written yet";
        }

		// 6.7
		TEST BlockFolding()
        {
            return "  not written yet";
        }

		// 6.8
		TEST FlowFolding()
        {
            return "  not written yet";
        }

		// 6.9
		TEST SeparatedComment()
        {
            return "  not written yet";
        }

		// 6.10
		TEST CommentLines()
        {
            return "  not written yet";
        }

		// 6.11
		TEST MultiLineComments()
        {
            return "  not written yet";
        }

		// 6.12
		TEST SeparationSpacesII()
        {
            return "  not written yet";
        }

		// 6.13
		TEST ReservedDirectives()
        {
            return "  not written yet";
        }

		// 6.14
		TEST YAMLDirective()
        {
            return "  not written yet";
        }

		// 6.15
		TEST InvalidRepeatedYAMLDirective()
        {
            return "  not written yet";
        }

		// 6.16
		TEST TagDirective()
        {
            return "  not written yet";
        }

		// 6.17
		TEST InvalidRepeatedTagDirective()
        {
            return "  not written yet";
        }

		// 6.18
		TEST PrimaryTagHandle()
        {
            return "  not written yet";
        }

		// 6.19
		TEST SecondaryTagHandle()
        {
            return "  not written yet";
        }

		// 6.20
		TEST TagHandles()
        {
            return "  not written yet";
        }

		// 6.21
		TEST LocalTagPrefix()
        {
            return "  not written yet";
        }

		// 6.22
		TEST GlobalTagPrefix()
        {
            return "  not written yet";
        }

		// 6.23
		TEST NodeProperties()
        {
            return "  not written yet";
        }

		// 6.24
		TEST VerbatimTags()
        {
            return "  not written yet";
        }

		// 6.25
		TEST InvalidVerbatimTags()
        {
            return "  not written yet";
        }

		// 6.26
		TEST TagShorthands()
        {
            return "  not written yet";
        }

		// 6.27
		TEST InvalidTagShorthands()
        {
            return "  not written yet";
        }

		// 6.28
		TEST NonSpecificTags()
        {
            return "  not written yet";
        }

		// 6.29
		TEST NodeAnchors()
        {
            return "  not written yet";
        }

		// 7.1
		TEST AliasNodes()
        {
            return "  not written yet";
        }

		// 7.2
		TEST EmptyNodes()
        {
            return "  not written yet";
        }

		// 7.3
		TEST CompletelyEmptyNodes()
        {
            return "  not written yet";
        }

		// 7.4
		TEST DoubleQuotedImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.5
		TEST DoubleQuotedLineBreaks()
        {
            return "  not written yet";
        }

		// 7.6
		TEST DoubleQuotedLines()
        {
            return "  not written yet";
        }

		// 7.7
		TEST SingleQuotedCharacters()
        {
            return "  not written yet";
        }

		// 7.8
		TEST SingleQuotedImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.9
		TEST SingleQuotedLines()
        {
            return "  not written yet";
        }

		// 7.10
		TEST PlainCharacters()
        {
            return "  not written yet";
        }

		// 7.11
		TEST PlainImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.12
		TEST PlainLines()
        {
            return "  not written yet";
        }

		// 7.13
		TEST FlowSequence()
        {
            return "  not written yet";
        }

		// 7.14
		TEST FlowSequenceEntries()
        {
            return "  not written yet";
        }

		// 7.15
		TEST FlowMappings()
        {
            return "  not written yet";
        }

		// 7.16
		TEST FlowMappingEntries()
        {
            return "  not written yet";
        }

		// 7.17
		TEST FlowMappingSeparateValues()
        {
            return "  not written yet";
        }

		// 7.18
		TEST FlowMappingAdjacentValues()
        {
            return "  not written yet";
        }

		// 7.19
		TEST SinglePairFlowMappings()
        {
            return "  not written yet";
        }

		// 7.20
		TEST SinglePairExplicitEntry()
        {
            return "  not written yet";
        }

		// 7.21
		TEST SinglePairImplicitEntries()
        {
            return "  not written yet";
        }

		// 7.22
		TEST InvalidImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.23
		TEST FlowContent()
        {
            return "  not written yet";
        }

		// 7.24
		TEST FlowNodes()
        {
            return "  not written yet";
        }

		// 8.1
		TEST BlockScalarHeader()
        {
            return "  not written yet";
        }

		// 8.2
		TEST BlockIndentationHeader()
        {
            return "  not written yet";
        }

		// 8.3
		TEST InvalidBlockScalarIndentationIndicators()
        {
            return "  not written yet";
        }

		// 8.4
		TEST ChompingFinalLineBreak()
        {
            return "  not written yet";
        }

		// 8.5
		TEST ChompingTrailingLines()
        {
            return "  not written yet";
        }

		// 8.6
		TEST EmptyScalarChomping()
        {
            return "  not written yet";
        }

		// 8.7
		TEST LiteralScalar()
        {
            return "  not written yet";
        }

		// 8.8
		TEST LiteralContent()
        {
            return "  not written yet";
        }

		// 8.9
		TEST FoldedScalar()
        {
            return "  not written yet";
        }

		// 8.10
		TEST FoldedLines()
        {
            return "  not written yet";
        }

		// 8.11
		TEST MoreIndentedLines()
        {
            return "  not written yet";
        }

		// 8.12
		TEST EmptySeparationLines()
        {
            return "  not written yet";
        }

		// 8.13
		TEST FinalEmptyLines()
        {
            return "  not written yet";
        }

		// 8.14
		TEST BlockSequence()
        {
            return "  not written yet";
        }

		// 8.15
		TEST BlockSequenceEntryTypes()
        {
            return "  not written yet";
        }

		// 8.16
		TEST BlockMappings()
        {
            return "  not written yet";
        }

		// 8.17
		TEST ExplicitBlockMappingEntries()
        {
            return "  not written yet";
        }

		// 8.18
		TEST ImplicitBlockMappingEntries()
        {
            return "  not written yet";
        }

		// 8.19
		TEST CompactBlockMappings()
        {
            return "  not written yet";
        }

		// 8.20
		TEST BlockNodeTypes()
        {
            return "  not written yet";
        }

		// 8.21
		TEST BlockScalarNodes()
        {
            return "  not written yet";
        }

		// 8.22
		TEST BlockCollectionNodes()
        {
            return "  not written yet";
        }
	}
}
<commit_msg>Added framework for spectests with event handling<commit_after>#include "spectests.h"
#include "specexamples.h"
#include "yaml-cpp/yaml.h"
#include "yaml-cpp/eventhandler.h"
#include <cassert>

namespace Test {
    struct Event {
        enum Type { DocStart, DocEnd, Null, Alias, Scalar, SeqStart, SeqEnd, MapStart, MapEnd };

        typedef YAML::Mark Mark;
        typedef YAML::anchor_t anchor_t;

        Event(Type type_, const std::string& tag_, anchor_t anchor_, const std::string& scalar_): type(type_), tag(tag_), anchor(anchor_), scalar(scalar_) {}

        Type type;
        std::string tag;
        anchor_t anchor;
        std::string scalar;

        std::ostream& write(std::ostream& out) const {
            switch(type) {
                case DocStart:
                    return out << "DocStart";
                case DocEnd:
                    return out << "DocEnd";
                case Null:
                    return out << "Null(" << anchor << ")";
                case Alias:
                    return out << "Alias(" << anchor << ")";
                case Scalar:
                    return out << "Scalar(" << tag << ", " << anchor << ", " << scalar << ")";
                case SeqStart:
                    return out << "SeqStart(" << tag << ", " << anchor << ")";
                case SeqEnd:
                    return out << "SeqEnd";
                case MapStart:
                    return out << "MapStart(" << tag << ", " << anchor << ")";
                case MapEnd:
                    return out << "MapEnd";
            }
            assert(false);
            return out;
        }
    };

    std::ostream& operator << (std::ostream& out, const Event& event) {
        return event.write(out);
    }

    bool operator == (const Event& a, const Event& b) {
        return a.type == b.type && a.tag == b.tag && a.anchor == b.anchor && a.scalar == b.scalar;
    }

    bool operator != (const Event& a, const Event& b) {
        return !(a == b);
    }

	class MockEventHandler: public YAML::EventHandler
	{
	public:
        typedef YAML::Mark Mark;
        typedef YAML::anchor_t anchor_t;

        MockEventHandler() {}

		virtual void OnDocumentStart(const Mark&) {
            m_actualEvents.push_back(Event(Event::DocStart, "", 0, ""));
        }

		virtual void OnDocumentEnd() {
            m_actualEvents.push_back(Event(Event::DocEnd, "", 0, ""));
        }

		virtual void OnNull(const Mark&, anchor_t anchor) {
            m_actualEvents.push_back(Event(Event::Null, "", anchor, ""));
        }

		virtual void OnAlias(const Mark&, anchor_t anchor) {
            m_actualEvents.push_back(Event(Event::Alias, "", anchor, ""));
        }

		virtual void OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) {
            m_actualEvents.push_back(Event(Event::Scalar, tag, anchor, value));
        }

		virtual void OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) {
            m_actualEvents.push_back(Event(Event::SeqStart, tag, anchor, ""));
        }

		virtual void OnSequenceEnd() {
            m_actualEvents.push_back(Event(Event::SeqEnd, "", 0, ""));
        }

		virtual void OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) {
            m_actualEvents.push_back(Event(Event::MapStart, tag, anchor, ""));
        }

		virtual void OnMapEnd() {
            m_actualEvents.push_back(Event(Event::MapEnd, "", 0, ""));
        }

        void Expect(const Event& event) { m_expectedEvents.push_back(event); }

        Test::TEST Check() const {
            std::size_t N = std::max(m_expectedEvents.size(), m_actualEvents.size());
            for(std::size_t i=0;i<N;i++) {
                if(i >= m_expectedEvents.size()) {
                    std::stringstream out;
                    for(std::size_t j=0;j<i;j++) {
                        out << m_expectedEvents[j] << "\n";
                    }
                    out << "EXPECTED: (no event expected)\n";
                    out << "ACTUAL  : " << m_actualEvents[i] << "\n";
                    return out.str().c_str();
                }

                if(i >= m_actualEvents.size()) {
                    std::stringstream out;
                    for(std::size_t j=0;j<i;j++) {
                        out << m_expectedEvents[j] << "\n";
                    }
                    out << "EXPECTED: " << m_expectedEvents[i] << "\n";
                    out << "ACTUAL  : (no event recorded)\n";
                    return out.str().c_str();
                }

                if(m_expectedEvents[i] != m_actualEvents[i]) {
                    std::stringstream out;
                    for(std::size_t j=0;j<i;j++) {
                        out << m_expectedEvents[j] << "\n";
                    }
                    out << "EXPECTED: " << m_expectedEvents[i] << "\n";
                    out << "ACTUAL  : " << m_actualEvents[i] << "\n";
                    return out.str().c_str();
                }
            }

            return true;
        }

        std::vector<Event> m_expectedEvents;
        std::vector<Event> m_actualEvents;
	};

#define HANDLE(ex)\
    MockEventHandler handler;\
    std::stringstream stream(ex);\
    YAML::Parser parser(stream);\
    parser.HandleNextDocument(handler)

#define HANDLE_NEXT(ex)\
    parser.HandleNextDocument(handler)

#define EXPECT_DOC_START()\
    do {\
        handler.Expect(Event(Event::DocStart, "", 0, ""));\
    } while(false)

#define EXPECT_DOC_END()\
    do {\
        handler.Expect(Event(Event::DocEnd, "", 0, ""));\
    } while(false)

#define EXPECT_NULL(anchor)\
    do {\
        handler.Expect(Event(Event::Null, "", anchor, ""));\
    } while(false)

#define EXPECT_ALIAS(anchor)\
    do {\
        handler.Expect(Event(Event::Alias, "", anchor, ""));\
    } while(false)

#define EXPECT_SCALAR(tag, anchor, value)\
    do {\
        handler.Expect(Event(Event::Scalar, tag, anchor, value));\
    } while(false)

#define EXPECT_SEQ_START(tag, anchor)\
    do {\
        handler.Expect(Event(Event::SeqStart, tag, anchor, ""));\
    } while(false)

#define EXPECT_SEQ_END()\
    do {\
        handler.Expect(Event(Event::SeqEnd, "", 0, ""));\
    } while(false)

#define EXPECT_MAP_START(tag, anchor)\
    do {\
        handler.Expect(Event(Event::MapStart, tag, anchor, ""));\
    } while(false)

#define EXPECT_MAP_END()\
    do {\
        handler.Expect(Event(Event::MapEnd, "", 0, ""));\
    } while(false)

#define DONE()\
    do {\
        return handler.Check();\
    } while(false)

	namespace Spec {
		// 2.1
		TEST SeqScalars()
        {
            HANDLE(ex2_1);
            EXPECT_DOC_START();
            EXPECT_SEQ_START("?", 0);
            EXPECT_SCALAR("?", 0, "Mark McGwire");
            EXPECT_SCALAR("?", 0, "Sammy Sosa");
            EXPECT_SCALAR("?", 0, "Ken Griffey");
            EXPECT_SEQ_END();
            EXPECT_DOC_END();
            DONE();
        }

		// 2.2
		TEST MappingScalarsToScalars()
        {
            return "  not written yet";
        }

		// 2.3
		TEST MappingScalarsToSequences()
        {
            return "  not written yet";
        }

		// 2.4
		TEST SequenceOfMappings()
        {
            return "  not written yet";
        }

		// 2.5
		TEST SequenceOfSequences()
        {
            return "  not written yet";
        }

		// 2.6
		TEST MappingOfMappings()
        {
            return "  not written yet";
        }

		// 2.7
		TEST TwoDocumentsInAStream()
        {
            return "  not written yet";
        }

		// 2.8
		TEST PlayByPlayFeed()
        {
            return "  not written yet";
        }

		// 2.9
		TEST SingleDocumentWithTwoComments()
        {
            return "  not written yet";
        }

		// 2.10
		TEST SimpleAnchor()
        {
            return "  not written yet";
        }

		// 2.11
		TEST MappingBetweenSequences()
        {
            return "  not written yet";
        }

		// 2.12
		TEST CompactNestedMapping()
        {
            return "  not written yet";
        }

		// 2.13
		TEST InLiteralsNewlinesArePreserved()
        {
            return "  not written yet";
        }

		// 2.14
		TEST InFoldedScalarsNewlinesBecomeSpaces()
        {
            return "  not written yet";
        }

		// 2.15
		TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
        {
            return "  not written yet";
        }

		// 2.16
		TEST IndentationDeterminesScope()
        {
            return "  not written yet";
        }

		// 2.17
		TEST QuotedScalars()
        {
            return "  not written yet";
        }

		// 2.18
		TEST MultiLineFlowScalars()
        {
            return "  not written yet";
        }

		// TODO: 2.19 - 2.22 schema tags

		// 2.23
		TEST VariousExplicitTags()
        {
            return "  not written yet";
        }

		// 2.24
		TEST GlobalTags()
        {
            return "  not written yet";
        }

		// 2.25
		TEST UnorderedSets()
        {
            return "  not written yet";
        }

		// 2.26
		TEST OrderedMappings()
        {
            return "  not written yet";
        }

		// 2.27
		TEST Invoice()
        {
            return "  not written yet";
        }

		// 2.28
		TEST LogFile()
        {
            return "  not written yet";
        }

		// TODO: 5.1 - 5.2 BOM

		// 5.3
		TEST BlockStructureIndicators()
        {
            return "  not written yet";
        }

		// 5.4
		TEST FlowStructureIndicators()
        {
            return "  not written yet";
        }

		// 5.5
		TEST CommentIndicator()
        {
            return "  not written yet";
        }

		// 5.6
		TEST NodePropertyIndicators()
        {
            return "  not written yet";
        }

		// 5.7
		TEST BlockScalarIndicators()
        {
            return "  not written yet";
        }

		// 5.8
		TEST QuotedScalarIndicators()
        {
            return "  not written yet";
        }

		// TODO: 5.9 directive
		// TODO: 5.10 reserved indicator

		// 5.11
		TEST LineBreakCharacters()
        {
            return "  not written yet";
        }

		// 5.12
		TEST TabsAndSpaces()
        {
            return "  not written yet";
        }

		// 5.13
		TEST EscapedCharacters()
        {
            return "  not written yet";
        }

		// 5.14
		TEST InvalidEscapedCharacters()
        {
            return "  not written yet";
        }

		// 6.1
		TEST IndentationSpaces()
        {
            return "  not written yet";
        }

		// 6.2
		TEST IndentationIndicators()
        {
            return "  not written yet";
        }

		// 6.3
		TEST SeparationSpaces()
        {
            return "  not written yet";
        }

		// 6.4
		TEST LinePrefixes()
        {
            return "  not written yet";
        }

		// 6.5
		TEST EmptyLines()
        {
            return "  not written yet";
        }

		// 6.6
		TEST LineFolding()
        {
            return "  not written yet";
        }

		// 6.7
		TEST BlockFolding()
        {
            return "  not written yet";
        }

		// 6.8
		TEST FlowFolding()
        {
            return "  not written yet";
        }

		// 6.9
		TEST SeparatedComment()
        {
            return "  not written yet";
        }

		// 6.10
		TEST CommentLines()
        {
            return "  not written yet";
        }

		// 6.11
		TEST MultiLineComments()
        {
            return "  not written yet";
        }

		// 6.12
		TEST SeparationSpacesII()
        {
            return "  not written yet";
        }

		// 6.13
		TEST ReservedDirectives()
        {
            return "  not written yet";
        }

		// 6.14
		TEST YAMLDirective()
        {
            return "  not written yet";
        }

		// 6.15
		TEST InvalidRepeatedYAMLDirective()
        {
            return "  not written yet";
        }

		// 6.16
		TEST TagDirective()
        {
            return "  not written yet";
        }

		// 6.17
		TEST InvalidRepeatedTagDirective()
        {
            return "  not written yet";
        }

		// 6.18
		TEST PrimaryTagHandle()
        {
            return "  not written yet";
        }

		// 6.19
		TEST SecondaryTagHandle()
        {
            return "  not written yet";
        }

		// 6.20
		TEST TagHandles()
        {
            return "  not written yet";
        }

		// 6.21
		TEST LocalTagPrefix()
        {
            return "  not written yet";
        }

		// 6.22
		TEST GlobalTagPrefix()
        {
            return "  not written yet";
        }

		// 6.23
		TEST NodeProperties()
        {
            return "  not written yet";
        }

		// 6.24
		TEST VerbatimTags()
        {
            return "  not written yet";
        }

		// 6.25
		TEST InvalidVerbatimTags()
        {
            return "  not written yet";
        }

		// 6.26
		TEST TagShorthands()
        {
            return "  not written yet";
        }

		// 6.27
		TEST InvalidTagShorthands()
        {
            return "  not written yet";
        }

		// 6.28
		TEST NonSpecificTags()
        {
            return "  not written yet";
        }

		// 6.29
		TEST NodeAnchors()
        {
            return "  not written yet";
        }

		// 7.1
		TEST AliasNodes()
        {
            return "  not written yet";
        }

		// 7.2
		TEST EmptyNodes()
        {
            return "  not written yet";
        }

		// 7.3
		TEST CompletelyEmptyNodes()
        {
            return "  not written yet";
        }

		// 7.4
		TEST DoubleQuotedImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.5
		TEST DoubleQuotedLineBreaks()
        {
            return "  not written yet";
        }

		// 7.6
		TEST DoubleQuotedLines()
        {
            return "  not written yet";
        }

		// 7.7
		TEST SingleQuotedCharacters()
        {
            return "  not written yet";
        }

		// 7.8
		TEST SingleQuotedImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.9
		TEST SingleQuotedLines()
        {
            return "  not written yet";
        }

		// 7.10
		TEST PlainCharacters()
        {
            return "  not written yet";
        }

		// 7.11
		TEST PlainImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.12
		TEST PlainLines()
        {
            return "  not written yet";
        }

		// 7.13
		TEST FlowSequence()
        {
            return "  not written yet";
        }

		// 7.14
		TEST FlowSequenceEntries()
        {
            return "  not written yet";
        }

		// 7.15
		TEST FlowMappings()
        {
            return "  not written yet";
        }

		// 7.16
		TEST FlowMappingEntries()
        {
            return "  not written yet";
        }

		// 7.17
		TEST FlowMappingSeparateValues()
        {
            return "  not written yet";
        }

		// 7.18
		TEST FlowMappingAdjacentValues()
        {
            return "  not written yet";
        }

		// 7.19
		TEST SinglePairFlowMappings()
        {
            return "  not written yet";
        }

		// 7.20
		TEST SinglePairExplicitEntry()
        {
            return "  not written yet";
        }

		// 7.21
		TEST SinglePairImplicitEntries()
        {
            return "  not written yet";
        }

		// 7.22
		TEST InvalidImplicitKeys()
        {
            return "  not written yet";
        }

		// 7.23
		TEST FlowContent()
        {
            return "  not written yet";
        }

		// 7.24
		TEST FlowNodes()
        {
            return "  not written yet";
        }

		// 8.1
		TEST BlockScalarHeader()
        {
            return "  not written yet";
        }

		// 8.2
		TEST BlockIndentationHeader()
        {
            return "  not written yet";
        }

		// 8.3
		TEST InvalidBlockScalarIndentationIndicators()
        {
            return "  not written yet";
        }

		// 8.4
		TEST ChompingFinalLineBreak()
        {
            return "  not written yet";
        }

		// 8.5
		TEST ChompingTrailingLines()
        {
            return "  not written yet";
        }

		// 8.6
		TEST EmptyScalarChomping()
        {
            return "  not written yet";
        }

		// 8.7
		TEST LiteralScalar()
        {
            return "  not written yet";
        }

		// 8.8
		TEST LiteralContent()
        {
            return "  not written yet";
        }

		// 8.9
		TEST FoldedScalar()
        {
            return "  not written yet";
        }

		// 8.10
		TEST FoldedLines()
        {
            return "  not written yet";
        }

		// 8.11
		TEST MoreIndentedLines()
        {
            return "  not written yet";
        }

		// 8.12
		TEST EmptySeparationLines()
        {
            return "  not written yet";
        }

		// 8.13
		TEST FinalEmptyLines()
        {
            return "  not written yet";
        }

		// 8.14
		TEST BlockSequence()
        {
            return "  not written yet";
        }

		// 8.15
		TEST BlockSequenceEntryTypes()
        {
            return "  not written yet";
        }

		// 8.16
		TEST BlockMappings()
        {
            return "  not written yet";
        }

		// 8.17
		TEST ExplicitBlockMappingEntries()
        {
            return "  not written yet";
        }

		// 8.18
		TEST ImplicitBlockMappingEntries()
        {
            return "  not written yet";
        }

		// 8.19
		TEST CompactBlockMappings()
        {
            return "  not written yet";
        }

		// 8.20
		TEST BlockNodeTypes()
        {
            return "  not written yet";
        }

		// 8.21
		TEST BlockScalarNodes()
        {
            return "  not written yet";
        }

		// 8.22
		TEST BlockCollectionNodes()
        {
            return "  not written yet";
        }
	}
}
<|endoftext|>


<commit_before>#include "FImage.h"

using namespace FImage;

int main(int argc, char **argv) {
    Var x, y;
    Var xo, xi, yo, yi;

    Func f, g;

    printf("Defining function...\n");

    f(x, y) = 2.0f;
    g(x, y) = f(x+1, y) + f(x-1, y);

    g.tile(x, y, xo, yo, xi, yi, 8, 8);
    f.chunk(xo);

    if (use_gpu()) {
        g.cuda(xo, yo, xi, yi);
        // Tell f to directly use the thread ids for x and y
        f.rename(x, Var("threadidx")).rename(y, Var("threadidy"));
    }

    printf("Realizing function...\n");

    Image<float> im = g.realize(32, 32);

    for (size_t i = 0; i < 32; i++) {
        for (size_t j = 0; j < 32; j++) {
            if (im(i,j) != 4.0) {
                printf("im[%d, %d] = %f\n", (int)i, (int)j, im(i,j));
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Fix chunk test on GPU<commit_after>#include "FImage.h"

using namespace FImage;

int main(int argc, char **argv) {
    Var x, y;
    Var xo, xi, yo, yi;

    Func f, g;

    printf("Defining function...\n");

    f(x, y) = 2.0f;
    g(x, y) = f(x+1, y) + f(x-1, y);

    if (use_gpu()) {
        g.cudaTile(x, y, 8, 8);
        f.chunk(Var("blockidx"));
        // Tell f to directly use the thread ids for x and y
        f.parallel(x).parallel(y).rename(x, Var("threadidx")).rename(y, Var("threadidy"));
    } else {
        g.tile(x, y, xo, yo, xi, yi, 8, 8);
        f.chunk(xo);
    }

    printf("Realizing function...\n");

    Image<float> im = g.realize(32, 32);

    for (size_t i = 0; i < 32; i++) {
        for (size_t j = 0; j < 32; j++) {
            if (im(i,j) != 4.0) {
                printf("im[%d, %d] = %f\n", (int)i, (int)j, im(i,j));
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>#include "Vector.h"
#include <iostream>
#include "gtest/gtest.h"

float add1[] = {0,1,2};
float add2[] = {3,4,5};
float sub3[] = {0,-1,-2};
float bad1[] = {0,1};
float bad2[] = {1,2};

Vector vec1  = Vector(3, add1);
Vector vec2  = Vector(3, add2);
Vector vec3  = Vector(3, sub3);
Vector vec4  = Vector(2, bad1);
Vector vec5  = Vector(2, bad2);

// test if two arrays are equal. This doesn't account for
// different sizes in the aray.
bool arraysEqual(int size, float* arr1, float* arr2)
{
    bool equal = true;

    for(int i = 0; i < size; ++i)
    {
        if(*(arr1 + i) != *(arr2 + i))
        {
            equal = false;
            break;
        }
    }

    return equal;
}

/// -------------------- useful commands --------------------
// testing GetSize
TEST(cpp_vector_test, vector_get_size)
{
    EXPECT_EQ(3, vec1.GetSize());
    EXPECT_EQ(2, vec4.GetSize());
}

// testing GetVectorArray
TEST(cpp_vector_test, vector_get_array)
{
    EXPECT_EQ(true, arraysEqual(3, vec1.GetVectorArray(), add1));
    EXPECT_EQ(true, arraysEqual(2, vec4.GetVectorArray(), bad1));
}

// testing GetString
TEST(cpp_vector_test, vector_to_string)
{
    std::string vec1_str = "0.000000, 1.000000, 2.000000";
    std::string vec2_str = "0.000000, 1.000000";

    EXPECT_EQ(0, vec1.ToString().compare(vec1_str));
    EXPECT_EQ(0, vec4.ToString().compare(vec2_str));
}

/// -------------------- Scalar Calculations --------------------
// test AddScalar
TEST(cpp_vector_test, vector_add_scalar)
{
    float expected1[] = {3.0,4.0,5.0};
    float expected2[] = {3.0,4.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.AddScalar(3);
    test2.AddScalar(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test SubtractScalar
TEST(cpp_vector_test, vector_sub_scalar)
{
    float expected1[] = {-3.0,-2.0,-1.0};
    float expected2[] = {-3.0,-2.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.SubtractScalar(3);
    test2.SubtractScalar(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test MultiplyScaler
TEST(cpp_vector_test, vector_multiply_scalar)
{
    float expected1[] = {0.0,3.0,6.0};
    float expected2[] = {0.0,3.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.MultiplyScaler(3);
    test2.MultiplyScaler(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test DivideScaler
TEST(cpp_vector_test, vector_divide_scalar)
{
    float expected2[] = {0.0,0.5};

    Vector test2 = Vector(&vec4);

    test2.DivideScaler(2);

    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
    EXPECT_THROW(test2.DivideScaler(0), std::overflow_error);
}

// test ModulusScalar
TEST(cpp_vector_test, vector_mudulus_scalar)
{
    float expected1[] = {0.0,1.0,0.0};
    float expected2[] = {0.0,1.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.ModulusScalar(2);
    test2.ModulusScalar(2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
    EXPECT_THROW(test2.ModulusScalar(0), std::overflow_error);
}

// test RaisePowerScalar
TEST(cpp_vector_test, vector_raise_power_scalar)
{
    float expected1[] = {0.0,1.0,4.0};
    float expected2[] = {0.0,1.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.RaisePowerScalar(2);
    test2.RaisePowerScalar(2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

/// -------------------- Vector Calculations --------------------
// test Add
TEST(cpp_vector_test, vector_add)
{
    float expected1[] = {3.0,5.0,7.0};
    float expected2[] = {1.0,3.0};

    Vector test1 = Vector(3);
    Vector test2 = Vector(2);

    vec1.Add(&vec2, &test1);
    vec4.Add(&vec5, &test2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test Subtract
TEST(cpp_vector_test, vector_subtract)
{
    float expected1[] = {-3.0,-3.0,-3.0};
    float expected2[] = {-1.0,-1.0};

    Vector test1 = Vector(3);
    Vector test2 = Vector(2);

    vec1.Subtract(&vec2, &test1);
    vec4.Subtract(&vec5, &test2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test Dot
TEST(cpp_vector_test, vector_dot)
{
    EXPECT_EQ(14, vec1.Dot(&vec2));
    EXPECT_EQ(2,  vec4.Dot(&vec5));
    EXPECT_THROW(vec1.Dot(&vec4), std::overflow_error);
}

// test: vec1 + vec2 operation
TEST(cpp_vector_test, vector_operator_add)
{
    float expected1[] = {3,5,7};
    float expected2[] = {0,0,0};
    float expected3[] = {1,3};

    Vector exp1 = Vector(3, expected1);
    Vector exp2 = Vector(3, expected2);
    Vector exp3 = Vector(2, expected3);

    // test basic addition
    Vector result1 = vec1 + vec2;
    bool additionResult = result1 == exp1;
    EXPECT_EQ(true, additionResult);

    // test basic addition with subtraction
    result1 = vec1 + vec3;
    additionResult = result1 == exp2;
    EXPECT_EQ(true, additionResult);

    // test different size
    result1 = vec4 + vec5;
    additionResult = result1 == exp3;
    EXPECT_EQ(true, additionResult);

    // test mismatching sizes
    EXPECT_THROW(vec4 + vec1, std::overflow_error);
}

// test: vec1 - vec2 operation
TEST(cpp_vector_test, vector_operator_sub)
{
    float expected1[] = {-3,-3,-3};
    float expected2[] = {0,2,4};
    float expected3[] = {-1,-1};

    Vector exp1 = Vector(3, expected1);
    Vector exp2 = Vector(3, expected2);
    Vector exp3 = Vector(2, expected3);

    // test basic addition
    Vector result1 = vec1 - vec2;
    bool additionResult = result1 == exp1;
    EXPECT_EQ(true, additionResult);

    // test basic addition with subtraction
    result1 = vec1 - vec3;
    additionResult = result1 == exp2;
    EXPECT_EQ(true, additionResult);

    // test different size
    result1 = vec4 - vec5;
    additionResult = result1 == exp3;
    EXPECT_EQ(true, additionResult);

    // test mismatching sizes
    EXPECT_THROW(vec4 - vec1, std::overflow_error);
}

int main(int argc, const char * argv[])
{
    testing::InitGoogleTest(&argc, (char**)argv);
    return RUN_ALL_TESTS();
}<commit_msg>updated unit tests - testing unit testing function - improved coverage of function GetVectorArray<commit_after>#include "Vector.h"
#include <iostream>
#include "gtest/gtest.h"

float add1[] = {0,1,2};
float add2[] = {3,4,5};
float sub3[] = {0,-1,-2};
float bad1[] = {0,1};
float bad2[] = {1,2};

Vector vec1  = Vector(3, add1);
Vector vec2  = Vector(3, add2);
Vector vec3  = Vector(3, sub3);
Vector vec4  = Vector(2, bad1);
Vector vec5  = Vector(2, bad2);

// test if two arrays are equal. This doesn't account for
// different sizes in the aray.
bool arraysEqual(int size, float* arr1, float* arr2)
{
    bool equal = true;

    for(int i = 0; i < size; ++i)
    {
        if(*(arr1 + i) != *(arr2 + i))
        {
            equal = false;
            break;
        }
    }

    return equal;
}

TEST(cpp_google_test_functions, arrays_equal)
{
    float test1[] = {2,3,4,5};
    float test2[] = {2,3,4,5};
    float test3[] = {1,2,3,4};

    EXPECT_EQ(true, arraysEqual(3, test1, test2));
    EXPECT_EQ(false, arraysEqual(3, test1, test3));
}

/// -------------------- useful commands --------------------
// testing GetSize
TEST(cpp_vector_test, vector_get_size)
{
    EXPECT_EQ(3, vec1.GetSize());
    EXPECT_EQ(2, vec4.GetSize());
}

// testing GetVectorArray
TEST(cpp_vector_test, vector_get_array)
{
    EXPECT_EQ(true, arraysEqual(3, vec1.GetVectorArray(), add1));
    EXPECT_EQ(false, arraysEqual(3, vec1.GetVectorArray(), add2));
    EXPECT_EQ(true, arraysEqual(2, vec4.GetVectorArray(), bad1));
}

// testing GetString
TEST(cpp_vector_test, vector_to_string)
{
    std::string vec1_str = "0.000000, 1.000000, 2.000000";
    std::string vec2_str = "0.000000, 1.000000";

    EXPECT_EQ(0, vec1.ToString().compare(vec1_str));
    EXPECT_EQ(0, vec4.ToString().compare(vec2_str));
}

/// -------------------- Scalar Calculations --------------------
// test AddScalar
TEST(cpp_vector_test, vector_add_scalar)
{
    float expected1[] = {3.0,4.0,5.0};
    float expected2[] = {3.0,4.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.AddScalar(3);
    test2.AddScalar(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test SubtractScalar
TEST(cpp_vector_test, vector_sub_scalar)
{
    float expected1[] = {-3.0,-2.0,-1.0};
    float expected2[] = {-3.0,-2.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.SubtractScalar(3);
    test2.SubtractScalar(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test MultiplyScaler
TEST(cpp_vector_test, vector_multiply_scalar)
{
    float expected1[] = {0.0,3.0,6.0};
    float expected2[] = {0.0,3.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.MultiplyScaler(3);
    test2.MultiplyScaler(3);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test DivideScaler
TEST(cpp_vector_test, vector_divide_scalar)
{
    float expected2[] = {0.0,0.5};

    Vector test2 = Vector(&vec4);

    test2.DivideScaler(2);

    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
    EXPECT_THROW(test2.DivideScaler(0), std::overflow_error);
}

// test ModulusScalar
TEST(cpp_vector_test, vector_mudulus_scalar)
{
    float expected1[] = {0.0,1.0,0.0};
    float expected2[] = {0.0,1.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.ModulusScalar(2);
    test2.ModulusScalar(2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
    EXPECT_THROW(test2.ModulusScalar(0), std::overflow_error);
}

// test RaisePowerScalar
TEST(cpp_vector_test, vector_raise_power_scalar)
{
    float expected1[] = {0.0,1.0,4.0};
    float expected2[] = {0.0,1.0};

    Vector test1 = Vector(&vec1);
    Vector test2 = Vector(&vec4);

    test1.RaisePowerScalar(2);
    test2.RaisePowerScalar(2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

/// -------------------- Vector Calculations --------------------
// test Add
TEST(cpp_vector_test, vector_add)
{
    float expected1[] = {3.0,5.0,7.0};
    float expected2[] = {1.0,3.0};

    Vector test1 = Vector(3);
    Vector test2 = Vector(2);

    vec1.Add(&vec2, &test1);
    vec4.Add(&vec5, &test2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test Subtract
TEST(cpp_vector_test, vector_subtract)
{
    float expected1[] = {-3.0,-3.0,-3.0};
    float expected2[] = {-1.0,-1.0};

    Vector test1 = Vector(3);
    Vector test2 = Vector(2);

    vec1.Subtract(&vec2, &test1);
    vec4.Subtract(&vec5, &test2);

    EXPECT_EQ(true, arraysEqual(3, test1.GetVectorArray(), expected1));
    EXPECT_EQ(true, arraysEqual(2, test2.GetVectorArray(), expected2));
}

// test Dot
TEST(cpp_vector_test, vector_dot)
{
    EXPECT_EQ(14, vec1.Dot(&vec2));
    EXPECT_EQ(2,  vec4.Dot(&vec5));
    EXPECT_THROW(vec1.Dot(&vec4), std::overflow_error);
}

// test: vec1 + vec2 operation
TEST(cpp_vector_test, vector_operator_add)
{
    float expected1[] = {3,5,7};
    float expected2[] = {0,0,0};
    float expected3[] = {1,3};

    Vector exp1 = Vector(3, expected1);
    Vector exp2 = Vector(3, expected2);
    Vector exp3 = Vector(2, expected3);

    // test basic addition
    Vector result1 = vec1 + vec2;
    bool additionResult = result1 == exp1;
    EXPECT_EQ(true, additionResult);

    // test basic addition with subtraction
    result1 = vec1 + vec3;
    additionResult = result1 == exp2;
    EXPECT_EQ(true, additionResult);

    // test different size
    result1 = vec4 + vec5;
    additionResult = result1 == exp3;
    EXPECT_EQ(true, additionResult);

    // test mismatching sizes
    EXPECT_THROW(vec4 + vec1, std::overflow_error);
}

// test: vec1 - vec2 operation
TEST(cpp_vector_test, vector_operator_sub)
{
    float expected1[] = {-3,-3,-3};
    float expected2[] = {0,2,4};
    float expected3[] = {-1,-1};

    Vector exp1 = Vector(3, expected1);
    Vector exp2 = Vector(3, expected2);
    Vector exp3 = Vector(2, expected3);

    // test basic addition
    Vector result1 = vec1 - vec2;
    bool additionResult = result1 == exp1;
    EXPECT_EQ(true, additionResult);

    // test basic addition with subtraction
    result1 = vec1 - vec3;
    additionResult = result1 == exp2;
    EXPECT_EQ(true, additionResult);

    // test different size
    result1 = vec4 - vec5;
    additionResult = result1 == exp3;
    EXPECT_EQ(true, additionResult);

    // test mismatching sizes
    EXPECT_THROW(vec4 - vec1, std::overflow_error);
}

int main(int argc, const char * argv[])
{
    testing::InitGoogleTest(&argc, (char**)argv);
    return RUN_ALL_TESTS();
}<|endoftext|>


<commit_before>#ifndef NNXX_MESSAGE_SREAMBUF_HPP
#define NNXX_MESSAGE_SREAMBUF_HPP

#include <algorithm>

namespace nnxx {

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(size_type base_size) noexcept:
    base_type(),
    m_base_size(base_size),
    m_msg()
  { }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(size_type size, int type):
    base_type(),
    m_base_size(size),
    m_msg(size * sizeof(char_type), type)
  { clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(message &&msg) noexcept:
    base_type(),
    m_base_size(msg.empty() ? 1000 : msg.size()),
    m_msg(std::move(msg))
  { clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  ~basic_message_streambuf()
  { }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::clear() noexcept
  {
    const auto b = reinterpret_cast<char_type *>(m_msg.data());
    const auto e = reinterpret_cast<char_type *>(m_msg.data()) + m_msg.size();
    this->setg(b, b, e);
    this->setp(b, e);
  }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::msg(message &&m) noexcept
  {
    m_msg = std::move(m);
    clear();
  }

  template < typename Char, typename Traits >
  message basic_message_streambuf<Char, Traits>::msg(int type)
  { return copy(m_msg, this->pptr() - this->pbase(), type); }

  template < typename Char, typename Traits >
  message basic_message_streambuf<Char, Traits>::move_msg()
  {
    message m;
    m_msg.resize(this->pptr() - this->pbase());
    m_msg.swap(m);
    clear();
    return m;
  }

  template < typename Char, typename Traits >
  typename
  basic_message_streambuf<Char, Traits>::streamsize
  basic_message_streambuf<Char, Traits>::xsputn(const char_type *s, streamsize n)
  {
    using std::copy;

    if (n > static_cast<streamsize>(this->epptr() - this->pptr())) {
      overflow(traits_type::eof());
    }

    copy(s, s + n, this->pptr());
    this->pbump(n);
    return n;
  }

  template < typename Char, typename Traits >
  typename
  basic_message_streambuf<Char, Traits>::int_type
  basic_message_streambuf<Char, Traits>::overflow(int_type c)
  {
    const auto n = m_msg.size();

    if (!m_msg) {
      m_msg = message{ m_base_size * sizeof(char_type) };
    }
    else {
      m_msg.resize(2 * m_msg.size());
    }

    const auto b = reinterpret_cast<char_type *>(m_msg.data());
    const auto e = reinterpret_cast<char_type *>(m_msg.data()) + m_msg.size();
    this->setp(b, e);
    this->pbump(n);

    if (!traits_type::eq_int_type(c, traits_type::eof())) {
      *(this->pptr()) = char_type(c);
      this->pbump(1);
    }

    return ~traits_type::eof();
  }

#if NNXX_LIBCPP
  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(basic_message_streambuf &&m) noexcept:
    base_type(std::move(m)),
    m_base_size(m.m_base_size),
    m_msg(std::move(m.m_msg))
  { m.clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits> &
  basic_message_streambuf<Char, Traits>::
  operator=(basic_message_streambuf &&m) noexcept
  {
    m.swap(*this);
    return *this;
  }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::
  swap(basic_message_streambuf &m) noexcept
  {
    using std::swap;
    base_type::swap(m);
    swap(m_base_size, m.m_base_size);
    swap(m_msg, m.m_msg);
  }
#endif // NNXX_LIBCPP

}

#endif // NNXX_MESSAGE_SREAMBUF_H
<commit_msg>Resizing the output messages to the right size.<commit_after>#ifndef NNXX_MESSAGE_SREAMBUF_HPP
#define NNXX_MESSAGE_SREAMBUF_HPP

#include <algorithm>

namespace nnxx {

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(size_type base_size) noexcept:
    base_type(),
    m_base_size(base_size),
    m_msg()
  { }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(size_type size, int type):
    base_type(),
    m_base_size(size),
    m_msg(size * sizeof(char_type), type)
  { clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(message &&msg) noexcept:
    base_type(),
    m_base_size(msg.empty() ? 1000 : msg.size()),
    m_msg(std::move(msg))
  { clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  ~basic_message_streambuf()
  { }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::clear() noexcept
  {
    const auto b = reinterpret_cast<char_type *>(m_msg.data());
    const auto e = reinterpret_cast<char_type *>(m_msg.data()) + m_msg.size();
    this->setg(b, b, e);
    this->setp(b, e);
  }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::msg(message &&m) noexcept
  {
    m_msg = std::move(m);
    clear();
  }

  template < typename Char, typename Traits >
  message basic_message_streambuf<Char, Traits>::msg(int type)
  { message m(this->pptr() - this->pbase(), type);
    m_msg.resize(this->pptr() - this->pbase());
    m_msg.swap(m);
    clear();
    return m;}

  template < typename Char, typename Traits >
  message basic_message_streambuf<Char, Traits>::move_msg()
  {
    message m;
    m_msg.resize(this->pptr() - this->pbase());
    m_msg.swap(m);
    clear();
    return m;
  }

  template < typename Char, typename Traits >
  typename
  basic_message_streambuf<Char, Traits>::streamsize
  basic_message_streambuf<Char, Traits>::xsputn(const char_type *s, streamsize n)
  {
    using std::copy;

    if (n > static_cast<streamsize>(this->epptr() - this->pptr())) {
      overflow(traits_type::eof());
    }

    copy(s, s + n, this->pptr());
    this->pbump(n);
    return n;
  }

  template < typename Char, typename Traits >
  typename
  basic_message_streambuf<Char, Traits>::int_type
  basic_message_streambuf<Char, Traits>::overflow(int_type c)
  {
    const auto n = m_msg.size();

    if (!m_msg) {
      m_msg = message{ m_base_size * sizeof(char_type) };
    }
    else {
      m_msg.resize(2 * m_msg.size());
    }

    const auto b = reinterpret_cast<char_type *>(m_msg.data());
    const auto e = reinterpret_cast<char_type *>(m_msg.data()) + m_msg.size();
    this->setp(b, e);
    this->pbump(n);

    if (!traits_type::eq_int_type(c, traits_type::eof())) {
      *(this->pptr()) = char_type(c);
      this->pbump(1);
    }

    return ~traits_type::eof();
  }

#if NNXX_LIBCPP
  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits>::
  basic_message_streambuf(basic_message_streambuf &&m) noexcept:
    base_type(std::move(m)),
    m_base_size(m.m_base_size),
    m_msg(std::move(m.m_msg))
  { m.clear(); }

  template < typename Char, typename Traits >
  basic_message_streambuf<Char, Traits> &
  basic_message_streambuf<Char, Traits>::
  operator=(basic_message_streambuf &&m) noexcept
  {
    m.swap(*this);
    return *this;
  }

  template < typename Char, typename Traits >
  void basic_message_streambuf<Char, Traits>::
  swap(basic_message_streambuf &m) noexcept
  {
    using std::swap;
    base_type::swap(m);
    swap(m_base_size, m.m_base_size);
    swap(m_msg, m.m_msg);
  }
#endif // NNXX_LIBCPP

}

#endif // NNXX_MESSAGE_SREAMBUF_H
<|endoftext|>