mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 06:15:20 +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;
 | 
				
			||||||
      reader.Parse(serialized.c_str());
 | 
					      if (gTestOutputMode)
 | 
				
			||||||
 | 
					        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