<commit_before>//============================================================================//
// File:          qcan_frame.cpp                                              //
// Description:   QCAN classes - CAN frame                                    //
//                                                                            //
// Copyright (C) MicroControl GmbH & Co. KG                                   //
// 53844 Troisdorf - Germany                                                  //
// www.microcontrol.net                                                       //
//                                                                            //
//----------------------------------------------------------------------------//
// Redistribution and use in source and binary forms, with or without         //
// modification, are permitted provided that the following conditions         //
// are met:                                                                   //
// 1. Redistributions of source code must retain the above copyright          //
//    notice, this list of conditions, the following disclaimer and           //
//    the referenced file 'LICENSE'.                                          //
// 2. Redistributions in binary form must reproduce the above copyright       //
//    notice, this list of conditions and the following disclaimer in the     //
//    documentation and/or other materials provided with the distribution.    //
// 3. Neither the name of MicroControl nor the names of its contributors      //
//    may be used to endorse or promote products derived from this software   //
//    without specific prior written permission.                              //
//                                                                            //
// Provided that this notice is retained in full, this software may be        //
// distributed under the terms of the GNU Lesser General Public License       //
// ("LGPL") version 3 as distributed in the 'LICENSE' file.                   //
//                                                                            //
//============================================================================//

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

#include <QCanFrame>

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

#define  QCAN_FRAME_ID_MASK_STD     ((uint32_t) 0x000007FF)

#define  QCAN_FRAME_ID_MASK_EXT     ((uint32_t) 0x1FFFFFFF)

#define  QCAN_FRAME_FORMAT_EXT      ((uint8_t) 0x01)

#define  QCAN_FRAME_FORMAT_FD       ((uint8_t) 0x02)

#define  QCAN_FRAME_FORMAT_RTR      ((uint8_t) 0x04)

/*----------------------------------------------------------------------------*\
** Class methods                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

//----------------------------------------------------------------------------//
// QCanFrame()                                                                //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanFrame::QCanFrame() : CpFrame()
{

}

//----------------------------------------------------------------------------//
// QCanFrame()                                                                //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanFrame::QCanFrame(const Type_e & ubTypeR, const uint32_t & ulIdentifierR,
                     const uint8_t & ubDlcR)
         : CpFrame(ubTypeR, ulIdentifierR, ubDlcR)
{
}

//----------------------------------------------------------------------------//
// ~QCanFrame()                                                               //
// destructor                                                                 //
//----------------------------------------------------------------------------//
QCanFrame::~QCanFrame()
{

}

//----------------------------------------------------------------------------//
// data()                                                                     //
// get data                                                                   //
//----------------------------------------------------------------------------//
QByteArray  QCanFrame::data(void) const
{
   QByteArray clDataT((const char *)&aubByteP[0], this->dataSize());
   return(clDataT);
}

uint8_t QCanFrame::data(const uint8_t & ubPosR) const
{
   return(CpFrame::data(ubPosR));
}

//----------------------------------------------------------------------------//
// fromByteArray()                                                            //
// test for Extended Frame format                                             //
//----------------------------------------------------------------------------//
bool QCanFrame::fromByteArray(const QByteArray & clByteArrayR)
{
   //----------------------------------------------------------------
   // test size of byte array
   //
   if(clByteArrayR.size() < QCAN_FRAME_ARRAY_SIZE)
   {
      return(false);
   }

   //----------------------------------------------------------------
   // build checksum from byte 0 .. 93, and compare with checksum
   // value at the end
   //
   uint16_t uwChecksumT = clByteArrayR[94];
   uwChecksumT = uwChecksumT << 8;
   uwChecksumT = uwChecksumT + (uint8_t) clByteArrayR[95];

   if(uwChecksumT != qChecksum(clByteArrayR.constData(),
                               QCAN_FRAME_ARRAY_SIZE - 2))
   {
      return(false);
   }

   //----------------------------------------------------------------
   // structure seems to be valid, now start copying the contents,
   // start with the identifier value
   //----------------------------------------------------------------

   //----------------------------------------------------------------
   // set identifier field from byte 0 .. 3, MSB first
   //
   ulIdentifierP = clByteArrayR[0];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[1];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[2];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[3];

   //----------------------------------------------------------------
   // set DLC field from byte 4
   //
   ubMsgDlcP = clByteArrayR[4];

   //----------------------------------------------------------------
   // set message control field from byte 5
   //
   ubMsgCtrlP = clByteArrayR[5];

   //----------------------------------------------------------------
   // set message data field from byte 6 .. 69
   //
   for(uint8_t ubPosT = 0; ubPosT < CAN_FRAME_DATA_MAX; ubPosT++)
   {
      aubByteP[ubPosT] = clByteArrayR[6 + ubPosT];
   }

   //----------------------------------------------------------------
   // set message timestamp field from byte 70 .. 77, MSB first
   //
   /*
   tsMsgTimeP.ulSeconds  = clByteArrayR[70];
   tsMsgTimeP.ulSeconds  = tsMsgTimeP.ulSeconds << 8;
   tsMsgTimeP.ulSeconds += (uint8_t) clByteArrayR[71];
   tsMsgTimeP.ulSeconds  = tsMsgTimeP.ulSeconds << 8;
   tsMsgTimeP.ulSeconds += (uint8_t) clByteArrayR[72];
   tsMsgTimeP.ulSeconds  = tsMsgTimeP.ulSeconds << 8;
   tsMsgTimeP.ulSeconds += (uint8_t) clByteArrayR[73];

   tsMsgTimeP.ulNanoSeconds  = clByteArrayR[74];
   tsMsgTimeP.ulNanoSeconds  = tsMsgTimeP.ulNanoSeconds << 8;
   tsMsgTimeP.ulNanoSeconds += (uint8_t) clByteArrayR[75];
   tsMsgTimeP.ulNanoSeconds  = tsMsgTimeP.ulNanoSeconds << 8;
   tsMsgTimeP.ulNanoSeconds += (uint8_t) clByteArrayR[76];
   tsMsgTimeP.ulNanoSeconds  = tsMsgTimeP.ulNanoSeconds << 8;
   tsMsgTimeP.ulNanoSeconds += (uint8_t) clByteArrayR[77];
   */

   //----------------------------------------------------------------
   // set message user field from byte 78 .. 81, MSB first
   //
   ulMsgUserP  = clByteArrayR[78];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[79];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[80];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[81];

   //----------------------------------------------------------------
   // set message marker field from byte 82 .. 85, MSB first
   //
   ulMsgMarkerP  = clByteArrayR[82];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[83];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[84];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[85];

   return(true);
}

void QCanFrame::setData(const uint8_t & ubPosR, const uint8_t & ubValueR)
{
   CpFrame::setData(ubPosR, ubValueR);
}

//----------------------------------------------------------------------------//
// toByteArray()                                                              //
// test for Extended Frame format                                             //
//----------------------------------------------------------------------------//
QByteArray QCanFrame::toByteArray() const
{
   //----------------------------------------------------------------
   // setup a defined length and clear contents
   //
   QByteArray clByteArrayT(QCAN_FRAME_ARRAY_SIZE, 0x00);

   //----------------------------------------------------------------
   // place identifier field in byte 0 .. 3, MSB first
   //
   clByteArrayT[0] = (uint8_t) (ulIdentifierP >> 24);
   clByteArrayT[1] = (uint8_t) (ulIdentifierP >> 16);
   clByteArrayT[2] = (uint8_t) (ulIdentifierP >>  8);
   clByteArrayT[3] = (uint8_t) (ulIdentifierP >>  0);

   //----------------------------------------------------------------
   // place message DLC field in byte 4
   //
   clByteArrayT[4] = ubMsgDlcP;

   //----------------------------------------------------------------
   // place message control field in byte 5
   //
   clByteArrayT[5] = ubMsgCtrlP;

   //----------------------------------------------------------------
   // place message data field in byte 6 .. 69
   //
   for(uint8_t ubPosT = 0; ubPosT < CAN_FRAME_DATA_MAX; ubPosT++)
   {
      clByteArrayT[6 + ubPosT] = aubByteP[ubPosT];
   }

   //----------------------------------------------------------------
   // place message timestamp field in byte 70 .. 77, MSB first
   //
   /*
   clByteArrayT[70] = (uint8_t) (tsMsgTimeP.ulSeconds >> 24);
   clByteArrayT[71] = (uint8_t) (tsMsgTimeP.ulSeconds >> 16);
   clByteArrayT[72] = (uint8_t) (tsMsgTimeP.ulSeconds >>  8);
   clByteArrayT[73] = (uint8_t) (tsMsgTimeP.ulSeconds >>  0);
   clByteArrayT[74] = (uint8_t) (tsMsgTimeP.ulNanoSeconds >>  24);
   clByteArrayT[75] = (uint8_t) (tsMsgTimeP.ulNanoSeconds >>  16);
   clByteArrayT[76] = (uint8_t) (tsMsgTimeP.ulNanoSeconds >>   8);
   clByteArrayT[77] = (uint8_t) (tsMsgTimeP.ulNanoSeconds >>   0);
   */

   //----------------------------------------------------------------
   // place message user field in byte 78 .. 81, MSB first
   //
   clByteArrayT[78] = (uint8_t) (ulMsgUserP >>  24);
   clByteArrayT[79] = (uint8_t) (ulMsgUserP >>  16);
   clByteArrayT[80] = (uint8_t) (ulMsgUserP >>   8);
   clByteArrayT[81] = (uint8_t) (ulMsgUserP >>   0);

   //----------------------------------------------------------------
   // place message marker field in byte 82 .. 85, MSB first
   //
   clByteArrayT[82] = (uint8_t) (ulMsgMarkerP >>  24);
   clByteArrayT[83] = (uint8_t) (ulMsgMarkerP >>  16);
   clByteArrayT[84] = (uint8_t) (ulMsgMarkerP >>   8);
   clByteArrayT[85] = (uint8_t) (ulMsgMarkerP >>   0);

   //----------------------------------------------------------------
   // byte 86 .. 93 (i.e. 8 bytes) are not used, set to 0
   //----------------------------------------------------------------

   //----------------------------------------------------------------
   // build checksum from byte 0 .. 93, add checksum at the end
   //
   uint16_t uwChecksumT = qChecksum(clByteArrayT.constData(),
                                    QCAN_FRAME_ARRAY_SIZE - 2);

   clByteArrayT[94] = (uint8_t) (uwChecksumT >> 8);
   clByteArrayT[95] = (uint8_t) (uwChecksumT >> 0);

   return(clByteArrayT);
}

//----------------------------------------------------------------------------//
// toString()                                                                 //
// print CAN frame                                                            //
//----------------------------------------------------------------------------//
QString QCanFrame::toString(const bool & btShowTimeR)
{
   //----------------------------------------------------------------
   // setup a string object
   //
   QString clStringT; //(QCAN_FRAME_STRING_SIZE, '\0');

   if(btShowTimeR == true)
   {

   }

   //----------------------------------------------------------------
   // print identifier
   //
   clStringT += QString("%1  ").arg(ulIdentifierP, 8, 16).toUpper();

   //----------------------------------------------------------------
   // print frame format
   //
   switch(frameType())
   {
      case eTYPE_CAN_STD:
         clStringT += "CAN-STD ";
         break;

      case eTYPE_CAN_EXT:
         clStringT += "CAN-EXT ";
         break;

      case eTYPE_FD_STD:
         clStringT += " FD-STD ";
         break;

      case eTYPE_FD_EXT:
         clStringT += " FD-EXT ";
         break;

      case eTYPE_QCAN_ERR:
         clStringT += "QCan-ERR";
         break;

      case eTYPE_QCAN_API:
         clStringT += "QCan-API";
         break;

      default:
         clStringT += " N/A    ";
         break;
   }

   //----------------------------------------------------------------
   // print DLC
   //
   clStringT += QString("%1  ").arg(dlc(), 2, 10);

   //----------------------------------------------------------------
   // print data
   //
   for(uint8_t ubCntT = 0; ubCntT < dataSize(); ubCntT++)
   {
      //---------------------------------------------------
      // print a newline and 22 spaces after 16 data bytes
      //
      if((ubCntT > 0) && ((ubCntT % 16) == 0))
      {
         clStringT +="\n                      ";
      }
      clStringT += QString("%1 ").arg( aubByteP[ubCntT],
                                       2,          // 2 digits
                                      16,          // hex value
                                      QLatin1Char('0')).toUpper();
   }

   return(clStringT);
}

//----------------------------------------------------------------------------//
// operator <<                                                                //
// stream to a QDataStream object                                             //
//----------------------------------------------------------------------------//
QDataStream & operator<< ( QDataStream & clStreamR,
                           const QCanFrame & clCanFrameR)
{
   //----------------------------------------------------------------
   // set version of stream
   //
   clStreamR.setVersion(QDataStream::Qt_5_6);

   //----------------------------------------------------------------
   // place all members to the stream
   //
   clStreamR << clCanFrameR.ulIdentifierP;

   for(uint8_t ubIndexT = 0; ubIndexT < CAN_FRAME_DATA_MAX; ubIndexT++)
   {
      clStreamR << clCanFrameR.aubByteP[ubIndexT];
   }

   clStreamR << clCanFrameR.ubMsgDlcP;
   clStreamR << clCanFrameR.ubMsgCtrlP;

   clStreamR << clCanFrameR.clMsgTimeP.seconds();
   clStreamR << clCanFrameR.clMsgTimeP.nanoSeconds();

   clStreamR << clCanFrameR.ulMsgUserP;

   return(clStreamR);
}

<commit_msg>Remove QCAN_FRAME_ values (defined already in CpFrame class) and add time-satmp in byte array<commit_after>//============================================================================//
// File:          qcan_frame.cpp                                              //
// Description:   QCAN classes - CAN frame                                    //
//                                                                            //
// Copyright (C) MicroControl GmbH & Co. KG                                   //
// 53844 Troisdorf - Germany                                                  //
// www.microcontrol.net                                                       //
//                                                                            //
//----------------------------------------------------------------------------//
// Redistribution and use in source and binary forms, with or without         //
// modification, are permitted provided that the following conditions         //
// are met:                                                                   //
// 1. Redistributions of source code must retain the above copyright          //
//    notice, this list of conditions, the following disclaimer and           //
//    the referenced file 'LICENSE'.                                          //
// 2. Redistributions in binary form must reproduce the above copyright       //
//    notice, this list of conditions and the following disclaimer in the     //
//    documentation and/or other materials provided with the distribution.    //
// 3. Neither the name of MicroControl nor the names of its contributors      //
//    may be used to endorse or promote products derived from this software   //
//    without specific prior written permission.                              //
//                                                                            //
// Provided that this notice is retained in full, this software may be        //
// distributed under the terms of the GNU Lesser General Public License       //
// ("LGPL") version 3 as distributed in the 'LICENSE' file.                   //
//                                                                            //
//============================================================================//

/*----------------------------------------------------------------------------*\
** Include files                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

#include <QCanFrame>

/*----------------------------------------------------------------------------*\
** Definitions                                                                **
**                                                                            **
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
** Class methods                                                              **
**                                                                            **
\*----------------------------------------------------------------------------*/

//----------------------------------------------------------------------------//
// QCanFrame()                                                                //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanFrame::QCanFrame() : CpFrame()
{

}

//----------------------------------------------------------------------------//
// QCanFrame()                                                                //
// constructor                                                                //
//----------------------------------------------------------------------------//
QCanFrame::QCanFrame(const Type_e & ubTypeR, const uint32_t & ulIdentifierR,
                     const uint8_t & ubDlcR)
         : CpFrame(ubTypeR, ulIdentifierR, ubDlcR)
{
}

//----------------------------------------------------------------------------//
// ~QCanFrame()                                                               //
// destructor                                                                 //
//----------------------------------------------------------------------------//
QCanFrame::~QCanFrame()
{

}

//----------------------------------------------------------------------------//
// data()                                                                     //
// get data                                                                   //
//----------------------------------------------------------------------------//
QByteArray  QCanFrame::data(void) const
{
   QByteArray clDataT((const char *)&aubByteP[0], this->dataSize());
   return(clDataT);
}

uint8_t QCanFrame::data(const uint8_t & ubPosR) const
{
   return(CpFrame::data(ubPosR));
}
//----------------------------------------------------------------------------//
// fromByteArray()                                                            //
// test for Extended Frame format                                             //
//----------------------------------------------------------------------------//
bool QCanFrame::fromByteArray(const QByteArray & clByteArrayR)
{
   //----------------------------------------------------------------
   // test size of byte array
   //
   if(clByteArrayR.size() < QCAN_FRAME_ARRAY_SIZE)
   {
      return(false);
   }

   //----------------------------------------------------------------
   // build checksum from byte 0 .. 93, and compare with checksum
   // value at the end
   //
   uint16_t uwChecksumT = clByteArrayR[94];
   uwChecksumT = uwChecksumT << 8;
   uwChecksumT = uwChecksumT + (uint8_t) clByteArrayR[95];

   if(uwChecksumT != qChecksum(clByteArrayR.constData(),
                               QCAN_FRAME_ARRAY_SIZE - 2))
   {
      return(false);
   }

   //----------------------------------------------------------------
   // structure seems to be valid, now start copying the contents,
   // start with the identifier value
   //----------------------------------------------------------------

   //----------------------------------------------------------------
   // set identifier field from byte 0 .. 3, MSB first
   //
   ulIdentifierP = clByteArrayR[0];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[1];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[2];
   ulIdentifierP = ulIdentifierP << 8;
   ulIdentifierP = ulIdentifierP + (uint8_t) clByteArrayR[3];

   //----------------------------------------------------------------
   // set DLC field from byte 4
   //
   ubMsgDlcP = clByteArrayR[4];

   //----------------------------------------------------------------
   // set message control field from byte 5
   //
   ubMsgCtrlP = clByteArrayR[5];

   //----------------------------------------------------------------
   // set message data field from byte 6 .. 69
   //
   for(uint8_t ubPosT = 0; ubPosT < CAN_FRAME_DATA_MAX; ubPosT++)
   {
      aubByteP[ubPosT] = clByteArrayR[6 + ubPosT];
   }

   //----------------------------------------------------------------
   // set message timestamp field from byte 70 .. 77, MSB first
   //
   uint32_t  ulTimeValT = 0;

   ulTimeValT  = clByteArrayR[70];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[71];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[72];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[73];
   clMsgTimeP.setSeconds(ulTimeValT);

   ulTimeValT  = 0;
   ulTimeValT  = clByteArrayR[74];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[75];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[76];
   ulTimeValT  = ulTimeValT << 8;
   ulTimeValT += (uint8_t) clByteArrayR[77];
   clMsgTimeP.setNanoSeconds(ulTimeValT);

   //----------------------------------------------------------------
   // set message user field from byte 78 .. 81, MSB first
   //
   ulMsgUserP  = clByteArrayR[78];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[79];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[80];
   ulMsgUserP  = ulMsgUserP << 8;
   ulMsgUserP += (uint8_t) clByteArrayR[81];

   //----------------------------------------------------------------
   // set message marker field from byte 82 .. 85, MSB first
   //
   ulMsgMarkerP  = clByteArrayR[82];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[83];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[84];
   ulMsgMarkerP  = ulMsgMarkerP << 8;
   ulMsgMarkerP += (uint8_t) clByteArrayR[85];

   return(true);
}

void QCanFrame::setData(const uint8_t & ubPosR, const uint8_t & ubValueR)
{
   CpFrame::setData(ubPosR, ubValueR);
}

//----------------------------------------------------------------------------//
// toByteArray()                                                              //
// test for Extended Frame format                                             //
//----------------------------------------------------------------------------//
QByteArray QCanFrame::toByteArray() const
{
   //----------------------------------------------------------------
   // setup a defined length and clear contents
   //
   QByteArray clByteArrayT(QCAN_FRAME_ARRAY_SIZE, 0x00);

   //----------------------------------------------------------------
   // place identifier field in byte 0 .. 3, MSB first
   //
   clByteArrayT[0] = (uint8_t) (ulIdentifierP >> 24);
   clByteArrayT[1] = (uint8_t) (ulIdentifierP >> 16);
   clByteArrayT[2] = (uint8_t) (ulIdentifierP >>  8);
   clByteArrayT[3] = (uint8_t) (ulIdentifierP >>  0);

   //----------------------------------------------------------------
   // place message DLC field in byte 4
   //
   clByteArrayT[4] = ubMsgDlcP;

   //----------------------------------------------------------------
   // place message control field in byte 5
   //
   clByteArrayT[5] = ubMsgCtrlP;

   //----------------------------------------------------------------
   // place message data field in byte 6 .. 69
   //
   for(uint8_t ubPosT = 0; ubPosT < CAN_FRAME_DATA_MAX; ubPosT++)
   {
      clByteArrayT[6 + ubPosT] = aubByteP[ubPosT];
   }

   //----------------------------------------------------------------
   // place message timestamp field in byte 70 .. 77, MSB first
   //
   uint32_t  ulTimeValT = 0;

   ulTimeValT = clMsgTimeP.seconds();
   clByteArrayT[70] = (uint8_t) (ulTimeValT >> 24);
   clByteArrayT[71] = (uint8_t) (ulTimeValT >> 16);
   clByteArrayT[72] = (uint8_t) (ulTimeValT >>  8);
   clByteArrayT[73] = (uint8_t) (ulTimeValT >>  0);

   ulTimeValT = clMsgTimeP.nanoSeconds();
   clByteArrayT[74] = (uint8_t) (ulTimeValT >>  24);
   clByteArrayT[75] = (uint8_t) (ulTimeValT >>  16);
   clByteArrayT[76] = (uint8_t) (ulTimeValT >>   8);
   clByteArrayT[77] = (uint8_t) (ulTimeValT >>   0);

   //----------------------------------------------------------------
   // place message user field in byte 78 .. 81, MSB first
   //
   clByteArrayT[78] = (uint8_t) (ulMsgUserP >>  24);
   clByteArrayT[79] = (uint8_t) (ulMsgUserP >>  16);
   clByteArrayT[80] = (uint8_t) (ulMsgUserP >>   8);
   clByteArrayT[81] = (uint8_t) (ulMsgUserP >>   0);

   //----------------------------------------------------------------
   // place message marker field in byte 82 .. 85, MSB first
   //
   clByteArrayT[82] = (uint8_t) (ulMsgMarkerP >>  24);
   clByteArrayT[83] = (uint8_t) (ulMsgMarkerP >>  16);
   clByteArrayT[84] = (uint8_t) (ulMsgMarkerP >>   8);
   clByteArrayT[85] = (uint8_t) (ulMsgMarkerP >>   0);

   //----------------------------------------------------------------
   // byte 86 .. 93 (i.e. 8 bytes) are not used, set to 0
   //----------------------------------------------------------------

   //----------------------------------------------------------------
   // build checksum from byte 0 .. 93, add checksum at the end
   //
   uint16_t uwChecksumT = qChecksum(clByteArrayT.constData(),
                                    QCAN_FRAME_ARRAY_SIZE - 2);

   clByteArrayT[94] = (uint8_t) (uwChecksumT >> 8);
   clByteArrayT[95] = (uint8_t) (uwChecksumT >> 0);

   return(clByteArrayT);
}

//----------------------------------------------------------------------------//
// toString()                                                                 //
// print CAN frame                                                            //
//----------------------------------------------------------------------------//
QString QCanFrame::toString(const bool & btShowTimeR)
{
   //----------------------------------------------------------------
   // setup a string object
   //
   QString clStringT; //(QCAN_FRAME_STRING_SIZE, '\0');

   if(btShowTimeR == true)
   {

   }

   //----------------------------------------------------------------
   // print identifier
   //
   clStringT += QString("%1  ").arg(ulIdentifierP, 8, 16).toUpper();

   //----------------------------------------------------------------
   // print frame format
   //
   switch(frameType())
   {
      case eTYPE_CAN_STD:
         clStringT += "CAN-STD ";
         break;

      case eTYPE_CAN_EXT:
         clStringT += "CAN-EXT ";
         break;

      case eTYPE_FD_STD:
         clStringT += " FD-STD ";
         break;

      case eTYPE_FD_EXT:
         clStringT += " FD-EXT ";
         break;

      default:
         clStringT += " N/A    ";
         break;
   }

   //----------------------------------------------------------------
   // print DLC
   //
   clStringT += QString("%1  ").arg(dlc(), 2, 10);

   //----------------------------------------------------------------
   // print data
   //
   for(uint8_t ubCntT = 0; ubCntT < dataSize(); ubCntT++)
   {
      //---------------------------------------------------
      // print a newline and 22 spaces after 16 data bytes
      //
      if((ubCntT > 0) && ((ubCntT % 16) == 0))
      {
         clStringT +="\n                      ";
      }
      clStringT += QString("%1 ").arg( aubByteP[ubCntT],
                                       2,          // 2 digits
                                      16,          // hex value
                                      QLatin1Char('0')).toUpper();
   }

   return(clStringT);
}

//----------------------------------------------------------------------------//
// operator <<                                                                //
// stream to a QDataStream object                                             //
//----------------------------------------------------------------------------//
QDataStream & operator<< ( QDataStream & clStreamR,
                           const QCanFrame & clCanFrameR)
{
   //----------------------------------------------------------------
   // set version of stream
   //
   clStreamR.setVersion(QDataStream::Qt_5_6);

   //----------------------------------------------------------------
   // place all members to the stream
   //
   clStreamR << clCanFrameR.ulIdentifierP;

   for(uint8_t ubIndexT = 0; ubIndexT < CAN_FRAME_DATA_MAX; ubIndexT++)
   {
      clStreamR << clCanFrameR.aubByteP[ubIndexT];
   }

   clStreamR << clCanFrameR.ubMsgDlcP;
   clStreamR << clCanFrameR.ubMsgCtrlP;

   clStreamR << clCanFrameR.clMsgTimeP.seconds();
   clStreamR << clCanFrameR.clMsgTimeP.nanoSeconds();

   clStreamR << clCanFrameR.ulMsgUserP;

   return(clStreamR);
}

<|endoftext|>


<commit_before>/*
 -----------------------------------------------------------------------------
 This source file is part of OGRE
 (Object-oriented Graphics Rendering Engine)
 For the latest info, see http://www.ogre3d.org/

 Copyright (c) 2000-2014 Torus Knot Software Ltd

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 -----------------------------------------------------------------------------
 */
#include "OgreStableHeaders.h"
#include "OgreFileSystemLayer.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#if !((OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE))
#   include <shlobj.h>
#endif
#include <io.h>

namespace Ogre
{
    bool widePathToOgreString(String& dest, const WCHAR* wpath)
    {
        // need to convert to narrow (OEM or ANSI) codepage so that fstream can use it
        // properly on international systems.
        char npath[MAX_PATH];
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        // Note, that on legacy CRT versions codepage for narrow CRT file functions can be changed using
        // SetFileApisANSI/OEM, but on modern runtimes narrow pathes are always widened using ANSI codepage.
        // We suppose that on such runtimes file APIs codepage is left in default, ANSI state.
        UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        // Runtime is modern, narrow calls are widened inside CRT using CP_ACP codepage.
        UINT codepage = CP_ACP;
#endif
        if(0 == WideCharToMultiByte(codepage, 0 /* Use default flags */, wpath, -1, npath, sizeof(npath), NULL, NULL))
        {
            dest.clear();
            return false;
        }

        // success
        dest = npath;
        return true;
    }

    void FileSystemLayer::getConfigPaths()
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        // try to determine the application's path
        DWORD bufsize = 256;
        char* resolved = 0;
        do
        {
            char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL);
            DWORD retval = GetModuleFileName(NULL, buf, bufsize);
            if (retval == 0)
            {
                // failed
                OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL);
                break;
            }

            if (retval < bufsize)
            {
                // operation was successful.
                resolved = buf;
            }
            else
            {
                // buffer was too small, grow buffer and try again
                OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL);
                bufsize <<= 1;
            }
        } while (!resolved);

        Ogre::String appPath = resolved;
        if (resolved)
            OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL);
        if (!appPath.empty())
        {
            // need to strip the application filename from the path
            Ogre::String::size_type pos = appPath.rfind('\\');
            if (pos != Ogre::String::npos)
                appPath.erase(pos);
        }
        else
        {
            // fall back to current working dir
            appPath = ".";
        }

#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        Ogre::String appPath;
        if(!widePathToOgreString(appPath, Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data()))
        {
            // fallback to current working dir
            appPath = ".";
        }
#endif

        // use application path as config search path
        mConfigPaths.push_back(appPath + '\\');
    }
    //---------------------------------------------------------------------
    void FileSystemLayer::prepareUserHome(const Ogre::String& subdir)
    {
        // fill mHomePath
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        WCHAR wpath[MAX_PATH];
        if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, 0, wpath)))
            widePathToOgreString(mHomePath, wpath);
#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        widePathToOgreString(mHomePath, Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data());
#endif

        if(!mHomePath.empty())
        {
            // create Ogre subdir
            mHomePath += "\\Ogre\\";
            if (!createDirectory(mHomePath))
            {
                // couldn't create directory, fall back to current working dir
                mHomePath.clear();
            }
            else
            {
                mHomePath += subdir + '\\';
                // create release subdir
                if (!createDirectory(mHomePath))
                {
                    // couldn't create directory, fall back to current working dir
                    mHomePath.clear();
                }
            }
        }
    }
    //---------------------------------------------------------------------
    bool FileSystemLayer::fileExists(const Ogre::String& path) const
    {
        WIN32_FILE_ATTRIBUTE_DATA attr_data;
        return GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &attr_data) != 0;
    }
    //---------------------------------------------------------------------
    bool FileSystemLayer::createDirectory(const Ogre::String& path)
    {
        return CreateDirectoryA(path.c_str(), NULL) != 0 ||
            GetLastError() == ERROR_ALREADY_EXISTS;
    }
}
<commit_msg>[Win32] Use CRT API (_access,_mkdir rather than GetFileAttributesExA,CreateDirectoryA) to pass Windows Store validation<commit_after>/*
 -----------------------------------------------------------------------------
 This source file is part of OGRE
 (Object-oriented Graphics Rendering Engine)
 For the latest info, see http://www.ogre3d.org/

 Copyright (c) 2000-2014 Torus Knot Software Ltd

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 -----------------------------------------------------------------------------
 */
#include "OgreStableHeaders.h"
#include "OgreFileSystemLayer.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#if !((OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE))
#   include <shlobj.h>
#endif
#include <io.h>
#include <direct.h>

namespace Ogre
{
    bool widePathToOgreString(String& dest, const WCHAR* wpath)
    {
        // need to convert to narrow (OEM or ANSI) codepage so that fstream can use it
        // properly on international systems.
        char npath[MAX_PATH];
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        // Note, that on legacy CRT versions codepage for narrow CRT file functions can be changed using
        // SetFileApisANSI/OEM, but on modern runtimes narrow pathes are always widened using ANSI codepage.
        // We suppose that on such runtimes file APIs codepage is left in default, ANSI state.
        UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        // Runtime is modern, narrow calls are widened inside CRT using CP_ACP codepage.
        UINT codepage = CP_ACP;
#endif
        if(0 == WideCharToMultiByte(codepage, 0 /* Use default flags */, wpath, -1, npath, sizeof(npath), NULL, NULL))
        {
            dest.clear();
            return false;
        }

        // success
        dest = npath;
        return true;
    }

    void FileSystemLayer::getConfigPaths()
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        // try to determine the application's path
        DWORD bufsize = 256;
        char* resolved = 0;
        do
        {
            char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL);
            DWORD retval = GetModuleFileName(NULL, buf, bufsize);
            if (retval == 0)
            {
                // failed
                OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL);
                break;
            }

            if (retval < bufsize)
            {
                // operation was successful.
                resolved = buf;
            }
            else
            {
                // buffer was too small, grow buffer and try again
                OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL);
                bufsize <<= 1;
            }
        } while (!resolved);

        Ogre::String appPath = resolved;
        if (resolved)
            OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL);
        if (!appPath.empty())
        {
            // need to strip the application filename from the path
            Ogre::String::size_type pos = appPath.rfind('\\');
            if (pos != Ogre::String::npos)
                appPath.erase(pos);
        }
        else
        {
            // fall back to current working dir
            appPath = ".";
        }

#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        Ogre::String appPath;
        if(!widePathToOgreString(appPath, Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data()))
        {
            // fallback to current working dir
            appPath = ".";
        }
#endif

        // use application path as config search path
        mConfigPaths.push_back(appPath + '\\');
    }
    //---------------------------------------------------------------------
    void FileSystemLayer::prepareUserHome(const Ogre::String& subdir)
    {
        // fill mHomePath
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        WCHAR wpath[MAX_PATH];
        if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, 0, wpath)))
            widePathToOgreString(mHomePath, wpath);
#elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT
        widePathToOgreString(mHomePath, Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data());
#endif

        if(!mHomePath.empty())
        {
            // create Ogre subdir
            mHomePath += "\\Ogre\\";
            if (!createDirectory(mHomePath))
            {
                // couldn't create directory, fall back to current working dir
                mHomePath.clear();
            }
            else
            {
                mHomePath += subdir + '\\';
                // create release subdir
                if (!createDirectory(mHomePath))
                {
                    // couldn't create directory, fall back to current working dir
                    mHomePath.clear();
                }
            }
        }
    }
    //---------------------------------------------------------------------
    bool FileSystemLayer::fileExists(const Ogre::String& path) const
    {
        return _access(path.c_str(), 04) == 0; // Use CRT API rather than GetFileAttributesExA to pass Windows Store validation
    }
    //---------------------------------------------------------------------
    bool FileSystemLayer::createDirectory(const Ogre::String& path)
    {
        return !_mkdir(path.c_str()) || errno == EEXIST; // Use CRT API rather than CreateDirectoryA to pass Windows Store validation
    }
}
<|endoftext|>


<commit_before>/*!
    \file password.cpp
    \brief Password string implementation
    \author Ivan Shynkarenka
    \date 04.06.2019
    \copyright MIT License
*/

#include "string/password.h"

#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#define __USE_MISC
#include <string.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

namespace CppCommon {

void ZeroPasswordMemory(void* buffer, size_t size)
{
#if defined(__APPLE__)
    volatile char* ptr = buffer;
    while (size--) *ptr++ = 0;
#elif defined(unix) || defined(__unix) || defined(__unix__)
    explicit_bzero(buffer, size);
#elif defined(_WIN32) || defined(_WIN64)
    SecureZeroMemory(buffer, size);
#else
    #error Unsupported platform
#endif
}

} // namespace CppCommon
<commit_msg>build<commit_after>/*!
    \file password.cpp
    \brief Password string implementation
    \author Ivan Shynkarenka
    \date 04.06.2019
    \copyright MIT License
*/

#include "string/password.h"

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

namespace CppCommon {

void ZeroPasswordMemory(void* buffer, size_t size)
{
#if defined(_WIN32) || defined(_WIN64)
    SecureZeroMemory(buffer, size);
#else
    volatile char* ptr = (volatile char*)buffer;
    while (size--) *ptr++ = 0;
#endif
}

} // namespace CppCommon
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
//

#include "MarbleDirs.h"
#include "MarbleDebug.h"

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtGui/QApplication>

#include <stdlib.h>

#ifdef Q_OS_MACX
//for getting app bundle path
#include <ApplicationServices/ApplicationServices.h>
#endif

#ifdef Q_OS_WIN
//for getting appdata path
#define _WIN32_IE 0x0400
#include <shlobj.h>
#endif

#include <config-marble.h>

using namespace Marble;

namespace
{
    QString runTimeMarbleDataPath = "";

    QString runTimeMarblePluginPath = "";
}

MarbleDirs::MarbleDirs()
    : d( 0 )
{
}

QString MarbleDirs::path( const QString& relativePath )
{
    QString  localpath = localPath() + '/' + relativePath;	// local path
    QString  systempath  = systemPath() + '/' + relativePath;	// system path

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }

    return QDir( fullpath ).canonicalPath();
}

QString MarbleDirs::pluginPath( const QString& relativePath )
{
    QString  localpath = pluginLocalPath() + QDir::separator() + relativePath;    // local path
    QString  systempath  = pluginSystemPath() + QDir::separator() + relativePath; // system path

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }

    return QDir( fullpath ).canonicalPath();
}

QStringList MarbleDirs::entryList( const QString& relativePath, QDir::Filters filters )
{
    QStringList filesLocal = QDir( MarbleDirs::localPath() + '/' + relativePath ).entryList(filters);
    QStringList filesSystem = QDir( MarbleDirs::systemPath() + '/' + relativePath ).entryList(filters);
    QStringList allFiles( filesLocal );
    allFiles << filesSystem;

    // remove duplicate entries
    allFiles.sort();
    for ( int i = 1; i < allFiles.size(); ++i ) {
        if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
            allFiles.removeAt(i);
            --i;
        }
    }

    return allFiles;
}

QStringList MarbleDirs::pluginEntryList( const QString& relativePath, QDir::Filters filters )
{
    QStringList filesLocal = QDir( MarbleDirs::pluginLocalPath() + '/' + relativePath ).entryList(filters);
    QStringList filesSystem = QDir( MarbleDirs::pluginSystemPath() + '/' + relativePath ).entryList(filters);
    QStringList allFiles( filesLocal );
    allFiles << filesSystem;

    // remove duplicate entries
    allFiles.sort();
    for ( int i = 1; i < allFiles.size(); ++i ) {
        if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
            allFiles.removeAt(i);
            --i;
        }
    }

    return allFiles;
}

QString MarbleDirs::systemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/data";
    }

    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarbleDataPath.isEmpty() )
    return runTimeMarbleDataPath;

#ifdef MARBLE_DATA_PATH
    //MARBLE_DATA_PATH is a compiler define set by cmake
    QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);

    if(QDir(compileTimeMarbleDataPath).exists())
        return compileTimeMarbleDataPath;
#endif  // MARBLE_DATA_PATH

    return QDir( QCoreApplication::applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/data" )
#else
                     + QLatin1String( "/../share/apps/marble/data" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::pluginSystemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/plugins";
    }

    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarblePluginPath.isEmpty() )
    return runTimeMarblePluginPath;

#ifdef MARBLE_PLUGIN_PATH
    //MARBLE_PLUGIN_PATH is a compiler define set by cmake
    QString compileTimeMarblePluginPath(MARBLE_PLUGIN_PATH);

    if(QDir(compileTimeMarblePluginPath).exists())
        return compileTimeMarblePluginPath;
#endif  // MARBLE_PLUGIN_PATH

    return QDir( QCoreApplication::applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/plugins" )
#else
                     + QLatin1String( "/../lib/kde4/plugins/marble" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::localPath()
{
#ifndef Q_OS_WIN
    QString dataHome = getenv( "XDG_DATA_HOME" );
    if( dataHome.isEmpty() )
        dataHome = QDir::homePath() + "/.local/share";

    return dataHome + "/marble"; // local path
#else
    HWND hwnd = 0;
    WCHAR *appdata_path = new WCHAR[MAX_PATH+1];

    SHGetSpecialFolderPathW( hwnd, appdata_path, CSIDL_APPDATA, 0 );
    QString appdata = QString::fromUtf16( reinterpret_cast<ushort*>( appdata_path ) );
    delete[] appdata_path;
    return QString( QDir::fromNativeSeparators( appdata ) + "/.marble/data" ); // local path
#endif
}

QStringList MarbleDirs::oldLocalPaths()
{
    QStringList possibleOldPaths;

#ifndef Q_OS_WIN
    QString oldDefault = QDir::homePath() + "/.marble/data";
    possibleOldPaths.append( oldDefault );

    QString xdgDefault = QDir::homePath() + "/.local/share/marble";
    possibleOldPaths.append( xdgDefault );

    QString xdg = getenv( "XDG_DATA_HOME" );
    xdg += "/marble/";
    possibleOldPaths.append( xdg );
#endif
    QString currentLocalPath = QDir( MarbleDirs::localPath() ).canonicalPath();
    QStringList oldPaths;
    foreach( const QString& possibleOldPath, possibleOldPaths ) {
        if( !QDir().exists( possibleOldPath ) ) {
            continue;
        }

        QString canonicalPossibleOldPath = QDir( possibleOldPath ).canonicalPath();
        if( canonicalPossibleOldPath == currentLocalPath ) {
            continue;
        }

        oldPaths.append( canonicalPossibleOldPath );
    }

    return oldPaths;
}

QString MarbleDirs::pluginLocalPath()
{
#ifndef Q_OS_WIN
    return QString( QDir::homePath() + "/.marble/plugins" ); // local path
#else
    HWND hwnd = 0;
    WCHAR *appdata_path = new WCHAR[MAX_PATH+1];

    SHGetSpecialFolderPathW( hwnd, appdata_path, CSIDL_APPDATA, 0 );
    QString appdata = QString::fromUtf16( reinterpret_cast<ushort*>( appdata_path ) );
    delete[] appdata_path;
    return QString( QDir::fromNativeSeparators( appdata ) + "/.marble/plugins" ); // local path
#endif
}

QString MarbleDirs::marbleDataPath()
{
    return runTimeMarbleDataPath;
}

QString MarbleDirs::marblePluginPath()
{
    return runTimeMarbleDataPath;
}

void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarbleDataPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarbleDataPath = adaptedPath;
}

void MarbleDirs::setMarblePluginPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarblePluginPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarblePluginPath = adaptedPath;
}

void MarbleDirs::debug()
{
    mDebug() << "=== MarbleDirs: ===";
    mDebug() << "Local Path:" << localPath();
    mDebug() << "Plugin Local Path:" << pluginLocalPath();
    mDebug() << "";
    mDebug() << "Marble Data Path (Run Time) :" << runTimeMarbleDataPath;
    mDebug() << "Marble Data Path (Compile Time):" << QString(MARBLE_DATA_PATH);
    mDebug() << "";
    mDebug() << "Marble Plugin Path (Run Time) :" << runTimeMarblePluginPath;
    mDebug() << "Marble Plugin Path (Compile Time):" << QString(MARBLE_PLUGIN_PATH);
    mDebug() << "";
    mDebug() << "System Path:" << systemPath();
    mDebug() << "Plugin System Path:" << pluginSystemPath();
    mDebug() << "===================";
}
<commit_msg>mingw w64 need at east internet explorrer 5.1<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
//

#include "MarbleDirs.h"
#include "MarbleDebug.h"

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtGui/QApplication>

#include <stdlib.h>

#ifdef Q_OS_MACX
//for getting app bundle path
#include <ApplicationServices/ApplicationServices.h>
#endif

#ifdef Q_OS_WIN
//for getting appdata path
//mingw-w64 Internet Explorer 5.01
#define _WIN32_IE 0x0501
#include <shlobj.h>
#endif

#include <config-marble.h>

using namespace Marble;

namespace
{
    QString runTimeMarbleDataPath = "";

    QString runTimeMarblePluginPath = "";
}

MarbleDirs::MarbleDirs()
    : d( 0 )
{
}

QString MarbleDirs::path( const QString& relativePath )
{
    QString  localpath = localPath() + '/' + relativePath;	// local path
    QString  systempath  = systemPath() + '/' + relativePath;	// system path

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }

    return QDir( fullpath ).canonicalPath();
}

QString MarbleDirs::pluginPath( const QString& relativePath )
{
    QString  localpath = pluginLocalPath() + QDir::separator() + relativePath;    // local path
    QString  systempath  = pluginSystemPath() + QDir::separator() + relativePath; // system path

    QString fullpath = systempath;
    if ( QFile::exists( localpath ) ) {
        fullpath = localpath;
    }

    return QDir( fullpath ).canonicalPath();
}

QStringList MarbleDirs::entryList( const QString& relativePath, QDir::Filters filters )
{
    QStringList filesLocal = QDir( MarbleDirs::localPath() + '/' + relativePath ).entryList(filters);
    QStringList filesSystem = QDir( MarbleDirs::systemPath() + '/' + relativePath ).entryList(filters);
    QStringList allFiles( filesLocal );
    allFiles << filesSystem;

    // remove duplicate entries
    allFiles.sort();
    for ( int i = 1; i < allFiles.size(); ++i ) {
        if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
            allFiles.removeAt(i);
            --i;
        }
    }

    return allFiles;
}

QStringList MarbleDirs::pluginEntryList( const QString& relativePath, QDir::Filters filters )
{
    QStringList filesLocal = QDir( MarbleDirs::pluginLocalPath() + '/' + relativePath ).entryList(filters);
    QStringList filesSystem = QDir( MarbleDirs::pluginSystemPath() + '/' + relativePath ).entryList(filters);
    QStringList allFiles( filesLocal );
    allFiles << filesSystem;

    // remove duplicate entries
    allFiles.sort();
    for ( int i = 1; i < allFiles.size(); ++i ) {
        if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
            allFiles.removeAt(i);
            --i;
        }
    }

    return allFiles;
}

QString MarbleDirs::systemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/data";
    }

    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarbleDataPath.isEmpty() )
    return runTimeMarbleDataPath;

#ifdef MARBLE_DATA_PATH
    //MARBLE_DATA_PATH is a compiler define set by cmake
    QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);

    if(QDir(compileTimeMarbleDataPath).exists())
        return compileTimeMarbleDataPath;
#endif  // MARBLE_DATA_PATH

    return QDir( QCoreApplication::applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/data" )
#else
                     + QLatin1String( "/../share/apps/marble/data" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::pluginSystemPath()
{
    QString systempath;

#ifdef Q_OS_MACX
    //
    // On OSX lets try to find any file first in the bundle
    // before branching out to home and sys dirs
    //
    CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
    CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
    const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
    CFRelease(myBundleRef);
    CFRelease(myMacPath);
    QString myPath(mypPathPtr);
    //do some magick so that we can still find data dir if
    //marble was not built as a bundle
    if (myPath.contains(".app"))  //its a bundle!
    {
      systempath = myPath + "/Contents/Resources/plugins";
    }

    if ( QFile::exists( systempath ) ){
      return systempath;
    }
#endif   // mac bundle

// Should this happen before the Mac bundle already?
if ( !runTimeMarblePluginPath.isEmpty() )
    return runTimeMarblePluginPath;

#ifdef MARBLE_PLUGIN_PATH
    //MARBLE_PLUGIN_PATH is a compiler define set by cmake
    QString compileTimeMarblePluginPath(MARBLE_PLUGIN_PATH);

    if(QDir(compileTimeMarblePluginPath).exists())
        return compileTimeMarblePluginPath;
#endif  // MARBLE_PLUGIN_PATH

    return QDir( QCoreApplication::applicationDirPath()

#if defined(QTONLY)
                     + QLatin1String( "/plugins" )
#else
                     + QLatin1String( "/../lib/kde4/plugins/marble" )
#endif
                     ).canonicalPath();
}

QString MarbleDirs::localPath()
{
#ifndef Q_OS_WIN
    QString dataHome = getenv( "XDG_DATA_HOME" );
    if( dataHome.isEmpty() )
        dataHome = QDir::homePath() + "/.local/share";

    return dataHome + "/marble"; // local path
#else
    HWND hwnd = 0;
    WCHAR *appdata_path = new WCHAR[MAX_PATH+1];

    SHGetSpecialFolderPathW( hwnd, appdata_path, CSIDL_APPDATA, 0 );
    QString appdata = QString::fromUtf16( reinterpret_cast<ushort*>( appdata_path ) );
    delete[] appdata_path;
    return QString( QDir::fromNativeSeparators( appdata ) + "/.marble/data" ); // local path
#endif
}

QStringList MarbleDirs::oldLocalPaths()
{
    QStringList possibleOldPaths;

#ifndef Q_OS_WIN
    QString oldDefault = QDir::homePath() + "/.marble/data";
    possibleOldPaths.append( oldDefault );

    QString xdgDefault = QDir::homePath() + "/.local/share/marble";
    possibleOldPaths.append( xdgDefault );

    QString xdg = getenv( "XDG_DATA_HOME" );
    xdg += "/marble/";
    possibleOldPaths.append( xdg );
#endif
    QString currentLocalPath = QDir( MarbleDirs::localPath() ).canonicalPath();
    QStringList oldPaths;
    foreach( const QString& possibleOldPath, possibleOldPaths ) {
        if( !QDir().exists( possibleOldPath ) ) {
            continue;
        }

        QString canonicalPossibleOldPath = QDir( possibleOldPath ).canonicalPath();
        if( canonicalPossibleOldPath == currentLocalPath ) {
            continue;
        }

        oldPaths.append( canonicalPossibleOldPath );
    }

    return oldPaths;
}

QString MarbleDirs::pluginLocalPath()
{
#ifndef Q_OS_WIN
    return QString( QDir::homePath() + "/.marble/plugins" ); // local path
#else
    HWND hwnd = 0;
    WCHAR *appdata_path = new WCHAR[MAX_PATH+1];

    SHGetSpecialFolderPathW( hwnd, appdata_path, CSIDL_APPDATA, 0 );
    QString appdata = QString::fromUtf16( reinterpret_cast<ushort*>( appdata_path ) );
    delete[] appdata_path;
    return QString( QDir::fromNativeSeparators( appdata ) + "/.marble/plugins" ); // local path
#endif
}

QString MarbleDirs::marbleDataPath()
{
    return runTimeMarbleDataPath;
}

QString MarbleDirs::marblePluginPath()
{
    return runTimeMarbleDataPath;
}

void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarbleDataPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarbleDataPath = adaptedPath;
}

void MarbleDirs::setMarblePluginPath( const QString& adaptedPath )
{
    if ( !QDir::root().exists( adaptedPath ) )
    {
        qDebug( "WARNING: Invalid MarblePluginPath %s. Using builtin path instead.",
                qPrintable( adaptedPath ) );
        return;
    }

    runTimeMarblePluginPath = adaptedPath;
}

void MarbleDirs::debug()
{
    mDebug() << "=== MarbleDirs: ===";
    mDebug() << "Local Path:" << localPath();
    mDebug() << "Plugin Local Path:" << pluginLocalPath();
    mDebug() << "";
    mDebug() << "Marble Data Path (Run Time) :" << runTimeMarbleDataPath;
    mDebug() << "Marble Data Path (Compile Time):" << QString(MARBLE_DATA_PATH);
    mDebug() << "";
    mDebug() << "Marble Plugin Path (Run Time) :" << runTimeMarblePluginPath;
    mDebug() << "Marble Plugin Path (Compile Time):" << QString(MARBLE_PLUGIN_PATH);
    mDebug() << "";
    mDebug() << "System Path:" << systemPath();
    mDebug() << "Plugin System Path:" << pluginSystemPath();
    mDebug() << "===================";
}
<|endoftext|>


<commit_before>#include <map>
#include <vector>
#include <string>
#include <time.h>
#include "NFComm/NFPluginModule/NFIPluginManager.h"
#include "NFComm/NFCore/NFQueue.h"
#include "NFComm/RapidXML/rapidxml.hpp"
#include "NFComm/RapidXML/rapidxml_iterators.hpp"
#include "NFComm/RapidXML/rapidxml_print.hpp"
#include "NFComm/RapidXML/rapidxml_utils.hpp"
#include "NFComm/NFPluginModule/NFPlatform.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>

#if NF_PLATFORM == NF_PLATFORM_WIN
#include <io.h>
#include <windows.h>
#include <conio.h>
#else
#include <iconv.h>
#include <unistd.h>
#include <cstdio>
#include <dirent.h>
#include <sys/stat.h>
#endif

bool GetPluginNameList(std::string& strPlugin, std::vector<std::string>& pluginList, std::string& configPath)
{
	rapidxml::file<> fdoc(strPlugin.c_str());
	rapidxml::xml_document<>  doc;
	doc.parse<0>(fdoc.data());

	rapidxml::xml_node<>* pRoot = doc.first_node();
	for (rapidxml::xml_node<>* pPluginNode = pRoot->first_node("Plugin"); pPluginNode; pPluginNode = pPluginNode->next_sibling("Plugin"))
	{
		const char* strPluginName = pPluginNode->first_attribute("Name")->value();
		const char* strMain = pPluginNode->first_attribute("Main")->value();
		pluginList.push_back(std::string(strPluginName));
	}

	rapidxml::xml_node<>* pPluginAppNode = pRoot->first_node("APPID");
	if (!pPluginAppNode)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	const char* strAppID = pPluginAppNode->first_attribute("Name")->value();
	if (!strAppID)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	rapidxml::xml_node<>* pPluginConfigPathNode = pRoot->first_node("ConfigPath");
	if (!pPluginConfigPathNode)
	{
		//NFASSERT(0, "There are no ConfigPath", __FILE__, __FUNCTION__);
		return false;
	}

	if (NULL == pPluginConfigPathNode->first_attribute("Name"))
	{
		//NFASSERT(0, "There are no ConfigPath.Name", __FILE__, __FUNCTION__);
		return false;
	}

	configPath = pPluginConfigPathNode->first_attribute("Name")->value();

	return true;
}

int CopyFile(std::string& SourceFile, std::string& NewFile)
{
	ifstream in;
	ofstream out;
	in.open(SourceFile.c_str(), ios::binary);//Դļ
	if (in.fail())//Դļʧ
	{
		cout << "Error 1: Fail to open the source file." << endl;
		in.close();
		out.close();
		return 0;
	}
	out.open(NewFile.c_str(), ios::binary);//Ŀļ
	if (out.fail())//ļʧ
	{
		cout << "Error 2: Fail to create the new file." << endl;
		out.close();
		in.close();
		return 0;
	}
	else//ļ
	{
		out << in.rdbuf();
		out.close();
		in.close();
		return 1;
	}
}

std::vector<std::string> GetFileListInFolder(std::string folderPath, int depth)
{
	std::vector<std::string> result;
#if NF_PLATFORM == NF_PLATFORM_WIN
	_finddata_t FileInfo;
	std::string strfind = folderPath + "\\*";
	long long Handle = _findfirst(strfind.c_str(), &FileInfo);

	if (Handle == -1L)
	{
		std::cerr << "can not match the folder path" << std::endl;
		exit(-1);
	}
	do {
		//жǷĿ¼
		if (FileInfo.attrib & _A_SUBDIR)
		{
			//Ҫ
			if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
			{
				std::string newPath = folderPath + "\\" + FileInfo.name;
				//dfsFolder(newPath, depth);
				auto newResult = GetFileListInFolder(newPath, depth);
				result.insert(result.begin(), newResult.begin(), newResult.end());
			}
		}
		else
		{

			std::string filename = (folderPath + "\\" + FileInfo.name);
			result.push_back(filename);
		}
	} while (_findnext(Handle, &FileInfo) == 0);

	_findclose(Handle);
#else
	DIR *pDir;
	struct dirent *ent;
	char childpath[512];
	char absolutepath[512];
	pDir = opendir(folderPath.c_str());
	memset(childpath, 0, sizeof(childpath));
	while ((ent = readdir(pDir)) != NULL)
	{
		if (ent->d_type & DT_DIR)
		{
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
			{
				continue;
			}
			std::string childpath = folderPath + "/" + ent->d_name;
			auto newResult = GetFileListInFolder(childpath, depth);
			result.insert(result.begin(), newResult.begin(), newResult.end());
		}
		else
		{
			sprintf(absolutepath, "%s/%s", folderPath.c_str(), ent->d_name);
			result.push_back(absolutepath);
		}
	}

	sort(result.begin(), result.end());//
#endif
	return result;
}

void StringReplace(std::string &strBig, const std::string &strsrc, const std::string &strdst)
{
	std::string::size_type pos = 0;
	std::string::size_type srclen = strsrc.size();
	std::string::size_type dstlen = strdst.size();

	while ((pos = strBig.find(strsrc, pos)) != std::string::npos)
	{
		strBig.replace(pos, srclen, strdst);
		pos += dstlen;
	}
}

void printResult(int result, std::string& strName)
{
	if (result == 1)
	{
		printf("Copy file: %s success!\n", strName.c_str());
	}
	else
	{
		printf("Copy file: %s failed!\n", strName.c_str());
	}
}

int main()
{
	std::vector<std::string> fileList;
#ifdef NF_DEBUG_MODE
	fileList = GetFileListInFolder("../../Debug", 10);
#else
	fileList = GetFileListInFolder("../../Release", 10);
#endif
	for (auto fileName : fileList)
	{
		if (fileName.find("Plugin.xml") != std::string::npos)
		{
			StringReplace(fileName, "\\", "/");
			StringReplace(fileName, "//", "/");
			printf("Reading xml file: %s\n", fileName.c_str());

			std::vector<std::string> pluginList;
			std::string configPath = "";
			GetPluginNameList(fileName, pluginList, configPath);
			if (pluginList.size() > 0 && configPath != "")
			{
#if NF_PLATFORM == NF_PLATFORM_WIN
				pluginList.push_back("libprotobuf");
				pluginList.push_back("NFMessageDefine");
#else
				pluginList.push_back("NFMessageDefine");
#endif
				pluginList.push_back("NFPluginLoader");
				configPath = "../" + configPath;
				configPath = fileName.substr(0, fileName.find_last_of("/")) + "/" + configPath;

				for (std::string name : pluginList)
				{
#if NF_PLATFORM == NF_PLATFORM_WIN

#else

#endif

					int result = 0;
					if (name == "NFPluginLoader")
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.exe";
						auto strDes = des + "_d.exe";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d";
						auto strDes = des + "_d";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif

					}
					else
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.dll";
						auto strDes = des + "_d.dll";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/lib" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.so";
						auto strDes = des + "_d.so";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif
					}
				}
			}
		}
	}

	std::cin.ignore();
	return 0;
}<commit_msg>update<commit_after>#include <map>
#include <vector>
#include <string>
#include <time.h>
#include "NFComm/NFPluginModule/NFIPluginManager.h"
#include "NFComm/NFCore/NFQueue.h"
#include "NFComm/RapidXML/rapidxml.hpp"
#include "NFComm/RapidXML/rapidxml_iterators.hpp"
#include "NFComm/RapidXML/rapidxml_print.hpp"
#include "NFComm/RapidXML/rapidxml_utils.hpp"
#include "NFComm/NFPluginModule/NFPlatform.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>

#if NF_PLATFORM == NF_PLATFORM_WIN
#include <io.h>
#include <windows.h>
#include <conio.h>
#else
#include <iconv.h>
#include <unistd.h>
#include <cstdio>
#include <dirent.h>
#include <sys/stat.h>
#endif

bool GetPluginNameList(std::string& strPlugin, std::vector<std::string>& pluginList, std::string& configPath)
{
	rapidxml::file<> fdoc(strPlugin.c_str());
	rapidxml::xml_document<>  doc;
	doc.parse<0>(fdoc.data());

	rapidxml::xml_node<>* pRoot = doc.first_node();
	for (rapidxml::xml_node<>* pPluginNode = pRoot->first_node("Plugin"); pPluginNode; pPluginNode = pPluginNode->next_sibling("Plugin"))
	{
		const char* strPluginName = pPluginNode->first_attribute("Name")->value();
		const char* strMain = pPluginNode->first_attribute("Main")->value();
		pluginList.push_back(std::string(strPluginName));
	}

	rapidxml::xml_node<>* pPluginAppNode = pRoot->first_node("APPID");
	if (!pPluginAppNode)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	const char* strAppID = pPluginAppNode->first_attribute("Name")->value();
	if (!strAppID)
	{
		//NFASSERT(0, "There are no App ID", __FILE__, __FUNCTION__);
		return false;
	}

	rapidxml::xml_node<>* pPluginConfigPathNode = pRoot->first_node("ConfigPath");
	if (!pPluginConfigPathNode)
	{
		//NFASSERT(0, "There are no ConfigPath", __FILE__, __FUNCTION__);
		return false;
	}

	if (NULL == pPluginConfigPathNode->first_attribute("Name"))
	{
		//NFASSERT(0, "There are no ConfigPath.Name", __FILE__, __FUNCTION__);
		return false;
	}

	configPath = pPluginConfigPathNode->first_attribute("Name")->value();

	return true;
}

int CopyFile(std::string& SourceFile, std::string& NewFile)
{
	ifstream in;
	ofstream out;
	in.open(SourceFile.c_str(), ios::binary);//Դļ
	if (in.fail())//Դļʧ
	{
		cout << "Error 1: Fail to open the source file." << endl;
		in.close();
		out.close();
		return 0;
	}
	out.open(NewFile.c_str(), ios::binary);//Ŀļ
	if (out.fail())//ļʧ
	{
		cout << "Error 2: Fail to create the new file." << endl;
		out.close();
		in.close();
		return 0;
	}
	else//ļ
	{
		out << in.rdbuf();
		out.close();
		in.close();
		return 1;
	}
}

std::vector<std::string> GetFileListInFolder(std::string folderPath, int depth)
{
	std::vector<std::string> result;
#if NF_PLATFORM == NF_PLATFORM_WIN
	_finddata_t FileInfo;
	std::string strfind = folderPath + "\\*";
	long long Handle = _findfirst(strfind.c_str(), &FileInfo);

	if (Handle == -1L)
	{
		std::cerr << "can not match the folder path" << std::endl;
		exit(-1);
	}
	do {
		//жǷĿ¼
		if (FileInfo.attrib & _A_SUBDIR)
		{
			//Ҫ
			if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
			{
				std::string newPath = folderPath + "\\" + FileInfo.name;
				//dfsFolder(newPath, depth);
				auto newResult = GetFileListInFolder(newPath, depth);
				result.insert(result.begin(), newResult.begin(), newResult.end());
			}
		}
		else
		{

			std::string filename = (folderPath + "\\" + FileInfo.name);
			result.push_back(filename);
		}
	} while (_findnext(Handle, &FileInfo) == 0);

	_findclose(Handle);
#else
	DIR *pDir;
	struct dirent *ent;
	char childpath[512];
	char absolutepath[512];
	pDir = opendir(folderPath.c_str());
	memset(childpath, 0, sizeof(childpath));
	while ((ent = readdir(pDir)) != NULL)
	{
		if (ent->d_type & DT_DIR)
		{
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
			{
				continue;
			}
			std::string childpath = folderPath + "/" + ent->d_name;
			auto newResult = GetFileListInFolder(childpath, depth);
			result.insert(result.begin(), newResult.begin(), newResult.end());
		}
		else
		{
			sprintf(absolutepath, "%s/%s", folderPath.c_str(), ent->d_name);
			result.push_back(absolutepath);
		}
	}

	sort(result.begin(), result.end());//
#endif
	return result;
}

void StringReplace(std::string &strBig, const std::string &strsrc, const std::string &strdst)
{
	std::string::size_type pos = 0;
	std::string::size_type srclen = strsrc.size();
	std::string::size_type dstlen = strdst.size();

	while ((pos = strBig.find(strsrc, pos)) != std::string::npos)
	{
		strBig.replace(pos, srclen, strdst);
		pos += dstlen;
	}
}

void printResult(int result, std::string& strName)
{
	if (result == 1)
	{
		printf("Copy file: %s success!\n", strName.c_str());
	}
	else
	{
		printf("Copy file: %s failed!\n", strName.c_str());
	}
}

int main()
{
	std::vector<std::string> fileList;
#ifdef NF_DEBUG_MODE
	fileList = GetFileListInFolder("../../Debug", 10);
#else
	fileList = GetFileListInFolder("../../Release", 10);
#endif
	for (auto fileName : fileList)
	{
		if (fileName.find("Plugin.xml") != std::string::npos)
		{
			StringReplace(fileName, "\\", "/");
			StringReplace(fileName, "//", "/");
			printf("Reading xml file: %s\n", fileName.c_str());

			std::vector<std::string> pluginList;
			std::string configPath = "";
			GetPluginNameList(fileName, pluginList, configPath);
			if (pluginList.size() > 0 && configPath != "")
			{
#if NF_PLATFORM == NF_PLATFORM_WIN
				pluginList.push_back("libprotobuf");
				pluginList.push_back("NFMessageDefine");
#else
				pluginList.push_back("NFMessageDefine");
#endif
				pluginList.push_back("NFPluginLoader");
				configPath = "../" + configPath;
				configPath = fileName.substr(0, fileName.find_last_of("/")) + "/" + configPath;

				for (std::string name : pluginList)
				{
					int result = 0;
					if (name == "NFPluginLoader")
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.exe";
						auto strDes = des + "_d.exe";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d";
						auto strDes = des + "_d";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif

					}
					else
					{
#if NF_PLATFORM == NF_PLATFORM_WIN
#ifdef NF_DEBUG_MODE
						std::string src = configPath + "Comm/Debug/" + name;
#else
						std::string src = configPath + "Comm/Release/" + name;
#endif
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.dll";
						auto strDes = des + "_d.dll";
						auto strSrcPDB = src + "_d.pdb";
						auto strDesPDB = des + "_d.pdb";
						printResult(CopyFile(strSrc, strDes), strSrc);
						printResult(CopyFile(strSrcPDB, strDesPDB), strSrcPDB);
#else
						std::string src = configPath + "Comm/lib" + name;
						std::string des = fileName.substr(0, fileName.find_last_of("/")) + "/" + name;
						auto strSrc = src + "_d.so";
						auto strDes = des + "_d.so";
						printResult(CopyFile(strSrc, strDes), strSrc);
#endif
					}
				}
			}
		}
	}
#if NF_PLATFORM == NF_PLATFORM_WIN
	getch();
#else

#endif
	return 0;
}<|endoftext|>


<commit_before>#define serial Serial

#include <Arduino.h>
#include <Wire.h>

#include "ChibiOS_AVR.h"
#include "Serial.h"
#include "Tools.h"

#include "CommunicationUtils.h"
#include "DebugUtils.h"
#include "ADXL345.h"
#include "ITG3200.h"
#include "FreeIMU.h"

#include "Sensors.h"
#include "Led.h"
#include "DriveSystem.h"
#include "Motor.h"

#include "./lib/Arbitrer.h"
#include "./lib/Cruise.h"
#include "./lib/Bump.h"
#include "./lib/Stabilization.h"

void chSetup() {
	chThdSleepMilliseconds(5000);

	chThdCreateStatic(waArbitrerThread, sizeof(waArbitrerThread),
			NORMALPRIO + 10, ArbitrerThread, NULL);
	chThdCreateStatic(waStabilizationThread, sizeof(waStabilizationThread),
			NORMALPRIO, StabilizationThread, NULL);
	chThdCreateStatic(waCruiseThread, sizeof(waCruiseThread),
			NORMALPRIO + 1, CruiseThread, NULL);
	chThdCreateStatic(waBumpThread, sizeof(waBumpThread),
			NORMALPRIO + 2, BumpThread, NULL);

	/* chThdSleepMilliseconds(6000);
	   Serial.println("YOLO");
	   robot.spin(sensors, RIGHT, 160, 90);

	   chThdSleepMilliseconds(600);

	   robot.go(FORTH, 130, 3000, 350);
	   robot.stop(500);

	//chThdSleepMilliseconds(1000);

	robot.spin(sensors, LEFT, 160, 90);

	chThdSleepMilliseconds(600);

	robot.go(BACK, 130, 3000, 350);
	robot.stop(500);

	Serial.println("SWAG");
	robot.stop();*/
}

void setup() {
	Serial.begin(115200);
	sensors.init();

	Serial.println("111");

	chBegin(chSetup);

	while(1) {
		// nothing to do here
	}
}

void loop() {
	// nothing to do here
}

<commit_msg>create simple code to test compilation<commit_after>#include <Arduino.h>
#include "MyFirstLib.h"

MyFirstClass MyFirstObject;

void setup() {

	Serial.begin(115200);
	delay(1000);

}

void loop() {

	MyFirstObject.methodNumberOne();
	delay(1000);
	MyFirstObject.methodNumberTwo();
	delay(1000);

}

<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP
#define STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/prim/scal/err/check_positive.hpp>
#include <stan/math/prim/mat/err/check_pos_definite.hpp>
#include <stan/math/prim/scal/err/check_size_match.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <sstream>
#include <string>

namespace stan {
namespace math {

/**
 * Check if the specified matrix is a valid correlation matrix.
 * A valid correlation matrix is symmetric, has a unit diagonal
 * (all 1 values), and has all values between -1 and 1
 * (inclusive).
 * This function throws exceptions if the variable is not a valid
 * correlation matrix.
 * @tparam T_y Type of scalar
 * @param function Name of the function this was called from
 * @param name Name of the variable
 * @param y Matrix to test
 * @throw std::invalid_argument if the matrix is not square
 *   or if the matrix is 0x0
 * @throw std::domain_error if the matrix is non-symmetric,
 *   diagonals not near 1, not positive definite, or any of the
 *   elements nan
 */
template <typename T_y>
inline void check_corr_matrix(
    const char* function, const char* name,
    const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y) {
  using size_type = typename index_type<
      Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic> >::type;

  check_size_match(function, "Rows of correlation matrix", y.rows(),
                   "columns of correlation matrix", y.cols());
  check_positive(function, name, "rows", y.rows());

  for (size_type k = 0; k < y.rows(); ++k) {
    if (!(fabs(y(k, k) - 1.0) <= CONSTRAINT_TOLERANCE)) {
      std::ostringstream msg;
      msg << "is not a valid correlation matrix. " << name << "("
          << stan::error_index::value + k << "," << stan::error_index::value + k
          << ") is ";
      std::string msg_str(msg.str());
      domain_error(function, name, y(k, k), msg_str.c_str(),
                   ", but should be near 1.0");
    }
  }
  check_pos_definite(function, "y", y);
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>Replace check_size_match with check_square<commit_after>#ifndef STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP
#define STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/prim/scal/err/check_positive.hpp>
#include <stan/math/prim/mat/err/check_pos_definite.hpp>
#include <stan/math/prim/mat/err/check_square.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <sstream>
#include <string>

namespace stan {
namespace math {

/**
 * Check if the specified matrix is a valid correlation matrix.
 * A valid correlation matrix is symmetric, has a unit diagonal
 * (all 1 values), and has all values between -1 and 1
 * (inclusive).
 * This function throws exceptions if the variable is not a valid
 * correlation matrix.
 * @tparam T_y Type of scalar
 * @param function Name of the function this was called from
 * @param name Name of the variable
 * @param y Matrix to test
 * @throw std::invalid_argument if the matrix is not square
 *   or if the matrix is 0x0
 * @throw std::domain_error if the matrix is non-symmetric,
 *   diagonals not near 1, not positive definite, or any of the
 *   elements nan
 */
template <typename T_y>
inline void check_corr_matrix(
    const char* function, const char* name,
    const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y) {
  using size_type = typename index_type<
      Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic> >::type;

  check_square(function, name, y);
  check_positive(function, name, "rows", y.rows());

  for (size_type k = 0; k < y.rows(); ++k) {
    if (!(fabs(y(k, k) - 1.0) <= CONSTRAINT_TOLERANCE)) {
      std::ostringstream msg;
      msg << "is not a valid correlation matrix. " << name << "("
          << stan::error_index::value + k << "," << stan::error_index::value + k
          << ") is ";
      std::string msg_str(msg.str());
      domain_error(function, name, y(k, k), msg_str.c_str(),
                   ", but should be near 1.0");
    }
  }
  check_pos_definite(function, "y", y);
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_CORE_SCOPED_CHAINABLESTACK_HPP
#define STAN_MATH_REV_CORE_SCOPED_CHAINABLESTACK_HPP

#include <stan/math/rev/core/chainablestack.hpp>

#include <vector>

namespace stan {
namespace math {

/**
 * The AD tape of reverse mode AD is by default stored globally within the
 * process (or thread). With the ScopedChainableStack class one may execute a
 * nullary functor with reference to an AD tape which is stored with the
 * instance of ScopedChainableStack. Example:
 *
 * ScopedChainableStack scoped_stack;
 *
 * double cgrad = scoped_stack.execute([] {
 *   var a = 1;
 *   var b = 4;
 *   var c = a + b;
 *   grad();
 *   return c.adj();
 * });
 *
 * Doing so will not interfere with the process (or thread) AD tape.
 */
class ScopedChainableStack {
  ChainableStack::AutodiffStackStorage local_stack_;

  std::vector<ChainableStack::AutodiffStackStorage*> stack_queue_;

  struct activate_scope {
    ScopedChainableStack& scoped_stack_;

    explicit activate_scope(ScopedChainableStack& scoped_stack)
        : scoped_stack_(scoped_stack) {
      scoped_stack_.stack_queue_.push_back(ChainableStack::instance_);
      ChainableStack::instance_ = &scoped_stack_.local_stack_;
    }

    ~activate_scope() {
      ChainableStack::instance_ = scoped_stack_.stack_queue_.back();
      scoped_stack_.stack_queue_.pop_back();
    }
  };

 public:
  ScopedChainableStack() = default;

  // Execute in the current thread a nullary function and write the AD
  // tape to local_stack_ of this instance. The function may return
  // any type.
  template <typename F>
  auto execute(F&& f) {
    activate_scope active_scope(*this);
    return std::forward<F>(f)();
  }
};

}  // namespace math
}  // namespace stan
#endif
<commit_msg>add doxygen doc<commit_after>#ifndef STAN_MATH_REV_CORE_SCOPED_CHAINABLESTACK_HPP
#define STAN_MATH_REV_CORE_SCOPED_CHAINABLESTACK_HPP

#include <stan/math/rev/core/chainablestack.hpp>

#include <vector>

namespace stan {
namespace math {

/**
 * The AD tape of reverse mode AD is by default stored globally within the
 * process (or thread). With the ScopedChainableStack class one may execute a
 * nullary functor with reference to an AD tape which is stored with the
 * instance of ScopedChainableStack. Example:
 *
 * ScopedChainableStack scoped_stack;
 *
 * double cgrad = scoped_stack.execute([] {
 *   var a = 1;
 *   var b = 4;
 *   var c = a + b;
 *   grad();
 *   return c.adj();
 * });
 *
 * Doing so will not interfere with the process (or thread) AD tape.
 */
class ScopedChainableStack {
  ChainableStack::AutodiffStackStorage local_stack_;

  std::vector<ChainableStack::AutodiffStackStorage*> stack_queue_;

  struct activate_scope {
    ScopedChainableStack& scoped_stack_;

    explicit activate_scope(ScopedChainableStack& scoped_stack)
        : scoped_stack_(scoped_stack) {
      scoped_stack_.stack_queue_.push_back(ChainableStack::instance_);
      ChainableStack::instance_ = &scoped_stack_.local_stack_;
    }

    ~activate_scope() {
      ChainableStack::instance_ = scoped_stack_.stack_queue_.back();
      scoped_stack_.stack_queue_.pop_back();
    }
  };

 public:
  ScopedChainableStack() = default;

  /**
   * Execute in the current thread a nullary function and write the AD
   * tape to local_stack_ of this instance. The function may return
   * any type.
   *
   * @tparam F nullary functor to evaluate
   * @param f instance of nullary functor
   * @return Result of evaluated functor
   */
  template <typename F>
  auto execute(F&& f) {
    activate_scope active_scope(*this);
    return std::forward<F>(f)();
  }
};

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#include "FileAdapter.h"
#include <OpenSim/Common/IO.h>

namespace OpenSim {

std::shared_ptr<DataAdapter>
createSTOFileAdapterForReading(const std::string&);

std::shared_ptr<DataAdapter>
createSTOFileAdapterForWriting(const DataAdapter::InputTables&);

FileAdapter::OutputTables
FileAdapter::readFile(const std::string& fileName) {
    auto extension = findExtension(fileName);
    std::shared_ptr<DataAdapter> dataAdapter{};
    if(extension == "sto")
        dataAdapter = createSTOFileAdapterForReading(fileName);
    else
        dataAdapter = createAdapter(extension);
    auto& fileAdapter = static_cast<FileAdapter&>(*dataAdapter);
    return fileAdapter.extendRead(fileName);
}

void
FileAdapter::writeFile(const InputTables& tables,
                       const std::string& fileName) {
    auto extension = findExtension(fileName);
    std::shared_ptr<DataAdapter> dataAdapter{};
    if(extension == "sto")
        dataAdapter = createSTOFileAdapterForWriting(tables);
    else
        dataAdapter = createAdapter(extension);
    auto& fileAdapter = static_cast<FileAdapter&>(*dataAdapter);
    fileAdapter.extendWrite(tables, fileName);
}

std::string
FileAdapter::findExtension(const std::string& filename) {
    std::size_t found = filename.find_last_of('.');

    OPENSIM_THROW_IF(found == std::string::npos,
                     FileExtensionNotFound,
                     filename);

    auto ext = filename.substr(found + 1);
    std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
    return ext;
}

std::vector<std::string>
FileAdapter::tokenize(const std::string& str,
                      const std::string& delims) {
    using size_type = std::string::size_type;

    std::vector<std::string> tokens{};
    std::string token;

    size_type token_start{0}, token_end{ std::string::npos };
    while((token_end = str.find_first_of(delims, token_start)) != std::string::npos) {
        if (token_end >= token_start) {
            token = str.substr(token_start, token_end - token_start);
            OpenSim::IO::TrimWhitespace(token);
            tokens.push_back(token);
            token_start = token_end;
        }
        ++token_start;
    }
    // end has reach std::string::npos, so now peg it at end of the string
    token_end = str.size();
    //capture from last delimiter to the end of string that is not empty
    if (token_end > token_start) {
        token = str.substr(token_start, token_end - token_start);
        OpenSim::IO::TrimWhitespace(token);
        tokens.push_back(token);
    }
    return tokens;
}

std::vector<std::string>
FileAdapter::getNextLine(std::istream& stream,
                         const std::string& delims) {
    std::string line{};
    if(std::getline(stream, line)) {
        // Get rid of the extra \r if parsing a file with CRLF line endings.
        if (!line.empty() && line.back() == '\r')
            line.pop_back();

        auto tokens = tokenize(line, delims);
        if(tokens.size() > 0)
            return tokens;
    }
    return {};
}

} // namespace OpenSim
<commit_msg>Eliminate unnecessary if statement and update comments.<commit_after>#include "FileAdapter.h"
#include <OpenSim/Common/IO.h>

namespace OpenSim {

std::shared_ptr<DataAdapter>
createSTOFileAdapterForReading(const std::string&);

std::shared_ptr<DataAdapter>
createSTOFileAdapterForWriting(const DataAdapter::InputTables&);

FileAdapter::OutputTables
FileAdapter::readFile(const std::string& fileName) {
    auto extension = findExtension(fileName);
    std::shared_ptr<DataAdapter> dataAdapter{};
    if(extension == "sto")
        dataAdapter = createSTOFileAdapterForReading(fileName);
    else
        dataAdapter = createAdapter(extension);
    auto& fileAdapter = static_cast<FileAdapter&>(*dataAdapter);
    return fileAdapter.extendRead(fileName);
}

void
FileAdapter::writeFile(const InputTables& tables,
                       const std::string& fileName) {
    auto extension = findExtension(fileName);
    std::shared_ptr<DataAdapter> dataAdapter{};
    if(extension == "sto")
        dataAdapter = createSTOFileAdapterForWriting(tables);
    else
        dataAdapter = createAdapter(extension);
    auto& fileAdapter = static_cast<FileAdapter&>(*dataAdapter);
    fileAdapter.extendWrite(tables, fileName);
}

std::string
FileAdapter::findExtension(const std::string& filename) {
    std::size_t found = filename.find_last_of('.');

    OPENSIM_THROW_IF(found == std::string::npos,
                     FileExtensionNotFound,
                     filename);

    auto ext = filename.substr(found + 1);
    std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
    return ext;
}

std::vector<std::string>
FileAdapter::tokenize(const std::string& str,
                      const std::string& delims) {
    using size_type = std::string::size_type;

    std::vector<std::string> tokens{};
    std::string token;

    size_type token_start{0}, token_end{ std::string::npos };
    while((token_end = str.find_first_of(delims, token_start))
                    != std::string::npos) {
        token = str.substr(token_start, token_end - token_start);
        OpenSim::IO::TrimWhitespace(token);
        tokens.push_back(token);
        token_start = token_end;
        ++token_start;
    }
    // reached std::string::npos, now set token_end to be the end of the string
    token_end = str.size();
    //capture from last delimiter to the end of string that is not empty
    if (token_end > token_start) {
        token = str.substr(token_start, token_end - token_start);
        OpenSim::IO::TrimWhitespace(token);
        tokens.push_back(token);
    }
    return tokens;
}

std::vector<std::string>
FileAdapter::getNextLine(std::istream& stream,
                         const std::string& delims) {
    std::string line{};
    if(std::getline(stream, line)) {
        // Get rid of the extra \r if parsing a file with CRLF line endings.
        if (!line.empty() && line.back() == '\r')
            line.pop_back();

        auto tokens = tokenize(line, delims);
        if(tokens.size() > 0)
            return tokens;
    }
    return {};
}

} // namespace OpenSim
<|endoftext|>