Logo
~Sockets~
~Examples~
~Contact~


MemFile.cpp

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2004-2007  Anders Hedstrom
00007 
00008 This library is made available under the terms of the GNU GPL.
00009 
00010 If you would like to use this library in a closed-source application,
00011 a separate license agreement is available. For information about 
00012 the closed-source license agreement for the C++ sockets library,
00013 please visit http://www.alhem.net/Sockets/license.html and/or
00014 email license@alhem.net.
00015 
00016 This program is free software; you can redistribute it and/or
00017 modify it under the terms of the GNU General Public License
00018 as published by the Free Software Foundation; either version 2
00019 of the License, or (at your option) any later version.
00020 
00021 This program is distributed in the hope that it will be useful,
00022 but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 GNU General Public License for more details.
00025 
00026 You should have received a copy of the GNU General Public License
00027 along with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00029 */
00030 #ifdef _WIN32
00031 #pragma warning(disable:4786)
00032 #endif
00033 #include <stdarg.h>
00034 
00035 #include "MemFile.h"
00036 
00037 
00038 #ifdef SOCKETS_NAMESPACE
00039 namespace SOCKETS_NAMESPACE {
00040 #endif
00041 
00042 
00043 std::map<std::string,MemFile::block_t *> MemFile::m_files;
00044 
00045 
00046 MemFile::MemFile()
00047 :m_temporary(true)
00048 ,m_base(new block_t)
00049 ,m_current_read(m_base)
00050 ,m_current_write(m_base)
00051 ,m_read_ptr(0)
00052 ,m_write_ptr(0)
00053 ,m_b_read_caused_eof(false)
00054 {
00055 }
00056 
00057 
00058 MemFile::MemFile(const std::string& path)
00059 :m_path(path)
00060 ,m_temporary(false)
00061 ,m_base(m_files[path])
00062 ,m_current_read(NULL)
00063 ,m_current_write(NULL)
00064 ,m_read_ptr(0)
00065 ,m_write_ptr(0)
00066 ,m_b_read_caused_eof(false)
00067 {
00068         if (!m_base)
00069         {
00070                 m_base = new block_t;
00071                 m_files[path] = m_base;
00072         }
00073         m_current_read = m_base;
00074         m_current_write = m_base;
00075 }
00076 
00077 
00078 MemFile::~MemFile()
00079 {
00080         while (m_base && m_temporary)
00081         {
00082                 block_t *p = m_base;
00083                 m_base = p -> next;
00084                 delete p;
00085         }
00086 }
00087 
00088 
00089 bool MemFile::fopen(const std::string& path, const std::string& mode)
00090 {
00091         return true;
00092 }
00093 
00094 
00095 void MemFile::fclose()
00096 {
00097 }
00098 
00099 
00101 size_t MemFile::fread(char *ptr, size_t size, size_t nmemb) const
00102 {
00103         size_t p = m_read_ptr % BLOCKSIZE;
00104         size_t sz = size * nmemb;
00105         size_t available = m_write_ptr - m_read_ptr;
00106         if (sz > available) // read beyond eof
00107         {
00108                 sz = available;
00109                 m_b_read_caused_eof = true;
00110         }
00111         if (!sz)
00112         {
00113                 return 0;
00114         }
00115         if (p + sz < BLOCKSIZE)
00116         {
00117                 memcpy(ptr, m_current_read -> data + p, sz);
00118                 m_read_ptr += sz;
00119         }
00120         else
00121         {
00122                 size_t sz1 = BLOCKSIZE - p;
00123                 size_t sz2 = size - sz1;
00124                 memcpy(ptr, m_current_read -> data + p, sz1);
00125                 m_read_ptr += sz1;
00126                 if (m_current_read -> next)
00127                 {
00128                         m_current_read = m_current_read -> next;
00129                         memcpy(ptr + sz1, m_current_read -> data, sz2);
00130                         m_read_ptr += sz2;
00131                 }
00132                 else
00133                 {
00134                         return sz1;
00135                 }
00136         }
00137         return sz;
00138 }
00139 
00140 
00142 size_t MemFile::fwrite(const char *ptr, size_t size, size_t nmemb)
00143 {
00144         size_t p = m_write_ptr % BLOCKSIZE;
00145         size_t sz = size * nmemb;
00146         if (p + sz <= BLOCKSIZE)
00147         {
00148                 memcpy(m_current_write -> data + p, ptr, sz);
00149                 m_write_ptr += sz;
00150         }
00151         else
00152         {
00153                 size_t sz1 = BLOCKSIZE - p; // size left
00154                 size_t sz2 = sz - sz1;
00155                 memcpy(m_current_write -> data + p, ptr, sz1);
00156                 block_t *next = new block_t;
00157                 m_current_write -> next = next;
00158                 m_current_write = next;
00159                 memcpy(m_current_write -> data, ptr + sz1, sz2);
00160                 m_write_ptr += sz;
00161         }
00162         return sz;
00163 }
00164 
00165 
00166 
00167 char *MemFile::fgets(char *s, int size) const
00168 {
00169         int n = 0;
00170         while (n < size - 1 && !eof())
00171         {
00172                 char c;
00173                 size_t sz = fread(&c, 1, 1);
00174                 if (sz)
00175                 {
00176                         if (c == 10)
00177                         {
00178                                 s[n] = 0;
00179                                 return s;
00180                         }
00181                         s[n++] = c;
00182                 }
00183         }
00184         s[n] = 0;
00185         return s;
00186 }
00187 
00188 
00189 void MemFile::fprintf(const char *format, ...)
00190 {
00191         va_list ap;
00192         char tmp[BLOCKSIZE];
00193         va_start(ap, format);
00194 #ifdef _WIN32
00195         vsprintf(tmp, format, ap);
00196 #else
00197         vsnprintf(tmp, BLOCKSIZE - 1, format, ap);
00198 #endif
00199         va_end(ap);
00200         fwrite(tmp, 1, strlen(tmp));
00201 }
00202 
00203 
00204 off_t MemFile::size() const
00205 {
00206         return (off_t)m_write_ptr;
00207 }
00208 
00209 
00210 bool MemFile::eof() const
00211 {
00212         return m_b_read_caused_eof; //(m_read_ptr < m_write_ptr) ? false : true;
00213 }
00214 
00215 
00216 #ifdef SOCKETS_NAMESPACE
00217 }
00218 #endif
00219 
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4