00001
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 #ifdef _MSC_VER
00033 #pragma warning(disable:4786)
00034 #endif
00035 #include <stdio.h>
00036 #include <stdarg.h>
00037 #include <cstring>
00038 #include <iostream>
00039
00040 #include "MemFile.h"
00041 #include "Exception.h"
00042 #include "Lock.h"
00043 #include "Utility.h"
00044
00045
00046 #ifdef SOCKETS_NAMESPACE
00047 namespace SOCKETS_NAMESPACE {
00048 #endif
00049
00050
00051 MemFile::MemFile()
00052 :m_src(m_src)
00053 ,m_src_valid(false)
00054 ,m_base(new block_t)
00055 ,m_current_read(m_base)
00056 ,m_current_write(m_base)
00057 ,m_current_write_nr(0)
00058 ,m_read_ptr(0)
00059 ,m_write_ptr(0)
00060 ,m_b_read_caused_eof(false)
00061 ,m_ref_count(0)
00062 ,m_ref_decreased(false)
00063 {
00064 }
00065
00066
00067 MemFile::MemFile(MemFile& s)
00068 :m_src(s)
00069 ,m_src_valid(true)
00070 ,m_base(s.m_base)
00071 ,m_current_read(m_base)
00072 ,m_current_write(s.m_current_write)
00073 ,m_current_write_nr(s.m_current_write_nr)
00074 ,m_read_ptr(0)
00075 ,m_write_ptr(s.m_write_ptr)
00076 ,m_b_read_caused_eof(false)
00077 ,m_ref_count(0)
00078 ,m_ref_decreased(false)
00079 ,m_path(s.m_path)
00080 {
00081 m_src.Increase();
00082 }
00083
00084
00085 MemFile::MemFile(File& f)
00086 :m_src(m_src)
00087 ,m_src_valid(false)
00088 ,m_base(new block_t)
00089 ,m_current_read(NULL)
00090 ,m_current_write(NULL)
00091 ,m_current_write_nr(0)
00092 ,m_read_ptr(0)
00093 ,m_write_ptr(0)
00094 ,m_b_read_caused_eof(false)
00095 ,m_ref_count(0)
00096 ,m_ref_decreased(false)
00097 ,m_path(f.Path())
00098 {
00099 m_current_read = m_base;
00100 m_current_write = m_base;
00101 char slask[32768];
00102 size_t n;
00103 while ((n = f.fread(slask, 1, 32768)) > 0)
00104 {
00105 fwrite(slask, 1, n);
00106 }
00107 }
00108
00109
00110 MemFile::~MemFile()
00111 {
00112 if (m_ref_count)
00113 std::cerr << "MemFile destructor with a ref count of " + Utility::l2string(m_ref_count) << std::endl;
00114 while (m_base && !m_src_valid)
00115 {
00116 block_t *p = m_base;
00117 m_base = p -> next;
00118 delete p;
00119 }
00120 if (m_src_valid && !m_ref_decreased)
00121 {
00122 m_src.Decrease();
00123 m_ref_decreased = true;
00124 }
00125 }
00126
00127
00128 bool MemFile::fopen(const std::string& path, const std::string& mode)
00129 {
00130 return true;
00131 }
00132
00133
00134 void MemFile::fclose() const
00135 {
00136 if (m_src_valid && !m_ref_decreased)
00137 {
00138 m_src.Decrease();
00139 m_ref_decreased = true;
00140 }
00141 }
00142
00143
00144 size_t MemFile::fread(char *ptr, size_t size, size_t nmemb) const
00145 {
00146 size_t p = m_read_ptr % BLOCKSIZE;
00147 size_t sz = size * nmemb;
00148 size_t available = m_write_ptr - m_read_ptr;
00149 if (sz > available)
00150 {
00151 sz = available;
00152 m_b_read_caused_eof = true;
00153 }
00154 if (!sz)
00155 {
00156 return 0;
00157 }
00158 if (p + sz < BLOCKSIZE)
00159 {
00160 memcpy(ptr, m_current_read -> data + p, sz);
00161 m_read_ptr += sz;
00162 }
00163 else
00164 {
00165 size_t sz1 = BLOCKSIZE - p;
00166 size_t sz2 = sz - sz1;
00167 memcpy(ptr, m_current_read -> data + p, sz1);
00168 m_read_ptr += sz1;
00169 while (sz2 > BLOCKSIZE)
00170 {
00171 if (m_current_read -> next)
00172 {
00173 m_current_read = m_current_read -> next;
00174 memcpy(ptr + sz1, m_current_read -> data, BLOCKSIZE);
00175 m_read_ptr += BLOCKSIZE;
00176 sz1 += BLOCKSIZE;
00177 sz2 -= BLOCKSIZE;
00178 }
00179 else
00180 {
00181 return sz1;
00182 }
00183 }
00184 if (m_current_read -> next)
00185 {
00186 m_current_read = m_current_read -> next;
00187 memcpy(ptr + sz1, m_current_read -> data, sz2);
00188 m_read_ptr += sz2;
00189 }
00190 else
00191 {
00192 return sz1;
00193 }
00194 }
00195 return sz;
00196 }
00197
00198
00199 size_t MemFile::fwrite(const char *ptr, size_t size, size_t nmemb)
00200 {
00201 size_t p = m_write_ptr % BLOCKSIZE;
00202 int nr = (int)m_write_ptr / BLOCKSIZE;
00203 size_t sz = size * nmemb;
00204 if (m_current_write_nr < nr)
00205 {
00206 block_t *next = new block_t;
00207 m_current_write -> next = next;
00208 m_current_write = next;
00209 m_current_write_nr++;
00210 }
00211 if (p + sz <= BLOCKSIZE)
00212 {
00213 memcpy(m_current_write -> data + p, ptr, sz);
00214 m_write_ptr += sz;
00215 }
00216 else
00217 {
00218 size_t sz1 = BLOCKSIZE - p;
00219 size_t sz2 = sz - sz1;
00220 memcpy(m_current_write -> data + p, ptr, sz1);
00221 m_write_ptr += sz1;
00222 while (sz2 > BLOCKSIZE)
00223 {
00224 if (m_current_write -> next)
00225 {
00226 m_current_write = m_current_write -> next;
00227 m_current_write_nr++;
00228 }
00229 else
00230 {
00231 block_t *next = new block_t;
00232 m_current_write -> next = next;
00233 m_current_write = next;
00234 m_current_write_nr++;
00235 }
00236 memcpy(m_current_write -> data, ptr + sz1, BLOCKSIZE);
00237 m_write_ptr += BLOCKSIZE;
00238 sz1 += BLOCKSIZE;
00239 sz2 -= BLOCKSIZE;
00240 }
00241 if (m_current_write -> next)
00242 {
00243 m_current_write = m_current_write -> next;
00244 m_current_write_nr++;
00245 }
00246 else
00247 {
00248 block_t *next = new block_t;
00249 m_current_write -> next = next;
00250 m_current_write = next;
00251 m_current_write_nr++;
00252 }
00253 memcpy(m_current_write -> data, ptr + sz1, sz2);
00254 m_write_ptr += sz2;
00255 }
00256 return sz;
00257 }
00258
00259
00260
00261 char *MemFile::fgets(char *s, int size) const
00262 {
00263 int n = 0;
00264 while (n < size - 1 && !eof())
00265 {
00266 char c;
00267 size_t sz = fread(&c, 1, 1);
00268 if (sz)
00269 {
00270 if (c == 10)
00271 {
00272 s[n] = 0;
00273 return s;
00274 }
00275 s[n++] = c;
00276 }
00277 }
00278 s[n] = 0;
00279 return s;
00280 }
00281
00282
00283 void MemFile::fprintf(const char *format, ...)
00284 {
00285 va_list ap;
00286 char tmp[BLOCKSIZE];
00287 va_start(ap, format);
00288 vsnprintf(tmp, sizeof(tmp), format, ap);
00289 va_end(ap);
00290 fwrite(tmp, 1, strlen(tmp));
00291 }
00292
00293
00294 off_t MemFile::size() const
00295 {
00296 return (off_t)m_write_ptr;
00297 }
00298
00299
00300 bool MemFile::eof() const
00301 {
00302 return m_b_read_caused_eof;
00303 }
00304
00305
00306 void MemFile::reset_read() const
00307 {
00308 m_read_ptr = 0;
00309 m_current_read = m_base;
00310 }
00311
00312
00313 void MemFile::reset_write()
00314 {
00315 m_write_ptr = 0;
00316 m_current_write = m_base;
00317 m_current_write_nr = 0;
00318 }
00319
00320
00321 int MemFile::RefCount() const
00322 {
00323 return m_ref_count;
00324 }
00325
00326
00327 void MemFile::Increase()
00328 {
00329 ++m_ref_count;
00330 }
00331
00332
00333 void MemFile::Decrease()
00334 {
00335 --m_ref_count;
00336 }
00337
00338
00339 const std::string& MemFile::Path() const
00340 {
00341 return m_path;
00342 }
00343
00344
00345 #ifdef SOCKETS_NAMESPACE
00346 }
00347 #endif
00348
00349