<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <cstring>
#include <i18n.h>
#include <Context.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, const char** argv)
{
  int status = 0;

  // Lightweight version checking that doesn't require initialization or any I/O.
  if (argc == 2 && !strcmp (argv[1], "--version"))
  {
    std::cout << VERSION << "\n";
  }
  else
  {
    try
    {
      status = context.initialize (argc, argv);
      if (status == 0)
        status = context.run ();
    }

    catch (const std::string& error)
    {
      std::cerr << error << "\n";
      status = -1;
    }

    catch (...)
    {
      std::cerr << STRING_UNKNOWN_ERROR << "\n";
      status = -2;
    }
  }

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Errors<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <new>
#include <cstring>
#include <i18n.h>
#include <Context.h>

Context context;

////////////////////////////////////////////////////////////////////////////////
int main (int argc, const char** argv)
{
  int status = 0;

  // Lightweight version checking that doesn't require initialization or any I/O.
  if (argc == 2 && !strcmp (argv[1], "--version"))
  {
    std::cout << VERSION << "\n";
  }
  else
  {
    try
    {
      status = context.initialize (argc, argv);
      if (status == 0)
        status = context.run ();
    }

    catch (const std::string& error)
    {
      std::cerr << error << "\n";
      status = -1;
    }

    catch (std::bad_alloc& error)
    {
      std::cerr << "Error: Memory allocation failed: " << error.what () << "\n";
      status = -3;
    }

    catch (...)
    {
      std::cerr << STRING_UNKNOWN_ERROR << "\n";
      status = -2;
    }
  }

  return status;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkAggregateLabelMapFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"

#include "itkLabelObject.h"
#include "itkLabelMap.h"
#include "itkLabelImageToLabelMapFilter.h"
#include "itkAggregateLabelMapFilter.h"
#include "itkLabelMapToLabelImageFilter.h"

int itkAggregateLabelMapFilterTest(int argc, char * argv[])
{

  if( argc != 3 )
    {
    std::cerr << "usage: " << argv[0] << " input output" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 2;

  typedef itk::Image< unsigned char, dim > ImageType;

  typedef itk::LabelObject< unsigned char, dim >  LabelObjectType;
  typedef itk::LabelMap< LabelObjectType >        LabelMapType;

  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::LabelImageToLabelMapFilter< ImageType, LabelMapType> I2LType;
  I2LType::Pointer i2l = I2LType::New();
  i2l->SetInput( reader->GetOutput() );

  typedef itk::AggregateLabelMapFilter< LabelMapType > ChangeType;
  ChangeType::Pointer change = ChangeType::New();
  change->SetInput( i2l->GetOutput() );
  itk::SimpleFilterWatcher watcher6(change, "filter");

  typedef itk::LabelMapToLabelImageFilter< LabelMapType, ImageType> L2IType;
  L2IType::Pointer l2i = L2IType::New();
  l2i->SetInput( change->GetOutput() );

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( l2i->GetOutput() );
  writer->SetFileName( argv[2] );
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Added UseCompressionOn() to writer.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkAggregateLabelMapFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"

#include "itkLabelObject.h"
#include "itkLabelMap.h"
#include "itkLabelImageToLabelMapFilter.h"
#include "itkAggregateLabelMapFilter.h"
#include "itkLabelMapToLabelImageFilter.h"

int itkAggregateLabelMapFilterTest(int argc, char * argv[])
{

  if( argc != 3 )
    {
    std::cerr << "usage: " << argv[0] << " input output" << std::endl;
    // std::cerr << "  : " << std::endl;
    exit(1);
    }

  const int dim = 2;

  typedef itk::Image< unsigned char, dim > ImageType;

  typedef itk::LabelObject< unsigned char, dim >  LabelObjectType;
  typedef itk::LabelMap< LabelObjectType >        LabelMapType;

  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::LabelImageToLabelMapFilter< ImageType, LabelMapType> I2LType;
  I2LType::Pointer i2l = I2LType::New();
  i2l->SetInput( reader->GetOutput() );

  typedef itk::AggregateLabelMapFilter< LabelMapType > ChangeType;
  ChangeType::Pointer change = ChangeType::New();
  change->SetInput( i2l->GetOutput() );
  itk::SimpleFilterWatcher watcher6(change, "filter");

  typedef itk::LabelMapToLabelImageFilter< LabelMapType, ImageType> L2IType;
  L2IType::Pointer l2i = L2IType::New();
  l2i->SetInput( change->GetOutput() );

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( l2i->GetOutput() );
  writer->SetFileName( argv[2] );
  writer->UseCompressionOn();
  writer->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Machinecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "protocol.h"

#include "util.h"
#include "utilstrencodings.h"

#ifndef WIN32
# include <arpa/inet.h>
#endif

namespace NetMsgType {
const char *VERSION="version";
const char *VERACK="verack";
const char *ADDR="addr";
const char *INV="inv";
const char *GETDATA="getdata";
const char *MERKLEBLOCK="merkleblock";
const char *GETBLOCKS="getblocks";
const char *GETHEADERS="getheaders";
const char *TX="tx";
const char *HEADERS="headers";
const char *BLOCK="block";
const char *GETADDR="getaddr";
const char *MEMPOOL="mempool";
const char *PING="ping";
const char *PONG="pong";
const char *NOTFOUND="notfound";
const char *FILTERLOAD="filterload";
const char *FILTERADD="filteradd";
const char *FILTERCLEAR="filterclear";
const char *REJECT="reject";
const char *SENDHEADERS="sendheaders";
const char *FEEFILTER="feefilter";
const char *SENDCMPCT="sendcmpct";
const char *CMPCTBLOCK="cmpctblock";
const char *GETBLOCKTXN="getblocktxn";
const char *BLOCKTXN="blocktxn";
// Machinecoin message types
const char *SPORK="spork";
const char *GETSPORKS="getsporks";
const char *MASTERNODEPAYMENTVOTE="mnw";
const char *MASTERNODEPAYMENTBLOCK="mnwb";
const char *MASTERNODEPAYMENTSYNC="mnget";
const char *MNBUDGETSYNC="mnvs"; // depreciated since 12.1
const char *MNBUDGETVOTE="mvote"; // depreciated since 12.1
const char *MNBUDGETPROPOSAL="mprop"; // depreciated since 12.1
const char *MNBUDGETFINAL="fbs"; // depreciated since 12.1
const char *MNBUDGETFINALVOTE="fbvote"; // depreciated since 12.1
const char *MNQUORUM="mn quorum"; // not implemented
const char *MNANNOUNCE="mnb";
const char *MNPING="mnp";
const char *DSACCEPT="dsa";
const char *DSVIN="dsi";
const char *DSFINALTX="dsf";
const char *DSSIGNFINALTX="dss";
const char *DSCOMPLETE="dsc";
const char *DSSTATUSUPDATE="dssu";
const char *DSTX="dstx";
const char *DSQUEUE="dsq";
const char *DSEG="dseg";
const char *SYNCSTATUSCOUNT="ssc";
const char *MNGOVERNANCESYNC="govsync";
const char *MNGOVERNANCEOBJECT="govobj";
const char *MNGOVERNANCEOBJECTVOTE="govobjvote";
const char *MNVERIFY="mnv";
};

const static std::string ppszTypeName[] =
{
    "ERROR", // Should never occur
    NetMsgType::TX,
    NetMsgType::BLOCK,
    NetMsgType::MERKLEBLOCK,
    NetMsgType::CMPCTBLOCK,
    // Machinecoin message types
    // NOTE: include non-implmented here, we must keep this list in sync with enum in protocol.h
    NetMsgType::TXLOCKREQUEST,
    NetMsgType::TXLOCKVOTE,
    NetMsgType::SPORK,
    NetMsgType::MASTERNODEPAYMENTVOTE,
    NetMsgType::MASTERNODEPAYMENTBLOCK, // reusing, was MNSCANERROR previousely, was NOT used in 12.0, we need this for inv
    NetMsgType::MNBUDGETVOTE, // depreciated since 12.1
    NetMsgType::MNBUDGETPROPOSAL, // depreciated since 12.1
    NetMsgType::MNBUDGETFINAL, // depreciated since 12.1
    NetMsgType::MNBUDGETFINALVOTE, // depreciated since 12.1
    NetMsgType::MNQUORUM, // not implemented
    NetMsgType::MNANNOUNCE,
    NetMsgType::MNPING,
    NetMsgType::DSACCEPT,
    NetMsgType::DSVIN,
    NetMsgType::DSFINALTX,
    NetMsgType::DSSIGNFINALTX,
    NetMsgType::DSCOMPLETE,
    NetMsgType::DSSTATUSUPDATE,
    NetMsgType::DSQUEUE,
    NetMsgType::DSEG,
    NetMsgType::DSTX,
    NetMsgType::MNGOVERNANCEOBJECT,
    NetMsgType::MNGOVERNANCEOBJECTVOTE,
    NetMsgType::MNVERIFY,
};

/** All known message types. Keep this in the same order as the list of
 * messages above and in protocol.h.
 */
const static std::string allNetMessageTypes[] = {
    NetMsgType::VERSION,
    NetMsgType::VERACK,
    NetMsgType::ADDR,
    NetMsgType::INV,
    NetMsgType::GETDATA,
    NetMsgType::MERKLEBLOCK,
    NetMsgType::GETBLOCKS,
    NetMsgType::GETHEADERS,
    NetMsgType::TX,
    NetMsgType::HEADERS,
    NetMsgType::BLOCK,
    NetMsgType::GETADDR,
    NetMsgType::MEMPOOL,
    NetMsgType::PING,
    NetMsgType::PONG,
    NetMsgType::NOTFOUND,
    NetMsgType::FILTERLOAD,
    NetMsgType::FILTERADD,
    NetMsgType::FILTERCLEAR,
    NetMsgType::REJECT,
    NetMsgType::SENDHEADERS,
    NetMsgType::FEEFILTER,
    NetMsgType::SENDCMPCT,
    NetMsgType::CMPCTBLOCK,
    NetMsgType::GETBLOCKTXN,
    NetMsgType::BLOCKTXN,
    // Machinecoin message types
    // NOTE: do NOT include non-implmented here, we want them to be "Unknown command" in ProcessMessage()
    NetMsgType::SPORK,
    NetMsgType::GETSPORKS,
    NetMsgType::MASTERNODEPAYMENTVOTE,
    // NetMsgType::MASTERNODEPAYMENTBLOCK, // there is no message for this, only inventory
    NetMsgType::MASTERNODEPAYMENTSYNC,
    NetMsgType::MNANNOUNCE,
    NetMsgType::MNPING,
    NetMsgType::SYNCSTATUSCOUNT,
    NetMsgType::MNGOVERNANCESYNC,
    NetMsgType::MNGOVERNANCEOBJECT,
    NetMsgType::MNGOVERNANCEOBJECTVOTE,
    NetMsgType::MNVERIFY,
};
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));

CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
{
    memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    nMessageSize = -1;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
{
    memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    strncpy(pchCommand, pszCommand, COMMAND_SIZE);
    nMessageSize = nMessageSizeIn;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

std::string CMessageHeader::GetCommand() const
{
    return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}

bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
{
    // Check start string
    if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
        return false;

    // Check the command string for errors
    for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
    {
        if (*p1 == 0)
        {
            // Must be all zeros after the first zero
            for (; p1 < pchCommand + COMMAND_SIZE; p1++)
                if (*p1 != 0)
                    return false;
        }
        else if (*p1 < ' ' || *p1 > 0x7E)
            return false;
    }

    // Message size
    if (nMessageSize > MAX_SIZE)
    {
        LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

CAddress::CAddress() : CService()
{
    Init();
}

CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn)
{
    Init();
    nServices = nServicesIn;
}

void CAddress::Init()
{
    nServices = NODE_NONE;
    nTime = 100000000;
}

CInv::CInv()
{
    type = 0;
    hash.SetNull();
}

CInv::CInv(int typeIn, const uint256& hashIn)
{
    type = typeIn;
    hash = hashIn;
}

// Machinecoin
CInv::CInv(const std::string& strType, const uint256& hashIn)
{
    unsigned int i;
    for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
    {
        if (strType == ppszTypeName[i])
        {
            type = i;
            break;
        }
    }
    if (i == ARRAYLEN(ppszTypeName))
        throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType));
    hash = hashIn;
}

bool CInv::IsKnownType() const
{
    return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}

std::string CInv::GetCommand() const
{
    std::string cmd;
    if (type & MSG_WITNESS_FLAG)
        cmd.append("witness-");

    if (!IsKnownType())
        throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
    return ppszTypeName[type];
}

bool operator<(const CInv& a, const CInv& b)
{
    return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}

std::string CInv::ToString() const
{
    try {
        return strprintf("%s %s", GetCommand(), hash.ToString());
    } catch(const std::out_of_range &) {
        return strprintf("0x%08x %s", type, hash.ToString());
    }
}

const std::vector<std::string> &getAllNetMessageTypes()
{
    return allNetMessageTypesVec;
}
<commit_msg>Removed unnecessary types<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Machinecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "protocol.h"

#include "util.h"
#include "utilstrencodings.h"

#ifndef WIN32
# include <arpa/inet.h>
#endif

namespace NetMsgType {
const char *VERSION="version";
const char *VERACK="verack";
const char *ADDR="addr";
const char *INV="inv";
const char *GETDATA="getdata";
const char *MERKLEBLOCK="merkleblock";
const char *GETBLOCKS="getblocks";
const char *GETHEADERS="getheaders";
const char *TX="tx";
const char *HEADERS="headers";
const char *BLOCK="block";
const char *GETADDR="getaddr";
const char *MEMPOOL="mempool";
const char *PING="ping";
const char *PONG="pong";
const char *NOTFOUND="notfound";
const char *FILTERLOAD="filterload";
const char *FILTERADD="filteradd";
const char *FILTERCLEAR="filterclear";
const char *REJECT="reject";
const char *SENDHEADERS="sendheaders";
const char *FEEFILTER="feefilter";
const char *SENDCMPCT="sendcmpct";
const char *CMPCTBLOCK="cmpctblock";
const char *GETBLOCKTXN="getblocktxn";
const char *BLOCKTXN="blocktxn";
// Machinecoin message types
const char *SPORK="spork";
const char *GETSPORKS="getsporks";
const char *MASTERNODEPAYMENTVOTE="mnw";
const char *MASTERNODEPAYMENTBLOCK="mnwb";
const char *MASTERNODEPAYMENTSYNC="mnget";
const char *MNBUDGETSYNC="mnvs"; // depreciated since 12.1
const char *MNBUDGETVOTE="mvote"; // depreciated since 12.1
const char *MNBUDGETPROPOSAL="mprop"; // depreciated since 12.1
const char *MNBUDGETFINAL="fbs"; // depreciated since 12.1
const char *MNBUDGETFINALVOTE="fbvote"; // depreciated since 12.1
const char *MNQUORUM="mn quorum"; // not implemented
const char *MNANNOUNCE="mnb";
const char *MNPING="mnp";
const char *DSACCEPT="dsa";
const char *DSVIN="dsi";
const char *DSFINALTX="dsf";
const char *DSSIGNFINALTX="dss";
const char *DSCOMPLETE="dsc";
const char *DSSTATUSUPDATE="dssu";
const char *DSTX="dstx";
const char *DSQUEUE="dsq";
const char *DSEG="dseg";
const char *SYNCSTATUSCOUNT="ssc";
const char *MNGOVERNANCESYNC="govsync";
const char *MNGOVERNANCEOBJECT="govobj";
const char *MNGOVERNANCEOBJECTVOTE="govobjvote";
const char *MNVERIFY="mnv";
};

const static std::string ppszTypeName[] =
{
    "ERROR", // Should never occur
    NetMsgType::TX,
    NetMsgType::BLOCK,
    NetMsgType::MERKLEBLOCK,
    NetMsgType::CMPCTBLOCK,
    // Machinecoin message types
    // NOTE: include non-implmented here, we must keep this list in sync with enum in protocol.h
    NetMsgType::SPORK,
    NetMsgType::MASTERNODEPAYMENTVOTE,
    NetMsgType::MASTERNODEPAYMENTBLOCK, // reusing, was MNSCANERROR previousely, was NOT used in 12.0, we need this for inv
    NetMsgType::MNBUDGETVOTE, // depreciated since 12.1
    NetMsgType::MNBUDGETPROPOSAL, // depreciated since 12.1
    NetMsgType::MNBUDGETFINAL, // depreciated since 12.1
    NetMsgType::MNBUDGETFINALVOTE, // depreciated since 12.1
    NetMsgType::MNQUORUM, // not implemented
    NetMsgType::MNANNOUNCE,
    NetMsgType::MNPING,
    NetMsgType::DSACCEPT,
    NetMsgType::DSVIN,
    NetMsgType::DSFINALTX,
    NetMsgType::DSSIGNFINALTX,
    NetMsgType::DSCOMPLETE,
    NetMsgType::DSSTATUSUPDATE,
    NetMsgType::DSQUEUE,
    NetMsgType::DSEG,
    NetMsgType::DSTX,
    NetMsgType::MNGOVERNANCEOBJECT,
    NetMsgType::MNGOVERNANCEOBJECTVOTE,
    NetMsgType::MNVERIFY,
};

/** All known message types. Keep this in the same order as the list of
 * messages above and in protocol.h.
 */
const static std::string allNetMessageTypes[] = {
    NetMsgType::VERSION,
    NetMsgType::VERACK,
    NetMsgType::ADDR,
    NetMsgType::INV,
    NetMsgType::GETDATA,
    NetMsgType::MERKLEBLOCK,
    NetMsgType::GETBLOCKS,
    NetMsgType::GETHEADERS,
    NetMsgType::TX,
    NetMsgType::HEADERS,
    NetMsgType::BLOCK,
    NetMsgType::GETADDR,
    NetMsgType::MEMPOOL,
    NetMsgType::PING,
    NetMsgType::PONG,
    NetMsgType::NOTFOUND,
    NetMsgType::FILTERLOAD,
    NetMsgType::FILTERADD,
    NetMsgType::FILTERCLEAR,
    NetMsgType::REJECT,
    NetMsgType::SENDHEADERS,
    NetMsgType::FEEFILTER,
    NetMsgType::SENDCMPCT,
    NetMsgType::CMPCTBLOCK,
    NetMsgType::GETBLOCKTXN,
    NetMsgType::BLOCKTXN,
    // Machinecoin message types
    // NOTE: do NOT include non-implmented here, we want them to be "Unknown command" in ProcessMessage()
    NetMsgType::SPORK,
    NetMsgType::GETSPORKS,
    NetMsgType::MASTERNODEPAYMENTVOTE,
    // NetMsgType::MASTERNODEPAYMENTBLOCK, // there is no message for this, only inventory
    NetMsgType::MASTERNODEPAYMENTSYNC,
    NetMsgType::MNANNOUNCE,
    NetMsgType::MNPING,
    NetMsgType::SYNCSTATUSCOUNT,
    NetMsgType::MNGOVERNANCESYNC,
    NetMsgType::MNGOVERNANCEOBJECT,
    NetMsgType::MNGOVERNANCEOBJECTVOTE,
    NetMsgType::MNVERIFY,
};
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));

CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
{
    memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    nMessageSize = -1;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
{
    memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    strncpy(pchCommand, pszCommand, COMMAND_SIZE);
    nMessageSize = nMessageSizeIn;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

std::string CMessageHeader::GetCommand() const
{
    return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}

bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
{
    // Check start string
    if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
        return false;

    // Check the command string for errors
    for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
    {
        if (*p1 == 0)
        {
            // Must be all zeros after the first zero
            for (; p1 < pchCommand + COMMAND_SIZE; p1++)
                if (*p1 != 0)
                    return false;
        }
        else if (*p1 < ' ' || *p1 > 0x7E)
            return false;
    }

    // Message size
    if (nMessageSize > MAX_SIZE)
    {
        LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

CAddress::CAddress() : CService()
{
    Init();
}

CAddress::CAddress(CService ipIn, ServiceFlags nServicesIn) : CService(ipIn)
{
    Init();
    nServices = nServicesIn;
}

void CAddress::Init()
{
    nServices = NODE_NONE;
    nTime = 100000000;
}

CInv::CInv()
{
    type = 0;
    hash.SetNull();
}

CInv::CInv(int typeIn, const uint256& hashIn)
{
    type = typeIn;
    hash = hashIn;
}

// Machinecoin
CInv::CInv(const std::string& strType, const uint256& hashIn)
{
    unsigned int i;
    for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
    {
        if (strType == ppszTypeName[i])
        {
            type = i;
            break;
        }
    }
    if (i == ARRAYLEN(ppszTypeName))
        throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType));
    hash = hashIn;
}

bool CInv::IsKnownType() const
{
    return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}

std::string CInv::GetCommand() const
{
    std::string cmd;
    if (type & MSG_WITNESS_FLAG)
        cmd.append("witness-");

    if (!IsKnownType())
        throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
    return ppszTypeName[type];
}

bool operator<(const CInv& a, const CInv& b)
{
    return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}

std::string CInv::ToString() const
{
    try {
        return strprintf("%s %s", GetCommand(), hash.ToString());
    } catch(const std::out_of_range &) {
        return strprintf("0x%08x %s", type, hash.ToString());
    }
}

const std::vector<std::string> &getAllNetMessageTypes()
{
    return allNetMessageTypesVec;
}
<|endoftext|>


<commit_before>#include <QDebug>

#include "sysuid.h"
#include "main.h"

#include <QTimer>
#include <QDebug>
#include <DuiSceneManager>
#include <DuiApplication>
#include <DuiApplicationWindow>

#include "signal.h"

TestObj::TestObj() : QObject()
{
}

TestObj::~TestObj()
{
}

void TestObj::doRotation()
{
    int orientation = (int)DuiSceneManager::instance()->orientationAngle();
    orientation += 90;
    orientation %= 360;
    DuiSceneManager::instance()->setOrientationAngle((Dui::OrientationAngle) orientation);
}

static DuiApplication *exitPtr;
void sysuid_exit(int sig)
{
    Q_UNUSED(sig);
    if (exitPtr) {
        exitPtr->quit();
        exitPtr = NULL;
    }
}

int main(int argc, char** argv)
{
    DuiApplication app(argc, argv);
    exitPtr = &app;

    DuiApplicationWindow win;
    Qt::WindowFlags flags = 0;
        flags |= Qt::FramelessWindowHint;// | Qt::WindowStaysOnTopHint;
    win.setWindowOpacity(0);
    win.setWindowFlags(flags);

    // qDebug and qWarning are filttered off.
    qInstallMsgHandler(0);

    signal(SIGINT, sysuid_exit);

    Sysuid daemon;

    /* Comment in if rotation test needed. */
    TestObj obj;
    QTimer *rotation = new QTimer(0);
    rotation->setInterval(5*1000);
    rotation->start();
    QObject::connect(rotation, SIGNAL(timeout()), &obj, SLOT(doRotation()));
    /**/

    int ret = app.exec();
    //qDebug() << "Bye!";
    return ret;
}

<commit_msg>Rotation commented out.<commit_after>#include <QDebug>

#include "sysuid.h"
#include "main.h"

#include <QTimer>
#include <QDebug>
#include <DuiSceneManager>
#include <DuiApplication>
#include <DuiApplicationWindow>

#include "signal.h"

TestObj::TestObj() : QObject()
{
}

TestObj::~TestObj()
{
}

void TestObj::doRotation()
{
    int orientation = (int)DuiSceneManager::instance()->orientationAngle();
    orientation += 90;
    orientation %= 360;
    DuiSceneManager::instance()->setOrientationAngle((Dui::OrientationAngle) orientation);
}

static DuiApplication *exitPtr;
void sysuid_exit(int sig)
{
    Q_UNUSED(sig);
    if (exitPtr) {
        exitPtr->quit();
        exitPtr = NULL;
    }
}

int main(int argc, char** argv)
{
    DuiApplication app(argc, argv);
    exitPtr = &app;

    DuiApplicationWindow win;
    Qt::WindowFlags flags = 0;
        flags |= Qt::FramelessWindowHint;// | Qt::WindowStaysOnTopHint;
    win.setWindowOpacity(0);
    win.setWindowFlags(flags);

    // qDebug and qWarning are filttered off.
    qInstallMsgHandler(0);

    signal(SIGINT, sysuid_exit);

    Sysuid daemon;

    /* Comment in if rotation test needed. *
    TestObj obj;
    QTimer *rotation = new QTimer(0);
    rotation->setInterval(5*1000);
    rotation->start();
    QObject::connect(rotation, SIGNAL(timeout()), &obj, SLOT(doRotation()));
    **/

    int ret = app.exec();
    //qDebug() << "Bye!";
    return ret;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include "hmd_ovr.h"

#if BGFX_CONFIG_USE_OVR

namespace bgfx
{
#define _OVR_CHECK(_call) \
			BX_MACRO_BLOCK_BEGIN \
				ovrResult __result__ = _call; \
				BX_CHECK(OVR_SUCCESS(__result__), #_call " FAILED %d", __result__); \
			BX_MACRO_BLOCK_END

#if BGFX_CONFIG_DEBUG
#	define OVR_CHECK(_call) _OVR_CHECK(_call)
#else
#	define OVR_CHECK(_call) _call
#endif // BGFX_CONFIG_DEBUG

	OVR::OVR()
		: m_hmd(NULL)
		, m_enabled(false)
		, m_mirror(NULL)
		, m_frameIndex(0)
		, m_sensorSampleTime(0)
	{
		memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
	}

	OVR::~OVR()
	{
		BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
	}

	void OVR::init()
	{
		ovrResult result = ovr_Initialize(NULL);

		if (result != ovrSuccess)
		{
			BX_TRACE("Unable to create OVR device.");
			return;
		}

		ovrGraphicsLuid luid;
		result = ovr_Create(&m_hmd, &luid);
		if (result != ovrSuccess)
		{
			BX_TRACE("Unable to create OVR device.");
			return;
		}

		m_hmdDesc = ovr_GetHmdDesc(m_hmd);

		BX_TRACE("HMD: %s, %s, firmware: %d.%d"
			, m_hmdDesc.ProductName
			, m_hmdDesc.Manufacturer
			, m_hmdDesc.FirmwareMajor
			, m_hmdDesc.FirmwareMinor
			);

		ovrSizei sizeL = ovr_GetFovTextureSize(m_hmd, ovrEye_Left,  m_hmdDesc.DefaultEyeFov[0], 1.0f);
		ovrSizei sizeR = ovr_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmdDesc.DefaultEyeFov[1], 1.0f);
		m_hmdSize.w = sizeL.w + sizeR.w;
		m_hmdSize.h = bx::uint32_max(sizeL.h, sizeR.h);
	}

	void OVR::shutdown()
	{
		BX_CHECK(!m_enabled, "HMD not disabled.");

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			if (NULL != m_eyeBuffers[ii])
			{
				m_eyeBuffers[ii]->destroy(m_hmd);
				m_eyeBuffers[ii] = NULL;
			}
		}

		if (NULL != m_mirror)
		{
			m_mirror->destroy(m_hmd);
			m_mirror = NULL;
		}

		ovr_Destroy(m_hmd);
		m_hmd = NULL;
		ovr_Shutdown();
	}

	void OVR::getViewport(uint8_t _eye, Rect* _viewport)
	{
		_viewport->m_x      = 0;
		_viewport->m_y      = 0;
		_viewport->m_width  = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
		_viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
	}

	void OVR::renderEyeStart(uint8_t _eye)
	{
		m_eyeBuffers[_eye]->render(m_hmd);
	}

	bool OVR::postReset()
	{
		if (NULL == m_hmd)
		{
			return false;
		}

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			m_erd[ii] = ovr_GetRenderDesc(m_hmd, ovrEyeType(ii), m_hmdDesc.DefaultEyeFov[ii]);
		}

		m_enabled = true;

		return true;
	}

	void OVR::preReset()
	{
		if (m_enabled)
		{
			// on window resize this will recreate the mirror texture in ovrPostReset
			m_mirror->destroy(m_hmd);
			m_mirror = NULL;
			m_enabled = false;
		}
	}

	OVR::Enum OVR::swap(HMD& _hmd, bool originBottomLeft)
	{
		_hmd.flags = BGFX_HMD_NONE;

		if (NULL != m_hmd)
		{
			_hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
			_hmd.deviceWidth  = m_hmdDesc.Resolution.w;
			_hmd.deviceHeight = m_hmdDesc.Resolution.h;
		}

		if (!m_enabled)
		{
			return NotEnabled;
		}

		ovrResult result;

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			m_eyeBuffers[ii]->postRender(m_hmd);
			result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain);
			if (!OVR_SUCCESS(result) )
			{
				return DeviceLost;
			}
		}

		_hmd.flags |= BGFX_HMD_RENDERING;

		// finish frame for current eye
		ovrViewScaleDesc viewScaleDesc;
		viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
		viewScaleDesc.HmdToEyeOffset[0] = m_hmdToEyeOffset[0];
		viewScaleDesc.HmdToEyeOffset[1] = m_hmdToEyeOffset[1];

		// create the main eye layer
		ovrLayerEyeFov eyeLayer;
		eyeLayer.Header.Type = ovrLayerType_EyeFov;
		eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			eyeLayer.ColorTexture[ii]    = m_eyeBuffers[ii]->m_textureSwapChain;
			eyeLayer.Viewport[ii].Pos.x  = 0;
			eyeLayer.Viewport[ii].Pos.y  = 0;
			eyeLayer.Viewport[ii].Size.w = m_eyeBuffers[ii]->m_eyeTextureSize.w;
			eyeLayer.Viewport[ii].Size.h = m_eyeBuffers[ii]->m_eyeTextureSize.h;
			eyeLayer.Fov[ii]             = m_hmdDesc.DefaultEyeFov[ii];
			eyeLayer.RenderPose[ii]      = m_pose[ii];
			eyeLayer.SensorSampleTime    = m_sensorSampleTime;
		}

		// append all the layers to global list
		ovrLayerHeader* layerList = &eyeLayer.Header;

		result = ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
		if (!OVR_SUCCESS(result) )
		{
			return DeviceLost;
		}

		// perform mirror texture blit right after the entire frame is submitted to HMD
		m_mirror->blit(m_hmd);

		m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;
		m_hmdToEyeOffset[1] = m_erd[1].HmdToEyeOffset;

		ovr_GetEyePoses(m_hmd, m_frameIndex, ovrTrue, m_hmdToEyeOffset, m_pose, &m_sensorSampleTime);

		getEyePose(_hmd);

		return Success;
	}

	void OVR::recenter()
	{
		if (NULL != m_hmd)
		{
			OVR_CHECK(ovr_RecenterTrackingOrigin(m_hmd) );
		}
	}

	void OVR::getEyePose(HMD& _hmd)
	{
		if (NULL != m_hmd)
		{
			for (uint32_t ii = 0; ii < 2; ++ii)
			{
				const ovrPosef& pose = m_pose[ii];
				HMD::Eye& eye = _hmd.eye[ii];
				eye.rotation[0] = pose.Orientation.x;
				eye.rotation[1] = pose.Orientation.y;
				eye.rotation[2] = pose.Orientation.z;
				eye.rotation[3] = pose.Orientation.w;
				eye.translation[0] = pose.Position.x;
				eye.translation[1] = pose.Position.y;
				eye.translation[2] = pose.Position.z;

				const ovrEyeRenderDesc& erd = m_erd[ii];
				eye.fov[0] = erd.Fov.UpTan;
				eye.fov[1] = erd.Fov.DownTan;
				eye.fov[2] = erd.Fov.LeftTan;
				eye.fov[3] = erd.Fov.RightTan;

				ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
				for (uint32_t jj = 0; jj < 4; ++jj)
				{
					for (uint32_t kk = 0; kk < 4; ++kk)
					{
						eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
					}
				}

				eye.viewOffset[0] = erd.HmdToEyeOffset.x;
				eye.viewOffset[1] = erd.HmdToEyeOffset.y;
				eye.viewOffset[2] = erd.HmdToEyeOffset.z;

				eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
				eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
			}
		}

		_hmd.width  = uint16_t(m_hmdSize.w);
		_hmd.height = uint16_t(m_hmdSize.h);
	}

} // namespace bgfx

#endif // BGFX_CONFIG_USE_OVR
<commit_msg>OculusVR: fix stereoscopic view<commit_after>/*
 * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include "hmd_ovr.h"

#if BGFX_CONFIG_USE_OVR

namespace bgfx
{
#define _OVR_CHECK(_call) \
			BX_MACRO_BLOCK_BEGIN \
				ovrResult __result__ = _call; \
				BX_CHECK(OVR_SUCCESS(__result__), #_call " FAILED %d", __result__); \
			BX_MACRO_BLOCK_END

#if BGFX_CONFIG_DEBUG
#	define OVR_CHECK(_call) _OVR_CHECK(_call)
#else
#	define OVR_CHECK(_call) _call
#endif // BGFX_CONFIG_DEBUG

	OVR::OVR()
		: m_hmd(NULL)
		, m_enabled(false)
		, m_mirror(NULL)
		, m_frameIndex(0)
		, m_sensorSampleTime(0)
	{
		memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
	}

	OVR::~OVR()
	{
		BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
	}

	void OVR::init()
	{
		ovrResult result = ovr_Initialize(NULL);

		if (result != ovrSuccess)
		{
			BX_TRACE("Unable to create OVR device.");
			return;
		}

		ovrGraphicsLuid luid;
		result = ovr_Create(&m_hmd, &luid);
		if (result != ovrSuccess)
		{
			BX_TRACE("Unable to create OVR device.");
			return;
		}

		m_hmdDesc = ovr_GetHmdDesc(m_hmd);

		BX_TRACE("HMD: %s, %s, firmware: %d.%d"
			, m_hmdDesc.ProductName
			, m_hmdDesc.Manufacturer
			, m_hmdDesc.FirmwareMajor
			, m_hmdDesc.FirmwareMinor
			);

		ovrSizei sizeL = ovr_GetFovTextureSize(m_hmd, ovrEye_Left,  m_hmdDesc.DefaultEyeFov[0], 1.0f);
		ovrSizei sizeR = ovr_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmdDesc.DefaultEyeFov[1], 1.0f);
		m_hmdSize.w = sizeL.w + sizeR.w;
		m_hmdSize.h = bx::uint32_max(sizeL.h, sizeR.h);
	}

	void OVR::shutdown()
	{
		BX_CHECK(!m_enabled, "HMD not disabled.");

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			if (NULL != m_eyeBuffers[ii])
			{
				m_eyeBuffers[ii]->destroy(m_hmd);
				m_eyeBuffers[ii] = NULL;
			}
		}

		if (NULL != m_mirror)
		{
			m_mirror->destroy(m_hmd);
			m_mirror = NULL;
		}

		ovr_Destroy(m_hmd);
		m_hmd = NULL;
		ovr_Shutdown();
	}

	void OVR::getViewport(uint8_t _eye, Rect* _viewport)
	{
		_viewport->m_x      = 0;
		_viewport->m_y      = 0;
		_viewport->m_width  = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
		_viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
	}

	void OVR::renderEyeStart(uint8_t _eye)
	{
		m_eyeBuffers[_eye]->render(m_hmd);
	}

	bool OVR::postReset()
	{
		if (NULL == m_hmd)
		{
			return false;
		}

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			m_erd[ii] = ovr_GetRenderDesc(m_hmd, ovrEyeType(ii), m_hmdDesc.DefaultEyeFov[ii]);
		}

		m_enabled = true;

		return true;
	}

	void OVR::preReset()
	{
		if (m_enabled)
		{
			// on window resize this will recreate the mirror texture in ovrPostReset
			m_mirror->destroy(m_hmd);
			m_mirror = NULL;
			m_enabled = false;
		}
	}

	OVR::Enum OVR::swap(HMD& _hmd, bool originBottomLeft)
	{
		_hmd.flags = BGFX_HMD_NONE;

		if (NULL != m_hmd)
		{
			_hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
			_hmd.deviceWidth  = m_hmdDesc.Resolution.w;
			_hmd.deviceHeight = m_hmdDesc.Resolution.h;
		}

		if (!m_enabled)
		{
			return NotEnabled;
		}

		ovrResult result;

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			m_eyeBuffers[ii]->postRender(m_hmd);
			result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain);
			if (!OVR_SUCCESS(result) )
			{
				return DeviceLost;
			}
		}

		_hmd.flags |= BGFX_HMD_RENDERING;

		// finish frame for current eye
		ovrViewScaleDesc viewScaleDesc;
		viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
		viewScaleDesc.HmdToEyeOffset[0] = m_hmdToEyeOffset[0];
		viewScaleDesc.HmdToEyeOffset[1] = m_hmdToEyeOffset[1];

		// create the main eye layer
		ovrLayerEyeFov eyeLayer;
		eyeLayer.Header.Type = ovrLayerType_EyeFov;
		eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;

		for (uint32_t ii = 0; ii < 2; ++ii)
		{
			eyeLayer.ColorTexture[ii]    = m_eyeBuffers[ii]->m_textureSwapChain;
			eyeLayer.Viewport[ii].Pos.x  = 0;
			eyeLayer.Viewport[ii].Pos.y  = 0;
			eyeLayer.Viewport[ii].Size.w = m_eyeBuffers[ii]->m_eyeTextureSize.w;
			eyeLayer.Viewport[ii].Size.h = m_eyeBuffers[ii]->m_eyeTextureSize.h;
			eyeLayer.Fov[ii]             = m_hmdDesc.DefaultEyeFov[ii];
			eyeLayer.RenderPose[ii]      = m_pose[ii];
			eyeLayer.SensorSampleTime    = m_sensorSampleTime;
		}

		// append all the layers to global list
		ovrLayerHeader* layerList = &eyeLayer.Header;

		result = ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
		if (!OVR_SUCCESS(result) )
		{
			return DeviceLost;
		}

		// perform mirror texture blit right after the entire frame is submitted to HMD
		m_mirror->blit(m_hmd);

		m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;
		m_hmdToEyeOffset[1] = m_erd[1].HmdToEyeOffset;

		ovr_GetEyePoses(m_hmd, m_frameIndex, ovrTrue, m_hmdToEyeOffset, m_pose, &m_sensorSampleTime);

		getEyePose(_hmd);

		return Success;
	}

	void OVR::recenter()
	{
		if (NULL != m_hmd)
		{
			OVR_CHECK(ovr_RecenterTrackingOrigin(m_hmd) );
		}
	}

	void OVR::getEyePose(HMD& _hmd)
	{
		if (NULL != m_hmd)
		{
			for (uint32_t ii = 0; ii < 2; ++ii)
			{
				const ovrPosef& pose = m_pose[ii];
				HMD::Eye& eye = _hmd.eye[ii];
				eye.rotation[0] = pose.Orientation.x;
				eye.rotation[1] = pose.Orientation.y;
				eye.rotation[2] = pose.Orientation.z;
				eye.rotation[3] = pose.Orientation.w;
				eye.translation[0] = pose.Position.x;
				eye.translation[1] = pose.Position.y;
				eye.translation[2] = pose.Position.z;

				const ovrEyeRenderDesc& erd = m_erd[ii];
				eye.fov[0] = erd.Fov.UpTan;
				eye.fov[1] = erd.Fov.DownTan;
				eye.fov[2] = erd.Fov.LeftTan;
				eye.fov[3] = erd.Fov.RightTan;

				ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
				for (uint32_t jj = 0; jj < 4; ++jj)
				{
					for (uint32_t kk = 0; kk < 4; ++kk)
					{
						eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
					}
				}

				eye.viewOffset[0] = -erd.HmdToEyeOffset.x;
				eye.viewOffset[1] = -erd.HmdToEyeOffset.y;
				eye.viewOffset[2] = -erd.HmdToEyeOffset.z;

				eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
				eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
			}
		}

		_hmd.width  = uint16_t(m_hmdSize.w);
		_hmd.height = uint16_t(m_hmdSize.h);
	}

} // namespace bgfx

#endif // BGFX_CONFIG_USE_OVR
<|endoftext|>


<commit_before>/*!
*	@file	MinimumWeightTriangulation.cpp
*	@brief	Functions for minimum weight triangulation
*/

#include "MinimumWeightTriangulation.h"

namespace psalm
{

/*!
*	Sets default attributes for the minimum-weight triangulation algorithm:
*	The objective function is set to be a minimum-area function.
*/

MinimumWeightTriangulation::MinimumWeightTriangulation()
{
	objective_function = minimum_area_and_normal_angle;
}

/*!
*	Applies triangulation algorithm to the input mesh. The function
*	requires the input mesh to consist solely of unconnected points. If
*	this is not the case, the function will abort.
*
*	@param input_mesh Mesh that will be triangulated.
*
*	@return true if the mesh could be triangulated, else false. Errors may
*	occur when the topology of the mesh is already defined.
*/

bool MinimumWeightTriangulation::apply_to(mesh& input_mesh)
{
	if(	input_mesh.num_faces() > 0 ||
		input_mesh.num_edges() > 0)
		return(false);

	size_t n = input_mesh.num_vertices();
	if(n < 3)
	{
		std::cerr	<< "psalm: MinimumWeightTriangulation::apply_to(): Not enough vertices to perform triangulation"
				<< std::endl;
		return(false);
	}

	indices = new size_t*[n];		// store minimum indices (private member)
	ktuple** weights = new ktuple*[n];	// store weights of triangulation (only required locally)

	for(size_t i = 0; i < n-1; i++)
	{
		indices[i] = new size_t[n];
		weights[i] = new ktuple[n];

		// Initialize weights array correctly
		if(i < n-1)
			weights[i][i+1] = 0;
		if(i < n-2)
			weights[i][i+2] = objective_function(	input_mesh.get_vertex(i),
								input_mesh.get_vertex(i+1),
								input_mesh.get_vertex(i+2));
	}

	size_t j = 2;
	while(j++ < n-1)	// this is correct -- the loop is supposed to start
				// with j == 3
	{
		for(size_t i = 0; i < n-j; i++)
		{
			size_t k = i+j;

			// Find minimum
			ktuple min_weight = boost::tuple<double, double>(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
			size_t min_index = std::numeric_limits<size_t>::max();
			for(size_t m = i+1; m < k; m++)
			{
				ktuple cur_weight = objective_function(	input_mesh.get_vertex(i),
									input_mesh.get_vertex(m),
									input_mesh.get_vertex(k));

				// The first component of the tuples can be
				// added; for the second component, only the
				// maximum of _all_ tuples is used

				double area	= weights[i][m].get<1>()+weights[m][k].get<1>()+cur_weight.get<1>();
				double angle	= std::max(	cur_weight.get<0>(),
								std::max(	weights[i][m].get<0>(),
										weights[m][k].get<0>()));

				ktuple res = boost::tuple<double, double>(angle, area);
				if(res < min_weight)
				{
					min_weight = res;
					min_index = m;
				}
			}

			weights[i][k] = min_weight;
			indices[i][k] = min_index;
		}
	}

	// Now weights[0][n-1] contains the weight of the minimal
	// triangulation. Construct triangulation using the stored indices.
	bool result = construct_triangulation(input_mesh, 0, n-1);

	for(size_t i = 0; i < n-1; i++)
	{
		delete[] weights[i];
		delete[] indices[i];
	}

	delete[] weights;
	delete[] indices;

	/*
		Mark _all_ vertices as boundary vertices. Upon subdivision, the
		boundary vertices will not be changed and we need to identify
		them when storing the subdivided mesh.
	*/

	for(size_t i = 0; i < input_mesh.num_vertices(); i++)
		input_mesh.get_vertex(i)->set_on_boundary();

	return(result);
}

/*!
*	Using the array of indices that achieve the minimum of the
*	minimum-weight triangulation, this function constructs the actual
*	triangulation of the mesh.
*
*	This function calls itself recursively.
*
*	@param input_mesh Mesh for which the triangles are constructed
*	@param i Smallest index for constructing a triangle
*	@param k Largest index for constructing a triangle
*
*	@return true if the triangulation could be constructed, else false.
*/

bool MinimumWeightTriangulation::construct_triangulation(mesh& input_mesh, size_t i, size_t k)
{
	// abort
	if(i+2 == k)
	{
		if(input_mesh.add_face(	input_mesh.get_vertex(i),
					input_mesh.get_vertex(i+1),
					input_mesh.get_vertex(k)) == NULL)
		{
			std::cerr << "psalm: Error: MinimumWeightTriangulation: Unable to construct triangulation\n";
			return(false);
		}
	}

	// use minimum index to branch off
	else
	{
		size_t j = indices[i][k];
		if(j != i+1)
		{
			if(!construct_triangulation(input_mesh, i, j))
				return(false);
		}

		if(input_mesh.add_face(	input_mesh.get_vertex(i),
					input_mesh.get_vertex(j),
					input_mesh.get_vertex(k)) == NULL)
		{
			std::cerr << "psalm: Error: MinimumWeightTriangulation: Unable to construct triangulation\n";
			return(false);
		}

		if(j != k-1)
		{
			if(!construct_triangulation(input_mesh, j, k))
				return(false);
		}
	}

	return(true);
}

} // end of namespace "psalm"
<commit_msg>Fixed tuple initialization<commit_after>/*!
*	@file	MinimumWeightTriangulation.cpp
*	@brief	Functions for minimum weight triangulation
*/

#include "MinimumWeightTriangulation.h"

namespace psalm
{

/*!
*	Sets default attributes for the minimum-weight triangulation algorithm:
*	The objective function is set to be a minimum-area function.
*/

MinimumWeightTriangulation::MinimumWeightTriangulation()
{
	objective_function = minimum_area_and_normal_angle;
}

/*!
*	Applies triangulation algorithm to the input mesh. The function
*	requires the input mesh to consist solely of unconnected points. If
*	this is not the case, the function will abort.
*
*	@param input_mesh Mesh that will be triangulated.
*
*	@return true if the mesh could be triangulated, else false. Errors may
*	occur when the topology of the mesh is already defined.
*/

bool MinimumWeightTriangulation::apply_to(mesh& input_mesh)
{
	if(	input_mesh.num_faces() > 0 ||
		input_mesh.num_edges() > 0)
		return(false);

	size_t n = input_mesh.num_vertices();
	if(n < 3)
	{
		std::cerr	<< "psalm: MinimumWeightTriangulation::apply_to(): Not enough vertices to perform triangulation"
				<< std::endl;
		return(false);
	}

	indices = new size_t*[n];		// store minimum indices (private member)
	ktuple** weights = new ktuple*[n];	// store weights of triangulation (only required locally)

	for(size_t i = 0; i < n-1; i++)
	{
		indices[i] = new size_t[n];
		weights[i] = new ktuple[n];

		// Initialize weights array correctly
		if(i < n-1)
			weights[i][i+1] = ktuple( 0 );
		if(i < n-2)
			weights[i][i+2] = objective_function(	input_mesh.get_vertex(i),
								input_mesh.get_vertex(i+1),
								input_mesh.get_vertex(i+2));
	}

	size_t j = 2;
	while(j++ < n-1)	// this is correct -- the loop is supposed to start
				// with j == 3
	{
		for(size_t i = 0; i < n-j; i++)
		{
			size_t k = i+j;

			// Find minimum
			ktuple min_weight = boost::tuple<double, double>(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
			size_t min_index = std::numeric_limits<size_t>::max();
			for(size_t m = i+1; m < k; m++)
			{
				ktuple cur_weight = objective_function(	input_mesh.get_vertex(i),
									input_mesh.get_vertex(m),
									input_mesh.get_vertex(k));

				// The first component of the tuples can be
				// added; for the second component, only the
				// maximum of _all_ tuples is used

				double area	= weights[i][m].get<1>()+weights[m][k].get<1>()+cur_weight.get<1>();
				double angle	= std::max(	cur_weight.get<0>(),
								std::max(	weights[i][m].get<0>(),
										weights[m][k].get<0>()));

				ktuple res = boost::tuple<double, double>(angle, area);
				if(res < min_weight)
				{
					min_weight = res;
					min_index = m;
				}
			}

			weights[i][k] = min_weight;
			indices[i][k] = min_index;
		}
	}

	// Now weights[0][n-1] contains the weight of the minimal
	// triangulation. Construct triangulation using the stored indices.
	bool result = construct_triangulation(input_mesh, 0, n-1);

	for(size_t i = 0; i < n-1; i++)
	{
		delete[] weights[i];
		delete[] indices[i];
	}

	delete[] weights;
	delete[] indices;

	/*
		Mark _all_ vertices as boundary vertices. Upon subdivision, the
		boundary vertices will not be changed and we need to identify
		them when storing the subdivided mesh.
	*/

	for(size_t i = 0; i < input_mesh.num_vertices(); i++)
		input_mesh.get_vertex(i)->set_on_boundary();

	return(result);
}

/*!
*	Using the array of indices that achieve the minimum of the
*	minimum-weight triangulation, this function constructs the actual
*	triangulation of the mesh.
*
*	This function calls itself recursively.
*
*	@param input_mesh Mesh for which the triangles are constructed
*	@param i Smallest index for constructing a triangle
*	@param k Largest index for constructing a triangle
*
*	@return true if the triangulation could be constructed, else false.
*/

bool MinimumWeightTriangulation::construct_triangulation(mesh& input_mesh, size_t i, size_t k)
{
	// abort
	if(i+2 == k)
	{
		if(input_mesh.add_face(	input_mesh.get_vertex(i),
					input_mesh.get_vertex(i+1),
					input_mesh.get_vertex(k)) == NULL)
		{
			std::cerr << "psalm: Error: MinimumWeightTriangulation: Unable to construct triangulation\n";
			return(false);
		}
	}

	// use minimum index to branch off
	else
	{
		size_t j = indices[i][k];
		if(j != i+1)
		{
			if(!construct_triangulation(input_mesh, i, j))
				return(false);
		}

		if(input_mesh.add_face(	input_mesh.get_vertex(i),
					input_mesh.get_vertex(j),
					input_mesh.get_vertex(k)) == NULL)
		{
			std::cerr << "psalm: Error: MinimumWeightTriangulation: Unable to construct triangulation\n";
			return(false);
		}

		if(j != k-1)
		{
			if(!construct_triangulation(input_mesh, j, k))
				return(false);
		}
	}

	return(true);
}

} // end of namespace "psalm"
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Testcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "protocol.h"

#include "chainparams.h"
#include "util.h"
#include "utilstrencodings.h"

#ifndef WIN32
# include <arpa/inet.h>
#endif

static const char* ppszTypeName[] =
{
    "ERROR",
    "tx",
    "block",
    "filtered block"
};

CMessageHeader::CMessageHeader()
{
    memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    nMessageSize = -1;
    nChecksum = 0;
}

CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
{
    memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    strncpy(pchCommand, pszCommand, COMMAND_SIZE);
    nMessageSize = nMessageSizeIn;
    nChecksum = 0;
}

std::string CMessageHeader::GetCommand() const
{
    return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}

bool CMessageHeader::IsValid() const
{
    // Check start string
    if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
        return false;

    // Check the command string for errors
    for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
    {
        if (*p1 == 0)
        {
            // Must be all zeros after the first zero
            for (; p1 < pchCommand + COMMAND_SIZE; p1++)
                if (*p1 != 0)
                    return false;
        }
        else if (*p1 < ' ' || *p1 > 0x7E)
            return false;
    }

    // Message size
    if (nMessageSize > MAX_SIZE)
    {
        LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

CAddress::CAddress() : CService()
{
    Init();
}

CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
{
    Init();
    nServices = nServicesIn;
}

void CAddress::Init()
{
    nServices = NODE_NETWORK;
    nTime = 100000000;
    nLastTry = 0;
}

CInv::CInv()
{
    type = 0;
    hash.SetNull();
}

CInv::CInv(int typeIn, const uint256& hashIn)
{
    type = typeIn;
    hash = hashIn;
}

CInv::CInv(const std::string& strType, const uint256& hashIn)
{
    unsigned int i;
    for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
    {
        if (strType == ppszTypeName[i])
        {
            type = i;
            break;
        }
    }
    if (i == ARRAYLEN(ppszTypeName))
        throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
    hash = hashIn;
}

bool operator<(const CInv& a, const CInv& b)
{
    return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}

bool CInv::IsKnownType() const
{
    return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}

const char* CInv::GetCommand() const
{
    if (!IsKnownType())
        throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
    return ppszTypeName[type];
}

std::string CInv::ToString() const
{
    return strprintf("%s %s", GetCommand(), hash.ToString());
}
<commit_msg>Update protocol.cpp<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Testcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "protocol.h"

#include "chainparams.h"
#include "util.h"
#include "utilstrencodings.h"

#ifndef WIN32
# include <arpa/inet.h>
#endif

static const char* ppszTypeName[] =
{
    "ERROR",
    "tx",
    "block",
    "filtered block"
};

CMessageHeader::CMessageHeader()
{
    memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    nMessageSize = -1;
    nChecksum = 0;
}

CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
{
    memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
    memset(pchCommand, 0, sizeof(pchCommand));
    strncpy(pchCommand, pszCommand, COMMAND_SIZE);
    nMessageSize = nMessageSizeIn;
    nChecksum = 0;
}

std::string CMessageHeader::GetCommand() const
{
    return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}

bool CMessageHeader::IsValid() const
{
    // Check start string
    if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
        return false;

    // Check the command string for errors
    for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
    {
        if (*p1 == 0)
        {
            // Must be all zeros after the first zero
            for (; p1 < pchCommand + COMMAND_SIZE; p1++)
                if (*p1 != 0)
                    return false;
        }
        else if (*p1 < ' ' || *p1 > 0x7E)
            return false;
    }

    // Message size
    if (nMessageSize > MAX_SIZE)
    {
        LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

CAddress::CAddress() : CService()
{
    Init();
}

CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
{
    Init();
    nServices = nServicesIn;
}

void CAddress::Init()
{
    nServices = NODE_NETWORK;
    nTime = 1421262356;
    nLastTry = 0;
}

CInv::CInv()
{
    type = 0;
    hash.SetNull();
}

CInv::CInv(int typeIn, const uint256& hashIn)
{
    type = typeIn;
    hash = hashIn;
}

CInv::CInv(const std::string& strType, const uint256& hashIn)
{
    unsigned int i;
    for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
    {
        if (strType == ppszTypeName[i])
        {
            type = i;
            break;
        }
    }
    if (i == ARRAYLEN(ppszTypeName))
        throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
    hash = hashIn;
}

bool operator<(const CInv& a, const CInv& b)
{
    return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}

bool CInv::IsKnownType() const
{
    return (type >= 1 && type < (int)ARRAYLEN(ppszTypeName));
}

const char* CInv::GetCommand() const
{
    if (!IsKnownType())
        throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
    return ppszTypeName[type];
}

std::string CInv::ToString() const
{
    return strprintf("%s %s", GetCommand(), hash.ToString());
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <protocol.h>

#include <chainparams.h>
#include <config.h>
#include <util/strencodings.h>
#include <util/system.h>

#ifndef WIN32
#include <arpa/inet.h>
#endif
#include <atomic>

static std::atomic<bool> g_initial_block_download_completed(false);

namespace NetMsgType {
const char *VERSION = "version";
const char *VERACK = "verack";
const char *ADDR = "addr";
const char *ADDRV2 = "addrv2";
const char *SENDADDRV2 = "sendaddrv2";
const char *INV = "inv";
const char *GETDATA = "getdata";
const char *MERKLEBLOCK = "merkleblock";
const char *GETBLOCKS = "getblocks";
const char *GETHEADERS = "getheaders";
const char *TX = "tx";
const char *HEADERS = "headers";
const char *BLOCK = "block";
const char *GETADDR = "getaddr";
const char *MEMPOOL = "mempool";
const char *PING = "ping";
const char *PONG = "pong";
const char *NOTFOUND = "notfound";
const char *FILTERLOAD = "filterload";
const char *FILTERADD = "filteradd";
const char *FILTERCLEAR = "filterclear";
const char *SENDHEADERS = "sendheaders";
const char *FEEFILTER = "feefilter";
const char *SENDCMPCT = "sendcmpct";
const char *CMPCTBLOCK = "cmpctblock";
const char *GETBLOCKTXN = "getblocktxn";
const char *BLOCKTXN = "blocktxn";
const char *GETCFILTERS = "getcfilters";
const char *CFILTER = "cfilter";
const char *GETCFHEADERS = "getcfheaders";
const char *CFHEADERS = "cfheaders";
const char *GETCFCHECKPT = "getcfcheckpt";
const char *CFCHECKPT = "cfcheckpt";
const char *AVAHELLO = "avahello";
const char *AVAPOLL = "avapoll";
const char *AVARESPONSE = "avaresponse";
const char *AVAPROOF = "avaproof";

bool IsBlockLike(const std::string &strCommand) {
    return strCommand == NetMsgType::BLOCK ||
           strCommand == NetMsgType::CMPCTBLOCK ||
           strCommand == NetMsgType::BLOCKTXN;
}
}; // namespace NetMsgType

/**
 * All known message types. Keep this in the same order as the list of messages
 * above and in protocol.h.
 */
static const std::string allNetMessageTypes[] = {
    NetMsgType::VERSION,     NetMsgType::VERACK,       NetMsgType::ADDR,
    NetMsgType::ADDRV2,      NetMsgType::SENDADDRV2,   NetMsgType::INV,
    NetMsgType::GETDATA,     NetMsgType::MERKLEBLOCK,  NetMsgType::GETBLOCKS,
    NetMsgType::GETHEADERS,  NetMsgType::TX,           NetMsgType::HEADERS,
    NetMsgType::BLOCK,       NetMsgType::GETADDR,      NetMsgType::MEMPOOL,
    NetMsgType::PING,        NetMsgType::PONG,         NetMsgType::NOTFOUND,
    NetMsgType::FILTERLOAD,  NetMsgType::FILTERADD,    NetMsgType::FILTERCLEAR,
    NetMsgType::SENDHEADERS, NetMsgType::FEEFILTER,    NetMsgType::SENDCMPCT,
    NetMsgType::CMPCTBLOCK,  NetMsgType::GETBLOCKTXN,  NetMsgType::BLOCKTXN,
    NetMsgType::GETCFILTERS, NetMsgType::CFILTER,      NetMsgType::GETCFHEADERS,
    NetMsgType::CFHEADERS,   NetMsgType::GETCFCHECKPT, NetMsgType::CFCHECKPT,
};
static const std::vector<std::string>
    allNetMessageTypesVec(allNetMessageTypes,
                          allNetMessageTypes + ARRAYLEN(allNetMessageTypes));

CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn) {
    memcpy(std::begin(pchMessageStart), std::begin(pchMessageStartIn),
           MESSAGE_START_SIZE);
    memset(pchCommand.data(), 0, sizeof(pchCommand));
    nMessageSize = -1;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn,
                               const char *pszCommand,
                               unsigned int nMessageSizeIn) {
    memcpy(std::begin(pchMessageStart), std::begin(pchMessageStartIn),
           MESSAGE_START_SIZE);
    // Copy the command name, zero-padding to COMMAND_SIZE bytes
    size_t i = 0;
    for (; i < pchCommand.size() && pszCommand[i] != 0; ++i) {
        pchCommand[i] = pszCommand[i];
    }
    // Assert that the command name passed in is not longer than COMMAND_SIZE
    assert(pszCommand[i] == 0);
    for (; i < pchCommand.size(); ++i) {
        pchCommand[i] = 0;
    }

    nMessageSize = nMessageSizeIn;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

std::string CMessageHeader::GetCommand() const {
    // return std::string(pchCommand.begin(), pchCommand.end());
    return std::string(pchCommand.data(),
                       pchCommand.data() +
                           strnlen(pchCommand.data(), COMMAND_SIZE));
}

static bool
CheckHeaderMagicAndCommand(const CMessageHeader &header,
                           const CMessageHeader::MessageMagic &magic) {
    // Check start string
    if (memcmp(std::begin(header.pchMessageStart), std::begin(magic),
               CMessageHeader::MESSAGE_START_SIZE) != 0) {
        return false;
    }

    // Check the command string for errors
    for (const char *p1 = header.pchCommand.data();
         p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE; p1++) {
        if (*p1 == 0) {
            // Must be all zeros after the first zero
            for (; p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE;
                 p1++) {
                if (*p1 != 0) {
                    return false;
                }
            }
        } else if (*p1 < ' ' || *p1 > 0x7E) {
            return false;
        }
    }

    return true;
}

bool CMessageHeader::IsValid(const Config &config) const {
    // Check start string
    if (!CheckHeaderMagicAndCommand(*this,
                                    config.GetChainParams().NetMagic())) {
        return false;
    }

    // Message size
    if (IsOversized(config)) {
        LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) is oversized\n",
                  GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

/**
 * This is a transition method in order to stay compatible with older code that
 * do not use the config. It assumes message will not get too large. This cannot
 * be used for any piece of code that will download blocks as blocks may be
 * bigger than the permitted size. Idealy, code that uses this function should
 * be migrated toward using the config.
 */
bool CMessageHeader::IsValidWithoutConfig(const MessageMagic &magic) const {
    // Check start string
    if (!CheckHeaderMagicAndCommand(*this, magic)) {
        return false;
    }

    // Message size
    if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
        LogPrintf(
            "CMessageHeader::IsValidForSeeder(): (%s, %u bytes) is oversized\n",
            GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

bool CMessageHeader::IsOversized(const Config &config) const {
    // If the message doesn't not contain a block content, check against
    // MAX_PROTOCOL_MESSAGE_LENGTH.
    if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH &&
        !NetMsgType::IsBlockLike(GetCommand())) {
        return true;
    }

    // Scale the maximum accepted size with the block size.
    if (nMessageSize > 2 * config.GetMaxBlockSize()) {
        return true;
    }

    return false;
}

ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
    if ((services & NODE_NETWORK_LIMITED) &&
        g_initial_block_download_completed) {
        return ServiceFlags(NODE_NETWORK_LIMITED);
    }
    return ServiceFlags(NODE_NETWORK);
}

void SetServiceFlagsIBDCache(bool state) {
    g_initial_block_download_completed = state;
}

std::string CInv::GetCommand() const {
    std::string cmd;
    switch (GetKind()) {
        case MSG_TX:
            return cmd.append(NetMsgType::TX);
        case MSG_BLOCK:
            return cmd.append(NetMsgType::BLOCK);
        case MSG_FILTERED_BLOCK:
            return cmd.append(NetMsgType::MERKLEBLOCK);
        case MSG_CMPCT_BLOCK:
            return cmd.append(NetMsgType::CMPCTBLOCK);
        case MSG_AVA_PROOF:
            return cmd.append(NetMsgType::AVAPROOF);
        default:
            throw std::out_of_range(
                strprintf("CInv::GetCommand(): type=%d unknown type", type));
    }
}

std::string CInv::ToString() const {
    try {
        return strprintf("%s %s", GetCommand(), hash.ToString());
    } catch (const std::out_of_range &) {
        return strprintf("0x%08x %s", type, hash.ToString());
    }
}

const std::vector<std::string> &getAllNetMessageTypes() {
    return allNetMessageTypesVec;
}

/**
 * Convert a service flag (NODE_*) to a human readable string.
 * It supports unknown service flags which will be returned as "UNKNOWN[...]".
 * @param[in] bit the service flag is calculated as (1 << bit)
 */
static std::string serviceFlagToStr(const size_t bit) {
    const uint64_t service_flag = 1ULL << bit;
    switch (ServiceFlags(service_flag)) {
        case NODE_NONE:
            // impossible
            abort();
        case NODE_NETWORK:
            return "NETWORK";
        case NODE_GETUTXO:
            return "GETUTXO";
        case NODE_BLOOM:
            return "BLOOM";
        case NODE_NETWORK_LIMITED:
            return "NETWORK_LIMITED";
        case NODE_COMPACT_FILTERS:
            return "COMPACT_FILTERS";
        case NODE_AVALANCHE:
            return "AVALANCHE";
        default:
            std::ostringstream stream;
            stream.imbue(std::locale::classic());
            stream << "UNKNOWN[";
            stream << "2^" << bit;
            stream << "]";
            return stream.str();
    }
}

std::vector<std::string> serviceFlagsToStr(const uint64_t flags) {
    std::vector<std::string> str_flags;

    for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
        if (flags & (1ULL << i)) {
            str_flags.emplace_back(serviceFlagToStr(i));
        }
    }

    return str_flags;
}
<commit_msg>refactor: remove unused header <arpa/inet.h> in protocol.cpp<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <protocol.h>

#include <chainparams.h>
#include <config.h>
#include <util/strencodings.h>
#include <util/system.h>

#include <atomic>

static std::atomic<bool> g_initial_block_download_completed(false);

namespace NetMsgType {
const char *VERSION = "version";
const char *VERACK = "verack";
const char *ADDR = "addr";
const char *ADDRV2 = "addrv2";
const char *SENDADDRV2 = "sendaddrv2";
const char *INV = "inv";
const char *GETDATA = "getdata";
const char *MERKLEBLOCK = "merkleblock";
const char *GETBLOCKS = "getblocks";
const char *GETHEADERS = "getheaders";
const char *TX = "tx";
const char *HEADERS = "headers";
const char *BLOCK = "block";
const char *GETADDR = "getaddr";
const char *MEMPOOL = "mempool";
const char *PING = "ping";
const char *PONG = "pong";
const char *NOTFOUND = "notfound";
const char *FILTERLOAD = "filterload";
const char *FILTERADD = "filteradd";
const char *FILTERCLEAR = "filterclear";
const char *SENDHEADERS = "sendheaders";
const char *FEEFILTER = "feefilter";
const char *SENDCMPCT = "sendcmpct";
const char *CMPCTBLOCK = "cmpctblock";
const char *GETBLOCKTXN = "getblocktxn";
const char *BLOCKTXN = "blocktxn";
const char *GETCFILTERS = "getcfilters";
const char *CFILTER = "cfilter";
const char *GETCFHEADERS = "getcfheaders";
const char *CFHEADERS = "cfheaders";
const char *GETCFCHECKPT = "getcfcheckpt";
const char *CFCHECKPT = "cfcheckpt";
const char *AVAHELLO = "avahello";
const char *AVAPOLL = "avapoll";
const char *AVARESPONSE = "avaresponse";
const char *AVAPROOF = "avaproof";

bool IsBlockLike(const std::string &strCommand) {
    return strCommand == NetMsgType::BLOCK ||
           strCommand == NetMsgType::CMPCTBLOCK ||
           strCommand == NetMsgType::BLOCKTXN;
}
}; // namespace NetMsgType

/**
 * All known message types. Keep this in the same order as the list of messages
 * above and in protocol.h.
 */
static const std::string allNetMessageTypes[] = {
    NetMsgType::VERSION,     NetMsgType::VERACK,       NetMsgType::ADDR,
    NetMsgType::ADDRV2,      NetMsgType::SENDADDRV2,   NetMsgType::INV,
    NetMsgType::GETDATA,     NetMsgType::MERKLEBLOCK,  NetMsgType::GETBLOCKS,
    NetMsgType::GETHEADERS,  NetMsgType::TX,           NetMsgType::HEADERS,
    NetMsgType::BLOCK,       NetMsgType::GETADDR,      NetMsgType::MEMPOOL,
    NetMsgType::PING,        NetMsgType::PONG,         NetMsgType::NOTFOUND,
    NetMsgType::FILTERLOAD,  NetMsgType::FILTERADD,    NetMsgType::FILTERCLEAR,
    NetMsgType::SENDHEADERS, NetMsgType::FEEFILTER,    NetMsgType::SENDCMPCT,
    NetMsgType::CMPCTBLOCK,  NetMsgType::GETBLOCKTXN,  NetMsgType::BLOCKTXN,
    NetMsgType::GETCFILTERS, NetMsgType::CFILTER,      NetMsgType::GETCFHEADERS,
    NetMsgType::CFHEADERS,   NetMsgType::GETCFCHECKPT, NetMsgType::CFCHECKPT,
};
static const std::vector<std::string>
    allNetMessageTypesVec(allNetMessageTypes,
                          allNetMessageTypes + ARRAYLEN(allNetMessageTypes));

CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn) {
    memcpy(std::begin(pchMessageStart), std::begin(pchMessageStartIn),
           MESSAGE_START_SIZE);
    memset(pchCommand.data(), 0, sizeof(pchCommand));
    nMessageSize = -1;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

CMessageHeader::CMessageHeader(const MessageMagic &pchMessageStartIn,
                               const char *pszCommand,
                               unsigned int nMessageSizeIn) {
    memcpy(std::begin(pchMessageStart), std::begin(pchMessageStartIn),
           MESSAGE_START_SIZE);
    // Copy the command name, zero-padding to COMMAND_SIZE bytes
    size_t i = 0;
    for (; i < pchCommand.size() && pszCommand[i] != 0; ++i) {
        pchCommand[i] = pszCommand[i];
    }
    // Assert that the command name passed in is not longer than COMMAND_SIZE
    assert(pszCommand[i] == 0);
    for (; i < pchCommand.size(); ++i) {
        pchCommand[i] = 0;
    }

    nMessageSize = nMessageSizeIn;
    memset(pchChecksum, 0, CHECKSUM_SIZE);
}

std::string CMessageHeader::GetCommand() const {
    // return std::string(pchCommand.begin(), pchCommand.end());
    return std::string(pchCommand.data(),
                       pchCommand.data() +
                           strnlen(pchCommand.data(), COMMAND_SIZE));
}

static bool
CheckHeaderMagicAndCommand(const CMessageHeader &header,
                           const CMessageHeader::MessageMagic &magic) {
    // Check start string
    if (memcmp(std::begin(header.pchMessageStart), std::begin(magic),
               CMessageHeader::MESSAGE_START_SIZE) != 0) {
        return false;
    }

    // Check the command string for errors
    for (const char *p1 = header.pchCommand.data();
         p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE; p1++) {
        if (*p1 == 0) {
            // Must be all zeros after the first zero
            for (; p1 < header.pchCommand.data() + CMessageHeader::COMMAND_SIZE;
                 p1++) {
                if (*p1 != 0) {
                    return false;
                }
            }
        } else if (*p1 < ' ' || *p1 > 0x7E) {
            return false;
        }
    }

    return true;
}

bool CMessageHeader::IsValid(const Config &config) const {
    // Check start string
    if (!CheckHeaderMagicAndCommand(*this,
                                    config.GetChainParams().NetMagic())) {
        return false;
    }

    // Message size
    if (IsOversized(config)) {
        LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) is oversized\n",
                  GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

/**
 * This is a transition method in order to stay compatible with older code that
 * do not use the config. It assumes message will not get too large. This cannot
 * be used for any piece of code that will download blocks as blocks may be
 * bigger than the permitted size. Idealy, code that uses this function should
 * be migrated toward using the config.
 */
bool CMessageHeader::IsValidWithoutConfig(const MessageMagic &magic) const {
    // Check start string
    if (!CheckHeaderMagicAndCommand(*this, magic)) {
        return false;
    }

    // Message size
    if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
        LogPrintf(
            "CMessageHeader::IsValidForSeeder(): (%s, %u bytes) is oversized\n",
            GetCommand(), nMessageSize);
        return false;
    }

    return true;
}

bool CMessageHeader::IsOversized(const Config &config) const {
    // If the message doesn't not contain a block content, check against
    // MAX_PROTOCOL_MESSAGE_LENGTH.
    if (nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH &&
        !NetMsgType::IsBlockLike(GetCommand())) {
        return true;
    }

    // Scale the maximum accepted size with the block size.
    if (nMessageSize > 2 * config.GetMaxBlockSize()) {
        return true;
    }

    return false;
}

ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
    if ((services & NODE_NETWORK_LIMITED) &&
        g_initial_block_download_completed) {
        return ServiceFlags(NODE_NETWORK_LIMITED);
    }
    return ServiceFlags(NODE_NETWORK);
}

void SetServiceFlagsIBDCache(bool state) {
    g_initial_block_download_completed = state;
}

std::string CInv::GetCommand() const {
    std::string cmd;
    switch (GetKind()) {
        case MSG_TX:
            return cmd.append(NetMsgType::TX);
        case MSG_BLOCK:
            return cmd.append(NetMsgType::BLOCK);
        case MSG_FILTERED_BLOCK:
            return cmd.append(NetMsgType::MERKLEBLOCK);
        case MSG_CMPCT_BLOCK:
            return cmd.append(NetMsgType::CMPCTBLOCK);
        case MSG_AVA_PROOF:
            return cmd.append(NetMsgType::AVAPROOF);
        default:
            throw std::out_of_range(
                strprintf("CInv::GetCommand(): type=%d unknown type", type));
    }
}

std::string CInv::ToString() const {
    try {
        return strprintf("%s %s", GetCommand(), hash.ToString());
    } catch (const std::out_of_range &) {
        return strprintf("0x%08x %s", type, hash.ToString());
    }
}

const std::vector<std::string> &getAllNetMessageTypes() {
    return allNetMessageTypesVec;
}

/**
 * Convert a service flag (NODE_*) to a human readable string.
 * It supports unknown service flags which will be returned as "UNKNOWN[...]".
 * @param[in] bit the service flag is calculated as (1 << bit)
 */
static std::string serviceFlagToStr(const size_t bit) {
    const uint64_t service_flag = 1ULL << bit;
    switch (ServiceFlags(service_flag)) {
        case NODE_NONE:
            // impossible
            abort();
        case NODE_NETWORK:
            return "NETWORK";
        case NODE_GETUTXO:
            return "GETUTXO";
        case NODE_BLOOM:
            return "BLOOM";
        case NODE_NETWORK_LIMITED:
            return "NETWORK_LIMITED";
        case NODE_COMPACT_FILTERS:
            return "COMPACT_FILTERS";
        case NODE_AVALANCHE:
            return "AVALANCHE";
        default:
            std::ostringstream stream;
            stream.imbue(std::locale::classic());
            stream << "UNKNOWN[";
            stream << "2^" << bit;
            stream << "]";
            return stream.str();
    }
}

std::vector<std::string> serviceFlagsToStr(const uint64_t flags) {
    std::vector<std::string> str_flags;

    for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
        if (flags & (1ULL << i)) {
            str_flags.emplace_back(serviceFlagToStr(i));
        }
    }

    return str_flags;
}
<|endoftext|>


<commit_before>#include <iostream>
#include "yaml-cpp/yaml.h"

int main()
{
  YAML::Node config = YAML::LoadFile("../config/config.yaml");
  std::cout << "Your slack token is: " << config["slack_token"].as<std::string>() << std::endl;

  return 0;
}
<commit_msg>smartassery<commit_after>#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include "yaml-cpp/yaml.h"

int main()
{
  YAML::Node config = YAML::LoadFile("../config/config.yaml");
  std::cout << "Your slack token is: " << config["slack_token"].as<std::string>() << std::endl;

  // smartassery
  printf("I'm a C function! \n");
  std::printf("I'm a C function wearing a C++ std namespace wrapper!\n");

  return 0;
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <hw/apic.hpp>
#include <hw/apic_regs.hpp>
#include <hw/ioapic.hpp>
#include <hw/acpi.hpp> // ACPI
#include <hw/apic_revenant.hpp>
#include <hw/cpu.hpp>
#include <hw/pic.hpp>
#include <kernel/irq_manager.hpp>
#include <cstdio>
#include <debug>
#include <info>

extern "C" {
  void apic_enable();
  int  get_cpu_id();
  extern char _binary_apic_boot_bin_start;
  extern char _binary_apic_boot_bin_end;
  void lapic_send_eoi();
  void lapic_exception_handler();
  void lapic_irq_entry();
  // current selected EOI method
  void (*current_eoi_mechanism)() = lapic_send_eoi;
  // KVM para PV-EOI feature
  void kvm_pv_eoi();
  void kvm_pv_eoi_init();
}
extern idt_loc smp_lapic_idt;

namespace hw {

  static const uintptr_t IA32_APIC_BASE_MSR = 0x1B;
  static const uintptr_t IA32_APIC_BASE_MSR_ENABLE = 0x800;
  static const uintptr_t BOOTLOADER_LOCATION = 0x80000;
  static const uint8_t   SPURIOUS_INTR = IRQ_manager::INTR_LINES-1;

  // every CPU has a local APIC
  apic lapic;

  struct apic_boot {
    // the jump instruction at the start
    uint32_t   jump;
    // stuff we will need to modify
    void*  worker_addr;
    void*  stack_base;
    size_t stack_size;
  };

  union addr_union {
    uint32_t whole;
    uint16_t part[2];

    addr_union(void(*addr)()) {
      whole = (uintptr_t) addr;
    }
  };

  void APIC::init()
  {
    const uint64_t APIC_BASE_MSR = CPU::read_msr(IA32_APIC_BASE_MSR);
    /// find the LAPICs base address ///
    const uintptr_t APIC_BASE_ADDR = APIC_BASE_MSR & 0xFFFFF000;
    // acquire infos
    lapic = apic(APIC_BASE_ADDR);
    INFO2("LAPIC id: %x  ver: %x\n", lapic.get_id(), lapic.regs->lapic_ver.reg);

    // disable the legacy 8259 PIC
    // by masking off all interrupts
    hw::PIC::set_intr_mask(0xFFFF);

    // enable Local APIC
    void _lapic_enable();
    _lapic_enable();

    // turn the Local APIC on
    INFO("APIC", "Enabling BSP LAPIC");
    CPU::write_msr(IA32_APIC_BASE_MSR,
        (APIC_BASE_MSR & 0xfffff100) | IA32_APIC_BASE_MSR_ENABLE, 0);
    INFO2("APIC_BASE MSR is now 0x%llx\n", CPU::read_msr(IA32_APIC_BASE_MSR));

    // initialize I/O APICs
    IOAPIC::init(ACPI::get_ioapics());

    /// initialize and start APs found in ACPI-tables ///
    if (ACPI::get_cpus().size() > 1) {
      INFO("APIC", "SMP Init");
      init_smp();
    }

    // use KVMs paravirt EOI if supported
    //kvm_pv_eoi_init();

    // subscribe to APIC-related interrupts
    setup_subs();
  }

  void _lapic_enable()
  {
    /// enable interrupts ///
    lapic.regs->task_pri.reg       = 0xff;
    lapic.regs->dest_format.reg    = 0xffffffff; // flat mode
    lapic.regs->logical_dest.reg   = 0x01000000; // logical ID 1

    // program local interrupts
    lapic.regs->lint0.reg = INTR_MASK | LAPIC_IRQ_LINT0;
    lapic.regs->lint1.reg = INTR_MASK | LAPIC_IRQ_LINT1;
    lapic.regs->error.reg = INTR_MASK | LAPIC_IRQ_ERROR;

    // start receiving interrupts (0x100), set spurious vector
    // note: spurious IRQ must have 4 last bits set (0x?F)
    lapic.enable_intr(SPURIOUS_INTR);

    // acknowledge any outstanding interrupts
    (*current_eoi_mechanism)();

    // enable APIC by resetting task priority
    lapic.regs->task_pri.reg = 0;
  }

  /// initialize and start registered APs found in ACPI-tables ///
  void APIC::init_smp()
  {
    // smp with only one CPU == :facepalm:
    assert(ACPI::get_cpus().size() > 1);

    // copy our bootloader to APIC init location
    const char* start = &_binary_apic_boot_bin_start;
    ptrdiff_t bootloader_size = &_binary_apic_boot_bin_end - start;
    debug("Copying bootloader from %p to 0x%x (size=%d)\n",
          start, BOOTLOADER_LOCATION, bootloader_size);
    memcpy((char*) BOOTLOADER_LOCATION, start, bootloader_size);

    // modify bootloader to support our cause
    auto* boot = (apic_boot*) BOOTLOADER_LOCATION;
    // populate IDT used with SMP LAPICs
    smp_lapic_idt.limit = 256 * sizeof(IDTDescr) - 1;
    smp_lapic_idt.base  = (uintptr_t) new IDTDescr[256];

    auto* idt = (IDTDescr*) smp_lapic_idt.base;
    for (size_t i = 0; i < 32; i++) {
      addr_union addr(lapic_exception_handler);
      idt[i].offset_1 = addr.part[0];
      idt[i].offset_2 = addr.part[1];
      idt[i].selector  = 0x8;
      idt[i].type_attr = 0x8e;
      idt[i].zero      = 0;
    }
    for (size_t i = 32; i < 48; i++) {
      addr_union addr(lapic_irq_entry);
      idt[i].offset_1 = addr.part[0];
      idt[i].offset_2 = addr.part[1];
      idt[i].selector  = 0x8;
      idt[i].type_attr = 0x8e;
      idt[i].zero      = 0;
    }

    // assign stack and main func
    size_t CPUcount = ACPI::get_cpus().size();

    boot->worker_addr = (void*) &revenant_main;
    boot->stack_base = aligned_alloc(CPUcount * REV_STACK_SIZE, 4096);
    boot->stack_size = REV_STACK_SIZE;
    debug("APIC stack base: %p  size: %u   main size: %u\n",
        boot->stack_base, boot->stack_size, sizeof(boot->worker_addr));

    // reset barrier
    smp.boot_barrier.reset(1);

    // turn on CPUs
    INFO("APIC", "Initializing APs");
    for (auto& cpu : ACPI::get_cpus())
    {
      debug("-> CPU %u ID %u  fl 0x%x\n",
        cpu.cpu, cpu.id, cpu.flags);
      // except the CPU we are using now
      if (cpu.id != lapic.get_id())
        lapic.ap_init(cpu.id);
    }
    // start CPUs
    INFO("APIC", "Starting APs");
    for (auto& cpu : ACPI::get_cpus())
    {
      // except the CPU we are using now
      if (cpu.id == lapic.get_id()) continue;
      // Send SIPI with start address 0x80000
      lapic.ap_start(cpu.id, 0x80);
      lapic.ap_start(cpu.id, 0x80);
    }

    // wait for all APs to start
    smp.boot_barrier.spin_wait(CPUcount);
    INFO("APIC", "All APs are online now\n");
  }

  uint8_t APIC::get_isr()
  {
    for (uint8_t i = 0; i < 8; i++)
      if (lapic.regs->isr[i].reg)
        return 32 * i + __builtin_ffs(lapic.regs->isr[i].reg) - 1;
    return 255;
  }
  uint8_t APIC::get_irr()
  {
    for (uint8_t i = 0; i < 8; i++)
      if (lapic.regs->irr[i].reg)
        return 32 * i + __builtin_ffs(lapic.regs->irr[i].reg) - 1;
    return 255;
  }

  void APIC::eoi()
  {
    debug("-> eoi @ %p for %u\n", &lapic.regs->eoi.reg, lapic.get_id());
    lapic.regs->eoi.reg = 0;
  }

  void APIC::send_ipi(uint8_t id, uint8_t vector)
  {
    debug("send_ipi  id %u  vector %u\n", id, vector);
    // select APIC ID
    uint32_t value = lapic.regs->intr_hi.reg & 0x00ffffff;
    lapic.regs->intr_hi.reg = value | (id << 24);
    // write vector and trigger/level/mode
    value = ICR_ASSERT | ICR_FIXED | vector;
    lapic.regs->intr_lo.reg = value;
  }
  void APIC::send_bsp_intr()
  {
    // for now we will just assume BSP is 0
    send_ipi(0, 32 + BSP_LAPIC_IPI_IRQ);
  }
  void APIC::bcast_ipi(uint8_t vector)
  {
    debug("bcast_ipi  vector %u\n", vector);
    //lapic.regs->intr_hi.reg = id << 24;
    lapic.regs->intr_lo.reg = ICR_ALL_EXCLUDING_SELF | ICR_ASSERT | vector;
  }

  void APIC::add_task(smp_task_func task, smp_done_func done)
  {
    lock(smp.tlock);
    smp.tasks.emplace_back(task, done);
    unlock(smp.tlock);
  }
  void APIC::work_signal()
  {
    // broadcast that we have work to do
    bcast_ipi(0x20);
  }

  void APIC::enable_irq(uint8_t irq)
  {
    auto& overrides = ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        INFO2("Enabled redirected IRQ %u -> %u on lapic %u",
            redir.irq_source, redir.global_intr, lapic.get_id());
        IOAPIC::enable(redir.global_intr, irq, lapic.get_id());
        return;
      }
    }
    INFO2("Enabled non-redirected IRQ %u on LAPIC %u", irq, lapic.get_id());
    IOAPIC::enable(irq, irq, lapic.get_id());
  }
  void APIC::disable_irq(uint8_t irq)
  {
    auto& overrides = ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        IOAPIC::disable(redir.global_intr);
        return;
      }
    }
    IOAPIC::disable(irq);
  }
  void APIC::setup_subs()
  {
    // IRQ handler for completed async jobs
    IRQ_manager::get().subscribe(BSP_LAPIC_IPI_IRQ,
    [] {
      // copy all the done functions out from queue to our local vector
      std::vector<smp_done_func> done;
      lock(smp.flock);
      for (auto& func : smp.completed)
        done.push_back(func);
      unlock(smp.flock);

      // call all the done functions
      for (auto& func : done) {
        func();
      }
    });
  }
}

// *** manual ***
// http://choon.net/forum/read.php?21,1123399
// https://www.kernel.org/doc/Documentation/virtual/kvm/cpuid.txt

#define KVM_FEATURE_PV_EOI     6
#define KVM_MSR_ENABLED        1
#define MSR_KVM_PV_EOI_EN      0x4b564d04
#define KVM_PV_EOI_BIT         0
#define KVM_PV_EOI_MASK       (0x1 << KVM_PV_EOI_BIT)
#define KVM_PV_EOI_ENABLED     KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED    0x0

#define _ADDR_ (*(volatile long *) addr)
int __test_and_clear_bit(long nr, volatile unsigned long* addr)
{
  int oldbit;

	asm volatile( "lock "
		"btrl %2,%1\n\tsbbl %0,%0"
		:"=r" (oldbit),"=m" (_ADDR_)
		:"dIr" (nr) : "memory");
	return oldbit;
}

static volatile unsigned long kvm_apic_eoi = KVM_PV_EOI_DISABLED;
void kvm_pv_eoi() {

  //printf("BEFOR: %#lx  intr %u  irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
  // fast EOI by KVM
  if (__test_and_clear_bit(KVM_PV_EOI_BIT, &kvm_apic_eoi)) {
      printf("avoided\n");
      return;
  }
  // fallback to normal APIC EOI
  hw::lapic.regs->eoi.reg = 0;
  // check after
  //printf("AFTER: %#lx  intr %u  irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
}
void kvm_pv_eoi_init() {
  kvm_apic_eoi = 0;
  auto pv_eoi = (uintptr_t) &kvm_apic_eoi;
  printf("MSR %#x  pv_eoi = %#x\n", MSR_KVM_PV_EOI_EN, pv_eoi);
  hw::CPU::write_msr(MSR_KVM_PV_EOI_EN, pv_eoi | KVM_MSR_ENABLED, 0);
  // set new EOI handler
  current_eoi_mechanism = kvm_pv_eoi;
  kvm_apic_eoi = KVM_PV_EOI_ENABLED;
}
<commit_msg>pv_eoi: Verify that feature was enabled<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <hw/apic.hpp>
#include <hw/apic_regs.hpp>
#include <hw/ioapic.hpp>
#include <hw/acpi.hpp> // ACPI
#include <hw/apic_revenant.hpp>
#include <hw/cpu.hpp>
#include <hw/pic.hpp>
#include <kernel/cpuid.hpp>
#include <kernel/irq_manager.hpp>
#include <cstdio>
#include <debug>
#include <info>

extern "C" {
  void apic_enable();
  int  get_cpu_id();
  extern char _binary_apic_boot_bin_start;
  extern char _binary_apic_boot_bin_end;
  void lapic_send_eoi();
  void lapic_exception_handler();
  void lapic_irq_entry();
  // current selected EOI method
  void (*current_eoi_mechanism)() = lapic_send_eoi;
  // KVM para PV-EOI feature
  void kvm_pv_eoi();
  void kvm_pv_eoi_init();
}
extern idt_loc smp_lapic_idt;

namespace hw {

  static const uintptr_t IA32_APIC_BASE_MSR = 0x1B;
  static const uintptr_t IA32_APIC_BASE_MSR_ENABLE = 0x800;
  static const uintptr_t BOOTLOADER_LOCATION = 0x80000;
  static const uint8_t   SPURIOUS_INTR = IRQ_manager::INTR_LINES-1;

  // every CPU has a local APIC
  apic lapic;

  struct apic_boot {
    // the jump instruction at the start
    uint32_t   jump;
    // stuff we will need to modify
    void*  worker_addr;
    void*  stack_base;
    size_t stack_size;
  };

  union addr_union {
    uint32_t whole;
    uint16_t part[2];

    addr_union(void(*addr)()) {
      whole = (uintptr_t) addr;
    }
  };

  void APIC::init()
  {
    const uint64_t APIC_BASE_MSR = CPU::read_msr(IA32_APIC_BASE_MSR);
    /// find the LAPICs base address ///
    const uintptr_t APIC_BASE_ADDR = APIC_BASE_MSR & 0xFFFFF000;
    // acquire infos
    lapic = apic(APIC_BASE_ADDR);
    INFO2("LAPIC id: %x  ver: %x\n", lapic.get_id(), lapic.regs->lapic_ver.reg);

    // disable the legacy 8259 PIC
    // by masking off all interrupts
    hw::PIC::set_intr_mask(0xFFFF);

    // enable Local APIC
    void _lapic_enable();
    _lapic_enable();

    // turn the Local APIC on
    INFO("APIC", "Enabling BSP LAPIC");
    CPU::write_msr(IA32_APIC_BASE_MSR,
        (APIC_BASE_MSR & 0xfffff100) | IA32_APIC_BASE_MSR_ENABLE, 0);
    INFO2("APIC_BASE MSR is now 0x%llx\n", CPU::read_msr(IA32_APIC_BASE_MSR));

    // initialize I/O APICs
    IOAPIC::init(ACPI::get_ioapics());

    /// initialize and start APs found in ACPI-tables ///
    if (ACPI::get_cpus().size() > 1) {
      INFO("APIC", "SMP Init");
      init_smp();
    }

    // use KVMs paravirt EOI if supported
    if (CPUID::kvm_feature(KVM_FEATURE_PV_EOI))
        kvm_pv_eoi_init();

    // subscribe to APIC-related interrupts
    setup_subs();
  }

  void _lapic_enable()
  {
    /// enable interrupts ///
    lapic.regs->task_pri.reg       = 0xff;
    lapic.regs->dest_format.reg    = 0xffffffff; // flat mode
    lapic.regs->logical_dest.reg   = 0x01000000; // logical ID 1

    // program local interrupts
    lapic.regs->lint0.reg = INTR_MASK | LAPIC_IRQ_LINT0;
    lapic.regs->lint1.reg = INTR_MASK | LAPIC_IRQ_LINT1;
    lapic.regs->error.reg = INTR_MASK | LAPIC_IRQ_ERROR;

    // start receiving interrupts (0x100), set spurious vector
    // note: spurious IRQ must have 4 last bits set (0x?F)
    lapic.enable_intr(SPURIOUS_INTR);

    // acknowledge any outstanding interrupts
    (*current_eoi_mechanism)();

    // enable APIC by resetting task priority
    lapic.regs->task_pri.reg = 0;
  }

  /// initialize and start registered APs found in ACPI-tables ///
  void APIC::init_smp()
  {
    // smp with only one CPU == :facepalm:
    assert(ACPI::get_cpus().size() > 1);

    // copy our bootloader to APIC init location
    const char* start = &_binary_apic_boot_bin_start;
    ptrdiff_t bootloader_size = &_binary_apic_boot_bin_end - start;
    debug("Copying bootloader from %p to 0x%x (size=%d)\n",
          start, BOOTLOADER_LOCATION, bootloader_size);
    memcpy((char*) BOOTLOADER_LOCATION, start, bootloader_size);

    // modify bootloader to support our cause
    auto* boot = (apic_boot*) BOOTLOADER_LOCATION;
    // populate IDT used with SMP LAPICs
    smp_lapic_idt.limit = 256 * sizeof(IDTDescr) - 1;
    smp_lapic_idt.base  = (uintptr_t) new IDTDescr[256];

    auto* idt = (IDTDescr*) smp_lapic_idt.base;
    for (size_t i = 0; i < 32; i++) {
      addr_union addr(lapic_exception_handler);
      idt[i].offset_1 = addr.part[0];
      idt[i].offset_2 = addr.part[1];
      idt[i].selector  = 0x8;
      idt[i].type_attr = 0x8e;
      idt[i].zero      = 0;
    }
    for (size_t i = 32; i < 48; i++) {
      addr_union addr(lapic_irq_entry);
      idt[i].offset_1 = addr.part[0];
      idt[i].offset_2 = addr.part[1];
      idt[i].selector  = 0x8;
      idt[i].type_attr = 0x8e;
      idt[i].zero      = 0;
    }

    // assign stack and main func
    size_t CPUcount = ACPI::get_cpus().size();

    boot->worker_addr = (void*) &revenant_main;
    boot->stack_base = aligned_alloc(CPUcount * REV_STACK_SIZE, 4096);
    boot->stack_size = REV_STACK_SIZE;
    debug("APIC stack base: %p  size: %u   main size: %u\n",
        boot->stack_base, boot->stack_size, sizeof(boot->worker_addr));

    // reset barrier
    smp.boot_barrier.reset(1);

    // turn on CPUs
    INFO("APIC", "Initializing APs");
    for (auto& cpu : ACPI::get_cpus())
    {
      debug("-> CPU %u ID %u  fl 0x%x\n",
        cpu.cpu, cpu.id, cpu.flags);
      // except the CPU we are using now
      if (cpu.id != lapic.get_id())
        lapic.ap_init(cpu.id);
    }
    // start CPUs
    INFO("APIC", "Starting APs");
    for (auto& cpu : ACPI::get_cpus())
    {
      // except the CPU we are using now
      if (cpu.id == lapic.get_id()) continue;
      // Send SIPI with start address 0x80000
      lapic.ap_start(cpu.id, 0x80);
      lapic.ap_start(cpu.id, 0x80);
    }

    // wait for all APs to start
    smp.boot_barrier.spin_wait(CPUcount);
    INFO("APIC", "All APs are online now\n");
  }

  uint8_t APIC::get_isr()
  {
    for (int i = 8; i >= 0; i--)
      if (lapic.regs->isr[i].reg)
        return 32 * i + __builtin_ffs(lapic.regs->isr[i].reg) - 1;
    return 255;
  }
  uint8_t APIC::get_irr()
  {
    for (int i = 8; i >= 0; i--)
      if (lapic.regs->irr[i].reg)
        return 32 * i + __builtin_ffs(lapic.regs->irr[i].reg) - 1;
    return 255;
  }

  void APIC::eoi()
  {
    debug("-> eoi @ %p for %u\n", &lapic.regs->eoi.reg, lapic.get_id());
    lapic.regs->eoi.reg = 0;
  }

  void APIC::send_ipi(uint8_t id, uint8_t vector)
  {
    debug("send_ipi  id %u  vector %u\n", id, vector);
    // select APIC ID
    uint32_t value = lapic.regs->intr_hi.reg & 0x00ffffff;
    lapic.regs->intr_hi.reg = value | (id << 24);
    // write vector and trigger/level/mode
    value = ICR_ASSERT | ICR_FIXED | vector;
    lapic.regs->intr_lo.reg = value;
  }
  void APIC::send_bsp_intr()
  {
    // for now we will just assume BSP is 0
    send_ipi(0, 32 + BSP_LAPIC_IPI_IRQ);
  }
  void APIC::bcast_ipi(uint8_t vector)
  {
    debug("bcast_ipi  vector %u\n", vector);
    //lapic.regs->intr_hi.reg = id << 24;
    lapic.regs->intr_lo.reg = ICR_ALL_EXCLUDING_SELF | ICR_ASSERT | vector;
  }

  void APIC::add_task(smp_task_func task, smp_done_func done)
  {
    lock(smp.tlock);
    smp.tasks.emplace_back(task, done);
    unlock(smp.tlock);
  }
  void APIC::work_signal()
  {
    // broadcast that we have work to do
    bcast_ipi(0x20);
  }

  void APIC::enable_irq(uint8_t irq)
  {
    auto& overrides = ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        INFO2("Enabled redirected IRQ %u -> %u on lapic %u",
            redir.irq_source, redir.global_intr, lapic.get_id());
        IOAPIC::enable(redir.global_intr, irq, lapic.get_id());
        return;
      }
    }
    INFO2("Enabled non-redirected IRQ %u on LAPIC %u", irq, lapic.get_id());
    IOAPIC::enable(irq, irq, lapic.get_id());
  }
  void APIC::disable_irq(uint8_t irq)
  {
    auto& overrides = ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        IOAPIC::disable(redir.global_intr);
        return;
      }
    }
    IOAPIC::disable(irq);
  }
  void APIC::setup_subs()
  {
    // IRQ handler for completed async jobs
    IRQ_manager::get().subscribe(BSP_LAPIC_IPI_IRQ,
    [] {
      // copy all the done functions out from queue to our local vector
      std::vector<smp_done_func> done;
      lock(smp.flock);
      for (auto& func : smp.completed)
        done.push_back(func);
      unlock(smp.flock);

      // call all the done functions
      for (auto& func : done) {
        func();
      }
    });
  }
}

// *** manual ***
// http://choon.net/forum/read.php?21,1123399
// https://www.kernel.org/doc/Documentation/virtual/kvm/cpuid.txt

#define KVM_MSR_ENABLED        1
#define MSR_KVM_PV_EOI_EN      0x4b564d04
#define KVM_PV_EOI_BIT         0
#define KVM_PV_EOI_MASK       (0x1 << KVM_PV_EOI_BIT)
#define KVM_PV_EOI_ENABLED     KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED    0x0

#define _ADDR_ (*(volatile long *) addr)
int __test_and_clear_bit(long nr, volatile unsigned long* addr)
{
  int oldbit;

	asm volatile( "lock "
		"btrl %2,%1\n\tsbbl %0,%0"
		:"=r" (oldbit),"=m" (_ADDR_)
		:"dIr" (nr) : "memory");
	return oldbit;
}

static volatile unsigned long kvm_apic_eoi = KVM_PV_EOI_DISABLED;
void kvm_pv_eoi() {

  printf("BEFOR: %#lx  intr %u  irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
  // fast EOI by KVM
  if (__test_and_clear_bit(KVM_PV_EOI_BIT, &kvm_apic_eoi)) {
      printf("avoided\n");
      return;
  }
  // fallback to normal APIC EOI
  hw::lapic.regs->eoi.reg = 0;
  // check after
  printf("AFTER: %#lx  intr %u  irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
}
void kvm_pv_eoi_init() {
  printf("* Enabling KVM paravirtual EOI\n");
  // set new EOI handler
  current_eoi_mechanism = kvm_pv_eoi;
  // setup PV EOI using local variable
  kvm_apic_eoi = 0;
  auto pv_eoi = (uintptr_t) &kvm_apic_eoi;
  printf("  MSR %#x  pv_eoi = %#x\n", MSR_KVM_PV_EOI_EN, pv_eoi);
  hw::CPU::write_msr(MSR_KVM_PV_EOI_EN, pv_eoi | KVM_MSR_ENABLED, 0);
  // verify that the feature was enabled
  auto res = hw::CPU::read_msr(MSR_KVM_PV_EOI_EN);
  assert(res == (pv_eoi | KVM_MSR_ENABLED));
}
<|endoftext|>