Skip to content

Commit

Permalink
Separate string helper, Add test, Add methods in PathHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
durswd committed Jul 23, 2023
1 parent cd1d7f7 commit 132dc4c
Show file tree
Hide file tree
Showing 9 changed files with 648 additions and 317 deletions.
1 change: 1 addition & 0 deletions Dev/Cpp/Effekseer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ set(effekseer_public_h
Effekseer/Network/Effekseer.Server.h
Effekseer/Network/Effekseer.Client.h
Effekseer/Utils/Effekseer.CustomAllocator.h
Effekseer/Utils/String.h
Effekseer/IO/Effekseer.EfkEfcFactory.h

Effekseer/SIMD/Base.h
Expand Down
1 change: 1 addition & 0 deletions Dev/Cpp/Effekseer/Effekseer/Backend/GraphicsDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../Effekseer.Base.Pre.h"
#include "../Effekseer.Color.h"
#include "../Utils/Effekseer.CustomAllocator.h"
#include "../Utils/String.h"
#include <array>
#include <stdint.h>
#include <string>
Expand Down
203 changes: 0 additions & 203 deletions Dev/Cpp/Effekseer/Effekseer/Effekseer.Base.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,209 +103,6 @@ enum class BindType : int32_t
Always = 2,
};

class StringHelper
{
public:
template <typename T>
static std::vector<std::basic_string<T>> Split(const std::basic_string<T>& s, T delim)
{
std::vector<std::basic_string<T>> elems;

size_t start = 0;

for (size_t i = 0; i < s.size(); i++)
{
if (s[i] == delim)
{
elems.emplace_back(s.substr(start, i - start));
start = i + 1;
}
}

if (start == s.size())
{
elems.emplace_back(std::basic_string<T>());
}
else
{
elems.emplace_back(s.substr(start, s.size() - start));
}

return elems;
}

template <typename T>
static std::basic_string<T> Replace(std::basic_string<T> target, std::basic_string<T> from_, std::basic_string<T> to_)
{
auto Pos = target.find(from_);

while (Pos != std::basic_string<T>::npos)
{
target.replace(Pos, from_.length(), to_);
Pos = target.find(from_, Pos + to_.length());
}

return target;
}

template <typename T, typename U>
static std::basic_string<T> To(const U* str)
{
std::basic_string<T> ret;
size_t len = 0;
while (str[len] != 0)
{
len++;
}

ret.resize(len);

for (size_t i = 0; i < len; i++)
{
ret[i] = static_cast<T>(str[i]);
}

return ret;
}

template <typename T>
static std::basic_string<T> Join(const std::vector<std::basic_string<T>>& elems, std::basic_string<T> separator)
{
std::basic_string<T> ret;

for (size_t i = 0; i < elems.size(); i++)
{
ret += elems[i];

if (i != elems.size() - 1)
{
ret += separator;
}
}

return ret;
}
};

class PathHelper
{
private:
template <typename T>
static std::basic_string<T> Normalize(const std::vector<std::basic_string<T>>& paths)
{
std::vector<std::basic_string<T>> elems;

for (size_t i = 0; i < paths.size(); i++)
{
if (paths[i] == StringHelper::To<T>(".."))
{
if (elems.size() > 0 && elems.back() != StringHelper::To<T>(".."))
{
elems.pop_back();
}
else
{
elems.push_back(StringHelper::To<T>(".."));
}
}
else
{
elems.push_back(paths[i]);
}
}

return StringHelper::Join(elems, StringHelper::To<T>("/"));
}

public:
template <typename T>
static std::basic_string<T> Normalize(const std::basic_string<T>& path)
{
if (path.size() == 0)
return path;

auto paths =
StringHelper::Split(StringHelper::Replace(path, StringHelper::To<T>("\\"), StringHelper::To<T>("/")), static_cast<T>('/'));

return Normalize(paths);
}

template <typename T>
static std::basic_string<T> Relative(const std::basic_string<T>& targetPath, const std::basic_string<T>& basePath)
{
if (basePath.size() == 0 || targetPath.size() == 0)
{
return targetPath;
}

auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To<T>("\\"), StringHelper::To<T>("/")),
static_cast<T>('/'));
auto basePaths =
StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To<T>("\\"), StringHelper::To<T>("/")), static_cast<T>('/'));

if (*(basePath.end() - 1) != static_cast<T>('/') && *(basePath.end() - 1) != static_cast<T>('\\'))
{
basePaths.pop_back();
}

int32_t offset = 0;
while (targetPaths.size() > offset && basePaths.size() > offset)
{
if (targetPaths[offset] == basePaths[offset])
{
offset++;
}
else
{
break;
}
}

std::basic_string<T> ret;

for (size_t i = offset; i < basePaths.size(); i++)
{
ret += StringHelper::To<T>("../");
}

for (size_t i = offset; i < targetPaths.size(); i++)
{
ret += targetPaths[i];

if (i != targetPaths.size() - 1)
{
ret += StringHelper::To<T>("/");
}
}

return ret;
}

template <typename T>
static std::basic_string<T> Absolute(const std::basic_string<T>& targetPath, const std::basic_string<T>& basePath)
{
if (targetPath == StringHelper::To<T>(""))
return StringHelper::To<T>("");

if (basePath == StringHelper::To<T>(""))
return targetPath;

auto targetPaths = StringHelper::Split(StringHelper::Replace(targetPath, StringHelper::To<T>("\\"), StringHelper::To<T>("/")),
static_cast<T>('/'));
auto basePaths =
StringHelper::Split(StringHelper::Replace(basePath, StringHelper::To<T>("\\"), StringHelper::To<T>("/")), static_cast<T>('/'));

if (*(basePath.end() - 1) != static_cast<T>('/') && *(basePath.end() - 1) != static_cast<T>('\\'))
{
basePaths.pop_back();
}

std::copy(targetPaths.begin(), targetPaths.end(), std::back_inserter(basePaths));

return Normalize(basePaths);
}
};

} // namespace Effekseer

#endif // __EFFEKSEER_BASE_H__
1 change: 1 addition & 0 deletions Dev/Cpp/Effekseer/Effekseer/Effekseer.ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Effekseer.Resource.h"
#include "Model//ProceduralModelParameter.h"
#include "Model/ProceduralModelGenerator.h"
#include "Utils/String.h"
#include <algorithm>

namespace Effekseer
Expand Down
84 changes: 0 additions & 84 deletions Dev/Cpp/Effekseer/Effekseer/Utils/Effekseer.CustomAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,90 +216,6 @@ using CustomUnorderedMap = std::unordered_map<T, U, Hasher, KeyEq, CustomAllocat
template <class T, class U, class Hasher = std::hash<T>, class KeyEq = std::equal_to<T>>
using CustomAlignedUnorderedMap = std::unordered_map<T, U, Hasher, KeyEq, CustomAlignedAllocator<std::pair<const T, U>>>;

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
template <typename T>
class StringView
{
using Traits = std::char_traits<T>;

public:
StringView()
: ptr_(nullptr)
, size_(0)
{
}

StringView(const T* ptr)
: ptr_(ptr)
, size_(Traits::length(ptr))
{
}

StringView(const T* ptr, size_t size)
: ptr_(ptr)
, size_(size)
{
}

template <size_t N>
StringView(const T ptr[N])
: ptr_(ptr)
, size_(N)
{
}

StringView(const CustomString<T>& str)
: ptr_(str.data())
, size_(str.size())
{
}

const T* data() const
{
return ptr_;
}

size_t size() const
{
return size_;
}

bool operator==(const StringView<T>& rhs) const
{
return size() == rhs.size() && Traits::compare(data(), rhs.data(), size()) == 0;
}

bool operator!=(const StringView<T>& rhs) const
{
return size() != rhs.size() || Traits::compare(data(), rhs.data(), size()) != 0;
}

struct Hash
{
size_t operator()(const StringView<T>& key) const
{
constexpr size_t basis = (sizeof(size_t) == 8) ? 14695981039346656037ULL : 2166136261U;
constexpr size_t prime = (sizeof(size_t) == 8) ? 1099511628211ULL : 16777619U;

const uint8_t* data = reinterpret_cast<const uint8_t*>(key.data());
size_t count = key.size() * sizeof(T);
size_t val = basis;
for (size_t i = 0; i < count; i++)
{
val ^= static_cast<size_t>(data[i]);
val *= prime;
}
return val;
}
};

private:
const T* ptr_;
size_t size_;
};

} // namespace Effekseer

#endif // __EFFEKSEER_BASE_PRE_H__
Loading

0 comments on commit 132dc4c

Please sign in to comment.