<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2016 Mustafa Serdar Sanli
//
// 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 <cstdlib>
#include <iostream>
#include <stdexcept>

#include "Attributes.hpp"
#include "Parser.hpp"
#include "Tokenizer.hpp"

using namespace std;

using TokenIt = vector<Token>::const_iterator;

void AssertToken(TokenIt it, Token::Type t)
{
	if (it->type != t)
	{
		cerr << "Assertion failed: Expected token " << (int)t << " found " << (int)it->type << "\n";
		exit(1);
	}
}

void AssertToken(TokenIt it, Token::Type t, string val)
{
	if (it->type != t || it->strValue != val)
	{
		cerr << "Assertion failed: Expected token " << (int)t << " " << val << "\n";
		exit(1);
	}
}

// If the type is one of the reserved ones like `string`
// It will be converted to C++ equivalent like `std::string`
static void MakeStandardType(VariableTypeDef* type)
{
	if (type->typeName == "string" && type->of.size() == 0)
	{
		type->typeName = "std::string";
		return;
	}
	if (type->typeName == "vector" && type->of.size() > 0)
	{
		type->typeName = "std::vector";
		return;
	}
	if (type->typeName == "map" && type->of.size() > 0)
	{
		type->typeName = "std::map";
		return;
	}
}

TokenIt ParseVariableType(TokenIt it, TokenIt end, VariableTypeDef* vtOut)
{
	// parse type name with namespace
	if (it->type == Token::Type::NamespaceSeparator)
	{
		vtOut->typeName = "::";
		++it;
	}

	AssertToken(it, Token::Type::Name);
	vtOut->typeName += it->strValue;
	++it;

	while (it->type == Token::Type::NamespaceSeparator)
	{
		++it;

		AssertToken(it, Token::Type::Name);
		vtOut->typeName += "::" + it->strValue;
		++it;
	}

	// Parse template parameters
	if (it->type == Token::Type::TemplateOpen)
	{
		++it;
		vtOut->of.emplace_back();
		it = ParseVariableType(it, end, &vtOut->of.back());

		while (it->type == Token::Type::Comma)
		{
			++it;
			vtOut->of.emplace_back();
			it = ParseVariableType(it, end, &vtOut->of.back());
		}

		AssertToken(it++, Token::Type::TemplateClose);
	}

	MakeStandardType(vtOut);

	return it;
}

// [[ attr1("val1"), attr2("val2") ]]
TokenIt ParseAttributes(TokenIt it, TokenIt end, map< string, AttributeDef > *attributes)
{
	attributes->clear();
	AssertToken(it, Token::Type::AttributeOpen);
	++it;

	bool firstAttr = true;

	while (it->type != Token::Type::AttributeClose)
	{
		if (firstAttr)
		{
			firstAttr = false;
		}
		else
		{
			AssertToken(it, Token::Type::Comma);
			++it;
		}

		AttributeDef attr;
		AssertToken(it, Token::Type::Name);
		attr.name = it->strValue;
		++it;

		// Check if the attribute is known
		const AttributeInfo *knownAttribute = GetKnownAttribute(attr.name);
		if (!knownAttribute)
		{
			throw runtime_error("Unknown attribute: [" + attr.name + "]");
		}
		if (attributes->find(attr.name) != attributes->end())
		{
			throw runtime_error("Duplicate attribute: [" + attr.name + "]");
		}

		if (it->type == Token::Type::ParenthesesOpen)
		{
			++it;

			AssertToken(it, Token::Type::String);
			string arg = it->strValue;
			++it;
			attr.args.push_back(arg);

			while (it->type == Token::Type::Comma)
			{
				++it;

				AssertToken(it, Token::Type::String);
				string arg = it->strValue;
				++it;
				attr.args.push_back(arg);
			}

			AssertToken(it, Token::Type::ParenthesesClose);
			++it;
		}

		if (attr.args.size() != knownAttribute->arg_count)
		{
			throw runtime_error("Unexpected number of args for attribute: [" + attr.name + "]");
		}

		(*attributes)[attr.name] = attr;
	}

	AssertToken(it, Token::Type::AttributeClose);
	++it;
	return it;
}

TokenIt ParseVariableDef(TokenIt it, TokenIt end, VariableDef *vOut)
{
	it = ParseVariableType(it, end, &vOut->type);

	AssertToken(it, Token::Type::Name);
	vOut->name = it->strValue;
	++it;

	if (it->type == Token::Type::AttributeOpen)
	{
		it = ParseAttributes(it, end, &vOut->attributes);
	}

	while (it->type != Token::Type::Semicolon)
	{
		++it;
	}

	AssertToken(it++, Token::Type::Semicolon);
	return it;
}

TokenIt ParseStructDef(TokenIt it, TokenIt end, StructDef* sOut)
{
	AssertToken(it++, Token::Type::KeywordStruct);
	AssertToken(it, Token::Type::Name);
	sOut->name = it->strValue;
	++it;
	AssertToken(it++, Token::Type::BracesOpen);

	// Assume struct defns can not be nested
	while (it->type != Token::Type::BracesClose)
	{
		// Anything inside a struct should be a variable definition ?
		sOut->variables.resize(sOut->variables.size() + 1);
		it = ParseVariableDef(it, end, &sOut->variables[sOut->variables.size() - 1]);
	}

	AssertToken(it++, Token::Type::BracesClose);
	AssertToken(it++, Token::Type::Semicolon);
	return it; // Return next token
}

// Parses a tokenized file, and returns extracted `ParsedFile`
ParsedFile Parse(const vector<Token> &tokens)
{
	// namespace A {
	// namespace B::C {
	// ...
	// would be represented as [ [ "A" ], [ "B", "C" ] ]
	vector< vector<string> > currentNamespace;

	auto flatten = [](const vector< vector<string>> &namespaces) -> vector<string>
	{
		vector<string> res;

		for (const vector<string> &nsDef : namespaces)
		{
			for (const string &ns : nsDef)
			{
				res.push_back(ns);
			}
		}

		return res;
	};

	ParsedFile f;
	TokenIt it = tokens.begin();
	TokenIt end   = tokens.end();

	while (it != end)
	{
		const Token &nextToken = *it;

		switch (nextToken.type)
		{
			case Token::Type::KeywordStruct:
				f.structs.resize(f.structs.size() + 1);
				f.structs.back().inNamespace = flatten(currentNamespace);
				it = ParseStructDef(it, end, &f.structs[f.structs.size() - 1]);
				continue;
			case Token::Type::KeywordNamespace:
			{
				++it;
				AssertToken(it, Token::Type::Name);
				currentNamespace.emplace_back(1, it->strValue);
				++it;

				while (it->type == Token::Type::NamespaceSeparator)
				{
					++it;
					AssertToken(it, Token::Type::Name);
					currentNamespace.back().push_back(it->strValue);
					++it;
				}

				AssertToken(it++, Token::Type::BracesOpen); // TODO add skiptoken fn
				break;
			}
			case Token::Type::BracesClose:
			{
				++it;
				if (currentNamespace.size() == 0)
				{
					goto unknown_token;
				}
				currentNamespace.pop_back();
				break;
			}
			case Token::Type::EndOfFile:
				goto parsing_finished;
			default:
			unknown_token:
				cerr << "Unable to understand next token: "
				     << (int)it->type << ": " << it->strValue << "\n";
				exit(1);
		}
	}
	parsing_finished:

	return f;
}
<commit_msg>Add line number to error messages<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2016 Mustafa Serdar Sanli
//
// 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 <cstdlib>
#include <iostream>
#include <stdexcept>

#include "Attributes.hpp"
#include "Parser.hpp"
#include "Tokenizer.hpp"

using namespace std;

using TokenIt = vector<Token>::const_iterator;

void AssertToken(TokenIt it, Token::Type t)
{
	if (it->type != t)
	{
		cerr << "ERROR: At line: " << it->line << " col: " << it->col << "\n"
		     << "  Expected token: " << (int)t << ", but found " << (int)it->type << "\n";
		exit(1);
	}
}

// If the type is one of the reserved ones like `string`
// It will be converted to C++ equivalent like `std::string`
static void MakeStandardType(VariableTypeDef* type)
{
	if (type->typeName == "string" && type->of.size() == 0)
	{
		type->typeName = "std::string";
		return;
	}
	if (type->typeName == "vector" && type->of.size() > 0)
	{
		type->typeName = "std::vector";
		return;
	}
	if (type->typeName == "map" && type->of.size() > 0)
	{
		type->typeName = "std::map";
		return;
	}
}

TokenIt ParseVariableType(TokenIt it, TokenIt end, VariableTypeDef* vtOut)
{
	// parse type name with namespace
	if (it->type == Token::Type::NamespaceSeparator)
	{
		vtOut->typeName = "::";
		++it;
	}

	AssertToken(it, Token::Type::Name);
	vtOut->typeName += it->strValue;
	++it;

	while (it->type == Token::Type::NamespaceSeparator)
	{
		++it;

		AssertToken(it, Token::Type::Name);
		vtOut->typeName += "::" + it->strValue;
		++it;
	}

	// Parse template parameters
	if (it->type == Token::Type::TemplateOpen)
	{
		++it;
		vtOut->of.emplace_back();
		it = ParseVariableType(it, end, &vtOut->of.back());

		while (it->type == Token::Type::Comma)
		{
			++it;
			vtOut->of.emplace_back();
			it = ParseVariableType(it, end, &vtOut->of.back());
		}

		AssertToken(it++, Token::Type::TemplateClose);
	}

	MakeStandardType(vtOut);

	return it;
}

// [[ attr1("val1"), attr2("val2") ]]
TokenIt ParseAttributes(TokenIt it, TokenIt end, map< string, AttributeDef > *attributes)
{
	attributes->clear();
	AssertToken(it, Token::Type::AttributeOpen);
	++it;

	bool firstAttr = true;

	while (it->type != Token::Type::AttributeClose)
	{
		if (firstAttr)
		{
			firstAttr = false;
		}
		else
		{
			AssertToken(it, Token::Type::Comma);
			++it;
		}

		AttributeDef attr;
		AssertToken(it, Token::Type::Name);
		attr.name = it->strValue;
		++it;

		// Check if the attribute is known
		const AttributeInfo *knownAttribute = GetKnownAttribute(attr.name);
		if (!knownAttribute)
		{
			throw runtime_error("Unknown attribute: [" + attr.name + "]");
		}
		if (attributes->find(attr.name) != attributes->end())
		{
			throw runtime_error("Duplicate attribute: [" + attr.name + "]");
		}

		if (it->type == Token::Type::ParenthesesOpen)
		{
			++it;

			AssertToken(it, Token::Type::String);
			string arg = it->strValue;
			++it;
			attr.args.push_back(arg);

			while (it->type == Token::Type::Comma)
			{
				++it;

				AssertToken(it, Token::Type::String);
				string arg = it->strValue;
				++it;
				attr.args.push_back(arg);
			}

			AssertToken(it, Token::Type::ParenthesesClose);
			++it;
		}

		if (attr.args.size() != knownAttribute->arg_count)
		{
			throw runtime_error("Unexpected number of args for attribute: [" + attr.name + "]");
		}

		(*attributes)[attr.name] = attr;
	}

	AssertToken(it, Token::Type::AttributeClose);
	++it;
	return it;
}

TokenIt ParseVariableDef(TokenIt it, TokenIt end, VariableDef *vOut)
{
	it = ParseVariableType(it, end, &vOut->type);

	AssertToken(it, Token::Type::Name);
	vOut->name = it->strValue;
	++it;

	if (it->type == Token::Type::AttributeOpen)
	{
		it = ParseAttributes(it, end, &vOut->attributes);
	}

	while (it->type != Token::Type::Semicolon)
	{
		++it;
	}

	AssertToken(it++, Token::Type::Semicolon);
	return it;
}

TokenIt ParseStructDef(TokenIt it, TokenIt end, StructDef* sOut)
{
	AssertToken(it++, Token::Type::KeywordStruct);
	AssertToken(it, Token::Type::Name);
	sOut->name = it->strValue;
	++it;
	AssertToken(it++, Token::Type::BracesOpen);

	// Assume struct defns can not be nested
	while (it->type != Token::Type::BracesClose)
	{
		// Anything inside a struct should be a variable definition ?
		sOut->variables.resize(sOut->variables.size() + 1);
		it = ParseVariableDef(it, end, &sOut->variables[sOut->variables.size() - 1]);
	}

	AssertToken(it++, Token::Type::BracesClose);
	AssertToken(it++, Token::Type::Semicolon);
	return it; // Return next token
}

// Parses a tokenized file, and returns extracted `ParsedFile`
ParsedFile Parse(const vector<Token> &tokens)
{
	// namespace A {
	// namespace B::C {
	// ...
	// would be represented as [ [ "A" ], [ "B", "C" ] ]
	vector< vector<string> > currentNamespace;

	auto flatten = [](const vector< vector<string>> &namespaces) -> vector<string>
	{
		vector<string> res;

		for (const vector<string> &nsDef : namespaces)
		{
			for (const string &ns : nsDef)
			{
				res.push_back(ns);
			}
		}

		return res;
	};

	ParsedFile f;
	TokenIt it = tokens.begin();
	TokenIt end   = tokens.end();

	while (it != end)
	{
		const Token &nextToken = *it;

		switch (nextToken.type)
		{
			case Token::Type::KeywordStruct:
				f.structs.resize(f.structs.size() + 1);
				f.structs.back().inNamespace = flatten(currentNamespace);
				it = ParseStructDef(it, end, &f.structs[f.structs.size() - 1]);
				continue;
			case Token::Type::KeywordNamespace:
			{
				++it;
				AssertToken(it, Token::Type::Name);
				currentNamespace.emplace_back(1, it->strValue);
				++it;

				while (it->type == Token::Type::NamespaceSeparator)
				{
					++it;
					AssertToken(it, Token::Type::Name);
					currentNamespace.back().push_back(it->strValue);
					++it;
				}

				AssertToken(it++, Token::Type::BracesOpen); // TODO add skiptoken fn
				break;
			}
			case Token::Type::BracesClose:
			{
				++it;
				if (currentNamespace.size() == 0)
				{
					goto unknown_token;
				}
				currentNamespace.pop_back();
				break;
			}
			case Token::Type::EndOfFile:
				goto parsing_finished;
			default:
			unknown_token:
				cerr << "ERROR: At line: " << it->line << " col: " << it->col << "\n"
				     << "  Unexpected token: " << (int)it->type << ": " << it->strValue << "\n";
				exit(1);
		}
	}
	parsing_finished:

	return f;
}
<|endoftext|>


<commit_before>#include <stdexcept>
#include "ClassFile.h"
#include "InputStream.h"

namespace
{
uint32_t readUnsigned(InputStream* fp, int n)
{
  uint8_t buf[256];

  fp->read(buf, n);

  uint32_t val = 0;

  for(int i = 0; i < n; ++i)
  {
    val <<= 8;
    val |= buf[i];
  }

  return val;
}

uint16_t readWord(InputStream* fp)
{
  return readUnsigned(fp, 2);
}

struct Parser
{
  ClassFile m_class;

  void parse(InputStream* fp)
  {
    parseHeader(fp);
    parseConstPool(fp);
    parseFlagAndClass(fp);
    parseInterface(fp);
    parseField(fp);
    parseMethod(fp);
    parseAttr(fp);
  }

  void parseHeader(InputStream* fp)
  {
    auto const magic = readUnsigned(fp, 4);

    if(magic != 0xCAFEBABE)
      throw runtime_error("invalid magic");

    m_class.minor_version = readWord(fp);
    m_class.major_version = readWord(fp);
  }

  void parseConstPool(InputStream* fp)
  {
    m_class.const_pool_count = readWord(fp);

    m_class.const_pool.resize(m_class.const_pool_count);

    for(size_t i = 1; i < m_class.const_pool_count; ++i)   // no use index 0
    {
      uint8_t tag = readUnsigned(fp, 1);

      parseConstPoolContents(m_class.const_pool[i], fp, tag);

      // those are take two entries
      if((CONSTANT)tag == CONSTANT::Long || (CONSTANT)tag == CONSTANT::Double)
        ++i;
    }
  }

  void parseConstPoolContents(ConstPoolInfo& info, InputStream* fp, uint8_t tag)
  {
    info.tag = (CONSTANT)tag;
    switch((CONSTANT)tag)
    {
    case CONSTANT::Fieldref:
    case CONSTANT::Methodref:
    case CONSTANT::InterfaceMethodref:
      info.class_index = readWord(fp);
      info.name_and_type_index = readWord(fp);
      break;
    case CONSTANT::InvokeDynamic:
      fp->read(info.info, 2);
      fp->read(&info.info[2], 2);
      break;
    case CONSTANT::NameAndType:
      info.name_index = readWord(fp);
      info.descriptor_index = readWord(fp);
      break;
    case CONSTANT::Class:
      info.name_index = readWord(fp);
      break;
    case CONSTANT::String:
    case CONSTANT::MethodType:
      fp->read(info.info, 2);
      break;
    case CONSTANT::Integer:
    case CONSTANT::Float:
      fp->read(info.info, 4);
      break;
    case CONSTANT::Long:
    case CONSTANT::Double:
      fp->read(info.info, 4);
      fp->read(&info.info[4], 4);
      break;
    case CONSTANT::Utf8:
      {
        auto const len = readWord(fp);
        info.utf8.resize(len);
        fp->read((uint8_t*)info.utf8.data(), len);
      }
      break;
    case CONSTANT::MethodHandle:
      fp->read(info.info, 1);
      fp->read(&info.info[1], 2);
      break;
    default:
      throw runtime_error("unsupported constant pool tag");
    }
  }

  void parseFlagAndClass(InputStream* fp)
  {
    m_class.access_flags = readWord(fp);
    m_class.this_class = readWord(fp);
    m_class.super_class = readWord(fp);
  }

  void parseInterface(InputStream* fp)
  {
    auto const interfaceCount = readWord(fp);
    m_class.interfaces.resize(interfaceCount);

    for(auto& itf : m_class.interfaces)
      itf = readWord(fp);
  }

  void parseField(InputStream* fp)
  {
    auto const fieldCount = readWord(fp);
    m_class.fields.resize(fieldCount);

    for(auto& field : m_class.fields)
    {
      field.access_flags = readWord(fp);
      field.name_index = readWord(fp);
      field.descriptor_index = readWord(fp);
      field.attrs_count = readWord(fp);

      parseAttrInner(field.attrs, field.attrs_count, fp);
    }
  }

  void parseMethod(InputStream* fp)
  {
    auto const methodCount = readWord(fp);
    m_class.methods.resize(methodCount);

    for(auto& method : m_class.methods)
    {
      method.access_flags = readWord(fp);
      method.name_index = readWord(fp);
      method.descriptor_index = readWord(fp);
      method.attrs_count = readWord(fp);

      parseAttrInner(method.attrs, method.attrs_count, fp);
    }
  }

  void parseAttr(InputStream* fp)
  {
    m_class.attrs_count = readWord(fp);

    parseAttrInner(m_class.attrs, m_class.attrs_count, fp);
  }

  void parseAttrInner(vector<AttrInfo>& info, size_t num, InputStream* fp)
  {
    info.resize(num);

    for(auto& inf : info)
    {
      inf.attr_name_index = readWord(fp);
      inf.attr_len = readUnsigned(fp, 4);

      parseAttrInnerInner(inf.info, inf.attr_len, fp);
    }
  }

  void parseAttrInnerInner(vector<uint8_t>& info, size_t num, InputStream* fp)
  {
    info.resize(num);

    for(auto& inf : info)
      fp->read(&inf, 1);
  }
};
}

// module entry point
ClassFile parseClass(InputStream* fp)
{
  Parser p;
  p.parse(fp);

  return p.m_class;
}

<commit_msg>Cosmetics<commit_after>#include <stdexcept>
#include "ClassFile.h"
#include "InputStream.h"

namespace
{
uint32_t readUnsigned(InputStream* fp, int n)
{
  uint8_t buf[256];

  fp->read(buf, n);

  uint32_t val = 0;

  for(int i = 0; i < n; ++i)
  {
    val <<= 8;
    val |= buf[i];
  }

  return val;
}

uint16_t readWord(InputStream* fp)
{
  return readUnsigned(fp, 2);
}

struct Parser
{
  ClassFile m_class;

  void parse(InputStream* fp)
  {
    parseHeader(fp);
    parseConstPool(fp);
    parseFlagAndClass(fp);
    parseInterface(fp);
    parseField(fp);
    parseMethod(fp);
    parseAttr(fp);
  }

  void parseHeader(InputStream* fp)
  {
    auto const magic = readUnsigned(fp, 4);

    if(magic != 0xCAFEBABE)
      throw runtime_error("invalid magic");

    m_class.minor_version = readWord(fp);
    m_class.major_version = readWord(fp);
  }

  void parseConstPool(InputStream* fp)
  {
    m_class.const_pool_count = readWord(fp);

    m_class.const_pool.resize(m_class.const_pool_count);

    for(size_t i = 1; i < m_class.const_pool_count; ++i)   // no use index 0
    {
      uint8_t tag = readUnsigned(fp, 1);

      parseConstPoolContents(m_class.const_pool[i], fp, tag);

      // those take two entries
      if((CONSTANT)tag == CONSTANT::Long || (CONSTANT)tag == CONSTANT::Double)
        ++i;
    }
  }

  void parseConstPoolContents(ConstPoolInfo& info, InputStream* fp, uint8_t tag)
  {
    info.tag = (CONSTANT)tag;
    switch(info.tag)
    {
    case CONSTANT::Fieldref:
    case CONSTANT::Methodref:
    case CONSTANT::InterfaceMethodref:
      info.class_index = readWord(fp);
      info.name_and_type_index = readWord(fp);
      break;
    case CONSTANT::InvokeDynamic:
      fp->read(info.info, 2);
      fp->read(&info.info[2], 2);
      break;
    case CONSTANT::NameAndType:
      info.name_index = readWord(fp);
      info.descriptor_index = readWord(fp);
      break;
    case CONSTANT::Class:
      info.name_index = readWord(fp);
      break;
    case CONSTANT::String:
    case CONSTANT::MethodType:
      fp->read(info.info, 2);
      break;
    case CONSTANT::Integer:
    case CONSTANT::Float:
      fp->read(info.info, 4);
      break;
    case CONSTANT::Long:
    case CONSTANT::Double:
      fp->read(info.info, 4);
      fp->read(&info.info[4], 4);
      break;
    case CONSTANT::Utf8:
      {
        auto const len = readWord(fp);
        info.utf8.resize(len);
        fp->read((uint8_t*)info.utf8.data(), len);
      }
      break;
    case CONSTANT::MethodHandle:
      fp->read(info.info, 1);
      fp->read(&info.info[1], 2);
      break;
    default:
      throw runtime_error("unsupported constant pool tag");
    }
  }

  void parseFlagAndClass(InputStream* fp)
  {
    m_class.access_flags = readWord(fp);
    m_class.this_class = readWord(fp);
    m_class.super_class = readWord(fp);
  }

  void parseInterface(InputStream* fp)
  {
    auto const interfaceCount = readWord(fp);
    m_class.interfaces.resize(interfaceCount);

    for(auto& itf : m_class.interfaces)
      itf = readWord(fp);
  }

  void parseField(InputStream* fp)
  {
    auto const fieldCount = readWord(fp);
    m_class.fields.resize(fieldCount);

    for(auto& field : m_class.fields)
    {
      field.access_flags = readWord(fp);
      field.name_index = readWord(fp);
      field.descriptor_index = readWord(fp);
      field.attrs_count = readWord(fp);

      parseAttrInner(field.attrs, field.attrs_count, fp);
    }
  }

  void parseMethod(InputStream* fp)
  {
    auto const methodCount = readWord(fp);
    m_class.methods.resize(methodCount);

    for(auto& method : m_class.methods)
    {
      method.access_flags = readWord(fp);
      method.name_index = readWord(fp);
      method.descriptor_index = readWord(fp);
      method.attrs_count = readWord(fp);

      parseAttrInner(method.attrs, method.attrs_count, fp);
    }
  }

  void parseAttr(InputStream* fp)
  {
    m_class.attrs_count = readWord(fp);

    parseAttrInner(m_class.attrs, m_class.attrs_count, fp);
  }

  void parseAttrInner(vector<AttrInfo>& info, size_t num, InputStream* fp)
  {
    info.resize(num);

    for(auto& inf : info)
    {
      inf.attr_name_index = readWord(fp);
      inf.attr_len = readUnsigned(fp, 4);

      parseAttrInnerInner(inf.info, inf.attr_len, fp);
    }
  }

  void parseAttrInnerInner(vector<uint8_t>& info, size_t num, InputStream* fp)
  {
    info.resize(num);

    for(auto& inf : info)
      fp->read(&inf, 1);
  }
};
}

// module entry point
ClassFile parseClass(InputStream* fp)
{
  Parser p;
  p.parse(fp);

  return p.m_class;
}

<|endoftext|>


<commit_before>#include "WeibullRand.h"

WeibullRand::WeibullRand(double scale, double shape)
{
    setParameters(scale, shape);
}

std::string WeibullRand::name()
{
    return "Weibull(" + toStringWithPrecision(getShape()) + ", " + toStringWithPrecision(getScale()) + ")";
}

void WeibullRand::setParameters(double scale, double shape)
{
    lambda = std::max(scale, MIN_POSITIVE);
    k = std::max(shape, MIN_POSITIVE);
    lambdaInv = 1.0 / lambda;
    kInv = 1.0 / k;
}

double WeibullRand::f(double x) const
{
    if (x <= 0)
        return 0;
    double xAdj = x * lambdaInv;
    double xAdjPow = std::pow(xAdj, k - 1);
    return k * lambdaInv * xAdjPow * std::exp(-xAdj * xAdjPow);
}

double WeibullRand::F(double x) const
{
    if (x <= 0)
        return 0;
    return 1 - std::exp(-std::pow(x * lambdaInv, k));
}

double WeibullRand::variate() const
{
    return lambda * std::pow(ExponentialRand::standardVariate(), kInv);
}

double WeibullRand::Mean() const
{
    return lambda * std::tgamma(1 + kInv);
}

double WeibullRand::Variance() const
{
    double res = std::tgamma(1 + kInv);
    res *= res;
    res += std::tgamma(1 + kInv + kInv);
    return lambda * lambda * res;
}

double WeibullRand::Median() const
{
    return lambda * std::pow(M_LN2, kInv);
}

double WeibullRand::Mode() const
{
    if (k < 1)
        return INFINITY;
    return lambda * std::pow(1 - kInv, kInv);
}

double WeibullRand::Skewness() const
{
    double mu = Mean();
    double var = Variance();
    double sigma = std::sqrt(var);
    double numerator = std::tgamma(1 + 3.0 * kInv);
    numerator *= lambda * lambda * lambda;
    numerator -= 3 * mu * var;
    numerator -= mu * mu * mu;
    double denominator = var * sigma;
    return numerator / denominator;
}

double WeibullRand::ExcessKurtosis() const
{
    double mu = Mean();
    double var = Variance();
    double sigma = std::sqrt(var);
    double skewness = Skewness();
    double numerator = lambda * lambda;
    numerator *= numerator;
    numerator *= std::tgamma(1 + 4.0 * kInv);
    numerator -= 4 * skewness * var * sigma * mu;
    double mu2 = mu * mu;
    numerator -= 6 * mu2 * var;
    numerator -= mu2 * mu2;
    double kurtosis = numerator / (var * var);
    return kurtosis - 3;
}
<commit_msg>Update WeibullRand.cpp<commit_after>#include "WeibullRand.h"

WeibullRand::WeibullRand(double scale, double shape)
{
    setParameters(scale, shape);
}

std::string WeibullRand::name()
{
    return "Weibull(" + toStringWithPrecision(getShape()) + ", " + toStringWithPrecision(getScale()) + ")";
}

void WeibullRand::setParameters(double scale, double shape)
{
    lambda = scale;
    if (lambda <= 0)
        lambda = MIN_POSITIVE;
    lambdaInv = 1.0 / lambda;

    k = shape;
    if (k <= 0)
        k = MIN_POSITIVE;
    kInv = 1.0 / k;
}

double WeibullRand::f(double x) const
{
    if (x <= 0)
        return 0;
    double xAdj = x * lambdaInv;
    double xAdjPow = std::pow(xAdj, k - 1);
    return k * lambdaInv * xAdjPow * std::exp(-xAdj * xAdjPow);
}

double WeibullRand::F(double x) const
{
    if (x <= 0)
        return 0;
    return 1 - std::exp(-std::pow(x * lambdaInv, k));
}

double WeibullRand::variate() const
{
    return lambda * std::pow(ExponentialRand::standardVariate(), kInv);
}

double WeibullRand::Mean() const
{
    return lambda * std::tgamma(1 + kInv);
}

double WeibullRand::Variance() const
{
    double res = std::tgamma(1 + kInv);
    res *= res;
    res += std::tgamma(1 + kInv + kInv);
    return lambda * lambda * res;
}

double WeibullRand::Median() const
{
    return lambda * std::pow(M_LN2, kInv);
}

double WeibullRand::Mode() const
{
    if (k < 1)
        return INFINITY;
    return lambda * std::pow(1 - kInv, kInv);
}

double WeibullRand::Skewness() const
{
    double mu = Mean();
    double var = Variance();
    double sigma = std::sqrt(var);
    double numerator = std::tgamma(1 + 3.0 * kInv);
    numerator *= lambda * lambda * lambda;
    numerator -= 3 * mu * var;
    numerator -= mu * mu * mu;
    double denominator = var * sigma;
    return numerator / denominator;
}

double WeibullRand::ExcessKurtosis() const
{
    double mu = Mean();
    double var = Variance();
    double sigma = std::sqrt(var);
    double skewness = Skewness();
    double numerator = lambda * lambda;
    numerator *= numerator;
    numerator *= std::tgamma(1 + 4.0 * kInv);
    numerator -= 4 * skewness * var * sigma * mu;
    double mu2 = mu * mu;
    numerator -= 6 * mu2 * var;
    numerator -= mu2 * mu2;
    double kurtosis = numerator / (var * var);
    return kurtosis - 3;
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// 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
//
//     https://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 "google/cloud/internal/async_polling_loop.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/log.h"
#include <algorithm>
#include <mutex>
#include <string>

namespace google {
namespace cloud {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {

using ::google::longrunning::Operation;

class AsyncPollingLoopImpl
    : public std::enable_shared_from_this<AsyncPollingLoopImpl> {
 public:
  AsyncPollingLoopImpl(google::cloud::CompletionQueue cq,
                       AsyncPollLongRunningOperation poll,
                       AsyncCancelLongRunningOperation cancel,
                       std::unique_ptr<PollingPolicy> polling_policy,
                       std::string location)
      : cq_(std::move(cq)),
        poll_(std::move(poll)),
        cancel_(std::move(cancel)),
        polling_policy_(std::move(polling_policy)),
        location_(std::move(location)),
        promise_(null_promise_t{}) {}

  future<StatusOr<Operation>> Start(future<StatusOr<Operation>> op) {
    auto self = shared_from_this();
    auto w = WeakFromThis();
    auto const& options = CurrentOptions();
    promise_ = promise<StatusOr<Operation>>([w, options]() mutable {
      if (auto self = w.lock()) {
        OptionsSpan span(std::move(options));
        self->DoCancel();
      }
    });
    op.then([self](future<StatusOr<Operation>> f) { self->OnStart(f.get()); });
    return promise_.get_future();
  }

 private:
  using TimerResult = future<StatusOr<std::chrono::system_clock::time_point>>;

  std::weak_ptr<AsyncPollingLoopImpl> WeakFromThis() {
    return shared_from_this();
  }

  void DoCancel() {
    google::longrunning::CancelOperationRequest request;
    {
      std::unique_lock<std::mutex> lk(mu_);
      if (op_name_.empty()) {
        delayed_cancel_ = true;  // Wait for OnStart() to set `op_name_`.
        return;
      }
      request.set_name(op_name_);
    }
    // Cancels are best effort, so we use weak pointers.
    auto w = WeakFromThis();
    auto context = absl::make_unique<grpc::ClientContext>();
    ConfigurePollContext(*context, CurrentOptions());
    cancel_(cq_, std::move(context), request).then([w](future<Status> f) {
      if (auto self = w.lock()) self->OnCancel(f.get());
    });
  }

  void OnCancel(Status const& status) {
    GCP_LOG(DEBUG) << location_ << "() cancelled: " << status;
  }

  void OnStart(StatusOr<Operation> op) {
    if (!op || op->done()) return promise_.set_value(std::move(op));
    GCP_LOG(DEBUG) << location_ << "() polling loop starting for "
                   << op->name();
    bool do_cancel = false;
    {
      std::unique_lock<std::mutex> lk(mu_);
      std::swap(delayed_cancel_, do_cancel);
      op_name_ = std::move(*op->mutable_name());
    }
    if (do_cancel) DoCancel();
    return Wait();
  }

  void Wait() {
    std::chrono::milliseconds duration = polling_policy_->WaitPeriod();
    GCP_LOG(DEBUG) << location_ << "() polling loop waiting "
                   << duration.count() << "ms";
    auto self = shared_from_this();
    cq_.MakeRelativeTimer(duration).then(
        [self](TimerResult f) { self->OnTimer(std::move(f)); });
  }

  void OnTimer(TimerResult f) {
    GCP_LOG(DEBUG) << location_ << "() polling loop awakened";
    auto t = f.get();
    if (!t) return promise_.set_value(std::move(t).status());
    google::longrunning::GetOperationRequest request;
    {
      std::unique_lock<std::mutex> lk(mu_);
      request.set_name(op_name_);
    }
    auto self = shared_from_this();
    auto context = absl::make_unique<grpc::ClientContext>();
    ConfigurePollContext(*context, CurrentOptions());
    poll_(cq_, std::move(context), request)
        .then([self](future<StatusOr<Operation>> g) {
          self->OnPoll(std::move(g));
        });
  }

  void OnPoll(future<StatusOr<Operation>> f) {
    GCP_LOG(DEBUG) << location_ << "() polling loop result";
    auto op = f.get();
    if (op && op->done()) {
      return promise_.set_value(*std::move(op));
    }
    // Update the polling policy even on successful requests, so we can stop
    // after too many polling attempts.
    if (!polling_policy_->OnFailure(op.status())) {
      if (op) {
        // We should not be fabricating a `Status` value here. Rather, we
        // should cancel the operation and wait for the next poll to return
        // an accurate status to the user, otherwise they will have no idea
        // how to react.
        return promise_.set_value(Status(
            StatusCode::kDeadlineExceeded,
            location_ + "() - polling loop terminated by polling policy"));
      }
      return promise_.set_value(std::move(op).status());
    }
    if (op) {
      std::unique_lock<std::mutex> lk(mu_);
      op_name_ = std::move(*op->mutable_name());
    }
    return Wait();
  }

  // These member variables are initialized in the constructor or from
  // `Start()`, and then only used from the `On*()` callbacks, which are
  // serialized, so they need no external synchronization.
  google::cloud::CompletionQueue cq_;
  AsyncPollLongRunningOperation poll_;
  AsyncCancelLongRunningOperation cancel_;
  std::unique_ptr<PollingPolicy> polling_policy_;
  std::string location_;
  promise<StatusOr<Operation>> promise_;

  // `delayed_cancel_` and `op_name_`, in contrast, are also used from
  // `DoCancel()`, which is called asynchronously, so they need locking.
  std::mutex mu_;
  bool delayed_cancel_ = false;  // GUARDED_BY(mu_)
  std::string op_name_;          // GUARDED_BY(mu_)
};

future<StatusOr<Operation>> AsyncPollingLoop(
    google::cloud::CompletionQueue cq, future<StatusOr<Operation>> op,
    AsyncPollLongRunningOperation poll, AsyncCancelLongRunningOperation cancel,
    std::unique_ptr<PollingPolicy> polling_policy, std::string location) {
  auto loop = std::make_shared<AsyncPollingLoopImpl>(
      std::move(cq), std::move(poll), std::move(cancel),
      std::move(polling_policy), std::move(location));
  return loop->Start(std::move(op));
}

}  // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace cloud
}  // namespace google
<commit_msg>impl(spanner): carry over some updates to AsyncPollingLoopImpl::OnPoll() (#8756)<commit_after>// Copyright 2021 Google LLC
//
// 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
//
//     https://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 "google/cloud/internal/async_polling_loop.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/log.h"
#include <algorithm>
#include <mutex>
#include <string>

namespace google {
namespace cloud {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {

using ::google::longrunning::Operation;

class AsyncPollingLoopImpl
    : public std::enable_shared_from_this<AsyncPollingLoopImpl> {
 public:
  AsyncPollingLoopImpl(google::cloud::CompletionQueue cq,
                       AsyncPollLongRunningOperation poll,
                       AsyncCancelLongRunningOperation cancel,
                       std::unique_ptr<PollingPolicy> polling_policy,
                       std::string location)
      : cq_(std::move(cq)),
        poll_(std::move(poll)),
        cancel_(std::move(cancel)),
        polling_policy_(std::move(polling_policy)),
        location_(std::move(location)),
        promise_(null_promise_t{}) {}

  future<StatusOr<Operation>> Start(future<StatusOr<Operation>> op) {
    auto self = shared_from_this();
    auto w = WeakFromThis();
    auto const& options = CurrentOptions();
    promise_ = promise<StatusOr<Operation>>([w, options]() mutable {
      if (auto self = w.lock()) {
        OptionsSpan span(std::move(options));
        self->DoCancel();
      }
    });
    op.then([self](future<StatusOr<Operation>> f) { self->OnStart(f.get()); });
    return promise_.get_future();
  }

 private:
  using TimerResult = future<StatusOr<std::chrono::system_clock::time_point>>;

  std::weak_ptr<AsyncPollingLoopImpl> WeakFromThis() {
    return shared_from_this();
  }

  void DoCancel() {
    google::longrunning::CancelOperationRequest request;
    {
      std::unique_lock<std::mutex> lk(mu_);
      if (op_name_.empty()) {
        delayed_cancel_ = true;  // Wait for OnStart() to set `op_name_`.
        return;
      }
      request.set_name(op_name_);
    }
    // Cancels are best effort, so we use weak pointers.
    auto w = WeakFromThis();
    auto context = absl::make_unique<grpc::ClientContext>();
    ConfigurePollContext(*context, CurrentOptions());
    cancel_(cq_, std::move(context), request).then([w](future<Status> f) {
      if (auto self = w.lock()) self->OnCancel(f.get());
    });
  }

  void OnCancel(Status const& status) {
    GCP_LOG(DEBUG) << location_ << "() cancelled: " << status;
  }

  void OnStart(StatusOr<Operation> op) {
    if (!op || op->done()) return promise_.set_value(std::move(op));
    GCP_LOG(DEBUG) << location_ << "() polling loop starting for "
                   << op->name();
    bool do_cancel = false;
    {
      std::unique_lock<std::mutex> lk(mu_);
      std::swap(delayed_cancel_, do_cancel);
      op_name_ = std::move(*op->mutable_name());
    }
    if (do_cancel) DoCancel();
    return Wait();
  }

  void Wait() {
    std::chrono::milliseconds duration = polling_policy_->WaitPeriod();
    GCP_LOG(DEBUG) << location_ << "() polling loop waiting "
                   << duration.count() << "ms";
    auto self = shared_from_this();
    cq_.MakeRelativeTimer(duration).then(
        [self](TimerResult f) { self->OnTimer(std::move(f)); });
  }

  void OnTimer(TimerResult f) {
    GCP_LOG(DEBUG) << location_ << "() polling loop awakened";
    auto t = f.get();
    if (!t) return promise_.set_value(std::move(t).status());
    google::longrunning::GetOperationRequest request;
    {
      std::unique_lock<std::mutex> lk(mu_);
      request.set_name(op_name_);
    }
    auto self = shared_from_this();
    auto context = absl::make_unique<grpc::ClientContext>();
    ConfigurePollContext(*context, CurrentOptions());
    poll_(cq_, std::move(context), request)
        .then([self](future<StatusOr<Operation>> g) {
          self->OnPoll(std::move(g));
        });
  }

  void OnPoll(future<StatusOr<Operation>> f) {
    GCP_LOG(DEBUG) << location_ << "() polling loop result";
    auto op = f.get();
    if (op && op->done()) {
      return promise_.set_value(*std::move(op));
    }
    // Update the polling policy even on successful requests, so we can stop
    // after too many polling attempts.
    if (!polling_policy_->OnFailure(op.status())) {
      if (op) {
        // We should not be fabricating a `Status` value here. Rather, we
        // should cancel the operation and wait for the next poll to return
        // an accurate status to the user, otherwise they will have no idea
        // how to react. But for now, we leave the operation running. It
        // may eventually complete.
        return promise_.set_value(Status(
            StatusCode::kDeadlineExceeded,
            location_ + "() - polling loop terminated by polling policy"));
      }
      // This could be a transient error if the policy is exhausted.
      return promise_.set_value(std::move(op).status());
    }
    return Wait();
  }

  // These member variables are initialized in the constructor or from
  // `Start()`, and then only used from the `On*()` callbacks, which are
  // serialized, so they need no external synchronization.
  google::cloud::CompletionQueue cq_;
  AsyncPollLongRunningOperation poll_;
  AsyncCancelLongRunningOperation cancel_;
  std::unique_ptr<PollingPolicy> polling_policy_;
  std::string location_;
  promise<StatusOr<Operation>> promise_;

  // `delayed_cancel_` and `op_name_`, in contrast, are also used from
  // `DoCancel()`, which is called asynchronously, so they need locking.
  std::mutex mu_;
  bool delayed_cancel_ = false;  // GUARDED_BY(mu_)
  std::string op_name_;          // GUARDED_BY(mu_)
};

future<StatusOr<Operation>> AsyncPollingLoop(
    google::cloud::CompletionQueue cq, future<StatusOr<Operation>> op,
    AsyncPollLongRunningOperation poll, AsyncCancelLongRunningOperation cancel,
    std::unique_ptr<PollingPolicy> polling_policy, std::string location) {
  auto loop = std::make_shared<AsyncPollingLoopImpl>(
      std::move(cq), std::move(poll), std::move(cancel),
      std::move(polling_policy), std::move(location));
  return loop->Start(std::move(op));
}

}  // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace cloud
}  // namespace google
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: gtkframe.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 15:28:41 $
 *
 *  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 _VCL_GTKFRAME_HXX
#define _VCL_GTKFRAME_HXX

#include <prex.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <postx.h>

#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_SYSDATA_HXX
#include <sysdata.hxx>
#endif

#include <list>

class X11SalGraphics;
class GtkSalDisplay;

class GtkSalFrame : public SalFrame
{
    static const int nMaxGraphics = 2;

    struct GraphicsHolder
    {
        X11SalGraphics*     pGraphics;
        bool                bInUse;
        GraphicsHolder()
                : pGraphics( NULL ),
                  bInUse( false )
        {}
        ~GraphicsHolder();
    };

    //--------------------------------------------------------
    // Not all GTK Input Methods swallow key release
    // events.  Since they swallow the key press events and we
    // are left with the key release events, we need to
    // manually swallow those.  To do this, we keep a list of
    // the previous 10 key press events in each GtkSalFrame
    // and when we get a key release that matches one of the
    // key press events in our list, we swallow it.
    struct PreviousKeyPress
    {
        GdkWindow *window;
        gint8   send_event;
        guint32 time;
        guint   state;
        guint   keyval;

        PreviousKeyPress (GdkEventKey *event)
        :   window (NULL),
            send_event (0),
            time (0),
            state (0),
            keyval (0)
        {
            if (event)
            {
                window = event->window;
                send_event = event->send_event;
                time = event->time;
                state = event->state;
                keyval = event->keyval;
            }
        }

        PreviousKeyPress( const PreviousKeyPress& rPrev )
        :   window( rPrev.window ),
            send_event( rPrev.send_event ),
            time( rPrev.time ),
            state( rPrev.state ),
            keyval( rPrev.keyval )
        {}

        bool PreviousKeyPress::operator== (GdkEventKey *event) const
        {
            return (event != NULL)
                && (event->window == window)
                && (event->send_event == send_event)
                && (event->state == state)
                && (event->keyval == keyval)
                && (event->time - time < 3)
                ;
        }
    };

    GtkWindow*                      m_pWindow;
    GdkWindow*                      m_pForeignParent;
    GdkWindow*                      m_pForeignTopLevel;
    ULONG                           m_nStyle;
    GtkFixed*                       m_pFixedContainer;
    GtkSalFrame*                    m_pParent;
    GdkWindowState                  m_nState;
    GtkIMContext*                   m_pIMContext;
    SystemEnvData                   m_aSystemData;
    GraphicsHolder                  m_aGraphics[ nMaxGraphics ];
    USHORT                          m_nKeyModifiers;
    GdkCursor                      *m_pCurrentCursor;
    GdkVisibilityState              m_nVisibility;
    int                             m_nSavedScreenSaverTimeout;
    bool                            m_bFullscreen;
    bool                            m_bSingleAltPress;
    bool                            m_bDefaultPos;
    bool                            m_bDefaultSize;
    bool                            m_bSendModChangeOnRelease;
    bool                            m_bWasPreedit;

    Size                            m_aMaxSize;
    Size                            m_aMinSize;

    std::list< PreviousKeyPress >   m_aPrevKeyPresses;
    int                             m_nPrevKeyPresses; // avoid using size()

    void Init( SalFrame* pParent, ULONG nStyle );
    void Init( SystemParentData* pSysData );
    void InitCommon();

    // signals
    static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
    static void         signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer );
    static gboolean     signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
    static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
    static gboolean     signalMap( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalUnmap( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer );
    static gboolean     signalMotion( GtkWidget*, GdkEventMotion*, gpointer );
    static gboolean     signalKey( GtkWidget*, GdkEventKey*, gpointer );
    static gboolean     signalDelete( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalState( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalScroll( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer );
    static gboolean     signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer );
    static void         signalIMCommit( GtkIMContext*, gchar*, gpointer );
    static gboolean     signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
    static void         signalIMPreeditChanged( GtkIMContext*, gpointer );
    static void         signalIMPreeditEnd( GtkIMContext*, gpointer );
    static void         signalIMPreeditStart( GtkIMContext*, gpointer );
    static gboolean     signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
    static void         signalDestroy( GtkObject*, gpointer );

    GtkSalDisplay*  getDisplay();
    GdkDisplay*     getGdkDisplay();
    void            Center();
    void            SetDefaultSize();
    void            setAutoLock( bool bLock );
    void            setScreenSaverTimeout( int nTimeout );

    GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );

    static int m_nFloats;

    bool isFloatGrabWindow() const
    {
        return
            (m_nStyle & SAL_FRAME_STYLE_FLOAT) &&       // only a float can be floatgrab
            !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) &&    // tool tips are not
            !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION); // toolbars are also not
    }

    Size calcDefaultSize();

    void setMinMaxSize();
    void updateIMSpotLocation();
public:
    GtkSalFrame( SalFrame* pParent, ULONG nStyle );
    GtkSalFrame( SystemParentData* pSysData );

    // dispatches an event, returns true if dispatched
    // and false else; if true was returned the event should
    // be swallowed
    bool Dispatch( const XEvent* pEvent );
    void grabPointer( BOOL bGrab, BOOL bOwnerEvents = FALSE );

    GtkWindow*  getWindow() const { return m_pWindow; }
    GtkFixed*   getFixedContainer() const { return m_pFixedContainer; }
    GdkWindow*  getForeignParent() const { return m_pForeignParent; }
    GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
    GdkWindow*  getForeignTopLevel() const { return m_pForeignTopLevel; }
    GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
    GdkVisibilityState getVisibilityState() const
    { return m_nVisibility; }

    virtual ~GtkSalFrame();

    // SalGraphics or NULL, but two Graphics for all SalFrames
    // must be returned
    virtual SalGraphics*        GetGraphics();
    virtual void                ReleaseGraphics( SalGraphics* pGraphics );

    // Event must be destroyed, when Frame is destroyed
    // When Event is called, SalInstance::Yield() must be returned
    virtual BOOL                PostEvent( void* pData );

    virtual void                SetTitle( const XubString& rTitle );
    virtual void                SetIcon( USHORT nIcon );
    virtual void                SetMenu( SalMenu *pSalMenu );
    virtual void                DrawMenuBar();

    // Before the window is visible, a resize event
    // must be sent with the correct size
    virtual void                Show( BOOL bVisible, BOOL bNoActivate = FALSE );
    virtual void                Enable( BOOL bEnable );
    // Set ClientSize and Center the Window to the desktop
    // and send/post a resize message
    virtual void                SetMinClientSize( long nWidth, long nHeight );
    virtual void                SetMaxClientSize( long nWidth, long nHeight );
    virtual void                SetPosSize( long nX, long nY, long nWidth, long nHeight, USHORT nFlags );
    virtual void                GetClientSize( long& rWidth, long& rHeight );
    virtual void                GetWorkArea( Rectangle& rRect );
    virtual SalFrame*           GetParent() const;
    virtual void                SetWindowState( const SalFrameState* pState );
    virtual BOOL                GetWindowState( SalFrameState* pState );
    virtual void                ShowFullScreen( BOOL bFullScreen );
    // Enable/Disable ScreenSaver, SystemAgents, ...
    virtual void                StartPresentation( BOOL bStart );
    // Show Window over all other Windows
    virtual void                SetAlwaysOnTop( BOOL bOnTop );

    // Window to top and grab focus
    virtual void                ToTop( USHORT nFlags );

    // this function can call with the same
    // pointer style
    virtual void                SetPointer( PointerStyle ePointerStyle );
    virtual void                CaptureMouse( BOOL bMouse );
    virtual void                SetPointerPos( long nX, long nY );

    // flush output buffer
    virtual void                Flush();
    // flush output buffer, wait till outstanding operations are done
    virtual void                Sync();

    virtual void                SetInputContext( SalInputContext* pContext );
    virtual void                EndExtTextInput( USHORT nFlags );

    virtual String              GetKeyName( USHORT nKeyCode );
    virtual String              GetSymbolKeyName( const XubString& rFontName, USHORT nKeyCode );

    // returns the input language used for the last key stroke
    // may be LANGUAGE_DONTKNOW if not supported by the OS
    virtual LanguageType        GetInputLanguage();

    virtual SalBitmap*          SnapShot();

    virtual void                UpdateSettings( AllSettings& rSettings );

    virtual void                Beep( SoundType eSoundType );

    // returns system data (most prominent: window handle)
    virtual const SystemEnvData*    GetSystemData() const;

    // get current modifier and button mask
    virtual SalPointerState     GetPointerState();

    // set new parent window
    virtual void                SetParent( SalFrame* pNewParent );
    // reparent window to act as a plugin; implementation
    // may choose to use a new system window internally
    // return false to indicate failure
    virtual bool                SetPluginParent( SystemParentData* pNewParent );

};

#endif //_VCL_GTKFRAME_HXX
<commit_msg>#i10000# merge problem, missing members<commit_after>/*************************************************************************
 *
 *  $RCSfile: gtkframe.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-22 10:13:44 $
 *
 *  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 _VCL_GTKFRAME_HXX
#define _VCL_GTKFRAME_HXX

#include <prex.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <postx.h>

#ifndef _SV_SALFRAME_HXX
#include <salframe.hxx>
#endif
#ifndef _SV_SYSDATA_HXX
#include <sysdata.hxx>
#endif

#include <list>

class X11SalGraphics;
class GtkSalDisplay;

class GtkSalFrame : public SalFrame
{
    static const int nMaxGraphics = 2;

    struct GraphicsHolder
    {
        X11SalGraphics*     pGraphics;
        bool                bInUse;
        GraphicsHolder()
                : pGraphics( NULL ),
                  bInUse( false )
        {}
        ~GraphicsHolder();
    };

    //--------------------------------------------------------
    // Not all GTK Input Methods swallow key release
    // events.  Since they swallow the key press events and we
    // are left with the key release events, we need to
    // manually swallow those.  To do this, we keep a list of
    // the previous 10 key press events in each GtkSalFrame
    // and when we get a key release that matches one of the
    // key press events in our list, we swallow it.
    struct PreviousKeyPress
    {
        GdkWindow *window;
        gint8   send_event;
        guint32 time;
        guint   state;
        guint   keyval;

        PreviousKeyPress (GdkEventKey *event)
        :   window (NULL),
            send_event (0),
            time (0),
            state (0),
            keyval (0)
        {
            if (event)
            {
                window = event->window;
                send_event = event->send_event;
                time = event->time;
                state = event->state;
                keyval = event->keyval;
            }
        }

        PreviousKeyPress( const PreviousKeyPress& rPrev )
        :   window( rPrev.window ),
            send_event( rPrev.send_event ),
            time( rPrev.time ),
            state( rPrev.state ),
            keyval( rPrev.keyval )
        {}

        bool PreviousKeyPress::operator== (GdkEventKey *event) const
        {
            return (event != NULL)
                && (event->window == window)
                && (event->send_event == send_event)
                && (event->state == state)
                && (event->keyval == keyval)
                && (event->time - time < 3)
                ;
        }
    };

    GtkWindow*                      m_pWindow;
    GdkWindow*                      m_pForeignParent;
    GdkNativeWindow                 m_aForeignParentWindow;
    GdkWindow*                      m_pForeignTopLevel;
    GdkNativeWindow                 m_aForeignTopLevelWindow;
    ULONG                           m_nStyle;
    GtkFixed*                       m_pFixedContainer;
    GtkSalFrame*                    m_pParent;
    GdkWindowState                  m_nState;
    GtkIMContext*                   m_pIMContext;
    SystemEnvData                   m_aSystemData;
    GraphicsHolder                  m_aGraphics[ nMaxGraphics ];
    USHORT                          m_nKeyModifiers;
    GdkCursor                      *m_pCurrentCursor;
    GdkVisibilityState              m_nVisibility;
    int                             m_nSavedScreenSaverTimeout;
    bool                            m_bFullscreen;
    bool                            m_bSingleAltPress;
    bool                            m_bDefaultPos;
    bool                            m_bDefaultSize;
    bool                            m_bSendModChangeOnRelease;
    bool                            m_bWasPreedit;

    Size                            m_aMaxSize;
    Size                            m_aMinSize;

    std::list< PreviousKeyPress >   m_aPrevKeyPresses;
    int                             m_nPrevKeyPresses; // avoid using size()

    void Init( SalFrame* pParent, ULONG nStyle );
    void Init( SystemParentData* pSysData );
    void InitCommon();

    // signals
    static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
    static void         signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer );
    static gboolean     signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
    static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
    static gboolean     signalMap( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalUnmap( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer );
    static gboolean     signalMotion( GtkWidget*, GdkEventMotion*, gpointer );
    static gboolean     signalKey( GtkWidget*, GdkEventKey*, gpointer );
    static gboolean     signalDelete( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalState( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalScroll( GtkWidget*, GdkEvent*, gpointer );
    static gboolean     signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer );
    static gboolean     signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer );
    static void         signalIMCommit( GtkIMContext*, gchar*, gpointer );
    static gboolean     signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
    static void         signalIMPreeditChanged( GtkIMContext*, gpointer );
    static void         signalIMPreeditEnd( GtkIMContext*, gpointer );
    static void         signalIMPreeditStart( GtkIMContext*, gpointer );
    static gboolean     signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
    static void         signalDestroy( GtkObject*, gpointer );

    GtkSalDisplay*  getDisplay();
    GdkDisplay*     getGdkDisplay();
    void            Center();
    void            SetDefaultSize();
    void            setAutoLock( bool bLock );
    void            setScreenSaverTimeout( int nTimeout );

    GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );

    static int m_nFloats;

    bool isFloatGrabWindow() const
    {
        return
            (m_nStyle & SAL_FRAME_STYLE_FLOAT) &&       // only a float can be floatgrab
            !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) &&    // tool tips are not
            !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION); // toolbars are also not
    }

    Size calcDefaultSize();

    void setMinMaxSize();
    void updateIMSpotLocation();
public:
    GtkSalFrame( SalFrame* pParent, ULONG nStyle );
    GtkSalFrame( SystemParentData* pSysData );

    // dispatches an event, returns true if dispatched
    // and false else; if true was returned the event should
    // be swallowed
    bool Dispatch( const XEvent* pEvent );
    void grabPointer( BOOL bGrab, BOOL bOwnerEvents = FALSE );

    GtkWindow*  getWindow() const { return m_pWindow; }
    GtkFixed*   getFixedContainer() const { return m_pFixedContainer; }
    GdkWindow*  getForeignParent() const { return m_pForeignParent; }
    GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
    GdkWindow*  getForeignTopLevel() const { return m_pForeignTopLevel; }
    GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
    GdkVisibilityState getVisibilityState() const
    { return m_nVisibility; }

    virtual ~GtkSalFrame();

    // SalGraphics or NULL, but two Graphics for all SalFrames
    // must be returned
    virtual SalGraphics*        GetGraphics();
    virtual void                ReleaseGraphics( SalGraphics* pGraphics );

    // Event must be destroyed, when Frame is destroyed
    // When Event is called, SalInstance::Yield() must be returned
    virtual BOOL                PostEvent( void* pData );

    virtual void                SetTitle( const XubString& rTitle );
    virtual void                SetIcon( USHORT nIcon );
    virtual void                SetMenu( SalMenu *pSalMenu );
    virtual void                DrawMenuBar();

    // Before the window is visible, a resize event
    // must be sent with the correct size
    virtual void                Show( BOOL bVisible, BOOL bNoActivate = FALSE );
    virtual void                Enable( BOOL bEnable );
    // Set ClientSize and Center the Window to the desktop
    // and send/post a resize message
    virtual void                SetMinClientSize( long nWidth, long nHeight );
    virtual void                SetMaxClientSize( long nWidth, long nHeight );
    virtual void                SetPosSize( long nX, long nY, long nWidth, long nHeight, USHORT nFlags );
    virtual void                GetClientSize( long& rWidth, long& rHeight );
    virtual void                GetWorkArea( Rectangle& rRect );
    virtual SalFrame*           GetParent() const;
    virtual void                SetWindowState( const SalFrameState* pState );
    virtual BOOL                GetWindowState( SalFrameState* pState );
    virtual void                ShowFullScreen( BOOL bFullScreen );
    // Enable/Disable ScreenSaver, SystemAgents, ...
    virtual void                StartPresentation( BOOL bStart );
    // Show Window over all other Windows
    virtual void                SetAlwaysOnTop( BOOL bOnTop );

    // Window to top and grab focus
    virtual void                ToTop( USHORT nFlags );

    // this function can call with the same
    // pointer style
    virtual void                SetPointer( PointerStyle ePointerStyle );
    virtual void                CaptureMouse( BOOL bMouse );
    virtual void                SetPointerPos( long nX, long nY );

    // flush output buffer
    virtual void                Flush();
    // flush output buffer, wait till outstanding operations are done
    virtual void                Sync();

    virtual void                SetInputContext( SalInputContext* pContext );
    virtual void                EndExtTextInput( USHORT nFlags );

    virtual String              GetKeyName( USHORT nKeyCode );
    virtual String              GetSymbolKeyName( const XubString& rFontName, USHORT nKeyCode );

    // returns the input language used for the last key stroke
    // may be LANGUAGE_DONTKNOW if not supported by the OS
    virtual LanguageType        GetInputLanguage();

    virtual SalBitmap*          SnapShot();

    virtual void                UpdateSettings( AllSettings& rSettings );

    virtual void                Beep( SoundType eSoundType );

    // returns system data (most prominent: window handle)
    virtual const SystemEnvData*    GetSystemData() const;

    // get current modifier and button mask
    virtual SalPointerState     GetPointerState();

    // set new parent window
    virtual void                SetParent( SalFrame* pNewParent );
    // reparent window to act as a plugin; implementation
    // may choose to use a new system window internally
    // return false to indicate failure
    virtual bool                SetPluginParent( SystemParentData* pNewParent );

};

#endif //_VCL_GTKFRAME_HXX
<|endoftext|>


<commit_before>#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <time.h>
#include <wiringPi.h>
#include "camera.hpp"
#include "../motor.h"

#pragma comment(lib,"opencv_world320.lib")

static const int ROTATE_POWER = 100;
static const int ROTATE_MILLISECONDS = 200;
static const int LEFT_MAX = -100;
static const int RIGHT_MAX = 100;
static const int CENTER_THRESHOLD = 30;//-30~30で直進するようにする
static const double EXIST_THRESHOLD = 0.7;//ゴール存在判定 パーセンテージ
static const int TIME_LIMIT = 600;//10分

//TODO turn millisecondどんどん大きくしていくPI制御にする
int main (void)
{
	time_t startTime;
	time(&startTime);
	time_t lastTime;
	time(&lastTime);
	pwm_initialize();
	while(lastTime-startTime<TIME_LIMIT)
	{
		printf("lastTime - startTime %d\n",lastTime - startTime);
		time(&lastTime);
		cv::Mat red = Mred();
		double count = countArea(red);
		if(count < EXIST_THRESHOLD)
		{
			//回転するだけ
			motor_right(ROTATE_POWER);
			delay(ROTATE_MILLISECONDS);
			motor_stop();
			delay(10);
		}
		else
		{
			//見つけれたら前進
			motor_forward(100);
			delay(400);
			motor_stop();
			delay(10);
		}
	}
	printf("TIME IS OUT\n");
	return 0;
}
<commit_msg>eitst<commit_after>#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <time.h>
#include <wiringPi.h>
#include "camera.hpp"
#include "../motor.h"

#pragma comment(lib,"opencv_world320.lib")

static const int ROTATE_POWER = 100;
static const int ROTATE_MILLISECONDS = 200;
static const int LEFT_MAX = -100;
static const int RIGHT_MAX = 100;
static const int CENTER_THRESHOLD = 30;//-30~30で直進するようにする
static const double EXIST_THRESHOLD = 0.2;//ゴール存在判定 パーセンテージ
static const int TIME_LIMIT = 600;//10分

//TODO turn millisecondどんどん大きくしていくPI制御にする
int main (void)
{
	time_t startTime;
	time(&startTime);
	time_t lastTime;
	time(&lastTime);
	pwm_initialize();
	while(lastTime-startTime<TIME_LIMIT)
	{
		printf("lastTime - startTime %d\n",lastTime - startTime);
		time(&lastTime);
		cv::Mat red = Mred();
		double count = countArea(red);
		if(count < EXIST_THRESHOLD)
		{
			//回転するだけ
			motor_right(ROTATE_POWER);
			delay(ROTATE_MILLISECONDS);
			motor_stop();
			delay(10);
		}
		else
		{
			//見つけれたら前進
			motor_forward(100);
			delay(400);
			motor_stop();
			delay(10);
		}
	}
	printf("TIME IS OUT\n");
	return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "osl/module.h"
#include "osl/process.h"

#include "rtl/ustrbuf.hxx"

#include "vcl/salinst.hxx"
#include "saldata.hxx"

#include <cstdio>
#include <unistd.h>

using namespace rtl;

extern "C" {
typedef SalInstance*(*salFactoryProc)( oslModule pModule);
}

static oslModule pCloseModule = NULL;

enum {
    DESKTOP_NONE = 0,
    DESKTOP_UNKNOWN,
    DESKTOP_GNOME,
    DESKTOP_KDE,
    DESKTOP_KDE4,
    DESKTOP_CDE
};

static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4", "CDE" };

static SalInstance* tryInstance( const OUString& rModuleBase )
{
    SalInstance* pInst = NULL;

    OUStringBuffer aModName( 128 );
    aModName.appendAscii( SAL_DLLPREFIX"vclplug_" );
    aModName.append( rModuleBase );
    aModName.appendAscii( SAL_DLLPOSTFIX );
    aModName.appendAscii( SAL_DLLEXTENSION );
    OUString aModule = aModName.makeStringAndClear();

    oslModule aMod = osl_loadModuleRelative(
        reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
        SAL_LOADMODULE_DEFAULT );
    if( aMod )
    {
        salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" );
        if( aProc )
        {
            pInst = aProc( aMod );
#if OSL_DEBUG_LEVEL > 1
            std::fprintf( stderr, "sal plugin %s produced instance %p\n",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     pInst );
#endif
            if( pInst )
            {
                pCloseModule = aMod;

                /*
                 * Recent GTK+ versions load their modules with RTLD_LOCAL, so we can
                 * not access the 'gnome_accessibility_module_shutdown' anymore.
                 * So make sure libgtk+ & co are still mapped into memory when
                 * atk-bridge's atexit handler gets called.
                 */
                if( rModuleBase.equalsAscii("gtk") )
                {
                    pCloseModule = NULL;
                }

                GetSalData()->m_pPlugin = aMod;
            }
            else
                osl_unloadModule( aMod );
        }
        else
        {
#if OSL_DEBUG_LEVEL > 1
            std::fprintf( stderr, "could not load symbol %s from shared object %s\n",
                     "create_SalInstance",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
            osl_unloadModule( aMod );
        }
    }
#if OSL_DEBUG_LEVEL > 1
    else
        std::fprintf( stderr, "could not load shared object %s\n",
                 OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif

    return pInst;
}

static const rtl::OUString& get_desktop_environment()
{
    static rtl::OUString aRet;
    if( ! aRet.getLength() )
    {
        OUStringBuffer aModName( 128 );
        aModName.appendAscii( SAL_DLLPREFIX"desktop_detector" );
        aModName.appendAscii( SAL_DLLPOSTFIX );
        aModName.appendAscii( SAL_DLLEXTENSION );
        OUString aModule = aModName.makeStringAndClear();

        oslModule aMod = osl_loadModuleRelative(
            reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
            SAL_LOADMODULE_DEFAULT );
        if( aMod )
        {
            rtl::OUString (*pSym)() = (rtl::OUString(*)())
                osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" );
            if( pSym )
                aRet = pSym();
        }
        osl_unloadModule( aMod );
    }
    return aRet;
}

static SalInstance* autodetect_plugin()
{
    static const char* pKDEFallbackList[] =
    {
        "kde4", "kde", "gtk", "gen", 0
    };

    static const char* pStandardFallbackList[] =
    {
        "gtk", "gen", 0
    };

    static const char* pHeadlessFallbackList[] =
    {
        "svp", 0
    };

    const rtl::OUString& desktop( get_desktop_environment() );
    const char ** pList = pStandardFallbackList;
    int nListEntry = 0;

    // no server at all: dummy plugin
    if ( desktop.equalsAscii( desktop_strings[DESKTOP_NONE] ) )
        pList = pHeadlessFallbackList;
    else if ( desktop.equalsAscii( desktop_strings[DESKTOP_GNOME] ) )
        pList = pStandardFallbackList;
    else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE] ) )
    {
        pList = pKDEFallbackList;
        nListEntry = 1;
    }
    else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE4] ) )
        pList = pKDEFallbackList;

    SalInstance* pInst = NULL;
    while( pList[nListEntry] && pInst == NULL )
    {
        rtl::OUString aTry( rtl::OUString::createFromAscii( pList[nListEntry] ) );
        pInst = tryInstance( aTry );
        #if OSL_DEBUG_LEVEL > 1
        if( pInst )
            std::fprintf( stderr, "plugin autodetection: %s\n", pList[nListEntry] );
        #endif
        nListEntry++;
    }

    return pInst;
}

static SalInstance* check_headless_plugin()
{
    int nParams = osl_getCommandArgCount();
    OUString aParam;
    for( int i = 0; i < nParams; i++ )
    {
        osl_getCommandArg( i, &aParam.pData );
        if( aParam.equalsAscii( "-headless" ) )
            return tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "svp" ) ) );
    }
    return NULL;
}

SalInstance *CreateSalInstance()
{
    SalInstance*    pInst = NULL;

    static const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );

    if( !(pUsePlugin && *pUsePlugin) )
        pInst = check_headless_plugin();
    else
        pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );

    if( ! pInst )
        pInst = autodetect_plugin();

    // fallback to gen
    if( ! pInst )
        pInst = tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "gen" ) ) );

    if( ! pInst )
    {
        std::fprintf( stderr, "no suitable windowing system found, exiting.\n" );
        _exit( 1 );
    }

    // acquire SolarMutex
    pInst->AcquireYieldMutex( 1 );

    return pInst;
}

void DestroySalInstance( SalInstance *pInst )
{
    // release SolarMutex
    pInst->ReleaseYieldMutex();

    delete pInst;
    if( pCloseModule )
        osl_unloadModule( pCloseModule );
}

void InitSalData()
{
}

void DeInitSalData()
{
}

void InitSalMain()
{
}

void DeInitSalMain()
{
}

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        std::fprintf( stderr, "Application Error" );
    else
        std::fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

const OUString& SalGetDesktopEnvironment()
{
    return get_desktop_environment();
}

SalData::SalData() :
    m_pInstance(NULL),
    m_pPlugin(NULL)
{
}

SalData::~SalData()
{
}
<commit_msg>vcl110: #i109007# workaround atexit handler in kde3 plugin<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "osl/module.h"
#include "osl/process.h"

#include "rtl/ustrbuf.hxx"

#include "vcl/salinst.hxx"
#include "saldata.hxx"

#include <cstdio>
#include <unistd.h>

using namespace rtl;

extern "C" {
typedef SalInstance*(*salFactoryProc)( oslModule pModule);
}

static oslModule pCloseModule = NULL;

enum {
    DESKTOP_NONE = 0,
    DESKTOP_UNKNOWN,
    DESKTOP_GNOME,
    DESKTOP_KDE,
    DESKTOP_KDE4,
    DESKTOP_CDE
};

static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4", "CDE" };

static SalInstance* tryInstance( const OUString& rModuleBase )
{
    SalInstance* pInst = NULL;

    OUStringBuffer aModName( 128 );
    aModName.appendAscii( SAL_DLLPREFIX"vclplug_" );
    aModName.append( rModuleBase );
    aModName.appendAscii( SAL_DLLPOSTFIX );
    aModName.appendAscii( SAL_DLLEXTENSION );
    OUString aModule = aModName.makeStringAndClear();

    oslModule aMod = osl_loadModuleRelative(
        reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
        SAL_LOADMODULE_DEFAULT );
    if( aMod )
    {
        salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" );
        if( aProc )
        {
            pInst = aProc( aMod );
#if OSL_DEBUG_LEVEL > 1
            std::fprintf( stderr, "sal plugin %s produced instance %p\n",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     pInst );
#endif
            if( pInst )
            {
                pCloseModule = aMod;

                /*
                 * Recent GTK+ versions load their modules with RTLD_LOCAL, so we can
                 * not access the 'gnome_accessibility_module_shutdown' anymore.
                 * So make sure libgtk+ & co are still mapped into memory when
                 * atk-bridge's atexit handler gets called.
                 */
                if( rModuleBase.equalsAscii("gtk") )
                {
                    pCloseModule = NULL;
                }
                /*
                 * #i109007# KDE3 seems to have the same problem; an atexit cleanup
                 * handler, which cannot be resolved anymore if the plugin is already unloaded.
                 */
                else if( rModuleBase.equalsAscii("kde") )
                {
                    pCloseModule = NULL;
                }

                GetSalData()->m_pPlugin = aMod;
            }
            else
                osl_unloadModule( aMod );
        }
        else
        {
#if OSL_DEBUG_LEVEL > 1
            std::fprintf( stderr, "could not load symbol %s from shared object %s\n",
                     "create_SalInstance",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
            osl_unloadModule( aMod );
        }
    }
#if OSL_DEBUG_LEVEL > 1
    else
        std::fprintf( stderr, "could not load shared object %s\n",
                 OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif

    return pInst;
}

static const rtl::OUString& get_desktop_environment()
{
    static rtl::OUString aRet;
    if( ! aRet.getLength() )
    {
        OUStringBuffer aModName( 128 );
        aModName.appendAscii( SAL_DLLPREFIX"desktop_detector" );
        aModName.appendAscii( SAL_DLLPOSTFIX );
        aModName.appendAscii( SAL_DLLEXTENSION );
        OUString aModule = aModName.makeStringAndClear();

        oslModule aMod = osl_loadModuleRelative(
            reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
            SAL_LOADMODULE_DEFAULT );
        if( aMod )
        {
            rtl::OUString (*pSym)() = (rtl::OUString(*)())
                osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" );
            if( pSym )
                aRet = pSym();
        }
        osl_unloadModule( aMod );
    }
    return aRet;
}

static SalInstance* autodetect_plugin()
{
    static const char* pKDEFallbackList[] =
    {
        "kde4", "kde", "gtk", "gen", 0
    };

    static const char* pStandardFallbackList[] =
    {
        "gtk", "gen", 0
    };

    static const char* pHeadlessFallbackList[] =
    {
        "svp", 0
    };

    const rtl::OUString& desktop( get_desktop_environment() );
    const char ** pList = pStandardFallbackList;
    int nListEntry = 0;

    // no server at all: dummy plugin
    if ( desktop.equalsAscii( desktop_strings[DESKTOP_NONE] ) )
        pList = pHeadlessFallbackList;
    else if ( desktop.equalsAscii( desktop_strings[DESKTOP_GNOME] ) )
        pList = pStandardFallbackList;
    else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE] ) )
    {
        pList = pKDEFallbackList;
        nListEntry = 1;
    }
    else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE4] ) )
        pList = pKDEFallbackList;

    SalInstance* pInst = NULL;
    while( pList[nListEntry] && pInst == NULL )
    {
        rtl::OUString aTry( rtl::OUString::createFromAscii( pList[nListEntry] ) );
        pInst = tryInstance( aTry );
        #if OSL_DEBUG_LEVEL > 1
        if( pInst )
            std::fprintf( stderr, "plugin autodetection: %s\n", pList[nListEntry] );
        #endif
        nListEntry++;
    }

    return pInst;
}

static SalInstance* check_headless_plugin()
{
    int nParams = osl_getCommandArgCount();
    OUString aParam;
    for( int i = 0; i < nParams; i++ )
    {
        osl_getCommandArg( i, &aParam.pData );
        if( aParam.equalsAscii( "-headless" ) )
            return tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "svp" ) ) );
    }
    return NULL;
}

SalInstance *CreateSalInstance()
{
    SalInstance*    pInst = NULL;

    static const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );

    if( !(pUsePlugin && *pUsePlugin) )
        pInst = check_headless_plugin();
    else
        pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );

    if( ! pInst )
        pInst = autodetect_plugin();

    // fallback to gen
    if( ! pInst )
        pInst = tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "gen" ) ) );

    if( ! pInst )
    {
        std::fprintf( stderr, "no suitable windowing system found, exiting.\n" );
        _exit( 1 );
    }

    // acquire SolarMutex
    pInst->AcquireYieldMutex( 1 );

    return pInst;
}

void DestroySalInstance( SalInstance *pInst )
{
    // release SolarMutex
    pInst->ReleaseYieldMutex();

    delete pInst;
    if( pCloseModule )
        osl_unloadModule( pCloseModule );
}

void InitSalData()
{
}

void DeInitSalData()
{
}

void InitSalMain()
{
}

void DeInitSalMain()
{
}

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        std::fprintf( stderr, "Application Error" );
    else
        std::fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

const OUString& SalGetDesktopEnvironment()
{
    return get_desktop_environment();
}

SalData::SalData() :
    m_pInstance(NULL),
    m_pPlugin(NULL)
{
}

SalData::~SalData()
{
}
<|endoftext|>


<commit_before>#include <stdio.h>
//#include "jsoncpp/json/json.h"
#include <map>
#include <errno.h>
#include <fcntl.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "nvme.h"
#include "mp.h"

class StringSearchResponse : public StringSearchResponseWrapper {
public:
    virtual void strstrLoc ( const uint32_t loc ) {
	fprintf(stderr, "strstr loc loc=%d\n", loc);
    }
    StringSearchResponse(int id, PortalPoller *poller = 0) : StringSearchResponseWrapper(id, poller) {
    }
};

int main(int argc, char * const *argv)
{
    Nvme nvme;
    StringSearchRequestProxy search(IfcNames_StringSearchRequestS2H);
    StringSearchResponse     searchResponse(IfcNames_StringSearchResponseH2S);

    int flags, opt;
    const char *filename;
    const char *needle = "needle";
    int source_fd = -1;

    int doidentify;
    int dosearch = 0;
    int dotrace = 0;
    int dowrite = 0;
    while ((opt = getopt(argc, argv, "iw:s:t")) != -1) {
	switch (opt) {
	case 'i':
	    doidentify = 1;
	    break;
	case 's':
	    needle = optarg;
	    dosearch = 1;
	    break;
	case 't':
	    dotrace = 1;
	    break;
	case 'w':
	    filename = optarg;
	    dowrite = 1;
	    break;
	}
    }

    if (dowrite) {
	struct stat statbuf;
	int rc = stat(filename, &statbuf);
	if (rc < 0) {
	    fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno));
	    char pwd[128];
	    getcwd(pwd, sizeof(pwd));
	    fprintf(stderr, "cwd = %s\n", pwd);
	    return rc;
	}
    }

    sleep(1);

    nvme.setup();

    if (dosearch) {
	int needle_len = strlen(needle);
	int border[needle_len+1];

	compute_borders(nvme.needleBuffer.buffer(), border, needle_len);
	compute_MP_next(nvme.needleBuffer.buffer(), (struct MP *)nvme.mpNextBuffer.buffer(), needle_len);
	nvme.needleBuffer.cacheInvalidate(0, 1); // flush the whole thing
	nvme.mpNextBuffer.cacheInvalidate(0, 1); // flush the whole thing

	//FIXME: read the text from NVME storage
	//MP(needle, haystack, mpNext, needle_len, haystack_len, &sw_match_cnt);

	// the MPEngine will read in the needle and mpNext
	search.setSearchString(nvme.needleRef, nvme.mpNextRef, needle_len);
    }

    if (doidentify)
	identify(&nvme);
    getFeatures(&nvme);
    allocIOQueues(&nvme, 0);

    fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c));
    int startBlock = 100000; // base and extent of test file in SSD
    int blocksPerRequest = 8; //12*BlocksPerRequest;
    int numBlocks = 1*blocksPerRequest; // 55; //8177;
    if (dosearch) {
	search.startSearch(numBlocks*512);
    } else {
      // if search is not running, then data read below will be discarded
    }
    if (dowrite) {
	struct stat statbuf;
	int rc = stat(filename, &statbuf);
	if (rc < 0) {
	    fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno));
	    char pwd[128];
	    getcwd(pwd, sizeof(pwd));
	    fprintf(stderr, "cwd = %s\n", pwd);
	    return rc;
	}
	numBlocks = statbuf.st_blocks;
	numBlocks -= (numBlocks % blocksPerRequest);
	fprintf(stderr, "Writing %d blocks from file %s to flash at block %d\n", numBlocks, filename, startBlock);
	source_fd = open(filename, O_RDONLY);
    }

    for (int block = 0; block < numBlocks; block += blocksPerRequest) {
	nvme_io_opcode opcode = (dowrite) ? nvme_write : nvme_read;
	fprintf(stderr, "starting transfer dowrite=%d opcode=%d\n", dowrite, opcode);
	if (opcode == nvme_write) {
	    if (filename) {
		read(source_fd, (char *)nvme.transferBuffer.buffer(), 512*blocksPerRequest);
	    } else {
		    int *buffer = (int *)nvme.transferBuffer.buffer();
		for (int i = 0; i < numBlocks*512/4; i ++)
		    buffer[i] = i;
	    }
	}
	int sc = doIO(&nvme, opcode, startBlock, blocksPerRequest, (opcode == nvme_read ? 2 : 1), dotrace);
	nvme.status();
	if (sc != 0)
	    break;
	startBlock += blocksPerRequest;
    }

    nvme.dumpTrace();
    nvme.transferStats();
    fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c));

    return 0;
}
<commit_msg>reduce string search verbosity<commit_after>#include <stdio.h>
//#include "jsoncpp/json/json.h"
#include <map>
#include <errno.h>
#include <fcntl.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "nvme.h"
#include "mp.h"

class StringSearchResponse : public StringSearchResponseWrapper {
public:
    virtual void strstrLoc ( const uint32_t loc ) {
	if (loc != -1)
	    fprintf(stderr, "strstr loc loc=%d\n", loc);
    }
    StringSearchResponse(int id, PortalPoller *poller = 0) : StringSearchResponseWrapper(id, poller) {
    }
};

int main(int argc, char * const *argv)
{
    Nvme nvme;
    StringSearchRequestProxy search(IfcNames_StringSearchRequestS2H);
    StringSearchResponse     searchResponse(IfcNames_StringSearchResponseH2S);

    int flags, opt;
    const char *filename;
    const char *needle = "needle";
    int source_fd = -1;

    int doidentify;
    int dosearch = 0;
    int dotrace = 0;
    int dowrite = 0;
    while ((opt = getopt(argc, argv, "iw:s:t")) != -1) {
	switch (opt) {
	case 'i':
	    doidentify = 1;
	    break;
	case 's':
	    needle = optarg;
	    dosearch = 1;
	    break;
	case 't':
	    dotrace = 1;
	    break;
	case 'w':
	    filename = optarg;
	    dowrite = 1;
	    break;
	}
    }

    if (dowrite) {
	struct stat statbuf;
	int rc = stat(filename, &statbuf);
	if (rc < 0) {
	    fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno));
	    char pwd[128];
	    getcwd(pwd, sizeof(pwd));
	    fprintf(stderr, "cwd = %s\n", pwd);
	    return rc;
	}
    }

    sleep(1);

    nvme.setup();

    if (dosearch) {
	int needle_len = strlen(needle);
	int border[needle_len+1];

	compute_borders(nvme.needleBuffer.buffer(), border, needle_len);
	compute_MP_next(nvme.needleBuffer.buffer(), (struct MP *)nvme.mpNextBuffer.buffer(), needle_len);
	nvme.needleBuffer.cacheInvalidate(0, 1); // flush the whole thing
	nvme.mpNextBuffer.cacheInvalidate(0, 1); // flush the whole thing

	//FIXME: read the text from NVME storage
	//MP(needle, haystack, mpNext, needle_len, haystack_len, &sw_match_cnt);

	// the MPEngine will read in the needle and mpNext
	search.setSearchString(nvme.needleRef, nvme.mpNextRef, needle_len);
    }

    if (doidentify)
	identify(&nvme);
    getFeatures(&nvme);
    allocIOQueues(&nvme, 0);

    fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c));
    int startBlock = 100000; // base and extent of test file in SSD
    int blocksPerRequest = 8; //12*BlocksPerRequest;
    int numBlocks = 1*blocksPerRequest; // 55; //8177;
    if (dosearch) {
	search.startSearch(numBlocks*512);
    } else {
      // if search is not running, then data read below will be discarded
    }
    if (dowrite) {
	struct stat statbuf;
	int rc = stat(filename, &statbuf);
	if (rc < 0) {
	    fprintf(stderr, "%s:%d File %s does not exist %d:%s\n", __FILE__, __LINE__, filename, errno, strerror(errno));
	    char pwd[128];
	    getcwd(pwd, sizeof(pwd));
	    fprintf(stderr, "cwd = %s\n", pwd);
	    return rc;
	}
	numBlocks = statbuf.st_blocks;
	numBlocks -= (numBlocks % blocksPerRequest);
	fprintf(stderr, "Writing %d blocks from file %s to flash at block %d\n", numBlocks, filename, startBlock);
	source_fd = open(filename, O_RDONLY);
    }

    for (int block = 0; block < numBlocks; block += blocksPerRequest) {
	nvme_io_opcode opcode = (dowrite) ? nvme_write : nvme_read;
	fprintf(stderr, "starting transfer dowrite=%d opcode=%d\n", dowrite, opcode);
	if (opcode == nvme_write) {
	    if (filename) {
		read(source_fd, (char *)nvme.transferBuffer.buffer(), 512*blocksPerRequest);
	    } else {
		    int *buffer = (int *)nvme.transferBuffer.buffer();
		for (int i = 0; i < numBlocks*512/4; i ++)
		    buffer[i] = i;
	    }
	}
	int sc = doIO(&nvme, opcode, startBlock, blocksPerRequest, (opcode == nvme_read ? 2 : 1), dotrace);
	nvme.status();
	if (sc != 0)
	    break;
	startBlock += blocksPerRequest;
    }

    nvme.dumpTrace();
    //nvme.transferStats();
    fprintf(stderr, "CSTS %08x\n", nvme.read32( 0x1c));

    return 0;
}
<|endoftext|>