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