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

* Author:            wanzhongping
* Date:              2021-03-17 16:05:37
* Email:             zhongpingw@chinadci.com
* copyright:         广州城市信息研究所有限公司
***************************************************************************/

#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();
  }

  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;
  }