This repository has been archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomm.h
194 lines (180 loc) · 6.46 KB
/
comm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// SPDX-FileCopyrightText: 2011-2012 Tasos Varoudis
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <chrono>
#include <fstream>
#include <string>
#include <sys/types.h>
#include <vector>
#ifdef _WIN32
// Quick mod - TV
#pragma warning(disable : 4244)
#pragma warning(disable : 4100)
#else
#endif
const char *const g_default_file_set = "File set";
struct FilePath {
std::string path;
std::string name;
std::string ext;
FilePath(const std::string &pathname) {
size_t dot = pathname.find_last_of('.');
#ifdef _WIN32
size_t slash = pathname.find_last_of('\\'); // WIN32
#else
size_t slash = pathname.find_last_of('/'); // Other
#endif
if (slash != std::string::npos) {
path = pathname.substr(0, slash + 1);
}
if (dot != std::string::npos) {
name = pathname.substr(slash + 1, dot - slash - 1);
ext = pathname.substr(dot + 1);
} else {
name = pathname.substr(slash + 1);
}
}
};
class Communicator {
public:
class CancelledException // throw from your class
{
public:
CancelledException() { ; }
};
enum { NUM_STEPS, CURRENT_STEP, NUM_RECORDS, CURRENT_RECORD };
protected:
mutable bool m_cancelled;
bool m_deleteFlag;
// nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11)
std::string m_infilename;
std::ifstream *m_infile;
std::ifstream *m_infile2; // <- MapInfo MIF files come in two parts
std::ofstream *m_outfile;
// nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11)
std::vector<std::string> m_fileset; // <- sometimes you want to load a whole set of files
public:
Communicator()
: m_cancelled(false), m_deleteFlag(false), m_infile(nullptr), m_infile2(nullptr),
m_outfile(nullptr) {}
//
bool GetDeleteFlag() // used by ICommunicator and IComm together
{
return m_deleteFlag;
}
//
virtual ~Communicator() {
if (m_infile)
delete m_infile;
m_infile = nullptr;
if (m_infile2)
delete m_infile2;
m_infile2 = nullptr;
if (m_outfile)
delete m_outfile;
m_outfile = nullptr;
}
//
void SetInfile(const char *filename) {
m_infile = new std::ifstream(filename);
FilePath fp(filename);
m_infilename = fp.name;
}
void SetInfile2(const char *filename) { m_infile2 = new std::ifstream(filename); }
std::string GetInfileName() {
return m_fileset.size() ? std::string(g_default_file_set) : m_infilename;
}
std::string GetMBInfileName() {
std::string ret;
if (!m_fileset.empty()) {
ret = "File set";
} else {
ret = std::string(m_infilename.c_str());
}
return ret;
}
long GetInfileSize() {
if (m_infile) {
m_infile->seekg(0, std::ios::beg);
long beginPos = m_infile->tellg();
m_infile->seekg(0, std::ios::end);
long endPos = m_infile->tellg();
m_infile->seekg(0, std::ios::beg);
return endPos - beginPos;
}
return 0;
}
void SetOutfile(const char *filename) { m_outfile = new std::ofstream(filename); }
//
bool IsCancelled() const { return m_cancelled; }
void Cancel() { m_cancelled = true; }
// const version is for cases where we need to Cancel from a const
// context, for example from within an implemented CommPostMessage,
// i.e. in cases where an external handler does not explicitly
// cancel, but instead also sets a "cancelled" variable
void Cancel() const { m_cancelled = true; }
std::ifstream &getInFileStream() { return *m_infile; }
std::ifstream &GetInfile2() { return *m_infile2; }
//
const std::vector<std::string> &GetFileSet() const { return m_fileset; }
//
virtual void CommPostMessage(size_t m,
size_t x) const = 0; // Override for specific operating system
};
// this is a simple version of the Communicator which can be used for
// an interface
class ICommunicator : public Communicator {
friend class IComm; // IComm is found in idepthmap.h
//
protected:
mutable size_t m_numSteps;
mutable size_t m_numRecords;
mutable size_t m_step;
mutable size_t m_record;
//
public:
ICommunicator() {
m_deleteFlag = true;
} // note: an ICommunicator lets IComm know that it should delete it
~ICommunicator() override { ; }
void CommPostMessage(size_t m, size_t x) const override;
};
inline void ICommunicator::CommPostMessage(size_t m, size_t x) const {
switch (m) {
case Communicator::NUM_STEPS:
m_numSteps = x;
break;
case Communicator::CURRENT_STEP:
m_step = x;
break;
case Communicator::NUM_RECORDS:
m_numRecords = x;
break;
case Communicator::CURRENT_RECORD:
m_record = x;
break;
default:
break;
}
}
// a helpful little function...
// This function is used exclusively to update the communicators at specific intervals (set in
// milliseconds by the timeout argument). Typical usage: Create a time_t t1 and pass to this
// function with timeout = 0, setting thus t1 to the current time in milliseconds. Then continuously
// pass the same t1 to this function along with an interval timeout (in most cases 500ms). The
// function only synchronises t1 to the current time if its difference to the current time is longer
// than the interval (i.e. more than 500 milliseconds have passed since the last synchronisation).
// If a synchronisation occurs then the communicator is updated along with the equivalent user
// interface element.
// TODO: All time handling in the application uses time_t and stores milliseconds in it, though
// time_t is supposed to only store seconds. Replace with std::chrono::time_point everywhere
inline bool qtimer(time_t &t1, time_t timeout) {
auto time2 = std::chrono::system_clock::now().time_since_epoch();
time_t t2 = std::chrono::duration_cast<std::chrono::milliseconds>(time2).count();
if ((t2 - t1) > timeout || (t2 - t1) < 0) { // also catch a loop
t1 = t2;
return true;
}
return false;
}