OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDuration.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Garrett Potts
8 //
9 //*************************************************************************
10 // $Id$
12 #include <ossim/base/ossimCommon.h>
13 #include <sstream>
14 #include <cctype>
16 :theSign(1),
17 theYears(0),
18 theMonths(0),
19 theWeeks(0),
20 theDays(0),
21 theHours(0),
22 theMinutes(0),
23 theSeconds(0)
24 {
25  if(!iso8601Duration.empty())
26  {
27  setByIso8601DurationString(iso8601Duration);
28  }
29 }
30 
32 {
33  theSign = 1;
34  theYears = 0;
35  theMonths = 0;
36  theWeeks = 0;
37  theDays = 0;
38  theHours = 0;
39  theMinutes = 0;
40  theSeconds = 0;
41 }
42 
43 static bool isWhiteSpace(int c)
44 {
45  return ((c==' ') ||
46  (c=='\n')||
47  (c=='\r')||
48  (c=='\t'));
49 }
50 
52 {
53  clearFields();
54 
55  if(in.peek()=='-')
56  {
57  theSign = -1;
58  in.ignore();
59  }
60  if(in.peek()!='P')
61  {
62  return false;
63  }
64  // skip the period indicater
65  in.ignore();
66 
67  // now we start parsing the date portion and the time portion
68  ossimString value;
69  bool doneFlag = false;
70  bool badParseFlag = false;
71  bool doingTimeFlag = false;
72  while(!doneFlag)
73  {
74  int c = in.peek();
75  if(!in)
76  {
77  doneFlag = true;
78  }
79  else
80  {
81  if(isWhiteSpace(c))
82  {
83  doneFlag = true; // parse til blank character is met
84  }
85  else if(isalpha(c))
86  {
87  // we are done with current value
88  //
89  // check to see if was a Time seaprator of value
90  // 'T'
91  if(c == 'T')
92  {
93  // then it was a time separator so do nothing
94  value = ""; // go ahead and null it out for now
95  doingTimeFlag = true; // now in time parsing portion
96  }
97  else
98  {
99  if(doingTimeFlag)
100  {
101  // check time values
102  if(c == 'H')
103  {
104  theHours = value.toUInt64();
105  }
106  else if(c == 'M')
107  {
108  theMinutes = value.toUInt64();
109  }
110  else if(c == 'S')
111  {
112  theSeconds = value.toFloat64();
113  }
114  else
115  {
116  doneFlag = true;
117  badParseFlag = true;
118  }
119  value = ""; // reset the value
120  }
121  else // check date characters instead
122  {
123  if(c == 'Y')
124  {
125  theYears = value.toUInt64();
126  }
127  else if(c == 'M')
128  {
129  theMonths = value.toUInt64();
130  }
131  else if(c == 'W')
132  {
133  theWeeks = value.toUInt64();
134  }
135  else if(c == 'D')
136  {
137  theDays = value.toUInt64();
138  }
139  else
140  {
141  doneFlag = true;
142  badParseFlag = true;
143  }
144  value = ""; // reset the value
145  }
146  }
147  }
148  else if(isdigit(c)||(c=='.'))// not an alphabetic character so add it to the value string
149  {
150  value += static_cast<char>(c);
151  }
152  else
153  {
154  doneFlag = true;
155  badParseFlag = true;
156  }
157  }
158  if(!doneFlag)
159  {
160  in.ignore();
161  }
162  }
163 
164  return badParseFlag;
165 }
166 
168 {
169  if(iso8601Duration.empty())
170  {
171  clearFields();
172  return true;
173  }
174  std::istringstream in(iso8601Duration);
175  return readIso8601Encoding(in);
176 }
177 
179 {
180  result = "";
181  bool hasDatePeriod = ((theYears!=0)||
182  (theMonths!=0)||
183  (theWeeks!=0)||
184  (theDays!=0));
185  bool hasTimePeriod = ((theHours!=0)||
186  (theMinutes!=0)||
187  (!ossim::almostEqual(theSeconds, 0.0, .00000000001)));
188  // if no time or date period present then return empty
189  if(!(hasDatePeriod || hasTimePeriod))
190  {
191  return;
192  }
193  if(theSign < 0)
194  {
195  result += "-";
196  }
197  result += "P";
198  if(hasDatePeriod)
199  {
200  if(theYears > 0)
201  {
203  result+="Y";
204  }
205  if(theMonths>0)
206  {
208  result+="M";
209  }
210  if(theWeeks>0)
211  {
213  result+="W";
214  }
215  if(theDays>0)
216  {
218  result+="D";
219  }
220  }
221  if(hasTimePeriod)
222  {
223  result+="T";
224  if(theHours>0)
225  {
227  result+="H";
228  }
229  if(theMinutes>0)
230  {
232  result+="M";
233  }
234  if(theSeconds>0)
235  {
236  result+=ossimString::toString(theSeconds, 15);
237  result+="S";
238  }
239  }
240 }
241 
243 {
244  ossim_float64 result = theSeconds;
245 
246  if(theMinutes > 0)
247  {
248  result += theMinutes*60.0;
249  }
250  if(theHours > 0)
251  {
252  result += theHours*3600.0;
253  }
254  if(theDays > 0)
255  {
256  result += theDays*86400.0;
257  }
258  if(theWeeks > 0)
259  {
260  result += theWeeks*604800;
261  }
262  if(theSign < 0)
263  {
264  result *= -1.0;
265  }
266  return result;
267 }
268 
269 
ossim_int64 theHours
ossim_int64 theDays
ossim_int64 theYears
ossim_float64 toSeconds() const
this will not use the months field or the years field but will use all other fields to calculate a to...
bool almostEqual(T x, T y, T tolerance=FLT_EPSILON)
Definition: ossimCommon.h:53
static ossimString toString(bool aValue)
Numeric to string methods.
void clearFields()
zero out all fields
double ossim_float64
ossim_float64 theSeconds
ossim_float64 toFloat64() const
void toIso8601DurationString(ossimString &result)
Will take the field values and encode into a iso8601 string format.
bool readIso8601Encoding(std::istream &in)
This will take an iso8601 encoded duration stream and parse out the individual values it will stop wh...
ossimDuration(const ossimString &iso8601Duration=ossimString(""))
This will take an iso8601 encoded duration string and parse out the individual values.
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
ossim_int64 theMinutes
ossim_int64 theMonths
ossim_uint64 toUInt64() const
ossim_int32 theSign
bool empty() const
Definition: ossimString.h:411
ossim_int64 theWeeks
bool setByIso8601DurationString(const ossimString &iso8601Duration)
This will take an iso8601 encoded duration stream and parse out the individual values it will stop wh...
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32