00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019 using namespace std;
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025
00026 #include "BufferStream.h"
00027 #include "RioError.h"
00028
00029 BufferStream::BufferStream( char *fileName, unsigned int streamSize,
00030 unsigned int blockSize )
00031 {
00032 #ifndef RIO_EMUL
00033 char path[ MAXLEN_FILE + 1 ];
00034 #endif
00035
00036 streamControl = new StreamControl [ streamSize ];
00037
00038 for( int i = 0 ; i < (int)streamSize ; i++ )
00039 {
00040 streamControl[ i ].writePoint = 0;
00041 streamControl[ i ].unicastRequested = false;
00042 }
00043
00044 #ifndef RIO_EMUL
00045 if( getcwd( path, MAXLEN_FILE ) == NULL )
00046 {
00047 RioErr << "[ Error ] Unable to get working directory " << endl;
00048 }
00049 setFileName( ( const char * ) fileName );
00050 #endif
00051
00052 this->streamSize = streamSize;
00053 this->blockSize = blockSize;
00054
00055 this->writePoint = 0;
00056 this->offset = 0;
00057
00058 #ifndef RIO_EMUL
00059 char tempName[ MAXLEN_FILE +1];
00060 strcpy( tempName , "riommclientStream." );
00061 strncat( tempName , getFileName() , MAXLEN_FILE - 6 - 1 );
00062 strcat( tempName , ".XXXXXX" );
00063 int fd = mkstemp( tempName );
00064 if( fd )
00065 close( fd );
00066
00067 setFileName( tempName, path );
00068 if( ( streamFile = fopen( getFileName() , "w+" ) ) == NULL ) {
00069 RioErr << "[ Error ] Unable to Open " << getFileName() << endl;
00070 }
00071 #ifdef RIO_DEBUG2
00072 else
00073 RioErr << "Creating cache at " << getFileName() << endl;
00074 #endif
00075 #endif // end ifndef RIO_EMUL
00076
00077 }
00078
00079 BufferStream::~BufferStream()
00080 {
00081 #ifndef RIO_EMUL
00082 if( streamFile )
00083 {
00084 fclose( streamFile );
00085 remove( getFileName() );
00086 }
00087 #endif
00088
00089 delete[] streamControl;
00090 }
00091
00092 unsigned int BufferStream::getBlockSize()
00093 {
00094 return this->blockSize;
00095 }
00096
00097 void BufferStream::setFileName( const char *fileName )
00098 {
00099 if( fileName )
00100 {
00101 char file[ MAXLEN_FILE + 1 ];
00102 strncpy( file , fileName , MAXLEN_FILE );
00103
00104 char *shortFileName;
00105 if( ( shortFileName = strrchr( file , '/' ) ) == NULL )
00106 shortFileName = file;
00107 else
00108 shortFileName++;
00109
00110 snprintf( this->fileName , MAXLEN_FILE , "%s" , shortFileName );
00111 this->fileName[ MAXLEN_FILE ] = '\0';
00112 }
00113 else
00114 {
00115 strcpy( this->fileName , "" );
00116 }
00117 }
00118
00119 void BufferStream::setFileName( const char *fileName, const char *localPath )
00120 {
00121 char file[ MAXLEN_FILE + MAXLEN_FILE + 1 ];
00122
00123 setFileName( fileName );
00124 if( localPath )
00125 {
00126 sprintf( file, "%s/%s", localPath, fileName );
00127 strcpy( this->fileName, file );
00128 }
00129 }
00130
00131 char *BufferStream::getFileName()
00132 {
00133 return this->fileName;
00134 }
00135
00136
00137 int BufferStream::writeBlock( unsigned int n , unsigned char *block )
00138 {
00139
00140 #ifdef RIO_EMUL
00141 bool simulacao = true;
00142 #endif
00143
00144 #ifndef RIO_EMUL
00145 if( streamFile == NULL )
00146 return 2;
00147 #endif
00148
00149 unsigned int writeN = 0;
00150
00151 if( n >= streamSize )
00152 return 1;
00153
00154 #ifdef RIO_EMUL
00155 if( simulacao )
00156 #else
00157
00158
00159 if( fseek( streamFile , offset , SEEK_END ) == 0 )
00160 {
00161 if( ( writeN = fwrite( block , 1 , blockSize , streamFile ) ) ==
00162 blockSize
00163 )
00164 #endif
00165 {
00166 offset = 0;
00167 writePoint++;
00168 streamControl[ n ].writePoint = writePoint;
00169
00170 #ifdef RIO_DEBUG2
00171 RioErr << "[BufferStream] BUFFER GRAVADO (Bloco="<< n
00172 << " & Posicao=" << streamControl[ n ].writePoint << ")" << endl;
00173 #endif
00174
00175 return 0;
00176 }
00177 else
00178 {
00179 offset = -1 * writeN;
00180
00181 #ifdef RIO_DEBUG2
00182 RioErr << "[BufferStream] Nao conseguiu gravar dados na cache."
00183 << endl;
00184 #endif
00185
00186 return 1;
00187 }
00188 #ifndef RIO_EMUL
00189 }
00190 #endif
00191
00192 return 1;
00193 }
00194
00195 int BufferStream::getNextBlock( unsigned int *block )
00196 {
00197 if( !block )
00198 return 1;
00199
00200 if( *block > streamSize )
00201 return 2;
00202
00203 while( exist( *block ) )
00204 (*block)++;
00205
00206 return 0;
00207 }
00208
00209 int BufferStream::readBlock( unsigned int n , unsigned char *block )
00210 {
00211 #ifndef RIO_EMUL
00212 unsigned int readN;
00213 #endif
00214
00215 int status;
00216
00217 status = 5;
00218
00219 #ifndef RIO_EMUL
00220 if( streamFile == NULL )
00221 status = 2;
00222 #endif
00223
00224 if( status == 5 && n >= streamSize )
00225 status = 1;
00226 else if( status == 5 && streamControl[ n ].writePoint == 0 )
00227 status = 3;
00228
00229 #ifndef RIO_EMUL
00230 {
00231 if( fseek( streamFile, ( streamControl[n].writePoint - 1 ) * blockSize,
00232 SEEK_SET ) == 0)
00233 {
00234 #ifdef RIO_DEBUG2
00235 RioErr << "[BufferStream] readBlock - Lendo bloco " << n
00236 << " da cache... ";
00237 #endif
00238
00239 if( ( readN = fread( block , 1 , blockSize , streamFile ) ) ==
00240 blockSize
00241 )
00242 {
00243 status = 0;
00244 }
00245 else
00246 {
00247 status = 4;
00248 }
00249
00250 #ifdef RIO_DEBUG2
00251 RioErr << "lido " << (float) ( 100 * readN ) / (float) blockSize
00252 << "%"<< endl;
00253 #endif
00254
00255 }
00256 #ifdef RIO_DEBUG2
00257 else
00258 RioErr << "[BufferStream] readBlock - Bloco " << n
00259 << " n�o est� na cache... " << endl;
00260 #endif
00261 }
00262 #else
00263 {
00264 if( status == 5 )
00265 {
00266 status = 0;
00267 }
00268 }
00269 #endif
00270
00271 return status;
00272 }
00273
00274 int BufferStream::exist( unsigned int n )
00275 {
00276 if( n >= streamSize )
00277 return 0;
00278
00279 if( streamControl[ n ].writePoint == 0 )
00280 return 0;
00281 else
00282 return 1;
00283 }
00284
00285 #ifdef RIO_EMUL
00286 bool BufferStream::dropBlock( unsigned int n )
00287 {
00288 if( n >= streamSize )
00289 return false;
00290
00291 streamControl[ n ].writePoint = 0;
00292
00293 return true;
00294 }
00295 #endif
00296
00297 int BufferStream::isUnicast( unsigned int n )
00298 {
00299 if( n >= streamSize )
00300 {
00301 #ifdef RIO_DEBUG2
00302 RioErr << "[BufferStream - isUnicast] Erro tentando acessar posicao "
00303 << "inexistente da cache: " << n << "/" << streamSize << endl;
00304 #endif
00305
00306 return -1;
00307 }
00308
00309 return streamControl[n].unicastRequested;
00310 }
00311
00312 void BufferStream::setUnicast( unsigned int n )
00313 {
00314 streamControl[n].unicastRequested = true;
00315 }