1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #if   defined(_WIN32) && !defined(__STDWX_H__)
19 #include "boinc_win.h"
20 #elif defined(_WIN32) && defined(__STDWX_H__)
21 #include "stdwx.h"
22 #else
23 #include "config.h"
24 #include <string>
25 #include <cstring>
26 #include <cstdarg>
27 #endif
28 
29 #include "error_numbers.h"
30 #include "str_replace.h"
31 
32 #include "miofile.h"
33 
34 using std::string;
35 
MIOFILE()36 MIOFILE::MIOFILE() {
37     mf = 0;
38     wbuf = 0;
39     len = 0;
40     f = 0;
41     buf = 0;
42 }
43 
~MIOFILE()44 MIOFILE::~MIOFILE() {
45 }
46 
init_mfile(MFILE * _mf)47 void MIOFILE::init_mfile(MFILE* _mf) {
48     mf = _mf;
49 }
50 
init_file(FILE * _f)51 void MIOFILE::init_file(FILE* _f) {
52     f = _f;
53 }
54 
init_buf_read(const char * _buf)55 void MIOFILE::init_buf_read(const char* _buf) {
56     buf = _buf;
57 }
58 
init_buf_write(char * _buf,int _len)59 void MIOFILE::init_buf_write(char* _buf, int _len) {
60     wbuf = _buf;
61     len = _len;
62     wbuf[0] = 0;
63 }
64 
eof()65 bool MIOFILE::eof() {
66     if (f) {
67         if (!feof(f)) {
68             return false;
69         }
70     }
71     return true;
72 }
73 
74 
printf(const char * format,...)75 int MIOFILE::printf(const char* format, ...) {
76     int retval;
77 
78     va_list ap;
79     va_start(ap, format);
80     if (mf) {
81         retval = mf->vprintf(format, ap);
82     } else if (f) {
83         retval = vfprintf(f, format, ap);
84     } else {
85         size_t cursize = strlen(wbuf);
86         size_t remaining_len = len - cursize;
87         retval = vsnprintf(wbuf+cursize, remaining_len, format, ap);
88     }
89     va_end(ap);
90     return retval;
91 }
92 
fgets(char * dst,int dst_len)93 char* MIOFILE::fgets(char* dst, int dst_len) {
94     if (f) {
95 #ifndef _USING_FCGI_
96         return ::fgets(dst, dst_len, f);
97 #else
98         return FCGI::fgets(dst, dst_len, f);
99 #endif
100     }
101     const char* q = strchr(buf, '\n');
102     if (!q) return 0;
103 
104     q++;
105     int n = (int)(q - buf);
106     if (n > dst_len-1) n = dst_len-1;
107     memcpy(dst, buf, n);
108     dst[n] = 0;
109 
110     buf = q;
111     return dst;
112 }
113 
_ungetc(int c)114 int MIOFILE::_ungetc(int c) {
115     if (f) {
116 #ifdef _USING_FCGI_
117         return FCGI_ungetc(c, f);
118 #else
119         return ungetc(c, f);
120 #endif
121     } else {
122         buf--;
123         // NOTE: we assume that the char being pushed
124         // is what's already there
125         //*buf = c;
126     }
127     return c;
128 }
129 
130 // copy from a file to static buffer
131 //
copy_element_contents(MIOFILE & in,const char * end_tag,char * p,int len)132 int copy_element_contents(MIOFILE& in, const char* end_tag, char* p, int len) {
133     char buf[256];
134     int n;
135 
136     strlcpy(p, "", len);
137     while (in.fgets(buf, 256)) {
138         if (strstr(buf, end_tag)) {
139             return 0;
140         }
141         n = (int)strlen(buf);
142         if (n >= len-1) return ERR_XML_PARSE;
143         strlcat(p, buf, len);
144         len -= n;
145     }
146     return ERR_XML_PARSE;
147 }
148 
copy_element_contents(MIOFILE & in,const char * end_tag,string & str)149 int copy_element_contents(MIOFILE& in, const char* end_tag, string& str) {
150     char buf[256];
151 
152     str = "";
153     while (in.fgets(buf, 256)) {
154         if (strstr(buf, end_tag)) {
155             return 0;
156         }
157         str += buf;
158     }
159     fprintf(stderr, "copy_element_contents(): no end tag\n");
160     return ERR_XML_PARSE;
161 }
162 
163