<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.

// This is a file for random testcases that we run into that at one point or
// another have crashed the program.

#include "chrome/test/ui/ui_test.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/platform_thread.h"
#include "chrome/common/chrome_switches.h"
#include "net/base/net_util.h"

class GoogleTest : public UITest {
 protected:
  GoogleTest() : UITest() {
    FilePath test_file =
        test_data_directory_.AppendASCII("google").AppendASCII("google.html");
    homepage_ = GURL(net::FilePathToFileURL(test_file)).spec();
  }
};

TEST_F(GoogleTest, Crash) {
  std::wstring page_title = L"Google";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

class ColumnLayout : public UITest {
 protected:
  ColumnLayout() : UITest() {
    FilePath test_file = test_data_directory_.AppendASCII("columns.html");
    homepage_ = GURL(net::FilePathToFileURL(test_file)).spec();
  }
};

TEST_F(ColumnLayout, Crash) {
  std::wstring page_title = L"Column test";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

// By passing kTryChromeAgain with a magic value > 10000 we cause chrome
// to exit fairly early. This was the cause of crashes. See bug 34799.
class EarlyReturnTest : public UITest {
 public:
  EarlyReturnTest() {
    wait_for_initial_loads_ = false;
    launch_arguments_.AppendSwitchASCII(switches::kTryChromeAgain, "10001");
  }
};

// Flaky: http://crbug.com/45115
TEST_F(EarlyReturnTest, FLAKY_ToastCrasher) {
  // UITest will check if this crashed.
}
<commit_msg>ui_tests: disable EarlyReturnTest.<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.

// This is a file for random testcases that we run into that at one point or
// another have crashed the program.

#include "chrome/test/ui/ui_test.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/platform_thread.h"
#include "chrome/common/chrome_switches.h"
#include "net/base/net_util.h"

class GoogleTest : public UITest {
 protected:
  GoogleTest() : UITest() {
    FilePath test_file =
        test_data_directory_.AppendASCII("google").AppendASCII("google.html");
    homepage_ = GURL(net::FilePathToFileURL(test_file)).spec();
  }
};

TEST_F(GoogleTest, Crash) {
  std::wstring page_title = L"Google";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

class ColumnLayout : public UITest {
 protected:
  ColumnLayout() : UITest() {
    FilePath test_file = test_data_directory_.AppendASCII("columns.html");
    homepage_ = GURL(net::FilePathToFileURL(test_file)).spec();
  }
};

TEST_F(ColumnLayout, Crash) {
  std::wstring page_title = L"Column test";

  // Make sure the navigation succeeded.
  EXPECT_EQ(page_title, GetActiveTabTitle());

  // UITest will check if this crashed.
}

// By passing kTryChromeAgain with a magic value > 10000 we cause Chrome
// to exit fairly early.
// Quickly exiting Chrome (regardless of this particular flag -- it
// doesn't do anything other than cause Chrome to quit on startup on
// non-Windows) was a cause of crashes (see bug 34799 for example) so
// this is a useful test of the startup/quick-shutdown cycle.
class EarlyReturnTest : public UITest {
 public:
  EarlyReturnTest() {
    wait_for_initial_loads_ = false;  // Don't wait for any pages to load.
    launch_arguments_.AppendSwitchASCII(switches::kTryChromeAgain, "10001");
  }
};

// Disabled: http://crbug.com/45115
// Due to limitations in our test infrastructure, this test currently doesn't
// work.
TEST_F(EarlyReturnTest, DISABLED_ToastCrasher) {
  // UITest will check if this crashed.
}
<|endoftext|>


<commit_before><commit_msg>Fix chrome frame build.<commit_after><|endoftext|>


<commit_before>#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>
#include <iostream>

#include "../../include/Helper/fileUtils.h"

std::vector<std::string>* Helper::readLinesFromFile(std::ifstream& inFromFile)
{
    std::vector<std::string>* returnStrings = new std::vector<std::string>();

    std::string curLine;
    while(std::getline(inFromFile, curLine))
    {
        returnStrings->push_back(curLine);
    }

    return returnStrings;

}

void Helper::stripBrackets(std::string &stripString)
{
    std::string retString;

    for(int i = 0; i < stripString.length(); i++)
    {
        if(stripString.at(i) == '[' || stripString.at(i) == ']')
            continue;
        else
            retString += stripString.at(i);
    }

    stripString = retString;
}

std::vector<int>* Helper::csvToInt(std::string &convertString)
{
    std::vector<int>* returnVector = new std::vector<int>();
    const char *cstrConvertString = convertString.c_str();

    char* tmpString = strtok((char*)cstrConvertString, " ,");
    while(tmpString != NULL)
    {
        int tmp = atoi(tmpString);
        returnVector->push_back(tmp);
        tmpString = strtok(NULL, " ,");
    }

    return returnVector;
}

std::vector<std::vector<int>*>* Helper::processMSSFile(std::ifstream &inStream)
{
    std::vector<std::vector<int>*>* convertedLines = new std::vector<std::vector<int>*>();
    std::vector<std::string>* MSSFileLines = Helper::readLinesFromFile(inStream);

    for(int i = 0; i < MSSFileLines->size(); i++)
    {
        Helper::stripBrackets(MSSFileLines->at(i));
        convertedLines->push_back(Helper::csvToInt(MSSFileLines->at(i)));
    }

    return convertedLines;
}

void Helper::WriteResultsToFile(std::ofstream &outStream, std::vector<int>& results, int start, int end, int total)
{
    outStream << "[";
    for(int i = 0; i < results.size() - 1; i++)
        outStream << results.at(i) << ", ";
    outStream << results.at(results.size() - 1) << "]" << std::endl;

    outStream << "[";
    for(int i = start; i < end; i++)
        outStream << results.at(i) << ", ";
    outStream << results.at(end) << ']' << std::endl;
    outStream << total << std::endl;
}
<commit_msg>Fix some unsigned warnings in fileUtils<commit_after>#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>
#include <iostream>

#include "../../include/Helper/fileUtils.h"

std::vector<std::string>* Helper::readLinesFromFile(std::ifstream& inFromFile)
{
    std::vector<std::string>* returnStrings = new std::vector<std::string>();

    std::string curLine;
    while(std::getline(inFromFile, curLine))
    {
        returnStrings->push_back(curLine);
    }

    return returnStrings;

}

void Helper::stripBrackets(std::string &stripString)
{
    std::string retString;

    for(int i = 0; i < stripString.length(); i++)
    {
        if(stripString.at((unsigned)i) == '[' || stripString.at((unsigned)i) == ']')
            continue;
        else
            retString += stripString.at((unsigned)i);
    }

    stripString = retString;
}

std::vector<int>* Helper::csvToInt(std::string &convertString)
{
    std::vector<int>* returnVector = new std::vector<int>();
    const char *cstrConvertString = convertString.c_str();

    char* tmpString = strtok((char*)cstrConvertString, " ,");
    while(tmpString != NULL)
    {
        int tmp = atoi(tmpString);
        returnVector->push_back(tmp);
        tmpString = strtok(NULL, " ,");
    }

    return returnVector;
}

std::vector<std::vector<int>*>* Helper::processMSSFile(std::ifstream &inStream)
{
    std::vector<std::vector<int>*>* convertedLines = new std::vector<std::vector<int>*>();
    std::vector<std::string>* MSSFileLines = Helper::readLinesFromFile(inStream);

    for(int i = 0; i < MSSFileLines->size(); i++)
    {
        Helper::stripBrackets(MSSFileLines->at(i));
        convertedLines->push_back(Helper::csvToInt(MSSFileLines->at(i)));
    }

    return convertedLines;
}

void Helper::WriteResultsToFile(std::ofstream &outStream, std::vector<int>& results, int start, int end, int total)
{
    outStream << "[";
    for(int i = 0; i < results.size() - 1; i++)
        outStream << results.at((unsigned)i) << ", ";
    outStream << results.at(results.size() - 1) << "]" << std::endl;

    outStream << "[";
    for(int i = start; i < end; i++)
        outStream << results.at((unsigned)i) << ", ";
    outStream << results.at((unsigned)end) << ']' << std::endl;
    outStream << total << std::endl;
}
<|endoftext|>


<commit_before>/**************************************************************************

The MIT License (MIT)

Copyright (c) 2017 Dmitry Sovetov

https://github.com/dmsovetov

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

**************************************************************************/

#include "Dto.h"
#include <cassert>
#include <memory.h>

DTO_BEGIN

// ------------------------------------------------------ Dto ------------------------------------------------------ //

// ** Dto::Dto
Dto::Dto()
	: m_data(0)
	, m_capacity(0)
{
}

// ** Dto::Dto
Dto::Dto(byte* data, int32 capacity)
	: m_data(data)
	, m_capacity(capacity)
{
	assert(capacity >= 0);
	assert(data != 0);
}

// ** Dto::operator bool
Dto::operator bool() const
{
	return m_capacity > 0 && m_data != 0;
}

// ** Dto::capacity
int32 Dto::capacity() const
{
	return m_capacity;
}

// ** Dto::length
int32 Dto::length() const
{
	return *reinterpret_cast<const int32*>(m_data);
}

// ** Dto::data
const byte* Dto::data() const
{
	return m_data;
}

// ** Dto::data
byte* Dto::data()
{
	return m_data;
}

// ** Dto::iter
DtoIter Dto::iter() const
{
	return DtoIter(m_data + sizeof(int32), m_capacity);
}

// ---------------------------------------------------- DtoIter ---------------------------------------------------- //

// ** DtoIter::DtoIter
DtoIter::DtoIter(const byte* input, int32 length)
	: m_input(input)
	, m_length(length)
	, m_type(DtoEnd)
{
	memset(&m_key, 0, sizeof(m_key));
	memset(&m_value, 0, sizeof(m_value));
}

// ** DtoIter::next
bool DtoIter::next()
{
	// Decode next entry from an input stream.
	DtoByteBufferInput input(m_input, m_length);
	m_input += BinaryDtoReader::decode(input, m_key, m_value);

	// Skip a nested DTO body
	if (m_value.type == DtoKeyValue || m_value.type == DtoSequence)
	{
		m_input += m_value.binary.length - sizeof(int32);
	}

	bool isValid = m_value.type != DtoEnd;

	return isValid;
}

// ** DtoIter::type
DtoValueType DtoIter::type() const
{
	return m_type;
}

// ** DtoIter::key
const DtoStringView& DtoIter::key() const
{
	return m_key;
}

// ** DtoIter::toBool
bool DtoIter::toBool() const
{
	assert(m_type == DtoBool);
	return m_value.boolean;
}

// ** DtoIter::toString
const DtoStringView& DtoIter::toString() const
{
	assert(m_type == DtoString);
	return m_value.string;
}

// ** DtoIter::toInt32
int32 DtoIter::toInt32() const
{
	assert(m_type == DtoInt32);
	return m_value.int32;
}

// ** DtoIter::toDouble
double DtoIter::toDouble() const
{
	assert(m_type == DtoDouble);
	return m_value.number;
}

DTO_END<commit_msg>Fixed: Dto::length method<commit_after>/**************************************************************************

The MIT License (MIT)

Copyright (c) 2017 Dmitry Sovetov

https://github.com/dmsovetov

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

**************************************************************************/

#include "Dto.h"
#include <cassert>
#include <memory.h>

DTO_BEGIN

// ------------------------------------------------------ Dto ------------------------------------------------------ //

// ** Dto::Dto
Dto::Dto()
	: m_data(0)
	, m_capacity(0)
{
}

// ** Dto::Dto
Dto::Dto(byte* data, int32 capacity)
	: m_data(data)
	, m_capacity(capacity)
{
	assert(capacity >= 0);
	assert(data != 0);
}

// ** Dto::operator bool
Dto::operator bool() const
{
	return m_capacity > 0 && m_data != 0;
}

// ** Dto::capacity
int32 Dto::capacity() const
{
	return m_capacity;
}

// ** Dto::length
int32 Dto::length() const
{
	if (m_data)
	{
		return *reinterpret_cast<const int32*>(m_data);
	}

	return 0;
}

// ** Dto::data
const byte* Dto::data() const
{
	return m_data;
}

// ** Dto::data
byte* Dto::data()
{
	return m_data;
}

// ** Dto::iter
DtoIter Dto::iter() const
{
	return DtoIter(m_data + sizeof(int32), m_capacity);
}

// ---------------------------------------------------- DtoIter ---------------------------------------------------- //

// ** DtoIter::DtoIter
DtoIter::DtoIter(const byte* input, int32 length)
	: m_input(input)
	, m_length(length)
	, m_type(DtoEnd)
{
	memset(&m_key, 0, sizeof(m_key));
	memset(&m_value, 0, sizeof(m_value));
}

// ** DtoIter::next
bool DtoIter::next()
{
	// Decode next entry from an input stream.
	DtoByteBufferInput input(m_input, m_length);
	m_input += BinaryDtoReader::decode(input, m_key, m_value);

	// Skip a nested DTO body
	if (m_value.type == DtoKeyValue || m_value.type == DtoSequence)
	{
		m_input += m_value.binary.length - sizeof(int32);
	}

	bool isValid = m_value.type != DtoEnd;

	return isValid;
}

// ** DtoIter::type
DtoValueType DtoIter::type() const
{
	return m_type;
}

// ** DtoIter::key
const DtoStringView& DtoIter::key() const
{
	return m_key;
}

// ** DtoIter::toBool
bool DtoIter::toBool() const
{
	assert(m_type == DtoBool);
	return m_value.boolean;
}

// ** DtoIter::toString
const DtoStringView& DtoIter::toString() const
{
	assert(m_type == DtoString);
	return m_value.string;
}

// ** DtoIter::toInt32
int32 DtoIter::toInt32() const
{
	assert(m_type == DtoInt32);
	return m_value.int32;
}

// ** DtoIter::toDouble
double DtoIter::toDouble() const
{
	assert(m_type == DtoDouble);
	return m_value.number;
}

DTO_END<|endoftext|>


<commit_before>// -*- mode: c++ , coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012, 2013  Mattias Andrée (maandree@kth.se)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "InventoryExaminor.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  #define  __store_tty()		       \
    struct termios saved_stty;                 \
    struct termios stty;                       \
    tcgetattr(STDIN_FILENO, &saved_stty);      \
    tcgetattr(STDIN_FILENO, &stty);            \
    stty.c_lflag &= ~(ICANON | ECHO | ISIG);   \
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty)

  #define __restore_tty()  \
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)

  #define  ESC  "\033"  /* since \e generates a non-ISO-standard warning */
  #define  CSI  ESC "["

  /**
   * Construction
   */
  InventoryExaminor::InventoryExaminor()
  {
    // Do nothing
  }

  /**
   * Destructor
   */
  InventoryExaminor::~InventoryExaminor()
  {
    // Do nothing
  }

  /**
   * Examine a characters inventory
   *
   * @param  character   The index of the active character
   * @param  characters  The party members
   */
  void InventoryExaminor::examine(long character, std::vector<GameCharacter*>* characters) const
  {
    #define __print(X, Y)					\
      std::cout << (i == index ? CSI "02m" : "")		\
		<< X						\
		<< (Y == nullptr ? "(empty)" : Y->name);	\
      if ((Y != nullptr) && (Y->quantity_limit > 1))		\
	std::cout << " (" << Y->quantity << ")";        	\
      std::cout << CSI "22m" << std::endl

    __store_tty();

    std::cout << CSI "?25l";

    Item* hand = nullptr;
    size_t page = 0, index = 0;

    Inventory& inventory = (*(characters))[character]->character->record.inventory;
    std::vector<Item*>& personal = inventory.personal;
    std::vector<Item*>& ground = (*(characters))[character]->area->items;

    char c;
    bool reading = true;

    while (reading)
      {
	std::flush(std::cout);
	if (read(STDIN_FILENO, &c, 1) <= 0)
	  c = CTRL('G');

	bool readinginner = true;
	while (readinginner)
	  {
	    readinginner = false;
	    switch (c)
	      {
	      case '\033':
		if (read(STDIN_FILENO, &c, 1) <= 0)
		  break;
		if (c == 'O')
		  {
		    read(STDIN_FILENO, &c, 1);
		    switch (c)
		      {
		      case 'P':
			c = '1';
			readinginner = true;
			break;
		      case 'Q':
			c = '2';
			readinginner = true;
			break;
		      case 'R':
			c = '3';
			readinginner = true;
			break;
		      }
		  }
		else if (c == '[')
		  {
		    read(STDIN_FILENO, &c, 1);
		    if (c == '1')
		      {
			switch (c)
			  {
			  case '1':
			  case '2':
			  case '3':
			    readinginner = true;
			    break;
			  }
			read(STDIN_FILENO, &c, 1);
			if (c != '~')
			  readinginner = false;
		      }
		    else if ((c == 'A') || (c == 'B'))
		      {
			c = CTRL((c == 'A' ? 'P' : 'N'));
			readinginner = true;
		      }
		  }
		break;

	      case '1': /* Equipped items */
	      case '2': /* Personal inventory */
	      case '3': /* Item on the ground */
		page = c - '1';
		index = 0;
		index++;
	      case CTRL('P'): /* Navigate up */ /* XXX this could be speed up */
		index -= 2;
	      case CTRL('N'): /* Navigate down */
		index++;
		if (index < 0)
		  index = 0;
		else
		  {
		    size_t n = page == 2 ? ground.size() + 1
			     : page = 1 ? personal.size()
			     : inventory.left_hand.size() + inventory.quiver.size()
			     + inventory.quick_items.size() + inventory.rings.size() + 8;
		    if (index >= n)
		      index = n - 1;
		  }
	      case CTRL('L'): /* Redraw */
		std::cout << CSI "H" CSI "2J"
			  << "Temporary slot: "
			  << (hand == nullptr ? "(empty)" : hand->name);
		if ((hand != nullptr) && (hand->quantity_limit > 1))
		  std::cout << " (" << hand->quantity << ")";
		std::cout << std::endl << std::endl;
		if (page == 0)
		  {
		    size_t i = 0;
		    for (size_t j = 0, n = inventory.left_hand.size(); j < n; j++)
		      {
			__print("Left hand " << j << " ", inventory.left_hand[j]); i++;
		      }
		    for (size_t j = 0, n = inventory.quiver.size(); j < n; j++)
		      {
			__print("Quiver " << j << "    ", inventory.quiver[j]); i++;
		      }
		    for (size_t j = 0, n = inventory.quick_items.size(); j < n; j++)
		      {
			__print("Quick item " << j << "", inventory.quick_items[j]); i++;
		      }
		    __print("Right hand  ", inventory.right_hand); i++;
		    __print("Headgear    ", inventory.headgear); i++;
		    __print("Amulet      ", inventory.amulet); i++;
		    for (size_t j = 0, n = inventory.rings.size(); j < n; j++)
		      {
			__print("Ring " << j << "      ", inventory.rings[j]); i++;
		      }
		    __print("Body        ", inventory.body); i++;
		    __print("Gauntlets   ", inventory.gauntlets); i++;
		    __print("Girdle      ", inventory.girdle); i++;
		    __print("Boots       ", inventory.boots); i++;
		    __print("Cloak       ", inventory.cloak); i++;
		  }
		else if (page == 1)
		  for (size_t i = 0, n = personal.size(); i < n; i++)
		    {
		      __print((i < 10 ? "Personal  " : "Personal ") << i, personal[i]);
		    }
		else if (page == 2)
		  {
		    for (size_t i = 0, n = ground.size(); i < n; i++)
		    {
		      __print("Ground " << i, ground[i]);
		    }
		    size_t i = ground.size();
		    __print("Ground " << i, nullptr);
		  }
		break;

	      /* XXX many things here gound be speed up */
	      case 'd': /* Drop temporary slot item on the ground */
		if (hand == nullptr)
		  break;
		ground.push_back(hand);
		hand = nullptr;
		readinginner = true;
		c = CTRL('L');
		break;

	      case 'D': /* Drop item on the ground */
		break;

	      case 'p': /* Pick up item to temporary slot */
		break;

	      case 's': /* Swap item with temporary slot */
		break;

	      case 'e': /* Examine item in slot */
		break;

	      case 'E': /* Examine item in temporary slot */
		break;

	      case 'P': /* Give item to another party member */
		break;

	      case CTRL('G'): /* Abort */
		if ((hand))
		  ground.push_back(hand);
		hand = nullptr;
	      case CTRL('D'): /* Complete */
		if (hand == nullptr)
		  reading = false;
		break;
	      }
	  }
      }

    std::flush(std::cout << CSI "?25l");

    __restore_tty();
    #undef __print
  }

}

<commit_msg>dropping some of the items to the ground<commit_after>// -*- mode: c++ , coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012, 2013  Mattias Andrée (maandree@kth.se)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "InventoryExaminor.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  #define  __store_tty()		       \
    struct termios saved_stty;                 \
    struct termios stty;                       \
    tcgetattr(STDIN_FILENO, &saved_stty);      \
    tcgetattr(STDIN_FILENO, &stty);            \
    stty.c_lflag &= ~(ICANON | ECHO | ISIG);   \
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty)

  #define __restore_tty()  \
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)

  #define  ESC  "\033"  /* since \e generates a non-ISO-standard warning */
  #define  CSI  ESC "["

  /**
   * Construction
   */
  InventoryExaminor::InventoryExaminor()
  {
    // Do nothing
  }

  /**
   * Destructor
   */
  InventoryExaminor::~InventoryExaminor()
  {
    // Do nothing
  }

  /**
   * Examine a characters inventory
   *
   * @param  character   The index of the active character
   * @param  characters  The party members
   */
  void InventoryExaminor::examine(long character, std::vector<GameCharacter*>* characters) const
  {
    #define __print(X, Y)					\
      std::cout << (i == index ? CSI "02m" : "")		\
		<< X						\
		<< (Y == nullptr ? "(empty)" : Y->name);	\
      if ((Y != nullptr) && (Y->quantity_limit > 1))		\
	std::cout << " (" << Y->quantity << ")";        	\
      std::cout << CSI "22m" << std::endl

    __store_tty();

    std::cout << CSI "?25l";

    Item* hand = nullptr;
    size_t page = 0, index = 0;

    Inventory& inventory = (*(characters))[character]->character->record.inventory;
    std::vector<Item*>& personal = inventory.personal;
    std::vector<Item*>& ground = (*(characters))[character]->area->items;

    char c;
    bool reading = true;

    while (reading)
      {
	std::flush(std::cout);
	if (read(STDIN_FILENO, &c, 1) <= 0)
	  c = CTRL('G');

	bool readinginner = true;
	while (readinginner)
	  {
	    readinginner = false;
	    switch (c)
	      {
	      case '\033':
		if (read(STDIN_FILENO, &c, 1) <= 0)
		  break;
		if (c == 'O')
		  {
		    read(STDIN_FILENO, &c, 1);
		    switch (c)
		      {
		      case 'P':
			c = '1';
			readinginner = true;
			break;
		      case 'Q':
			c = '2';
			readinginner = true;
			break;
		      case 'R':
			c = '3';
			readinginner = true;
			break;
		      }
		  }
		else if (c == '[')
		  {
		    read(STDIN_FILENO, &c, 1);
		    if (c == '1')
		      {
			switch (c)
			  {
			  case '1':
			  case '2':
			  case '3':
			    readinginner = true;
			    break;
			  }
			read(STDIN_FILENO, &c, 1);
			if (c != '~')
			  readinginner = false;
		      }
		    else if ((c == 'A') || (c == 'B'))
		      {
			c = CTRL((c == 'A' ? 'P' : 'N'));
			readinginner = true;
		      }
		  }
		break;

	      case '1': /* Equipped items */
	      case '2': /* Personal inventory */
	      case '3': /* Item on the ground */
		page = c - '1';
		index = 0;
		index++;
	      case CTRL('P'): /* Navigate up */ /* XXX this could be speed up */
		index -= 2;
	      case CTRL('N'): /* Navigate down */
		index++;
		if (index < 0)
		  index = 0;
		else
		  {
		    size_t n = page == 2 ? ground.size() + 1
			     : page = 1 ? personal.size()
			     : inventory.left_hand.size() + inventory.quiver.size()
			     + inventory.quick_items.size() + inventory.rings.size() + 8;
		    if (index >= n)
		      index = n - 1;
		  }
	      case CTRL('L'): /* Redraw */
		std::cout << CSI "H" CSI "2J"
			  << "Temporary slot: "
			  << (hand == nullptr ? "(empty)" : hand->name);
		if ((hand != nullptr) && (hand->quantity_limit > 1))
		  std::cout << " (" << hand->quantity << ")";
		std::cout << std::endl << std::endl;
		if (page == 0)
		  {
		    size_t i = 0;
		    for (size_t j = 0, n = inventory.left_hand.size(); j < n; j++)
		      {
			__print("Left hand " << j << " ", inventory.left_hand[j]); i++;
		      }
		    for (size_t j = 0, n = inventory.quiver.size(); j < n; j++)
		      {
			__print("Quiver " << j << "    ", inventory.quiver[j]); i++;
		      }
		    for (size_t j = 0, n = inventory.quick_items.size(); j < n; j++)
		      {
			__print("Quick item " << j << "", inventory.quick_items[j]); i++;
		      }
		    __print("Right hand  ", inventory.right_hand); i++;
		    __print("Headgear    ", inventory.headgear); i++;
		    __print("Amulet      ", inventory.amulet); i++;
		    for (size_t j = 0, n = inventory.rings.size(); j < n; j++)
		      {
			__print("Ring " << j << "      ", inventory.rings[j]); i++;
		      }
		    __print("Body        ", inventory.body); i++;
		    __print("Gauntlets   ", inventory.gauntlets); i++;
		    __print("Girdle      ", inventory.girdle); i++;
		    __print("Boots       ", inventory.boots); i++;
		    __print("Cloak       ", inventory.cloak); i++;
		  }
		else if (page == 1)
		  for (size_t i = 0, n = personal.size(); i < n; i++)
		    {
		      __print((i < 10 ? "Personal  " : "Personal ") << i, personal[i]);
		    }
		else if (page == 2)
		  {
		    for (size_t i = 0, n = ground.size(); i < n; i++)
		    {
		      __print("Ground " << i, ground[i]);
		    }
		    size_t i = ground.size();
		    __print("Ground " << i, nullptr);
		  }
		break;

	      /* XXX many things here gound be speed up */
	      case 'd': /* Drop temporary slot item on the ground */
		if (hand == nullptr)
		  break;
		ground.push_back(hand);
		hand = nullptr;
		readinginner = true;
		c = CTRL('L');
		break;

	      case 'D': /* Drop item on the ground */
		if ((page == 2) && (index < ground.size()))
		  {
		    ground.push_back(ground[index]);
		    ground.erase(index);
		    readinginner = true;
		    c = CTRL('L');
		  }
		else if ((page == 1) && (personal[index] != nullptr))
		  {
		    ground.push_back(personal[index]);
		    personal[index] = nullptr;
		    readinginner = true;
		    c = CTRL('L');
		  }
		else if (page == 0)
		  {
		    ;
		  }
		break;

	      case 'p': /* Pick up item to temporary slot */
		break;

	      case 's': /* Swap item with temporary slot */
		break;

	      case 'e': /* Examine item in slot */
		break;

	      case 'E': /* Examine item in temporary slot */
		break;

	      case 'P': /* Give item to another party member */
		break;

	      case CTRL('G'): /* Abort */
		if ((hand))
		  ground.push_back(hand);
		hand = nullptr;
	      case CTRL('D'): /* Complete */
		if (hand == nullptr)
		  reading = false;
		break;
	      }
	  }
      }

    std::flush(std::cout << CSI "?25l");

    __restore_tty();
    #undef __print
  }

}

<|endoftext|>


<commit_before>#include <unit_test/unit_test.h>

#include <systemlib/err.h>

#include <stdio.h>
#include <unistd.h>

#include <drivers/drv_hrt.h>

#define DSM_DEBUG
#include <lib/rc/sbus.h>
#include <lib/rc/dsm.h>
#include <lib/rc/st24.h>
#include <lib/rc/sumd.h>

#if !defined(CONFIG_ARCH_BOARD_SITL)
#define TEST_DATA_PATH "/fs/microsd"
#else
#define TEST_DATA_PATH "./test_data/"
#endif

extern "C" __EXPORT int rc_tests_main(int argc, char *argv[]);

class RCTest : public UnitTest
{
public:
	virtual bool run_tests(void);

private:
	bool dsmTest();
	bool sbus2Test();
	bool st24Test();
	bool sumdTest();
};

bool RCTest::run_tests(void)
{
	ut_run_test(dsmTest);
	ut_run_test(sbus2Test);
	ut_run_test(st24Test);
	ut_run_test(sumdTest);

	return (_tests_failed == 0);
}

bool RCTest::dsmTest(void)
{

	const char *filepath = TEST_DATA_PATH "dsm_x_data.txt";

	FILE *fp;
	fp = fopen(filepath, "rt");

	ut_test(fp != nullptr);
	//warnx("loading data from: %s", filepath);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	// Init the parser
	uint8_t frame[20];
	uint16_t rc_values[18];
	uint16_t num_values;
	bool dsm_11_bit;
	unsigned dsm_frame_drops = 0;
	uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);

	int rate_limiter = 0;
	unsigned last_drop = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {

		ut_test(ret > 0);

		frame[0] = x;
		unsigned len = 1;

		// Pipe the data into the parser
		bool result = dsm_parse(f * 1e6f, &frame[0], len, rc_values, &num_values,
					&dsm_11_bit, &dsm_frame_drops, max_channels);

		if (result) {
			//warnx("decoded packet with %d channels and %s encoding:", num_values, (dsm_11_bit) ? "11 bit" : "10 bit");

			for (unsigned i = 0; i < num_values; i++) {
				//printf("chan #%u:\t%d\n", i, (int)rc_values[i]);
			}
		}

		if (last_drop != (dsm_frame_drops)) {
			//warnx("frame dropped, now #%d", (dsm_frame_drops));
			last_drop = dsm_frame_drops;
		}

		rate_limiter++;
	}

	ut_test(ret == EOF);

	return true;
}

bool RCTest::sbus2Test(void)
{
	const char *filepath = TEST_DATA_PATH "sbus2_r7008SB.txt";

	FILE *fp;
	fp = fopen(filepath, "rt");

	ut_test(fp != nullptr);
	//warnx("loading data from: %s", filepath);

	// if (argc < 2)
	// 	errx(1, "Need a filename for the input file");

	//int byte_offset = 7;

	// if (argc > 2) {
	// 	char* end;
	// 	byte_offset = strtol(argv[2],&end,10);
	// }

	//warnx("RUNNING TEST WITH BYTE OFFSET OF: %d", byte_offset);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	// Init the parser
	uint8_t frame[SBUS_BUFFER_SIZE];
	uint16_t rc_values[18];
	uint16_t num_values;
	unsigned sbus_frame_drops = 0;
	unsigned sbus_frame_resets = 0;
	bool sbus_failsafe;
	bool sbus_frame_drop;
	uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);

	int rate_limiter = 0;
	unsigned last_drop = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {

		ut_test(ret > 0);

		frame[0] = x;
		unsigned len = 1;

		// Pipe the data into the parser
		hrt_abstime now = hrt_absolute_time();

		// if (rate_limiter % byte_offset == 0) {
		bool result = sbus_parse(now, &frame[0], len, rc_values, &num_values,
					 &sbus_failsafe, &sbus_frame_drop, &sbus_frame_drops, max_channels);

		if (result) {
			//warnx("decoded packet");
		}

		// }

		if (last_drop != (sbus_frame_drops + sbus_frame_resets)) {
			warnx("frame dropped, now #%d", (sbus_frame_drops + sbus_frame_resets));
			last_drop = sbus_frame_drops + sbus_frame_resets;
		}

		rate_limiter++;
	}

	ut_test(ret == EOF);

	return true;
}

bool RCTest::st24Test(void)
{
	const char *filepath = TEST_DATA_PATH "st24_data.txt";

	//warnx("loading data from: %s", filepath);

	FILE *fp;

	fp = fopen(filepath, "rt");
	ut_test(fp != nullptr);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		ut_test(ret > 0);

		if (((f - last_time) * 1000 * 1000) > 3000) {
			// warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		//hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		uint16_t channels[20];

		if (!st24_decode(b, &rssi, &rx_count, &channel_count, channels, sizeof(channels) / sizeof(channels[0]))) {
			//warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);

			for (unsigned i = 0; i < channel_count; i++) {
				//int16_t val = channels[i];
				//warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
		}
	}

	ut_test(ret == EOF);

	return true;
}

bool RCTest::sumdTest(void)
{
	const char *filepath = TEST_DATA_PATH "sumd_data.txt";

	//warnx("loading data from: %s", filepath);

	FILE *fp;

	fp = fopen(filepath, "rt");
	ut_test(fp != nullptr);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		ut_test(ret > 0);

		if (((f - last_time) * 1000 * 1000) > 3000) {
			// warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		//hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		uint16_t channels[32];

		if (!sumd_decode(b, &rssi, &rx_count, &channel_count, channels, 32)) {
			//warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);

			for (unsigned i = 0; i < channel_count; i++) {
				//int16_t val = channels[i];
				//warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
		}
	}

	ut_test(ret == EOF);

	return true;
}

ut_declare_test_c(rc_tests_main, RCTest)

<commit_msg>Expand RC test to 2nd receiver with 12 channels<commit_after>#include <unit_test/unit_test.h>

#include <systemlib/err.h>

#include <stdio.h>
#include <unistd.h>

#include <drivers/drv_hrt.h>

#define DSM_DEBUG
#include <lib/rc/sbus.h>
#include <lib/rc/dsm.h>
#include <lib/rc/st24.h>
#include <lib/rc/sumd.h>

#if !defined(CONFIG_ARCH_BOARD_SITL)
#define TEST_DATA_PATH "/fs/microsd"
#else
#define TEST_DATA_PATH "./test_data/"
#endif

extern "C" __EXPORT int rc_tests_main(int argc, char *argv[]);

class RCTest : public UnitTest
{
public:
	virtual bool run_tests(void);

private:
	bool dsmTest(const char *filepath, unsigned expected_chancount, unsigned expected_dropcount, unsigned chan0);
	bool dsmTest10Ch();
	bool dsmTest12Ch();
	bool sbus2Test();
	bool st24Test();
	bool sumdTest();
};

bool RCTest::run_tests(void)
{
	ut_run_test(dsmTest10Ch);
	ut_run_test(dsmTest12Ch);
	ut_run_test(sbus2Test);
	ut_run_test(st24Test);
	ut_run_test(sumdTest);

	return (_tests_failed == 0);
}

bool RCTest::dsmTest10Ch()
{
	return dsmTest(TEST_DATA_PATH "dsm_x_data.txt", 10, 6, 0);
}

bool RCTest::dsmTest12Ch()
{
	return dsmTest(TEST_DATA_PATH "dsm_x_dx9_data.txt", 12, 11, 1500);
}

bool RCTest::dsmTest(const char *filepath, unsigned expected_chancount, unsigned expected_dropcount, unsigned chan0)
{

	FILE *fp;
	fp = fopen(filepath, "rt");

	ut_test(fp != nullptr);
	//PX4_INFO("loading data from: %s", filepath);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	// Init the parser
	uint8_t frame[20];
	uint16_t rc_values[18];
	uint16_t num_values;
	bool dsm_11_bit;
	unsigned dsm_frame_drops = 0;
	uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);

	int rate_limiter = 0;
	unsigned last_drop = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {

		ut_test(ret > 0);

		frame[0] = x;
		unsigned len = 1;

		// Pipe the data into the parser
		bool result = dsm_parse(f * 1e6f, &frame[0], len, rc_values, &num_values,
					&dsm_11_bit, &dsm_frame_drops, max_channels);

		if (result) {
			ut_test(num_values == expected_chancount);

			if (chan0 > 0) {
				ut_test((chan0 - rc_values[0]) < 3);
			}

			//PX4_INFO("decoded packet with %d channels and %s encoding:", num_values, (dsm_11_bit) ? "11 bit" : "10 bit");

			for (unsigned i = 0; i < num_values; i++) {
				//PX4_INFO("chan #%u:\t%d", i, (int)rc_values[i]);
			}
		}

		if (last_drop != (dsm_frame_drops)) {
			//PX4_INFO("frame dropped, now #%d", (dsm_frame_drops));
			last_drop = dsm_frame_drops;
		}

		rate_limiter++;
	}

	ut_test(ret == EOF);
	PX4_INFO("drop: %d", (int)last_drop);
	ut_test(last_drop == expected_dropcount);

	return true;
}

bool RCTest::sbus2Test(void)
{
	const char *filepath = TEST_DATA_PATH "sbus2_r7008SB.txt";

	FILE *fp;
	fp = fopen(filepath, "rt");

	ut_test(fp != nullptr);
	//warnx("loading data from: %s", filepath);

	// if (argc < 2)
	// 	errx(1, "Need a filename for the input file");

	//int byte_offset = 7;

	// if (argc > 2) {
	// 	char* end;
	// 	byte_offset = strtol(argv[2],&end,10);
	// }

	//warnx("RUNNING TEST WITH BYTE OFFSET OF: %d", byte_offset);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	// Init the parser
	uint8_t frame[SBUS_BUFFER_SIZE];
	uint16_t rc_values[18];
	uint16_t num_values;
	unsigned sbus_frame_drops = 0;
	unsigned sbus_frame_resets = 0;
	bool sbus_failsafe;
	bool sbus_frame_drop;
	uint16_t max_channels = sizeof(rc_values) / sizeof(rc_values[0]);

	int rate_limiter = 0;
	unsigned last_drop = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {

		ut_test(ret > 0);

		frame[0] = x;
		unsigned len = 1;

		// Pipe the data into the parser
		hrt_abstime now = hrt_absolute_time();

		// if (rate_limiter % byte_offset == 0) {
		bool result = sbus_parse(now, &frame[0], len, rc_values, &num_values,
					 &sbus_failsafe, &sbus_frame_drop, &sbus_frame_drops, max_channels);

		if (result) {
			//warnx("decoded packet");
		}

		// }

		if (last_drop != (sbus_frame_drops + sbus_frame_resets)) {
			PX4_WARN("frame dropped, now #%d", (sbus_frame_drops + sbus_frame_resets));
			last_drop = sbus_frame_drops + sbus_frame_resets;
		}

		rate_limiter++;
	}

	ut_test(ret == EOF);

	return true;
}

bool RCTest::st24Test(void)
{
	const char *filepath = TEST_DATA_PATH "st24_data.txt";

	//warnx("loading data from: %s", filepath);

	FILE *fp;

	fp = fopen(filepath, "rt");
	ut_test(fp != nullptr);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		ut_test(ret > 0);

		if (((f - last_time) * 1000 * 1000) > 3000) {
			// warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		//hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		uint16_t channels[20];

		if (!st24_decode(b, &rssi, &rx_count, &channel_count, channels, sizeof(channels) / sizeof(channels[0]))) {
			//warnx("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);

			for (unsigned i = 0; i < channel_count; i++) {
				//int16_t val = channels[i];
				//warnx("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
		}
	}

	ut_test(ret == EOF);

	return true;
}

bool RCTest::sumdTest(void)
{
	const char *filepath = TEST_DATA_PATH "sumd_data.txt";

	//warnx("loading data from: %s", filepath);

	FILE *fp;

	fp = fopen(filepath, "rt");
	ut_test(fp != nullptr);

	float f;
	unsigned x;
	int ret;

	// Trash the first 20 lines
	for (unsigned i = 0; i < 20; i++) {
		char buf[200];
		(void)fgets(buf, sizeof(buf), fp);
	}

	float last_time = 0;

	while (EOF != (ret = fscanf(fp, "%f,%x,,", &f, &x))) {
		ut_test(ret > 0);

		if (((f - last_time) * 1000 * 1000) > 3000) {
			// warnx("FRAME RESET\n\n");
		}

		uint8_t b = static_cast<uint8_t>(x);

		last_time = f;

		// Pipe the data into the parser
		//hrt_abstime now = hrt_absolute_time();

		uint8_t rssi;
		uint8_t rx_count;
		uint16_t channel_count;
		uint16_t channels[32];

		if (!sumd_decode(b, &rssi, &rx_count, &channel_count, channels, 32)) {
			//PX4_INFO("decoded: %u channels (converted to PPM range)", (unsigned)channel_count);

			for (unsigned i = 0; i < channel_count; i++) {
				//int16_t val = channels[i];
				//PX4_INFO("channel %u: %d 0x%03X", i, static_cast<int>(val), static_cast<int>(val));
			}
		}
	}

	ut_test(ret == EOF);

	return true;
}

ut_declare_test_c(rc_tests_main, RCTest)

<|endoftext|>


<commit_before>/* Copyright (C) Teemu Suutari */

#include <array>

#include "LZCBDecompressor.hpp"
#include "RangeDecoder.hpp"
#include "InputStream.hpp"
#include "OutputStream.hpp"

template<size_t T>
class FrequencyTree
{
public:
	FrequencyTree()
	{
		for (uint32_t i=0;i<_size;i++)
			_tree[i]=0;
	}

	~FrequencyTree()
	{
		// nothing needed
	}

	uint16_t decode(uint16_t value,uint16_t &low,uint16_t &freq) const
	{
		if (value>=_tree[_size-1])
			throw Decompressor::DecompressionError();
		uint16_t symbol=0;
		low=0;
		for (uint32_t i=_levels-2;;i--)
		{
			uint16_t tmp=_tree[_levelOffsets[i]+symbol];
			if (uint32_t(symbol+1)<_levelSizes[i] && value>=tmp)
			{
				symbol++;
				low+=tmp;
				value-=tmp;
			}
			if (!i) break;
			symbol<<=1;
		}
		freq=_tree[symbol];
		return symbol;
	}

	bool exists(uint16_t symbol) const
	{
		return _tree[symbol];
	}

	void increment(uint16_t symbol)
	{
		for (uint16_t i=0;i<_levels;i++)
		{
			_tree[_levelOffsets[i]+symbol]++;
			symbol>>=1;
		}
	}

	void halve()
	{
		// non-standard way
		for (uint32_t i=0;i<T;i++)
			_tree[i]>>=1;
		for (uint32_t i=T;i<_size;i++)
			_tree[i]=0;
		for (uint32_t i=0,length=T;i<_levels-1;i++,length=(length+1)>>1)
		{
			for (uint32_t j=0;j<length;j++)
				_tree[_levelOffsets[i+1]+(j>>1)]+=_tree[_levelOffsets[i]+j];
		}
	}

	uint32_t getTotal() const
	{
		return _tree[_size-1];
	}

private:
	static constexpr uint32_t levelSize(uint32_t level)
	{
		uint32_t ret=T;
		for (uint32_t i=0;i<level;i++)
		{
			ret=(ret+1)>>1;
		}
		return ret;
	}

	static constexpr uint32_t levels()
	{
		uint32_t ret=0;
		while (levelSize(ret)!=1) ret++;
		return ret+1;
	}

	static constexpr uint32_t size()
	{
		uint32_t ret=0;
		for (uint32_t i=0;i<levels();i++)
			ret+=levelSize(i);
		return ret;
	}

	static constexpr uint32_t levelOffset(uint32_t level)
	{
		uint32_t ret=0;
		for (uint32_t i=0;i<level;i++)
			ret+=levelSize(i);
		return ret;
	}

	template<uint32_t... I>
	static constexpr auto makeLevelOffsetSequence(std::integer_sequence<uint32_t,I...>)
	{
		return std::integer_sequence<uint32_t,levelOffset(I)...>{};
	}

	template<uint32_t... I>
	static constexpr auto makeLevelSizeSequence(std::integer_sequence<uint32_t,I...>)
	{
		return std::integer_sequence<uint32_t,levelSize(I)...>{};
	}

	template<uint32_t... I>
	static constexpr std::array<uint32_t,sizeof...(I)> makeArray(std::integer_sequence<uint32_t,I...>)
	{
		return std::array<uint32_t,sizeof...(I)>{{I...}};
	}

	static constexpr uint32_t			_size=size();
	static constexpr uint32_t			_levels=levels();
	static constexpr std::array<uint32_t,levels()>	_levelOffsets=makeArray(makeLevelOffsetSequence(std::make_integer_sequence<uint32_t,levels()>{}));
	static constexpr std::array<uint32_t,levels()>	_levelSizes=makeArray(makeLevelSizeSequence(std::make_integer_sequence<uint32_t,levels()>{}));

	uint16_t					_tree[size()];
};

#if __cplusplus < 201703L
// difference on semantics on C++14 / C++17
template<size_t T>
constexpr std::array<uint32_t,FrequencyTree<T>::levels()> FrequencyTree<T>::_levelOffsets;

template<size_t T>
constexpr std::array<uint32_t,FrequencyTree<T>::levels()> FrequencyTree<T>::_levelSizes;
#endif

template<size_t T>
class FrequencyDecoder
{
public:
	FrequencyDecoder(RangeDecoder &decoder) :
		_decoder(decoder)
	{
		// nothing needed
	}

	~FrequencyDecoder()
	{
		// nothing needed
	}

	template<typename F>
	uint16_t decode(F readFunc)
	{
		uint16_t freq=0,symbol,value=_decoder.decode(_threshold+_tree.getTotal());
		if (value>=_threshold)
		{
			uint16_t low;
			symbol=_tree.decode(value-_threshold,low,freq);
			_decoder.scale(_threshold+low,_threshold+low+freq,_threshold+_tree.getTotal());
			if (freq==1 && _threshold>1)
				_threshold--;
		} else {
			_decoder.scale(0,_threshold,_threshold+_tree.getTotal());
			symbol=readFunc();
			// A bug in the encoder
			if (!symbol && _tree.exists(symbol)) symbol=T;
			_threshold++;
		}
		_tree.increment(symbol);
		if (_threshold+_tree.getTotal()>=0x3ffdU)
		{
			_tree.halve();
			_threshold=(_threshold>>1)+1;
		}
		return symbol;
	}

private:
	RangeDecoder					&_decoder;
	FrequencyTree<T+1>				_tree;
	uint16_t					_threshold=1;
};

bool LZCBDecompressor::detectHeaderXPK(uint32_t hdr) noexcept
{
	return hdr==FourCC("LZCB");
}

std::unique_ptr<XPKDecompressor> LZCBDecompressor::create(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify)
{
	return std::make_unique<LZCBDecompressor>(hdr,recursionLevel,packedData,state,verify);
}

LZCBDecompressor::LZCBDecompressor(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify) :
	XPKDecompressor(recursionLevel),
	_packedData(packedData)
{
	if (packedData.size()<2) throw Decompressor::InvalidFormatError();
}

LZCBDecompressor::~LZCBDecompressor()
{
	// nothing needed
}

const std::string &LZCBDecompressor::getSubName() const noexcept
{
	static std::string name="XPK-LZCB: LZ-compressor";
	return name;
}

void LZCBDecompressor::decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify)
{
	class BitReader : public RangeDecoder::BitReader
	{
	public:
		BitReader(ForwardInputStream &stream) :
			_reader(stream)
		{
			// nothing needed
		}

		virtual ~BitReader()
		{
			// nothing needed
		}

		virtual uint32_t readBit() override final
		{
			return _reader.readBitsBE32(1);
		}

		uint32_t readBits(uint32_t bitCount)
		{
			return _reader.readBitsBE32(bitCount);
		}

	private:
		MSBBitReader<ForwardInputStream>	_reader;
	};

	ForwardInputStream inputStream(_packedData,0,_packedData.size(),true);
	ForwardOutputStream outputStream(rawData,0,rawData.size());
	BitReader bitReader(inputStream);

	RangeDecoder rangeDecoder(bitReader,bitReader.readBits(16));

	// Ugly duplicates
	auto readByte=[&]()->uint16_t
	{
		uint16_t ret=rangeDecoder.decode(0x100U);
		rangeDecoder.scale(ret,ret+1,0x100U);
		return ret;
	};

	auto readCount=[&]()->uint16_t
	{
		uint16_t ret=rangeDecoder.decode(0x101U);
		rangeDecoder.scale(ret,ret+1,0x101U);
		return ret;
	};

	FrequencyDecoder<256> baseLiteralDecoder(rangeDecoder);
	FrequencyDecoder<257> repeatCountDecoder(rangeDecoder);
	FrequencyDecoder<257> literalCountDecoder(rangeDecoder);
	FrequencyDecoder<256> distanceDecoder(rangeDecoder);

	std::unique_ptr<FrequencyDecoder<256>> literalDecoders[256];

	uint8_t ch=baseLiteralDecoder.decode(readByte);
	outputStream.writeByte(ch);
	bool lastIsLiteral=true;
	while (!outputStream.eof())
	{
		uint32_t count=repeatCountDecoder.decode(readCount);
		if (count)
		{
			if (count==0x100U)
			{
				uint32_t tmp;
				do
				{
					tmp=readByte();
					count+=tmp;
				} while (tmp==0xffU);
			}
			count+=lastIsLiteral?5:4;

			uint32_t distance=distanceDecoder.decode(readByte)<<8;
			distance|=readByte();

			ch=outputStream.copy(distance,count);
			lastIsLiteral=false;
		} else {
			uint16_t literalCount;
			do
			{
				literalCount=literalCountDecoder.decode(readCount);
				if (!literalCount) throw Decompressor::DecompressionError();

				for (uint32_t i=0;i<literalCount;i++)
				{
					auto &literalDecoder=literalDecoders[ch];
					if (!literalDecoder) literalDecoder=std::make_unique<FrequencyDecoder<256>>(rangeDecoder);
					ch=literalDecoder->decode([&]()
					{
						return baseLiteralDecoder.decode(readByte);
					});
					outputStream.writeByte(ch);
				}
			} while (literalCount==0x100U);
			lastIsLiteral=true;
		}
	}
}

XPKDecompressor::Registry<LZCBDecompressor> LZCBDecompressor::_XPKregistration;
<commit_msg>MSVC support. Dropping c++14 compatibility<commit_after>/* Copyright (C) Teemu Suutari */

#include <array>

#include "LZCBDecompressor.hpp"
#include "RangeDecoder.hpp"
#include "InputStream.hpp"
#include "OutputStream.hpp"

template<size_t T>
class FrequencyTree
{
public:
	FrequencyTree()
	{
		for (uint32_t i=0;i<_size;i++)
			_tree[i]=0;
	}

	~FrequencyTree()
	{
		// nothing needed
	}

	uint16_t decode(uint16_t value,uint16_t &low,uint16_t &freq) const
	{
		if (value>=_tree[_size-1])
			throw Decompressor::DecompressionError();
		uint16_t symbol=0;
		low=0;
		for (uint32_t i=_levels-2;;i--)
		{
			uint16_t tmp=_tree[_levelOffsets[i]+symbol];
			if (uint32_t(symbol+1)<_levelSizes[i] && value>=tmp)
			{
				symbol++;
				low+=tmp;
				value-=tmp;
			}
			if (!i) break;
			symbol<<=1;
		}
		freq=_tree[symbol];
		return symbol;
	}

	bool exists(uint16_t symbol) const
	{
		return _tree[symbol];
	}

	void increment(uint16_t symbol)
	{
		for (uint16_t i=0;i<_levels;i++)
		{
			_tree[_levelOffsets[i]+symbol]++;
			symbol>>=1;
		}
	}

	void halve()
	{
		// non-standard way
		for (uint32_t i=0;i<T;i++)
			_tree[i]>>=1;
		for (uint32_t i=T;i<_size;i++)
			_tree[i]=0;
		for (uint32_t i=0,length=T;i<_levels-1;i++,length=(length+1)>>1)
		{
			for (uint32_t j=0;j<length;j++)
				_tree[_levelOffsets[i+1]+(j>>1)]+=_tree[_levelOffsets[i]+j];
		}
	}

	uint32_t getTotal() const
	{
		return _tree[_size-1];
	}

private:
	static constexpr uint32_t levelSize(uint32_t level)
	{
		uint32_t ret=T;
		for (uint32_t i=0;i<level;i++)
		{
			ret=(ret+1)>>1;
		}
		return ret;
	}

	static constexpr uint32_t levels()
	{
		uint32_t ret=0;
		while (levelSize(ret)!=1) ret++;
		return ret+1;
	}

	static constexpr uint32_t size()
	{
		uint32_t ret=0;
		for (uint32_t i=0;i<levels();i++)
			ret+=levelSize(i);
		return ret;
	}

	static constexpr uint32_t levelOffset(uint32_t level)
	{
		uint32_t ret=0;
		for (uint32_t i=0;i<level;i++)
			ret+=levelSize(i);
		return ret;
	}

	template<uint32_t... I>
	static constexpr auto makeLevelOffsetSequence(std::integer_sequence<uint32_t,I...>)
	{
		return std::integer_sequence<uint32_t,levelOffset(I)...>{};
	}

	template<uint32_t... I>
	static constexpr auto makeLevelSizeSequence(std::integer_sequence<uint32_t,I...>)
	{
		return std::integer_sequence<uint32_t,levelSize(I)...>{};
	}

	template<uint32_t... I>
	static constexpr std::array<uint32_t,sizeof...(I)> makeArray(std::integer_sequence<uint32_t,I...>)
	{
		return std::array<uint32_t,sizeof...(I)>{{I...}};
	}

	static constexpr uint32_t			_size=size();
	static constexpr uint32_t			_levels=levels();
	static constexpr std::array<uint32_t,_levels>	_levelOffsets=makeArray(makeLevelOffsetSequence(std::make_integer_sequence<uint32_t,levels()>{}));
	static constexpr std::array<uint32_t,_levels>	_levelSizes=makeArray(makeLevelSizeSequence(std::make_integer_sequence<uint32_t,levels()>{}));

	uint16_t					_tree[size()];
};

template<size_t T>
class FrequencyDecoder
{
public:
	FrequencyDecoder(RangeDecoder &decoder) :
		_decoder(decoder)
	{
		// nothing needed
	}

	~FrequencyDecoder()
	{
		// nothing needed
	}

	template<typename F>
	uint16_t decode(F readFunc)
	{
		uint16_t freq=0,symbol,value=_decoder.decode(_threshold+_tree.getTotal());
		if (value>=_threshold)
		{
			uint16_t low;
			symbol=_tree.decode(value-_threshold,low,freq);
			_decoder.scale(_threshold+low,_threshold+low+freq,_threshold+_tree.getTotal());
			if (freq==1 && _threshold>1)
				_threshold--;
		} else {
			_decoder.scale(0,_threshold,_threshold+_tree.getTotal());
			symbol=readFunc();
			// A bug in the encoder
			if (!symbol && _tree.exists(symbol)) symbol=T;
			_threshold++;
		}
		_tree.increment(symbol);
		if (_threshold+_tree.getTotal()>=0x3ffdU)
		{
			_tree.halve();
			_threshold=(_threshold>>1)+1;
		}
		return symbol;
	}

private:
	RangeDecoder					&_decoder;
	FrequencyTree<T+1>				_tree;
	uint16_t					_threshold=1;
};

bool LZCBDecompressor::detectHeaderXPK(uint32_t hdr) noexcept
{
	return hdr==FourCC("LZCB");
}

std::unique_ptr<XPKDecompressor> LZCBDecompressor::create(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify)
{
	return std::make_unique<LZCBDecompressor>(hdr,recursionLevel,packedData,state,verify);
}

LZCBDecompressor::LZCBDecompressor(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify) :
	XPKDecompressor(recursionLevel),
	_packedData(packedData)
{
	if (packedData.size()<2) throw Decompressor::InvalidFormatError();
}

LZCBDecompressor::~LZCBDecompressor()
{
	// nothing needed
}

const std::string &LZCBDecompressor::getSubName() const noexcept
{
	static std::string name="XPK-LZCB: LZ-compressor";
	return name;
}

void LZCBDecompressor::decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify)
{
	class BitReader : public RangeDecoder::BitReader
	{
	public:
		BitReader(ForwardInputStream &stream) :
			_reader(stream)
		{
			// nothing needed
		}

		virtual ~BitReader()
		{
			// nothing needed
		}

		virtual uint32_t readBit() override final
		{
			return _reader.readBitsBE32(1);
		}

		uint32_t readBits(uint32_t bitCount)
		{
			return _reader.readBitsBE32(bitCount);
		}

	private:
		MSBBitReader<ForwardInputStream>	_reader;
	};

	ForwardInputStream inputStream(_packedData,0,_packedData.size(),true);
	ForwardOutputStream outputStream(rawData,0,rawData.size());
	BitReader bitReader(inputStream);

	RangeDecoder rangeDecoder(bitReader,bitReader.readBits(16));

	// Ugly duplicates
	auto readByte=[&]()->uint16_t
	{
		uint16_t ret=rangeDecoder.decode(0x100U);
		rangeDecoder.scale(ret,ret+1,0x100U);
		return ret;
	};

	auto readCount=[&]()->uint16_t
	{
		uint16_t ret=rangeDecoder.decode(0x101U);
		rangeDecoder.scale(ret,ret+1,0x101U);
		return ret;
	};

	FrequencyDecoder<256> baseLiteralDecoder(rangeDecoder);
	FrequencyDecoder<257> repeatCountDecoder(rangeDecoder);
	FrequencyDecoder<257> literalCountDecoder(rangeDecoder);
	FrequencyDecoder<256> distanceDecoder(rangeDecoder);

	std::unique_ptr<FrequencyDecoder<256>> literalDecoders[256];

	uint8_t ch=baseLiteralDecoder.decode(readByte);
	outputStream.writeByte(ch);
	bool lastIsLiteral=true;
	while (!outputStream.eof())
	{
		uint32_t count=repeatCountDecoder.decode(readCount);
		if (count)
		{
			if (count==0x100U)
			{
				uint32_t tmp;
				do
				{
					tmp=readByte();
					count+=tmp;
				} while (tmp==0xffU);
			}
			count+=lastIsLiteral?5:4;

			uint32_t distance=distanceDecoder.decode(readByte)<<8;
			distance|=readByte();

			ch=outputStream.copy(distance,count);
			lastIsLiteral=false;
		} else {
			uint16_t literalCount;
			do
			{
				literalCount=literalCountDecoder.decode(readCount);
				if (!literalCount) throw Decompressor::DecompressionError();

				for (uint32_t i=0;i<literalCount;i++)
				{
					auto &literalDecoder=literalDecoders[ch];
					if (!literalDecoder) literalDecoder=std::make_unique<FrequencyDecoder<256>>(rangeDecoder);
					ch=literalDecoder->decode([&]()
					{
						return baseLiteralDecoder.decode(readByte);
					});
					outputStream.writeByte(ch);
				}
			} while (literalCount==0x100U);
			lastIsLiteral=true;
		}
	}
}

XPKDecompressor::Registry<LZCBDecompressor> LZCBDecompressor::_XPKregistration;
<|endoftext|>


<commit_before>#include "dp.h"

#include <memory>

DynamicParallelism::DynamicParallelism()
{
	runtime  = clRuntime::getInstance();
	file     = clFile::getInstance();

	platform = runtime->getPlatformID();
	device   = runtime->getDevice();
	context  = runtime->getContext();
	cmdQueue = runtime->getCmdQueue(0);

	glbSize = 8192;
	locSize = 256;
	factor  = 2.3f;

	init();
}

DynamicParallelism::~DynamicParallelism()
{
	clean();
}

void DynamicParallelism::init()
{
	initKernel();
	initBuffer();
}

void DynamicParallelism::initKernel()
{
	cl_int err;

	// Open kernel file
        file->open("dp_Kernels.cl");

        // Create program
        const char *source = file->getSourceChar();
        program = clCreateProgramWithSource(context, 1,
                (const char **)&source, NULL, &err);
        checkOpenCLErrors(err, "Failed to create Program with source\n");

        // Create program with OpenCL 2.0 support
        err = clBuildProgram(program, 0, NULL, "-I. -cl-std=CL2.0", NULL, NULL);
        checkOpenCLErrors(err, "Failed to build program...\n");

        // Create kernels
        kernel_saxpy_naive = clCreateKernel(program, "saxpy_naive", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_naive kernel");
        kernel_saxpy_stride = clCreateKernel(program, "saxpy_stride", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_stride kernel");
        kernel_saxpy_dp = clCreateKernel(program, "saxpy_dp", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_dp kernel");
}

void DynamicParallelism::initBuffer()
{
	cl_int err;
	size_t glbSizeBytes = glbSize * sizeof(float);

	saxpy_src_0 = (float *)clSVMAlloc(context, CL_MEM_READ_ONLY, glbSizeBytes, 0);
	saxpy_src_1 = (float *)clSVMAlloc(context, CL_MEM_READ_ONLY, glbSizeBytes, 0);
	saxpy_dst_0 = (float *)clSVMAlloc(context, CL_MEM_READ_WRITE, glbSizeBytes, 0);

	// Map SVM buffers
	err  = clEnqueueSVMMap(cmdQueue, true, CL_MEM_READ_WRITE, saxpy_src_0, glbSizeBytes, 0, NULL, NULL);
	err |= clEnqueueSVMMap(cmdQueue, true, CL_MEM_READ_WRITE, saxpy_src_1, glbSizeBytes, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to map SVM buffers for initialization");

	// Initialize buffers
	for (int i = 0; i < glbSize; ++i)
	{
		saxpy_src_0[i] = (float)i;
		saxpy_src_1[i] = (float)i;
	}

	// Unmap SVM buffers
	err  = clEnqueueSVMUnmap(cmdQueue, saxpy_src_0, 0, NULL, NULL);
	err |= clEnqueueSVMUnmap(cmdQueue, saxpy_src_1, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to unmap SVM buffers after initialization");

}

void DynamicParallelism::clean()
{
	cleanKernel();
	cleanBuffer();
}

void DynamicParallelism::cleanKernel()
{
	cl_int err;

	err = clReleaseKernel(kernel_saxpy_naive);
	err |= clReleaseKernel(kernel_saxpy_stride);
	err |= clReleaseKernel(kernel_saxpy_dp);
	checkOpenCLErrors(err, "Failed to release kernels");

	err = clReleaseProgram(program);
	checkOpenCLErrors(err, "Failed to release program");
}

void DynamicParallelism::cleanBuffer()
{
	clSVMFreeSafe(context, saxpy_src_0);
	clSVMFreeSafe(context, saxpy_src_1);
	clSVMFreeSafe(context, saxpy_dst_0);
}

void DynamicParallelism::runNaive()
{
	cl_int err;

	size_t globalSize = glbSize;
	size_t localSize  = locSize;

	err  = clSetKernelArg(kernel_saxpy_naive, 0, sizeof(int), (void *)&glbSize);
	err |= clSetKernelArg(kernel_saxpy_naive, 1, sizeof(int), (void *)&factor);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 2, saxpy_src_0);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 3, saxpy_src_1);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 4, saxpy_dst_0);
	checkOpenCLErrors(err, "Failed to set args in saxpy_naive kernel");

        err = clEnqueueNDRangeKernel(
                cmdQueue,
                kernel_saxpy_naive,
                1,
                0, &globalSize, &localSize,
                0, 0, 0
        );
        checkOpenCLErrors(err, "Failed at clEnqueueNDRangeKernel");
}

void DynamicParallelism::runStride()
{

}

void DynamicParallelism::runDP()
{

}
int main(int argc, char const *argv[])
{
	std::unique_ptr<DynamicParallelism> dp(new DynamicParallelism());

	dp->runNaive();
	dp->runStride();
	dp->runDP();

	printf("Done!\n");

	return 0;
}<commit_msg>Result check<commit_after>#include "dp.h"

#include <memory>

DynamicParallelism::DynamicParallelism()
{
	runtime  = clRuntime::getInstance();
	file     = clFile::getInstance();

	platform = runtime->getPlatformID();
	device   = runtime->getDevice();
	context  = runtime->getContext();
	cmdQueue = runtime->getCmdQueue(0);

	glbSize = 8192;
	locSize = 256;
	factor  = 2.3f;

	init();
}

DynamicParallelism::~DynamicParallelism()
{
	clean();
}

void DynamicParallelism::init()
{
	initKernel();
	initBuffer();
}

void DynamicParallelism::initKernel()
{
	cl_int err;

	// Open kernel file
        file->open("dp_Kernels.cl");

        // Create program
        const char *source = file->getSourceChar();
        program = clCreateProgramWithSource(context, 1,
                (const char **)&source, NULL, &err);
        checkOpenCLErrors(err, "Failed to create Program with source\n");

        // Create program with OpenCL 2.0 support
        err = clBuildProgram(program, 0, NULL, "-I. -cl-std=CL2.0", NULL, NULL);
        checkOpenCLErrors(err, "Failed to build program...\n");

        // Create kernels
        kernel_saxpy_naive = clCreateKernel(program, "saxpy_naive", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_naive kernel");
        kernel_saxpy_stride = clCreateKernel(program, "saxpy_stride", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_stride kernel");
        kernel_saxpy_dp = clCreateKernel(program, "saxpy_dp", &err);
        checkOpenCLErrors(err, "Failed to create saxpy_dp kernel");
}

void DynamicParallelism::initBuffer()
{
	cl_int err;
	size_t glbSizeBytes = glbSize * sizeof(float);

	saxpy_src_0 = (float *)clSVMAlloc(context, CL_MEM_READ_ONLY, glbSizeBytes, 0);
	saxpy_src_1 = (float *)clSVMAlloc(context, CL_MEM_READ_ONLY, glbSizeBytes, 0);
	saxpy_dst_0 = (float *)clSVMAlloc(context, CL_MEM_READ_WRITE, glbSizeBytes, 0);

	// Map SVM buffers
	err  = clEnqueueSVMMap(cmdQueue, true, CL_MEM_READ_WRITE, saxpy_src_0, glbSizeBytes, 0, NULL, NULL);
	err |= clEnqueueSVMMap(cmdQueue, true, CL_MEM_READ_WRITE, saxpy_src_1, glbSizeBytes, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to map SVM buffers for initialization");

	// Initialize buffers
	for (int i = 0; i < glbSize; ++i)
	{
		saxpy_src_0[i] = (float)i;
		saxpy_src_1[i] = (float)i;
	}

	// Unmap SVM buffers
	err  = clEnqueueSVMUnmap(cmdQueue, saxpy_src_0, 0, NULL, NULL);
	err |= clEnqueueSVMUnmap(cmdQueue, saxpy_src_1, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to unmap SVM buffers after initialization");

}

void DynamicParallelism::clean()
{
	cleanKernel();
	cleanBuffer();
}

void DynamicParallelism::cleanKernel()
{
	cl_int err;

	err = clReleaseKernel(kernel_saxpy_naive);
	err |= clReleaseKernel(kernel_saxpy_stride);
	err |= clReleaseKernel(kernel_saxpy_dp);
	checkOpenCLErrors(err, "Failed to release kernels");

	err = clReleaseProgram(program);
	checkOpenCLErrors(err, "Failed to release program");
}

void DynamicParallelism::cleanBuffer()
{
	clSVMFreeSafe(context, saxpy_src_0);
	clSVMFreeSafe(context, saxpy_src_1);
	clSVMFreeSafe(context, saxpy_dst_0);
}

void DynamicParallelism::runNaive()
{
	cl_int err;

	size_t globalSize = glbSize;
	size_t localSize  = locSize;

	err  = clSetKernelArg(kernel_saxpy_naive, 0, sizeof(int), (void *)&glbSize);
	err |= clSetKernelArg(kernel_saxpy_naive, 1, sizeof(int), (void *)&factor);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 2, saxpy_src_0);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 3, saxpy_src_1);
	err |= clSetKernelArgSVMPointer(kernel_saxpy_naive, 4, saxpy_dst_0);
	checkOpenCLErrors(err, "Failed to set args in saxpy_naive kernel");

        err = clEnqueueNDRangeKernel(
                cmdQueue,
                kernel_saxpy_naive,
                1,
                0, &globalSize, &localSize,
                0, 0, 0
        );
        checkOpenCLErrors(err, "Failed at clEnqueueNDRangeKernel");

	// Map SVM buffers
	size_t glbSizeBytes = glbSize * sizeof(float);
	err  = clEnqueueSVMMap(cmdQueue, true, CL_MEM_READ_ONLY, saxpy_dst_0, glbSizeBytes, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to map SVM buffers for checking result");

	// Check result
	for (int i = 0; i < glbSize / locSize; ++i)
		printf("%f\n", saxpy_dst_0[i]);

	// Unmap SVM buffers
	err  = clEnqueueSVMUnmap(cmdQueue, saxpy_src_0, 0, NULL, NULL);
	err |= clEnqueueSVMUnmap(cmdQueue, saxpy_src_1, 0, NULL, NULL);
	checkOpenCLErrors(err, "Failed to unmap SVM buffers after checking result");

}

void DynamicParallelism::runStride()
{

}

void DynamicParallelism::runDP()
{

}
int main(int argc, char const *argv[])
{
	std::unique_ptr<DynamicParallelism> dp(new DynamicParallelism());

	printf("Running...\n");

	dp->runNaive();
	dp->runStride();
	dp->runDP();

	printf("Done!\n");

	return 0;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pe_tpltp.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2005-01-27 11:24:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef ADC_CPP_PE_TPLTP_HXX
#define ADC_CPP_PE_TPLTP_HXX

// USED SERVICES
    // BASE CLASSES
#include "cpp_pe.hxx"
    // COMPONENTS
#include <semantic/callf.hxx>
#include <semantic/sub_peu.hxx>
    // PARAMETERS

namespace cpp {

class PE_TemplateTop : public cpp::Cpp_PE
{
  public:
    enum E_State
    {
        start,
        expect_qualifier,
        expect_name,
        expect_separator,
        size_of_states
    };
                        PE_TemplateTop(
                            Cpp_PE *            i_pParent );
                        ~PE_TemplateTop();

    const StringVector &
                        Result_Parameters() const;

    virtual void        Call_Handler(
                            const cpp::Token &  i_rTok );
  private:
    void                Setup_StatusFunctions();
    virtual void        InitData();
    virtual void        TransferData();
    void                Hdl_SyntaxError(const char *);

    void                On_start_Less(const char *);

    void                On_expect_qualifier_ClassOrTypename(const char *);
    void                On_expect_qualifier_Other(const char *);

    void                On_expect_name_Identifier(const char *);

    void                On_expect_separator_Comma(const char *);
    void                On_expect_separator_Greater(const char *);

    // DATA
    Dyn< PeStatusArray<PE_TemplateTop> >
                        pStati;

    StringVector
                        aResult_Parameters;
    bool                bCurIsConstant;
};

// IMPLEMENTATION

inline const StringVector &
PE_TemplateTop::Result_Parameters() const
    { return aResult_Parameters; }

}   // namespace cpp

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.16); FILE MERGED 2005/09/05 13:11:49 rt 1.2.16.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_tpltp.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:29:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef ADC_CPP_PE_TPLTP_HXX
#define ADC_CPP_PE_TPLTP_HXX

// USED SERVICES
    // BASE CLASSES
#include "cpp_pe.hxx"
    // COMPONENTS
#include <semantic/callf.hxx>
#include <semantic/sub_peu.hxx>
    // PARAMETERS

namespace cpp {

class PE_TemplateTop : public cpp::Cpp_PE
{
  public:
    enum E_State
    {
        start,
        expect_qualifier,
        expect_name,
        expect_separator,
        size_of_states
    };
                        PE_TemplateTop(
                            Cpp_PE *            i_pParent );
                        ~PE_TemplateTop();

    const StringVector &
                        Result_Parameters() const;

    virtual void        Call_Handler(
                            const cpp::Token &  i_rTok );
  private:
    void                Setup_StatusFunctions();
    virtual void        InitData();
    virtual void        TransferData();
    void                Hdl_SyntaxError(const char *);

    void                On_start_Less(const char *);

    void                On_expect_qualifier_ClassOrTypename(const char *);
    void                On_expect_qualifier_Other(const char *);

    void                On_expect_name_Identifier(const char *);

    void                On_expect_separator_Comma(const char *);
    void                On_expect_separator_Greater(const char *);

    // DATA
    Dyn< PeStatusArray<PE_TemplateTop> >
                        pStati;

    StringVector
                        aResult_Parameters;
    bool                bCurIsConstant;
};

// IMPLEMENTATION

inline const StringVector &
PE_TemplateTop::Result_Parameters() const
    { return aResult_Parameters; }

}   // namespace cpp

#endif

<|endoftext|>


<commit_before>#include <string.h>
#include <node.h>
#include <node_buffer.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/ecdh.h>

#include "eckey.h"

using namespace v8;
using namespace node;

static Handle<Value> V8Exception(const char* msg) {
	HandleScope scope;
	return ThrowException(Exception::Error(String::New(msg)));
}

// Not sure where this came from. but looks like a function that should be part of openssl
int static inline EC_KEY_regenerate_key(EC_KEY *eckey, const BIGNUM *priv_key) {
	if (!eckey) return 0;
	int ok = 0;
	BN_CTX *ctx = NULL;
	EC_POINT *pub_key = NULL;
	const EC_GROUP *group = EC_KEY_get0_group(eckey);
	if ((ctx = BN_CTX_new()) == NULL)
		goto err;
	pub_key = EC_POINT_new(group);
	if (pub_key == NULL)
		goto err;
	if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
		goto err;
	EC_KEY_set_private_key(eckey, priv_key);
	EC_KEY_set_public_key(eckey, pub_key);
	ok = 1;
err:
	if (pub_key)
		EC_POINT_free(pub_key);
	if (ctx != NULL)
		BN_CTX_free(ctx);
	return ok;
}

ECKey::ECKey(int curve) {
	mHasPrivateKey = false;
	mCurve = curve;
	mKey = EC_KEY_new_by_curve_name(mCurve);
	if (!mKey) {
		V8Exception("EC_KEY_new_by_curve_name Invalid curve?");
		return;
	}
}
ECKey::~ECKey() {
	if (mKey) {
		EC_KEY_free(mKey);
	}
}

// Node module init
void ECKey::Init(Handle<Object> exports) {
	Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
	tpl->SetClassName(String::NewSymbol("ECKey"));
	tpl->InstanceTemplate()->SetInternalFieldCount(1);

	//Accessors
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("HasPrivateKey"), GetHasPrivateKey);
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("PublicKey"), GetPublicKey);
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("PrivateKey"), GetPrivateKey);

	//Methods (Prototype)
	tpl->PrototypeTemplate()->Set(String::NewSymbol("sign"), FunctionTemplate::New(Sign)->GetFunction());
	tpl->PrototypeTemplate()->Set(String::NewSymbol("verifySignature"), FunctionTemplate::New(VerifySignature)->GetFunction());
	tpl->PrototypeTemplate()->Set(String::NewSymbol("deriveSharedSecret"), FunctionTemplate::New(DeriveSharedSecret)->GetFunction());

	Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
	exports->Set(String::NewSymbol("ECKey"), constructor);
}

// Node constructor function
// new ECKey(curve, buffer, isPrivate)
Handle<Value> ECKey::New(const Arguments &args) {
	if (!args.IsConstructCall()) {
		return V8Exception("Must use new keyword");
	}
	if (args[0]->IsUndefined()) {
		return V8Exception("First argument must be an ECCurve");
	}
	HandleScope scope;
	ECKey *eckey = new ECKey(args[0]->NumberValue());
	if (!args[1]->IsUndefined()) {
		//we have a second parameter, check the third to see if it is public or private.
		if (!Buffer::HasInstance(args[1])) {
			return V8Exception("Second parameter must be a buffer");
		}
		Handle<Object> buffer = args[1]->ToObject();
		const unsigned char *bufferData = (unsigned char *) Buffer::Data(buffer);
		if ((args[2]->IsUndefined()) || (args[2]->BooleanValue() == false)) {
			// it's a private key
			BIGNUM *bn = BN_bin2bn(bufferData, Buffer::Length(buffer), BN_new());
			if (EC_KEY_regenerate_key(eckey->mKey, bn) == 0) {
				BN_clear_free(bn);
				return V8Exception("Invalid private key");
			}
			BN_clear_free(bn);
			eckey->mHasPrivateKey = true;
		} else {
			// it's a public key
			if (!o2i_ECPublicKey(&(eckey->mKey), &bufferData, Buffer::Length(buffer))) {
				return V8Exception("o2i_ECPublicKey failed");
			}
		}
	} else {
		if (!EC_KEY_generate_key(eckey->mKey)) {
			return V8Exception("EC_KEY_generate_key failed");
		}
		eckey->mHasPrivateKey = true;
	}
	eckey->Wrap(args.Holder());
	return args.Holder();
}

// Node properity functions
Handle<Value> ECKey::GetHasPrivateKey(Local<String> property, const AccessorInfo &info) {
	HandleScope scope;
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	return scope.Close(Boolean::New(eckey->mHasPrivateKey));
}
Handle<Value> ECKey::GetPublicKey(Local<String> property, const AccessorInfo &info) {
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	const EC_GROUP *group = EC_KEY_get0_group(eckey->mKey);
	const EC_POINT *point = EC_KEY_get0_public_key(eckey->mKey);
	unsigned int nReq = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
	if (!nReq) {
		return V8Exception("EC_POINT_point2oct error");
	}
	unsigned char *buf, *buf2;
	buf = buf2 = (unsigned char *)malloc(nReq);
	if (EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, buf, nReq, NULL) != nReq) {
		return V8Exception("EC_POINT_point2oct didn't return correct size");
	}
	HandleScope scope;
	Buffer *buffer = Buffer::New(nReq);
	memcpy(Buffer::Data(buffer), buf2, nReq);
	free(buf2);
	return scope.Close(buffer->handle_);
}
Handle<Value> ECKey::GetPrivateKey(Local<String> property, const AccessorInfo &info) {
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	const BIGNUM *bn = EC_KEY_get0_private_key(eckey->mKey);
	if (bn == NULL) {
		return V8Exception("EC_KEY_get0_private_key failed");
	}
	int priv_size = BN_num_bytes(bn);
	unsigned char *priv_buf = (unsigned char *)malloc(priv_size);
	int n = BN_bn2bin(bn, priv_buf);
	if (n != priv_size) {
		return V8Exception("BN_bn2bin didn't return priv_size");
	}
	HandleScope scope;
	Buffer *buffer = Buffer::New(priv_size);
	memcpy(Buffer::Data(buffer), priv_buf, priv_size);
	free(priv_buf);
	return scope.Close(buffer->handle_);
}

// Node method functions
Handle<Value> ECKey::Sign(const Arguments &args) {
	HandleScope scope;
	ECKey * eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	if (!Buffer::HasInstance(args[0])) {
		return V8Exception("digest must be a buffer");
	}
	if (!eckey->mHasPrivateKey) {
		return V8Exception("cannot sign without private key");
	}
	Handle<Object> digest = args[0]->ToObject();
	const unsigned char *digest_data = (unsigned char *)Buffer::Data(digest);
	unsigned int digest_len = Buffer::Length(digest);

	ECDSA_SIG *sig = ECDSA_do_sign(digest_data, digest_len, eckey->mKey);
	if (!sig) {
		return V8Exception("ECDSA_do_sign");
	}
	int sig_len = i2d_ECDSA_SIG(sig, NULL);
	if (!sig_len) {
		return V8Exception("i2d_ECDSA_SIG");
	}
	unsigned char *sig_data, *sig_data2;
	sig_data = sig_data2 = (unsigned char *)malloc(sig_len);
	if (i2d_ECDSA_SIG(sig, &sig_data) != sig_len) {
		ECDSA_SIG_free(sig);
		free(sig_data2);
		return V8Exception("i2d_ECDSA_SIG didnot return correct length");
	}
	ECDSA_SIG_free(sig);
	Buffer *result = Buffer::New(sig_len);
	memcpy(Buffer::Data(result), sig_data2, sig_len);
	free(sig_data2);
	return scope.Close(result->handle_);
}
Handle<Value> ECKey::VerifySignature(const Arguments &args) {
	HandleScope scope;
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	if (!Buffer::HasInstance(args[0])) {
		return V8Exception("digest must be a buffer");
	}
	if (!Buffer::HasInstance(args[1])) {
		return V8Exception("signature must be a buffer");
	}
	Handle<Object> digest = args[0]->ToObject();
	Handle<Object> signature = args[1]->ToObject();
	const unsigned char *digest_data = (unsigned char *)Buffer::Data(digest);
	const unsigned char *signature_data = (unsigned char *)Buffer::Data(signature);
	unsigned int digest_len = Buffer::Length(digest);
	unsigned int signature_len = Buffer::Length(signature);
	int result = ECDSA_verify(0, digest_data, digest_len, signature_data, signature_len, eckey->mKey);
	if (result == -1) {
		return V8Exception("ECDSA_verify");
	} else if (result == 0) {
		return scope.Close(Boolean::New(false));
	} else if (result == 1) {
		return scope.Close(Boolean::New(true));
	} else {
		return V8Exception("ECDSA_verify gave an unexpected return value");
	}
}
Handle<Value> ECKey::DeriveSharedSecret(const Arguments &args) {
	HandleScope scope;
	if (args[0]->IsUndefined()) {
		return V8Exception("other is required");
	}
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	ECKey *other = ObjectWrap::Unwrap<ECKey>(args[0]->ToObject());
	if (!other) {
		return V8Exception("other must be an ECKey");
	}
	unsigned char *secret = (unsigned char*)malloc(512);
	int len = ECDH_compute_key(secret, 512, EC_KEY_get0_public_key(other->mKey), eckey->mKey, NULL);
	Buffer *result = Buffer::New(len);
	memcpy(Buffer::Data(result), secret, len);
	free(secret);
	return scope.Close(result->handle_);
}

<commit_msg>correct incorrect comment<commit_after>#include <string.h>
#include <node.h>
#include <node_buffer.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/ecdh.h>

#include "eckey.h"

using namespace v8;
using namespace node;

static Handle<Value> V8Exception(const char* msg) {
	HandleScope scope;
	return ThrowException(Exception::Error(String::New(msg)));
}

// Not sure where this came from. but looks like a function that should be part of openssl
int static inline EC_KEY_regenerate_key(EC_KEY *eckey, const BIGNUM *priv_key) {
	if (!eckey) return 0;
	int ok = 0;
	BN_CTX *ctx = NULL;
	EC_POINT *pub_key = NULL;
	const EC_GROUP *group = EC_KEY_get0_group(eckey);
	if ((ctx = BN_CTX_new()) == NULL)
		goto err;
	pub_key = EC_POINT_new(group);
	if (pub_key == NULL)
		goto err;
	if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
		goto err;
	EC_KEY_set_private_key(eckey, priv_key);
	EC_KEY_set_public_key(eckey, pub_key);
	ok = 1;
err:
	if (pub_key)
		EC_POINT_free(pub_key);
	if (ctx != NULL)
		BN_CTX_free(ctx);
	return ok;
}

ECKey::ECKey(int curve) {
	mHasPrivateKey = false;
	mCurve = curve;
	mKey = EC_KEY_new_by_curve_name(mCurve);
	if (!mKey) {
		V8Exception("EC_KEY_new_by_curve_name Invalid curve?");
		return;
	}
}
ECKey::~ECKey() {
	if (mKey) {
		EC_KEY_free(mKey);
	}
}

// Node module init
void ECKey::Init(Handle<Object> exports) {
	Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
	tpl->SetClassName(String::NewSymbol("ECKey"));
	tpl->InstanceTemplate()->SetInternalFieldCount(1);

	//Accessors
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("HasPrivateKey"), GetHasPrivateKey);
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("PublicKey"), GetPublicKey);
	tpl->InstanceTemplate()->SetAccessor(String::NewSymbol("PrivateKey"), GetPrivateKey);

	//Methods (Prototype)
	tpl->PrototypeTemplate()->Set(String::NewSymbol("sign"), FunctionTemplate::New(Sign)->GetFunction());
	tpl->PrototypeTemplate()->Set(String::NewSymbol("verifySignature"), FunctionTemplate::New(VerifySignature)->GetFunction());
	tpl->PrototypeTemplate()->Set(String::NewSymbol("deriveSharedSecret"), FunctionTemplate::New(DeriveSharedSecret)->GetFunction());

	Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
	exports->Set(String::NewSymbol("ECKey"), constructor);
}

// Node constructor function
// new ECKey(curve, buffer, isPublic)
Handle<Value> ECKey::New(const Arguments &args) {
	if (!args.IsConstructCall()) {
		return V8Exception("Must use new keyword");
	}
	if (args[0]->IsUndefined()) {
		return V8Exception("First argument must be an ECCurve");
	}
	HandleScope scope;
	ECKey *eckey = new ECKey(args[0]->NumberValue());
	if (!args[1]->IsUndefined()) {
		if (!Buffer::HasInstance(args[1])) {
			return V8Exception("Second parameter must be a buffer");
		}
		//we have a second parameter, check the third to see if it is public or private.
		Handle<Object> buffer = args[1]->ToObject();
		const unsigned char *bufferData = (unsigned char *) Buffer::Data(buffer);
		if ((args[2]->IsUndefined()) || (args[2]->BooleanValue() == false)) {
			// it's a private key
			BIGNUM *bn = BN_bin2bn(bufferData, Buffer::Length(buffer), BN_new());
			if (EC_KEY_regenerate_key(eckey->mKey, bn) == 0) {
				BN_clear_free(bn);
				return V8Exception("Invalid private key");
			}
			BN_clear_free(bn);
			eckey->mHasPrivateKey = true;
		} else {
			// it's a public key
			if (!o2i_ECPublicKey(&(eckey->mKey), &bufferData, Buffer::Length(buffer))) {
				return V8Exception("o2i_ECPublicKey failed");
			}
		}
	} else {
		if (!EC_KEY_generate_key(eckey->mKey)) {
			return V8Exception("EC_KEY_generate_key failed");
		}
		eckey->mHasPrivateKey = true;
	}
	eckey->Wrap(args.Holder());
	return args.Holder();
}

// Node properity functions
Handle<Value> ECKey::GetHasPrivateKey(Local<String> property, const AccessorInfo &info) {
	HandleScope scope;
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	return scope.Close(Boolean::New(eckey->mHasPrivateKey));
}
Handle<Value> ECKey::GetPublicKey(Local<String> property, const AccessorInfo &info) {
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	const EC_GROUP *group = EC_KEY_get0_group(eckey->mKey);
	const EC_POINT *point = EC_KEY_get0_public_key(eckey->mKey);
	unsigned int nReq = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
	if (!nReq) {
		return V8Exception("EC_POINT_point2oct error");
	}
	unsigned char *buf, *buf2;
	buf = buf2 = (unsigned char *)malloc(nReq);
	if (EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, buf, nReq, NULL) != nReq) {
		return V8Exception("EC_POINT_point2oct didn't return correct size");
	}
	HandleScope scope;
	Buffer *buffer = Buffer::New(nReq);
	memcpy(Buffer::Data(buffer), buf2, nReq);
	free(buf2);
	return scope.Close(buffer->handle_);
}
Handle<Value> ECKey::GetPrivateKey(Local<String> property, const AccessorInfo &info) {
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(info.Holder());
	const BIGNUM *bn = EC_KEY_get0_private_key(eckey->mKey);
	if (bn == NULL) {
		return V8Exception("EC_KEY_get0_private_key failed");
	}
	int priv_size = BN_num_bytes(bn);
	unsigned char *priv_buf = (unsigned char *)malloc(priv_size);
	int n = BN_bn2bin(bn, priv_buf);
	if (n != priv_size) {
		return V8Exception("BN_bn2bin didn't return priv_size");
	}
	HandleScope scope;
	Buffer *buffer = Buffer::New(priv_size);
	memcpy(Buffer::Data(buffer), priv_buf, priv_size);
	free(priv_buf);
	return scope.Close(buffer->handle_);
}

// Node method functions
Handle<Value> ECKey::Sign(const Arguments &args) {
	HandleScope scope;
	ECKey * eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	if (!Buffer::HasInstance(args[0])) {
		return V8Exception("digest must be a buffer");
	}
	if (!eckey->mHasPrivateKey) {
		return V8Exception("cannot sign without private key");
	}
	Handle<Object> digest = args[0]->ToObject();
	const unsigned char *digest_data = (unsigned char *)Buffer::Data(digest);
	unsigned int digest_len = Buffer::Length(digest);

	ECDSA_SIG *sig = ECDSA_do_sign(digest_data, digest_len, eckey->mKey);
	if (!sig) {
		return V8Exception("ECDSA_do_sign");
	}
	int sig_len = i2d_ECDSA_SIG(sig, NULL);
	if (!sig_len) {
		return V8Exception("i2d_ECDSA_SIG");
	}
	unsigned char *sig_data, *sig_data2;
	sig_data = sig_data2 = (unsigned char *)malloc(sig_len);
	if (i2d_ECDSA_SIG(sig, &sig_data) != sig_len) {
		ECDSA_SIG_free(sig);
		free(sig_data2);
		return V8Exception("i2d_ECDSA_SIG didnot return correct length");
	}
	ECDSA_SIG_free(sig);
	Buffer *result = Buffer::New(sig_len);
	memcpy(Buffer::Data(result), sig_data2, sig_len);
	free(sig_data2);
	return scope.Close(result->handle_);
}
Handle<Value> ECKey::VerifySignature(const Arguments &args) {
	HandleScope scope;
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	if (!Buffer::HasInstance(args[0])) {
		return V8Exception("digest must be a buffer");
	}
	if (!Buffer::HasInstance(args[1])) {
		return V8Exception("signature must be a buffer");
	}
	Handle<Object> digest = args[0]->ToObject();
	Handle<Object> signature = args[1]->ToObject();
	const unsigned char *digest_data = (unsigned char *)Buffer::Data(digest);
	const unsigned char *signature_data = (unsigned char *)Buffer::Data(signature);
	unsigned int digest_len = Buffer::Length(digest);
	unsigned int signature_len = Buffer::Length(signature);
	int result = ECDSA_verify(0, digest_data, digest_len, signature_data, signature_len, eckey->mKey);
	if (result == -1) {
		return V8Exception("ECDSA_verify");
	} else if (result == 0) {
		return scope.Close(Boolean::New(false));
	} else if (result == 1) {
		return scope.Close(Boolean::New(true));
	} else {
		return V8Exception("ECDSA_verify gave an unexpected return value");
	}
}
Handle<Value> ECKey::DeriveSharedSecret(const Arguments &args) {
	HandleScope scope;
	if (args[0]->IsUndefined()) {
		return V8Exception("other is required");
	}
	ECKey *eckey = ObjectWrap::Unwrap<ECKey>(args.Holder());
	ECKey *other = ObjectWrap::Unwrap<ECKey>(args[0]->ToObject());
	if (!other) {
		return V8Exception("other must be an ECKey");
	}
	unsigned char *secret = (unsigned char*)malloc(512);
	int len = ECDH_compute_key(secret, 512, EC_KEY_get0_public_key(other->mKey), eckey->mKey, NULL);
	Buffer *result = Buffer::New(len);
	memcpy(Buffer::Data(result), secret, len);
	free(secret);
	return scope.Close(result->handle_);
}

<|endoftext|>


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

#include <cstring>
#include "common.h"
#include "sentencepiece_processor.h"

namespace sentencepiece {
namespace error {
int gTestCounter = 0;

void Abort() {
  if (GetTestCounter() == 1) {
    SetTestCounter(2);
  } else {
    std::cerr << "Program terminated with an unrecoverable error." << std::endl;
    exit(-1);
  }
}

void Exit(int code) {
  if (GetTestCounter() == 1) {
    SetTestCounter(2);
  } else {
    exit(code);
  }
}

void SetTestCounter(int c) { gTestCounter = c; }
bool GetTestCounter() { return gTestCounter; }
}  // namespace error

namespace util {

Status::Status() {}
Status::~Status() {}

struct Status::Rep {
  error::Code code;
  std::string error_message;
};

Status::Status(error::Code code, const char* error_message) : rep_(new Rep) {
  rep_->code = code;
  rep_->error_message = error_message;
}

Status::Status(error::Code code, const std::string& error_message)
    : rep_(new Rep) {
  rep_->code = code;
  rep_->error_message = error_message;
}

Status::Status(const Status& s)
    : rep_((s.rep_ == nullptr) ? nullptr : new Rep(*s.rep_)) {}

void Status::operator=(const Status& s) {
  if (rep_ != s.rep_)
    rep_.reset((s.rep_ == nullptr) ? nullptr : new Rep(*s.rep_));
}

bool Status::operator==(const Status& s) const { return (rep_ == s.rep_); }

bool Status::operator!=(const Status& s) const { return (rep_ != s.rep_); }

const char* Status::error_message() const {
  return ok() ? "" : rep_->error_message.c_str();
}

void Status::set_error_message(const char* str) {
  if (rep_ == nullptr) rep_.reset(new Rep);
  rep_->error_message = str;
}

error::Code Status::code() const { return ok() ? error::OK : rep_->code; }

std::string Status::ToString() const {
  if (rep_ == nullptr) return "OK";

  std::string result;
  switch (code()) {
    case error::CANCELLED:
      result = "Cancelled";
      break;
    case error::UNKNOWN:
      result = "Unknown";
      break;
    case error::INVALID_ARGUMENT:
      result = "Invalid argument";
      break;
    case error::DEADLINE_EXCEEDED:
      result = "Deadline exceeded";
      break;
    case error::NOT_FOUND:
      result = "Not found";
      break;
    case error::ALREADY_EXISTS:
      result = "Already exists";
      break;
    case error::PERMISSION_DENIED:
      result = "Permission denied";
      break;
    case error::UNAUTHENTICATED:
      result = "Unauthenticated";
      break;
    case error::RESOURCE_EXHAUSTED:
      result = "Resource exhausted";
      break;
    case error::FAILED_PRECONDITION:
      result = "Failed precondition";
      break;
    case error::ABORTED:
      result = "Aborted";
      break;
    case error::OUT_OF_RANGE:
      result = "Out of range";
      break;
    case error::UNIMPLEMENTED:
      result = "Unimplemented";
      break;
    case error::INTERNAL:
      result = "Internal";
      break;
    case error::UNAVAILABLE:
      result = "Unavailable";
      break;
    case error::DATA_LOSS:
      result = "Data loss";
      break;
    default:
      result = "Unkown code:";
      break;
  }

  result += ": ";
  result += rep_->error_message;
  return result;
}

void Status::IgnoreError() {}

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

#include <cstring>
#include "common.h"
#include "sentencepiece_processor.h"

namespace sentencepiece {
namespace error {
int gTestCounter = 0;

void Abort() {
  if (GetTestCounter() == 1) {
    SetTestCounter(2);
  } else {
    std::cerr << "Program terminated with an unrecoverable error." << std::endl;
    exit(-1);
  }
}

void Exit(int code) {
  if (GetTestCounter() == 1) {
    SetTestCounter(2);
  } else {
    exit(code);
  }
}

void SetTestCounter(int c) { gTestCounter = c; }
bool GetTestCounter() { return gTestCounter; }
}  // namespace error

namespace util {

Status::Status() {}
Status::~Status() {}

struct Status::Rep {
  error::Code code;
  std::string error_message;
};

Status::Status(error::Code code, const char* error_message) : rep_(new Rep) {
  rep_->code = code;
  rep_->error_message = error_message;
}

Status::Status(error::Code code, const std::string& error_message)
    : rep_(new Rep) {
  rep_->code = code;
  rep_->error_message = error_message;
}

Status::Status(const Status& s)
    : rep_((s.rep_ == nullptr) ? nullptr : new Rep(*s.rep_)) {}

void Status::operator=(const Status& s) {
  if (rep_ != s.rep_)
    rep_.reset((s.rep_ == nullptr) ? nullptr : new Rep(*s.rep_));
}

bool Status::operator==(const Status& s) const { return (rep_ == s.rep_); }

bool Status::operator!=(const Status& s) const { return (rep_ != s.rep_); }

const char* Status::error_message() const {
  return ok() ? "" : rep_->error_message.c_str();
}

void Status::set_error_message(const char* str) {
  if (rep_ == nullptr) rep_.reset(new Rep);
  rep_->error_message = str;
}

error::Code Status::code() const { return ok() ? error::OK : rep_->code; }

std::string Status::ToString() const {
  if (rep_ == nullptr) return "OK";

  std::string result;
  switch (code()) {
    case error::CANCELLED:
      result = "Cancelled";
      break;
    case error::UNKNOWN:
      result = "Unknown";
      break;
    case error::INVALID_ARGUMENT:
      result = "Invalid argument";
      break;
    case error::DEADLINE_EXCEEDED:
      result = "Deadline exceeded";
      break;
    case error::NOT_FOUND:
      result = "Not found";
      break;
    case error::ALREADY_EXISTS:
      result = "Already exists";
      break;
    case error::PERMISSION_DENIED:
      result = "Permission denied";
      break;
    case error::UNAUTHENTICATED:
      result = "Unauthenticated";
      break;
    case error::RESOURCE_EXHAUSTED:
      result = "Resource exhausted";
      break;
    case error::FAILED_PRECONDITION:
      result = "Failed precondition";
      break;
    case error::ABORTED:
      result = "Aborted";
      break;
    case error::OUT_OF_RANGE:
      result = "Out of range";
      break;
    case error::UNIMPLEMENTED:
      result = "Unimplemented";
      break;
    case error::INTERNAL:
      result = "Internal";
      break;
    case error::UNAVAILABLE:
      result = "Unavailable";
      break;
    case error::DATA_LOSS:
      result = "Data loss";
      break;
    default:
      result = "Unknown code:";
      break;
  }

  result += ": ";
  result += rep_->error_message;
  return result;
}

void Status::IgnoreError() {}

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