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 #include <cstring> 00006 #include <cerrno> 00007 #include <cstdlib> 00008 00009 #include "typedefs.h" 00010 #include "globals.h" 00011 #include "log.h" 00012 #include "inisection.h" 00013 #include "util.h" 00014 #include "inisectionutil.h" 00015 00016 using namespace miniini_private; 00017 00018 void INISection::Init(const c * const sectionname, const c * * const currentcharptr, 00019 Allocator * const alloc) 00020 { 00021 MINIINI_ASSERT(sectionname, "NULL pointer was passed as section name to" 00022 "INISection::Init()"); 00023 MINIINI_ASSERT(alloc, "NULL pointer was passed as allocator to" 00024 "INISection::Init()"); 00025 MINIINI_ASSERT(currentcharptr, "NULL pointer was passed as current char " 00026 "pointer to INISection::Init()"); 00027 //If *currentcharptr is 0 (null character), we're at the end of buffer 00028 MINIINI_ASSERT(*currentcharptr, "An empty buffer was passed to " 00029 "INISection::Init()"); 00030 MINIINI_ASSERT(temptags, "INISection::Init() : temptags is not allocated"); 00031 MINIINI_ASSERT(tagbuf, "INISection::Init() : tagbuf is not allocated"); 00032 00033 //Copying allocator ptr 00034 Alloc = alloc; 00035 //Copying name of the section 00036 const ui namelen = strlen(sectionname) + 1; 00037 MINIINI_ASSERT(namelen > 1, "Section name passed to INISection::Init() is empty"); 00038 Name = Alloc->NewSpace(namelen); 00039 memcpy(Name, sectionname, namelen); 00040 //ptr to the current character in buffer 00041 const c * currentchar = *currentcharptr; 00042 //Iterating through lines in the buffer 00043 while(*currentchar != '\0') 00044 { 00045 //size of tag name (if any) read 00046 ui namesize = 0; 00047 //goes to start of next line if nothing found, 00048 //if value found, stops right after name=value separator, 00049 //if header found, stays at beginning of line 00050 LineToken token = TagName(currentchar, namesize); 00051 //value found (this line is a name=value pair) 00052 if(token == LT_VAL) 00053 { 00054 //size of name and value 00055 ui tagsize = TagValue(currentchar, namesize); 00056 //value is empty 00057 if(namesize == tagsize) 00058 { 00059 MINIINI_WARNING("Empty value in a tag (no characters after " 00060 "name=value separator. Ignoring. Section: %s", Name); 00061 continue; 00062 } 00063 //adding trailing zero to the tag value 00064 tagbuf[tagsize] = tagbuf[tagsize + 1] = 0; 00065 tagsize += 2; 00066 //if needed, reallocate the temp tags buffer 00067 if(Length >= temptagscap) 00068 { 00069 MINIINI_REALLOCATE(temptags, temptagscap, Length, c *); 00070 } 00071 //Add new tag to temp tags buffer. 00072 c * newtag = Alloc->NewSpace(tagsize); 00073 memcpy(newtag, tagbuf, tagsize * sizeof(c)); 00074 if(Insert(temptags, Length, newtag)) 00075 { 00076 ++Length; 00077 } 00078 else 00079 { 00080 Alloc->DeleteSpace(newtag); 00081 } 00082 } 00083 //header found 00084 else if(token == LT_HEADER) 00085 { 00086 //if this line is a header, we're finished loading the section 00087 if(Header(currentchar)) 00088 { 00089 break; 00090 } 00091 //else Header() leaves currentchar at the start of next line 00092 } 00093 } 00094 //Updating line token ptr of the caller 00095 *currentcharptr = currentchar; 00096 #ifdef MINIINI_DEBUG 00097 //There are no tags in the section 00098 if(!Length) 00099 { 00100 //only print empty section warning if this is not the [DEFAULT] section 00101 if(strcmp(Name, "[DEFAULT]")) 00102 { 00103 MINIINI_WARNING("Empty section. Section: %s", Name); 00104 } 00105 } 00106 #endif 00107 //Copy temp lines buffer to Lines 00108 Tags = new c * [Length]; 00109 memcpy(Tags, temptags, Length * sizeof(c *)); 00110 } 00111 00112 INISection::~INISection() 00113 { 00114 //There is no need to tell allocator to delete data here, 00115 //since this is only called on INIFile destruction and that's 00116 //when Allocator gets destroyed and deletes the data anyway. 00117 //However, if/when section deletion is implemented, there 00118 //will need to be a separate dtor to handle that case. 00119 if(Tags) 00120 { 00121 delete [] Tags; 00122 } 00123 } 00124 00125 inline bool INISection::ReadString(const char * name, const char * & out) const 00126 { 00127 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00128 "INISection::ReadString()"); 00129 i pos; 00130 //if an empty string ("") is passed, we're using the tag that the 00131 //iteration index points to 00132 if(*name == '\0') 00133 { 00134 MINIINI_ASSERT(Iter >= static_cast<i>(0) && Iter < static_cast<i>(Length), 00135 "Called INISection::ReadString with iteration index " 00136 "out of range"); 00137 pos = Iter; 00138 } 00139 else 00140 { 00141 pos = BinarySearch(Tags, Length, name); 00142 } 00143 if(pos >= 0) 00144 { 00145 out = Tags [pos] + strlen(Tags[pos]) + 1; 00146 return true; 00147 } 00148 return false; 00149 } 00150 00151 bool INISection::ReadInt(const char * const name, int & out) const 00152 { 00153 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00154 "INISection::ReadInt()"); 00155 const c * valstr; 00156 //Requested tag does not exist 00157 if(!ReadString(name, valstr)) 00158 { 00159 return false; 00160 } 00161 s32 tempout; 00162 ConversionStatus status = ParseInt(valstr, tempout); 00163 if(status == CONV_ERR_TYPE) 00164 { 00165 MINIINI_ERROR("Non-integer value in a tag where integer is expected." 00166 "Section: %s Tag (if known): %s Value: %s", 00167 Name, name, valstr); 00168 return false; 00169 } 00170 #ifdef MINIINI_DEBUG 00171 else if(status == CONV_WAR_OVERFLOW) 00172 { 00173 MINIINI_WARNING("Integer value out of range." 00174 "Section: %s Tag (if known): %s Value: %s", 00175 Name, name, valstr); 00176 } 00177 else if(status == CONV_WAR_REDUNANT) 00178 { 00179 MINIINI_WARNING("Redunant characters in a tag where integer is " 00180 "expected. Reading integer. " 00181 "Section: %s Tag (if known): %s Value: %s", 00182 Name, name, valstr); 00183 } 00184 #endif 00185 out = static_cast<int>(tempout); 00186 return true; 00187 } 00188 00189 bool INISection::ReadFloat(const char * const name, float & out) const 00190 { 00191 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00192 "INISection::ReadFloat()"); 00193 const c * valstr; 00194 //Requested tag does not exist 00195 if(!ReadString(name, valstr)) 00196 { 00197 return false; 00198 } 00199 00200 f tempout; 00201 ConversionStatus status = ParseFloat(valstr, tempout); 00202 if(status == CONV_ERR_TYPE) 00203 { 00204 MINIINI_ERROR("Non-float value in a tag where float is expected." 00205 "Section: %s Tag (if known): %s Value: %s", 00206 Name, name, valstr); 00207 return false; 00208 } 00209 #ifdef MINIINI_DEBUG 00210 else if(status == CONV_WAR_OVERFLOW) 00211 { 00212 MINIINI_WARNING("Float value out of range." 00213 "Section: %s Tag (if known): %s Value: %s", 00214 Name, name, valstr); 00215 } 00216 else if(status == CONV_WAR_REDUNANT) 00217 { 00218 MINIINI_WARNING("Redunant characters in a tag where float is " 00219 "expected. Reading float." 00220 "Section: %s Tag (if known): %s Value: %s", 00221 Name, name, valstr); 00222 } 00223 #endif 00224 out = static_cast<float>(tempout); 00225 return true; 00226 } 00227 00228 bool INISection::ReadBool(const char * const name, bool & out) const 00229 { 00230 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00231 "INISection::ReadBool()"); 00232 const c * valstr; 00233 //Requested tag does not exist 00234 if(!ReadString(name, valstr)) 00235 { 00236 return false; 00237 } 00238 //Parsing bool using the first character only 00239 switch(valstr[0]) 00240 { 00241 case 't': 00242 case 'T': 00243 case 'y': 00244 case 'Y': 00245 case '1': 00246 out = true; 00247 return true; 00248 case 'f': 00249 case 'F': 00250 case 'n': 00251 case 'N': 00252 case '0': 00253 out = false; 00254 return true; 00255 default: 00256 MINIINI_ERROR("Non-bool value in a tag where bool is expected." 00257 "Section: %s Tag (if known): %s Value: %s", 00258 Name, name, valstr); 00259 return false; 00260 } 00261 return false; 00262 } 00263 00264 unsigned INISection::MultiValSize(const char * const name) const 00265 { 00266 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00267 "INISection::MultiValSize()"); 00268 //ptr to current position in tag 00269 const c * tag; 00270 //Number of elements in the tag 00271 ui elems = 0; 00272 i pos; 00273 //if an empty string ("") is passed, we're using the tag that the 00274 //iteration index points to 00275 if(*name == '\0') 00276 { 00277 MINIINI_ASSERT(Iter >= static_cast<i>(0) && Iter < static_cast<i>(Length), 00278 "Called INISection::MultiValSize() with iteration index " 00279 "out of range"); 00280 pos = Iter; 00281 } 00282 else 00283 { 00284 pos = BinarySearch(Tags, Length, name); 00285 } 00286 if(pos >= 0) 00287 { 00288 //get to the start of the first value 00289 tag = Tags[pos]; 00290 while(*tag != '\0') 00291 { 00292 ++tag; 00293 } 00294 ++tag; 00295 //now we're at the first char of value 00296 while(*tag != '\0') 00297 { 00298 ++elems; 00299 while(*tag != '\0') 00300 { 00301 ++tag; 00302 } 00303 ++tag; 00304 //now we're at the char after the trailing zero of previous value 00305 } 00306 return static_cast<unsigned>(elems); 00307 } 00308 return 0; 00309 } 00310 00311 unsigned INISection::ReadMultiString(const char * const name, const char * * out, 00312 const unsigned cap) const 00313 { 00314 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00315 "INISection::ReadMultiString()"); 00316 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00317 "INISection::ReadMultiString()"); 00318 //ptr to current position in tag 00319 const c * tag; 00320 //Number of elements in the tag 00321 ui elems = 0; 00322 i pos; 00323 //if an empty string ("") is passed, we're using the tag that the 00324 //iteration index points to 00325 if(*name == '\0') 00326 { 00327 MINIINI_ASSERT(Iter >= static_cast<i>(0) && Iter < static_cast<i>(Length), 00328 "Called INISection::ReadMultiString() with iteration index " 00329 "out of range"); 00330 pos = Iter; 00331 } 00332 else 00333 { 00334 pos = BinarySearch(Tags, Length, name); 00335 } 00336 //tag exists 00337 if(pos >= 0) 00338 { 00339 //get to the start of the first value 00340 tag = Tags[pos]; 00341 while(*tag != '\0') 00342 { 00343 ++tag; 00344 } 00345 ++tag; 00346 //now we're at the first char of value 00347 while(*tag != '\0') 00348 { 00349 //out of capacity, don't read any more values 00350 if(elems == cap) 00351 { 00352 MINIINI_WARNING("Multi value tag element out of capacity." 00353 "Section: %s Tag (if known): %s Capacity: %d", 00354 Name, name, cap); 00355 break; 00356 } 00357 //add element 00358 out[elems] = tag; 00359 ++elems; 00360 //get to the zero after the current value 00361 while(*tag != '\0') 00362 { 00363 ++tag; 00364 } 00365 //go to the next character. if it's 0, we're at the end of the tag, 00366 //otherwise, there is another value. 00367 ++tag; 00368 //now we're at the char after the trailing zero of previous value 00369 } 00370 return static_cast<unsigned>(elems); 00371 } 00372 return 0; 00373 00374 } 00375 00376 unsigned INISection::ReadMultiInt(const char * const name, int * out, 00377 const unsigned cap) const 00378 { 00379 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00380 "INISection::ReadMultiInt()"); 00381 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00382 "INISection::ReadMultiInt()"); 00383 //Array of value strings to be converted to ints 00384 const c * * const valstrs = new const c * [cap]; 00385 //Number of strings read by ReadStrings to valstrs 00386 const ui tempelems = ReadMultiString(name, valstrs, cap); 00387 ui output = ParseInts(valstrs, out, tempelems); 00388 delete [] valstrs; 00389 return static_cast<unsigned>(output); 00390 } 00391 00392 unsigned INISection::ReadMultiFloat(const char * const name, float * out, 00393 const unsigned cap) const 00394 { 00395 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00396 "INISection::ReadMultiFloat()"); 00397 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00398 "INISection::ReadMultiFloat()"); 00399 //Array of value strings to be converted to floats 00400 const c * * const valstrs = new const c * [cap]; 00401 //Number of strings read by ReadStrings to valstrs 00402 const ui tempelems = ReadMultiString(name, valstrs, cap); 00403 ui output = ParseFloats(valstrs, out, tempelems); 00404 delete [] valstrs; 00405 return static_cast<unsigned>(output); 00406 } 00407 00408 unsigned INISection::ReadMultiBool(const char * const name, bool * out, 00409 const unsigned cap) const 00410 { 00411 MINIINI_ASSERT(name, "NULL pointer was passed as tag name to" 00412 "INISection::ReadMultiBool()"); 00413 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00414 "INISection::ReadMultiBool()"); 00415 //Array of value strings to be converted to floats 00416 const c * * const valstrs = new const c * [cap]; 00417 //Number of strings read by ReadStrings to valstrs 00418 const ui tempelems = ReadMultiString(name, valstrs, cap); 00419 ui output = ParseBools(valstrs, out, tempelems); 00420 delete [] valstrs; 00421 return static_cast<unsigned>(output); 00422 } 00423 00424 #ifndef MINIINI_NO_STL 00425 unsigned INISection::ReadMultiString(const std::string & name, 00426 std::vector<std::string> & out) const 00427 { 00428 const char * cname = name.c_str(); 00429 unsigned numelems = MultiValSize(cname); 00430 //Read data to this array first 00431 const char * * tempstrs = new const char * [numelems]; 00432 numelems = ReadMultiString(cname, tempstrs, numelems); 00433 out.reserve(numelems); 00434 //Move data to output vector 00435 for(ui str = 0; str < numelems; ++str) 00436 { 00437 out.push_back(std::string(tempstrs[str])); 00438 } 00439 delete [] tempstrs; 00440 return numelems; 00441 } 00442 00443 unsigned INISection::ReadMultiInt(const std::string & name, 00444 std::vector<int> & out) const 00445 { 00446 const char * cname = name.c_str(); 00447 unsigned numelems = MultiValSize(cname); 00448 //Read data to this array first 00449 int * tempints = new int [numelems]; 00450 numelems = ReadMultiInt(cname, tempints, numelems); 00451 out.reserve(numelems); 00452 //Move data to output vector 00453 for(ui in = 0; in < numelems; ++in) 00454 { 00455 out.push_back(tempints[in]); 00456 } 00457 delete [] tempints; 00458 return numelems; 00459 } 00460 00461 unsigned INISection::ReadMultiFloat(const std::string & name, 00462 std::vector<float> & out) const 00463 { 00464 const char * cname = name.c_str(); 00465 unsigned numelems = MultiValSize(cname); 00466 //Read data to this array first 00467 float * tempfloats = new float [numelems]; 00468 numelems = ReadMultiFloat(cname, tempfloats, numelems); 00469 out.reserve(numelems); 00470 //Move data to output vector 00471 for(ui fl = 0; fl < numelems; ++fl) 00472 { 00473 out.push_back(tempfloats[fl]); 00474 } 00475 delete [] tempfloats; 00476 return numelems; 00477 } 00478 00479 unsigned INISection::ReadMultiBool(const std::string & name, 00480 std::vector<bool> & out) const 00481 { 00482 const char * cname = name.c_str(); 00483 unsigned numelems = MultiValSize(cname); 00484 //Read data to this array first 00485 bool * tempbools = new bool [numelems]; 00486 numelems = ReadMultiBool(cname, tempbools, numelems); 00487 out.reserve(numelems); 00488 //Move data to output vector 00489 for(ui bo = 0; bo < numelems; ++bo) 00490 { 00491 out.push_back(tempbools[bo]); 00492 } 00493 delete [] tempbools; 00494 return numelems; 00495 } 00496 #endif 00497 00498 unsigned INISection::ArraySize(const char * const name) const 00499 { 00500 MINIINI_ASSERT(name, "NULL pointer was passed as base tag name to" 00501 "INISection::ArraySize()"); 00502 ui namelen = strlen(name); 00503 //ptr to current tag 00504 const c * tag; 00505 //Index of current array element 00506 s32 elemidx; 00507 ui indicescap = 32; 00508 ui indicessize = 0; 00509 //Stores indices of found elements 00510 ui * indices = new ui [indicescap]; 00511 //Status of conversion of int in current tag name to index of array elemenent 00512 ConversionStatus status; 00513 for(ui idx = 0; idx < Length; ++idx) 00514 { 00515 tag = Tags[idx]; 00516 //if tag name starts by name 00517 if(!strncmp(name, tag, namelen)) 00518 { 00519 status = ParseInt(tag + namelen, elemidx); 00520 if(status == CONV_OK) 00521 { 00522 //Reallocating indices if out of space 00523 if(indicessize >= indicescap) 00524 { 00525 MINIINI_REALLOCATE(indices, indicescap, indicessize, ui); 00526 } 00527 //Correct index, counting this array element 00528 indices[indicessize] = elemidx - 1; 00529 ++indicessize; 00530 } 00531 #ifdef MINIINI_DEBUG 00532 //Huge (out of range) integer in tag name- 00533 //Probably a different tag name or error 00534 else if(status == CONV_WAR_OVERFLOW) 00535 { 00536 MINIINI_WARNING("Integer in tag name out of range. Ignoring. " 00537 "Section: %s Tag name: %s", Name, tag); 00538 continue; 00539 } 00540 //Redunant chars after int - probably a different tag name or error 00541 else if(status == CONV_WAR_REDUNANT) 00542 { 00543 MINIINI_WARNING("Redunant characters after integer in tag name. " 00544 "Ignoring. Section: %s Tag name: %s", Name, tag); 00545 continue; 00546 } 00547 #endif 00548 } 00549 } 00550 ui elems = 0; 00551 bool finished = false; 00552 //Count number of consecutive indices 00553 while(!finished) 00554 { 00555 finished = true; 00556 for(ui idx = 0; idx < indicessize; ++idx) 00557 { 00558 if(indices[idx] == elems) 00559 { 00560 ++elems; 00561 finished = false; 00562 } 00563 } 00564 } 00565 delete [] indices; 00566 return static_cast<unsigned>(elems); 00567 } 00568 00569 unsigned INISection::ReadStrings(const char * const name, const char * * out, 00570 const unsigned cap) const 00571 { 00572 MINIINI_ASSERT(name, "NULL pointer was passed as base tag name to" 00573 "INISection::ReadStrings()"); 00574 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00575 "INISection::ReadStrings()"); 00576 ui namelen = strlen(name); 00577 //we fill out with zeroes, so we can search for null ptr to determine how 00578 //many elements we've read 00579 memset(out, 0, sizeof(const char *) * cap); 00580 //ptr to current tag 00581 const c * tag; 00582 //Index of current array element 00583 s32 elemidx; 00584 //Status of conversion of int in current tag name to index of array elemenent 00585 ConversionStatus status; 00586 for(ui idx = 0; idx < Length; ++idx) 00587 { 00588 tag = Tags[idx]; 00589 //if tag name starts by name 00590 if(!strncmp(name, tag, namelen)) 00591 { 00592 status = ParseInt(tag + namelen, elemidx); 00593 if(status == CONV_OK) 00594 { 00595 //Check for overflow 00596 if(elemidx > 0 && elemidx <= static_cast<s32>(cap)) 00597 { 00598 out[elemidx - 1] = (tag) + strlen(tag) + 1; 00599 } 00600 else 00601 { 00602 MINIINI_WARNING("Array element out of capacity." 00603 "Section: %s Tag name: %s Capacity: %d", 00604 Name, tag, cap); 00605 continue; 00606 } 00607 } 00608 #ifdef MINIINI_DEBUG 00609 //Huge (out of range) integer in tag name- 00610 //Probably a different tag name or error 00611 else if(status == CONV_WAR_OVERFLOW) 00612 { 00613 MINIINI_WARNING("Integer in tag name out of range. Ignoring. " 00614 "Section: %s Tag name: %s", Name, tag); 00615 continue; 00616 } 00617 //Redunant chars after int - probably a different tag name or error 00618 else if(status == CONV_WAR_REDUNANT) 00619 { 00620 MINIINI_WARNING("Redunant characters after integer in tag name. " 00621 "Ignoring. Section: %s Tag name: %s", Name, tag); 00622 continue; 00623 } 00624 #endif 00625 } 00626 } 00627 //return number of valid elements read 00628 //(if, say, elem 19 is missing, only elems 0-18 are valid) 00629 for(unsigned elem = 0; elem < cap; ++elem) 00630 { 00631 if(!out[elem]) 00632 { 00633 return elem; 00634 } 00635 } 00636 return cap; 00637 } 00638 00639 unsigned INISection::ReadInts(const char * const name, int * out, 00640 const unsigned cap) const 00641 { 00642 MINIINI_ASSERT(name, "NULL pointer was passed as base tag name to" 00643 "INISection::ReadInts()"); 00644 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00645 "INISection::ReadInts()"); 00646 //Array of value strings to be converted to ints 00647 const c * * const valstrs = new const c * [cap]; 00648 //Number of strings read by ReadStrings to valstrs 00649 const ui tempelems = ReadStrings(name, valstrs, cap); 00650 ui output = ParseInts(valstrs, out, tempelems); 00651 delete [] valstrs; 00652 return static_cast<unsigned>(output); 00653 } 00654 00655 unsigned INISection::ReadFloats(const char * const name, float * out, 00656 const unsigned cap) const 00657 { 00658 MINIINI_ASSERT(name, "NULL pointer was passed as base tag name to" 00659 "INISection::ReadFloats()"); 00660 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00661 "INISection::ReadFloats()"); 00662 //Array of value strings to be converted to floats 00663 const c * * const valstrs = new const c * [cap]; 00664 //Number of strings read by ReadStrings to valstrs 00665 const ui tempelems = ReadStrings(name, valstrs, cap); 00666 ui output = ParseFloats(valstrs, out, tempelems); 00667 delete [] valstrs; 00668 return static_cast<unsigned>(output); 00669 } 00670 00671 unsigned INISection::ReadBools(const char * const name, bool * out, 00672 const unsigned cap) const 00673 { 00674 MINIINI_ASSERT(name, "NULL pointer was passed as base tag name to" 00675 "INISection::ReadBools()"); 00676 MINIINI_ASSERT(out, "NULL pointer was passed as output buffer to" 00677 "INISection::ReadBools()"); 00678 //Array of value strings to be converted to bools 00679 const c * * const valstrs = new const c * [cap]; 00680 //Number of strings read by ReadStrings to valstrs 00681 const ui tempelems = ReadStrings(name, valstrs, cap); 00682 ui output = ParseBools(valstrs, out, tempelems); 00683 delete [] valstrs; 00684 return static_cast<unsigned>(output); 00685 } 00686 00687 #ifndef MINIINI_NO_STL 00688 unsigned INISection::ReadStrings(const std::string & name, 00689 std::vector<std::string> & out) const 00690 { 00691 const char * cname = name.c_str(); 00692 unsigned numelems = ArraySize(cname); 00693 //Read data to this array first 00694 const char * * tempstrs = new const char * [numelems]; 00695 numelems = ReadStrings(cname, tempstrs, numelems); 00696 out.reserve(numelems); 00697 //Move data to output vector 00698 for(ui str = 0; str < numelems; ++str) 00699 { 00700 out.push_back(std::string(tempstrs[str])); 00701 } 00702 delete [] tempstrs; 00703 return numelems; 00704 } 00705 00706 unsigned INISection::ReadInts(const std::string & name, 00707 std::vector<int> & out) const 00708 { 00709 const char * cname = name.c_str(); 00710 unsigned numelems = ArraySize(cname); 00711 //Read data to this array first 00712 int * tempints = new int [numelems]; 00713 numelems = ReadInts(cname, tempints, numelems); 00714 out.reserve(numelems); 00715 //Move data to output vector 00716 for(ui in = 0; in < numelems; ++in) 00717 { 00718 out.push_back(tempints[in]); 00719 } 00720 delete [] tempints; 00721 return numelems; 00722 } 00723 00724 unsigned INISection::ReadFloats(const std::string & name, 00725 std::vector<float> & out) const 00726 { 00727 const char * cname = name.c_str(); 00728 unsigned numelems = ArraySize(cname); 00729 //Read data to this array first 00730 float * tempfloats = new float [numelems]; 00731 numelems = ReadFloats(cname, tempfloats, numelems); 00732 out.reserve(numelems); 00733 //Move data to output vector 00734 for(ui fl = 0; fl < numelems; ++fl) 00735 { 00736 out.push_back(tempfloats[fl]); 00737 } 00738 delete [] tempfloats; 00739 return numelems; 00740 } 00741 00742 unsigned INISection::ReadBools(const std::string & name, 00743 std::vector<bool> & out) const 00744 { 00745 const char * cname = name.c_str(); 00746 unsigned numelems = ArraySize(cname); 00747 //Read data to this array first 00748 bool * tempbools = new bool [numelems]; 00749 numelems = ReadBools(cname, tempbools, numelems); 00750 out.reserve(numelems); 00751 //Move data to output vector 00752 for(ui bo = 0; bo < numelems; ++bo) 00753 { 00754 out.push_back(tempbools[bo]); 00755 } 00756 delete [] tempbools; 00757 return numelems; 00758 } 00759 #endif