flatten 20260225
This commit is contained in:
166
tjp/core/string_lookup/StringLookup.cpp
Executable file
166
tjp/core/string_lookup/StringLookup.cpp
Executable file
@@ -0,0 +1,166 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#include "StringLookup.h"
|
||||
#include <tjp/core/containers/StackArray.hpp>
|
||||
#include <tjp/core/algorithm/starts_with.hpp>
|
||||
#include <tjp/core/algorithm/map_value.hpp>
|
||||
#include <tjp/core/string/trim.h>
|
||||
|
||||
#include <tjp/core/string/StringView.hpp>
|
||||
#include <tjp/core/string/StringView+less.hpp>
|
||||
|
||||
#include "../file/Path.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <tjp/core/log/Log.h>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace string_lookup {
|
||||
|
||||
void SKeySource::clear()
|
||||
{
|
||||
kv.clear();
|
||||
}
|
||||
|
||||
void SKeySource::load(const String &path_)
|
||||
{
|
||||
path = path_;
|
||||
|
||||
std::ifstream f(path);
|
||||
if (!f)
|
||||
return ;
|
||||
|
||||
while (!f.eof())
|
||||
{
|
||||
String line;
|
||||
std::getline(f, line);
|
||||
line = core::trim_copy(line);
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
static String comment = "#";
|
||||
if (starts_with(line, comment))
|
||||
continue;
|
||||
|
||||
auto colon = line.find(':');
|
||||
if (colon == String::npos)
|
||||
continue;
|
||||
|
||||
auto key = line.substr(0, colon);
|
||||
auto value = line.substr(colon+1);
|
||||
|
||||
if (value == "$")
|
||||
{
|
||||
value = "";
|
||||
|
||||
line.clear();
|
||||
int notFirst = 0;
|
||||
while (!f.eof())
|
||||
{
|
||||
std::getline(f, line);
|
||||
line = core::trim_copy(line);
|
||||
if (line == "$")
|
||||
break;
|
||||
|
||||
if (notFirst++)
|
||||
value += "\n";
|
||||
|
||||
value += line;
|
||||
}
|
||||
}
|
||||
|
||||
kv[key] = value;
|
||||
}
|
||||
|
||||
version++;
|
||||
|
||||
#ifdef DEBUG
|
||||
empty = "XXXXXXX";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
const SKeyValue &SKeySource::get(const StringView &s) const
|
||||
{
|
||||
auto v = map_value(kv, s);
|
||||
if (v)
|
||||
return *v;
|
||||
|
||||
#ifdef DEBUG
|
||||
sLogDebug("debug", file::fileName(path) << " missing key: " << s);
|
||||
#endif
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
const SKeyValue &SKeySource::get(const KeySet &keys) const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
auto notFirst = 0;
|
||||
for (auto key: keys)
|
||||
{
|
||||
if (notFirst++)
|
||||
oss << ",";
|
||||
oss << key;
|
||||
}
|
||||
|
||||
auto s = oss.str();
|
||||
return get(s);
|
||||
}
|
||||
|
||||
SKey::SKey (SKeyKey key_, SKey *parent_) :
|
||||
key(key_),
|
||||
parent(parent_),
|
||||
source(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SKey::SKey (SKeyKey key_, SKeySource *source_) :
|
||||
key(key_),
|
||||
source(source_),
|
||||
parent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
KeySet SKey::getKeySet() const
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
auto result = parent->getKeySet();
|
||||
result.push_back(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
return { key };
|
||||
}
|
||||
|
||||
SKeySource *SKey::getSource() const
|
||||
{
|
||||
if (source)
|
||||
return source;
|
||||
|
||||
if (parent)
|
||||
return parent->getSource();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SKeyValue &SKey::get_ () const
|
||||
{
|
||||
auto &cacheTo = const_cast<SKey &>(*this);
|
||||
auto source = getSource();
|
||||
|
||||
cacheTo.source = source;
|
||||
cacheTo.cache = source->get(getKeySet());
|
||||
cacheTo.version.update(source->version);
|
||||
|
||||
return cacheTo.cache;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
98
tjp/core/string_lookup/StringLookup.h
Executable file
98
tjp/core/string_lookup/StringLookup.h
Executable file
@@ -0,0 +1,98 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tjp/core/string/String.h>
|
||||
#include <tjp/core/string/StringView.h>
|
||||
#include <tjp/core/containers/StackArray.hpp>
|
||||
#include <tjp/core/containers/Map.h>
|
||||
#include "../resource_version/GlobalResourceVersion.hpp"
|
||||
#include <tjp/core/algorithm/last_of_parameter_pack.hpp>
|
||||
|
||||
#include <tjp/core/containers/TransparentLess.hpp>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace string_lookup {
|
||||
|
||||
using SKeyValue = String;
|
||||
using SKeyKey = const char *;
|
||||
using Version = GlobalResourceVersion;
|
||||
|
||||
using KeySet = StackArray<SKeyKey, 4>;
|
||||
|
||||
struct SKeySource
|
||||
{
|
||||
Map<String, SKeyValue, TransparentLess> kv;
|
||||
Version version;
|
||||
String path;
|
||||
|
||||
SKeyValue empty;
|
||||
|
||||
void clear();
|
||||
void load(const String &path);
|
||||
|
||||
const SKeyValue &get(const StringView &v) const;
|
||||
const SKeyValue &get(const KeySet &keys) const;
|
||||
} ;
|
||||
|
||||
struct SKey {
|
||||
SKeyKey key;
|
||||
SKey *parent;
|
||||
SKeySource *source;
|
||||
|
||||
Version version;
|
||||
SKeyValue cache;
|
||||
|
||||
SKey (SKeyKey key_, SKey *parent_);
|
||||
SKey (SKeyKey key_, SKeySource *source_);
|
||||
|
||||
KeySet getKeySet() const;
|
||||
SKeySource *getSource() const;
|
||||
|
||||
const SKeyValue &get_ () const;
|
||||
const SKeyValue &get() const
|
||||
{
|
||||
if (source &&
|
||||
version == source->version)
|
||||
return cache;
|
||||
|
||||
return get_();
|
||||
}
|
||||
|
||||
operator const String &() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
operator StringView() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
const char *c_str() const
|
||||
{
|
||||
return get().c_str();
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return get().empty();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ... T>
|
||||
String SL(const SKeySource &source, T&& ... args)
|
||||
{
|
||||
return source.get(KeySet { (args.key)... });
|
||||
}
|
||||
|
||||
#define IMPLEMENT_STRING_LOOKUP_EXP(s, y, x) tjp::core::string_lookup::SKey x(y, &s)
|
||||
|
||||
#define IMPLEMENT_STRING_LOOKUP(s, x) IMPLEMENT_STRING_LOOKUP_EXP(s, #x, x)
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user