#ifndef FILEHH #define FILEHH #if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) #else #include #include #include #include #include #include #endif #include #include #include #include #include class File { // hand_written_marshalling_code lil_string name_; mutable bool updated_; public: static time_t lastruntime_; explicit File(char const* name) : name_(name), updated_(true) {} #ifdef MOVE_CTORS File(File&& file) { name_ = std::move(file.name_); } #endif template explicit File(B* buf) { lil_string(buf).swap(name_); boolReceive(buf, updated_); if (updated_) { buf->GiveFile(name_); } } void Send(SendCompressedBuffer* buf, bool = false) const { name_.Send(buf); boolSend(buf, updated_); if (updated_) { buf->ReceiveFile(name_); } } void CalculateMarshallingSize(Counter& cntr) const { if (name_.empty()) { throw failure("File::CalculateMarshallingSize -- zero length name"); } name_.CalculateMarshallingSize(cntr); cntr.Add(1); // updated_ #if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) HANDLE hcom = INVALID_HANDLE_VALUE; hcom = CreateFile(name_.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,0); if (hcom == INVALID_HANDLE_VALUE) { throw failure("File::CalculateMarshallingSize -- CreateFile failed ") << name_.c_str(); } LARGE_INTEGER li; bool bRet = GetFileSizeEx(hcom, &li); int32_t sz = static_cast (li.LowPart); FILETIME ftCreate, ftAccess, ftWrite; if (!GetFileTime(hcom, &ftCreate, &ftAccess, &ftWrite)) { throw failure("File::CalculateMarshallingSize -- GetFileTime failed"); } // convert FILETIME to time_t ULARGE_INTEGER ull; ull.LowPart = ftWrite.dwLowDateTime; ull.HighPart = ftWrite.dwHighDateTime; time_t mod_time = ull.QuadPart / 10000000ULL - 11644473600ULL; (mod_time > File::lastruntime_) ? updated_ = true : updated_ = false; CloseHandle(hcom); #else int fd = open(name_.c_str(), O_RDONLY); if (fd < 0) { throw failure("File::CalculateMarshallingSize -- open failed ") << name_.c_str(); } struct stat sb; if (fstat(fd, &sb) == -1) { close(fd); throw failure("File::CalculateMarshallingSize -- fstat failed."); } int32_t sz = static_cast(sb.st_size); (sb.st_mtime > File::lastruntime_) ? updated_ = true : updated_ = false; close(fd); #endif if (updated_) { cntr.Add(sizeof(sz) + sz); } } lil_string Name() { return name_; } static void load_lastruntime(char const* filename) { FILE* Fl; if ((Fl = fopen(filename, "rb")) != NULL) { fread(&File::lastruntime_, sizeof(File::lastruntime_), 1, Fl); fclose(Fl); } else { File::lastruntime_ = 0; } } template static void save_lastruntime(char const* filename, T time) { FILE* Fl; if ((Fl = fopen(filename, "wb")) != NULL) { if (fwrite(&time, sizeof(time), 1, Fl) != 1) { throw failure("LastRunTime::Update fwrite failed"); } fclose(Fl); } else { throw failure("LastRunTime::Update fopen failed"); } } }; #endif