root/OpenSceneGraph/trunk/src/osgDB/Field.cpp @ 13041

Revision 13041, 8.8 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osg/Notify>
15#include <osg/Math>
16
17#include <osgDB/Input>
18
19#include <string.h>
20#include <stdlib.h>
21
22using namespace osgDB;
23using namespace std;
24
25
26Field::Field()
27{
28    _init();
29}
30
31
32Field::Field(const Field& ic)
33{
34    _copy(ic);
35}
36
37
38Field::~Field()
39{
40    _free();
41}
42
43
44Field& Field::operator = (const Field& ic)
45{
46    if (this==&ic) return *this;
47    _free();
48    _copy(ic);
49    return *this;
50}
51
52
53void Field::_free()
54{
55    // free all data
56    if (_fieldCache) delete [] _fieldCache;
57
58    _init();
59
60}
61
62
63void Field::_init()
64{
65
66    _fieldCacheCapacity = 256;
67    _fieldCacheSize = 0;
68    _fieldCache = NULL;
69
70    _fieldType = UNINITIALISED;
71
72    _withinQuotes = false;
73
74    _noNestedBrackets = 0;
75
76}
77
78
79void Field::_copy(const Field& ic)
80{
81
82    // copy string cache.
83    if (ic._fieldCache)
84    {
85        _fieldCacheCapacity = ic._fieldCacheCapacity;
86        _fieldCacheSize = ic._fieldCacheSize;
87        _fieldCache = new char [_fieldCacheCapacity];
88        strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity);
89    }
90    else
91    {
92        _fieldCacheCapacity = 0;
93        _fieldCacheSize = 0;
94        _fieldCache = NULL;
95    }
96
97    _fieldType = ic._fieldType;
98
99    _withinQuotes = ic._withinQuotes;
100
101    _noNestedBrackets = ic._noNestedBrackets;
102}
103
104
105void Field::setWithinQuotes(bool withinQuotes)
106{
107    _withinQuotes=withinQuotes;
108    _fieldType = UNINITIALISED;
109}
110
111
112bool Field::getWithinQuotes()
113{
114    return _withinQuotes;
115}
116
117
118void Field::setNoNestedBrackets(int no)
119{
120    _noNestedBrackets=no;
121}
122
123
124int Field::getNoNestedBrackets()
125{
126    return _noNestedBrackets;
127}
128
129
130const char* Field::getStr() const
131{
132    if (_fieldCacheSize!=0) return _fieldCache;
133    else return NULL;
134}
135
136
137char* Field::takeStr()
138{
139    char* field = _fieldCache;
140
141    _fieldCache = NULL;
142    _fieldCacheSize = 0;
143
144    _fieldType = UNINITIALISED;
145    _withinQuotes = false;
146
147    return field;
148}
149
150
151void Field::reset()
152{
153    _fieldCacheSize = 0;
154    if (_fieldCache)
155    {
156        _fieldCache[_fieldCacheSize] = 0;
157    }
158
159    _withinQuotes = false;
160    _noNestedBrackets = 0;
161}
162
163
164void Field::addChar(char c)
165{
166    if (_fieldCache==NULL)
167    {
168        if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
169        _fieldCache = new char[_fieldCacheCapacity];
170        memset(_fieldCache,0,_fieldCacheCapacity);
171        _fieldCacheSize = 0;
172    }
173    else if (_fieldCacheSize>=_fieldCacheCapacity-1)
174    {
175        if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
176        while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2;
177        char* tmp_str = _fieldCache;
178        _fieldCache = new char[_fieldCacheCapacity];
179        memset(_fieldCache,0,_fieldCacheCapacity);
180        strncpy(_fieldCache,tmp_str,_fieldCacheSize);
181        delete [] tmp_str;
182
183    }
184    _fieldCache[_fieldCacheSize++] = c;
185    _fieldCache[_fieldCacheSize] = 0;
186    _fieldType = UNINITIALISED;
187}
188
189
190Field::FieldType Field::getFieldType() const
191{
192    if (_fieldType==UNINITIALISED && _fieldCache)
193    {
194        _fieldType = calculateFieldType(_fieldCache,_withinQuotes);
195    }
196    return _fieldType;
197}
198
199
200bool Field::isValid() const
201{
202    if (_fieldCacheSize>0  && !_withinQuotes) return true;
203    else return false;
204}
205
206
207bool Field::isOpenBracket() const
208{
209    if (_fieldCacheSize==1) return _fieldCache[0]=='{';
210    else return false;
211}
212
213
214bool Field::isCloseBracket() const
215{
216    if (_fieldCacheSize==1) return _fieldCache[0]=='}';
217    else return false;
218}
219
220
221bool Field::isWord() const
222{
223    getFieldType();
224    return (_fieldType==WORD);
225}
226
227
228bool Field::matchWord(const char* str) const
229{
230    getFieldType();
231    return _fieldType==WORD && strcmp(_fieldCache,str)==0;
232}
233
234
235bool Field::matchWord(const char* str,int noCharacters) const
236{
237    getFieldType();
238    return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0;
239}
240
241
242bool Field::isString() const
243{
244    return getNoCharacters()!=0;
245}
246
247
248bool Field::matchString(const char* str) const
249{
250    return strcmp(_fieldCache,str)==0;
251}
252
253
254bool Field::matchString(const char* str,int noCharacters) const
255{
256    return strncmp(_fieldCache,str,noCharacters)==0;
257}
258
259
260bool Field::isQuotedString() const
261{
262    return _withinQuotes;
263}
264
265
266bool Field::isInt() const
267{
268    getFieldType();
269    return _fieldType==INTEGER;
270}
271
272
273bool Field::matchInt(int i) const
274{
275    getFieldType();
276    if (_fieldType==INTEGER)
277    {
278        return strtol(_fieldCache,NULL,0)==i;
279    }
280    else
281    {
282        return false;
283    }
284}
285
286
287bool Field::getInt(int& i) const
288{
289    getFieldType();
290    if (_fieldType==INTEGER)
291    {
292        i = strtol(_fieldCache,NULL,0);
293        return true;
294    }
295    else
296    {
297        return false;
298    }
299}
300
301bool Field::isUInt() const
302{
303    getFieldType();
304    return _fieldType==INTEGER;
305}
306
307
308bool Field::matchUInt(unsigned int i) const
309{
310    getFieldType();
311    if (_fieldType==INTEGER)
312    {
313        return (unsigned int) strtoul(_fieldCache,NULL,0)==i;
314    }
315    else
316    {
317        return false;
318    }
319}
320
321
322bool Field::getUInt(unsigned int& i) const
323{
324    getFieldType();
325    if (_fieldType==INTEGER)
326    {
327        i = strtoul(_fieldCache,NULL,0);
328        return true;
329    }
330    else
331    {
332        return false;
333    }
334}
335
336bool Field::isFloat() const
337{
338    getFieldType();
339    return _fieldType==REAL || _fieldType==INTEGER;
340}
341
342
343bool Field::matchFloat(float f) const
344{
345    getFieldType();
346    if (_fieldType==REAL || _fieldType==INTEGER)
347    {
348        return osg::asciiToFloat(_fieldCache)==f;
349    }
350    else
351    {
352        return false;
353    }
354}
355
356
357bool Field::getFloat(float& f) const
358{
359    getFieldType();
360    if (_fieldType==REAL || _fieldType==INTEGER)
361    {
362        f = osg::asciiToFloat(_fieldCache);
363        return true;
364    }
365    else
366    {
367        return false;
368    }
369}
370
371bool Field::getFloat(double& f) const
372{
373    getFieldType();
374    if (_fieldType==REAL || _fieldType==INTEGER)
375    {
376        f = osg::asciiToDouble(_fieldCache);
377        return true;
378    }
379    else
380    {
381        return false;
382    }
383}
384
385
386Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes)
387{
388    if (str==NULL) return BLANK;
389    if (*str==0) return BLANK;
390
391    if (withinQuotes) return STRING;
392
393    bool hadPlusMinus = false;
394    bool hadDecimalPlace = false;
395    bool hadExponent = false;
396    bool couldBeInt = true;
397    bool couldBeFloat = true;
398    int noZeroToNine = 0;
399
400    const char* ptr = str;
401
402    // check if could be a hex number.
403    if (strncmp(ptr,"0x",2)==0)
404    {
405        // skip over leading 0x, and then go through rest of string
406        // checking to make sure all values are 0...9 or a..f.
407        ptr+=2;
408        while (
409               *ptr!=0 &&
410               ((*ptr>='0' && *ptr<='9') ||
411                (*ptr>='a' && *ptr<='f') ||
412                (*ptr>='A' && *ptr<='F'))
413              )
414        {
415            ++ptr;
416        }
417
418        // got to end of string without failure, therefore must be a hex integer.
419        if (*ptr==0) return INTEGER;
420    }
421
422    ptr = str;
423    // check if a float or an int.
424    while (*ptr!=0 && couldBeFloat)
425    {
426        if (*ptr=='+' || *ptr=='-')
427        {
428            if (hadPlusMinus)
429            {
430                couldBeInt = false;
431                couldBeFloat = false;
432            } else hadPlusMinus = true;
433        }
434        else if (*ptr>='0' && *ptr<='9')
435        {
436            noZeroToNine++;
437        }
438        else if (*ptr=='.')
439        {
440            if (hadDecimalPlace)
441            {
442                couldBeInt = false;
443                couldBeFloat = false;
444            }
445            else
446            {
447                hadDecimalPlace = true;
448                couldBeInt = false;
449            }
450        }
451        else if (*ptr=='e' || *ptr=='E')
452        {
453            if (hadExponent || noZeroToNine==0)
454            {
455                couldBeInt = false;
456                couldBeFloat = false;
457            }
458            else
459            {
460                hadExponent = true;
461                couldBeInt = false;
462                hadDecimalPlace = false;
463                hadPlusMinus = false;
464                noZeroToNine=0;
465            }
466        }
467        else
468        {
469            couldBeInt = false;
470            couldBeFloat = false;
471        }
472        ++ptr;
473    }
474
475    if (couldBeInt && noZeroToNine>0) return INTEGER;
476    if (couldBeFloat && noZeroToNine>0) return REAL;
477    if (str[0]=='{') return OPEN_BRACKET;
478    if (str[0]=='}') return CLOSE_BRACKET;
479    return WORD;
480}
Note: See TracBrowser for help on using the browser.