Made on Kubuntu
00001 // Copyright (C) 2009-2010 Ferdinand Majerech 00002 // This file is part of MiniINI 00003 // For conditions of distribution and use, see copyright notice in LICENSE.txt 00004 00005 #ifndef INISECTION_H_INCLUDED 00006 #define INISECTION_H_INCLUDED 00007 00008 #include <cstring> 00009 #include <cstdlib> 00010 00011 #include "typedefs.h" 00012 #include "allocator.h" 00013 #include "linetoken.h" 00014 #ifndef INI_NO_STL 00015 #include <string> 00016 #include <vector> 00017 #endif 00018 00019 00021 00024 class INISection 00025 { 00026 friend class INIFile; 00027 private: 00028 00030 miniini_private::c * Name; 00032 miniini_private::ui Length; 00034 00038 miniini_private::c * * Tags; 00040 miniini_private::Allocator * Alloc; 00041 00042 00045 static miniini_private::ui temptagscap; 00047 static miniini_private::c * * temptags; 00049 static miniini_private::ui tagcap; 00051 static miniini_private::c * tagbuf; 00052 00053 public: 00054 00056 const char * GetName() const 00057 { 00058 return Name; 00059 } 00060 00062 00072 bool ReadString(const char * const name, const char * & out) const; 00073 00075 00085 #ifndef INI_NO_STL 00086 bool ReadString(const std::string & name, std::string & out) const 00087 { 00088 const miniini_private::c * tempout; 00089 bool ret = ReadString(name.c_str(), tempout); 00090 if(ret) 00091 { 00092 out = tempout; 00093 } 00094 return ret; 00095 } 00096 #endif 00097 00099 00106 bool ReadInt(const char * const name, int & out) const; 00107 00109 00116 #ifndef INI_NO_STL 00117 bool ReadInt(const std::string & name, int & out) const 00118 { 00119 return ReadInt(name.c_str(), out); 00120 } 00121 #endif 00122 00124 00131 bool ReadFloat(const char * const name, float & out) const; 00132 00134 00141 #ifndef INI_NO_STL 00142 bool ReadFloat(const std::string & name, float & out) const 00143 { 00144 return ReadFloat(name.c_str(), out); 00145 } 00146 #endif 00147 00149 00156 bool ReadBool(const char * const name, bool & out) const; 00157 00159 00166 #ifndef INI_NO_STL 00167 bool ReadBool(const std::string & name, bool & out) const 00168 { 00169 return ReadBool(name.c_str(), out); 00170 } 00171 #endif 00172 00174 00178 unsigned MultiValSize(const char * const name) const; 00179 00181 00191 unsigned ReadMultiString(const char * const name, const char * * out, 00192 const unsigned cap) const; 00193 00195 00205 #ifndef INI_NO_STL 00206 unsigned ReadMultiString(const std::string & name, 00207 std::vector<std::string> & out) const; 00208 #endif 00209 00211 00218 unsigned ReadMultiInt(const char * const name, int * out, 00219 const unsigned cap) const; 00220 00222 00229 #ifndef INI_NO_STL 00230 unsigned ReadMultiInt(const std::string & name, 00231 std::vector<int> & out) const; 00232 #endif 00233 00235 00242 unsigned ReadMultiFloat(const char * const name, float * out, 00243 const unsigned cap) const; 00244 00246 00253 #ifndef INI_NO_STL 00254 unsigned ReadMultiFloat(const std::string & name, 00255 std::vector<float> & out) const; 00256 #endif 00257 00259 00266 unsigned ReadMultiBool(const char * const name, bool * out, 00267 const unsigned cap) const; 00268 00270 00277 #ifndef INI_NO_STL 00278 unsigned ReadMultiBool(const std::string & name, 00279 std::vector<bool> & out) const; 00280 #endif 00281 00283 00289 unsigned ArraySize(const char * const name) const; 00290 00292 00306 unsigned ReadStrings(const char * const name, const char * * out, 00307 const unsigned cap) const; 00308 00310 00323 #ifndef INI_NO_STL 00324 unsigned ReadStrings(const std::string & name, 00325 std::vector<std::string> & out) const; 00326 #endif 00327 00329 00338 unsigned ReadInts(const char * const name, int * out, 00339 const unsigned cap) const; 00340 00342 00352 #ifndef INI_NO_STL 00353 unsigned ReadInts(const std::string & name, 00354 std::vector<int> & out) const; 00355 #endif 00356 00358 00368 unsigned ReadFloats(const char * const name, float * out, 00369 const unsigned cap) const; 00370 00372 00382 #ifndef INI_NO_STL 00383 unsigned ReadFloats(const std::string & name, 00384 std::vector<float> & out) const; 00385 #endif 00386 00388 00397 unsigned ReadBools(const char * const name, bool * out, 00398 const unsigned cap) const; 00399 00401 00411 #ifndef INI_NO_STL 00412 unsigned ReadBools(const std::string & name, 00413 std::vector<bool> & out) const; 00414 #endif 00415 00417 unsigned GetLength() const 00418 { 00419 return static_cast<unsigned>(Length); 00420 } 00421 00422 private: 00423 00425 INISection() 00426 :Name(NULL) 00427 ,Length(0) 00428 ,Tags(NULL) 00429 ,Alloc(NULL) 00430 {} 00431 00433 ~INISection(); 00434 00436 00450 static inline miniini_private::LineToken TagName(const miniini_private::c * & currentcharref, 00451 miniini_private::ui & tagsizeref); 00452 00454 00462 static inline miniini_private::ui TagValue(const miniini_private::c * & currentcharref, 00463 miniini_private::ui tagsize); 00464 00466 00471 static inline bool Header(const miniini_private::c * & currentcharref); 00472 00474 00481 static inline miniini_private::ui ParseInts(const miniini_private::c * * strings, 00482 int * out, 00483 const miniini_private::ui numstrings); 00484 00486 00493 static inline miniini_private::ui ParseFloats(const miniini_private::c * * strings, 00494 float * out, 00495 const miniini_private::ui numstrings); 00496 00498 00505 static inline miniini_private::ui ParseBools(const miniini_private::c * * strings, 00506 bool * out, 00507 const miniini_private::ui numstrings); 00508 00510 /* 00511 * Loads the section and changes currentcharptr so that the caller can 00512 * start with another section. 00513 * @param sectionname Name of the section to initialize 00514 * @param currentcharptr Start of the section in a raw ini file buffer. 00515 * @return true if the section is valid. 00516 * @return false if the section is empty. 00517 */ 00518 void Init(const miniini_private::c * const sectionname, 00519 const miniini_private::c * * const currentcharptr, 00520 miniini_private::Allocator * const alloc); 00521 00523 static void InitTempData() 00524 { 00525 assert(!temptags); 00526 assert(!tagbuf); 00527 temptagscap = 8; 00528 temptags = new miniini_private::c * [temptagscap]; 00529 //MUST be over 6 00530 tagcap = 64; 00531 tagbuf = new miniini_private::c [tagcap]; 00532 } 00533 00535 static void DestroyTempData() 00536 { 00537 assert(temptags); 00538 assert(tagbuf); 00539 temptagscap = 0; 00540 delete [] temptags; 00541 temptags = NULL; 00542 tagcap = 0; 00543 delete [] tagbuf; 00544 tagbuf = NULL; 00545 } 00546 00548 00550 #ifndef INI_NO_STL 00551 #define BENCH(method, type, stltype)\ 00552 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00553 {\ 00554 if(stl)\ 00555 {\ 00556 stltype out;\ 00557 method(std::string(Tags[tag]), out);\ 00558 }\ 00559 else\ 00560 {\ 00561 type out;\ 00562 method(Tags[tag], out);\ 00563 }\ 00564 } 00565 #else 00566 #define BENCH(method, type, stltype)\ 00567 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00568 {\ 00569 type out;\ 00570 method(Tags[tag], out);\ 00571 } 00572 #endif 00573 00574 void BenchString(bool stl) 00575 { 00576 BENCH(ReadString, const char *, std::string); 00577 } 00578 00579 void BenchInt(bool stl) 00580 { 00581 BENCH(ReadInt, int, int); 00582 } 00583 00584 void BenchFloat(bool stl) 00585 { 00586 BENCH(ReadFloat, float, float); 00587 } 00588 00589 void BenchBool(bool stl) 00590 { 00591 BENCH(ReadBool, bool, bool); 00592 } 00593 00596 #ifndef INI_NO_STL 00597 #define BENCHMULTI(method, type, stltype)\ 00598 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00599 {\ 00600 if(stl)\ 00601 {\ 00602 std::vector<stltype> out;\ 00603 method(std::string(Tags[tag]), out);\ 00604 }\ 00605 else\ 00606 {\ 00607 unsigned elemcount = 1024;\ 00608 type * out = new type [elemcount];\ 00609 method(Tags[tag], out, elemcount);\ 00610 delete [] out;\ 00611 }\ 00612 } 00613 #else 00614 #define BENCHMULTI(method, type, stltype)\ 00615 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00616 {\ 00617 unsigned elemcount = 1024;\ 00618 type * out = new type [elemcount];\ 00619 method(Tags[tag], out, elemcount);\ 00620 delete [] out;\ 00621 } 00622 #endif 00623 00624 void BenchMultiString(bool stl) 00625 { 00626 BENCHMULTI(ReadMultiString, const char *, std::string); 00627 } 00628 00629 void BenchMultiInt(bool stl) 00630 { 00631 BENCHMULTI(ReadMultiInt, int, int); 00632 } 00633 00634 void BenchMultiFloat(bool stl) 00635 { 00636 BENCHMULTI(ReadMultiFloat, float, float); 00637 } 00638 00639 void BenchMultiBool(bool stl) 00640 { 00641 BENCHMULTI(ReadMultiBool, bool, bool); 00642 } 00643 00644 00649 #ifndef INI_NO_STL 00650 #define BENCHARRAY(method, type, stltype)\ 00651 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00652 {\ 00653 if(stl)\ 00654 {\ 00655 std::vector<stltype> out;\ 00656 method(std::string(tagname), out);\ 00657 }\ 00658 else\ 00659 {\ 00660 int elemcount;\ 00661 if(!ReadInt(tagname, elemcount))\ 00662 {\ 00663 break;\ 00664 }\ 00665 type * out = new type [elemcount];\ 00666 method(tagname, out, elemcount);\ 00667 delete [] out;\ 00668 }\ 00669 } 00670 #else 00671 #define BENCHARRAY(method, type, stltype)\ 00672 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00673 {\ 00674 int elemcount;\ 00675 if(!ReadInt(tagname, elemcount))\ 00676 {\ 00677 break;\ 00678 }\ 00679 type * out = new type [elemcount];\ 00680 method(tagname, out, elemcount);\ 00681 delete [] out;\ 00682 } 00683 #endif 00684 00685 void BenchStrings(bool stl) 00686 { 00687 BENCHARRAY(ReadStrings, const char *, std::string); 00688 } 00689 00690 void BenchInts(bool stl) 00691 { 00692 BENCHARRAY(ReadInts, int, int); 00693 } 00694 00695 void BenchFloats(bool stl) 00696 { 00697 BENCHARRAY(ReadFloats, float, float); 00698 } 00699 00700 void BenchBools(bool stl) 00701 { 00702 BENCHARRAY(ReadBools, bool, bool); 00703 } 00704 00705 #undef BENCH 00706 #undef BENCHARRAY 00707 #undef BENCHMULTI 00708 00709 00711 00712 INISection(const INISection &); 00713 00714 void operator = (const INISection &); 00715 }; 00716 00717 #endif