text: /**
   * Copyright (C) 2018, 2020-2022 Xilinx, Inc
   *
   * Licensed under the Apache License, Version 2.0 (the "License"). You may
   * not use this file except in compliance with the License. A copy of the
   * License is located at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   * License for the specific language governing permissions and limitations
   * under the License.
   */
  
  #ifndef __XclBinUtilities_h_
  #define __XclBinUtilities_h_
  
  // Include files
  #include "xclbin.h"
  
  #include <boost/filesystem.hpp>
  #include <boost/format.hpp>
  #include <boost/property_tree/ptree.hpp>
  #include <fstream>
  #include <iostream>
  #include <memory>
  #include <sstream>
  #include <sstream>
  #include <stdint.h>
  #include <string>
  #include <vector>
  
  
  class XclBin;
  
  // Custom exception with payloads
  typedef enum {
    xet_runtime = 1,           // Generic Runtime error (1)
    xet_missing_section = 100, // Section is missing
  } XclBinExceptionType;
  
  namespace XclBinUtilities {
  
  template <typename T>
  std::vector<T> as_vector(boost::property_tree::ptree const& pt, 
                           boost::property_tree::ptree::key_type const& key)
  {
      std::vector<T> r;
  
      boost::property_tree::ptree::const_assoc_iterator it = pt.find(key);
  
      if( it != pt.not_found()) {
        for (auto& item : pt.get_child(key)) {
          r.push_back(item.second);
        }
      }
      return r;
  }
  
  // This template will eventually replace "as_vector"
  // The issue is that the code needs to be refactored to use this new template
  template <typename T>
  std::vector<T> as_vector_simple(const boost::property_tree::ptree& pt, 
                                  const boost::property_tree::ptree::key_type& key)
  {
    static const boost::property_tree::ptree ptEmpty;
    std::vector<T> r;
  
    for (auto& item : pt.get_child(key, ptEmpty))
        r.push_back(item.second.get_value<T>());
    return r;
  }
  
  
  class XclBinUtilException : public std::runtime_error {
    private:
      std::string m_msg;
      std::string m_file;
      int m_line;
      std::string m_function;
      XclBinExceptionType m_eExceptionType;
  
  public:
      XclBinUtilException(XclBinExceptionType _eExceptionType,
                          const std::string & _msg,
                          const char * _function = "<not_defined>", 
                          const char * _file = __FILE__,
                          int _line = __LINE__)
      : std::runtime_error(_msg)
      , m_msg(_msg)
      , m_file(_file)
      , m_line(_line)
      , m_function(_function)
      , m_eExceptionType(_eExceptionType) {
        // Empty
      }
  
      ~XclBinUtilException() 
      {
        // Empty
      }
  
      // Use are version of what() and not runtime_error's
      const char* what() const noexcept override{
        return m_msg.c_str();
      }
  
      const char *file() const {
        return m_file.c_str();
      }
  
      int line() const throw() {
        return m_line;
      }
  
      const char *function() const {
        return m_function.c_str();
      }
  
      XclBinExceptionType exceptionType() const {
        return m_eExceptionType;
      }
  };
  
  struct SignatureHeader {
     unsigned char magicValue[16];   // Magic Signature Value 5349474E-9DFF41C0-8CCB82A7-131CC9F3
     unsigned char padding[8]  ;     // Future variables. Initialized to zero.
     unsigned int signedByOffset;    // The offset string by whom it was signed by
     unsigned int signedBySize;      // The size of the signature
     unsigned int signatureOffset;   // The offset string of the signature
     unsigned int signatureSize;     // The size of the signature
     unsigned int totalSignatureSize;// Total size of this structure and strings
  };
  
  void addSignature(const std::string& _sInputFile, const std::string& _sOutputFile, const std::string& _sSignature, const std::string& _sSignedBy);
  void reportSignature(const std::string& _sInputFile);
  void removeSignature(const std::string& _sInputFile, const std::string& _sOutputFile);
  bool getSignature(std::fstream& _istream, std::string& _sSignature, std::string& _sSignedBy, unsigned int & _totalSize);
  
  bool findBytesInStream(std::fstream& _istream, const std::string& _searchString, unsigned int& _foundOffset);
  void setVerbose(bool _bVerbose);
  bool getVerbose();
  void setQuiet(bool _bQuiet);
  bool isQuiet();
  
  void QUIET(const std::string& _msg);
  void QUIET(const boost::format & fmt);
  void TRACE(const std::string& _msg, bool _endl = true);
  void TRACE(const boost::format & fmt, bool _endl = true);
  void TRACE_PrintTree(const std::string& _msg, const boost::property_tree::ptree& _pt);
  void TRACE_BUF(const std::string& _msg, const char* _pData, uint64_t _size);
  
  void safeStringCopy(char* _destBuffer, const std::string& _source, unsigned int _bufferSize);
  unsigned int bytesToAlign(uint64_t _offset);
  unsigned int alignBytes(std::ostream & _buf, unsigned int _byteBoundary);
  
  void binaryBufferToHexString(const unsigned char* _binBuf, uint64_t _size, std::string& _outputString);
  void hexStringToBinaryBuffer(const std::string& _inputString, unsigned char* _destBuf, unsigned int _bufferSize);
  uint64_t stringToUInt64(const std::string& _sInteger, bool _bForceHex = false);
  void printKinds();
  std::string getUUIDAsString( const unsigned char (&_uuid)[16] );
  
  int exec(const boost::filesystem::path &cmd, const std::vector<std::string> &args, bool bThrow, std::ostringstream & os_stdout, std::ostringstream & os_stderr);
  void write_htonl(std::ostream & _buf, uint32_t _word32);
  
  void createMemoryBankGrouping(XclBin & xclbin);
  };
  
  #endif
  