4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "WaypointReaderBase.hpp"
26 #include "Terrain/RasterTerrain.hpp"
27 #include "Waypoint/Waypoint.hpp"
28 #include "Waypoint/Waypoints.hpp"
29 #include "Operation/Operation.hpp"
30 #include "IO/LineReader.hpp"
34 WaypointReaderBase::WaypointReaderBase(const int _file_num
,
38 compressed(_compressed
)
42 static bool is_closing_quote_char(TCHAR
const *s
) {
43 // Perform look-ahead to check if the detected quote_char terminates
44 // the quoted field. true for (optional) ' 's followed by ',' or
45 // end of input string.
46 while (*s
!= _T('\0')) {
57 WaypointReaderBase::ExtractParameters(const TCHAR
*src
, TCHAR
*dst
,
58 const TCHAR
**arr
, size_t sz
,
59 const bool trim
, const TCHAR quote_char
)
68 bool in_quote
= false;
74 // pointer to last character of d after which ' ' might be discarded for
75 // trimming. NULL can be used to test for start of field condition.
76 TCHAR
*last_non_discardable_char
= NULL
;
79 if (quote_char
&& *s
== quote_char
) {
80 // Handle quote characters if enabled, current char of src is quote_char
81 if (in_quote
&& is_closing_quote_char(s
+1)) {
82 // If currently in quoted string leave quote handling depending on
83 // look-ahead performed in is_closing_quote_char()
85 } else if (!in_quote
&& last_non_discardable_char
== NULL
) {
86 // Quote start detected at beginning of new field
89 // Quote inside quoted string (but not end), copy to dst
90 last_non_discardable_char
= d
;
92 if (*(s
+1) == quote_char
) {
93 // Spreadsheets use "" while exporting a single " contained in
94 // a textfield to a CSV file - skip second "
98 } else if (*s
== _T('\0') || ((*s
== _T(',') && !in_quote
))) {
99 // end of src or field separator (',') outside quoted part detected
100 // field content is already completely copied but may contain trailing spaces
101 if (trim
&& (last_non_discardable_char
!= NULL
))
102 // remove trailing unquoted whitespace from dst field
103 d
= last_non_discardable_char
+1;
105 // 0-terminate field and update pointer to individual field
108 // if size permits remember start of next field.
111 // start processing of next field
112 last_non_discardable_char
= NULL
;
114 // main part copying from src to dst
115 if (trim
&& !in_quote
) {
116 // we are not inside a quoted string and therefore need to trim
117 // leading and trailing spaces. Drop whitespace if dst is still empty
119 if (last_non_discardable_char
!= NULL
)
120 // dst field is not empty - append ' '
123 // no space, remember position and append to result
124 last_non_discardable_char
= d
;
128 // normal copy src to dst, all chars are retained
129 // all characters are not subject to trimming (even spaces)
130 last_non_discardable_char
= d
;
134 // advance src until end reached or no space in field pointers
135 } while (*s
++ != _T('\0') && i
< sz
);
141 WaypointReaderBase::CheckAltitude(Waypoint
&new_waypoint
,
142 const RasterTerrain
*terrain
)
147 // Load waypoint altitude from terrain
148 const short t_alt
= terrain
->GetTerrainHeight(new_waypoint
.location
);
149 if (RasterBuffer::IsSpecial(t_alt
))
150 new_waypoint
.elevation
= fixed(0);
153 new_waypoint
.elevation
= (fixed
)t_alt
;
159 WaypointReaderBase::CheckAltitude(Waypoint
&new_waypoint
) const
161 return CheckAltitude(new_waypoint
, terrain
);
165 WaypointReaderBase::Parse(Waypoints
&way_points
, TLineReader
&reader
,
166 OperationEnvironment
&operation
)
168 const long filesize
= std::max(reader
.GetSize(), 1l);
169 operation
.SetProgressRange(100);
171 // Read through the lines of the file
173 for (unsigned i
= 0; (line
= reader
.ReadLine()) != NULL
; i
++) {
175 ParseLine(line
, i
, way_points
);
178 operation
.SetProgressPosition(reader
.Tell() * 100 / filesize
);