mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55:38 +00:00
Merge pull request #308 from tomaz82/utils
Add String and FilesSystem utils
This commit is contained in:
commit
094c9ccd09
|
@ -69,6 +69,10 @@ set(CORE_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.h
|
||||||
|
|
||||||
|
# Utils
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/FileSystemUtil.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/StringUtil.h
|
||||||
|
|
||||||
# Embedded assets (needed by ResourceManager)
|
# Embedded assets (needed by ResourceManager)
|
||||||
${emulationstation-all_SOURCE_DIR}/data/Resources.h
|
${emulationstation-all_SOURCE_DIR}/data/Resources.h
|
||||||
)
|
)
|
||||||
|
@ -136,6 +140,10 @@ set(CORE_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureData.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureDataManager.cpp
|
||||||
|
|
||||||
|
# Utils
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/FileSystemUtil.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/StringUtil.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(EMBEDDED_ASSET_SOURCES
|
set(EMBEDDED_ASSET_SOURCES
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#ifndef ES_CORE_STRING_UTIL_H
|
|
||||||
#define ES_CORE_STRING_UTIL_H
|
|
||||||
|
|
||||||
namespace StringUtil
|
|
||||||
{
|
|
||||||
inline unsigned int chars2Unicode(const std::string& _string, size_t& _cursor)
|
|
||||||
{
|
|
||||||
const char& c = _string[_cursor];
|
|
||||||
unsigned int result = '?';
|
|
||||||
|
|
||||||
if((c & 0x80) == 0) // 0xxxxxxx, one byte character
|
|
||||||
{
|
|
||||||
// 0xxxxxxx
|
|
||||||
result = ((_string[_cursor++] ) );
|
|
||||||
}
|
|
||||||
else if((c & 0xE0) == 0xC0) // 110xxxxx, two byte character
|
|
||||||
{
|
|
||||||
// 110xxxxx 10xxxxxx
|
|
||||||
result = ((_string[_cursor++] & 0x1F) << 6) |
|
|
||||||
((_string[_cursor++] & 0x3F) );
|
|
||||||
}
|
|
||||||
else if((c & 0xF0) == 0xE0) // 1110xxxx, three byte character
|
|
||||||
{
|
|
||||||
// 1110xxxx 10xxxxxx 10xxxxxx
|
|
||||||
result = ((_string[_cursor++] & 0x0F) << 12) |
|
|
||||||
((_string[_cursor++] & 0x3F) << 6) |
|
|
||||||
((_string[_cursor++] & 0x3F) );
|
|
||||||
}
|
|
||||||
else if((c & 0xF8) == 0xF0) // 11110xxx, four byte character
|
|
||||||
{
|
|
||||||
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
||||||
result = ((_string[_cursor++] & 0x07) << 18) |
|
|
||||||
((_string[_cursor++] & 0x3F) << 12) |
|
|
||||||
((_string[_cursor++] & 0x3F) << 6) |
|
|
||||||
((_string[_cursor++] & 0x3F) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// error, invalid unicode
|
|
||||||
++_cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} // chars2Unicode
|
|
||||||
|
|
||||||
inline std::string unicode2Chars(const unsigned int _unicode)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
|
|
||||||
if(_unicode < 0x80) // one byte character
|
|
||||||
{
|
|
||||||
result += ((_unicode ) );
|
|
||||||
}
|
|
||||||
else if(_unicode < 0x800) // two byte character
|
|
||||||
{
|
|
||||||
result += ((_unicode >> 6) ) | 0xC0;
|
|
||||||
result += ((_unicode ) & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
else if(_unicode < 0xFFFF) // three byte character
|
|
||||||
{
|
|
||||||
result += ((_unicode >> 12) ) | 0xE0;
|
|
||||||
result += ((_unicode >> 6) & 0x3F) | 0x80;
|
|
||||||
result += ((_unicode ) & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
else if(_unicode <= 0x1fffff) // four byte character
|
|
||||||
{
|
|
||||||
result += ((_unicode >> 18) ) | 0xF0;
|
|
||||||
result += ((_unicode >> 12) & 0x3F) | 0x80;
|
|
||||||
result += ((_unicode >> 6) & 0x3F) | 0x80;
|
|
||||||
result += ((_unicode ) & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// error, invalid unicode
|
|
||||||
result += '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} // unicode2Chars
|
|
||||||
|
|
||||||
inline size_t nextCursor(const std::string& _string, const size_t _cursor)
|
|
||||||
{
|
|
||||||
size_t result = _cursor;
|
|
||||||
|
|
||||||
while(result < _string.length())
|
|
||||||
{
|
|
||||||
++result;
|
|
||||||
|
|
||||||
if((_string[result] & 0xC0) != 0x80) // break if current character is not 10xxxxxx
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} // nextCursor
|
|
||||||
|
|
||||||
inline size_t prevCursor(const std::string& _string, const size_t _cursor)
|
|
||||||
{
|
|
||||||
size_t result = _cursor;
|
|
||||||
|
|
||||||
while(result > 0)
|
|
||||||
{
|
|
||||||
--result;
|
|
||||||
|
|
||||||
if((_string[result] & 0xC0) != 0x80) // break if current character is not 10xxxxxx
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} // prevCursor
|
|
||||||
|
|
||||||
inline size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount)
|
|
||||||
{
|
|
||||||
size_t result = _cursor;
|
|
||||||
|
|
||||||
if(_amount > 0)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < _amount; ++i)
|
|
||||||
result = nextCursor(_string, result);
|
|
||||||
}
|
|
||||||
else if(_amount < 0)
|
|
||||||
{
|
|
||||||
for(int i = _amount; i < 0; ++i)
|
|
||||||
result = prevCursor(_string, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} // moveCursor
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ES_CORE_STRING_UTIL_H
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
|
|
||||||
|
#include "utils/StringUtil.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "StringUtil.h"
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
||||||
|
@ -198,7 +198,7 @@ void TextComponent::onTextChanged()
|
||||||
|
|
||||||
while(text.size() && size.x() + abbrevSize.x() > mSize.x())
|
while(text.size() && size.x() + abbrevSize.x() > mSize.x())
|
||||||
{
|
{
|
||||||
size_t newSize = StringUtil::prevCursor(text, text.size());
|
size_t newSize = Utils::String::prevCursor(text, text.size());
|
||||||
text.erase(newSize, text.size() - newSize);
|
text.erase(newSize, text.size() - newSize);
|
||||||
size = f->sizeText(text);
|
size = f->sizeText(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "components/TextEditComponent.h"
|
#include "components/TextEditComponent.h"
|
||||||
|
|
||||||
#include "resources/Font.h"
|
#include "resources/Font.h"
|
||||||
|
#include "utils/StringUtil.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "StringUtil.h"
|
|
||||||
|
|
||||||
#define TEXT_PADDING_HORIZ 10
|
#define TEXT_PADDING_HORIZ 10
|
||||||
#define TEXT_PADDING_VERT 2
|
#define TEXT_PADDING_VERT 2
|
||||||
|
@ -60,7 +60,7 @@ void TextEditComponent::textInput(const char* text)
|
||||||
{
|
{
|
||||||
if(mCursor > 0)
|
if(mCursor > 0)
|
||||||
{
|
{
|
||||||
size_t newCursor = StringUtil::prevCursor(mText, mCursor);
|
size_t newCursor = Utils::String::prevCursor(mText, mCursor);
|
||||||
mText.erase(mText.begin() + newCursor, mText.begin() + mCursor);
|
mText.erase(mText.begin() + newCursor, mText.begin() + mCursor);
|
||||||
mCursor = newCursor;
|
mCursor = newCursor;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ void TextEditComponent::updateCursorRepeat(int deltaTime)
|
||||||
|
|
||||||
void TextEditComponent::moveCursor(int amt)
|
void TextEditComponent::moveCursor(int amt)
|
||||||
{
|
{
|
||||||
mCursor = StringUtil::moveCursor(mText, mCursor, amt);
|
mCursor = Utils::String::moveCursor(mText, mCursor, amt);
|
||||||
onCursorChanged();
|
onCursorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "resources/Font.h"
|
#include "resources/Font.h"
|
||||||
|
|
||||||
|
#include "utils/StringUtil.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "StringUtil.h"
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
FT_Library Font::sLibrary = NULL;
|
FT_Library Font::sLibrary = NULL;
|
||||||
|
@ -448,7 +448,7 @@ Vector2f Font::sizeText(std::string text, float lineSpacing)
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while(i < text.length())
|
while(i < text.length())
|
||||||
{
|
{
|
||||||
unsigned int character = StringUtil::chars2Unicode(text, i); // advances i
|
unsigned int character = Utils::String::chars2Unicode(text, i); // advances i
|
||||||
|
|
||||||
if(character == '\n')
|
if(character == '\n')
|
||||||
{
|
{
|
||||||
|
@ -541,8 +541,8 @@ Vector2f Font::getWrappedTextCursorOffset(std::string text, float xLen, size_t s
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
while(cursor < stop)
|
while(cursor < stop)
|
||||||
{
|
{
|
||||||
unsigned int wrappedCharacter = StringUtil::chars2Unicode(wrappedText, wrapCursor);
|
unsigned int wrappedCharacter = Utils::String::chars2Unicode(wrappedText, wrapCursor);
|
||||||
unsigned int character = StringUtil::chars2Unicode(text, cursor);
|
unsigned int character = Utils::String::chars2Unicode(text, cursor);
|
||||||
|
|
||||||
if(wrappedCharacter == '\n' && character != '\n')
|
if(wrappedCharacter == '\n' && character != '\n')
|
||||||
{
|
{
|
||||||
|
@ -551,7 +551,7 @@ Vector2f Font::getWrappedTextCursorOffset(std::string text, float xLen, size_t s
|
||||||
lineWidth = 0.0f;
|
lineWidth = 0.0f;
|
||||||
y += getHeight(lineSpacing);
|
y += getHeight(lineSpacing);
|
||||||
|
|
||||||
cursor = StringUtil::prevCursor(text, cursor); // unconsume
|
cursor = Utils::String::prevCursor(text, cursor); // unconsume
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsign
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
while(cursor < text.length())
|
while(cursor < text.length())
|
||||||
{
|
{
|
||||||
unsigned int character = StringUtil::chars2Unicode(text, cursor); // also advances cursor
|
unsigned int character = Utils::String::chars2Unicode(text, cursor); // also advances cursor
|
||||||
Glyph* glyph;
|
Glyph* glyph;
|
||||||
|
|
||||||
// invalid character
|
// invalid character
|
||||||
|
|
168
es-core/src/utils/FileSystemUtil.cpp
Normal file
168
es-core/src/utils/FileSystemUtil.cpp
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
#include "utils/FileSystemUtil.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
// because windows...
|
||||||
|
#include <direct.h>
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define mkdir(x,y) _mkdir(x)
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
namespace FileSystem
|
||||||
|
{
|
||||||
|
bool createDirectory(const std::string& path)
|
||||||
|
{
|
||||||
|
// don't create if it already exists
|
||||||
|
if(exists(path))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// convert '\\' to '/'
|
||||||
|
fixSeparators(path);
|
||||||
|
|
||||||
|
// try to create directory
|
||||||
|
if(mkdir(path.c_str(), 0755) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// failed to create directory, try to create the parent
|
||||||
|
std::string parent = getParent(path);
|
||||||
|
|
||||||
|
// only try to create parent if it's not identical to path
|
||||||
|
if(parent != path)
|
||||||
|
createDirectory(parent);
|
||||||
|
|
||||||
|
// try to create directory again now that the parent should exist
|
||||||
|
return (mkdir(path.c_str(), 0755) == 0);
|
||||||
|
|
||||||
|
} // createDirectory
|
||||||
|
|
||||||
|
void fixSeparators(const std::string& path)
|
||||||
|
{
|
||||||
|
char* p = nullptr;
|
||||||
|
|
||||||
|
// convert '\\' to '/'
|
||||||
|
for(p = (char*)path.c_str() + 1; *p; ++p)
|
||||||
|
{
|
||||||
|
if(*p == '\\')
|
||||||
|
*p = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
} // fixSeparators
|
||||||
|
|
||||||
|
std::string escapePath(const std::string& path)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// windows escapes stuff by just putting everything in quotes
|
||||||
|
return '"' + path + '"';
|
||||||
|
#else // WIN32
|
||||||
|
// insert a backslash before most characters that would mess up a bash path
|
||||||
|
std::string escapedPath = path;
|
||||||
|
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
|
||||||
|
const char* invalidChar = invalidChars;
|
||||||
|
|
||||||
|
while(*invalidChar)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < escapedPath.length(); ++i)
|
||||||
|
{
|
||||||
|
if(escapedPath[i] == *invalidChar)
|
||||||
|
{
|
||||||
|
escapedPath.insert(i, 1, '\\');
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++invalidChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
return escapedPath;
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
} // escapePath
|
||||||
|
|
||||||
|
std::string getParent(const std::string& path)
|
||||||
|
{
|
||||||
|
// convert '\\' to '/'
|
||||||
|
fixSeparators(path);
|
||||||
|
|
||||||
|
// make a copy of the path
|
||||||
|
char temp[512];
|
||||||
|
size_t len = snprintf(temp, sizeof(temp), "%s", path.c_str());
|
||||||
|
|
||||||
|
// find last '/' and end the new path
|
||||||
|
while(len > 1)
|
||||||
|
{
|
||||||
|
if(temp[--len] == '/')
|
||||||
|
{
|
||||||
|
temp[len] = 0;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no parent found
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // getParent
|
||||||
|
|
||||||
|
std::string getFileName(const std::string& path)
|
||||||
|
{
|
||||||
|
// convert '\\' to '/'
|
||||||
|
fixSeparators(path);
|
||||||
|
|
||||||
|
// make a copy of the path
|
||||||
|
char temp[512];
|
||||||
|
size_t len = snprintf(temp, sizeof(temp), "%s", path.c_str());
|
||||||
|
|
||||||
|
// find last '/' and return the filename
|
||||||
|
while(len > 1)
|
||||||
|
{
|
||||||
|
// return "." if this is the end of the path, otherwise return filename
|
||||||
|
if(temp[--len] == '/')
|
||||||
|
return ((temp[len + 1] == 0) ? "." : (temp + len + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// no '/' found, entire path is a filename
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // getFileName
|
||||||
|
|
||||||
|
std::string getStem(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string fileName = getFileName(path);
|
||||||
|
|
||||||
|
// empty fileName
|
||||||
|
if(fileName == ".")
|
||||||
|
return fileName;
|
||||||
|
|
||||||
|
// make a copy of the filename
|
||||||
|
char temp[512];
|
||||||
|
size_t len = snprintf(temp, sizeof(temp), "%s", fileName.c_str());
|
||||||
|
|
||||||
|
// find last '.' and remove the extension
|
||||||
|
while(len > 1)
|
||||||
|
{
|
||||||
|
if(temp[--len] == '.')
|
||||||
|
{
|
||||||
|
temp[len] = 0;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no '.' found, filename has no extension
|
||||||
|
return fileName;
|
||||||
|
|
||||||
|
} // getStem
|
||||||
|
|
||||||
|
bool exists(const std::string& path)
|
||||||
|
{
|
||||||
|
struct stat info;
|
||||||
|
return (stat(path.c_str(), &info) == 0);
|
||||||
|
|
||||||
|
} // exists
|
||||||
|
|
||||||
|
} // FileSystem::
|
||||||
|
|
||||||
|
} // Utils::
|
23
es-core/src/utils/FileSystemUtil.h
Normal file
23
es-core/src/utils/FileSystemUtil.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef ES_CORE_FILE_SYSTEM_UTIL_H
|
||||||
|
#define ES_CORE_FILE_SYSTEM_UTIL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
namespace FileSystem
|
||||||
|
{
|
||||||
|
bool createDirectory(const std::string& path);
|
||||||
|
void fixSeparators(const std::string& path);
|
||||||
|
std::string escapePath(const std::string& path);
|
||||||
|
std::string getParent(const std::string& path);
|
||||||
|
std::string getFileName(const std::string& path);
|
||||||
|
std::string getStem(const std::string& path);
|
||||||
|
bool exists(const std::string& path);
|
||||||
|
|
||||||
|
} // FileSystem::
|
||||||
|
|
||||||
|
} // Utils::
|
||||||
|
|
||||||
|
#endif // ES_CORE_FILE_SYSTEM_UTIL_H
|
156
es-core/src/utils/StringUtil.cpp
Normal file
156
es-core/src/utils/StringUtil.cpp
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
#include "utils/StringUtil.h"
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
namespace String
|
||||||
|
{
|
||||||
|
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor)
|
||||||
|
{
|
||||||
|
const char& c = _string[_cursor];
|
||||||
|
unsigned int result = '?';
|
||||||
|
|
||||||
|
if((c & 0x80) == 0) // 0xxxxxxx, one byte character
|
||||||
|
{
|
||||||
|
// 0xxxxxxx
|
||||||
|
result = ((_string[_cursor++] ) );
|
||||||
|
}
|
||||||
|
else if((c & 0xE0) == 0xC0) // 110xxxxx, two byte character
|
||||||
|
{
|
||||||
|
// 110xxxxx 10xxxxxx
|
||||||
|
result = ((_string[_cursor++] & 0x1F) << 6) |
|
||||||
|
((_string[_cursor++] & 0x3F) );
|
||||||
|
}
|
||||||
|
else if((c & 0xF0) == 0xE0) // 1110xxxx, three byte character
|
||||||
|
{
|
||||||
|
// 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
result = ((_string[_cursor++] & 0x0F) << 12) |
|
||||||
|
((_string[_cursor++] & 0x3F) << 6) |
|
||||||
|
((_string[_cursor++] & 0x3F) );
|
||||||
|
}
|
||||||
|
else if((c & 0xF8) == 0xF0) // 11110xxx, four byte character
|
||||||
|
{
|
||||||
|
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
result = ((_string[_cursor++] & 0x07) << 18) |
|
||||||
|
((_string[_cursor++] & 0x3F) << 12) |
|
||||||
|
((_string[_cursor++] & 0x3F) << 6) |
|
||||||
|
((_string[_cursor++] & 0x3F) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// error, invalid unicode
|
||||||
|
++_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // chars2Unicode
|
||||||
|
|
||||||
|
std::string unicode2Chars(const unsigned int _unicode)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if(_unicode < 0x80) // one byte character
|
||||||
|
{
|
||||||
|
result += ((_unicode ) );
|
||||||
|
}
|
||||||
|
else if(_unicode < 0x800) // two byte character
|
||||||
|
{
|
||||||
|
result += ((_unicode >> 6) ) | 0xC0;
|
||||||
|
result += ((_unicode ) & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else if(_unicode < 0xFFFF) // three byte character
|
||||||
|
{
|
||||||
|
result += ((_unicode >> 12) ) | 0xE0;
|
||||||
|
result += ((_unicode >> 6) & 0x3F) | 0x80;
|
||||||
|
result += ((_unicode ) & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else if(_unicode <= 0x1fffff) // four byte character
|
||||||
|
{
|
||||||
|
result += ((_unicode >> 18) ) | 0xF0;
|
||||||
|
result += ((_unicode >> 12) & 0x3F) | 0x80;
|
||||||
|
result += ((_unicode >> 6) & 0x3F) | 0x80;
|
||||||
|
result += ((_unicode ) & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// error, invalid unicode
|
||||||
|
result += '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // unicode2Chars
|
||||||
|
|
||||||
|
size_t nextCursor(const std::string& _string, const size_t _cursor)
|
||||||
|
{
|
||||||
|
size_t result = _cursor;
|
||||||
|
|
||||||
|
while(result < _string.length())
|
||||||
|
{
|
||||||
|
++result;
|
||||||
|
|
||||||
|
if((_string[result] & 0xC0) != 0x80) // break if current character is not 10xxxxxx
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // nextCursor
|
||||||
|
|
||||||
|
size_t prevCursor(const std::string& _string, const size_t _cursor)
|
||||||
|
{
|
||||||
|
size_t result = _cursor;
|
||||||
|
|
||||||
|
while(result > 0)
|
||||||
|
{
|
||||||
|
--result;
|
||||||
|
|
||||||
|
if((_string[result] & 0xC0) != 0x80) // break if current character is not 10xxxxxx
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // prevCursor
|
||||||
|
|
||||||
|
size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount)
|
||||||
|
{
|
||||||
|
size_t result = _cursor;
|
||||||
|
|
||||||
|
if(_amount > 0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < _amount; ++i)
|
||||||
|
result = nextCursor(_string, result);
|
||||||
|
}
|
||||||
|
else if(_amount < 0)
|
||||||
|
{
|
||||||
|
for(int i = _amount; i < 0; ++i)
|
||||||
|
result = prevCursor(_string, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // moveCursor
|
||||||
|
|
||||||
|
void trim(std::string& _string)
|
||||||
|
{
|
||||||
|
if(_string.size())
|
||||||
|
{
|
||||||
|
size_t cursorB = 0;
|
||||||
|
size_t cursorE = _string.size();
|
||||||
|
|
||||||
|
while((cursorB < _string.size()) && _string[cursorB] == ' ')
|
||||||
|
++cursorB;
|
||||||
|
|
||||||
|
while((cursorE > 0) && _string[cursorE - 1] == ' ')
|
||||||
|
--cursorE;
|
||||||
|
|
||||||
|
_string.erase(_string.begin() + cursorE, _string.end());
|
||||||
|
_string.erase(_string.begin(), _string.begin() + cursorB);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // trim
|
||||||
|
|
||||||
|
} // String::
|
||||||
|
|
||||||
|
} // Utils::
|
22
es-core/src/utils/StringUtil.h
Normal file
22
es-core/src/utils/StringUtil.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef ES_CORE_STRING_UTIL_H
|
||||||
|
#define ES_CORE_STRING_UTIL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
namespace String
|
||||||
|
{
|
||||||
|
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor);
|
||||||
|
std::string unicode2Chars(const unsigned int _unicode);
|
||||||
|
size_t nextCursor(const std::string& _string, const size_t _cursor);
|
||||||
|
size_t prevCursor(const std::string& _string, const size_t _cursor);
|
||||||
|
size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount);
|
||||||
|
void trim(std::string& _string);
|
||||||
|
|
||||||
|
} // String::
|
||||||
|
|
||||||
|
} // Utils::
|
||||||
|
|
||||||
|
#endif // ES_CORE_STRING_UTIL_H
|
Loading…
Reference in a new issue