/*
|
/*
|
* Copyright (c) 2016 by Alex I. Kuznetsov.
|
* Copyright (c) 2016 by Alex I. Kuznetsov.
|
*
|
*
|
* Part of the LXP32 CPU IP core.
|
* Part of the LXP32 CPU IP core.
|
*
|
*
|
* This module implements members of the Utils namespace.
|
* This module implements members of the Utils namespace.
|
*/
|
*/
|
|
|
#include "utils.h"
|
#include "utils.h"
|
|
|
#include <iostream>
|
#include <iostream>
|
#include <fstream>
|
#include <fstream>
|
#include <algorithm>
|
#include <algorithm>
|
#include <stdexcept>
|
#include <stdexcept>
|
#include <cstring>
|
#include <cstring>
|
|
|
std::string Utils::urlEncode(const std::string &str) {
|
std::string Utils::urlEncode(const std::string &str) {
|
std::string res;
|
std::string res;
|
for(std::size_t i=0;i<str.size();i++) {
|
for(std::size_t i=0;i<str.size();i++) {
|
char ch=str[i];
|
char ch=str[i];
|
if(ch>='A'&&ch<='Z') res.push_back(ch);
|
if(ch>='A'&&ch<='Z') res.push_back(ch);
|
else if(ch>='a'&&ch<='z') res.push_back(ch);
|
else if(ch>='a'&&ch<='z') res.push_back(ch);
|
else if(ch>='0'&&ch<='9') res.push_back(ch);
|
else if(ch>='0'&&ch<='9') res.push_back(ch);
|
else if(ch=='-'||ch=='_'||ch=='.'||ch=='~') res.push_back(ch);
|
else if(ch=='-'||ch=='_'||ch=='.'||ch=='~') res.push_back(ch);
|
else res+="%"+hex(ch);
|
else res+="%"+hex(ch);
|
}
|
}
|
return res;
|
return res;
|
}
|
}
|
|
|
std::string Utils::urlDecode(const std::string &str) {
|
std::string Utils::urlDecode(const std::string &str) {
|
std::string res;
|
std::string res;
|
for(std::size_t i=0;i<str.size();i++) {
|
for(std::size_t i=0;i<str.size();i++) {
|
char ch=str[i];
|
char ch=str[i];
|
if(ch!='%') res.push_back(ch);
|
if(ch!='%') res.push_back(ch);
|
else {
|
else {
|
auto hexcode=str.substr(i+1,2);
|
auto hexcode=str.substr(i+1,2);
|
i+=hexcode.size();
|
i+=hexcode.size();
|
try {
|
try {
|
if(hexcode.size()!=2) throw std::exception();
|
if(hexcode.size()!=2) throw std::exception();
|
auto u=static_cast<unsigned char>(std::stoul(hexcode,nullptr,16));
|
auto u=static_cast<unsigned char>(std::stoul(hexcode,nullptr,16));
|
res.push_back(static_cast<char>(u));
|
res.push_back(static_cast<char>(u));
|
}
|
}
|
catch(std::exception &) {
|
catch(std::exception &) {
|
throw std::runtime_error("Ill-formed URL-encoded string");
|
throw std::runtime_error("Ill-formed URL-encoded string");
|
}
|
}
|
}
|
}
|
}
|
}
|
return res;
|
return res;
|
}
|
}
|
|
|
std::string Utils::normalizeSeparators(const std::string &path) {
|
std::string Utils::normalizeSeparators(const std::string &path) {
|
std::string str(path);
|
std::string str(path);
|
#ifdef _WIN32
|
#ifdef _WIN32
|
std::replace(str.begin(),str.end(),'\\','/');
|
std::replace(str.begin(),str.end(),'\\','/');
|
#endif
|
#endif
|
return str;
|
return str;
|
}
|
}
|
|
|
std::string Utils::nativeSeparators(const std::string &path) {
|
std::string Utils::nativeSeparators(const std::string &path) {
|
std::string str(path);
|
std::string str(path);
|
#ifdef _WIN32
|
#ifdef _WIN32
|
std::replace(str.begin(),str.end(),'/','\\');
|
std::replace(str.begin(),str.end(),'/','\\');
|
#endif
|
#endif
|
return str;
|
return str;
|
}
|
}
|
|
|
bool Utils::isAbsolutePath(const std::string &path) {
|
bool Utils::isAbsolutePath(const std::string &path) {
|
auto native=nativeSeparators(path);
|
auto native=nativeSeparators(path);
|
if(native.empty()) return false;
|
if(native.empty()) return false;
|
if(native[0]=='/') return true;
|
if(native[0]=='/') return true;
|
#ifdef _WIN32
|
#ifdef _WIN32
|
if(native.size()>1&&native[1]==':') return true;
|
if(native.size()>1&&native[1]==':') return true;
|
#endif
|
#endif
|
return false;
|
return false;
|
}
|
}
|
|
|
bool Utils::fileExists(const std::string &path) {
|
bool Utils::fileExists(const std::string &path) {
|
std::ifstream in(nativeSeparators(path),std::ios_base::in);
|
std::ifstream in(nativeSeparators(path),std::ios_base::in);
|
if(!in) return false;
|
if(!in) return false;
|
return true;
|
return true;
|
}
|
}
|
|
|
std::string Utils::relativePath(const std::string &from,const std::string &to) {
|
std::string Utils::relativePath(const std::string &from,const std::string &to) {
|
// Normalize directory separators
|
// Normalize directory separators
|
auto nfrom=normalizeSeparators(from);
|
auto nfrom=normalizeSeparators(from);
|
auto nto=normalizeSeparators(to);
|
auto nto=normalizeSeparators(to);
|
|
|
if(nto.empty()) return std::string();
|
if(nto.empty()) return std::string();
|
|
|
// If "nto" is an absolute path, just return it
|
// If "nto" is an absolute path, just return it
|
if(isAbsolutePath(nto)) return nativeSeparators(nto);
|
if(isAbsolutePath(nto)) return nativeSeparators(nto);
|
|
|
// Process relative path
|
// Process relative path
|
auto pos=nfrom.find_last_of('/');
|
auto pos=nfrom.find_last_of('/');
|
if(pos==std::string::npos) return nativeSeparators(nto);
|
if(pos==std::string::npos) return nativeSeparators(nto);
|
else return nativeSeparators(nfrom.substr(0,pos+1)+nto);
|
else return nativeSeparators(nfrom.substr(0,pos+1)+nto);
|
}
|
}
|
|
|
std::string Utils::dequoteString(const std::string &str) {
|
std::string Utils::dequoteString(const std::string &str) {
|
if(str.size()<2) throw std::runtime_error("String literal expected");
|
if(str.size()<2) throw std::runtime_error("String literal expected");
|
if(str.front()!='\"'||str.back()!='\"') throw std::runtime_error("String literal expected");
|
if(str.front()!='\"'||str.back()!='\"') throw std::runtime_error("String literal expected");
|
return str.substr(1,str.size()-2);
|
return str.substr(1,str.size()-2);
|
}
|
}
|
|
|
bool Utils::ishexdigit(char ch) {
|
bool Utils::ishexdigit(char ch) {
|
static const char *digits="0123456789ABCDEFabcdef";
|
static const char *digits="0123456789ABCDEFabcdef";
|
return (std::strchr(digits,ch)!=NULL);
|
return (std::strchr(digits,ch)!=NULL);
|
}
|
}
|
|
|
bool Utils::isoctdigit(char ch) {
|
bool Utils::isoctdigit(char ch) {
|
static const char *digits="01234567";
|
static const char *digits="01234567";
|
return (std::strchr(digits,ch)!=NULL);
|
return (std::strchr(digits,ch)!=NULL);
|
}
|
}
|
|
|