1 /**********************************************************************************************
2     Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 **********************************************************************************************/
18 
19 #include "CQlgtRoute.h"
20 
21 struct rte_head_entry_t
22 {
rte_head_entry_trte_head_entry_t23     rte_head_entry_t() : type(CQlgtRoute::eEnd), offset(0)
24     {
25     }
26     qint32 type;
27     quint32 offset;
28     QByteArray data;
29 };
30 
31 
operator >>(QDataStream & s,CQlgtRoute & route)32 QDataStream& operator >>(QDataStream& s, CQlgtRoute& route)
33 {
34     quint32 nRtePts = 0;
35     QIODevice* dev = s.device();
36     qint64 pos = dev->pos();
37 
38     char magic[9];
39     s.readRawData(magic, 9);
40 
41     if(strncmp(magic, "QLRte   ", 9))
42     {
43         dev->seek(pos);
44         return s;
45     }
46 
47     QList<rte_head_entry_t> entries;
48 
49     while(1)
50     {
51         rte_head_entry_t entry;
52         s >> entry.type >> entry.offset;
53         entries << entry;
54         if(entry.type == CQlgtRoute::eEnd)
55         {
56             break;
57         }
58     }
59 
60     QList<rte_head_entry_t>::iterator entry = entries.begin();
61     while(entry != entries.end())
62     {
63         qint64 o = pos + entry->offset;
64         dev->seek(o);
65         s >> entry->data;
66 
67         switch(entry->type)
68         {
69         case CQlgtRoute::eBase:
70         {
71             QDataStream s1(&entry->data, QIODevice::ReadOnly);
72             s1.setVersion(QDataStream::Qt_4_5);
73 
74             s1 >> route.key;
75             s1 >> route.timestamp;
76             s1 >> route.name;
77             s1 >> route.iconString;
78             s1 >> route.ttime;
79             s1 >> route.parentWpt;
80 
81             break;
82         }
83 
84         case CQlgtRoute::eRtePts:
85         {
86             QDataStream s1(&entry->data, QIODevice::ReadOnly);
87             s1.setVersion(QDataStream::Qt_4_5);
88             quint32 n;
89 
90             route.priRoute.clear();
91             s1 >> nRtePts;
92 
93             for(n = 0; n < nRtePts; ++n)
94             {
95                 CQlgtRoute::pt_t rtept;
96                 float u, v;
97                 QString action;
98 
99                 s1 >> u;
100                 s1 >> v;
101                 s1 >> action;
102 
103                 rtept.lon = u;
104                 rtept.lat = v;
105                 rtept.action = action;
106                 route.priRoute << rtept;
107             }
108             break;
109         }
110 //            case CQlgtRoute::eRteSec:
111 //            {
112 //                QDataStream s1(&entry->data, QIODevice::ReadOnly);
113 //                s1.setVersion(QDataStream::Qt_4_5);
114 //                quint32 n;
115 
116 //                route.secRoute.clear();
117 //                s1 >> nRtePts;
118 
119 //                for(n = 0; n < nRtePts; ++n)
120 //                {
121 //                    CQlgtRoute::pt_t rtept;
122 //                    float u, v;
123 //                    QString action;
124 
125 //                    s1 >> u;
126 //                    s1 >> v;
127 //                    s1 >> action;
128 
129 //                    rtept.lon = u;
130 //                    rtept.lat = v;
131 //                    rtept.action = action;
132 //                    route.secRoute << rtept;
133 //                }
134 //                break;
135 //            }
136         default:
137             ;
138         }
139 
140         ++entry;
141     }
142 
143 
144     return s;
145 }
146 
operator <<(QDataStream & s,CQlgtRoute & route)147 QDataStream& operator <<(QDataStream& s, CQlgtRoute& route)
148 {
149     QList<rte_head_entry_t> entries;
150 
151     //---------------------------------------
152     // prepare base data
153     //---------------------------------------
154     rte_head_entry_t entryBase;
155     entryBase.type = CQlgtRoute::eBase;
156     QDataStream s1(&entryBase.data, QIODevice::WriteOnly);
157     s1.setVersion(QDataStream::Qt_4_5);
158 
159     s1 << route.key;
160     s1 << route.timestamp;
161     s1 << route.name;
162     s1 << route.iconString;
163     s1 << route.ttime;
164     s1 << route.parentWpt;
165 
166     entries << entryBase;
167 
168     //---------------------------------------
169     // prepare primary routepoint data
170     //---------------------------------------
171     rte_head_entry_t entryPriRtePts;
172     entryPriRtePts.type = CQlgtRoute::eRtePts;
173     QDataStream s2(&entryPriRtePts.data, QIODevice::WriteOnly);
174     s2.setVersion(QDataStream::Qt_4_5);
175 
176     {
177         QVector<CQlgtRoute::pt_t>& rtepts = route.priRoute;
178         QVector<CQlgtRoute::pt_t>::iterator rtept = rtepts.begin();
179 
180         s2 << (quint32)rtepts.size();
181         while(rtept != rtepts.end())
182         {
183             s2 << (float)rtept->lon;
184             s2 << (float)rtept->lat;
185             s2 << rtept->action;
186             ++rtept;
187         }
188     }
189     entries << entryPriRtePts;
190 
191 //    //---------------------------------------
192 //    // prepare secondary routepoint data
193 //    //---------------------------------------
194 //    rte_head_entry_t entrySecRtePts;
195 //    entrySecRtePts.type = CQlgtRoute::eRteSec;
196 //    QDataStream s3(&entrySecRtePts.data, QIODevice::WriteOnly);
197 //    s3.setVersion(QDataStream::Qt_4_5);
198 
199 //    {
200 //        QVector<CQlgtRoute::pt_t>& rtepts           = route.getSecRtePoints();
201 //        QVector<CQlgtRoute::pt_t>::iterator rtept   = rtepts.begin();
202 
203 //        if(!rtepts.isEmpty())
204 //        {
205 //            s3 << (quint32)rtepts.size();
206 //            while(rtept != rtepts.end())
207 //            {
208 //                s3 << (float)rtept->lon;
209 //                s3 << (float)rtept->lat;
210 //                s3 << rtept->action;
211 //                ++rtept;
212 //            }
213 //            entries << entrySecRtePts;
214 //        }
215 
216 //    }
217 
218     //---------------------------------------
219     // prepare terminator
220     //---------------------------------------
221     rte_head_entry_t entryEnd;
222     entryEnd.type = CQlgtRoute::eEnd;
223     entries << entryEnd;
224 
225     //---------------------------------------
226     //---------------------------------------
227     // now start to actually write data;
228     //---------------------------------------
229     //---------------------------------------
230     // write magic key
231     s.writeRawData("QLRte   ", 9);
232 
233     // calculate offset table
234     quint32 offset = entries.count() * 8 + 9;
235 
236     QList<rte_head_entry_t>::iterator entry = entries.begin();
237     while(entry != entries.end())
238     {
239         entry->offset = offset;
240         offset += entry->data.size() + sizeof(quint32);
241         ++entry;
242     }
243 
244     // write offset table
245     entry = entries.begin();
246     while(entry != entries.end())
247     {
248         s << entry->type << entry->offset;
249         ++entry;
250     }
251 
252     // write entry data
253     entry = entries.begin();
254     while(entry != entries.end())
255     {
256         s << entry->data;
257         ++entry;
258     }
259 
260 
261     return s;
262 }
263 
CQlgtRoute(quint64 id,QObject * parent)264 CQlgtRoute::CQlgtRoute(quint64 id, QObject* parent)
265     : QObject(parent)
266     , IItem(id)
267 {
268 }
269 
~CQlgtRoute()270 CQlgtRoute::~CQlgtRoute()
271 {
272 }
273 
274