SectorZone: add attribute arc_boundary
[xcsoar.git] / src / Waypoint / WaypointReaderBase.cpp
blobd9eff449cc899dfbd17d252f99d9dddb5f40b595
1 /*
2 Copyright_License {
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"
32 #include <assert.h>
34 WaypointReaderBase::WaypointReaderBase(const int _file_num,
35 bool _compressed):
36 file_num(_file_num),
37 terrain(NULL),
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')) {
47 if (*s == _T(','))
48 return true;
49 if (*s != _T(' '))
50 return false;
51 s++;
53 return true;
56 size_t
57 WaypointReaderBase::ExtractParameters(const TCHAR *src, TCHAR *dst,
58 const TCHAR **arr, size_t sz,
59 const bool trim, const TCHAR quote_char)
61 assert(src != NULL);
62 assert(dst != NULL);
63 assert(arr != NULL);
64 assert(sz > 0);
66 TCHAR *d = dst;
67 TCHAR const *s = src;
68 bool in_quote = false;
70 size_t i = 0;
71 *d = _T('\0');
72 arr[i] = d;
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;
78 do {
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()
84 in_quote = false;
85 } else if (!in_quote && last_non_discardable_char == NULL) {
86 // Quote start detected at beginning of new field
87 in_quote = true;
88 } else {
89 // Quote inside quoted string (but not end), copy to dst
90 last_non_discardable_char = d;
91 *d++ = *s;
92 if (*(s+1) == quote_char) {
93 // Spreadsheets use "" while exporting a single " contained in
94 // a textfield to a CSV file - skip second "
95 s++;
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
106 *d++ = _T('\0');
107 if (++i < sz)
108 // if size permits remember start of next field.
109 arr[i] = d;
111 // start processing of next field
112 last_non_discardable_char = NULL;
113 } else {
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
118 if (*s == _T(' ')) {
119 if (last_non_discardable_char != NULL)
120 // dst field is not empty - append ' '
121 *d++ = *s;
122 } else {
123 // no space, remember position and append to result
124 last_non_discardable_char = d;
125 *d++ = *s;
127 } else {
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;
131 *d++ = *s;
134 // advance src until end reached or no space in field pointers
135 } while (*s++ != _T('\0') && i < sz);
137 return i;
140 bool
141 WaypointReaderBase::CheckAltitude(Waypoint &new_waypoint,
142 const RasterTerrain *terrain)
144 if (terrain == NULL)
145 return false;
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);
151 else
152 // TERRAIN_VALID
153 new_waypoint.elevation = (fixed)t_alt;
155 return true;
158 bool
159 WaypointReaderBase::CheckAltitude(Waypoint &new_waypoint) const
161 return CheckAltitude(new_waypoint, terrain);
164 void
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
172 TCHAR *line;
173 for (unsigned i = 0; (line = reader.ReadLine()) != NULL; i++) {
174 // and parse them
175 ParseLine(line, i, way_points);
177 if ((i & 0x3f) == 0)
178 operation.SetProgressPosition(reader.Tell() * 100 / filesize);