-
Notifications
You must be signed in to change notification settings - Fork 330
/
Copy pathFileAdapter.h
227 lines (196 loc) · 8.56 KB
/
FileAdapter.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* -------------------------------------------------------------------------- *
* OpenSim: FileAdapter.h *
* -------------------------------------------------------------------------- *
* The OpenSim API is a toolkit for musculoskeletal modeling and simulation. *
* OpenSim is developed at Stanford University and supported by the US *
* National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA *
* through the Warrior Web program. *
* *
* Copyright (c) 2005-2017 Stanford University and the Authors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain a *
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* -------------------------------------------------------------------------- */
#ifndef OPENSIM_FILE_ADAPTER_H_
#define OPENSIM_FILE_ADAPTER_H_
/** @file
* This file defines an abstract FileAdapter class, which implements the
OpenSim::DataAdpater interface for reading or writing data files.
*/
#include "DataAdapter.h"
#include <vector>
namespace OpenSim {
class EmptyFileName : public InvalidArgument {
public:
EmptyFileName(const std::string& file,
size_t line,
const std::string& func) :
InvalidArgument(file, line, func) {
std::string msg = "Filename is empty.";
addMessage(msg);
}
};
class FileDoesNotExist : public IOError {
public:
FileDoesNotExist(const std::string& file,
size_t line,
const std::string& func,
const std::string filename) :
IOError(file, line, func) {
std::string msg = "File '" + filename + "' does not exist.";
addMessage(msg);
}
};
class FileIsEmpty : public IOError {
public:
FileIsEmpty(const std::string& file,
size_t line,
const std::string& func,
const std::string& filename) :
IOError(file, line, func) {
std::string msg = "File '" + filename + "' is empty.";
addMessage(msg);
}
};
class FileExtensionNotFound : public InvalidArgument {
public:
FileExtensionNotFound(const std::string& file,
size_t line,
const std::string& func,
const std::string& filename) :
InvalidArgument(file, line, func) {
std::string msg = "Error inferring extension for file '";
msg += filename + "'.";
addMessage(msg);
}
};
class UnexpectedColumnLabel : public IOError {
public:
UnexpectedColumnLabel(const std::string& file,
size_t line,
const std::string& func,
const std::string& filename,
const std::string& expected,
const std::string& received) :
IOError(file, line, func) {
std::string msg = "Error reading column labels in file '" + filename;
msg += "'. Unexpected column label. ";
msg += "Expected = " + expected + ". ";
msg += "Received = " + received + ". ";
addMessage(msg);
}
};
class RowLengthMismatch : public IOError {
public:
RowLengthMismatch(const std::string& file,
size_t line,
const std::string& func,
const std::string& filename,
size_t line_num,
size_t expected,
size_t received) :
IOError(file, line, func) {
std::string msg = "Error reading rows in file '" + filename + "'. ";
msg += "Unexpected number of columns in line ";
msg += std::to_string(line_num) + ". ";
msg += "Expected = " + std::to_string(expected) + ". ";
msg += "Received = " + std::to_string(received) + ". ";
addMessage(msg);
}
};
class NoTableFound : public InvalidArgument {
public:
NoTableFound(const std::string& file,
size_t line,
const std::string& func) :
InvalidArgument(file, line, func) {
std::string msg = "No table to write.";
addMessage(msg);
}
};
class KeyMissing : public InvalidArgument {
public:
KeyMissing(const std::string& file,
size_t line,
const std::string& func,
const std::string& key) :
InvalidArgument(file, line, func) {
std::string msg = "Key '" + key + "' missing.";
addMessage(msg);
}
};
class IncorrectTableType : public InvalidArgument {
public:
IncorrectTableType(const std::string& file,
size_t line,
const std::string& func,
const std::string& message = "") :
InvalidArgument(file, line, func) {
std::string msg = "Incorrect Table type.";
if(!message.empty())
msg += " " + message;
addMessage(msg);
}
};
class TableMissingHeader : public Exception {
public:
TableMissingHeader(const std::string& file,
size_t line,
const std::string& func,
const std::string& message = "") :
Exception(file, line, func) {
std::string msg = "Table does not have metadata for 'header'.";
if(!message.empty())
msg += " " + message;
addMessage(msg);
}
};
/** FileAdapter is a DataAdapter that reads and writes files with methods
read and writeFile respectively. The read method is implemented in the base class and it
calls the virtual extendRead method implemented by format specific subclasses.
Typically you don't need to call read explicitly if reading one DataTable from file, instead use
a constructor of the table from the specific file. e.g.
\code{.cpp}
TimeSeriesTableVec3 table(filename);
\endcode
*/
class OSIMCOMMON_API FileAdapter : public DataAdapter {
public:
FileAdapter() = default;
FileAdapter(const FileAdapter&) = default;
FileAdapter(FileAdapter&&) = default;
FileAdapter& operator=(const FileAdapter&) = default;
FileAdapter& operator=(FileAdapter&&) = default;
virtual ~FileAdapter() = default;
/** Write a collection of tables to the given file. Different file formats
require different number/type of tables. See specific adapter's
documentation to see what is required. */
static void writeFile(const InputTables& tables,
const std::string& fileName);
/** Find the extension from a filename. */
static
std::string findExtension(const std::string& filename);
/** Get the next line from the stream and tokenize/split the line using
the given delimiters. */
static std::vector<std::string> getNextLine(std::istream& stream,
const std::string& delims);
/** Tokenize/split a given string using the given delimiters. The delimiters
are each required to be one character and the string is split if/when any
of those characters are found. For example, a delimiter string " \t"
specifies that either a space or a tab can act as the delimiter. */
static std::vector<std::string> tokenize(const std::string& str,
const std::string& delims);
/** Create a concerte FileAdapter based on the extension of the passed in file and return it.
This serves as a Factory of FileAdapters so clients don't need to know specific concrete
subclasses, as long as the generic base class read interface is used */
static std::shared_ptr<DataAdapter> createAdapterFromExtension(const std::string& fileName);
};
} // OpenSim namespace
#endif // OPENSIM_FILE_ADAPTER_H_