mirror of https://github.com/x64dbg/btparser
removed some dependencies
This commit is contained in:
parent
5c666ffce9
commit
87003fef8d
|
@ -19,21 +19,16 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="filehelper.cpp" />
|
|
||||||
<ClCompile Include="lexer.cpp" />
|
<ClCompile Include="lexer.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="parser.cpp" />
|
<ClCompile Include="parser.cpp" />
|
||||||
<ClCompile Include="stringutils.cpp" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ast.h" />
|
<ClInclude Include="ast.h" />
|
||||||
<ClInclude Include="dynamicmem.h" />
|
<ClInclude Include="helpers.h" />
|
||||||
<ClInclude Include="filehelper.h" />
|
|
||||||
<ClInclude Include="handle.h" />
|
|
||||||
<ClInclude Include="keywords.h" />
|
<ClInclude Include="keywords.h" />
|
||||||
<ClInclude Include="lexer.h" />
|
<ClInclude Include="lexer.h" />
|
||||||
<ClInclude Include="operators.h" />
|
<ClInclude Include="operators.h" />
|
||||||
<ClInclude Include="stringutils.h" />
|
|
||||||
<ClInclude Include="testfiles.h" />
|
<ClInclude Include="testfiles.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="filehelper.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="stringutils.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="lexer.cpp">
|
<ClCompile Include="lexer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -32,21 +26,9 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="filehelper.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="testfiles.h">
|
<ClInclude Include="testfiles.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="dynamicmem.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="handle.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="stringutils.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="keywords.h">
|
<ClInclude Include="keywords.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -59,6 +41,9 @@
|
||||||
<ClInclude Include="ast.h">
|
<ClInclude Include="ast.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="helpers.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="parser.h">
|
<None Include="parser.h">
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
static void* emalloc(size_t size)
|
|
||||||
{
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void efree(void* ptr)
|
|
||||||
{
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* erealloc(void* ptr, size_t size)
|
|
||||||
{
|
|
||||||
return realloc(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class Memory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//
|
|
||||||
// This class guarantees that the returned allocated memory
|
|
||||||
// will always be zeroed
|
|
||||||
//
|
|
||||||
explicit Memory(const char* Reason = "Memory:???")
|
|
||||||
{
|
|
||||||
m_Ptr = nullptr;
|
|
||||||
m_Size = 0;
|
|
||||||
m_Reason = Reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Memory(size_t Size, const char* Reason = "Memory:???")
|
|
||||||
{
|
|
||||||
m_Ptr = reinterpret_cast<T>(emalloc(Size));
|
|
||||||
m_Size = Size;
|
|
||||||
m_Reason = Reason;
|
|
||||||
|
|
||||||
memset(m_Ptr, 0, Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Memory()
|
|
||||||
{
|
|
||||||
if(m_Ptr)
|
|
||||||
efree(m_Ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
T realloc(size_t Size, const char* Reason = "Memory:???")
|
|
||||||
{
|
|
||||||
m_Ptr = reinterpret_cast<T>(erealloc(m_Ptr, Size));
|
|
||||||
m_Size = Size;
|
|
||||||
m_Reason = Reason;
|
|
||||||
|
|
||||||
return (T)memset(m_Ptr, 0, m_Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return m_Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
T operator()()
|
|
||||||
{
|
|
||||||
return m_Ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T m_Ptr;
|
|
||||||
size_t m_Size;
|
|
||||||
const char* m_Reason;
|
|
||||||
};
|
|
|
@ -1,43 +0,0 @@
|
||||||
#include "filehelper.h"
|
|
||||||
#include "handle.h"
|
|
||||||
#include "stringutils.h"
|
|
||||||
|
|
||||||
bool FileHelper::ReadAllData(const String & fileName, std::vector<unsigned char> & content)
|
|
||||||
{
|
|
||||||
Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
|
||||||
if(hFile == INVALID_HANDLE_VALUE)
|
|
||||||
return false;
|
|
||||||
unsigned int filesize = GetFileSize(hFile, nullptr);
|
|
||||||
if(!filesize)
|
|
||||||
{
|
|
||||||
content.clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
content.resize(filesize);
|
|
||||||
DWORD read = 0;
|
|
||||||
return !!ReadFile(hFile, content.data(), filesize, &read, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileHelper::WriteAllData(const String & fileName, const void* data, size_t size)
|
|
||||||
{
|
|
||||||
Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr);
|
|
||||||
if(hFile == INVALID_HANDLE_VALUE)
|
|
||||||
return false;
|
|
||||||
DWORD written = 0;
|
|
||||||
return !!WriteFile(hFile, data, DWORD(size), &written, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileHelper::ReadAllText(const String & fileName, String & content)
|
|
||||||
{
|
|
||||||
std::vector<unsigned char> data;
|
|
||||||
if(!ReadAllData(fileName, data))
|
|
||||||
return false;
|
|
||||||
data.push_back(0);
|
|
||||||
content = String((const char*)data.data());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileHelper::WriteAllText(const String & fileName, const String & content)
|
|
||||||
{
|
|
||||||
return WriteAllData(fileName, content.c_str(), content.length());
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef _FILEREADER_H
|
|
||||||
#define _FILEREADER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using String = std::string;
|
|
||||||
|
|
||||||
class FileHelper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static bool ReadAllData(const String & fileName, std::vector<unsigned char> & content);
|
|
||||||
static bool WriteAllData(const String & fileName, const void* data, size_t size);
|
|
||||||
static bool ReadAllText(const String & fileName, String & content);
|
|
||||||
static bool WriteAllText(const String & fileName, const String & content);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_FILEREADER_H
|
|
|
@ -1,51 +0,0 @@
|
||||||
#ifndef _HANDLE_H
|
|
||||||
#define _HANDLE_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
class Handle
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Handle(HANDLE h = nullptr)
|
|
||||||
{
|
|
||||||
mHandle = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Handle()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Close()
|
|
||||||
{
|
|
||||||
DWORD dwFlags = 0;
|
|
||||||
if(GetHandleInformation(mHandle, &dwFlags) && !(dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE))
|
|
||||||
CloseHandle(mHandle);
|
|
||||||
mHandle = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const HANDLE & operator=(const HANDLE & h)
|
|
||||||
{
|
|
||||||
return mHandle = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator HANDLE & ()
|
|
||||||
{
|
|
||||||
return mHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!() const
|
|
||||||
{
|
|
||||||
return (!mHandle || mHandle == INVALID_HANDLE_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
|
||||||
{
|
|
||||||
return !this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HANDLE mHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_HANDLE_H
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace StringUtils
|
||||||
|
{
|
||||||
|
static std::string sprintf(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
std::vector<char> buffer(256, '\0');
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
int res = _vsnprintf_s(buffer.data(), buffer.size(), _TRUNCATE, format, args);
|
||||||
|
if(res == -1)
|
||||||
|
{
|
||||||
|
buffer.resize(buffer.size() * 2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
return std::string(buffer.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string Escape(const std::string & s)
|
||||||
|
{
|
||||||
|
auto escape = [](unsigned char ch) -> std::string
|
||||||
|
{
|
||||||
|
char buf[8] = "";
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
return "\\0";
|
||||||
|
case '\t':
|
||||||
|
return "\\t";
|
||||||
|
case '\f':
|
||||||
|
return "\\f";
|
||||||
|
case '\v':
|
||||||
|
return "\\v";
|
||||||
|
case '\n':
|
||||||
|
return "\\n";
|
||||||
|
case '\r':
|
||||||
|
return "\\r";
|
||||||
|
case '\\':
|
||||||
|
return "\\\\";
|
||||||
|
case '\"':
|
||||||
|
return "\\\"";
|
||||||
|
default:
|
||||||
|
if(!isprint(ch)) //unknown unprintable character
|
||||||
|
sprintf_s(buf, "\\x%02X", ch);
|
||||||
|
else
|
||||||
|
*buf = ch;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::string escaped;
|
||||||
|
escaped.reserve(s.length() + s.length() / 2);
|
||||||
|
for(size_t i = 0; i < s.length(); i++)
|
||||||
|
escaped.append(escape((unsigned char)s[i]));
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string Utf16ToUtf8(const std::wstring & wstr)
|
||||||
|
{
|
||||||
|
std::string convertedString;
|
||||||
|
auto requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||||
|
if(requiredSize > 0)
|
||||||
|
{
|
||||||
|
std::vector<char> buffer(requiredSize);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, nullptr, nullptr);
|
||||||
|
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
||||||
|
}
|
||||||
|
return convertedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::wstring Utf8ToUtf16(const std::string & str)
|
||||||
|
{
|
||||||
|
std::wstring convertedString;
|
||||||
|
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
||||||
|
if(requiredSize > 0)
|
||||||
|
{
|
||||||
|
std::vector<wchar_t> buffer(requiredSize);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
|
||||||
|
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
||||||
|
}
|
||||||
|
return convertedString;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace FileHelper
|
||||||
|
{
|
||||||
|
static bool ReadAllData(const std::string & fileName, std::vector<uint8_t> & content)
|
||||||
|
{
|
||||||
|
auto hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
|
auto result = false;
|
||||||
|
if(hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
unsigned int filesize = GetFileSize(hFile, nullptr);
|
||||||
|
if(!filesize)
|
||||||
|
{
|
||||||
|
content.clear();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content.resize(filesize);
|
||||||
|
DWORD read = 0;
|
||||||
|
result = !!ReadFile(hFile, content.data(), filesize, &read, nullptr);
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool WriteAllData(const std::string & fileName, const void* data, size_t size)
|
||||||
|
{
|
||||||
|
auto hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||||
|
auto result = false;
|
||||||
|
if(hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
result = !!WriteFile(hFile, data, DWORD(size), &written, nullptr);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ReadAllText(const std::string & fileName, std::string & content)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
if(!ReadAllData(fileName, data))
|
||||||
|
return false;
|
||||||
|
data.push_back(0);
|
||||||
|
content = std::string((const char*)data.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool WriteAllText(const std::string & fileName, const std::string & content)
|
||||||
|
{
|
||||||
|
return WriteAllData(fileName, content.c_str(), content.length());
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "stringutils.h"
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include "filehelper.h"
|
#include <windows.h>
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
#define MAKE_OP_TRIPLE(ch1, ch2, ch3) (ch3 << 16 | ch2 << 8 | ch1)
|
#define MAKE_OP_TRIPLE(ch1, ch2, ch3) (ch3 << 16 | ch2 << 8 | ch1)
|
||||||
#define MAKE_OP_DOUBLE(ch1, ch2) (ch2 << 8 | ch1)
|
#define MAKE_OP_DOUBLE(ch1, ch2) (ch2 << 8 | ch1)
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "testfiles.h"
|
#include "testfiles.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "filehelper.h"
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
bool TestLexer(Lexer & lexer, const std::string & filename)
|
bool TestLexer(Lexer & lexer, const std::string & filename)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "stringutils.h"
|
|
||||||
|
|
||||||
using namespace AST;
|
using namespace AST;
|
||||||
|
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
#include <sstream>
|
|
||||||
#include "stringutils.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "dynamicmem.h"
|
|
||||||
#include <windows.h>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
StringList StringUtils::Split(const String & s, char delim, std::vector<String> & elems)
|
|
||||||
{
|
|
||||||
std::stringstream ss(s);
|
|
||||||
String item;
|
|
||||||
while(std::getline(ss, item, delim))
|
|
||||||
{
|
|
||||||
if(!item.length())
|
|
||||||
continue;
|
|
||||||
elems.push_back(item);
|
|
||||||
}
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringList StringUtils::Split(const String & s, char delim)
|
|
||||||
{
|
|
||||||
std::vector<String> elems;
|
|
||||||
Split(s, delim, elems);
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::Escape(const String & s)
|
|
||||||
{
|
|
||||||
String escaped = "";
|
|
||||||
for(size_t i = 0; i < s.length(); i++)
|
|
||||||
{
|
|
||||||
auto ch = uint8_t(s[i]);
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case '\0':
|
|
||||||
escaped += "\\0";
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
escaped += "\\t";
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
escaped += "\\f";
|
|
||||||
break;
|
|
||||||
case '\v':
|
|
||||||
escaped += "\\v";
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
escaped += "\\n";
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
escaped += "\\r";
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
escaped += "\\\\";
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
escaped += "\\\"";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(!isprint(ch)) //unknown unprintable character
|
|
||||||
{
|
|
||||||
char buf[16] = "";
|
|
||||||
sprintf_s(buf, "\\x%02X", ch);
|
|
||||||
escaped += buf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
escaped += ch;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return escaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707
|
|
||||||
const String StringUtils::WHITESPACE = " \n\r\t";
|
|
||||||
|
|
||||||
String StringUtils::Trim(const String & s)
|
|
||||||
{
|
|
||||||
return TrimRight(TrimLeft(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::TrimLeft(const String & s)
|
|
||||||
{
|
|
||||||
size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE);
|
|
||||||
return (startpos == String::npos) ? "" : s.substr(startpos);
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::TrimRight(const String & s)
|
|
||||||
{
|
|
||||||
size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE);
|
|
||||||
return (endpos == String::npos) ? "" : s.substr(0, endpos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289
|
|
||||||
String StringUtils::Utf16ToUtf8(const WString & wstr)
|
|
||||||
{
|
|
||||||
String convertedString;
|
|
||||||
auto requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
|
||||||
if(requiredSize > 0)
|
|
||||||
{
|
|
||||||
std::vector<char> buffer(requiredSize);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, nullptr, nullptr);
|
|
||||||
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
|
||||||
}
|
|
||||||
return convertedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::Utf16ToUtf8(const wchar_t* wstr)
|
|
||||||
{
|
|
||||||
return Utf16ToUtf8(wstr ? WString(wstr) : WString());
|
|
||||||
}
|
|
||||||
|
|
||||||
WString StringUtils::Utf8ToUtf16(const String & str)
|
|
||||||
{
|
|
||||||
WString convertedString;
|
|
||||||
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
|
||||||
if(requiredSize > 0)
|
|
||||||
{
|
|
||||||
std::vector<wchar_t> buffer(requiredSize);
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
|
|
||||||
convertedString.assign(buffer.begin(), buffer.end() - 1);
|
|
||||||
}
|
|
||||||
return convertedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
WString StringUtils::Utf8ToUtf16(const char* str)
|
|
||||||
{
|
|
||||||
return Utf8ToUtf16(str ? String(str) : String());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Taken from: http://stackoverflow.com/a/24315631
|
|
||||||
void StringUtils::ReplaceAll(String & s, const String & from, const String & to)
|
|
||||||
{
|
|
||||||
size_t start_pos = 0;
|
|
||||||
while((start_pos = s.find(from, start_pos)) != std::string::npos)
|
|
||||||
{
|
|
||||||
s.replace(start_pos, from.length(), to);
|
|
||||||
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StringUtils::ReplaceAll(WString & s, const WString & from, const WString & to)
|
|
||||||
{
|
|
||||||
size_t start_pos = 0;
|
|
||||||
while((start_pos = s.find(from, start_pos)) != std::string::npos)
|
|
||||||
{
|
|
||||||
s.replace(start_pos, from.length(), to);
|
|
||||||
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::sprintf(const char* format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
Memory<char*> buffer(256 * sizeof(char), "StringUtils::sprintf");
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
int res = _vsnprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args);
|
|
||||||
if(res == -1)
|
|
||||||
{
|
|
||||||
buffer.realloc(buffer.size() * 2, "StringUtils::sprintf");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
return String(buffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
WString StringUtils::sprintf(const wchar_t* format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
Memory<wchar_t*> buffer(256 * sizeof(wchar_t), "StringUtils::sprintf");
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
int res = _vsnwprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args);
|
|
||||||
if(res == -1)
|
|
||||||
{
|
|
||||||
buffer.realloc(buffer.size() * 2, "StringUtils::sprintf");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
return WString(buffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
String StringUtils::ToLower(const String & s)
|
|
||||||
{
|
|
||||||
auto result = s;
|
|
||||||
for(size_t i = 0; i < result.size(); i++)
|
|
||||||
result[i] = tolower(result[i]);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StringUtils::StartsWith(const String & h, const String & n)
|
|
||||||
{
|
|
||||||
return strstr(h.c_str(), n.c_str()) == h.c_str();
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef _STRINGUTILS_H
|
|
||||||
#define _STRINGUTILS_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
typedef std::string String;
|
|
||||||
typedef std::wstring WString;
|
|
||||||
typedef std::vector<String> StringList;
|
|
||||||
typedef std::vector<WString> WStringList;
|
|
||||||
|
|
||||||
class StringUtils
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static StringList Split(const String & s, char delim, std::vector<String> & elems);
|
|
||||||
static StringList Split(const String & s, char delim);
|
|
||||||
static String Escape(const String & s);
|
|
||||||
static String Trim(const String & s);
|
|
||||||
static String TrimLeft(const String & s);
|
|
||||||
static String TrimRight(const String & s);
|
|
||||||
static String Utf16ToUtf8(const WString & wstr);
|
|
||||||
static String Utf16ToUtf8(const wchar_t* wstr);
|
|
||||||
static WString Utf8ToUtf16(const String & str);
|
|
||||||
static WString Utf8ToUtf16(const char* str);
|
|
||||||
static void ReplaceAll(String & s, const String & from, const String & to);
|
|
||||||
static void ReplaceAll(WString & s, const WString & from, const WString & to);
|
|
||||||
static String sprintf(const char* format, ...);
|
|
||||||
static WString sprintf(const wchar_t* format, ...);
|
|
||||||
static String ToLower(const String & s);
|
|
||||||
static bool StartsWith(const String & h, const String & n);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const String WHITESPACE;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_STRINGUTILS_H
|
|
Loading…
Reference in New Issue