1 /* ************************
2    Copyright Terrain Experts Inc.
3    Terrain Experts Inc (TERREX) reserves all rights to this source code
4    unless otherwise specified in writing by the President of TERREX.
5    This copyright may be updated in the future, in which case that version
6    supercedes this one.
7    -------------------
8    Terrex Experts Inc.
9    4400 East Broadway #314
10    Tucson, AZ  85711
11    info@terrex.com
12    Tel: (520) 323-7990
13    ************************
14    */
15 
16 /* trpage_range.cpp
17     Methods for the Range Table.  Consult trpg_geom.h for details
18     on what this is and how it works.
19     */
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include <trpage_geom.h>
26 #include <trpage_read.h>
27 
28 /* *******************
29     Range Methods
30    *******************
31  */
32 
trpgRange(void)33 trpgRange::trpgRange(void)
34 {
35     category = NULL;
36     subCategory = NULL;
37     Reset();
38 }
39 
~trpgRange(void)40 trpgRange::~trpgRange(void)
41 {
42     Reset();
43 }
44 
trpgRange(const trpgRange & in)45 trpgRange::trpgRange(const trpgRange &in):
46     trpgReadWriteable(in)
47 {
48     category = NULL;
49     subCategory = NULL;
50     *this = in;
51 }
52 
Reset(void)53 void trpgRange::Reset(void)
54 {
55     errMess[0] = '\0';
56     if (category)
57         delete [] category;
58     category = NULL;
59     if (subCategory)
60         delete [] subCategory;
61     subCategory = NULL;
62 
63     inLod = outLod = 0.0;
64     priority = 0;
65     handle = -1;
66     writeHandle = false;
67 }
68 
SetCategory(const char * cat,const char * subCat)69 void trpgRange::SetCategory(const char *cat,const char *subCat)
70 {
71     if (category)  delete [] category;
72     category = NULL;
73     if (cat) {
74         category = new char[strlen(cat)+1];
75         strcpy(category,cat);
76     }
77 
78     if (subCategory)  delete [] subCategory;
79     subCategory = NULL;
80     if (subCat) {
81         subCategory = new char[strlen(subCat)+1];
82         strcpy(subCategory,subCat);
83     }
84 }
85 
GetCategory(char * cat,int catLen,char * subCat,int subCatLen) const86 void trpgRange::GetCategory(char *cat,int catLen,char *subCat,int subCatLen) const
87 {
88     if (category && cat) {
89         strncpy(cat,category,catLen);
90     } else
91         *cat = 0;
92     if (subCategory && subCat) {
93         strncpy(subCat,subCategory,subCatLen);
94     } else
95         *subCat = 0;
96 }
97 
SetLodInfo(double in,double out)98 void trpgRange::SetLodInfo(double in,double out)
99 {
100     inLod = in;
101     outLod = out;
102 }
103 
GetLodInfo(double & in,double & out) const104 void trpgRange::GetLodInfo(double &in,double &out) const
105 {
106     in = inLod;
107     out = outLod;
108 }
109 
SetPriority(int prior)110 void trpgRange::SetPriority(int prior)
111 {
112     priority = prior;
113 }
114 
GetPriority(int & prior) const115 void trpgRange::GetPriority(int &prior) const
116 {
117     prior = priority;
118 }
119 
operator =(const trpgRange & other)120 trpgRange & trpgRange::operator = (const trpgRange &other)
121 {
122     Reset();
123     inLod = other.inLod;
124     outLod = other.outLod;
125     SetCategory(other.category,other.subCategory);
126     priority = other.priority;
127     handle = other.handle;
128     writeHandle = other.writeHandle;
129     return *this;
130 }
131 
operator ==(const trpgRange & in) const132 bool trpgRange::operator == (const trpgRange &in) const
133 {
134     if (inLod != in.inLod || outLod != in.outLod)
135         return false;
136     if (priority != in.priority)  return false;
137 
138     if (category && in.category) {
139         if (strcmp(category,in.category))
140             return false;
141     } else {
142         if ((category && !in.category) ||
143             (!category && in.category) )
144             return false;
145     }
146 
147     if (subCategory && in.subCategory) {
148         if (strcmp(subCategory,in.subCategory))
149             return false;
150     } else {
151         if ((subCategory && !in.subCategory) ||
152             (subCategory && in.subCategory))
153             return false;
154     }
155     if(handle != in.handle)
156         return false;
157     if(writeHandle != in.writeHandle)
158         return false;
159     return true;
160 }
161 
Write(trpgWriteBuffer & buf)162 bool trpgRange::Write(trpgWriteBuffer &buf)
163 {
164     buf.Begin(TRPG_RANGE);
165     buf.Add(inLod);
166     buf.Add(outLod);
167     buf.Add(priority);
168     buf.Add((category ? category : ""));
169     buf.Add((subCategory ? subCategory : ""));
170     if(writeHandle) {
171         buf.Add((int32)handle);
172     }
173     buf.End();
174 
175     return true;
176 }
177 
Read(trpgReadBuffer & buf)178 bool trpgRange::Read(trpgReadBuffer &buf)
179 {
180     char catStr[1024],subStr[1024];
181 
182     Reset();
183     valid = false;
184 
185     try {
186         buf.Get(inLod);
187         buf.Get(outLod);
188         buf.Get(priority);
189         buf.Get(catStr,1024);
190         buf.Get(subStr,1024);
191         SetCategory(catStr,subStr);
192 
193         // Read the handle if we can..
194         try {
195             int32 tempHandle;
196             if(buf.Get(tempHandle))
197             {
198                 handle = tempHandle;
199             }
200             else
201             {
202                 handle = -1;
203             }
204         }
205         catch (...) {
206             handle = -1;
207         }
208         valid = true;
209     }
210 
211     catch (...) {
212         return false;
213     }
214 
215     return isValid();
216 }
217 
218 /*  ***************
219     Range Table methods
220     ***************
221  */
222 
trpgRangeTable(void)223 trpgRangeTable::trpgRangeTable(void)
224 {
225     valid = true;
226 }
227 
~trpgRangeTable(void)228 trpgRangeTable::~trpgRangeTable(void)
229 {
230     // vector cleans up itself
231 }
232 
Reset(void)233 void trpgRangeTable::Reset(void)
234 {
235     rangeMap.clear();
236     valid = true;
237 }
238 
GetRange(int id,trpgRange & ret) const239 bool trpgRangeTable::GetRange(int id,trpgRange &ret) const
240 {
241     if (!isValid())
242         return false;
243 
244     if (id < 0)// || id >= rangeList.size())
245         return false;
246 
247     RangeMapType::const_iterator itr = rangeMap.find(id);
248     if(itr == rangeMap.end()) {
249         return false;
250     }
251     ret = itr->second;
252     return true;
253 }
254 
SetRange(int id,trpgRange & inRange)255 bool trpgRangeTable::SetRange(int id,trpgRange &inRange)
256 {
257     if (!isValid())
258         return false;
259 
260     if (id < 0)// || id >= rangeList.size())
261         return false;
262 
263     rangeMap[id] = inRange;
264 
265     return true;
266 }
267 
AddRange(trpgRange & range)268 int trpgRangeTable::AddRange(trpgRange &range)
269 {
270     int handle = range.GetHandle();
271     if(handle==-1) {
272         handle = rangeMap.size();
273     }
274     rangeMap[handle] = range;
275     return handle;
276 
277 }
278 
FindAddRange(trpgRange & range)279 int trpgRangeTable::FindAddRange(trpgRange &range)
280 {
281     RangeMapType::iterator itr = rangeMap.begin();
282     for (  ; itr != rangeMap.end( ); itr++) {
283         if(itr->second==range)
284             return itr->first;
285     }
286 
287 #if 0
288     for (int i=0;i<rangeList.size();i++) {
289         if (range == rangeList[i])
290             return i;
291     }
292 #endif
293     return AddRange(range);
294 }
295 
Write(trpgWriteBuffer & buf)296 bool trpgRangeTable::Write(trpgWriteBuffer &buf)
297 {
298     if (!isValid())
299         return false;
300 
301     buf.Begin(TRPGRANGETABLE);
302     buf.Add((int32)rangeMap.size());
303 
304     RangeMapType::iterator itr = rangeMap.begin();
305     for (  ; itr != rangeMap.end( ); itr++) {
306         trpgRange &range = itr->second;
307         range.Write(buf);
308     }
309 
310     buf.End();
311 
312     return true;
313 }
314 
Read(trpgReadBuffer & buf)315 bool trpgRangeTable::Read(trpgReadBuffer &buf)
316 {
317     int32 numRange;
318     trpgToken tok;
319     int32 len;
320     valid = false;
321 
322     try {
323         buf.Get(numRange);
324         if (numRange < 0) throw 1;
325         for (int i=0;i<numRange;i++) {
326             // Read in the individual range
327             buf.GetToken(tok,len);
328             if (tok != TRPG_RANGE) throw 1;
329             buf.PushLimit(len);
330             trpgRange range;
331             bool status = range.Read(buf);
332             buf.PopLimit();
333             if (!status) throw 1;
334             AddRange(range);
335         }
336 
337         valid = true;
338     }
339 
340     catch (...) {
341         return false;
342     }
343 
344     return isValid();
345 }
346 
operator =(const trpgRangeTable & inTab)347 trpgRangeTable & trpgRangeTable::operator = (const trpgRangeTable &inTab)
348 {
349     Reset();
350     RangeMapType::const_iterator itr = inTab.rangeMap.begin();
351     for (  ; itr != inTab.rangeMap.end( ); itr++)
352         rangeMap[itr->first] = itr->second;
353 
354 #if 0
355     for (int i=0;i<inTab.rangeList.size();i++)
356         rangeList.push_back(inTab.rangeList[i]);
357 #endif
358     return *this;
359 }
360