00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <qfile.h>
00010 #include <qdir.h>
00011 #include <qapplication.h>
00012 #include <qdatastream.h>
00013 #include "cache.h"
00014
00015 using namespace QGit;
00016
00017 bool Cache::save(const QString& gitDir, const RevFileMap& rf,
00018 const StrVect& dirs, const StrVect& files) {
00019
00020 if (gitDir.isEmpty() || rf.isEmpty())
00021 return false;
00022
00023 QString path(gitDir + C_DAT_FILE);
00024 QString tmpPath(path + BAK_EXT);
00025
00026 QDir dir;
00027 if (!dir.exists(gitDir)) {
00028 dbs("Git directory not found, unable to save cache");
00029 return false;
00030 }
00031 QFile f(tmpPath);
00032 if (!f.open(IO_WriteOnly))
00033 return false;
00034
00035 dbs("Saving cache. Please wait...");
00036
00037
00038 QByteArray data;
00039 QDataStream stream(data, IO_WriteOnly);
00040
00041
00042 stream << (Q_UINT32)C_MAGIC;
00043 stream << (Q_INT32)C_VERSION;
00044
00045 stream << (Q_INT32)dirs.count();
00046 for (uint i = 0; i < dirs.count(); ++i)
00047 stream << dirs[i];
00048
00049 stream << (Q_INT32)files.count();
00050 for (uint i = 0; i < files.count(); ++i)
00051 stream << files[i];
00052
00053
00054
00055
00056
00057
00058 uint bufSize = rf.count() * 40 + 1000;
00059 stream << (Q_INT32)bufSize;
00060
00061 QString buf;
00062 buf.reserve(bufSize);
00063 QDictIterator<RevFile> it(rf);
00064 for ( ; it.current(); ++it) {
00065
00066 SCRef sha = it.currentKey();
00067 if ( sha == ZERO_SHA
00068 || sha == CUSTOM_SHA
00069 || sha.startsWith("A"))
00070 continue;
00071
00072 buf.append(sha);
00073 }
00074 stream << buf;
00075
00076 for (it.toFirst(); it.current(); ++it) {
00077
00078 SCRef sha = it.currentKey();
00079 if ( sha == ZERO_SHA
00080 || sha == CUSTOM_SHA
00081 || sha.startsWith("A"))
00082 continue;
00083
00084 const RevFile* rf = *it;
00085 stream << rf->names;
00086 stream << rf->dirs;
00087
00088
00089 bool isEmpty = rf->onlyModified;
00090 stream << (Q_UINT32)isEmpty;
00091 if (!isEmpty)
00092 stream << rf->status;
00093
00094
00095 isEmpty = (rf->mergeParent.isEmpty() || rf->mergeParent.last() == 1);
00096 stream << (Q_UINT32)isEmpty;
00097 if (!isEmpty)
00098 stream << rf->mergeParent;
00099
00100
00101 isEmpty = rf->extStatus.isEmpty();
00102 stream << (Q_UINT32)isEmpty;
00103 if (!isEmpty)
00104 stream << rf->extStatus;
00105 }
00106 dbs("Compressing data...");
00107 f.writeBlock(qCompress(data));
00108 f.close();
00109
00110
00111 if (dir.exists(path)) {
00112 if (!dir.remove(path)) {
00113 dbs("access denied to " + path);
00114 dir.remove(tmpPath);
00115 return false;
00116 }
00117 }
00118 dir.rename(tmpPath, path);
00119 dbs("Done.");
00120 return true;
00121 }
00122
00123 bool Cache::load(const QString& gitDir, RevFileMap& rfm, StrVect& dirs, StrVect& files) {
00124
00125
00126 QString path(gitDir + C_DAT_FILE);
00127 QFile f(path);
00128 if (!f.exists())
00129 return true;
00130
00131 if (!f.open(IO_ReadOnly))
00132 return false;
00133
00134 QDataStream* stream = new QDataStream(qUncompress(f.readAll()), IO_ReadOnly);
00135 Q_UINT32 magic;
00136 Q_INT32 version;
00137 Q_INT32 dirsNum, filesNum, bufSize;
00138 *stream >> magic;
00139 *stream >> version;
00140 if (magic != C_MAGIC || version != C_VERSION) {
00141 f.close();
00142 delete stream;
00143 return false;
00144 }
00145
00146 *stream >> dirsNum;
00147 dirs.resize(dirsNum);
00148 for (int i = 0; i < dirsNum; ++i)
00149 *stream >> dirs[i];
00150
00151 *stream >> filesNum;
00152 files.resize(filesNum);
00153 for (int i = 0; i < filesNum; ++i)
00154 *stream >> files[i];
00155
00156 *stream >> bufSize;
00157 QString buf;
00158 buf.reserve(bufSize);
00159 *stream >> buf;
00160
00161 uint bufIdx = 0;
00162 bool isEmpty;
00163 Q_UINT32 tmp;
00164 while (!stream->atEnd()) {
00165
00166 RevFile* rf = new RevFile();
00167 *stream >> rf->names;
00168 *stream >> rf->dirs;
00169
00170 *stream >> tmp;
00171 rf->onlyModified = (bool)tmp;
00172 if (!rf->onlyModified)
00173 *stream >> rf->status;
00174
00175 *stream >> tmp;
00176 isEmpty = (bool)tmp;
00177 if (!isEmpty)
00178 *stream >> rf->mergeParent;
00179
00180 *stream >> tmp;
00181 isEmpty = (bool)tmp;
00182 if (!isEmpty)
00183 *stream >> rf->extStatus;
00184
00185 SCRef sha(buf.mid(bufIdx, 40));
00186 rfm.insert(sha, rf);
00187 bufIdx += 40;
00188 }
00189 f.close();
00190 delete stream;
00191 return true;
00192 }