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 00084 const char * operator [] (const char * const name) const 00085 { 00086 const char * out; 00087 if(ReadString(name, out)) 00088 { 00089 return out; 00090 } 00091 else 00092 { 00093 return NULL; 00094 } 00095 } 00096 00098 00108 #ifndef INI_NO_STL 00109 bool ReadString(const std::string & name, std::string & out) const 00110 { 00111 const miniini_private::c * tempout; 00112 bool ret = ReadString(name.c_str(), tempout); 00113 if(ret) 00114 { 00115 out = tempout; 00116 } 00117 return ret; 00118 } 00119 #endif 00120 00122 00129 bool ReadInt(const char * const name, int & out) const; 00130 00132 00139 #ifndef INI_NO_STL 00140 bool ReadInt(const std::string & name, int & out) const 00141 { 00142 return ReadInt(name.c_str(), out); 00143 } 00144 #endif 00145 00147 00154 bool ReadFloat(const char * const name, float & out) const; 00155 00157 00164 #ifndef INI_NO_STL 00165 bool ReadFloat(const std::string & name, float & out) const 00166 { 00167 return ReadFloat(name.c_str(), out); 00168 } 00169 #endif 00170 00172 00179 bool ReadBool(const char * const name, bool & out) const; 00180 00182 00189 #ifndef INI_NO_STL 00190 bool ReadBool(const std::string & name, bool & out) const 00191 { 00192 return ReadBool(name.c_str(), out); 00193 } 00194 #endif 00195 00197 00201 unsigned MultiValSize(const char * const name) const; 00202 00204 00214 unsigned ReadMultiString(const char * const name, const char * * out, 00215 const unsigned cap) const; 00216 00218 00228 #ifndef INI_NO_STL 00229 unsigned ReadMultiString(const std::string & name, 00230 std::vector<std::string> & out) const; 00231 #endif 00232 00234 00241 unsigned ReadMultiInt(const char * const name, int * out, 00242 const unsigned cap) const; 00243 00245 00252 #ifndef INI_NO_STL 00253 unsigned ReadMultiInt(const std::string & name, 00254 std::vector<int> & out) const; 00255 #endif 00256 00258 00265 unsigned ReadMultiFloat(const char * const name, float * out, 00266 const unsigned cap) const; 00267 00269 00276 #ifndef INI_NO_STL 00277 unsigned ReadMultiFloat(const std::string & name, 00278 std::vector<float> & out) const; 00279 #endif 00280 00282 00289 unsigned ReadMultiBool(const char * const name, bool * out, 00290 const unsigned cap) const; 00291 00293 00300 #ifndef INI_NO_STL 00301 unsigned ReadMultiBool(const std::string & name, 00302 std::vector<bool> & out) const; 00303 #endif 00304 00306 00312 unsigned ArraySize(const char * const name) const; 00313 00315 00329 unsigned ReadStrings(const char * const name, const char * * out, 00330 const unsigned cap) const; 00331 00333 00346 #ifndef INI_NO_STL 00347 unsigned ReadStrings(const std::string & name, 00348 std::vector<std::string> & out) const; 00349 #endif 00350 00352 00361 unsigned ReadInts(const char * const name, int * out, 00362 const unsigned cap) const; 00363 00365 00375 #ifndef INI_NO_STL 00376 unsigned ReadInts(const std::string & name, 00377 std::vector<int> & out) const; 00378 #endif 00379 00381 00391 unsigned ReadFloats(const char * const name, float * out, 00392 const unsigned cap) const; 00393 00395 00405 #ifndef INI_NO_STL 00406 unsigned ReadFloats(const std::string & name, 00407 std::vector<float> & out) const; 00408 #endif 00409 00411 00420 unsigned ReadBools(const char * const name, bool * out, 00421 const unsigned cap) const; 00422 00424 00434 #ifndef INI_NO_STL 00435 unsigned ReadBools(const std::string & name, 00436 std::vector<bool> & out) const; 00437 #endif 00438 00440 unsigned GetLength() const 00441 { 00442 return static_cast<unsigned>(Length); 00443 } 00444 00445 private: 00446 00448 INISection() 00449 :Name(NULL) 00450 ,Length(0) 00451 ,Tags(NULL) 00452 ,Alloc(NULL) 00453 {} 00454 00456 ~INISection(); 00457 00459 00473 static inline miniini_private::LineToken TagName(const miniini_private::c * & currentcharref, 00474 miniini_private::ui & tagsizeref); 00475 00477 00485 static inline miniini_private::ui TagValue(const miniini_private::c * & currentcharref, 00486 miniini_private::ui tagsize); 00487 00489 00494 static inline bool Header(const miniini_private::c * & currentcharref); 00495 00497 00504 static inline miniini_private::ui ParseInts(const miniini_private::c * * strings, 00505 int * out, 00506 const miniini_private::ui numstrings); 00507 00509 00516 static inline miniini_private::ui ParseFloats(const miniini_private::c * * strings, 00517 float * out, 00518 const miniini_private::ui numstrings); 00519 00521 00528 static inline miniini_private::ui ParseBools(const miniini_private::c * * strings, 00529 bool * out, 00530 const miniini_private::ui numstrings); 00531 00533 /* 00534 * Loads the section and changes currentcharptr so that the caller can 00535 * start with another section. 00536 * @param sectionname Name of the section to initialize 00537 * @param currentcharptr Start of the section in a raw ini file buffer. 00538 * @return true if the section is valid. 00539 * @return false if the section is empty. 00540 */ 00541 void Init(const miniini_private::c * const sectionname, 00542 const miniini_private::c * * const currentcharptr, 00543 miniini_private::Allocator * const alloc); 00544 00546 static void InitTempData() 00547 { 00548 assert(!temptags); 00549 assert(!tagbuf); 00550 temptagscap = 8; 00551 temptags = new miniini_private::c * [temptagscap]; 00552 //MUST be over 6 00553 tagcap = 64; 00554 tagbuf = new miniini_private::c [tagcap]; 00555 } 00556 00558 static void DestroyTempData() 00559 { 00560 assert(temptags); 00561 assert(tagbuf); 00562 temptagscap = 0; 00563 delete [] temptags; 00564 temptags = NULL; 00565 tagcap = 0; 00566 delete [] tagbuf; 00567 tagbuf = NULL; 00568 } 00569 00571 00573 #ifndef INI_NO_STL 00574 #define BENCH(method, type, stltype)\ 00575 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00576 {\ 00577 if(stl)\ 00578 {\ 00579 stltype out;\ 00580 method(std::string(Tags[tag]), out);\ 00581 }\ 00582 else\ 00583 {\ 00584 type out;\ 00585 method(Tags[tag], out);\ 00586 }\ 00587 } 00588 #else 00589 #define BENCH(method, type, stltype)\ 00590 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00591 {\ 00592 type out;\ 00593 method(Tags[tag], out);\ 00594 } 00595 #endif 00596 00597 void BenchString(bool stl) 00598 { 00599 BENCH(ReadString, const char *, std::string); 00600 } 00601 00602 void BenchInt(bool stl) 00603 { 00604 BENCH(ReadInt, int, int); 00605 } 00606 00607 void BenchFloat(bool stl) 00608 { 00609 BENCH(ReadFloat, float, float); 00610 } 00611 00612 void BenchBool(bool stl) 00613 { 00614 BENCH(ReadBool, bool, bool); 00615 } 00616 00619 #ifndef INI_NO_STL 00620 #define BENCHMULTI(method, type, stltype)\ 00621 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00622 {\ 00623 if(stl)\ 00624 {\ 00625 std::vector<stltype> out;\ 00626 method(std::string(Tags[tag]), out);\ 00627 }\ 00628 else\ 00629 {\ 00630 unsigned elemcount = 1024;\ 00631 type * out = new type [elemcount];\ 00632 method(Tags[tag], out, elemcount);\ 00633 delete [] out;\ 00634 }\ 00635 } 00636 #else 00637 #define BENCHMULTI(method, type, stltype)\ 00638 for(miniini_private::ui tag = 0; tag < Length; ++tag)\ 00639 {\ 00640 unsigned elemcount = 1024;\ 00641 type * out = new type [elemcount];\ 00642 method(Tags[tag], out, elemcount);\ 00643 delete [] out;\ 00644 } 00645 #endif 00646 00647 void BenchMultiString(bool stl) 00648 { 00649 BENCHMULTI(ReadMultiString, const char *, std::string); 00650 } 00651 00652 void BenchMultiInt(bool stl) 00653 { 00654 BENCHMULTI(ReadMultiInt, int, int); 00655 } 00656 00657 void BenchMultiFloat(bool stl) 00658 { 00659 BENCHMULTI(ReadMultiFloat, float, float); 00660 } 00661 00662 void BenchMultiBool(bool stl) 00663 { 00664 BENCHMULTI(ReadMultiBool, bool, bool); 00665 } 00666 00667 00672 #ifndef INI_NO_STL 00673 #define BENCHARRAY(method, type, stltype)\ 00674 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00675 {\ 00676 if(stl)\ 00677 {\ 00678 std::vector<stltype> out;\ 00679 method(std::string(tagname), out);\ 00680 }\ 00681 else\ 00682 {\ 00683 int elemcount;\ 00684 if(!ReadInt(tagname, elemcount))\ 00685 {\ 00686 break;\ 00687 }\ 00688 type * out = new type [elemcount];\ 00689 method(tagname, out, elemcount);\ 00690 delete [] out;\ 00691 }\ 00692 } 00693 #else 00694 #define BENCHARRAY(method, type, stltype)\ 00695 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00696 {\ 00697 int elemcount;\ 00698 if(!ReadInt(tagname, elemcount))\ 00699 {\ 00700 break;\ 00701 }\ 00702 type * out = new type [elemcount];\ 00703 method(tagname, out, elemcount);\ 00704 delete [] out;\ 00705 } 00706 #endif 00707 00708 void BenchStrings(bool stl) 00709 { 00710 BENCHARRAY(ReadStrings, const char *, std::string); 00711 } 00712 00713 void BenchInts(bool stl) 00714 { 00715 BENCHARRAY(ReadInts, int, int); 00716 } 00717 00718 void BenchFloats(bool stl) 00719 { 00720 BENCHARRAY(ReadFloats, float, float); 00721 } 00722 00723 void BenchBools(bool stl) 00724 { 00725 BENCHARRAY(ReadBools, bool, bool); 00726 } 00727 00728 #undef BENCH 00729 #undef BENCHARRAY 00730 #undef BENCHMULTI 00731 00732 00734 00735 INISection(const INISection &); 00736 00737 void operator = (const INISection &); 00738 }; 00739 00740 #endif