mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-30 03:17:08 +00:00
parent
5763201838
commit
70bbe6c64c
@ -54,7 +54,7 @@ struct RealCacheManager : ICacheManager {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return Deserialize(config_->cacheFormat, path, *file_content,
|
return Deserialize(config_->cacheFormat, path, *file_content,
|
||||||
IndexFile::kCurrentVersion);
|
IndexFile::kMajorVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetCachePath(const std::string& source_file) {
|
std::string GetCachePath(const std::string& source_file) {
|
||||||
|
@ -565,9 +565,8 @@ void OnIndexReference_Function(IndexFile* db,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const int IndexFile::kCurrentVersion = 10;
|
const int IndexFile::kMajorVersion = 10;
|
||||||
const uint64_t IndexFile::kMessagePackMagic = 0x637175657279; // "cquery"
|
const int IndexFile::kMinorVersion = 0;
|
||||||
const int IndexFile::kMessagePackVersion = 0;
|
|
||||||
|
|
||||||
IndexFile::IndexFile(const std::string& path,
|
IndexFile::IndexFile(const std::string& path,
|
||||||
const optional<std::string>& contents)
|
const optional<std::string>& contents)
|
||||||
|
@ -483,14 +483,13 @@ MAKE_REFLECT_TYPE_PROXY(LanguageId, std::underlying_type<LanguageId>::type);
|
|||||||
struct IndexFile {
|
struct IndexFile {
|
||||||
IdCache id_cache;
|
IdCache id_cache;
|
||||||
|
|
||||||
static const int kCurrentVersion;
|
// For both JSON and MessagePack cache files.
|
||||||
static const uint64_t kMessagePackMagic;
|
static const int kMajorVersion;
|
||||||
// MessagePack cache files have its own version number.
|
// For MessagePack cache files.
|
||||||
// JSON has good forward compatibility because field addition/deletion do not
|
// JSON has good forward compatibility because field addition/deletion do not
|
||||||
// harm but currently no efforts have been made to make old MessagePack cache
|
// harm but currently no efforts have been made to make old MessagePack cache
|
||||||
// files accepted by newer cquery.
|
// files accepted by newer cquery.
|
||||||
static const int kMessagePackVersion;
|
static const int kMinorVersion;
|
||||||
int version = 0;
|
|
||||||
|
|
||||||
std::string path;
|
std::string path;
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
|
@ -206,7 +206,6 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) {
|
|||||||
assert(value.Resolve(it->second)->uses.size() == 0);
|
assert(value.Resolve(it->second)->uses.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
value.version = IndexFile::kCurrentVersion;
|
|
||||||
DefaultReflectMemberStart(visitor);
|
DefaultReflectMemberStart(visitor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -214,7 +213,6 @@ template <typename TVisitor>
|
|||||||
void Reflect(TVisitor& visitor, IndexFile& value) {
|
void Reflect(TVisitor& visitor, IndexFile& value) {
|
||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
if (!gTestOutputMode) {
|
if (!gTestOutputMode) {
|
||||||
REFLECT_MEMBER(version);
|
|
||||||
REFLECT_MEMBER(last_modification_time);
|
REFLECT_MEMBER(last_modification_time);
|
||||||
REFLECT_MEMBER(language);
|
REFLECT_MEMBER(language);
|
||||||
REFLECT_MEMBER(import_file);
|
REFLECT_MEMBER(import_file);
|
||||||
@ -263,6 +261,12 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
|
|||||||
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
|
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
|
||||||
writer.SetIndent(' ', 2);
|
writer.SetIndent(' ', 2);
|
||||||
JsonWriter json_writer(&writer);
|
JsonWriter json_writer(&writer);
|
||||||
|
if (!gTestOutputMode) {
|
||||||
|
std::string version = std::to_string(IndexFile::kMajorVersion);
|
||||||
|
for (char c : version)
|
||||||
|
output.Put(c);
|
||||||
|
output.Put('\n');
|
||||||
|
}
|
||||||
Reflect(json_writer, file);
|
Reflect(json_writer, file);
|
||||||
return output.GetString();
|
return output.GetString();
|
||||||
}
|
}
|
||||||
@ -270,8 +274,8 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
|
|||||||
msgpack::sbuffer buf;
|
msgpack::sbuffer buf;
|
||||||
msgpack::packer<msgpack::sbuffer> pk(&buf);
|
msgpack::packer<msgpack::sbuffer> pk(&buf);
|
||||||
MessagePackWriter msgpack_writer(&pk);
|
MessagePackWriter msgpack_writer(&pk);
|
||||||
uint64_t magic = IndexFile::kMessagePackMagic;
|
uint64_t magic = IndexFile::kMajorVersion;
|
||||||
int version = IndexFile::kMessagePackVersion;
|
int version = IndexFile::kMinorVersion;
|
||||||
Reflect(msgpack_writer, magic);
|
Reflect(msgpack_writer, magic);
|
||||||
Reflect(msgpack_writer, version);
|
Reflect(msgpack_writer, version);
|
||||||
Reflect(msgpack_writer, file);
|
Reflect(msgpack_writer, file);
|
||||||
@ -282,27 +286,26 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
||||||
std::string path,
|
const std::string& path,
|
||||||
std::string serialized,
|
const std::string& serialized,
|
||||||
optional<int> expected_version) {
|
optional<int> expected_version) {
|
||||||
std::unique_ptr<IndexFile> file;
|
std::unique_ptr<IndexFile> file;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case SerializeFormat::Json: {
|
case SerializeFormat::Json: {
|
||||||
rapidjson::Document reader;
|
rapidjson::Document reader;
|
||||||
|
if (gTestOutputMode)
|
||||||
reader.Parse(serialized.c_str());
|
reader.Parse(serialized.c_str());
|
||||||
|
else {
|
||||||
|
const char* p = strchr(serialized.c_str(), '\n');
|
||||||
|
if (!p)
|
||||||
|
return nullptr;
|
||||||
|
if (expected_version && atoi(serialized.c_str()) != *expected_version)
|
||||||
|
return nullptr;
|
||||||
|
reader.Parse(p + 1);
|
||||||
|
}
|
||||||
if (reader.HasParseError())
|
if (reader.HasParseError())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Do not deserialize a document with a bad version. Doing so could cause
|
|
||||||
// a crash because the file format may have changed.
|
|
||||||
if (expected_version) {
|
|
||||||
auto actual_version = reader.FindMember("version");
|
|
||||||
if (actual_version == reader.MemberEnd() ||
|
|
||||||
actual_version->value.GetInt() != expected_version) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file = MakeUnique<IndexFile>(path, nullopt);
|
file = MakeUnique<IndexFile>(path, nullopt);
|
||||||
JsonReader json_reader{&reader};
|
JsonReader json_reader{&reader};
|
||||||
try {
|
try {
|
||||||
@ -320,8 +323,7 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
|||||||
if (serialized.empty())
|
if (serialized.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
try {
|
try {
|
||||||
uint64_t magic;
|
int major, minor;
|
||||||
int version;
|
|
||||||
if (serialized.size() < 8)
|
if (serialized.size() < 8)
|
||||||
throw std::invalid_argument("Invalid");
|
throw std::invalid_argument("Invalid");
|
||||||
msgpack::unpacker upk;
|
msgpack::unpacker upk;
|
||||||
@ -330,15 +332,11 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
|||||||
upk.buffer_consumed(serialized.size());
|
upk.buffer_consumed(serialized.size());
|
||||||
file = MakeUnique<IndexFile>(path, nullopt);
|
file = MakeUnique<IndexFile>(path, nullopt);
|
||||||
MessagePackReader reader(&upk);
|
MessagePackReader reader(&upk);
|
||||||
Reflect(reader, magic);
|
Reflect(reader, major);
|
||||||
if (magic != IndexFile::kMessagePackMagic)
|
Reflect(reader, minor);
|
||||||
throw std::invalid_argument("Invalid magic");
|
if (major != IndexFile::kMajorVersion ||
|
||||||
Reflect(reader, version);
|
minor != IndexFile::kMinorVersion)
|
||||||
if (version != IndexFile::kMessagePackVersion) {
|
throw std::invalid_argument("Invalid version");
|
||||||
LOG_S(INFO) << "'" << path << "': skip old msgpack version "
|
|
||||||
<< IndexFile::kMessagePackVersion;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
Reflect(reader, *file);
|
Reflect(reader, *file);
|
||||||
} catch (std::invalid_argument& e) {
|
} catch (std::invalid_argument& e) {
|
||||||
LOG_S(INFO) << "Failed to deserialize msgpack '" << path
|
LOG_S(INFO) << "Failed to deserialize msgpack '" << path
|
||||||
|
@ -344,8 +344,8 @@ void ReflectMember(Reader& visitor, const char* name, T& value) {
|
|||||||
|
|
||||||
std::string Serialize(SerializeFormat format, IndexFile& file);
|
std::string Serialize(SerializeFormat format, IndexFile& file);
|
||||||
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
||||||
std::string path,
|
const std::string& path,
|
||||||
std::string serialized,
|
const std::string& serialized,
|
||||||
optional<int> expected_version);
|
optional<int> expected_version);
|
||||||
|
|
||||||
void SetTestOutputMode();
|
void SetTestOutputMode();
|
||||||
|
Loading…
Reference in New Issue
Block a user