Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <string.h>
00017 #include <shogun/io/IOBuffer.h>
00018
00019 using namespace shogun;
00020
00021 CIOBuffer::CIOBuffer()
00022 {
00023 init();
00024 }
00025
00026 CIOBuffer::CIOBuffer(int fd)
00027 {
00028 init();
00029 working_file = fd;
00030 }
00031
00032 CIOBuffer::~CIOBuffer()
00033 {
00034 }
00035
00036 void CIOBuffer::init()
00037 {
00038 size_t s = 1 << 16;
00039 space.reserve(s);
00040 endloaded = space.begin;
00041 }
00042
00043 void CIOBuffer::use_file(int fd)
00044 {
00045 working_file = fd;
00046 }
00047
00048 int CIOBuffer::open_file(const char* name, char flag)
00049 {
00050 int ret=1;
00051 switch(flag)
00052 {
00053 case 'r':
00054 working_file = open(name, O_RDONLY|O_LARGEFILE);
00055 break;
00056
00057 case 'w':
00058 working_file = open(name, O_CREAT|O_TRUNC|O_WRONLY, 0666);
00059 break;
00060
00061 default:
00062 SG_ERROR("Unknown file operation. Something other than 'r'/'w' specified.\n");
00063 ret = 0;
00064 }
00065 return ret;
00066 }
00067
00068 void CIOBuffer::reset_file()
00069 {
00070 lseek(working_file, 0, SEEK_SET);
00071 endloaded = space.begin;
00072 space.end = space.begin;
00073 }
00074
00075 void CIOBuffer::set(char *p)
00076 {
00077 space.end = p;
00078 }
00079
00080 ssize_t CIOBuffer::read_file(void* buf, size_t nbytes)
00081 {
00082 return read(working_file, buf, nbytes);
00083 }
00084
00085 size_t CIOBuffer::fill()
00086 {
00087 if (space.end_array - endloaded == 0)
00088 {
00089 size_t offset = endloaded - space.begin;
00090 space.reserve(2 * (space.end_array - space.begin));
00091 endloaded = space.begin+offset;
00092 }
00093 ssize_t num_read = read_file(endloaded, space.end_array - endloaded);
00094 if (num_read >= 0)
00095 {
00096 endloaded = endloaded+num_read;
00097 return num_read;
00098 }
00099 else
00100 return 0;
00101 }
00102
00103 ssize_t CIOBuffer::write_file(const void* buf, size_t nbytes)
00104 {
00105 return write(working_file, buf, nbytes);
00106 }
00107
00108 void CIOBuffer::flush()
00109 {
00110 if (write_file(space.begin, space.index()) != (int) space.index())
00111 SG_ERROR("Error, failed to write example!\n");
00112 space.end = space.begin;
00113 fsync(working_file);
00114 }
00115
00116 bool CIOBuffer::close_file()
00117 {
00118 if (working_file < 0)
00119 return false;
00120 else
00121 {
00122 int r = close(working_file);
00123 if (r < 0)
00124 SG_ERROR("Error closing the file!\n");
00125 return true;
00126 }
00127 }
00128
00129 ssize_t CIOBuffer::readto(char* &pointer, char terminal)
00130 {
00131
00132
00133 pointer = space.end;
00134 while (pointer != endloaded && *pointer != terminal)
00135 pointer++;
00136 if (pointer != endloaded)
00137 {
00138 size_t n = pointer - space.end;
00139 space.end = pointer+1;
00140 pointer -= n;
00141 return n;
00142 }
00143 else
00144 {
00145 if (endloaded == space.end_array)
00146 {
00147 size_t left = endloaded - space.end;
00148 memmove(space.begin, space.end, left);
00149 space.end = space.begin;
00150 endloaded = space.begin+left;
00151 pointer = endloaded;
00152 }
00153 if (fill() > 0)
00154 return readto(pointer,terminal);
00155 else
00156 return 0;
00157 }
00158 }
00159
00160 void CIOBuffer::buf_write(char* &pointer, int n)
00161 {
00162 if (space.end + n <= space.end_array)
00163 {
00164 pointer = space.end;
00165 space.end += n;
00166 }
00167 else
00168 {
00169 if (space.end != space.begin)
00170 flush();
00171 else
00172 {
00173 space.reserve(2 * (space.end_array - space.begin));
00174 endloaded = space.begin;
00175 }
00176 buf_write(pointer,n);
00177 }
00178 }
00179
00180 unsigned int CIOBuffer::buf_read(char* &pointer, int n)
00181 {
00182
00183
00184 if (space.end + n <= endloaded)
00185 {
00186 pointer = space.end;
00187 space.end += n;
00188 return n;
00189 }
00190 else
00191 {
00192 if (space.end != space.begin)
00193 {
00194
00195 int left = endloaded - space.end;
00196 memmove(space.begin, space.end, left);
00197 space.end = space.begin;
00198 endloaded = space.begin+left;
00199 }
00200 if (fill() > 0)
00201 return buf_read(pointer,n);
00202 else
00203 {
00204
00205 pointer = space.end;
00206 space.end = endloaded;
00207 return endloaded - pointer;
00208 }
00209 }
00210 }