<commit_before>/*
 * Copyright (c) 1998-2008,2010,2012 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

# include "config.h"

# include  "Statement.h"
# include  "PExpr.h"

Statement::~Statement()
{
}

PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant)
{
      delay_ = 0;
}

PAssign_::PAssign_(PExpr*lval__, PExpr*de, PExpr*ex)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(false)
{
      delay_ = de;
}

PAssign_::PAssign_(PExpr*lval__, PExpr*cnt, PEventStatement*ev, PExpr*ex)
: event_(ev), count_(cnt), lval_(lval__), rval_(ex), is_constant_(false)
{
      delay_ = 0;
}

PAssign_::~PAssign_()
{
      delete lval_;
      delete rval_;
}

PAssign::PAssign(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, char op, PExpr*ex)
: PAssign_(lval__, ex, false), op_(op)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant), op_(0)
{
}

PAssign::~PAssign()
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false)
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex)
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex)
{
}

PAssignNB::~PAssignNB()
{
}

PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t)
{
}

PBlock::PBlock(BL_TYPE t)
: PScope(perm_string()), bl_type_(t)
{
}

PBlock::~PBlock()
{
      for (unsigned idx = 0 ;  idx < list_.size() ;  idx += 1)
	    delete list_[idx];
}

void PBlock::set_join_type(PBlock::BL_TYPE type)
{
      assert(bl_type_ == BL_PAR);
      assert(type == BL_JOIN_NONE || type==BL_JOIN_ANY);
      bl_type_ = type;
}

void PBlock::set_statement(const vector<Statement*>&st)
{
      list_ = st;
}

PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: path_(n), parms_(p.size())
{
      list<PExpr*>::const_iterator cur = p.begin();
      for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
	    parms_[idx] = *cur;
	    ++cur;
      }
      assert(cur == p.end());
}

PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
: parms_(p.size())
{
      list<PExpr*>::const_iterator cur = p.begin();
      for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
	    parms_[idx] = *cur;
	    ++cur;
      }
      assert(cur == p.end());
      path_.push_back(name_component_t(n));
}

PCallTask::~PCallTask()
{
}

const pform_name_t& PCallTask::path() const
{
      return path_;
}

PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
: type_(t), expr_(ex), items_(l)
{
}

PCase::~PCase()
{
      delete expr_;
      for (unsigned idx = 0 ;  idx < items_->count() ;  idx += 1)
	    if ((*items_)[idx]->stat) delete (*items_)[idx]->stat;

      delete[]items_;
}

PCAssign::PCAssign(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}

PCAssign::~PCAssign()
{
      delete lval_;
      delete expr_;
}

PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e)
{
}

PCondit::~PCondit()
{
      delete expr_;
      delete if_;
      delete else_;
}

PDeassign::PDeassign(PExpr*l)
: lval_(l)
{
}

PDeassign::~PDeassign()
{
      delete lval_;
}

PDelayStatement::PDelayStatement(PExpr*d, Statement*st)
: delay_(d), statement_(st)
{
}

PDelayStatement::~PDelayStatement()
{
}

PDisable::PDisable(const pform_name_t&sc)
: scope_(sc)
{
}

PDisable::~PDisable()
{
}

PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
      assert(expr_.count() > 0);
}

PEventStatement::PEventStatement(PEEvent*ee)
: expr_(1), statement_(0)
{
      expr_[0] = ee;
}

PEventStatement::PEventStatement(void)
: statement_(0)
{
}

PEventStatement::~PEventStatement()
{
	// delete the events and the statement?
}

void PEventStatement::set_statement(Statement*st)
{
      statement_ = st;
}

bool PEventStatement::has_aa_term(Design*des, NetScope*scope)
{
      bool flag = false;
      for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
	    flag = expr_[idx]->has_aa_term(des, scope) || flag;
      }
      return flag;
}

PForce::PForce(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}

PForce::~PForce()
{
      delete lval_;
      delete expr_;
}

PForever::PForever(Statement*s)
: statement_(s)
{
}

PForever::~PForever()
{
      delete statement_;
}

PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
			     Statement*step, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
{
}

PForStatement::~PForStatement()
{
}

PProcess::~PProcess()
{
      delete statement_;
}

PRelease::PRelease(PExpr*l)
: lval_(l)
{
}

PRelease::~PRelease()
{
      delete lval_;
}

PRepeat::PRepeat(PExpr*e, Statement*s)
: expr_(e), statement_(s)
{
}

PRepeat::~PRepeat()
{
      delete expr_;
      delete statement_;
}

PTrigger::PTrigger(const pform_name_t&e)
: event_(e)
{
}

PTrigger::~PTrigger()
{
}

PWhile::PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st)
{
}

PWhile::~PWhile()
{
      delete cond_;
      delete statement_;
}
<commit_msg>Fix assertion settin join type is PBlock statements.<commit_after>/*
 * Copyright (c) 1998-2008,2010,2012 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

# include "config.h"

# include  "Statement.h"
# include  "PExpr.h"

Statement::~Statement()
{
}

PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant)
{
      delay_ = 0;
}

PAssign_::PAssign_(PExpr*lval__, PExpr*de, PExpr*ex)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(false)
{
      delay_ = de;
}

PAssign_::PAssign_(PExpr*lval__, PExpr*cnt, PEventStatement*ev, PExpr*ex)
: event_(ev), count_(cnt), lval_(lval__), rval_(ex), is_constant_(false)
{
      delay_ = 0;
}

PAssign_::~PAssign_()
{
      delete lval_;
      delete rval_;
}

PAssign::PAssign(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, char op, PExpr*ex)
: PAssign_(lval__, ex, false), op_(op)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex), op_(0)
{
}

PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant), op_(0)
{
}

PAssign::~PAssign()
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false)
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex)
{
}

PAssignNB::PAssignNB(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex)
{
}

PAssignNB::~PAssignNB()
{
}

PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t)
{
}

PBlock::PBlock(BL_TYPE t)
: PScope(perm_string()), bl_type_(t)
{
}

PBlock::~PBlock()
{
      for (unsigned idx = 0 ;  idx < list_.size() ;  idx += 1)
	    delete list_[idx];
}

void PBlock::set_join_type(PBlock::BL_TYPE type)
{
      assert(bl_type_ == BL_PAR);
      assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
      bl_type_ = type;
}

void PBlock::set_statement(const vector<Statement*>&st)
{
      list_ = st;
}

PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: path_(n), parms_(p.size())
{
      list<PExpr*>::const_iterator cur = p.begin();
      for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
	    parms_[idx] = *cur;
	    ++cur;
      }
      assert(cur == p.end());
}

PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
: parms_(p.size())
{
      list<PExpr*>::const_iterator cur = p.begin();
      for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
	    parms_[idx] = *cur;
	    ++cur;
      }
      assert(cur == p.end());
      path_.push_back(name_component_t(n));
}

PCallTask::~PCallTask()
{
}

const pform_name_t& PCallTask::path() const
{
      return path_;
}

PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
: type_(t), expr_(ex), items_(l)
{
}

PCase::~PCase()
{
      delete expr_;
      for (unsigned idx = 0 ;  idx < items_->count() ;  idx += 1)
	    if ((*items_)[idx]->stat) delete (*items_)[idx]->stat;

      delete[]items_;
}

PCAssign::PCAssign(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}

PCAssign::~PCAssign()
{
      delete lval_;
      delete expr_;
}

PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e)
{
}

PCondit::~PCondit()
{
      delete expr_;
      delete if_;
      delete else_;
}

PDeassign::PDeassign(PExpr*l)
: lval_(l)
{
}

PDeassign::~PDeassign()
{
      delete lval_;
}

PDelayStatement::PDelayStatement(PExpr*d, Statement*st)
: delay_(d), statement_(st)
{
}

PDelayStatement::~PDelayStatement()
{
}

PDisable::PDisable(const pform_name_t&sc)
: scope_(sc)
{
}

PDisable::~PDisable()
{
}

PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
      assert(expr_.count() > 0);
}

PEventStatement::PEventStatement(PEEvent*ee)
: expr_(1), statement_(0)
{
      expr_[0] = ee;
}

PEventStatement::PEventStatement(void)
: statement_(0)
{
}

PEventStatement::~PEventStatement()
{
	// delete the events and the statement?
}

void PEventStatement::set_statement(Statement*st)
{
      statement_ = st;
}

bool PEventStatement::has_aa_term(Design*des, NetScope*scope)
{
      bool flag = false;
      for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
	    flag = expr_[idx]->has_aa_term(des, scope) || flag;
      }
      return flag;
}

PForce::PForce(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}

PForce::~PForce()
{
      delete lval_;
      delete expr_;
}

PForever::PForever(Statement*s)
: statement_(s)
{
}

PForever::~PForever()
{
      delete statement_;
}

PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
			     Statement*step, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
{
}

PForStatement::~PForStatement()
{
}

PProcess::~PProcess()
{
      delete statement_;
}

PRelease::PRelease(PExpr*l)
: lval_(l)
{
}

PRelease::~PRelease()
{
      delete lval_;
}

PRepeat::PRepeat(PExpr*e, Statement*s)
: expr_(e), statement_(s)
{
}

PRepeat::~PRepeat()
{
      delete expr_;
      delete statement_;
}

PTrigger::PTrigger(const pform_name_t&e)
: event_(e)
{
}

PTrigger::~PTrigger()
{
}

PWhile::PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st)
{
}

PWhile::~PWhile()
{
      delete cond_;
      delete statement_;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/ftp/ftp_directory_listing_parser.h"

#include "base/i18n/icu_encoding_detection.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/stl_util.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/ftp/ftp_directory_listing_parser_ls.h"
#include "net/ftp/ftp_directory_listing_parser_netware.h"
#include "net/ftp/ftp_directory_listing_parser_os2.h"
#include "net/ftp/ftp_directory_listing_parser_vms.h"
#include "net/ftp/ftp_directory_listing_parser_windows.h"
#include "net/ftp/ftp_server_type_histograms.h"

namespace net {

namespace {

// Fills in |raw_name| for all |entries| using |encoding|. Returns network
// error code.
int FillInRawName(const std::string& encoding,
                  std::vector<FtpDirectoryListingEntry>* entries) {
  for (size_t i = 0; i < entries->size(); i++) {
    if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(),
                               base::OnStringConversionError::FAIL,
                               &entries->at(i).raw_name)) {
      return ERR_ENCODING_CONVERSION_FAILED;
    }
  }

  return OK;
}

// Parses |text| as an FTP directory listing. Fills in |entries|
// and |server_type| and returns network error code.
int ParseListing(const string16& text,
                 const std::string& encoding,
                 const base::Time& current_time,
                 std::vector<FtpDirectoryListingEntry>* entries,
                 FtpServerType* server_type) {
  std::vector<string16> lines;
  base::SplitString(text, '\n', &lines);

  // TODO(phajdan.jr): Use a table of callbacks instead of repeating code.

  entries->clear();
  if (ParseFtpDirectoryListingLs(lines, current_time, entries)) {
    *server_type = SERVER_LS;
    return FillInRawName(encoding, entries);
  }

  entries->clear();
  if (ParseFtpDirectoryListingWindows(lines, entries)) {
    *server_type = SERVER_WINDOWS;
    return FillInRawName(encoding, entries);
  }

  entries->clear();
  if (ParseFtpDirectoryListingVms(lines, entries)) {
    *server_type = SERVER_VMS;
    return FillInRawName(encoding, entries);
  }

  entries->clear();
  if (ParseFtpDirectoryListingNetware(lines, current_time, entries)) {
    *server_type = SERVER_NETWARE;
    return FillInRawName(encoding, entries);
  }

  entries->clear();
  if (ParseFtpDirectoryListingOS2(lines, entries)) {
    *server_type = SERVER_OS2;
    return FillInRawName(encoding, entries);
  }

  entries->clear();
  return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
}

// Detects encoding of |text| and parses it as an FTP directory listing.
// Fills in |entries| and |server_type| and returns network error code.
int DecodeAndParse(const std::string& text,
                   const base::Time& current_time,
                   std::vector<FtpDirectoryListingEntry>* entries,
                   FtpServerType* server_type) {
  std::vector<std::string> encodings;
  if (!base::DetectAllEncodings(text, &encodings))
    return ERR_ENCODING_DETECTION_FAILED;

  // Use first encoding that can be used to decode the text.
  for (size_t i = 0; i < encodings.size(); i++) {
    string16 converted_text;
    if (base::CodepageToUTF16(text,
                              encodings[i].c_str(),
                              base::OnStringConversionError::FAIL,
                              &converted_text)) {
      int rv = ParseListing(converted_text,
                            encodings[i],
                            current_time,
                            entries,
                            server_type);
      if (rv == OK)
        return rv;
    }
  }

  entries->clear();
  *server_type = SERVER_UNKNOWN;
  return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
}

}  // namespace

FtpDirectoryListingEntry::FtpDirectoryListingEntry()
    : type(UNKNOWN),
      size(-1) {
}

int ParseFtpDirectoryListing(const std::string& text,
                             const base::Time& current_time,
                             std::vector<FtpDirectoryListingEntry>* entries) {
  FtpServerType server_type = SERVER_UNKNOWN;
  int rv = DecodeAndParse(text, current_time, entries, &server_type);
  UpdateFtpServerTypeHistograms(server_type);
  return rv;
}

}  // namespace net
<commit_msg>FTP: refactor repetetive code to a table of callbacks.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/ftp/ftp_directory_listing_parser.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/i18n/icu_encoding_detection.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/stl_util.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/ftp/ftp_directory_listing_parser_ls.h"
#include "net/ftp/ftp_directory_listing_parser_netware.h"
#include "net/ftp/ftp_directory_listing_parser_os2.h"
#include "net/ftp/ftp_directory_listing_parser_vms.h"
#include "net/ftp/ftp_directory_listing_parser_windows.h"
#include "net/ftp/ftp_server_type_histograms.h"

namespace net {

namespace {

// Fills in |raw_name| for all |entries| using |encoding|. Returns network
// error code.
int FillInRawName(const std::string& encoding,
                  std::vector<FtpDirectoryListingEntry>* entries) {
  for (size_t i = 0; i < entries->size(); i++) {
    if (!base::UTF16ToCodepage(entries->at(i).name, encoding.c_str(),
                               base::OnStringConversionError::FAIL,
                               &entries->at(i).raw_name)) {
      return ERR_ENCODING_CONVERSION_FAILED;
    }
  }

  return OK;
}

// Parses |text| as an FTP directory listing. Fills in |entries|
// and |server_type| and returns network error code.
int ParseListing(const string16& text,
                 const std::string& encoding,
                 const base::Time& current_time,
                 std::vector<FtpDirectoryListingEntry>* entries,
                 FtpServerType* server_type) {
  std::vector<string16> lines;
  base::SplitString(text, '\n', &lines);

  struct {
    base::Callback<bool(void)> callback;
    FtpServerType server_type;
  } parsers[] = {
    {
      base::Bind(&ParseFtpDirectoryListingLs, lines, current_time, entries),
      SERVER_LS
    },
    {
      base::Bind(&ParseFtpDirectoryListingWindows, lines, entries),
      SERVER_WINDOWS
    },
    {
      base::Bind(&ParseFtpDirectoryListingVms, lines, entries),
      SERVER_VMS
    },
    {
      base::Bind(&ParseFtpDirectoryListingNetware,
                 lines, current_time, entries),
      SERVER_NETWARE
    },
    {
      base::Bind(&ParseFtpDirectoryListingOS2, lines, entries),
      SERVER_OS2
    }
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(parsers); i++) {
    entries->clear();
    if (parsers[i].callback.Run()) {
      *server_type = parsers[i].server_type;
      return FillInRawName(encoding, entries);
    }
  }

  entries->clear();
  return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
}

// Detects encoding of |text| and parses it as an FTP directory listing.
// Fills in |entries| and |server_type| and returns network error code.
int DecodeAndParse(const std::string& text,
                   const base::Time& current_time,
                   std::vector<FtpDirectoryListingEntry>* entries,
                   FtpServerType* server_type) {
  std::vector<std::string> encodings;
  if (!base::DetectAllEncodings(text, &encodings))
    return ERR_ENCODING_DETECTION_FAILED;

  // Use first encoding that can be used to decode the text.
  for (size_t i = 0; i < encodings.size(); i++) {
    string16 converted_text;
    if (base::CodepageToUTF16(text,
                              encodings[i].c_str(),
                              base::OnStringConversionError::FAIL,
                              &converted_text)) {
      int rv = ParseListing(converted_text,
                            encodings[i],
                            current_time,
                            entries,
                            server_type);
      if (rv == OK)
        return rv;
    }
  }

  entries->clear();
  *server_type = SERVER_UNKNOWN;
  return ERR_UNRECOGNIZED_FTP_DIRECTORY_LISTING_FORMAT;
}

}  // namespace

FtpDirectoryListingEntry::FtpDirectoryListingEntry()
    : type(UNKNOWN),
      size(-1) {
}

int ParseFtpDirectoryListing(const std::string& text,
                             const base::Time& current_time,
                             std::vector<FtpDirectoryListingEntry>* entries) {
  FtpServerType server_type = SERVER_UNKNOWN;
  int rv = DecodeAndParse(text, current_time, entries, &server_type);
  UpdateFtpServerTypeHistograms(server_type);
  return rv;
}

}  // namespace net
<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
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 WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "hip_runtime.h"
#include "hcc_detail/hip_hcc.h"
#include "hcc_detail/trace_helper.h"

//-------------------------------------------------------------------------------------------------
//Devices
//-------------------------------------------------------------------------------------------------
// TODO - does this initialize HIP runtime?
hipError_t hipGetDevice(int *deviceId)
{
    HIP_INIT_API(deviceId);

    hipError_t e = hipSuccess;

    auto ctx = ihipGetTlsDefaultCtx();

    if (ctx == nullptr) {
        e = hipErrorInvalidDevice; // TODO, check error code.
        *deviceId = -1;
    } else {
        *deviceId = ctx->getDevice()->_deviceId;
    }

    return ihipLogStatus(e);
}

// TODO - does this initialize HIP runtime?
hipError_t hipGetDeviceCount(int *count)
{
    HIP_INIT_API(count);

    *count = g_deviceCnt;

    if (*count > 0) {
        return ihipLogStatus(hipSuccess);
    } else {
        return ihipLogStatus(hipErrorNoDevice);
    }
}

hipError_t hipDeviceSetCacheConfig ( hipFuncCache cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    // Nop, AMD does not support variable cache configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetCacheConfig ( hipFuncCache *cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    *cacheConfig = hipFuncCachePreferNone;

    return ihipLogStatus(hipSuccess);
}

hipError_t hipFuncSetCacheConfig ( hipFuncCache cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    // Nop, AMD does not support variable cache configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceSetSharedMemConfig ( hipSharedMemConfig config )
{
    HIP_INIT_API(config);

    // Nop, AMD does not support variable shared mem configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetSharedMemConfig ( hipSharedMemConfig * pConfig )
{
    HIP_INIT_API(pConfig);

    *pConfig = hipSharedMemBankSizeFourByte;

    return ihipLogStatus(hipSuccess);
}

hipError_t hipSetDevice(int deviceId)
{
    HIP_INIT_API(deviceId);
    if ((deviceId < 0) || (deviceId >= g_deviceCnt)) {
        return ihipLogStatus(hipErrorInvalidDevice);
    } else {
        ihipSetTlsDefaultCtx(ihipGetPrimaryCtx(deviceId));
        return ihipLogStatus(hipSuccess);
    }
}

hipError_t hipDeviceSynchronize(void)
{
    HIP_INIT_API();
    return ihipLogStatus(ihipSynchronize());
}

hipError_t hipDeviceReset(void)
{
    HIP_INIT_API();

    auto *ctx = ihipGetTlsDefaultCtx();

    // TODO-HCC
    // This function currently does a user-level cleanup of known resources.
    // It could benefit from KFD support to perform a more "nuclear" clean that would include any associated kernel resources and page table entries.

    if (ctx) {
        // Release ctx resources (streams and memory):
        ctx->locked_reset();
    }

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetAttribute(int* pi, hipDeviceAttribute_t attr, int device)
{
    HIP_INIT_API(pi, attr, device);

    hipError_t e = hipSuccess;

    auto * hipDevice = ihipGetDevice(device);
    hipDeviceProp_t *prop = &hipDevice->_props;
    if (hipDevice) {
        switch (attr) {
        case hipDeviceAttributeMaxThreadsPerBlock:
            *pi = prop->maxThreadsPerBlock; break;
        case hipDeviceAttributeMaxBlockDimX:
            *pi = prop->maxThreadsDim[0]; break;
        case hipDeviceAttributeMaxBlockDimY:
            *pi = prop->maxThreadsDim[1]; break;
        case hipDeviceAttributeMaxBlockDimZ:
            *pi = prop->maxThreadsDim[2]; break;
        case hipDeviceAttributeMaxGridDimX:
            *pi = prop->maxGridSize[0]; break;
        case hipDeviceAttributeMaxGridDimY:
            *pi = prop->maxGridSize[1]; break;
        case hipDeviceAttributeMaxGridDimZ:
            *pi = prop->maxGridSize[2]; break;
        case hipDeviceAttributeMaxSharedMemoryPerBlock:
            *pi = prop->sharedMemPerBlock; break;
        case hipDeviceAttributeTotalConstantMemory:
            *pi = prop->totalConstMem; break;
        case hipDeviceAttributeWarpSize:
            *pi = prop->warpSize; break;
        case hipDeviceAttributeMaxRegistersPerBlock:
            *pi = prop->regsPerBlock; break;
        case hipDeviceAttributeClockRate:
            *pi = prop->clockRate; break;
        case hipDeviceAttributeMemoryClockRate:
            *pi = prop->memoryClockRate; break;
        case hipDeviceAttributeMemoryBusWidth:
            *pi = prop->memoryBusWidth; break;
        case hipDeviceAttributeMultiprocessorCount:
            *pi = prop->multiProcessorCount; break;
        case hipDeviceAttributeComputeMode:
            *pi = prop->computeMode; break;
        case hipDeviceAttributeL2CacheSize:
            *pi = prop->l2CacheSize; break;
        case hipDeviceAttributeMaxThreadsPerMultiProcessor:
            *pi = prop->maxThreadsPerMultiProcessor; break;
        case hipDeviceAttributeComputeCapabilityMajor:
            *pi = prop->major; break;
        case hipDeviceAttributeComputeCapabilityMinor:
            *pi = prop->minor; break;
        case hipDeviceAttributePciBusId:
            *pi = prop->pciBusID; break;
        case hipDeviceAttributeConcurrentKernels:
            *pi = prop->concurrentKernels; break;
        case hipDeviceAttributePciDeviceId:
            *pi = prop->pciDeviceID; break;
        case hipDeviceAttributeMaxSharedMemoryPerMultiprocessor:
            *pi = prop->maxSharedMemoryPerMultiProcessor; break;
        case hipDeviceAttributeIsMultiGpuBoard:
            *pi = prop->isMultiGpuBoard; break;
        default:
            e = hipErrorInvalidValue; break;
        }
    } else {
        e = hipErrorInvalidDevice;
    }
    return ihipLogStatus(e);
}

hipError_t hipGetDeviceProperties(hipDeviceProp_t* props, int device)
{
    HIP_INIT_API(props, device);

    hipError_t e;

    auto * hipDevice = ihipGetDevice(device);
    if (hipDevice) {
        // copy saved props
        *props = hipDevice->_props;
        e = hipSuccess;
    } else {
        e = hipErrorInvalidDevice;
    }

    return ihipLogStatus(e);
}

hipError_t hipSetDeviceFlags( unsigned int flags)
{
    HIP_INIT_API(flags);

    hipError_t e;

    auto * ctx = ihipGetTlsDefaultCtx();

    // TODO : does this really OR in the flags or replaces previous flags:
    // TODO : Review error handling behavior for this function, it often returns ErrorSetOnActiveProcess
    if (ctx) {
       ctx->_ctxFlags = ctx->_ctxFlags | flags;
       e = hipSuccess;
    } else {
       e = hipErrorInvalidDevice;
    }

    return ihipLogStatus(e);
};

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device)
{
    HIP_INIT_API(major,minor, device);
    hipError_t e = hipSuccess;
    int deviceId= device->_deviceId;
    e = hipDeviceGetAttribute(major, hipDeviceAttributeComputeCapabilityMajor, deviceId);
    e = hipDeviceGetAttribute(minor, hipDeviceAttributeComputeCapabilityMinor, deviceId);
    return ihipLogStatus(e);
}

hipError_t hipDeviceGetName(char *name,int len,hipDevice_t device)
{
    HIP_INIT_API(name,len, device);
    hipError_t e = hipSuccess;
    int nameLen = strlen(device->_props.name);
    if(nameLen <= len)
        memcpy(name,device->_props.name,nameLen);
    return ihipLogStatus(e);
}

hipError_t hipDeviceGetPCIBusId (int *pciBusId,int len,hipDevice_t device)
{
    HIP_INIT_API(pciBusId,len, device);
    hipError_t e = hipSuccess;
    int deviceId= device->_deviceId;
    e = hipDeviceGetAttribute(pciBusId, hipDeviceAttributePciBusId, deviceId);
    return ihipLogStatus(e);
}

hipError_t hipDeviceTotalMem (size_t *bytes,hipDevice_t device)
{
    HIP_INIT_API(bytes, device);
    hipError_t e = hipSuccess;
    *bytes= device->_props.totalGlobalMem;
    return ihipLogStatus(e);
}

hipError_t hipChooseDevice( int* device, const hipDeviceProp_t* prop )
{
    hipDeviceProp_t  tempProp;
    int deviceCount;
    int inPropCount=0;
    int matchedPropCount=0;
    hipError_t e = hipSuccess;
    hipGetDeviceCount( &deviceCount );
    *device = 0;
    for (int i=0; i< deviceCount; i++) {
        hipGetDeviceProperties( &tempProp, i );
        if(prop->major !=0) {
            inPropCount++;
            if(tempProp.major >= prop->major) {
                matchedPropCount++;
            }
            if(prop->minor !=0) {
                inPropCount++;
                 if(tempProp.minor >= prop->minor) {
                     matchedPropCount++;
                 }
            }
        }

        if(inPropCount == matchedPropCount) {
            *device = i;
        }
#if 0
        else{
            e= hipErrorInvalidValue;
        }
#endif
    }
    return ihipLogStatus(e);
}

<commit_msg>Added further properties in hipChooseDevice<commit_after>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
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 WARRANNTY OF ANY KIND, EXPRESS OR
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "hip_runtime.h"
#include "hcc_detail/hip_hcc.h"
#include "hcc_detail/trace_helper.h"

//-------------------------------------------------------------------------------------------------
//Devices
//-------------------------------------------------------------------------------------------------
// TODO - does this initialize HIP runtime?
hipError_t hipGetDevice(int *deviceId)
{
    HIP_INIT_API(deviceId);

    hipError_t e = hipSuccess;

    auto ctx = ihipGetTlsDefaultCtx();

    if (ctx == nullptr) {
        e = hipErrorInvalidDevice; // TODO, check error code.
        *deviceId = -1;
    } else {
        *deviceId = ctx->getDevice()->_deviceId;
    }

    return ihipLogStatus(e);
}

// TODO - does this initialize HIP runtime?
hipError_t hipGetDeviceCount(int *count)
{
    HIP_INIT_API(count);

    *count = g_deviceCnt;

    if (*count > 0) {
        return ihipLogStatus(hipSuccess);
    } else {
        return ihipLogStatus(hipErrorNoDevice);
    }
}

hipError_t hipDeviceSetCacheConfig ( hipFuncCache cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    // Nop, AMD does not support variable cache configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetCacheConfig ( hipFuncCache *cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    *cacheConfig = hipFuncCachePreferNone;

    return ihipLogStatus(hipSuccess);
}

hipError_t hipFuncSetCacheConfig ( hipFuncCache cacheConfig )
{
    HIP_INIT_API(cacheConfig);

    // Nop, AMD does not support variable cache configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceSetSharedMemConfig ( hipSharedMemConfig config )
{
    HIP_INIT_API(config);

    // Nop, AMD does not support variable shared mem configs.

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetSharedMemConfig ( hipSharedMemConfig * pConfig )
{
    HIP_INIT_API(pConfig);

    *pConfig = hipSharedMemBankSizeFourByte;

    return ihipLogStatus(hipSuccess);
}

hipError_t hipSetDevice(int deviceId)
{
    HIP_INIT_API(deviceId);
    if ((deviceId < 0) || (deviceId >= g_deviceCnt)) {
        return ihipLogStatus(hipErrorInvalidDevice);
    } else {
        ihipSetTlsDefaultCtx(ihipGetPrimaryCtx(deviceId));
        return ihipLogStatus(hipSuccess);
    }
}

hipError_t hipDeviceSynchronize(void)
{
    HIP_INIT_API();
    return ihipLogStatus(ihipSynchronize());
}

hipError_t hipDeviceReset(void)
{
    HIP_INIT_API();

    auto *ctx = ihipGetTlsDefaultCtx();

    // TODO-HCC
    // This function currently does a user-level cleanup of known resources.
    // It could benefit from KFD support to perform a more "nuclear" clean that would include any associated kernel resources and page table entries.

    if (ctx) {
        // Release ctx resources (streams and memory):
        ctx->locked_reset();
    }

    return ihipLogStatus(hipSuccess);
}

hipError_t hipDeviceGetAttribute(int* pi, hipDeviceAttribute_t attr, int device)
{
    HIP_INIT_API(pi, attr, device);

    hipError_t e = hipSuccess;

    auto * hipDevice = ihipGetDevice(device);
    hipDeviceProp_t *prop = &hipDevice->_props;
    if (hipDevice) {
        switch (attr) {
        case hipDeviceAttributeMaxThreadsPerBlock:
            *pi = prop->maxThreadsPerBlock; break;
        case hipDeviceAttributeMaxBlockDimX:
            *pi = prop->maxThreadsDim[0]; break;
        case hipDeviceAttributeMaxBlockDimY:
            *pi = prop->maxThreadsDim[1]; break;
        case hipDeviceAttributeMaxBlockDimZ:
            *pi = prop->maxThreadsDim[2]; break;
        case hipDeviceAttributeMaxGridDimX:
            *pi = prop->maxGridSize[0]; break;
        case hipDeviceAttributeMaxGridDimY:
            *pi = prop->maxGridSize[1]; break;
        case hipDeviceAttributeMaxGridDimZ:
            *pi = prop->maxGridSize[2]; break;
        case hipDeviceAttributeMaxSharedMemoryPerBlock:
            *pi = prop->sharedMemPerBlock; break;
        case hipDeviceAttributeTotalConstantMemory:
            *pi = prop->totalConstMem; break;
        case hipDeviceAttributeWarpSize:
            *pi = prop->warpSize; break;
        case hipDeviceAttributeMaxRegistersPerBlock:
            *pi = prop->regsPerBlock; break;
        case hipDeviceAttributeClockRate:
            *pi = prop->clockRate; break;
        case hipDeviceAttributeMemoryClockRate:
            *pi = prop->memoryClockRate; break;
        case hipDeviceAttributeMemoryBusWidth:
            *pi = prop->memoryBusWidth; break;
        case hipDeviceAttributeMultiprocessorCount:
            *pi = prop->multiProcessorCount; break;
        case hipDeviceAttributeComputeMode:
            *pi = prop->computeMode; break;
        case hipDeviceAttributeL2CacheSize:
            *pi = prop->l2CacheSize; break;
        case hipDeviceAttributeMaxThreadsPerMultiProcessor:
            *pi = prop->maxThreadsPerMultiProcessor; break;
        case hipDeviceAttributeComputeCapabilityMajor:
            *pi = prop->major; break;
        case hipDeviceAttributeComputeCapabilityMinor:
            *pi = prop->minor; break;
        case hipDeviceAttributePciBusId:
            *pi = prop->pciBusID; break;
        case hipDeviceAttributeConcurrentKernels:
            *pi = prop->concurrentKernels; break;
        case hipDeviceAttributePciDeviceId:
            *pi = prop->pciDeviceID; break;
        case hipDeviceAttributeMaxSharedMemoryPerMultiprocessor:
            *pi = prop->maxSharedMemoryPerMultiProcessor; break;
        case hipDeviceAttributeIsMultiGpuBoard:
            *pi = prop->isMultiGpuBoard; break;
        default:
            e = hipErrorInvalidValue; break;
        }
    } else {
        e = hipErrorInvalidDevice;
    }
    return ihipLogStatus(e);
}

hipError_t hipGetDeviceProperties(hipDeviceProp_t* props, int device)
{
    HIP_INIT_API(props, device);

    hipError_t e;

    auto * hipDevice = ihipGetDevice(device);
    if (hipDevice) {
        // copy saved props
        *props = hipDevice->_props;
        e = hipSuccess;
    } else {
        e = hipErrorInvalidDevice;
    }

    return ihipLogStatus(e);
}

hipError_t hipSetDeviceFlags( unsigned int flags)
{
    HIP_INIT_API(flags);

    hipError_t e;

    auto * ctx = ihipGetTlsDefaultCtx();

    // TODO : does this really OR in the flags or replaces previous flags:
    // TODO : Review error handling behavior for this function, it often returns ErrorSetOnActiveProcess
    if (ctx) {
       ctx->_ctxFlags = ctx->_ctxFlags | flags;
       e = hipSuccess;
    } else {
       e = hipErrorInvalidDevice;
    }

    return ihipLogStatus(e);
};

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device)
{
    HIP_INIT_API(major,minor, device);
    hipError_t e = hipSuccess;
    int deviceId= device->_deviceId;
    e = hipDeviceGetAttribute(major, hipDeviceAttributeComputeCapabilityMajor, deviceId);
    e = hipDeviceGetAttribute(minor, hipDeviceAttributeComputeCapabilityMinor, deviceId);
    return ihipLogStatus(e);
}

hipError_t hipDeviceGetName(char *name,int len,hipDevice_t device)
{
    HIP_INIT_API(name,len, device);
    hipError_t e = hipSuccess;
    int nameLen = strlen(device->_props.name);
    if(nameLen <= len)
        memcpy(name,device->_props.name,nameLen);
    return ihipLogStatus(e);
}

hipError_t hipDeviceGetPCIBusId (int *pciBusId,int len,hipDevice_t device)
{
    HIP_INIT_API(pciBusId,len, device);
    hipError_t e = hipSuccess;
    int deviceId= device->_deviceId;
    e = hipDeviceGetAttribute(pciBusId, hipDeviceAttributePciBusId, deviceId);
    return ihipLogStatus(e);
}

hipError_t hipDeviceTotalMem (size_t *bytes,hipDevice_t device)
{
    HIP_INIT_API(bytes, device);
    hipError_t e = hipSuccess;
    *bytes= device->_props.totalGlobalMem;
    return ihipLogStatus(e);
}

hipError_t hipChooseDevice( int* device, const hipDeviceProp_t* prop )
{
    hipDeviceProp_t  tempProp;
    int deviceCount;
    int inPropCount=0;
    int matchedPropCount=0;
    hipError_t e = hipSuccess;
    hipGetDeviceCount( &deviceCount );
    *device = 0;
    for (int i=0; i< deviceCount; i++) {
        hipGetDeviceProperties( &tempProp, i );
        if(prop->major !=0) {
            inPropCount++;
            if(tempProp.major >= prop->major) {
                matchedPropCount++;
            }
            if(prop->minor !=0) {
                inPropCount++;
                 if(tempProp.minor >= prop->minor) {
                     matchedPropCount++;
                 }
            }
        }
        if(prop->totalGlobalMem != 0) {
            inPropCount++;
            if(tempProp.totalGlobalMem >= prop->totalGlobalMem) {
                matchedPropCount++;
            }
        }
        if(prop->sharedMemPerBlock != 0) {
            inPropCount++;
            if(tempProp.sharedMemPerBlock >= prop->sharedMemPerBlock) {
                matchedPropCount++;
            }
        }
        if(prop->maxThreadsPerBlock  != 0) {
            inPropCount++;
            if(tempProp.maxThreadsPerBlock >= prop->maxThreadsPerBlock ) {
                matchedPropCount++;
            }
        }
        if(prop->totalConstMem  != 0) {
            inPropCount++;
            if(tempProp.totalConstMem >= prop->totalConstMem ) {
                matchedPropCount++;
            }
        }
        if(prop->multiProcessorCount  != 0) {
            inPropCount++;
            if(tempProp.multiProcessorCount >= prop->multiProcessorCount ) {
                matchedPropCount++;
            }
        }
        if(prop->maxThreadsPerMultiProcessor  != 0) {
            inPropCount++;
            if(tempProp.maxThreadsPerMultiProcessor >= prop->maxThreadsPerMultiProcessor ) {
                matchedPropCount++;
            }
        }
        if(prop->memoryClockRate  != 0) {
            inPropCount++;
            if(tempProp.memoryClockRate >= prop->memoryClockRate ) {
                matchedPropCount++;
            }
        }
        if(inPropCount == matchedPropCount) {
            *device = i;
        }
#if 0
        else{
            e= hipErrorInvalidValue;
        }
#endif
    }
    return ihipLogStatus(e);
}

<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>

#include "../../lazyflatset.hpp"

int main() {

    const unsigned max = 30 * 1000 * 1000;

    rs::LazyFlatSet<unsigned> set(16, 32 * 1024);

    auto start = std::chrono::steady_clock::now();

    for (unsigned i = 0; i < max; ++i) {
        set.insert(max - i - 1);
        //set.insert(i);

        if ((i & 0x7fff) == 0) {
            std::cout << i << std::endl;
        }
    }

    auto duration = std::chrono::steady_clock::now() - start;
    auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(duration);

    std::cout << "Populate: " << durationMS.count() << "ms" << std::endl;

    std::cout << "Size: " << set.size() << std::endl;
    std::cout << "[0] = " << set[0] << std::endl;
    std::cout << "[1] = " << set[1] << std::endl;
    std::cout << "[10] = " << set[10] << std::endl;
    std::cout << "[1000] = " << set[1000] << std::endl;

    return 0;
}

<commit_msg>Added performance tests for vector, set, list, unordered_set and lazyflatset - with csv output<commit_after>#include <iostream>
#include <chrono>
#include <functional>

#include <vector>
#include <set>
#include <unordered_set>
#include <list>
#include <queue>

#include "../../lazyflatset.hpp"

using DataType = unsigned;
using SourceIterator = std::vector<DataType>::const_iterator;

using TestFunction = std::function<void(SourceIterator, SourceIterator)>;

void vectorHeadInsert(SourceIterator begin, SourceIterator end) {
    std::vector<DataType> data;
    data.insert(data.cbegin(), begin, end);
}

void vectorTailInsert(SourceIterator begin, SourceIterator end) {
    std::vector<DataType> data;
    data.insert(data.cend(), begin, end);
}

void vectorHeadPush(SourceIterator begin, SourceIterator end) {
    std::vector<DataType> data;

    for (auto iter = begin; iter != end; ++iter) {
        data.insert(data.cbegin(), *iter);
    }
}

void vectorTailPush(SourceIterator begin, SourceIterator end) {
    std::vector<DataType> data;

    for (auto iter = begin; iter != end; ++iter) {
        data.push_back(*iter);
    }
}

void setInsert(SourceIterator begin, SourceIterator end) {
    std::set<DataType> data;
    data.insert(begin, end);
}

void unorderedSetInsert(SourceIterator begin, SourceIterator end) {
    std::unordered_set<DataType> data;
    data.insert(begin, end);
}

void priorityQueuePush(SourceIterator begin, SourceIterator end) {
    std::priority_queue <DataType> data;

    for (auto iter = begin; iter != end; ++iter) {
        data.push(*iter);
    }
}

void listTailInsert(SourceIterator begin, SourceIterator end) {
    std::list<DataType> data;
    data.insert(data.cbegin(), begin, end);
}

void lazyFlatSetInsert(SourceIterator begin, SourceIterator end) {
    rs::LazyFlatSet<DataType> data(128, 32 * 1024);

    for (auto iter = begin; iter != end; ++iter) {
        data.insert(*iter);
    }
}

void test(TestFunction func, SourceIterator begin, SourceIterator end, bool eol = false) {
    auto start = std::chrono::steady_clock::now();
    func(begin, end);
    auto duration = std::chrono::steady_clock::now() - start;
    auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(duration);

    std::cout << durationMS.count();

    if (eol) {
        std::cout << std::endl;
    } else {
        std::cout << ", ";
    }
}

int main() {
    std::vector<DataType> data;
    const unsigned max = 5 * 1000 * 1000;
    for (unsigned i = 0; i < max; ++i) {
        data.push_back(i);
    }

    std::cout << R"("", "listTailInsert", "vectorTailInsert", "vectorTailPush", "vectorHeadInsert", "setInsert", "unorderedSetInsert", "priorityQueuePush", "lazyFlatSetInsert")" << std::endl;

    std::cout << R"("Ascending", )";

    test(listTailInsert, data.cbegin(), data.cend());
    test(vectorTailInsert, data.cbegin(), data.cend());
    test(vectorTailPush, data.cbegin(), data.cend());
    test(vectorHeadInsert, data.cbegin(), data.cend());
    //test(vectorHeadPush, data.cbegin(), data.cend());
    test(setInsert, data.cbegin(), data.cend());
    test(unorderedSetInsert, data.cbegin(), data.cend());
    test(priorityQueuePush, data.cbegin(), data.cend());
    test(lazyFlatSetInsert, data.cbegin(), data.cend(), true);

    std::cout << R"("Descending", )";

    std::reverse(data.begin(), data.end());

    test(listTailInsert, data.cbegin(), data.cend());
    test(vectorTailInsert, data.cbegin(), data.cend());
    test(vectorTailPush, data.cbegin(), data.cend());
    test(vectorHeadInsert, data.cbegin(), data.cend());
    //test(vectorHeadPush, data.cbegin(), data.cend());
    test(setInsert, data.cbegin(), data.cend());
    test(unorderedSetInsert, data.cbegin(), data.cend());
    test(priorityQueuePush, data.cbegin(), data.cend());
    test(lazyFlatSetInsert, data.cbegin(), data.cend(), true);

    std::cout << R"("Partial shuffle", )";

    const unsigned blocks = 10000;
    const unsigned blockSize = max / blocks;
    auto iter = data.begin();
    for (unsigned i = 0; i < blocks; ++i) {
        auto iterEnd = iter + blockSize;
        std::random_shuffle(iter, iterEnd < data.end() ? iterEnd : data.end());
        iter += blockSize;
    }

    test(listTailInsert, data.cbegin(), data.cend());
    test(vectorTailInsert, data.cbegin(), data.cend());
    test(vectorTailPush, data.cbegin(), data.cend());
    test(vectorHeadInsert, data.cbegin(), data.cend());
    //test(vectorHeadPush, data.cbegin(), data.cend());
    test(setInsert, data.cbegin(), data.cend());
    test(unorderedSetInsert, data.cbegin(), data.cend());
    test(priorityQueuePush, data.cbegin(), data.cend());
    test(lazyFlatSetInsert, data.cbegin(), data.cend(), true);

    std::cout << R"("Full shuffle", )";

    std::random_shuffle(data.begin(), data.end());

    test(listTailInsert, data.cbegin(), data.cend());
    test(vectorTailInsert, data.cbegin(), data.cend());
    test(vectorTailPush, data.cbegin(), data.cend());
    test(vectorHeadInsert, data.cbegin(), data.cend());
    //test(vectorHeadPush, data.cbegin(), data.cend());
    test(setInsert, data.cbegin(), data.cend());
    test(unorderedSetInsert, data.cbegin(), data.cend());
    test(priorityQueuePush, data.cbegin(), data.cend());
    test(lazyFlatSetInsert, data.cbegin(), data.cend(), true);

    return 0;
}<|endoftext|>


<commit_before>/*********************************************************************
** Author: Zach Colbert
** Date: 30 November 2017
** Description: Book class
*********************************************************************/

/*********************************************************************
** Includes
*********************************************************************/

#include "Book.hpp"
#include <string>

/*********************************************************************
** Description:
*********************************************************************/
Book::Book(std::string idc, std::string t, std::string a)
{

}

/*********************************************************************
** Description:
*********************************************************************/
int Book::getCheckOutLength()
{

}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getIdCode()
{

}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getTitle()
{

}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getAuthor()
{

}

/*********************************************************************
** Description:
*********************************************************************/
Locale Book::getLocation()
{

}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setLocation(Locale)
{

}

/*********************************************************************
** Description:
*********************************************************************/
Patron* Book::getCheckedOutBy()
{

}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setCheckedOutBy(Patron*)
{

}

/*********************************************************************
** Description:
*********************************************************************/
Patron* Book::getRequestedBy()
{

}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setRequestedBy(Patron*)
{

}

/*********************************************************************
** Description:
*********************************************************************/
int Book::getDateCheckedOut()
{

}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setDateCheckedOut(int)
{

}<commit_msg>get functions are done<commit_after>/*********************************************************************
** Author: Zach Colbert
** Date: 30 November 2017
** Description: Book class
*********************************************************************/

/*********************************************************************
** Includes
*********************************************************************/

#include "Book.hpp"
#include <string>

/*********************************************************************
** Description:
*********************************************************************/
Book::Book(std::string idc, std::string t, std::string a)
{

}

/*********************************************************************
** Description:
*********************************************************************/
int Book::getCheckOutLength()
{
    return CHECK_OUT_LENGTH;
}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getIdCode()
{
    return idCode;
}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getTitle()
{
    return title;
}

/*********************************************************************
** Description:
*********************************************************************/
std::string Book::getAuthor()
{
    return author;
}

/*********************************************************************
** Description:
*********************************************************************/
Locale Book::getLocation()
{
    return location;
}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setLocation(Locale)
{

}

/*********************************************************************
** Description:
*********************************************************************/
Patron* Book::getCheckedOutBy()
{
    return checkedOutBy;
}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setCheckedOutBy(Patron*)
{

}

/*********************************************************************
** Description:
*********************************************************************/
Patron* Book::getRequestedBy()
{
    return requestedBy;
}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setRequestedBy(Patron*)
{

}

/*********************************************************************
** Description:
*********************************************************************/
int Book::getDateCheckedOut()
{
    return dateCheckedOut;
}

/*********************************************************************
** Description:
*********************************************************************/
void Book::setDateCheckedOut(int)
{

}<|endoftext|>


<commit_before>// ---------------------------------------------------------------
// bank.cpp
// ---------------------------------------------------------------

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

#include <thread>

#include "../../zmqHelper.h"

using namespace zmqHelper;

/*
 * Two threads communicate over inproc, using a shared context.
 */

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Bank {

private:

  SocketAdaptor< ZMQ_REP > theSocket;

  const std::string bankName;

public:

  // .............................................................
  // .............................................................
  using SocketType = decltype (theSocket);

  // .............................................................
  // .............................................................
  const std::string & getName () const {
	return bankName;
  }

  // .............................................................
  // .............................................................
  Bank (const std::string & bn, std::function<void(SocketType &)> f)  : bankName (bn)
  {
	std::string url = "inproc://bank" + bankName;
	// std::cout << " bank url = " << url << std::endl;

	theSocket.bind (url);

	theSocket.onMessage ( f );
  } //  ()

  // ..............................................................
  // ..............................................................
  zmq::context_t & getContext () {
	return theSocket.getContext ();
  }

  // .............................................................
  // .............................................................
  void closeDoors () {
	theSocket.stopReceiving ();
	theSocket.close ();
  }
};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Person {

private:

  // .............................................................
  std::string personName;

  // .............................................................
  std::thread * theThread = nullptr;

public:

  // .............................................................
  // .............................................................
  Person (const std::string & pn) :
	personName {pn}
  { }

  // .............................................................
  // .............................................................
  void act (Bank & theBank, std::function<void(const std::string &)> f ) {
	if ( theThread != nullptr) {
	  return;
	}

	theThread = new std::thread ( f, personName );
  } // ()

  // .............................................................
  // .............................................................
  void join () {
	if (theThread == nullptr) {
	  return;
	}

	theThread->join ();
	delete (theThread);
	theThread = nullptr;

  } // ()
};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
void personRole (Bank & bank, const std::string & name)  {

	// Two threads communicate over inproc, using a shared context.
	auto theSocket = new SocketAdaptor<ZMQ_REQ> { bank.getContext() };

	std::string url = "inproc://bank" + bank.getName();
	theSocket->connect (url);

	for (int i=1; i<=5; i++) {

	  std::cout << name << " sending \n";

	  // send request
	  std::vector<std::string> multi = { name, "put", "12.34" };
	  theSocket->sendText (multi);

	  //  get reply
	  auto lines = theSocket->receiveText ();

	  std::cout << name << " received: | ";
	  for ( auto s : lines ) { std::cout << s << " | "; }
	  std::cout << "\n";

	  sleep (1);
	} // for

	theSocket->close ();
	delete theSocket;
  }; // ()

// ---------------------------------------------------------------
// ---------------------------------------------------------------
int main () {

  auto bankName = "SwissBankers";

  auto bankRole =  [&]  (SocketAdaptor<ZMQ_REP> & socket ) -> void {
		//  Get the request.
		auto lines = socket.receiveText ();

		std::cout << bankName << " received: | ";
		for ( auto s : lines ) { std::cout << s << " | "; }
		std::cout << "\n";

		// Send the reply
		std::vector<std::string> multi = { "OK", lines[0] };
		socket.sendText ( multi );
  };

  Bank b1 (bankName, bankRole);

  Person p1 ( "john" );
  Person p2 ( "mary" );

  // curry personRole() from 2 args to 1 arg ( let bank be b1 )
  auto role = [&] (const std::string & s) { return personRole (b1, s); };

  p2.act (b1, role);
  p1.act (b1, role);

  p1.join ();
  p2.join ();

  b1.closeDoors ();

  std::cout << " happy ending \n";

  return 0;
} // main ()

<commit_msg>minor edit<commit_after>// ---------------------------------------------------------------
// bank.cpp
// ---------------------------------------------------------------

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

#include <thread>

#include "../../zmqHelper.h"

using namespace zmqHelper;

/*
 * Two threads communicate over inproc, using a shared context.
 */

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Bank {

private:

  SocketAdaptor< ZMQ_REP > theSocket;

  const std::string bankName;

public:

  // .............................................................
  // .............................................................
  using SocketType = decltype (theSocket);

  // .............................................................
  // .............................................................
  const std::string & getName () const {
	return bankName;
  }

  // .............................................................
  // .............................................................
  Bank (const std::string & bn, std::function<void(SocketType &)> f)  : bankName (bn)
  {
	std::string url = "inproc://bank" + bankName;
	// std::cout << " bank url = " << url << std::endl;

	theSocket.bind (url);

	theSocket.onMessage ( f );
  } //  ()

  // ..............................................................
  // ..............................................................
  zmq::context_t & getContext () {
	return theSocket.getContext ();
  }

  // .............................................................
  // .............................................................
  void closeDoors () {
	theSocket.stopReceiving ();
	theSocket.close ();
  }
};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
class Person {

private:

  // .............................................................
  std::string personName;

  // .............................................................
  std::thread * theThread = nullptr;

public:

  // .............................................................
  // .............................................................
  Person (const std::string & pn) :
	personName {pn}
  { }

  // .............................................................
  // .............................................................
  void act (std::function<void(const std::string &)> f ) {
	if ( theThread != nullptr) {
	  return;
	}

	theThread = new std::thread ( f, personName );
  } // ()

  // .............................................................
  // .............................................................
  void join () {
	if (theThread == nullptr) {
	  return;
	}

	theThread->join ();
	delete (theThread);
	theThread = nullptr;

  } // ()
};

// ---------------------------------------------------------------
// ---------------------------------------------------------------
void personRole (Bank & bank, const std::string & name)  {

	// Two threads communicate over inproc, using a shared context.
	auto theSocket = new SocketAdaptor<ZMQ_REQ> { bank.getContext() };

	std::string url = "inproc://bank" + bank.getName();
	theSocket->connect (url);

	for (int i=1; i<=5; i++) {

	  std::cout << name << " sending \n";

	  // send request
	  std::vector<std::string> multi = { name, "put", "12.34" };
	  theSocket->sendText (multi);

	  //  get reply
	  auto lines = theSocket->receiveText ();

	  std::cout << name << " received: | ";
	  for ( auto s : lines ) { std::cout << s << " | "; }
	  std::cout << "\n";

	  sleep (1);
	} // for

	theSocket->close ();
	delete theSocket;
  }; // ()

// ---------------------------------------------------------------
// ---------------------------------------------------------------
int main () {

  auto bankName = "SwissBankers";

  auto bankRole =  [&]  (SocketAdaptor<ZMQ_REP> & socket ) -> void {
		//  Get the request.
		auto lines = socket.receiveText ();

		std::cout << bankName << " received: | ";
		for ( auto s : lines ) { std::cout << s << " | "; }
		std::cout << "\n";

		// Send the reply
		std::vector<std::string> multi = { "OK", lines[0] };
		socket.sendText ( multi );
  };

  Bank b1 (bankName, bankRole);

  Person p1 ( "john" );
  Person p2 ( "mary" );

  // curry personRole() from 2 args to 1 arg ( let bank be b1 )
  auto role = [&] (const std::string & s) { return personRole (b1, s); };

  p2.act (role);
  p1.act (role);

  p1.join ();
  p2.join ();

  b1.closeDoors ();

  std::cout << " happy ending \n";

  return 0;
} // main ()

<|endoftext|>


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

#include <cstring>

AMX_NATIVE HookNative(AMX *amx, const char *nativeName, AMX_NATIVE native) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->natives);

    int numberOfNatives;
    amx_NumNatives(amx, &numberOfNatives);

    for (int i = 0; i < numberOfNatives; i++) {
        char *currentName = reinterpret_cast<char*>(amx->base + natives[i].nameofs);
        if (std::strcmp(currentName, nativeName) == 0) {
            cell address = natives[i].address;
            natives[i].address = reinterpret_cast<cell>(native);
            return reinterpret_cast<AMX_NATIVE>(address);
        }
    }

    return 0;
}

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

#include <cstring>

#include <sampgdk/amx/amx.h>

AMX_NATIVE HookNative(AMX *amx, const char *nativeName, AMX_NATIVE native) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->natives);

    int numberOfNatives;
    amx_NumNatives(amx, &numberOfNatives);

    for (int i = 0; i < numberOfNatives; i++) {
        char *currentName = reinterpret_cast<char*>(amx->base + natives[i].nameofs);
        if (std::strcmp(currentName, nativeName) == 0) {
            cell address = natives[i].address;
            natives[i].address = reinterpret_cast<cell>(native);
            return reinterpret_cast<AMX_NATIVE>(address);
        }
    }

    return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

#include "entry_p.h"

#if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID

#include <bgfxplatform.h>

#include <stdio.h>
#include <bx/thread.h>

#include <android/input.h>
#include <android/log.h>
#include <android/looper.h>
#include <android/window.h>
#include <android_native_app_glue.h>

extern "C"
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <android_native_app_glue.c>
#pragma GCC diagnostic pop
} // extern "C"

namespace entry
{
	struct MainThreadEntry
	{
		int m_argc;
		char** m_argv;

		static int32_t threadFunc(void* _userData);
	};

	struct Context
	{
		Context()
			: m_window(NULL)
		{
		}

		void run(android_app* _app)
		{
			m_app = _app;
			m_app->userData = (void*)this;
			m_app->onAppCmd = onAppCmdCB;
			m_app->onInputEvent = onInputEventCB;
			ANativeActivity_setWindowFlags(m_app->activity, 0
				| AWINDOW_FLAG_FULLSCREEN
				| AWINDOW_FLAG_KEEP_SCREEN_ON
				, 0
				);

			const char* argv[1] = { "android.so" };
			m_mte.m_argc = 1;
			m_mte.m_argv = const_cast<char**>(argv);

			while (0 == m_app->destroyRequested)
			{
				int32_t num;
				android_poll_source* source;
				/*int32_t id =*/ ALooper_pollAll(-1, NULL, &num, (void**)&source);

				if (NULL != source)
				{
					source->process(m_app, source);
				}
			}

			m_thread.shutdown();
		}

		void onAppCmd(int32_t _cmd)
		{
			switch (_cmd)
			{
				case APP_CMD_INPUT_CHANGED:
					// Command from main thread: the AInputQueue has changed.  Upon processing
					// this command, android_app->inputQueue will be updated to the new queue
					// (or NULL).
					break;

				case APP_CMD_INIT_WINDOW:
					// Command from main thread: a new ANativeWindow is ready for use.  Upon
					// receiving this command, android_app->window will contain the new window
					// surface.
					if (m_window == NULL)
					{
						m_window = m_app->window;
						bgfx::androidSetWindow(m_window);

						int32_t width  = ANativeWindow_getWidth(m_window);
						int32_t height = ANativeWindow_getHeight(m_window);

						DBG("ANativeWindow width %d, height %d", width, height);
						WindowHandle defaultWindow = { 0 };
						m_eventQueue.postSizeEvent(defaultWindow, width, height);

						m_thread.init(MainThreadEntry::threadFunc, &m_mte);
					}
					break;

				case APP_CMD_TERM_WINDOW:
					// Command from main thread: the existing ANativeWindow needs to be
					// terminated.  Upon receiving this command, android_app->window still
					// contains the existing window; after calling android_app_exec_cmd
					// it will be set to NULL.
					break;

				case APP_CMD_WINDOW_RESIZED:
					// Command from main thread: the current ANativeWindow has been resized.
					// Please redraw with its new size.
					break;

				case APP_CMD_WINDOW_REDRAW_NEEDED:
					// Command from main thread: the system needs that the current ANativeWindow
					// be redrawn.  You should redraw the window before handing this to
					// android_app_exec_cmd() in order to avoid transient drawing glitches.
					break;

				case APP_CMD_CONTENT_RECT_CHANGED:
					// Command from main thread: the content area of the window has changed,
					// such as from the soft input window being shown or hidden.  You can
					// find the new content rect in android_app::contentRect.
					break;

				case APP_CMD_GAINED_FOCUS:
					// Command from main thread: the app's activity window has gained
					// input focus.
					break;

				case APP_CMD_LOST_FOCUS:
					// Command from main thread: the app's activity window has lost
					// input focus.
					break;

				case APP_CMD_CONFIG_CHANGED:
					// Command from main thread: the current device configuration has changed.
					break;

				case APP_CMD_LOW_MEMORY:
					// Command from main thread: the system is running low on memory.
					// Try to reduce your memory use.
					break;

				case APP_CMD_START:
					// Command from main thread: the app's activity has been started.
					break;

				case APP_CMD_RESUME:
					// Command from main thread: the app's activity has been resumed.
					break;

				case APP_CMD_SAVE_STATE:
					// Command from main thread: the app should generate a new saved state
					// for itself, to restore from later if needed.  If you have saved state,
					// allocate it with malloc and place it in android_app.savedState with
					// the size in android_app.savedStateSize.  The will be freed for you
					// later.
					break;

				case APP_CMD_PAUSE:
					// Command from main thread: the app's activity has been paused.
					break;

				case APP_CMD_STOP:
					// Command from main thread: the app's activity has been stopped.
					break;

				case APP_CMD_DESTROY:
					// Command from main thread: the app's activity is being destroyed,
					// and waiting for the app thread to clean up and exit before proceeding.
					m_eventQueue.postExitEvent();
					break;
			}
		}

		int32_t onInputEvent(AInputEvent* _event)
		{
			BX_UNUSED(_event);
			return 0;
		}

		static void onAppCmdCB(struct android_app* _app, int32_t _cmd)
		{
			Context* self = (Context*)_app->userData;
			self->onAppCmd(_cmd);
		}

		static int32_t onInputEventCB(struct android_app* _app, AInputEvent* _event)
		{
			Context* self = (Context*)_app->userData;
			return self->onInputEvent(_event);
		}

		MainThreadEntry m_mte;
		bx::Thread m_thread;

		EventQueue m_eventQueue;

		ANativeWindow* m_window;
		android_app* m_app;
	};

	static Context s_ctx;

	const Event* poll()
	{
		return s_ctx.m_eventQueue.poll();
	}

	const Event* poll(WindowHandle _handle)
	{
		return s_ctx.m_eventQueue.poll(_handle);
	}

	void release(const Event* _event)
	{
		s_ctx.m_eventQueue.release(_event);
	}

	WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
	{
		BX_UNUSED(_x, _y, _width, _height, _flags, _title);
		WindowHandle handle = { UINT16_MAX };
		return handle;
	}

	void destroyWindow(WindowHandle _handle)
	{
		BX_UNUSED(_handle);
	}

	void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
	{
		BX_UNUSED(_handle, _x, _y);
	}

	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
	{
		BX_UNUSED(_handle, _width, _height);
	}

	void setWindowTitle(WindowHandle _handle, const char* _title)
	{
		BX_UNUSED(_handle, _title);
	}

	void toggleWindowFrame(WindowHandle _handle)
	{
		BX_UNUSED(_handle);
	}

	void setMouseLock(WindowHandle _handle, bool _lock)
	{
		BX_UNUSED(_handle, _lock);
	}

	int32_t MainThreadEntry::threadFunc(void* _userData)
	{
		int32_t result = chdir("/sdcard/bgfx/examples/runtime");
		BX_CHECK(0 == result, "Failed to chdir to dir. android.permission.WRITE_EXTERNAL_STORAGE?", errno);

		MainThreadEntry* self = (MainThreadEntry*)_userData;
		result = main(self->m_argc, self->m_argv);
//		PostMessage(s_ctx.m_hwnd, WM_QUIT, 0, 0);
		return result;
	}

} // namespace entry

extern "C" void android_main(android_app* _app)
{
	using namespace entry;
	s_ctx.run(_app);
}

#endif // ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID
<commit_msg>Android: Added input handling.<commit_after>/*
 * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

#include "entry_p.h"

#if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID

#include <bgfxplatform.h>

#include <stdio.h>
#include <bx/thread.h>

#include <android/input.h>
#include <android/log.h>
#include <android/looper.h>
#include <android/window.h>
#include <android_native_app_glue.h>

extern "C"
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <android_native_app_glue.c>
#pragma GCC diagnostic pop
} // extern "C"

namespace entry
{
	struct MainThreadEntry
	{
		int m_argc;
		char** m_argv;

		static int32_t threadFunc(void* _userData);
	};

	struct Context
	{
		Context()
			: m_window(NULL)
			, m_count(0)
		{
		}

		void run(android_app* _app)
		{
			m_app = _app;
			m_app->userData = (void*)this;
			m_app->onAppCmd = onAppCmdCB;
			m_app->onInputEvent = onInputEventCB;
			ANativeActivity_setWindowFlags(m_app->activity, 0
				| AWINDOW_FLAG_FULLSCREEN
				| AWINDOW_FLAG_KEEP_SCREEN_ON
				, 0
				);

			const char* argv[1] = { "android.so" };
			m_mte.m_argc = 1;
			m_mte.m_argv = const_cast<char**>(argv);

			while (0 == m_app->destroyRequested)
			{
				int32_t num;
				android_poll_source* source;
				/*int32_t id =*/ ALooper_pollAll(-1, NULL, &num, (void**)&source);

				if (NULL != source)
				{
					source->process(m_app, source);
				}
			}

			m_thread.shutdown();
		}

		void onAppCmd(int32_t _cmd)
		{
			switch (_cmd)
			{
				case APP_CMD_INPUT_CHANGED:
					// Command from main thread: the AInputQueue has changed.  Upon processing
					// this command, android_app->inputQueue will be updated to the new queue
					// (or NULL).
					break;

				case APP_CMD_INIT_WINDOW:
					// Command from main thread: a new ANativeWindow is ready for use.  Upon
					// receiving this command, android_app->window will contain the new window
					// surface.
					if (m_window == NULL)
					{
						m_window = m_app->window;
						bgfx::androidSetWindow(m_window);

						int32_t width  = ANativeWindow_getWidth(m_window);
						int32_t height = ANativeWindow_getHeight(m_window);

						DBG("ANativeWindow width %d, height %d", width, height);
						WindowHandle defaultWindow = { 0 };
						m_eventQueue.postSizeEvent(defaultWindow, width, height);

						m_thread.init(MainThreadEntry::threadFunc, &m_mte);
					}
					break;

				case APP_CMD_TERM_WINDOW:
					// Command from main thread: the existing ANativeWindow needs to be
					// terminated.  Upon receiving this command, android_app->window still
					// contains the existing window; after calling android_app_exec_cmd
					// it will be set to NULL.
					break;

				case APP_CMD_WINDOW_RESIZED:
					// Command from main thread: the current ANativeWindow has been resized.
					// Please redraw with its new size.
					break;

				case APP_CMD_WINDOW_REDRAW_NEEDED:
					// Command from main thread: the system needs that the current ANativeWindow
					// be redrawn.  You should redraw the window before handing this to
					// android_app_exec_cmd() in order to avoid transient drawing glitches.
					break;

				case APP_CMD_CONTENT_RECT_CHANGED:
					// Command from main thread: the content area of the window has changed,
					// such as from the soft input window being shown or hidden.  You can
					// find the new content rect in android_app::contentRect.
					break;

				case APP_CMD_GAINED_FOCUS:
					// Command from main thread: the app's activity window has gained
					// input focus.
					break;

				case APP_CMD_LOST_FOCUS:
					// Command from main thread: the app's activity window has lost
					// input focus.
					break;

				case APP_CMD_CONFIG_CHANGED:
					// Command from main thread: the current device configuration has changed.
					break;

				case APP_CMD_LOW_MEMORY:
					// Command from main thread: the system is running low on memory.
					// Try to reduce your memory use.
					break;

				case APP_CMD_START:
					// Command from main thread: the app's activity has been started.
					break;

				case APP_CMD_RESUME:
					// Command from main thread: the app's activity has been resumed.
					break;

				case APP_CMD_SAVE_STATE:
					// Command from main thread: the app should generate a new saved state
					// for itself, to restore from later if needed.  If you have saved state,
					// allocate it with malloc and place it in android_app.savedState with
					// the size in android_app.savedStateSize.  The will be freed for you
					// later.
					break;

				case APP_CMD_PAUSE:
					// Command from main thread: the app's activity has been paused.
					break;

				case APP_CMD_STOP:
					// Command from main thread: the app's activity has been stopped.
					break;

				case APP_CMD_DESTROY:
					// Command from main thread: the app's activity is being destroyed,
					// and waiting for the app thread to clean up and exit before proceeding.
					m_eventQueue.postExitEvent();
					break;
			}
		}

		int32_t onInputEvent(AInputEvent* _event)
		{
			int32_t type = AInputEvent_getType(_event);

			switch (type)
			{
			case AINPUT_EVENT_TYPE_MOTION:
				{
					float mx = AMotionEvent_getX(_event, 0);
					float my = AMotionEvent_getY(_event, 0);
					int32_t count = AMotionEvent_getPointerCount(_event);

					int32_t actionBits = AMotionEvent_getAction(_event);
					int32_t action     = (actionBits & AMOTION_EVENT_ACTION_MASK);
					int32_t index      = (actionBits & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

					WindowHandle defaultWindow = { 0 };

					count = m_count;

					switch (action)
					{
					case AMOTION_EVENT_ACTION_DOWN:
					case AMOTION_EVENT_ACTION_POINTER_DOWN:
						m_count++;
						break;

					case AMOTION_EVENT_ACTION_UP:
					case AMOTION_EVENT_ACTION_POINTER_UP:
						m_count--;
						break;

					default:
						break;
					}

					if (count != m_count)
					{
						m_eventQueue.postMouseEvent(defaultWindow
							, (int32_t)mx
							, (int32_t)my
							, 0
							, 1 == count ? MouseButton::Left : MouseButton::Right
							, false
							);

						if (0 != m_count)
						{
							m_eventQueue.postMouseEvent(defaultWindow
								, (int32_t)mx
								, (int32_t)my
								, 0
								, 1 == m_count ? MouseButton::Left : MouseButton::Right
								, true
								);
						}
					}

					switch (action)
					{
					case AMOTION_EVENT_ACTION_MOVE:
						if (0 == index)
						{
							m_eventQueue.postMouseEvent(defaultWindow
								, (int32_t)mx
								, (int32_t)my
								, 0
								);
						}
						break;

					default:
						break;
					}
				}
				break;

			case AINPUT_EVENT_TYPE_KEY:
				break;
			}
			return 0;
		}

		static void onAppCmdCB(struct android_app* _app, int32_t _cmd)
		{
			Context* self = (Context*)_app->userData;
			self->onAppCmd(_cmd);
		}

		static int32_t onInputEventCB(struct android_app* _app, AInputEvent* _event)
		{
			Context* self = (Context*)_app->userData;
			return self->onInputEvent(_event);
		}

		MainThreadEntry m_mte;
		bx::Thread m_thread;

		EventQueue m_eventQueue;

		ANativeWindow* m_window;
		android_app* m_app;

		int32_t m_count;
	};

	static Context s_ctx;

	const Event* poll()
	{
		return s_ctx.m_eventQueue.poll();
	}

	const Event* poll(WindowHandle _handle)
	{
		return s_ctx.m_eventQueue.poll(_handle);
	}

	void release(const Event* _event)
	{
		s_ctx.m_eventQueue.release(_event);
	}

	WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
	{
		BX_UNUSED(_x, _y, _width, _height, _flags, _title);
		WindowHandle handle = { UINT16_MAX };
		return handle;
	}

	void destroyWindow(WindowHandle _handle)
	{
		BX_UNUSED(_handle);
	}

	void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
	{
		BX_UNUSED(_handle, _x, _y);
	}

	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
	{
		BX_UNUSED(_handle, _width, _height);
	}

	void setWindowTitle(WindowHandle _handle, const char* _title)
	{
		BX_UNUSED(_handle, _title);
	}

	void toggleWindowFrame(WindowHandle _handle)
	{
		BX_UNUSED(_handle);
	}

	void setMouseLock(WindowHandle _handle, bool _lock)
	{
		BX_UNUSED(_handle, _lock);
	}

	int32_t MainThreadEntry::threadFunc(void* _userData)
	{
		int32_t result = chdir("/sdcard/bgfx/examples/runtime");
		BX_CHECK(0 == result, "Failed to chdir to dir. android.permission.WRITE_EXTERNAL_STORAGE?", errno);

		MainThreadEntry* self = (MainThreadEntry*)_userData;
		result = main(self->m_argc, self->m_argv);
//		PostMessage(s_ctx.m_hwnd, WM_QUIT, 0, 0);
		return result;
	}

} // namespace entry

extern "C" void android_main(android_app* _app)
{
	using namespace entry;
	s_ctx.run(_app);
}

#endif // ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_ANDROID
<|endoftext|>


<commit_before>/**\file
 * \brief "Hello World" HTTP Server
 *
 * This is an example HTTP server that serves a simple "Hello World!" on /, and
 * a 404 on all other resources.
 *
 * Call it like this:
 * \code
 * $ ./http-hello localhost 8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running, open a browser and go to
 * http://localhost:8080/ and you should see the familiar greeting.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/http.h>
#include <iostream>

using namespace efgy;
using asio::ip::tcp;

/**\brief Hello World request handler
 *
 * This function serves the familiar "Hello World!" when called.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool hello(typename net::http::server<tcp>::session &session,
                  std::smatch &) {
  session.reply(200, "Hello World!");

  return true;
}

/**\brief Hello World request handler for /quit
 *
 * When this handler is invoked, it stops the ASIO IO handler (after replying,
 * maybe...).
 *
 * \note Having this on your production server in this exact way is PROBABLY a
 *       really bad idea, unless you gate it in an upstream forward proxy. Or
 *       you have some way of automatically respawning your server. Or both.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool quit(typename net::http::server<tcp>::session &session,
                 std::smatch &) {
  session.reply(200, "Good Bye, Cruel World!");

  session.server.io.stop();

  return true;
}

/**\brief Main function for the HTTP demo
 *
 * This is the main function for the HTTP Hello World demo.
 *
 * \param[in] argc Process argument count.
 * \param[in] argv Process argument vector
 *
 * \returns 0 when nothing bad happened, 1 otherwise.
 */
int main(int argc, char *argv[]) {
  try {
    if (argc != 3) {
      std::cerr << "Usage: http-hello <host> <port>\n";
      return 1;
    }

    asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(argv[1], argv[2]);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;

    if (endpoint_iterator != end) {
      tcp::endpoint endpoint = *endpoint_iterator;
      net::http::server<tcp> s(io_service, endpoint, std::cout);

      s.processor.add("^/$", hello);
      s.processor.add("^/quit$", quit);

      io_service.run();
    }

    return 0;
  }
  catch (std::exception & e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  catch (std::system_error & e) {
    std::cerr << "System Error: " << e.what() << "\n";
  }

  return 1;
}
<commit_msg>split out the server code to a separate header file, so as to be reused for IRC<commit_after>/**\file
 * \brief "Hello World" HTTP Server
 *
 * This is an example HTTP server that serves a simple "Hello World!" on /, and
 * a 404 on all other resources.
 *
 * Call it like this:
 * \code
 * $ ./http-hello localhost 8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running, open a browser and go to
 * http://localhost:8080/ and you should see the familiar greeting.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/http.h>
#include <iostream>

using namespace efgy;
using asio::ip::tcp;

/**\brief Hello World request handler
 *
 * This function serves the familiar "Hello World!" when called.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool hello(typename net::http::server<tcp>::session &session,
                  std::smatch &) {
  session.reply(200, "Hello World!");

  return true;
}

/**\brief Hello World request handler for /quit
 *
 * When this handler is invoked, it stops the ASIO IO handler (after replying,
 * maybe...).
 *
 * \note Having this on your production server in this exact way is PROBABLY a
 *       really bad idea, unless you gate it in an upstream forward proxy. Or
 *       you have some way of automatically respawning your server. Or both.
 *
 * \param[out] session The HTTP session to answer on.
 *
 * \returns true (always, as we always reply).
 */
static bool quit(typename net::http::server<tcp>::session &session,
                 std::smatch &) {
  session.reply(200, "Good-Bye, Cruel World!");

  session.server.io.stop();

  return true;
}

/**\brief Main function for the HTTP demo
 *
 * This is the main function for the HTTP Hello World demo.
 *
 * \param[in] argc Process argument count.
 * \param[in] argv Process argument vector
 *
 * \returns 0 when nothing bad happened, 1 otherwise.
 */
int main(int argc, char *argv[]) {
  try {
    if (argc != 3) {
      std::cerr << "Usage: http-hello <host> <port>\n";
      return 1;
    }

    asio::io_service io_service;
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(argv[1], argv[2]);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;

    if (endpoint_iterator != end) {
      tcp::endpoint endpoint = *endpoint_iterator;
      net::http::server<tcp> s(io_service, endpoint, std::cout);

      s.processor.add("^/$", hello);
      s.processor.add("^/quit$", quit);

      io_service.run();
    }

    return 0;
  }
  catch (std::exception & e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  catch (std::system_error & e) {
    std::cerr << "System Error: " << e.what() << "\n";
  }

  return 1;
}
<|endoftext|>