00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <cstdio>
00042 #include <stdlib.h>
00043 #include <cerrno>
00044 #include <cstring>
00045
00046 #include "mmstools/mmsfile.h"
00047 #include "mmstools/tools.h"
00048
00049 #ifdef __HAVE_CURL__
00050
00051
00052
00053 size_t c_write_cb(char *buffer, size_t size, size_t nitems, void *outstream) {
00054 if (outstream)
00055 return ((MMSFile *)outstream)->write_cb(buffer, size, nitems, outstream);
00056 else
00057 return 0;
00058 }
00059
00060
00061 size_t MMSFile::write_cb(char *buffer, size_t size, size_t nitems, void *outstream) {
00062 char *newbuff;
00063 unsigned int freebuff;
00064
00065
00066 size *= nitems;
00067
00068
00069 freebuff=this->buf_len - this->buf_pos;
00070
00071 if(size > freebuff) {
00072
00073 newbuff=(char*)realloc(this->buffer,this->buf_len + (size - freebuff));
00074 if(newbuff==NULL) {
00075
00076 DEBUGERR("callback buffer grow failed\n");
00077 size=freebuff;
00078 }
00079 else {
00080
00081 this->buf_len+=size - freebuff;
00082 this->buffer=newbuff;
00083 }
00084 }
00085
00086 memcpy(&(this->buffer[this->buf_pos]), buffer, size);
00087 this->buf_pos += size;
00088
00089 return size;
00090 }
00091 #endif
00092
00093
00094 void MMSFile::resetAll() {
00095 this->type=MMSFT_NOTSET;
00096 this->mhandle=NULL;
00097 this->curl=NULL;
00098 this->file=NULL;
00099 this->buffer=NULL;
00100 this->buf_len=0;
00101 this->buf_pos=0;
00102 this->still_progr=0;
00103 this->cache=NULL;
00104 this->cache_fsize=0;
00105 this->cache_fpos=0;
00106 }
00107
00108
00109 bool MMSFile::fillCurlBuffer(size_t want, unsigned waittime) {
00110 #ifdef __HAVE_CURL__
00111 fd_set fdread;
00112 fd_set fdwrite;
00113 fd_set fdexcep;
00114 int maxfd;
00115 struct timeval timeout;
00116 int rc;
00117 CURLMcode cres;
00118
00119 if((!this->still_progr) || (this->buf_pos > want))
00120 return true;
00121
00122
00123 do {
00124
00125 if (!waittime) return false;
00126 waittime--;
00127
00128 FD_ZERO(&fdread);
00129 FD_ZERO(&fdwrite);
00130 FD_ZERO(&fdexcep);
00131
00132
00133 timeout.tv_sec = 60;
00134 timeout.tv_usec = 0;
00135
00136
00137 cres=curl_multi_fdset(this->mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
00138
00139 if(cres!=CURLM_OK) {
00140
00141 DEBUGERR("curl_multi_fdset failed %d\n",cres);
00142 return false;
00143 }
00144
00145
00146 rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
00147
00148 if (rc>0) {
00149 while(curl_multi_perform(this->mhandle, &this->still_progr) == CURLM_CALL_MULTI_PERFORM)
00150 usleep(10);
00151 }
00152 else
00153 if (rc<0) {
00154 return false;
00155 }
00156
00157 } while(this->still_progr && (this->buf_pos < want));
00158
00159 return true;
00160 #else
00161 return false;
00162 #endif
00163 }
00164
00165
00166 void MMSFile::freeCurlBuffer(size_t want) {
00167 #ifdef __HAVE_CURL__
00168
00169 if ((this->buf_pos - want) <=0) {
00170 if (this->buffer) free(this->buffer);
00171 this->buffer = NULL;
00172 this->buf_pos = 0;
00173 this->buf_len = 0;
00174 }
00175 else {
00176 memmove(this->buffer,
00177 &(this->buffer[want]),
00178 (this->buf_pos - want));
00179
00180 this->buf_pos -= want;
00181 }
00182 #endif
00183 }
00184
00185 bool MMSFile::openFile() {
00186 string tmp;
00187
00188
00189 if ((this->file)||(this->curl)) {
00190 this->lasterror = EBADF;
00191 return false;
00192 }
00193
00194
00195 this->type=MMSFT_NOTSET;
00196
00197
00198 tmp=this->name.substr(0, 7);
00199 strToUpr(&tmp);
00200 if (tmp=="HTTP://")
00201 this->type=MMSFT_URL;
00202 else
00203 this->type=MMSFT_FILE;
00204
00205 if (this->type!=MMSFT_URL) {
00206
00207 char tmpmode[4];
00208 switch (this->mode) {
00209 case MMSFM_READ:
00210 strcpy(tmpmode, "rb");
00211 break;
00212 case MMSFM_WRITE:
00213 strcpy(tmpmode, "wb");
00214 this->usecache=false;
00215 break;
00216 case MMSFM_APPEND:
00217 strcpy(tmpmode, "ab");
00218 this->usecache=false;
00219 break;
00220 case MMSFM_READWRITE:
00221 strcpy(tmpmode, "r+b");
00222 this->usecache=false;
00223 break;
00224 case MMSFM_WRITEREAD:
00225 strcpy(tmpmode, "w+b");
00226 this->usecache=false;
00227 break;
00228 case MMSFM_APPENDREAD:
00229 strcpy(tmpmode, "a+b");
00230 this->usecache=false;
00231 break;
00232 default:
00233 this->lasterror = EINVAL;
00234 return false;
00235 }
00236
00237 if (!(this->file=fopen(name.c_str(), tmpmode))) {
00238 this->lasterror=ENOENT;
00239 return false;
00240 }
00241 }
00242
00243 if (this->type!=MMSFT_FILE)
00244 {
00245 #ifdef __HAVE_CURL__
00246
00247
00248 if (this->mode!=MMSFM_READ) {
00249
00250 this->lasterror=EINVAL;
00251 return false;
00252 }
00253
00254 this->curl = curl_easy_init();
00255
00256 curl_easy_setopt(this->curl, CURLOPT_URL, this->name.c_str());
00257 curl_easy_setopt(this->curl, CURLOPT_FOLLOWLOCATION, true);
00258 curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, this);
00259 curl_easy_setopt(this->curl, CURLOPT_VERBOSE, false);
00260 curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, c_write_cb);
00261
00262 this->mhandle = curl_multi_init();
00263
00264 curl_multi_add_handle(mhandle, this->curl);
00265
00266
00267 while (curl_multi_perform(this->mhandle, &this->still_progr) == CURLM_CALL_MULTI_PERFORM)
00268 usleep(10);
00269
00270 if((this->buf_pos == 0) && (!this->still_progr)) {
00271
00272 curl_multi_remove_handle(this->mhandle, this->curl);
00273 curl_multi_cleanup(this->mhandle);
00274 curl_easy_cleanup(this->curl);
00275 resetAll();
00276 this->lasterror=ENOENT;
00277 return false;
00278 }
00279
00280
00281 this->type = MMSFT_URL;
00282 #else
00283 throw MMSFileError(-1, "compile curl support!");
00284 #endif
00285 }
00286
00287 if (this->usecache) {
00288
00289
00290 this->usecache=false;
00291
00292
00293 if (!readBufferEx((void**)&(this->cache), &(this->cache_fsize))) {
00294
00295 int err=this->lasterror;
00296 closeFile();
00297 this->lasterror=err;
00298 this->usecache=true;
00299 return false;
00300 }
00301
00302
00303 this->usecache=true;
00304
00305
00306 this->cache_fpos=0;
00307 }
00308
00309
00310 this->lasterror = 0;
00311 return true;
00312 }
00313
00314
00315 bool MMSFile::closeFile() {
00316 bool retcode=true;
00317
00318
00319 this->lasterror = 0;
00320
00321 switch(this->type) {
00322 case MMSFT_FILE:
00323 if (this->file) {
00324 if (fclose(this->file)!=0)
00325 this->lasterror = EOF;
00326 }
00327 else {
00328 this->lasterror = EBADF;
00329 retcode=false;
00330 }
00331 break;
00332
00333 case MMSFT_URL:
00334 #ifdef __HAVE_CURL__
00335
00336 if (this->curl) {
00337 if(this->mhandle) {
00338 curl_multi_remove_handle(this->mhandle, this->curl);
00339 curl_multi_cleanup(this->mhandle);
00340 }
00341 curl_easy_cleanup(this->curl);
00342 }
00343 else {
00344 this->lasterror = EBADF;
00345 retcode=false;
00346 }
00347 break;
00348 #else
00349 throw MMSFileError(-1, "compile curl support!");
00350 #endif
00351 default:
00352
00353 this->lasterror = EBADF;
00354 retcode=false;
00355 break;
00356 }
00357
00358
00359 if (this->buffer) free(this->buffer);
00360 if (this->cache) free(this->cache);
00361
00362
00363 resetAll();
00364
00365 return retcode;
00366 }
00367
00368
00369 MMSFile::MMSFile(string _name, MMSFileMode _mode, bool _usecache) :
00370 name(_name),
00371 mode(_mode),
00372 usecache(_usecache),
00373 lasterror(0) {
00374
00375
00376 resetAll();
00377
00378
00379 openFile();
00380 }
00381
00382
00383 MMSFile::~MMSFile() {
00384
00385 closeFile();
00386 }
00387
00388
00389 string MMSFile::getName(const bool effectiveUrl) {
00390 #ifdef __HAVE_CURL__
00391 if(effectiveUrl && this->type == MMSFT_URL) {
00392 char *buf = NULL;
00393 if(curl_easy_getinfo(this->curl, CURLINFO_EFFECTIVE_URL, buf) == CURLE_OK)
00394 return string(buf);
00395 }
00396
00397 return this->name;
00398 #else
00399 throw MMSFileError(-1, "compile curl support!");
00400 #endif
00401 }
00402
00403 MMSFileMode MMSFile::getMode() {
00404 return this->mode;
00405 }
00406
00407
00408 MMSFileType MMSFile::getType() {
00409 return this->type;
00410 }
00411
00412
00413 int MMSFile::getLastError() {
00414 return lasterror;
00415 }
00416
00417
00418 int MMSFile::endOfFile() {
00419
00420
00421 this->lasterror = 0;
00422
00423
00424 if (this->usecache) {
00425
00426 if (this->cache) {
00427 if (this->cache_fpos < this->cache_fsize)
00428
00429 return 0;
00430
00431
00432 this->lasterror = EOF;
00433 return EOF;
00434 }
00435
00436 this->lasterror = EBADF;
00437 return 1;
00438 }
00439
00440
00441 switch(this->type) {
00442 case MMSFT_FILE:
00443 if (this->file) {
00444 if (feof(this->file)==0)
00445
00446 return 0;
00447
00448
00449 this->lasterror = EOF;
00450 return EOF;
00451 }
00452 this->lasterror = EBADF;
00453 return 1;
00454
00455 case MMSFT_URL:
00456 #ifdef __HAVE_CURL__
00457 if (this->curl) {
00458 if((this->buf_pos == 0) && (!this->still_progr)) {
00459
00460 this->lasterror = EOF;
00461 return EOF;
00462 }
00463
00464 return 0;
00465 }
00466 this->lasterror = EBADF;
00467 return 1;
00468 #else
00469 throw MMSFileError(-1, "compile curl support!");
00470 #endif
00471
00472 default:
00473
00474 this->lasterror = EBADF;
00475 return 1;
00476 }
00477 }
00478
00479
00480 bool MMSFile::rewindFile() {
00481
00482
00483 this->lasterror = 0;
00484
00485
00486 if (this->usecache) {
00487
00488 if (this->cache) {
00489 this->cache_fpos = 0;
00490 return true;
00491 }
00492
00493 this->lasterror = EBADF;
00494 return false;
00495 }
00496
00497
00498 switch(this->type) {
00499 case MMSFT_FILE:
00500 if (this->file) {
00501 std::rewind(this->file);
00502 return true;
00503 }
00504 this->lasterror = EBADF;
00505 return false;
00506
00507 case MMSFT_URL:
00508 #ifdef __HAVE_CURL__
00509 if (this->curl) {
00510
00511 closeFile();
00512
00513
00514 return openFile();
00515 }
00516 this->lasterror = EBADF;
00517 return false;
00518 #else
00519 throw MMSFileError(-1, "compile curl support!");
00520 #endif
00521
00522 default:
00523
00524 this->lasterror = EBADF;
00525 return false;
00526 }
00527 }
00528
00529
00530 bool MMSFile::setFilePos(long offset, MMSFilePosOrigin origin) {
00531
00532
00533 this->lasterror = 0;
00534
00535
00536 if (this->usecache) {
00537
00538 if (this->cache) {
00539 long newfpos;
00540 switch (origin) {
00541 case MMSFPO_CUR:
00542 newfpos=(long)this->cache_fpos + offset;
00543 break;
00544 case MMSFPO_END:
00545 newfpos=(long)this->cache_fsize + offset;
00546 break;
00547 case MMSFPO_SET:
00548 newfpos=offset;
00549 break;
00550 default:
00551 this->lasterror = EINVAL;
00552 return false;
00553 }
00554 if (newfpos<0) {
00555 this->lasterror = EINVAL;
00556 return false;
00557 }
00558 if (newfpos>(long)this->cache_fsize) {
00559 this->lasterror = EINVAL;
00560 return false;
00561 }
00562 this->cache_fpos = (size_t)newfpos;
00563 return true;
00564 }
00565
00566 this->lasterror = EBADF;
00567 return false;
00568 }
00569
00570
00571 switch(this->type) {
00572 case MMSFT_FILE:
00573 if (this->file) {
00574 int tmporigin;
00575 switch (origin) {
00576 case MMSFPO_CUR:
00577 tmporigin=SEEK_CUR;
00578 break;
00579 case MMSFPO_END:
00580 tmporigin=SEEK_END;
00581 break;
00582 case MMSFPO_SET:
00583 tmporigin=SEEK_SET;
00584 break;
00585 default:
00586 this->lasterror = EINVAL;
00587 return false;
00588 }
00589 if (fseek(this->file, offset, tmporigin)==0)
00590 return true;
00591 }
00592 this->lasterror = EBADF;
00593 return false;
00594
00595 case MMSFT_URL:
00596 #ifdef __HAVE_CURL__
00597 if (this->curl) {
00598
00599
00600
00601
00602 }
00603 this->lasterror = EBADF;
00604 return false;
00605 #else
00606 throw MMSFileError(-1, "compile curl support!");
00607 #endif
00608 default:
00609
00610 this->lasterror = EBADF;
00611 return false;
00612 }
00613 }
00614
00615
00616 bool MMSFile::getFilePos(long *pos) {
00617 long mypos;
00618
00619
00620 this->lasterror = 0;
00621
00622
00623 if (this->usecache) {
00624
00625 if (this->cache) {
00626 *pos=(long)this->cache_fpos;
00627 return true;
00628 }
00629
00630 this->lasterror = EBADF;
00631 return false;
00632 }
00633
00634
00635 switch(this->type) {
00636 case MMSFT_FILE:
00637 if (this->file) {
00638 if ((mypos=ftell(this->file))>=0) {
00639 *pos=mypos;
00640 return true;
00641 }
00642 this->lasterror = errno;
00643 return false;
00644 }
00645 this->lasterror = EBADF;
00646 return false;
00647
00648 case MMSFT_URL:
00649 #ifdef __HAVE_CURL__
00650 if (this->curl) {
00651
00652
00653
00654
00655 }
00656 this->lasterror = EBADF;
00657 return false;
00658 #else
00659 throw MMSFileError(-1, "compile curl support!");
00660 #endif
00661
00662 default:
00663
00664 this->lasterror = EBADF;
00665 return false;
00666 }
00667 }
00668
00669
00670 bool MMSFile::readBuffer(void *ptr, size_t *ritems, size_t size, size_t nitems) {
00671 size_t myri;
00672
00673
00674 this->lasterror = 0;
00675
00676
00677 if (!ritems) ritems=&myri;
00678 *ritems=0;
00679
00680
00681 if ((!size) || (!nitems)) {
00682 this->lasterror = EINVAL;
00683 return false;
00684 }
00685
00686
00687 switch(this->type) {
00688 case MMSFT_FILE:
00689 if ((this->mode==MMSFM_WRITE)||(this->mode==MMSFM_APPEND)) {
00690 this->lasterror = EBADF;
00691 return false;
00692 }
00693 break;
00694
00695 case MMSFT_URL:
00696 #ifdef __HAVE_CURL__
00697 if (this->mode!=MMSFM_READ) {
00698 this->lasterror = EBADF;
00699 return false;
00700 }
00701 break;
00702 #else
00703 throw MMSFileError(-1, "compile curl support!");
00704 #endif
00705 default:
00706
00707 this->lasterror = EBADF;
00708 return false;
00709 }
00710
00711
00712 if (this->usecache) {
00713
00714 if (this->cache) {
00715
00716 size_t availdata=this->cache_fsize-this->cache_fpos;
00717 if (availdata <= 0) {
00718 availdata=0;
00719 this->lasterror=EOF;
00720 }
00721
00722
00723 *ritems = nitems * size;
00724 if (availdata < *ritems) *ritems=availdata;
00725
00726
00727 memcpy(ptr, &(this->cache[this->cache_fpos]), *ritems);
00728
00729
00730 this->cache_fpos+=*ritems;
00731
00732
00733 *ritems=*ritems/size;
00734 return true;
00735 }
00736
00737 this->lasterror = EBADF;
00738 return false;
00739 }
00740
00741
00742 switch(this->type) {
00743 case MMSFT_FILE:
00744 if (this->file) {
00745 *ritems = fread(ptr, size, nitems, this->file);
00746 if (*ritems < nitems) {
00747
00748 if (endOfFile()==EOF) return true;
00749
00750
00751 this->lasterror = EBADF;
00752 return false;
00753 }
00754 return true;
00755 }
00756 this->lasterror = EBADF;
00757 return false;
00758
00759 case MMSFT_URL:
00760 #ifdef __HAVE_CURL__
00761 if (this->curl) {
00762
00763 *ritems = nitems * size;
00764
00765
00766 if (!fillCurlBuffer(*ritems)) {
00767 this->lasterror = EBADF;
00768 return false;
00769 }
00770 if (!this->buf_pos) {
00771 this->lasterror = EBADF;
00772 return false;
00773 }
00774 if (this->buf_pos < *ritems)
00775 *ritems = this->buf_pos;
00776
00777
00778 memcpy(ptr, this->buffer, *ritems);
00779
00780
00781 freeCurlBuffer(*ritems);
00782
00783
00784 *ritems=*ritems/size;
00785 return true;
00786 }
00787 this->lasterror = EBADF;
00788 return false;
00789 #else
00790 throw MMSFileError(-1, "compile curl support!");
00791 #endif
00792
00793 default:
00794
00795 this->lasterror = EBADF;
00796 return false;
00797 }
00798 }
00799
00800
00801 bool MMSFile::readBufferEx(void **ptr, size_t *ritems, size_t size, size_t nitems) {
00802 size_t myri, myri2;
00803 size_t myni;
00804 void *newptr;
00805 bool ret;
00806
00807
00808 this->lasterror = 0;
00809
00810
00811 *ptr=NULL;
00812
00813
00814 if (!ritems) ritems=&myri2;
00815 *ritems=0;
00816
00817
00818 if ((!size) || (!nitems)) {
00819 this->lasterror = EINVAL;
00820 return false;
00821 }
00822
00823
00824 if ((myni = 0x1000 / size) < 1) myni=1;
00825 myri=0;
00826
00827
00828 do {
00829 if (endOfFile()==EOF) break;
00830 if ((myri > 0) && (myni > myri)) break;
00831 if (nitems == 0) break;
00832 if (nitems < myni) myni=nitems;
00833 nitems -= myni;
00834 *ritems = *ritems + myri;
00835
00836 newptr=realloc(*ptr,*ritems*size+myni*size);
00837 if (!newptr) {
00838 free(*ptr);
00839 *ptr=NULL;
00840 this->lasterror = ENOMEM;
00841 return false;
00842 }
00843 *ptr=newptr;
00844
00845 } while ((ret=readBuffer(&(((char*)*ptr)[*ritems*size]), &myri, size, myni)));
00846
00847
00848 if (ret) {
00849 if ((nitems == 0) || (endOfFile()==EOF)) {
00850 *ritems = *ritems + myri;
00851 return true;
00852 }
00853 else {
00854 free(*ptr);
00855 *ptr=NULL;
00856 this->lasterror = EBADF;
00857 return false;
00858 }
00859 }
00860 free(*ptr);
00861 *ptr=NULL;
00862 return false;
00863 }
00864
00865
00866 bool MMSFile::getString(char *ptr, size_t size) {
00867 size_t toget;
00868
00869
00870 this->lasterror = 0;
00871
00872
00873 if (!size) {
00874 this->lasterror = EINVAL;
00875 return false;
00876 }
00877
00878
00879 switch(this->type) {
00880 case MMSFT_FILE:
00881 if ((this->mode==MMSFM_WRITE)||(this->mode==MMSFM_APPEND)) {
00882 this->lasterror = EBADF;
00883 return false;
00884 }
00885 break;
00886
00887 case MMSFT_URL:
00888 #ifdef __HAVE_CURL__
00889 if (this->mode!=MMSFM_READ) {
00890 this->lasterror = EBADF;
00891 return false;
00892 }
00893 #else
00894 throw MMSFileError(-1, "compile curl support!");
00895 #endif
00896 break;
00897
00898 default:
00899
00900 this->lasterror = EBADF;
00901 return false;
00902 }
00903
00904
00905 if (this->usecache) {
00906
00907 if (this->cache) {
00908
00909 size_t availdata=this->cache_fsize-this->cache_fpos;
00910 if (availdata <= 0) {
00911 availdata=0;
00912 this->lasterror=EOF;
00913 }
00914
00915
00916 toget=size - 1;
00917 *ptr=0;
00918
00919
00920 if (availdata < toget) toget=availdata;
00921
00922
00923 for(unsigned int loop=this->cache_fpos; loop < this->cache_fpos + toget; loop++) {
00924 if (this->cache[loop] == '\n') {
00925 toget=loop+1-this->cache_fpos;
00926 break;
00927 }
00928 }
00929
00930
00931 memcpy(ptr, &(this->cache[this->cache_fpos]), toget);
00932 ptr[toget]=0;
00933
00934
00935 this->cache_fpos+=toget;
00936
00937 return true;
00938 }
00939
00940 this->lasterror = EBADF;
00941 return false;
00942 }
00943
00944
00945 switch(this->type) {
00946 case MMSFT_FILE:
00947 if (this->file) {
00948 *ptr=0;
00949 ptr = fgets(ptr, size, this->file);
00950 if (!ptr) {
00951
00952 if (endOfFile()==EOF) return true;
00953
00954
00955 this->lasterror = EBADF;
00956 return false;
00957 }
00958 return true;
00959 }
00960 this->lasterror = EBADF;
00961 return false;
00962
00963 case MMSFT_URL:
00964 #ifdef __HAVE_CURL__
00965 if (this->curl) {
00966
00967 toget=size - 1;
00968 *ptr=0;
00969
00970
00971 if (!fillCurlBuffer(toget)) {
00972 this->lasterror = EBADF;
00973 return false;
00974 }
00975 if (!this->buf_pos) {
00976 this->lasterror = EBADF;
00977 return false;
00978 }
00979 if (this->buf_pos < toget)
00980 toget = this->buf_pos;
00981
00982
00983 for(unsigned int loop=0; loop < toget; loop++) {
00984 if (this->buffer[loop] == '\n') {
00985 toget=loop+1;
00986 break;
00987 }
00988 }
00989
00990
00991 memcpy(ptr, this->buffer, toget);
00992 ptr[toget]=0;
00993
00994
00995 freeCurlBuffer(toget);
00996
00997 return true;
00998 }
00999 this->lasterror = EBADF;
01000 return false;
01001 #else
01002 throw MMSFileError(-1, "compile curl support!");
01003 #endif
01004
01005 default:
01006
01007 this->lasterror = EBADF;
01008 return false;
01009 }
01010 }
01011
01012
01013 bool MMSFile::getStringEx(char **ptr, size_t size) {
01014 size_t slen, mys;
01015 void *newptr;
01016 bool ret=false;
01017
01018
01019 this->lasterror = 0;
01020
01021
01022 *ptr=NULL;
01023
01024
01025 if (!size) {
01026 this->lasterror = EINVAL;
01027 return false;
01028 }
01029
01030
01031 mys=0x1000;
01032
01033
01034 do {
01035 if (endOfFile()==EOF) break;
01036
01037 slen=0;
01038 if (*ptr) {
01039 if (!**ptr) break;
01040 slen=strlen(*ptr);
01041 if ((*ptr)[slen-1] == '\n') {
01042 size=0;
01043 break;
01044 }
01045 }
01046 if (size == 0) break;
01047
01048 if (size<mys) mys=size;
01049 size-=mys;
01050
01051 newptr=realloc(*ptr, (!slen)?(slen+mys):(slen+mys+1));
01052 if (!newptr) {
01053 free(*ptr);
01054 *ptr=NULL;
01055 this->lasterror = ENOMEM;
01056 return false;
01057 }
01058 *ptr=(char*)newptr;
01059
01060 } while ((ret=getString(&((*ptr)[slen]), (!slen)?mys:(mys+1))));
01061
01062
01063 if (ret) {
01064 if ((size == 0) || (endOfFile()==EOF)) {
01065 return true;
01066 }
01067 else {
01068 free(*ptr);
01069 *ptr=NULL;
01070 this->lasterror = EBADF;
01071 return false;
01072 }
01073 }
01074 free(*ptr);
01075 *ptr=NULL;
01076 return false;
01077 }
01078
01079
01080 bool MMSFile::getLine(char **ptr) {
01081 int slen;
01082
01083 if (getStringEx(ptr))
01084 if (*ptr)
01085 if (**ptr) {
01086 slen=strlen(*ptr);
01087 if ((*ptr)[slen-1]=='\n')
01088 (*ptr)[slen-1]=0;
01089 return true;
01090 }
01091
01092 return false;
01093 }
01094
01095 bool MMSFile::getLine(string &line) {
01096 int slen;
01097 char *ptr = NULL;
01098 int ret = false;
01099
01100 if (getStringEx(&ptr)) {
01101 if (ptr) {
01102 if (*ptr) {
01103 slen=strlen(ptr);
01104 if ((ptr)[slen-1]=='\n')
01105 (ptr)[slen-1]=0;
01106 line = ptr;
01107 ret = true;
01108 }
01109 free(ptr);
01110 }
01111 }
01112
01113 return ret;
01114 }
01115
01116 bool MMSFile::getChar(char *ptr) {
01117 char retc;
01118 size_t ritems;
01119
01120 if (!ptr) ptr=&retc;
01121
01122 if (readBuffer(ptr, &ritems, 1, 1))
01123 if (ritems==1)
01124 return true;
01125
01126 return false;
01127 }
01128
01129
01130 bool MMSFile::writeBuffer(void *ptr, size_t *ritems, size_t size, size_t nitems) {
01131 size_t myri;
01132
01133
01134 this->lasterror = 0;
01135
01136
01137 if (!ritems) ritems=&myri;
01138 *ritems=0;
01139
01140
01141 if ((!size) || (!nitems)) {
01142 this->lasterror = EINVAL;
01143 return false;
01144 }
01145
01146
01147 switch(this->type) {
01148 case MMSFT_FILE:
01149 if (this->mode==MMSFM_READ) {
01150 this->lasterror = EBADF;
01151 return false;
01152 }
01153 break;
01154
01155 case MMSFT_URL:
01156 #ifdef __HAVE_CURL__
01157
01158
01159 this->lasterror = EBADF;
01160 return false;
01161 #else
01162 throw MMSFileError(-1, "compile curl support!");
01163 #endif
01164
01165 default:
01166
01167 this->lasterror = EBADF;
01168 return false;
01169 }
01170
01171
01172 if (this->usecache) {
01173
01174 this->lasterror = EBADF;
01175 return false;
01176 }
01177
01178
01179 switch(this->type) {
01180 case MMSFT_FILE:
01181 if (this->file) {
01182 *ritems = fwrite(ptr, size, nitems, this->file);
01183 if (*ritems < nitems) {
01184
01185 this->lasterror = EBADF;
01186 return false;
01187 }
01188 return true;
01189 }
01190 this->lasterror = EBADF;
01191 return false;
01192
01193 case MMSFT_URL:
01194 #ifdef __HAVE_CURL__
01195 if (this->curl) {
01196
01197
01198 }
01199 this->lasterror = EBADF;
01200 return false;
01201 #else
01202 throw MMSFileError(-1, "compile curl support!");
01203 #endif
01204
01205 default:
01206
01207 this->lasterror = EBADF;
01208 return false;
01209 }
01210 }