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 "Task/TaskFileIGC.hpp"
25 #include "IGC/IGCParser.hpp"
26 #include "IGC/IGCDeclaration.hpp"
27 #include "IO/FileLineReader.hpp"
28 #include "Engine/Task/Factory/AbstractTaskFactory.hpp"
29 #include "Engine/Task/Ordered/OrderedTask.hpp"
30 #include "Engine/Task/Ordered/Points/StartPoint.hpp"
31 #include "Engine/Task/Ordered/Points/FinishPoint.hpp"
32 #include "Engine/Task/Ordered/Points/IntermediatePoint.hpp"
33 #include "Language/Language.hpp"
34 #include "Waypoint/Waypoint.hpp"
40 ReadIGCDeclaration(const TCHAR
*path
, IGCDeclarationHeader
&header
,
41 std::list
<IGCDeclarationTurnpoint
> &turnpoints
)
43 // Create FileReader for reading the task
44 FileLineReaderA
reader(path
);
50 bool header_found
= false;
51 while ((line
= reader
.ReadLine()) != NULL
) {
52 // Skip lines which are not declaration records
57 if (!IGCParseDeclarationHeader(line
, header
))
64 IGCDeclarationTurnpoint tp
;
65 if (IGCParseDeclarationTurnpoint(line
, tp
))
66 turnpoints
.emplace_back(tp
);
73 TaskFileIGC::GetTask(const TaskBehaviour
&task_behaviour
,
74 const Waypoints
*waypoints
, unsigned index
) const
78 IGCDeclarationHeader header
;
79 std::list
<IGCDeclarationTurnpoint
> turnpoints
;
81 if (!ReadIGCDeclaration(path
, header
, turnpoints
))
84 // Number of turnpoints including start and finish
85 unsigned num_turnpoints
= header
.num_turnpoints
+ 2;
87 if (num_turnpoints
+ 2 == turnpoints
.size()) {
88 // Remove takeoff and landing points from the turnpoints list
89 turnpoints
.pop_front();
90 turnpoints
.pop_back();
91 } else if (num_turnpoints
!= turnpoints
.size())
92 // Declared number of turnpoints is not matching parsed number of turnpoints
95 // Create a blank task
96 OrderedTask
*task
= new OrderedTask(task_behaviour
);
97 AbstractTaskFactory
&fact
= task
->GetFactory();
100 for (const auto &it
: turnpoints
) {
101 StaticString
<256> waypoint_name
;
102 if (!it
.name
.empty()) {
103 waypoint_name
.clear();
104 waypoint_name
.UnsafeAppendASCII(it
.name
);
106 waypoint_name
= _T("Start");
107 else if (i
== num_turnpoints
- 1)
108 waypoint_name
= _T("Finish");
110 waypoint_name
.Format(_T("%s #%u"), _T("Turnpoint"), i
);
112 Waypoint
wp(it
.location
);
113 wp
.name
= waypoint_name
.c_str();
115 /* we don't know the elevation, so we just set it to zero; this is
116 not correct, but better than leaving it uninitialised */
117 wp
.elevation
= fixed(0);
119 OrderedTaskPoint
*tp
;
122 tp
= fact
.CreateStart(wp
);
123 else if (i
== num_turnpoints
- 1)
124 tp
= fact
.CreateFinish(wp
);
126 tp
= fact
.CreateIntermediate(wp
);
143 FileLineReaderA
reader(path
);
147 IGCDeclarationHeader header
;
149 // Search for declaration
151 while ((line
= reader
.ReadLine()) != NULL
) {
155 if (!IGCParseDeclarationHeader(line
, header
) ||
156 header
.num_turnpoints
== 0)
159 if (!header
.task_name
.empty() &&
160 !StringIsEqual(header
.task_name
, "Task")) {
161 // Remember the task name
162 StaticString
<256> task_name
;
164 task_name
.UnsafeAppendASCII(header
.task_name
.c_str());
165 namesuffixes
.append(_tcsdup(task_name
.c_str()));