<commit_before>// Copyright (c) 2006-2008 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 <string>

#include "base/basictypes.h"
#include "base/clipboard.h"
#include "base/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  class ClipboardTest : public testing::Test {
  };
}

TEST(ClipboardTest, ClearTest) {
  Clipboard clipboard;

  clipboard.Clear();
  EXPECT_EQ(false, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  EXPECT_EQ(false, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
}

TEST(ClipboardTest, TextTest) {
  Clipboard clipboard;

  std::wstring text(L"This is a wstring!#$"), text_result;
  std::string ascii_text;

  clipboard.Clear();
  clipboard.WriteText(text);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextWFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  clipboard.ReadText(&text_result);
  EXPECT_EQ(text, text_result);
  clipboard.ReadAsciiText(&ascii_text);
  EXPECT_EQ(WideToUTF8(text), ascii_text);
}

TEST(ClipboardTest, HTMLTest) {
  Clipboard clipboard;

  std::wstring markup(L"Hi!</string>"), markup_result;
  std::string url("http://www.example.com/"), url_result;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);
#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
}

TEST(ClipboardTest, TrickyHTMLTest) {
  Clipboard clipboard;

  std::wstring markup(L"Bye!"), markup_result;
  std::string url, url_result;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);

#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
}

TEST(ClipboardTest, BookmarkTest) {
  Clipboard clipboard;

  std::wstring title(L"The Example Company"), title_result;
  std::string url("http://www.example.com/"), url_result;

  clipboard.Clear();
  clipboard.WriteBookmark(title, url);
  EXPECT_EQ(true,
      clipboard.IsFormatAvailable(Clipboard::GetUrlWFormatType()));
  clipboard.ReadBookmark(&title_result, &url_result);
  EXPECT_EQ(title, title_result);
  EXPECT_EQ(url, url_result);
}

TEST(ClipboardTest, MultiFormatTest) {
  Clipboard clipboard;

  std::wstring text(L"Hi!"), text_result;
  std::wstring markup(L"Hi!</string>"), markup_result;
  std::string url("http://www.example.com/"), url_result;
  std::string ascii_text;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  clipboard.WriteText(text);
  EXPECT_EQ(true,
      clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextWFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);
#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
  clipboard.ReadText(&text_result);
  EXPECT_EQ(text, text_result);
  clipboard.ReadAsciiText(&ascii_text);
  EXPECT_EQ(WideToUTF8(text), ascii_text);
}

// Files for this test don't actually need to exist on the file system, just
// don't try to use a non-existent file you've retrieved from the clipboard.
TEST(ClipboardTest, FileTest) {
  Clipboard clipboard;
  clipboard.Clear();
#if defined(OS_WIN)
  std::wstring file = L"C:\\Downloads\\My Downloads\\A Special File.txt";
#else
  // OS X will print a warning message if we stick a non-existant file on the
  // clipboard.
  std::wstring file = L"/usr/bin/make";
#endif
  clipboard.WriteFile(file);
  std::wstring out_file;
  clipboard.ReadFile(&out_file);
  EXPECT_EQ(file, out_file);
}

TEST(ClipboardTest, MultipleFilesTest) {
  Clipboard clipboard;
  clipboard.Clear();

#if defined(OS_WIN)
  std::wstring file1 = L"C:\\Downloads\\My Downloads\\File 1.exe";
  std::wstring file2 = L"C:\\Downloads\\My Downloads\\File 2.pdf";
  std::wstring file3 = L"C:\\Downloads\\My Downloads\\File 3.doc";
#elif defined(OS_MACOSX)
  // OS X will print a warning message if we stick a non-existant file on the
  // clipboard.
  std::wstring file1 = L"/usr/bin/make";
  std::wstring file2 = L"/usr/bin/man";
  std::wstring file3 = L"/usr/bin/perl";
#endif
  std::vector<std::wstring> files;
  files.push_back(file1);
  files.push_back(file2);
  files.push_back(file3);
  clipboard.WriteFiles(files);

  std::vector<std::wstring> out_files;
  clipboard.ReadFiles(&out_files);

  EXPECT_EQ(files.size(), out_files.size());
  for (size_t i = 0; i < out_files.size(); ++i)
    EXPECT_EQ(files[i], out_files[i]);
}

#if defined(OS_WIN)  // Windows only tests.
TEST(ClipboardTest, HyperlinkTest) {
  Clipboard clipboard;

  std::wstring title(L"The Example Company"), title_result;
  std::string url("http://www.example.com/"), url_result;
  std::wstring html(L""
                    L"The Example Company"), html_result;

  clipboard.Clear();
  clipboard.WriteHyperlink(title, url);
  EXPECT_EQ(true,
            clipboard.IsFormatAvailable(Clipboard::GetUrlWFormatType()));
  EXPECT_EQ(true,
            clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType()));
  clipboard.ReadBookmark(&title_result, &url_result);
  EXPECT_EQ(title, title_result);
  EXPECT_EQ(url, url_result);
  clipboard.ReadHTML(&html_result, &url_result);
  EXPECT_EQ(html, html_result);
  //XXX EXPECT_FALSE(url_result.is_valid());
}

TEST(ClipboardTest, WebSmartPasteTest) {
  Clipboard clipboard;

  clipboard.Clear();
  clipboard.WriteWebSmartPaste();
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetWebKitSmartPasteFormatType()));
}

TEST(ClipboardTest, BitmapTest) {
  unsigned int fake_bitmap[] = {
    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
  };

  Clipboard clipboard;

  clipboard.Clear();
  clipboard.WriteBitmap(fake_bitmap, gfx::Size(3, 4));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
                      Clipboard::GetBitmapFormatType()));
}
#endif
<commit_msg>Make ClipboardTest a PlatformTest to get autorelease pool management, needed on the Mac Review URL: http://codereview.chromium.org/6455<commit_after>// Copyright (c) 2006-2008 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 <string>

#include "base/basictypes.h"
#include "base/clipboard.h"
#include "base/platform_test.h"
#include "base/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"

typedef PlatformTest ClipboardTest;

TEST_F(ClipboardTest, ClearTest) {
  Clipboard clipboard;

  clipboard.Clear();
  EXPECT_EQ(false, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  EXPECT_EQ(false, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
}

TEST_F(ClipboardTest, TextTest) {
  Clipboard clipboard;

  std::wstring text(L"This is a wstring!#$"), text_result;
  std::string ascii_text;

  clipboard.Clear();
  clipboard.WriteText(text);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextWFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  clipboard.ReadText(&text_result);
  EXPECT_EQ(text, text_result);
  clipboard.ReadAsciiText(&ascii_text);
  EXPECT_EQ(WideToUTF8(text), ascii_text);
}

TEST_F(ClipboardTest, HTMLTest) {
  Clipboard clipboard;

  std::wstring markup(L"Hi!</string>"), markup_result;
  std::string url("http://www.example.com/"), url_result;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);
#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
}

TEST_F(ClipboardTest, TrickyHTMLTest) {
  Clipboard clipboard;

  std::wstring markup(L"Bye!"), markup_result;
  std::string url, url_result;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetHtmlFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);

#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
}

TEST_F(ClipboardTest, BookmarkTest) {
  Clipboard clipboard;

  std::wstring title(L"The Example Company"), title_result;
  std::string url("http://www.example.com/"), url_result;

  clipboard.Clear();
  clipboard.WriteBookmark(title, url);
  EXPECT_EQ(true,
      clipboard.IsFormatAvailable(Clipboard::GetUrlWFormatType()));
  clipboard.ReadBookmark(&title_result, &url_result);
  EXPECT_EQ(title, title_result);
  EXPECT_EQ(url, url_result);
}

TEST_F(ClipboardTest, MultiFormatTest) {
  Clipboard clipboard;

  std::wstring text(L"Hi!"), text_result;
  std::wstring markup(L"Hi!</string>"), markup_result;
  std::string url("http://www.example.com/"), url_result;
  std::string ascii_text;

  clipboard.Clear();
  clipboard.WriteHTML(markup, url);
  clipboard.WriteText(text);
  EXPECT_EQ(true,
      clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextWFormatType()));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetPlainTextFormatType()));
  clipboard.ReadHTML(&markup_result, &url_result);
  EXPECT_EQ(markup, markup_result);
#if defined(OS_MACOSX)
  // TODO(playmobil): It's not clear that the OS X clipboard needs to support
  // this.
#else
  EXPECT_EQ(url, url_result);
#endif
  clipboard.ReadText(&text_result);
  EXPECT_EQ(text, text_result);
  clipboard.ReadAsciiText(&ascii_text);
  EXPECT_EQ(WideToUTF8(text), ascii_text);
}

// Files for this test don't actually need to exist on the file system, just
// don't try to use a non-existent file you've retrieved from the clipboard.
TEST_F(ClipboardTest, FileTest) {
  Clipboard clipboard;
  clipboard.Clear();
#if defined(OS_WIN)
  std::wstring file = L"C:\\Downloads\\My Downloads\\A Special File.txt";
#else
  // OS X will print a warning message if we stick a non-existant file on the
  // clipboard.
  std::wstring file = L"/usr/bin/make";
#endif
  clipboard.WriteFile(file);
  std::wstring out_file;
  clipboard.ReadFile(&out_file);
  EXPECT_EQ(file, out_file);
}

TEST_F(ClipboardTest, MultipleFilesTest) {
  Clipboard clipboard;
  clipboard.Clear();

#if defined(OS_WIN)
  std::wstring file1 = L"C:\\Downloads\\My Downloads\\File 1.exe";
  std::wstring file2 = L"C:\\Downloads\\My Downloads\\File 2.pdf";
  std::wstring file3 = L"C:\\Downloads\\My Downloads\\File 3.doc";
#elif defined(OS_MACOSX)
  // OS X will print a warning message if we stick a non-existant file on the
  // clipboard.
  std::wstring file1 = L"/usr/bin/make";
  std::wstring file2 = L"/usr/bin/man";
  std::wstring file3 = L"/usr/bin/perl";
#endif
  std::vector<std::wstring> files;
  files.push_back(file1);
  files.push_back(file2);
  files.push_back(file3);
  clipboard.WriteFiles(files);

  std::vector<std::wstring> out_files;
  clipboard.ReadFiles(&out_files);

  EXPECT_EQ(files.size(), out_files.size());
  for (size_t i = 0; i < out_files.size(); ++i)
    EXPECT_EQ(files[i], out_files[i]);
}

#if defined(OS_WIN)  // Windows only tests.
TEST_F(ClipboardTest, HyperlinkTest) {
  Clipboard clipboard;

  std::wstring title(L"The Example Company"), title_result;
  std::string url("http://www.example.com/"), url_result;
  std::wstring html(L""
                    L"The Example Company"), html_result;

  clipboard.Clear();
  clipboard.WriteHyperlink(title, url);
  EXPECT_EQ(true,
            clipboard.IsFormatAvailable(Clipboard::GetUrlWFormatType()));
  EXPECT_EQ(true,
            clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType()));
  clipboard.ReadBookmark(&title_result, &url_result);
  EXPECT_EQ(title, title_result);
  EXPECT_EQ(url, url_result);
  clipboard.ReadHTML(&html_result, &url_result);
  EXPECT_EQ(html, html_result);
  //XXX EXPECT_FALSE(url_result.is_valid());
}

TEST_F(ClipboardTest, WebSmartPasteTest) {
  Clipboard clipboard;

  clipboard.Clear();
  clipboard.WriteWebSmartPaste();
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
      Clipboard::GetWebKitSmartPasteFormatType()));
}

TEST_F(ClipboardTest, BitmapTest) {
  unsigned int fake_bitmap[] = {
    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
  };

  Clipboard clipboard;

  clipboard.Clear();
  clipboard.WriteBitmap(fake_bitmap, gfx::Size(3, 4));
  EXPECT_EQ(true, clipboard.IsFormatAvailable(
                      Clipboard::GetBitmapFormatType()));
}
#endif
<|endoftext|>


<commit_before><commit_msg>Add one line spacing before mission related text<commit_after><|endoftext|>


<commit_before>#include <core/stdafx.h>
#include <core/smartview/RecipientRowStream.h>
#include <core/smartview/PropertiesStruct.h>

namespace smartview
{
	ADRENTRYStruct::ADRENTRYStruct(std::shared_ptr<binaryParser> parser)
	{
		cValues = parser->Get<DWORD>();
		ulReserved1 = parser->Get<DWORD>();

		if (cValues && cValues < _MaxEntriesSmall)
		{
			rgPropVals.SetMaxEntries(cValues);
			rgPropVals.parse(parser, false);
		}
	}

	void RecipientRowStream::Parse()
	{
		m_cVersion = m_Parser->Get<DWORD>();
		m_cRowCount = m_Parser->Get<DWORD>();

		if (m_cRowCount)
		{
			if (m_cRowCount < _MaxEntriesSmall)
			{
				m_lpAdrEntry.reserve(m_cRowCount);
				for (DWORD i = 0; i < m_cRowCount; i++)
				{
					m_lpAdrEntry.emplace_back(std::make_shared<ADRENTRYStruct>(m_Parser));
				}
			}
		}
	}

	void RecipientRowStream::ParseBlocks()
	{
		setRoot(L"Recipient Row Stream\r\n");
		addBlock(m_cVersion, L"cVersion = %1!d!\r\n", m_cVersion.getData());
		addBlock(m_cRowCount, L"cRowCount = %1!d!\r\n", m_cRowCount.getData());
		if (!m_lpAdrEntry.empty())
		{
			addBlankLine();
			auto i = DWORD{};
			for (const auto& entry : m_lpAdrEntry)
			{
				terminateBlock();
				addHeader(L"Row %1!d!\r\n", i++);
				addBlock(entry->cValues, L"cValues = 0x%1!08X! = %1!d!\r\n", entry->cValues.getData());
				addBlock(entry->ulReserved1, L"ulReserved1 = 0x%1!08X! = %1!d!\r\n", entry->ulReserved1.getData());
				addBlock(entry->rgPropVals.getBlock());
			}
		}
	}
} // namespace smartview<commit_msg>adrentry to 100<commit_after>#include <core/stdafx.h>
#include <core/smartview/RecipientRowStream.h>
#include <core/smartview/PropertiesStruct.h>

namespace smartview
{
	ADRENTRYStruct::ADRENTRYStruct(std::shared_ptr<binaryParser> parser)
	{
		cValues = parser->Get<DWORD>();
		ulReserved1 = parser->Get<DWORD>();

		if (cValues)
		{
			if (cValues < _MaxEntriesSmall)
			{
				rgPropVals.SetMaxEntries(cValues);
				rgPropVals.parse(parser, false);
			}
		}
	}

	void RecipientRowStream::Parse()
	{
		m_cVersion = m_Parser->Get<DWORD>();
		m_cRowCount = m_Parser->Get<DWORD>();

		if (m_cRowCount)
		{
			if (m_cRowCount < _MaxEntriesSmall)
			{
				m_lpAdrEntry.reserve(m_cRowCount);
				for (DWORD i = 0; i < m_cRowCount; i++)
				{
					m_lpAdrEntry.emplace_back(std::make_shared<ADRENTRYStruct>(m_Parser));
				}
			}
		}
	}

	void RecipientRowStream::ParseBlocks()
	{
		setRoot(L"Recipient Row Stream\r\n");
		addBlock(m_cVersion, L"cVersion = %1!d!\r\n", m_cVersion.getData());
		addBlock(m_cRowCount, L"cRowCount = %1!d!\r\n", m_cRowCount.getData());
		if (!m_lpAdrEntry.empty())
		{
			addBlankLine();
			auto i = DWORD{};
			for (const auto& entry : m_lpAdrEntry)
			{
				terminateBlock();
				addHeader(L"Row %1!d!\r\n", i++);
				addBlock(entry->cValues, L"cValues = 0x%1!08X! = %1!d!\r\n", entry->cValues.getData());
				addBlock(entry->ulReserved1, L"ulReserved1 = 0x%1!08X! = %1!d!\r\n", entry->ulReserved1.getData());
				addBlock(entry->rgPropVals.getBlock());
			}
		}
	}
} // namespace smartview<|endoftext|>


<commit_before>/*
 * replaceSlashTabsParagBreakets.cpp
 *
 *  Created on: Apr 2, 2016
 *      Author: name
 */

#include "../inc/main.h"

void changeIdInJsonFromOldToNew(string &json, int newId) {
	string begin = json;
	string end = json;
	int task_begin = begin.find("\"task\":");
	begin.erase(task_begin + 9, begin.size() - 1);

	string breakets = json;

	breakets.erase(0, breakets.find("\"task\":") + 9);

	breakets.erase(breakets.find(","), breakets.size() - 1);

	int breaket_pos = breakets.find("\"");
	bool is_breakets = false;
	if (breaket_pos > -1)
		is_breakets = true;

	int task_end = end.find(",", task_begin + 8);
	end.erase(0, task_end);

	if (is_breakets == false)
		json = begin + to_string(newId) + end;
	else
		json = begin + "\"" + to_string(newId) + "\"" + end;
}

string replaceSlashTabsParagBreakets (string input)
{
	string output = "";
	bool first_slash = false;
	//bool second_slash = false;
	bool tab = false;
	bool paragraph = false;

	for (int i = 1; i < input.size() - 2; i++)
	{
		char curent = input[i];
		if (curent == '\\')
		{
			if ( !first_slash )
				first_slash = true;
			else
			{
				output += curent;
			}
		}
		else
			if ( curent == '\"')
			{
				if ( first_slash )
				{
					output += "\"";
					first_slash = false;
				}
				else
				{
					output += curent;
				}
			}
			else
				if ( curent == 't')
				{
					if ( first_slash)
					{
						output += "\t";
						first_slash = false;
					}
					else
					{
						output += curent;
					}
				}
				else
					if ( curent == 'n')
					{
						if ( first_slash)
						{
							output += '\n';
							first_slash = false;
						}
						else
						{
							output += curent;
						}
					}
					else
					{
						output += curent;
						first_slash = false;
					}

	}
	return output;

}

/*
string replaceSlashTabsParagBreakets (string input)
{
	string output = "";
	bool first_slash = false;
	bool second_slash = false;
	bool tab = false;
	bool paragraph = false;

	for (int i = 0; i < input.size(); i++)
	{
		char curent = input[i];
		if (curent == '\\')
		{
			if ( !first_slash )
				first_slash = true;
			else
				if (second_slash)
				{
					output += curent;
					first_slash = second_slash = false;
				}
				else
					second_slash = true;
		}
		else
			if ( curent == '\"')
			{
				if ( second_slash)
				{
					output += "\"";
					second_slash = first_slash = false;
				}
				else
				{
					output += curent;
					first_slash = second_slash = false;
				}
			}
			else
				if ( curent == 't')
				{
					if ( second_slash)
					{
						output += "\t";
						second_slash = first_slash = false;
					}
					else
					{
						output += curent;
						first_slash = second_slash = false;
					}
				}
				else
					if ( curent == 'n')
					{
						if ( second_slash)
						{
							output += '\n';
							second_slash = first_slash = false;
						}
						else
						{
							output += curent;
							first_slash = second_slash = false;
						}
					}
					else
					{
						output += curent;
						first_slash = second_slash = false;
					}

	}
	return output;

}
 */
<commit_msg>fix copyTask()<commit_after>/*
 * replaceSlashTabsParagBreakets.cpp
 *
 *  Created on: Apr 2, 2016
 *      Author: name
 */

#include "../inc/main.h"

void changeIdInJsonFromOldToNew(string &json, int newId) {
	string begin = json;
	string end = json;
	int task_begin = begin.find("\"task\":");
	begin.erase(task_begin + 8, begin.size() - 1);

	string breakets = json;

	breakets.erase(0, breakets.find("\"task\":") + 9);

	breakets.erase(breakets.find(","), breakets.size() - 1);

	int breaket_pos = breakets.find("\"");
	bool is_breakets = false;
	if (breaket_pos > -1)
		is_breakets = true;

	int task_end = end.find(",", task_begin + 8);
	end.erase(0, task_end);

	if (is_breakets == false)
		json = begin + to_string(newId) + end;
	else
		json = begin + "\"" + to_string(newId) + "\"" + end;
}

string replaceSlashTabsParagBreakets (string input)
{
	string output = "";
	bool first_slash = false;
	//bool second_slash = false;
	bool tab = false;
	bool paragraph = false;

	for (int i = 1; i < input.size() - 2; i++)
	{
		char curent = input[i];
		if (curent == '\\')
		{
			if ( !first_slash )
				first_slash = true;
			else
			{
				output += curent;
			}
		}
		else
			if ( curent == '\"')
			{
				if ( first_slash )
				{
					output += "\"";
					first_slash = false;
				}
				else
				{
					output += curent;
				}
			}
			else
				if ( curent == 't')
				{
					if ( first_slash)
					{
						output += "\t";
						first_slash = false;
					}
					else
					{
						output += curent;
					}
				}
				else
					if ( curent == 'n')
					{
						if ( first_slash)
						{
							output += '\n';
							first_slash = false;
						}
						else
						{
							output += curent;
						}
					}
					else
					{
						output += curent;
						first_slash = false;
					}

	}
	return output;

}

/*
string replaceSlashTabsParagBreakets (string input)
{
	string output = "";
	bool first_slash = false;
	bool second_slash = false;
	bool tab = false;
	bool paragraph = false;

	for (int i = 0; i < input.size(); i++)
	{
		char curent = input[i];
		if (curent == '\\')
		{
			if ( !first_slash )
				first_slash = true;
			else
				if (second_slash)
				{
					output += curent;
					first_slash = second_slash = false;
				}
				else
					second_slash = true;
		}
		else
			if ( curent == '\"')
			{
				if ( second_slash)
				{
					output += "\"";
					second_slash = first_slash = false;
				}
				else
				{
					output += curent;
					first_slash = second_slash = false;
				}
			}
			else
				if ( curent == 't')
				{
					if ( second_slash)
					{
						output += "\t";
						second_slash = first_slash = false;
					}
					else
					{
						output += curent;
						first_slash = second_slash = false;
					}
				}
				else
					if ( curent == 'n')
					{
						if ( second_slash)
						{
							output += '\n';
							second_slash = first_slash = false;
						}
						else
						{
							output += curent;
							first_slash = second_slash = false;
						}
					}
					else
					{
						output += curent;
						first_slash = second_slash = false;
					}

	}
	return output;

}
 */
<|endoftext|>


<commit_before>#include "mpage.h"

PageItemProxy & PageItemProxy::operator=(const uint8_t & value)
{
    MemoryPage & page = reinterpret_cast<MemoryPage&>(*this);
    page.m_Data[page.m_ProxyIndex] = value;
    page.m_Dirty = true;
    return *this;
}

PageItemProxy::operator uint8_t()
{
    MemoryPage & page = reinterpret_cast<MemoryPage&>(*this);
    return page.m_Data[page.m_ProxyIndex];
}

MemoryPage::MemoryPage() :
    m_Data(nullptr), m_Size(0), m_Start(0), m_Dirty(false)
{
}

int MemoryPage::size() const
{
    return m_Size;
}

uint64_t MemoryPage::start() const
{
    return m_Start;
}

bool MemoryPage::dirty() const
{
    return m_Dirty;
}

void MemoryPage::reset(int start, int size)
{
    m_Start = start;
    m_Size = size;
    m_Dirty = false;
}

uint8_t *& MemoryPage::data()
{
    return m_Data;
}

PageItemProxy & MemoryPage::relative(uint64_t idx)
{
    m_ProxyIndex = idx;
    return reinterpret_cast<PageItemProxy&>(*this);
}

PageItemProxy & MemoryPage::absolute(uint64_t idx)
{
    return relative(idx - m_Start);
}<commit_msg>Add potential optimization check in proxy<commit_after>#include "mpage.h"

PageItemProxy & PageItemProxy::operator=(const uint8_t & value)
{
    MemoryPage & page = reinterpret_cast<MemoryPage&>(*this);
    if (value == page.m_Data[page.m_ProxyIndex]) {
        return *this;
    }

    page.m_Data[page.m_ProxyIndex] = value;
    page.m_Dirty = true;
    return *this;
}

PageItemProxy::operator uint8_t()
{
    MemoryPage & page = reinterpret_cast<MemoryPage&>(*this);
    return page.m_Data[page.m_ProxyIndex];
}

MemoryPage::MemoryPage() :
    m_Data(nullptr), m_Size(0), m_Start(0), m_Dirty(false)
{
}

int MemoryPage::size() const
{
    return m_Size;
}

uint64_t MemoryPage::start() const
{
    return m_Start;
}

bool MemoryPage::dirty() const
{
    return m_Dirty;
}

void MemoryPage::reset(int start, int size)
{
    m_Start = start;
    m_Size = size;
    m_Dirty = false;
}

uint8_t *& MemoryPage::data()
{
    return m_Data;
}

PageItemProxy & MemoryPage::relative(uint64_t idx)
{
    m_ProxyIndex = idx;
    return reinterpret_cast<PageItemProxy&>(*this);
}

PageItemProxy & MemoryPage::absolute(uint64_t idx)
{
    return relative(idx - m_Start);
}<|endoftext|>


<commit_before>
#include "snow_core.h"
#include "snow_io.h"
#include "common/snow_event_queue.h"

#include <string>
#include <vector>

#include <windows.h>

namespace snow {

    extern double timestamp();

    namespace io {

        static eventqueue_t filewatch_queue;

        class FileWatcherThread {

          public:
            bool running;
            std::string path;
            HANDLE handle;
            HANDLE thread;
            OVERLAPPED overlap;
            BYTE* buffer;
            size_t buffer_size;
            CRITICAL_SECTION critical;

            static DWORD WINAPI run_thread( void *watcher );

            FileWatcherThread(const std::string &_path) {

                running = false;
                path = std::string(_path);
                buffer_size = 1024;
                buffer = new BYTE[buffer_size];

                    //I spitballed this 2048 spin count from reading some posts online
                int _spincount = 2048;
                #ifndef DEBUG
                    ::InitializeCriticalSectionEx(&critical, _spincount, CRITICAL_SECTION_NO_DEBUG_INFO);
                #else
                    ::InitializeCriticalSectionEx(&critical, _spincount, 0);
                #endif

                handle = ::CreateFile(
                    path.c_str(),
                    FILE_LIST_DIRECTORY,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                    NULL
                );

                if(handle != INVALID_HANDLE_VALUE) {

                    ZeroMemory(&overlap, sizeof(overlap));
                    overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                    DWORD threadid;
                    running = true;
                    thread = CreateThread(NULL, 0, &run_thread, this, 0, &threadid);

                } //!invalid handle

            } //construct

            ~FileWatcherThread() {

                running = false;

                ::LeaveCriticalSection(&critical);
                ::DeleteCriticalSection(&critical);

                ::CancelIo(handle);
                ::CloseHandle(handle);
                ::CloseHandle(thread);

            } //~

        }; //class FileWatcherThread

        DWORD WINAPI FileWatcherThread::run_thread( void *_watcher ) {

            FileWatcherThread *watcher = (FileWatcherThread*)_watcher;

            while(watcher->running) {

                ReadDirectoryChangesW(
                    watcher->handle, watcher->buffer, watcher->buffer_size, TRUE,
                    FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
                    NULL, &watcher->overlap, NULL
                );

                WaitForSingleObject(watcher->overlap.hEvent, INFINITE);

                    int seek = 0;

                    while(seek < watcher->buffer_size) {

                        PFILE_NOTIFY_INFORMATION notifier = PFILE_NOTIFY_INFORMATION(watcher->buffer + seek);

                        WCHAR szwFileName[MAX_PATH];
                        int ulCount = notifier->FileNameLength/2;
                        wcsncpy(szwFileName, notifier->FileName, ulCount);
                        szwFileName[ulCount] = L'\0';

                        std::wstring widepath(szwFileName);
                        std::string path(widepath.begin(), widepath.end());

                        FileEventType _event_type = fe_unknown;

                            switch( notifier->Action ) {

                                case FILE_ACTION_ADDED:{
                                    _event_type = fe_create;
                                    break;
                                }

                                case FILE_ACTION_REMOVED:{
                                    _event_type = fe_remove;
                                    break;
                                }

                                case FILE_ACTION_MODIFIED:{
                                    _event_type = fe_modify;
                                    break;
                                }

                                case FILE_ACTION_RENAMED_OLD_NAME:{
                                    _event_type = fe_remove;
                                    break;
                                }

                                case FILE_ACTION_RENAMED_NEW_NAME:{
                                    _event_type = fe_create;
                                    break;
                                }

                            } //switch

                            if(_event_type != fe_unknown) {

                                // put into queue
                                event_node_t* node = new event_node_t;
                                node->event = new FileEvent( _event_type, snow::timestamp(), (watcher->path+"/"+path) );
                                eventqueue_push(&filewatch_queue, node);

                            }

                        seek += notifier->NextEntryOffset;

                        if(notifier->NextEntryOffset == 0) {
                            break;
                        }

                    } //seek < buffer size

                } //while running

            return 0;

        } //run_thread

        std::vector<std::string> watched_paths;
        std::vector<FileWatcherThread*> watchers;

        bool init_filewatch() {

            snow::log(1, "/ snow / initialized file watch ok");

            // create our queue
            eventqueue_create((eventqueue_t*)&filewatch_queue);

            return true;

        } //init_filewatch

        void start_filewatch(){

            if(watched_paths.size() == 0) {
                return;
            }

            std::vector<std::string>::iterator it = watched_paths.begin();

            for( ; it != watched_paths.end(); ++it) {

                std::string path = *it;

                FileWatcherThread* watcher = new FileWatcherThread(path);
                watchers.push_back(watcher);

            } //each watched path

            snow::log(1, "/ snow / filewatch started");

        } //start_filewatch

        void stop_filewatch() {

            if(watchers.size() == 0) {
                return;
            }

            std::vector<FileWatcherThread*>::iterator it = watchers.begin();

            for( ; it != watchers.end(); ++it) {
                FileWatcherThread* watcher = *it;
                if(watcher) {
                    delete watcher;
                }
            }

            watchers.clear();

            snow::log(1, "/ snow / filewatch stopped");

        } //stop_filewatch

        void refresh_filewatch() {

            stop_filewatch();
            start_filewatch();

        } //refresh_filewatch

        void update_filewatch() {

            // clear the queue
            event_node_t* node;
            while( node = eventqueue_pop(&filewatch_queue) ) {
                snow::io::dispatch_event( *node->event );
                delete node->event;
                delete node;
            }

        } //update_filewatch

        void shutdown_filewatch() {

            stop_filewatch();

            snow::log(1, "/ snow / filewatch shutdown");

        } //shutdown_filewatch

    } //io namespace

} //snow namespace

<commit_msg>update windows logging on file watch<commit_after>
#include "snow_core.h"
#include "snow_io.h"
#include "common/snow_event_queue.h"

#include <string>
#include <vector>

#include <windows.h>

namespace snow {

    extern double timestamp();

    namespace io {

        static eventqueue_t filewatch_queue;

        class FileWatcherThread {

          public:
            bool running;
            std::string path;
            HANDLE handle;
            HANDLE thread;
            OVERLAPPED overlap;
            BYTE* buffer;
            size_t buffer_size;
            CRITICAL_SECTION critical;

            static DWORD WINAPI run_thread( void *watcher );

            FileWatcherThread(const std::string &_path) {

                running = false;
                path = std::string(_path);
                buffer_size = 1024;
                buffer = new BYTE[buffer_size];

                    //I spitballed this 2048 spin count from reading some posts online
                int _spincount = 2048;
                #ifndef DEBUG
                    ::InitializeCriticalSectionEx(&critical, _spincount, CRITICAL_SECTION_NO_DEBUG_INFO);
                #else
                    ::InitializeCriticalSectionEx(&critical, _spincount, 0);
                #endif

                handle = ::CreateFile(
                    path.c_str(),
                    FILE_LIST_DIRECTORY,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                    NULL
                );

                if(handle != INVALID_HANDLE_VALUE) {

                    ZeroMemory(&overlap, sizeof(overlap));
                    overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                    DWORD threadid;
                    running = true;
                    thread = CreateThread(NULL, 0, &run_thread, this, 0, &threadid);

                } //!invalid handle

            } //construct

            ~FileWatcherThread() {

                running = false;

                ::LeaveCriticalSection(&critical);
                ::DeleteCriticalSection(&critical);

                ::CancelIo(handle);
                ::CloseHandle(handle);
                ::CloseHandle(thread);

            } //~

        }; //class FileWatcherThread

        DWORD WINAPI FileWatcherThread::run_thread( void *_watcher ) {

            FileWatcherThread *watcher = (FileWatcherThread*)_watcher;

            while(watcher->running) {

                ReadDirectoryChangesW(
                    watcher->handle, watcher->buffer, watcher->buffer_size, TRUE,
                    FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
                    NULL, &watcher->overlap, NULL
                );

                WaitForSingleObject(watcher->overlap.hEvent, INFINITE);

                    int seek = 0;

                    while(seek < watcher->buffer_size) {

                        PFILE_NOTIFY_INFORMATION notifier = PFILE_NOTIFY_INFORMATION(watcher->buffer + seek);

                        WCHAR szwFileName[MAX_PATH];
                        int ulCount = notifier->FileNameLength/2;
                        wcsncpy(szwFileName, notifier->FileName, ulCount);
                        szwFileName[ulCount] = L'\0';

                        std::wstring widepath(szwFileName);
                        std::string path(widepath.begin(), widepath.end());

                        FileEventType _event_type = fe_unknown;

                            switch( notifier->Action ) {

                                case FILE_ACTION_ADDED:{
                                    _event_type = fe_create;
                                    break;
                                }

                                case FILE_ACTION_REMOVED:{
                                    _event_type = fe_remove;
                                    break;
                                }

                                case FILE_ACTION_MODIFIED:{
                                    _event_type = fe_modify;
                                    break;
                                }

                                case FILE_ACTION_RENAMED_OLD_NAME:{
                                    _event_type = fe_remove;
                                    break;
                                }

                                case FILE_ACTION_RENAMED_NEW_NAME:{
                                    _event_type = fe_create;
                                    break;
                                }

                            } //switch

                            if(_event_type != fe_unknown) {

                                // put into queue
                                event_node_t* node = new event_node_t;
                                node->event = new FileEvent( _event_type, snow::timestamp(), (watcher->path+"/"+path) );
                                eventqueue_push(&filewatch_queue, node);

                            }

                        seek += notifier->NextEntryOffset;

                        if(notifier->NextEntryOffset == 0) {
                            break;
                        }

                    } //seek < buffer size

                } //while running

            return 0;

        } //run_thread

        std::vector<std::string> watched_paths;
        std::vector<FileWatcherThread*> watchers;

        bool init_filewatch() {

            snow::log(2, "/ snow / initialized file watch ok");

            // create our queue
            eventqueue_create((eventqueue_t*)&filewatch_queue);

            return true;

        } //init_filewatch

        void start_filewatch(){

            if(watched_paths.size() == 0) {
                return;
            }

            std::vector<std::string>::iterator it = watched_paths.begin();

            for( ; it != watched_paths.end(); ++it) {

                std::string path = *it;

                FileWatcherThread* watcher = new FileWatcherThread(path);
                watchers.push_back(watcher);

            } //each watched path

            snow::log(2, "/ snow / filewatch started");

        } //start_filewatch

        void stop_filewatch() {

            if(watchers.size() == 0) {
                return;
            }

            std::vector<FileWatcherThread*>::iterator it = watchers.begin();

            for( ; it != watchers.end(); ++it) {
                FileWatcherThread* watcher = *it;
                if(watcher) {
                    delete watcher;
                }
            }

            watchers.clear();

            snow::log(2, "/ snow / filewatch stopped");

        } //stop_filewatch

        void refresh_filewatch() {

            stop_filewatch();
            start_filewatch();

        } //refresh_filewatch

        void update_filewatch() {

            // clear the queue
            event_node_t* node;
            while( node = eventqueue_pop(&filewatch_queue) ) {
                snow::io::dispatch_event( *node->event );
                delete node->event;
                delete node;
            }

        } //update_filewatch

        void shutdown_filewatch() {

            stop_filewatch();

            snow::log(2, "/ snow / filewatch shutdown");

        } //shutdown_filewatch

    } //io namespace

} //snow namespace

<|endoftext|>


<commit_before>#include "music.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"
#include "dumb/include/aldumb.h"

#ifdef _WIN32
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"
#include "util/file-system.h"

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

static void * bogus_thread( void * x){
	return NULL;
}

Music::Music( bool on ):
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ),
currentSong(""){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	if ( on ){
		pthread_create( &musicThread, NULL, playMusic, (void *)instance );
	} else {
		pthread_create( &musicThread, NULL, bogus_thread, NULL );
	}
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
    Music * music = (Music *) _music;

    Global::debug( 1 ) << "Playing music" << endl;

    /*
       unsigned int tick = 0;
       unsigned int counter;
       */

    bool playing = true;
    while ( playing ){

        LOCK;{
            playing = alive;
            music->doPlay();
        }
        UNLOCK;
        Util::rest( 10 );

        // Util::YIELD();
        // pthread_yield();
    }

    // cout << "Done with music thread" << endl;

    return NULL;
}

double Music::getVolume(){
    double vol = 0;
    LOCK;{
        vol = volume;
    }
    UNLOCK;
    return vol;
}

void Music::doPlay(){
    if ( this->playing ){
        double f = fading / 500.0;
        switch ( fading ){
            case -1 : {
                          if ( volume + f < 0 ){
                              fading = 0;
                              volume = 0;
                          } else {
                              volume += f;
                              this->_setVolume( volume );
                          }
                          break;
                      }
            case 1 : {
                         if ( volume + f > 1.0 ){
                             fading = 0;
                             volume = 1.0;
                         } else {
                             volume += f;
                             this->_setVolume( volume );
                         }
                         break;
                     }
        }
        if ( al_poll_duh( this->player ) != 0 ){
        }
    }
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeIn();
    }
    UNLOCK;
}

void Music::fadeOut( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeOut();
    }
    UNLOCK;
}

void Music::_fadeIn(){
    fading = 1;
}

void Music::_fadeOut(){
    fading = -1;
}

bool Music::loadSong( const char * song ){
    bool loaded = false;
    LOCK;{
        loaded = instance->internal_loadSong( song );
    }
    UNLOCK;
    return loaded;
    // muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
    int count = 0;
    typename vector< Tx_ >::iterator it;
    for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

    if ( it == toRemove.end() ){
        /* this isnt right, but whatever */
        return toRemove.front();
    }

    const Tx_ & removed = toRemove[ pos ];
    toRemove.erase( it );
    return removed;

}

void Music::loadSong( const vector< string > & Songs ){

    /*
       cout << "Songs = " << &Songs << endl;
       if ( ! loadSong( "music/song5.xm" ) ){
       cerr << "Could not load music/song5.xm" << endl;
       }
       return;
       */

    vector< string > _songs = Songs;
    vector< string > songs;
    while ( ! _songs.empty() ){
        int i = Util::rnd( _songs.size() );
        songs.push_back( removeVectorElement< string >( _songs, i ) );
    }

    /*
       songs.clear();
       songs.push_back( "music/song3.xm" );
       */

    for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
        Global::debug( 1 ) << "Trying to load song " << *it << endl;
        if (loadSong(*it)){
            break;
        }
    }
}

bool Music::loadSong( const string & song ){
    return loadSong( song.c_str() );
}

void Music::_play(){
    if ( playing == false && this->player != NULL ){
        al_resume_duh( this->player );
        playing = true;
    }
}

void Music::play(){
    LOCK;{
        instance->_play();
    }
    UNLOCK;
}

void Music::_pause(){
    playing = false;
    if ( this->player != NULL ){
        al_pause_duh( this->player );
    }
}

void Music::pause(){
    LOCK;{
        instance->_pause();
    }
    UNLOCK;
}

void Music::soften(){
    LOCK;{
        instance->_soften();
    }
    UNLOCK;
}

void Music::_soften(){
    if ( volume > 0.1 ){
        volume -= 0.1;
    } else {
        volume = 0.0;
    }

    _setVolume( volume );
}

void Music::louden(){
    LOCK;{
        instance->_louden();
    }
    UNLOCK;
}

void Music::_louden(){
    if ( volume < 0.9 ){
        volume += 0.1;
    } else {
        volume = 1.0;
    }

    _setVolume( volume );
}

void Music::mute(){
    setVolume( 0 );
}

void Music::setVolume( double vol ){

    LOCK;{
        volume = vol;
        if ( volume > 1.0 ){
            volume = 1.0;
        }
        if ( volume < 0 ){
            volume = 0;
        }
        instance->_setVolume( volume );
    }
    UNLOCK;
}

void Music::_setVolume( double vol ){

    if ( player ){
        al_duh_set_volume( player, vol );
    }

}

Music::~Music(){

    LOCK;{
        if ( player ){
            al_stop_duh( player );
            unload_duh( music_file );
        }

        alive = false;
        playing = false;
    }
    UNLOCK;

    Global::debug( 1 ) << "Waiting for music thread to die" << endl;
    pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
    switch (i){
        case 0 : return ".xm";
        case 1 : return ".s3m";
        case 2 : return ".it";
        case 3 : return ".mod";
        default : return "";
    }
}

bool Music::internal_loadSong( const char * path ){

    // cout << "Trying to load '" << path << "'" << endl;

    // Check current song and/or set it
    if (currentSong.compare(std::string(path))==0){
        return true;
    } else {
        currentSong = std::string(path);
    }

    if ( player != NULL ){
        al_stop_duh( player );
        unload_duh( music_file );
        player = NULL;
        music_file = NULL;
    }

    // music_file = dumb_load_mod( path );
    /*
       music_file = dumb_load_mod( path );
       if ( !music_file ){
       music_file = dumb_load_xm( path );
       }
       if ( !music_file ){
       music_file = dumb_load_s3m( path );
       }
       if ( !music_file ){
       music_file = dumb_load_it( path );
       }
       */

    for ( int i = 0; i < 4; i++ ){
        /* the order of trying xm/s3m/it/mod matters because mod could be
         * confused with one of the other formats, so load it last.
         */
        switch (i){
            case 0 : {
                         music_file = dumb_load_xm_quick( path );
                         break;
                     }
            case 1 : {
                         music_file = dumb_load_s3m_quick( path );
                         break;
                     }
            case 2 : {
                         music_file = dumb_load_it_quick( path );
                         break;
                     }
            case 3 : {
                         music_file = dumb_load_mod_quick( path );
                         break;
                     }
        }
        if ( music_file != NULL ){
            Global::debug(0) << "Loaded " << path << " type " << typeToExtension( i ) << "(" << i << ")" << endl;
            break;
        }
    }

    if (music_file){
        int buf = 1 << 11;
        player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
        // cout << "Loaded music player " << player << endl;

        /*
           while ( 1 ){
           al_poll_duh( player );
           rest( 1 );
           }
           */

        if (player != NULL){
            playing = true;
        } else {
            Global::debug(0) << "*BUG* Could not create music player" << endl;
        }
    } else {
        Global::debug( 0 )<<"Could not load "<<path<<endl;
        return false;
    }
    return true;

}

void Music::changeSong(){
    pause();
    fadeIn(0.3);
    loadSong(Util::getFiles(Filesystem::find(Filesystem::RelativePath("music/")), "*"));
    play();
}

#undef synchronized
#undef LOCK
#undef UNLOCK
<commit_msg>guard Music from using dumb-allegro functions<commit_after>#include "music.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"
#include "dumb/include/aldumb.h"

#ifdef _WIN32
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"
#include "util/file-system.h"

/* FIXME!!!!!!!!!
 * Get rid of the USE_ALLEGRO ifdef's in here.
 */

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

static void * bogus_thread( void * x){
	return NULL;
}

Music::Music( bool on ):
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ),
currentSong(""){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	if ( on ){
		pthread_create( &musicThread, NULL, playMusic, (void *)instance );
	} else {
		pthread_create( &musicThread, NULL, bogus_thread, NULL );
	}
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
    Music * music = (Music *) _music;

    Global::debug( 1 ) << "Playing music" << endl;

    /*
       unsigned int tick = 0;
       unsigned int counter;
       */

    bool playing = true;
    while ( playing ){

        LOCK;{
            playing = alive;
            music->doPlay();
        }
        UNLOCK;
        Util::rest( 10 );

        // Util::YIELD();
        // pthread_yield();
    }

    // cout << "Done with music thread" << endl;

    return NULL;
}

double Music::getVolume(){
    double vol = 0;
    LOCK;{
        vol = volume;
    }
    UNLOCK;
    return vol;
}

void Music::doPlay(){
    if ( this->playing ){
        double f = fading / 500.0;
        switch ( fading ){
            case -1 : {
                          if ( volume + f < 0 ){
                              fading = 0;
                              volume = 0;
                          } else {
                              volume += f;
                              this->_setVolume( volume );
                          }
                          break;
                      }
            case 1 : {
                         if ( volume + f > 1.0 ){
                             fading = 0;
                             volume = 1.0;
                         } else {
                             volume += f;
                             this->_setVolume( volume );
                         }
                         break;
                     }
        }
#ifdef USE_ALLEGRO
        if (al_poll_duh( this->player ) != 0){
        }
#endif
    }
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeIn();
    }
    UNLOCK;
}

void Music::fadeOut( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeOut();
    }
    UNLOCK;
}

void Music::_fadeIn(){
    fading = 1;
}

void Music::_fadeOut(){
    fading = -1;
}

bool Music::loadSong( const char * song ){
    bool loaded = false;
    LOCK;{
        loaded = instance->internal_loadSong( song );
    }
    UNLOCK;
    return loaded;
    // muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
    int count = 0;
    typename vector< Tx_ >::iterator it;
    for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

    if ( it == toRemove.end() ){
        /* this isnt right, but whatever */
        return toRemove.front();
    }

    const Tx_ & removed = toRemove[ pos ];
    toRemove.erase( it );
    return removed;

}

void Music::loadSong( const vector< string > & Songs ){

    /*
       cout << "Songs = " << &Songs << endl;
       if ( ! loadSong( "music/song5.xm" ) ){
       cerr << "Could not load music/song5.xm" << endl;
       }
       return;
       */

    vector< string > _songs = Songs;
    vector< string > songs;
    while ( ! _songs.empty() ){
        int i = Util::rnd( _songs.size() );
        songs.push_back( removeVectorElement< string >( _songs, i ) );
    }

    /*
       songs.clear();
       songs.push_back( "music/song3.xm" );
       */

    for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
        Global::debug( 1 ) << "Trying to load song " << *it << endl;
        if (loadSong(*it)){
            break;
        }
    }
}

bool Music::loadSong( const string & song ){
    return loadSong( song.c_str() );
}

void Music::_play(){
    if ( playing == false && this->player != NULL ){
#ifdef USE_ALLEGRO
        al_resume_duh( this->player );
#endif
        playing = true;
    }
}

void Music::play(){
    LOCK;{
        instance->_play();
    }
    UNLOCK;
}

void Music::_pause(){
    playing = false;
    if ( this->player != NULL ){
#ifdef USE_ALLEGRO
        al_pause_duh( this->player );
#endif
    }
}

void Music::pause(){
    LOCK;{
        instance->_pause();
    }
    UNLOCK;
}

void Music::soften(){
    LOCK;{
        instance->_soften();
    }
    UNLOCK;
}

void Music::_soften(){
    if ( volume > 0.1 ){
        volume -= 0.1;
    } else {
        volume = 0.0;
    }

    _setVolume( volume );
}

void Music::louden(){
    LOCK;{
        instance->_louden();
    }
    UNLOCK;
}

void Music::_louden(){
    if ( volume < 0.9 ){
        volume += 0.1;
    } else {
        volume = 1.0;
    }

    _setVolume( volume );
}

void Music::mute(){
    setVolume( 0 );
}

void Music::setVolume( double vol ){

    LOCK;{
        volume = vol;
        if ( volume > 1.0 ){
            volume = 1.0;
        }
        if ( volume < 0 ){
            volume = 0;
        }
        instance->_setVolume( volume );
    }
    UNLOCK;
}

void Music::_setVolume( double vol ){

    if ( player ){
#ifdef USE_ALLEGRO
        al_duh_set_volume( player, vol );
#endif
    }

}

Music::~Music(){

    LOCK;{
        if ( player ){
#ifdef USE_ALLEGRO
            al_stop_duh( player );
#endif
            unload_duh( music_file );
        }

        alive = false;
        playing = false;
    }
    UNLOCK;

    Global::debug( 1 ) << "Waiting for music thread to die" << endl;
    pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
    switch (i){
        case 0 : return ".xm";
        case 1 : return ".s3m";
        case 2 : return ".it";
        case 3 : return ".mod";
        default : return "";
    }
}

bool Music::internal_loadSong( const char * path ){

    // cout << "Trying to load '" << path << "'" << endl;

    // Check current song and/or set it
    if (currentSong.compare(std::string(path))==0){
        return true;
    } else {
        currentSong = std::string(path);
    }

    if ( player != NULL ){
#ifdef USE_ALLEGRO
        al_stop_duh( player );
#endif
        unload_duh( music_file );
        player = NULL;
        music_file = NULL;
    }

    // music_file = dumb_load_mod( path );
    /*
       music_file = dumb_load_mod( path );
       if ( !music_file ){
       music_file = dumb_load_xm( path );
       }
       if ( !music_file ){
       music_file = dumb_load_s3m( path );
       }
       if ( !music_file ){
       music_file = dumb_load_it( path );
       }
       */

    for ( int i = 0; i < 4; i++ ){
        /* the order of trying xm/s3m/it/mod matters because mod could be
         * confused with one of the other formats, so load it last.
         */
        switch (i){
            case 0 : {
                         music_file = dumb_load_xm_quick( path );
                         break;
                     }
            case 1 : {
                         music_file = dumb_load_s3m_quick( path );
                         break;
                     }
            case 2 : {
                         music_file = dumb_load_it_quick( path );
                         break;
                     }
            case 3 : {
                         music_file = dumb_load_mod_quick( path );
                         break;
                     }
        }
        if ( music_file != NULL ){
            Global::debug(0) << "Loaded " << path << " type " << typeToExtension( i ) << "(" << i << ")" << endl;
            break;
        }
    }

    if (music_file){
#ifdef USE_ALLEGRO
        int buf = 1 << 11;
        player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
        // cout << "Loaded music player " << player << endl;

        /*
           while ( 1 ){
           al_poll_duh( player );
           rest( 1 );
           }
           */

        if (player != NULL){
            playing = true;
        } else {
            Global::debug(0) << "*BUG* Could not create music player" << endl;
        }
#endif
    } else {
        Global::debug( 0 )<<"Could not load "<<path<<endl;
        return false;
    }
    return true;

}

void Music::changeSong(){
    pause();
    fadeIn(0.3);
    loadSong(Util::getFiles(Filesystem::find(Filesystem::RelativePath("music/")), "*"));
    play();
}

#undef synchronized
#undef LOCK
#undef UNLOCK
<|endoftext|>


<commit_before>#include <cassert>

#include "linear/mutex.h"

#include "mutex_impl.h"

#include "uv.h"

namespace linear {

// class mutex_impl
mutex::mutex_impl::mutex_impl() {
  if (uv_mutex_init(&mutex_)) {
    assert(false);
  }
}
mutex::mutex_impl::~mutex_impl() {
  uv_mutex_destroy(&mutex_);
}
void mutex::mutex_impl::lock() {
  uv_mutex_lock(&mutex_);
}
#define WAIT_UPDATING_LIBUV (1) // https://github.com/linear-rpc/linear-cpp/issues/1
bool mutex::mutex_impl::try_lock() {
#if WAIT_UPDATING_LIBUV
  int err;
  err = pthread_mutex_trylock(&mutex);
  if (err) {
    if (err != EBUSY && err != EAGAIN && err != EDEADLK)
      abort();
    return false;
  }
  return true;
#else
  if (uv_mutex_trylock(&mutex_)) {
    return false;
  }
  return true;
#endif
}
#undef WAIT_UPDATING_LIBUV
void mutex::mutex_impl::unlock() {
  uv_mutex_unlock(&mutex_);
}
uv_mutex_t* mutex::mutex_impl::native_handle() {
  return &mutex_;
}

// class mutex
mutex::mutex()
  : impl_(new mutex::mutex_impl()) {
}
mutex::~mutex() {
  delete impl_;
}
void mutex::lock() {
  impl_->lock();
}
bool mutex::try_lock() {
  return impl_->try_lock();
}
void mutex::unlock() {
  impl_->unlock();
}
mutex::native_handle_type mutex::native_handle() {
  return impl_;
}

}  // namespace linear
<commit_msg>fix typo<commit_after>#include <cassert>
#include <cstdlib>

#include "linear/mutex.h"

#include "mutex_impl.h"

#include "uv.h"

namespace linear {

// class mutex_impl
mutex::mutex_impl::mutex_impl() {
  if (uv_mutex_init(&mutex_)) {
    assert(false);
  }
}
mutex::mutex_impl::~mutex_impl() {
  uv_mutex_destroy(&mutex_);
}
void mutex::mutex_impl::lock() {
  uv_mutex_lock(&mutex_);
}
#define WAIT_UPDATING_LIBUV (1) // https://github.com/linear-rpc/linear-cpp/issues/1
bool mutex::mutex_impl::try_lock() {
#if WAIT_UPDATING_LIBUV
  int err;
  err = pthread_mutex_trylock(&mutex_);
  if (err) {
    if (err != EBUSY && err != EAGAIN && err != EDEADLK) {
      abort();
    }
    return false;
  }
  return true;
#else
  if (uv_mutex_trylock(&mutex_)) {
    return false;
  }
  return true;
#endif
}
#undef WAIT_UPDATING_LIBUV
void mutex::mutex_impl::unlock() {
  uv_mutex_unlock(&mutex_);
}
uv_mutex_t* mutex::mutex_impl::native_handle() {
  return &mutex_;
}

// class mutex
mutex::mutex()
  : impl_(new mutex::mutex_impl()) {
}
mutex::~mutex() {
  delete impl_;
}
void mutex::lock() {
  impl_->lock();
}
bool mutex::try_lock() {
  return impl_->try_lock();
}
void mutex::unlock() {
  impl_->unlock();
}
mutex::native_handle_type mutex::native_handle() {
  return impl_;
}

}  // namespace linear
<|endoftext|>


<commit_before>// Copyright (c) 2011, Cornell University
// 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 HyperDex 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.

#define __STDC_LIMIT_MACROS

// Google Log
#include <glog/logging.h>

// HyperDex
#include <hyperdex/city.h>
#include <hyperdex/hyperspace.h>
#include <hyperdex/region.h>

hyperdex :: region :: region(const regionid& ri, const po6::pathname& directory, uint16_t nc)
    : m_ref(0)
    , m_numcolumns(nc)
    , m_point_mask(get_point_for(UINT64_MAX))
    , m_log()
    , m_rwlock()
    , m_disks()
{
    std::ostringstream ostr;
    ostr << ri;
    // Create one disk to start.  It will split as necessary.
    // XXX Implement splitting.
    po6::pathname path = join(directory, ostr.str());
    e::intrusive_ptr<disk> d = new disk(join(directory, ostr.str()));
    m_disks.push_back(std::make_pair(ri, d));
}

hyperdex :: result_t
hyperdex :: region :: get(const e::buffer& key,
                          std::vector<e::buffer>* value,
                          uint64_t* version)
{
    log::iterator it(m_log.iterate());
    bool found = false;
    *version = 0;

    // Scan the in-memory WAL.
    for (; it.valid(); it.next())
    {
        if (it.key() == key)
        {
            if (it.op() == PUT)
            {
                *value = it.value();
                *version = it.version();
            }
            else if (it.op() == DEL)
            {
                *version = 0;
            }

            found = true;
        }
    }

    // We know that the log is a suffix of the linear ordering of all updates to
    // this region.  If we found something in the log, it is *guaranteed* to be
    // more recent than anything on-disk, so we just return.  In the uncommon
    // case this means that we'll not have to touch memory-mapped files.  We
    // have to iterate this part of the log anyway so it's not a big deal to do
    // part of it before touching disk.
    if (found)
    {
        return *version == 0 ? NOTFOUND : SUCCESS;
    }

    std::vector<e::buffer> tmp_value;
    uint64_t tmp_version = 0;
    uint64_t key_hash = CityHash64(key);
    uint64_t key_point = get_point_for(key_hash);
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        uint64_t pmask = prefixmask(i->first.prefix);

        if ((i->first.mask & m_point_mask & pmask)
                != (key_point & pmask))
        {
            continue;
        }

        result_t res = i->second->get(key, key_hash, &tmp_value, &tmp_version);

        if (res == SUCCESS)
        {
            if (tmp_version > *version)
            {
                value->swap(tmp_value);
                *version = tmp_version;
            }

            break;
        }
        else if (res != NOTFOUND)
        {
            return res;
        }
    }

    found = false;

    // Scan the in-memory WAL again.
    for (; it.valid(); it.next())
    {
        if (it.key() == key)
        {
            if (it.op() == PUT)
            {
                *value = it.value();
                *version = it.version();
            }
            else if (it.op() == DEL)
            {
                *version = 0;
            }

            found = true;
        }
    }

    if (*version > 0 || found)
    {
        return SUCCESS;
    }
    else
    {
        return NOTFOUND;
    }
}

hyperdex :: result_t
hyperdex :: region :: put(const e::buffer& key,
                          const std::vector<e::buffer>& value,
                          uint64_t version)
{
    uint64_t key_hash = CityHash64(key);
    std::vector<uint64_t> value_hashes;
    get_value_hashes(value, &value_hashes);
    uint64_t point = get_point_for(key_hash, value_hashes);

    if (value.size() + 1 != m_numcolumns)
    {
        return INVALID;
    }
    else if (m_log.append(point, key, key_hash, value, value_hashes, version))
    {
        return SUCCESS;
    }
    else
    {
        LOG(INFO) << "Could not append to in-memory WAL.";
        return ERROR;
    }
}

hyperdex :: result_t
hyperdex :: region :: del(const e::buffer& key)
{
    uint64_t key_hash = CityHash64(key);
    uint64_t point = get_point_for(key_hash);

    if (m_log.append(point, key, key_hash))
    {
        return SUCCESS;
    }
    else
    {
        LOG(INFO) << "Could not append to in-memory WAL.";
        return ERROR;
    }
}

size_t
hyperdex :: region :: flush()
{
    using std::tr1::placeholders::_1;
    using std::tr1::placeholders::_2;
    using std::tr1::placeholders::_3;
    using std::tr1::placeholders::_4;
    using std::tr1::placeholders::_5;
    using std::tr1::placeholders::_6;
    using std::tr1::placeholders::_7;
    return m_log.flush(std::tr1::bind(&region::flush_one, this, _1, _2, _3, _4, _5, _6, _7));
}

void
hyperdex :: region :: flush_one(op_t op, uint64_t point, const e::buffer& key,
                                uint64_t key_hash,
                                const std::vector<e::buffer>& value,
                                const std::vector<uint64_t>& value_hashes,
                                uint64_t version)
{
    // XXX to prevent excessive failures, we should probably add some logic here
    // to block until a split occurs to resolve disk space issues.

    // Delete from every disk
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        // Use m_point_mask because we want every disk which could have this
        // key.
        uint64_t pmask = prefixmask(i->first.prefix) & m_point_mask;

        if ((i->first.mask & pmask) != (point & pmask))
        {
            continue;
        }

        result_t res = i->second->del(key, key_hash);

        if (res != SUCCESS && res != NOTFOUND)
        {
            // XXX FAIL DISK
            LOG(INFO) << "Disk has failed.";
        }
    }

    // Put to one disk
    if (op == PUT)
    {
        for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
        {
            uint64_t pmask = prefixmask(i->first.prefix);

            if ((i->first.mask & pmask) != (point & pmask))
            {
                continue;
            }

            result_t res = i->second->put(key, key_hash, value, value_hashes, version);

            if (res != SUCCESS)
            {
                // XXX FAIL DISK
                LOG(INFO) << "Disk has failed.";
            }
        }
    }
}

void
hyperdex :: region :: async()
{
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        i->second->async();
    }
}

void
hyperdex :: region :: sync()
{
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        i->second->sync();
    }
}

void
hyperdex :: region :: get_value_hashes(const std::vector<e::buffer>& value,
                                       std::vector<uint64_t>* value_hashes)
{
    for (size_t i = 0; i < value.size(); ++i)
    {
        value_hashes->push_back(CityHash64(value[i]));
    }
}

uint64_t
hyperdex :: region :: get_point_for(uint64_t key_hash)
{
    std::vector<uint64_t> points;
    points.push_back(key_hash);

    for (size_t i = 1; i < m_numcolumns; ++i)
    {
        points.push_back(0);
    }

    return interlace(points);
}

uint64_t
hyperdex :: region :: get_point_for(uint64_t key_hash, const std::vector<uint64_t>& value_hashes)
{
    std::vector<uint64_t> points;
    points.push_back(key_hash);

    for (size_t i = 0; i < value_hashes.size(); ++i)
    {
        points.push_back(value_hashes[i]);
    }

    return interlace(points);
}
<commit_msg>Found the bug that caused the occasional NOTFOUND.<commit_after>// Copyright (c) 2011, Cornell University
// 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 HyperDex 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.

#define __STDC_LIMIT_MACROS

// Google Log
#include <glog/logging.h>

// HyperDex
#include <hyperdex/city.h>
#include <hyperdex/hyperspace.h>
#include <hyperdex/region.h>

hyperdex :: region :: region(const regionid& ri, const po6::pathname& directory, uint16_t nc)
    : m_ref(0)
    , m_numcolumns(nc)
    , m_point_mask(get_point_for(UINT64_MAX))
    , m_log()
    , m_rwlock()
    , m_disks()
{
    std::ostringstream ostr;
    ostr << ri;
    // Create one disk to start.  It will split as necessary.
    // XXX Implement splitting.
    po6::pathname path = join(directory, ostr.str());
    e::intrusive_ptr<disk> d = new disk(join(directory, ostr.str()));
    m_disks.push_back(std::make_pair(regionid(ri.get_subspace(), 0, 0), d));
}

hyperdex :: result_t
hyperdex :: region :: get(const e::buffer& key,
                          std::vector<e::buffer>* value,
                          uint64_t* version)
{
    log::iterator it(m_log.iterate());
    bool found = false;
    *version = 0;

    // Scan the in-memory WAL.
    for (; it.valid(); it.next())
    {
        if (it.key() == key)
        {
            if (it.op() == PUT)
            {
                *value = it.value();
                *version = it.version();
            }
            else if (it.op() == DEL)
            {
                *version = 0;
            }

            found = true;
        }
    }

    // We know that the log is a suffix of the linear ordering of all updates to
    // this region.  If we found something in the log, it is *guaranteed* to be
    // more recent than anything on-disk, so we just return.  In the uncommon
    // case this means that we'll not have to touch memory-mapped files.  We
    // have to iterate this part of the log anyway so it's not a big deal to do
    // part of it before touching disk.
    if (found)
    {
        return *version == 0 ? NOTFOUND : SUCCESS;
    }

    std::vector<e::buffer> tmp_value;
    uint64_t tmp_version = 0;
    uint64_t key_hash = CityHash64(key);
    uint64_t key_point = get_point_for(key_hash);
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        uint64_t pmask = prefixmask(i->first.prefix);

        if ((i->first.mask & m_point_mask & pmask)
                != (key_point & pmask))
        {
            continue;
        }

        result_t res = i->second->get(key, key_hash, &tmp_value, &tmp_version);

        if (res == SUCCESS)
        {
            if (tmp_version > *version)
            {
                value->swap(tmp_value);
                *version = tmp_version;
            }

            break;
        }
        else if (res != NOTFOUND)
        {
            return res;
        }
    }

    found = false;

    // Scan the in-memory WAL again.
    for (; it.valid(); it.next())
    {
        if (it.key() == key)
        {
            if (it.op() == PUT)
            {
                *value = it.value();
                *version = it.version();
            }
            else if (it.op() == DEL)
            {
                *version = 0;
            }

            found = true;
        }
    }

    if (*version > 0 || found)
    {
        return SUCCESS;
    }
    else
    {
        return NOTFOUND;
    }
}

hyperdex :: result_t
hyperdex :: region :: put(const e::buffer& key,
                          const std::vector<e::buffer>& value,
                          uint64_t version)
{
    uint64_t key_hash = CityHash64(key);
    std::vector<uint64_t> value_hashes;
    get_value_hashes(value, &value_hashes);
    uint64_t point = get_point_for(key_hash, value_hashes);

    if (value.size() + 1 != m_numcolumns)
    {
        return INVALID;
    }
    else if (m_log.append(point, key, key_hash, value, value_hashes, version))
    {
        return SUCCESS;
    }
    else
    {
        LOG(INFO) << "Could not append to in-memory WAL.";
        return ERROR;
    }
}

hyperdex :: result_t
hyperdex :: region :: del(const e::buffer& key)
{
    uint64_t key_hash = CityHash64(key);
    uint64_t point = get_point_for(key_hash);

    if (m_log.append(point, key, key_hash))
    {
        return SUCCESS;
    }
    else
    {
        LOG(INFO) << "Could not append to in-memory WAL.";
        return ERROR;
    }
}

size_t
hyperdex :: region :: flush()
{
    using std::tr1::placeholders::_1;
    using std::tr1::placeholders::_2;
    using std::tr1::placeholders::_3;
    using std::tr1::placeholders::_4;
    using std::tr1::placeholders::_5;
    using std::tr1::placeholders::_6;
    using std::tr1::placeholders::_7;
    return m_log.flush(std::tr1::bind(&region::flush_one, this, _1, _2, _3, _4, _5, _6, _7));
}

void
hyperdex :: region :: flush_one(op_t op, uint64_t point, const e::buffer& key,
                                uint64_t key_hash,
                                const std::vector<e::buffer>& value,
                                const std::vector<uint64_t>& value_hashes,
                                uint64_t version)
{
    // XXX to prevent excessive failures, we should probably add some logic here
    // to block until a split occurs to resolve disk space issues.

    // Delete from every disk
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        // Use m_point_mask because we want every disk which could have this
        // key.
        uint64_t pmask = prefixmask(i->first.prefix) & m_point_mask;

        if ((i->first.mask & pmask) != (point & pmask))
        {
            continue;
        }

        result_t res = i->second->del(key, key_hash);

        if (res != SUCCESS && res != NOTFOUND)
        {
            // XXX FAIL DISK
            LOG(INFO) << "Disk has failed.";
        }
    }

    // Put to one disk
    if (op == PUT)
    {
        for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
        {
            uint64_t pmask = prefixmask(i->first.prefix);

            if ((i->first.mask & pmask) != (point & pmask))
            {
                continue;
            }

            result_t res = i->second->put(key, key_hash, value, value_hashes, version);

            if (res != SUCCESS)
            {
                // XXX FAIL DISK
                LOG(INFO) << "Disk has failed.";
            }
        }
    }
}

void
hyperdex :: region :: async()
{
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        i->second->async();
    }
}

void
hyperdex :: region :: sync()
{
    po6::threads::rwlock::rdhold hold(&m_rwlock);

    for (disk_vector::iterator i = m_disks.begin(); i != m_disks.end(); ++i)
    {
        i->second->sync();
    }
}

void
hyperdex :: region :: get_value_hashes(const std::vector<e::buffer>& value,
                                       std::vector<uint64_t>* value_hashes)
{
    for (size_t i = 0; i < value.size(); ++i)
    {
        value_hashes->push_back(CityHash64(value[i]));
    }
}

uint64_t
hyperdex :: region :: get_point_for(uint64_t key_hash)
{
    std::vector<uint64_t> points;
    points.push_back(key_hash);

    for (size_t i = 1; i < m_numcolumns; ++i)
    {
        points.push_back(0);
    }

    return interlace(points);
}

uint64_t
hyperdex :: region :: get_point_for(uint64_t key_hash, const std::vector<uint64_t>& value_hashes)
{
    std::vector<uint64_t> points;
    points.push_back(key_hash);

    for (size_t i = 0; i < value_hashes.size(); ++i)
    {
        points.push_back(value_hashes[i]);
    }

    return interlace(points);
}
<|endoftext|>


<commit_before><commit_msg>removed unnecessary root solving call<commit_after><|endoftext|>


<commit_before>#include "multiply.decl.h"
#include "messages.h"
#include "timer.h"
#include "utilities.h"

#include <getopt.h>

class Multiply : public CBase_Multiply
{
  public:

    Multiply (CkArgMsg *msg)
    {
      int N = 1;
      int chunksize = 1;

      int c;
      char shortoptions[] = "hN:c:";
      option longoptions[] = {
        { "help",   no_argument,        NULL, 'h' },
        { "N",      required_argument,  NULL, 'N' },
        { "chunk",  required_argument,  NULL, 'c' },
        { NULL, 0, NULL, 0 }
      };

      while((c = getopt_long(msg->argc, msg->argv, shortoptions, longoptions, NULL)) != -1)
      {
        switch(c)
        {
          case 'h':
            CkPrintf("Usage:\n");
            CkPrintf("\n");
            CkPrintf("{ -h | --help }     This help\n");
            CkPrintf("-N N                Set the matrix size to NxN\n");
            CkPrintf("{ -c | --chunk } N  Set the chunk size to NxN\n");
            CkExit();
            break;

          case 'N':
            N = strtol(optarg, NULL, 10);
            break;

          case 'c':
            chunksize = strtol(optarg, NULL, 10);
            break;

          default:
            CkPrintf("unknown option\n");
            CkExit();
            break;
        }
      }

      thisProxy.run(N, chunksize);
    }

    void run (int N, int chunksize)
    {
      EmptyMsg *m;
      CProxy_Matrix A;
      CProxy_Matrix C;

      /* Done reading command line. */
      LOG_INFO("starting...\n");

      /* Create new matrix. */
      A = CProxy_Matrix::ckNew(N, chunksize);
      C = CProxy_Matrix::ckNew();

      /* Create timer. */
      timer timestamp = timer();

      /* Create random matrix of size N. */
      timestamp.start();
      for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++)
        {
          float aij = rand()/(float) RAND_MAX;
          LOG_DEBUG("setting matrix element A(%d,%d) <- %f\n", i, j, aij);
          m = A.set(i, j, aij); delete m;
        }
      }
      LOG_INFO("done setting matrix, %f seconds\n", timestamp.stop());

      /* Print matrix for debugging. */
      //LOG_INFO("printing A\n");
      //m = A.print(); delete m;

      /* Form matrix square. */
      timestamp.start();
      m = thisProxy.multiply(A, A, C); delete m;
      LOG_INFO("multiply took %f seconds\n", timestamp.stop());

      /* Print result. */
      //LOG_INFO("printing C <- A*A\n");
      //m = C.print(); delete m;

      /* Done. */
      CkExit();
    }

    /** Multiply two matrices and store the produce in a third one, @f$ C
     * \leftarrow A \times B @f$. The result matrix C is overwritten.
     *
     * @param A The matrix A.
     * @param B The matrix B.
     * @param C The matrix C.
     */
    EmptyMsg * multiply (CProxy_Matrix A, CProxy_Matrix B, CProxy_Matrix C)
    {
      EmptyMsg *m;

      IntMsg *N_A = A.getN();
      IntMsg *N_B = B.getN();

      if(N_A->i != N_B->i)
      {
        LOG_ERROR("mismatch in matrix dimensions\n");
        return new EmptyMsg;
      }

      IntMsg *chunksize_A = A.getChunksize();

      /* Delete C matrix. */
      LOG_DEBUG("Setting C to zero\n");
      m = C.remove(); delete m;

      /* Initialize C. */
      m = C.initialize(N_A->i, chunksize_A->i); delete m;

      delete N_A;
      delete N_B;
      delete chunksize_A;

      /* Multiply matrices. */
      LOG_DEBUG("multiplying\n");
      m = C.multiply(A, B); delete m;

      return new EmptyMsg;
    }
};

#include "multiply.def.h"
<commit_msg>Added matrix product validation.<commit_after>#include "multiply.decl.h"
#include "messages.h"
#include "timer.h"
#include "utilities.h"

#include <getopt.h>

#define TOLERANCE 1e-8

class Multiply : public CBase_Multiply
{
  public:

    Multiply (CkArgMsg *msg)
    {
      int N = 1;
      int chunksize = 1;

      int c;
      char shortoptions[] = "hN:c:";
      option longoptions[] = {
        { "help",   no_argument,        NULL, 'h' },
        { "N",      required_argument,  NULL, 'N' },
        { "chunk",  required_argument,  NULL, 'c' },
        { NULL, 0, NULL, 0 }
      };

      while((c = getopt_long(msg->argc, msg->argv, shortoptions, longoptions, NULL)) != -1)
      {
        switch(c)
        {
          case 'h':
            CkPrintf("Usage:\n");
            CkPrintf("\n");
            CkPrintf("{ -h | --help }     This help\n");
            CkPrintf("-N N                Set the matrix size to NxN\n");
            CkPrintf("{ -c | --chunk } N  Set the chunk size to NxN\n");
            CkExit();
            break;

          case 'N':
            N = strtol(optarg, NULL, 10);
            break;

          case 'c':
            chunksize = strtol(optarg, NULL, 10);
            break;

          default:
            CkPrintf("unknown option\n");
            CkExit();
            break;
        }
      }

      thisProxy.run(N, chunksize);
    }

    void run (int N, int chunksize)
    {
      EmptyMsg *m;
      float ADense[N*N];
      float CDense[N*N];
      CProxy_Matrix A;
      CProxy_Matrix C;

      /* Done reading command line. */
      LOG_INFO("starting...\n");

      /* Create new matrix. */
      A = CProxy_Matrix::ckNew(N, chunksize);
      C = CProxy_Matrix::ckNew();

      /* Create timer. */
      timer timestamp = timer();

      /* Create random matrix of size N. */
      timestamp.start();
      for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++)
        {
          ADense[i*N+j] = rand()/(float) RAND_MAX;
          LOG_DEBUG("setting matrix element A(%d,%d) <- %f\n", i, j, ADense[i*N+j]);
          m = A.set(i, j, ADense[i*N+j]); delete m;
        }
      }
      LOG_INFO("done setting matrix, %f seconds\n", timestamp.stop());

      /* Print matrix for debugging. */
      //LOG_INFO("printing A\n");
      //m = A.print(); delete m;

      /* Form matrix square. */
      timestamp.start();
      m = thisProxy.multiply(A, A, C); delete m;
      LOG_INFO("multiply took %f seconds\n", timestamp.stop());

      /* Print result. */
      //LOG_INFO("printing C <- A*A\n");
      //m = C.print(); delete m;

      for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++)
        {
          CDense[i*N+j] = 0;
          for(int k = 0; k < N; k++)
          {
            CDense[i*N+j] += ADense[i*N+k]*ADense[k*N+j];
          }
          FloatMsg *aij = C.get(i, j);
          if(fabs(CDense[i*N+j]-aij->a) > TOLERANCE)
          {
            CkPrintf("validation failed, C(%d,%d): %e <-> %e\n",
                i, j, CDense[i*N+j], aij->a);
            CkExit();
          }
        }
      }
      CkPrintf("result validated\n");

      /* Done. */
      CkExit();
    }

    /** Multiply two matrices and store the produce in a third one, @f$ C
     * \leftarrow A \times B @f$. The result matrix C is overwritten.
     *
     * @param A The matrix A.
     * @param B The matrix B.
     * @param C The matrix C.
     */
    EmptyMsg * multiply (CProxy_Matrix A, CProxy_Matrix B, CProxy_Matrix C)
    {
      EmptyMsg *m;

      IntMsg *N_A = A.getN();
      IntMsg *N_B = B.getN();

      if(N_A->i != N_B->i)
      {
        LOG_ERROR("mismatch in matrix dimensions\n");
        return new EmptyMsg;
      }

      IntMsg *chunksize_A = A.getChunksize();

      /* Delete C matrix. */
      LOG_DEBUG("Setting C to zero\n");
      m = C.remove(); delete m;

      /* Initialize C. */
      m = C.initialize(N_A->i, chunksize_A->i); delete m;

      delete N_A;
      delete N_B;
      delete chunksize_A;

      /* Multiply matrices. */
      LOG_DEBUG("multiplying\n");
      m = C.multiply(A, B); delete m;

      return new EmptyMsg;
    }
};

#include "multiply.def.h"
<|endoftext|>