dmpserverutils.cpp 5.5 KB
/**************************************************************************
* file:              dmpserverutils.cpp

* Author:            wanzhongping
* Date:              2021-03-17 16:05:37
* Email:             zhongpingw@chinadci.com
* copyright:         广州城市信息研究所有限公司
***************************************************************************/
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include "dmpserverutils.h"

  int DmpServerUtils::GetLibraryPaths(const boost::filesystem::path &dir, std::vector<boost::filesystem::path> &locations)
  {
    if (!boost::filesystem::exists(dir))
    {
      return -1;
    }

    std::string dllExt(".dll");
#ifdef IS_WINDOWS
    dllExt = ".dll";
#elif IS_LINUX
    dllExt = ".so";
#else
    dllExt = ".dll";
#endif

    boost::filesystem::directory_iterator end_iter;
    for (boost::filesystem::directory_iterator iter(dir); iter != end_iter; ++iter)
    {
      if (boost::filesystem::is_regular_file(iter->status()) && iter->path().extension() == dllExt)
      {
        locations.push_back(iter->path());
      }

      if (boost::filesystem::is_directory(iter->status()))
      {
        GetLibraryPaths(iter->path(), locations);
      }
    }

    return locations.size();
  }
  
bool DmpServerUtils::Base64Encode(const std::string& input, std::string* output) {
	typedef boost::archive::iterators::base64_from_binary<boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8> > Base64EncodeIterator;
	std::stringstream result;
	copy(Base64EncodeIterator(input.begin()),Base64EncodeIterator(input.end()), std::ostream_iterator<char>(result));
	size_t equal_count = (3 - input.length() % 3) % 3;
	for (size_t i = 0; i < equal_count; i++) {
		result.put('=');
	}
	*output = result.str();
	return output->empty() == false;
}
 
bool DmpServerUtils::Base64Decode(const std::string& input, std::string* output) {
	typedef boost::archive::iterators::transform_width<boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6> Base64DecodeIterator;
	std::stringstream result;
	try {
		copy(Base64DecodeIterator(input.begin()), Base64DecodeIterator(input.end()), std::ostream_iterator<char>(result));
	}
	catch (...) {
		return false;
	}
	*output = result.str();
	return output->empty() == false;
}
  std::string Percent::encode(const std::string &value) noexcept {
    static auto hex_chars = "0123456789ABCDEF";

    std::string result;
    result.reserve(value.size()); // Minimum size of result

    for(auto &chr : value) {
      if(!((chr >= '0' && chr <= '9') || (chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z') || chr == '-' || chr == '.' || chr == '_' || chr == '~'))
        result += std::string("%") + hex_chars[static_cast<unsigned char>(chr) >> 4] + hex_chars[static_cast<unsigned char>(chr) & 15];
      else
        result += chr;
    }

    return result;
  }

  // Returns percent-decoded string
  std::string Percent::decode(const std::string &value) noexcept {
    std::string result;
    result.reserve(value.size() / 3 + (value.size() % 3)); // Minimum size of result

    for(std::size_t i = 0; i < value.size(); ++i) {
      auto &chr = value[i];
      if(chr == '%' && i + 2 < value.size()) {
        auto hex = value.substr(i + 1, 2);
        auto decoded_chr = static_cast<char>(std::strtol(hex.c_str(), nullptr, 16));
        result += decoded_chr;
        i += 2;
      }
      else if(chr == '+')
        result += ' ';
      else
        result += chr;
    }
    return result;
  }


  // Returns query string created from given field names and values
  std::string QueryString::create(const CIMap &fields) noexcept {
    std::string result;

    bool first = true;
    for(auto &field : fields) {
      result += (!first ? "&" : "") + field.first + '=' + Percent::encode(field.second);
      first = false;
    }
    
    return result;
  }

  // Returns query keys with percent-decoded values.
  CIMap QueryString::parse(const std::string &query_string) noexcept {
    CIMap result;

    if(query_string.empty())
      return result;

    std::size_t name_pos = 0;
    auto name_end_pos = std::string::npos;
    auto value_pos = std::string::npos;
    for(std::size_t c = 0; c < query_string.size(); ++c) {
      if(query_string[c] == '&') {
        auto name = query_string.substr(name_pos, (name_end_pos == std::string::npos ? c : name_end_pos) - name_pos);
        if(!name.empty()) {
          auto value = value_pos == std::string::npos ? std::string() : query_string.substr(value_pos, c - value_pos);
          result.emplace(std::move(name), Percent::decode(value));
        }
        name_pos = c + 1;
        name_end_pos = std::string::npos;
        value_pos = std::string::npos;
      }
      else if(query_string[c] == '=' && name_end_pos == std::string::npos) {
        name_end_pos = c;
        value_pos = c + 1;
      }
    }
    if(name_pos < query_string.size()) {
      auto name = query_string.substr(name_pos, (name_end_pos == std::string::npos ? std::string::npos : name_end_pos - name_pos));
      if(!name.empty()) {
        auto value = value_pos >= query_string.size() ? std::string() : query_string.substr(value_pos);
        result.emplace(std::move(name), Percent::decode(value));
      }
    }
    return result;
  }