00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ctype.h>
00019 #include <stdlib.h>
00020 #include <limits.h>
00021 #include <string.h>
00022 #include <stdio.h>
00023 #include <unistd.h>
00024 #include <libgen.h>
00025 #include <errno.h>
00026 #include <iostream>
00027 using namespace std;
00028
00029 #include "RioMMSlideShow.h"
00030 #include "common.h"
00031 #include "RioFile.h"
00032 #include "RioError.h"
00033 #include "CommonLibraries.h"
00034
00035
00036 CRioMMSlideShow::CRioMMSlideShow( char * SlideName,
00037 unsigned int blocksize,
00038 RioBlock numBuffers,
00039 struct timeval RTT_average )
00040 : CRioMMObject( SlideName, blocksize, numBuffers , RTT_average )
00041 {
00042 CommandFile = NULL;
00043 LocalCommandFile = NULL;
00044
00045 CommandsList = NULL;
00046 NumberOfCommands = 0;
00047
00048 Command = NULL;
00049 TempDirectory = NULL;
00050 TempFileName = NULL;
00051 CurrentFileName = NULL;
00052 CurrentSlideNumber = 0;
00053 LastIndex = 0;
00054 Index = NULL;
00055 NextIndex = 0;
00056 NextCommandOffset = 0;
00057 Major = 0;
00058 Minor = 0;
00059 }
00060
00061
00062 CRioMMSlideShow::~CRioMMSlideShow( void )
00063 {
00064 if( LocalCommandFile )
00065 {
00066 fclose( LocalCommandFile );
00067 LocalCommandFile = NULL;
00068 }
00069
00070 if( CommandFile )
00071 {
00072 CommandFile->Delete( );
00073 delete CommandFile;
00074 CommandFile = NULL;
00075 }
00076
00077 RemoveSlides( );
00078 }
00079
00080
00081 int CRioMMSlideShow::init( void )
00082 {
00083 return 1;
00084 }
00085
00086
00087 void CRioMMSlideShow::SyncMedia( void * param )
00088 {
00089 int slide_number;
00090 int commands_offset;
00091 RioBlock first_command_index;
00092 ContextResult result;
00093
00094 #ifdef RIO_DEBUG2
00095 RioErr << "[RioMMSlideShow]: Entrou na SyncMedia (param=" << (RioBlock)(long)param
00096 << ")" << endl;
00097 #endif
00098
00099 SyncSpecific();
00100
00101
00102 result = Index->UpdateContext( (RioBlock)(long)param, TempFileName, &slide_number,
00103 &commands_offset, &first_command_index );
00104
00105
00106 if( result == CONTEXT_NOTCHANGED && (RioBlock)(long)param < LastIndex )
00107 {
00108
00109 result = CONTEXT_CHANGED;
00110 }
00111 LastIndex = (RioBlock)(long)param;
00112
00113 if( result == CONTEXT_FAILED )
00114 {
00115 #ifdef RIO_DEBUG2
00116 RioErr << "Synchronization out of context" << endl;
00117 #endif
00118
00119 return;
00120 }
00121
00122
00123 if( result == CONTEXT_CHANGED )
00124 {
00125 #ifdef RIO_DEBUG2
00126 RioErr << " [RioMMSlideShow]: Context HAS changed" << endl;
00127 #endif
00128
00129 if( !ChangeContext( (const char *)TempFileName, slide_number ) )
00130 {
00131 RioErr << "Cannot change slides from ("
00132 << TempFileName << "," << slide_number << ") to ("
00133
00134
00135 << "," << CurrentSlideNumber << ")" << endl;
00136 return;
00137 }
00138
00139 NextIndex = first_command_index;
00140 NextCommandOffset = commands_offset;
00141 }
00142
00143
00144 if( NextCommandOffset != -1 )
00145 {
00146
00147 while( NextIndex <= (RioBlock)(long)param )
00148 {
00149 InterpretNextCommand();
00150 }
00151 SyncSpecific();
00152 }
00153
00154 #ifdef RIO_DEBUG2
00155 RioErr << "[RioMMSlideShow]: Saindo da SyncMedia" << endl;
00156 #endif
00157 }
00158
00159
00160 int CRioMMSlideShow::GetCommands( RioAccess Access, CRioStream *Stream )
00161 {
00162 int rc = 1;
00163
00164 #ifdef RIO_DEBUG2
00165 RioErr << "[RioMMSlideShow]: Entrei na GetCommands" << endl;
00166 #endif
00167
00168 CommandFile = new RioFile( MMObjectName, BlockSize );
00169
00170 rc = CommandFile->Open( Access, Stream );
00171 if( rc < 0 )
00172 {
00173 return rc;
00174 }
00175
00176 CommandFile->Download();
00177
00178 LocalCommandFile = fopen( CommandFile->GetLocalFilename(), "r" );
00179
00180 Index = CRioMMIndexParser::ParseIndex( LocalCommandFile, TotalBlocks );
00181
00182 if( Index == NULL )
00183 {
00184 RioErr << "Cannot parse commands file" << endl;
00185 return -1;
00186 }
00187
00188 if( Index->GetMajor( ) != Major )
00189 {
00190 RioErr << "Incompatible command file: " << Index->GetMajor( )
00191 << " expecting " << Major << endl;
00192 return -1;
00193 }
00194 if( Index->GetMinor( ) != Minor )
00195 {
00196 RioErr << "Warning: Different command file" << endl;
00197 }
00198
00199 #ifdef RIO_DEBUG2
00200 RioErr << "[RioMMSlideShow]: Saindo da GetCommands" << endl;
00201 #endif
00202
00203 CommandFile->Close();
00204
00205 return rc;
00206 }
00207
00208
00209 int CRioMMSlideShow::GetSlides( RioAccess Access, CRioStream *Stream )
00210 {
00211 RioFile * ZipFile;
00212 int rc;
00213 int erro, errolib;
00214 TString temp_command;
00215 char temp_directory[ MAXPATHSIZE ];
00216 char archivePath[ MAXPATHSIZE ];
00217
00218 #ifdef RIO_DEBUG2
00219 RioErr << "[RioMMSlideShow]: Entrei na GetSlides" << endl;
00220 #endif
00221
00222 if( Index == NULL )
00223 {
00224 RioErr << "Cannot get slides without a command file" << endl;
00225 return -1;
00226 }
00227
00228 if( strcmp( Index->GetArchiveName(), basename(
00229 (char *)Index->GetArchiveName() ) ) == 0 )
00230 sprintf( archivePath, "%s/%s", dirname( MMObjectName ),
00231 Index->GetArchiveName() );
00232 else
00233 strcpy( archivePath, Index->GetArchiveName() );
00234
00235 ZipFile = new RioFile( archivePath, BlockSize );
00236
00237 #ifdef RIO_DEBUG2
00238 RioErr << " [RioMMSlideShow]: Vou abrir o arquivo ("
00239 << Index->GetArchiveName( ) << ")" << endl;
00240 #endif
00241
00242 rc = ZipFile->Open( Access, Stream );
00243 if( rc >= 0 )
00244 {
00245 ZipFile->Download( );
00246
00247 #ifdef RIO_DEBUG2
00248 RioErr << " [RioMMSlideShow]: Vou criar o diretorio" << endl;
00249 #endif
00250
00251 strcpy( temp_directory, "riommclient_slides_XXXXXXXXXXXXXXXX" );
00252 if( !RIOmktemp( temp_directory ) )
00253 {
00254 #ifdef RIO_DEBUG2
00255 RioErr << " [RioMMSlideShow]: Erro criando o diretorio "
00256 << "temporario" << endl;
00257 #endif
00258 }
00259 TempDirectory = temp_directory;
00260
00261 temp_command = "unzip -d " + TempDirectory + " "
00262 + ZipFile->GetLocalFilename();
00263
00264 #ifndef RIO_DEBUG2
00265 temp_command += " > /dev/null";
00266 #endif
00267
00268 erro = system( (const char *)temp_command );
00269 errolib = errno;
00270
00271 if( ( erro == -1 ) && ( errolib != ECHILD ) )
00272 {
00273 RioErr << "CRioMMSlideShow::GetSlides system falhou em executar o "
00274 << "comando " << (const char *) temp_command
00275 << " e gerou o erro " << errolib << " ("
00276 << strerror( errolib ) << ")." << endl;
00277 }
00278 else if( ( WIFEXITED( erro ) ) && ( WEXITSTATUS( erro ) != 0 ) )
00279 {
00280 RioErr << "CRioMMSlideShow::GetSlides o comando "
00281 << (const char *) temp_command << " executou corretamente, "
00282 << "mas retornou um valor " << WEXITSTATUS( erro )
00283 << " diferente de 0." << endl;
00284 }
00285
00286 #ifdef RIO_DEBUG2
00287 RioErr << "[SlideShow]: Deletando o arquivo" << endl;
00288 #endif
00289
00290 ZipFile->Delete();
00291 }
00292
00293 delete ZipFile;
00294
00295 #ifdef RIO_DEBUG2
00296 RioErr << "[RioMMSlideShow]: Saindo da GetSlides" << endl;
00297 #endif
00298 return rc;
00299 }
00300
00301
00302 void CRioMMSlideShow::RemoveSlides( void )
00303 {
00304 TString temp_command;
00305 int erro, errolib;
00306
00307 #ifdef RIO_DEBUG2
00308 RioErr << "[RioMMSlideShow]: Entrou na RemoveSlides" << endl;
00309 #endif
00310
00311 if( TempDirectory.Length( ) > 0 )
00312 {
00313 temp_command = "rm -rf " + TempDirectory;
00314 erro = system( (const char *)temp_command );
00315 errolib = errno;
00316
00317 if( ( erro == -1 ) && ( errolib != ECHILD ) )
00318 {
00319 RioErr << "CRioMMSlideShow::RemoveSlides system falhou em executar"
00320 << " o comando " << (const char *) temp_command
00321 << " e gerou o erro " << errolib << " ("
00322 << strerror( errolib ) << ")." << endl;
00323 }
00324 else if( ( WIFEXITED( erro ) ) && ( WEXITSTATUS( erro ) != 0 ) )
00325 {
00326 RioErr << "CRioMMSlideShow::GetSlides o comando "
00327 << (const char *) temp_command << " executou corretamente, "
00328 << "mas retornou um valor " << WEXITSTATUS( erro )
00329 << " diferente de 0." << endl;
00330 }
00331
00332 TempDirectory = NULL;
00333 }
00334
00335 #ifdef RIO_DEBUG2
00336 RioErr << "[RioMMSlideShow]: Saindo da RemoveSlides" << endl;
00337 #endif
00338 }
00339
00340
00341 void CRioMMSlideShow::CreateFakeSlide( void )
00342 {
00343 TString slidePath;
00344 ofstream slideFile;
00345
00346 slidePath = TempDirectory + "/init.html";
00347 slideFile.open( slidePath );
00348 if( slideFile )
00349 {
00350 slideFile << "<html>" << endl;
00351 slideFile << "<title>" << TempDirectory << "</title>" << endl;
00352 slideFile << "</html>" << endl;
00353 slideFile.close();
00354 }
00355 }
00356
00357
00358 void CRioMMSlideShow::Play( void )
00359 {
00360 Index->ResetContext( 1 );
00361 }
00362
00363
00364 void CRioMMSlideShow::Pause( void )
00365 {
00366 }
00367
00368
00369 void CRioMMSlideShow::FastForward( void )
00370 {
00371 }
00372
00373
00374 void CRioMMSlideShow::FastRewind( void )
00375 {
00376 }
00377
00378
00379 void CRioMMSlideShow::Stop( void )
00380 {
00381 }
00382
00383
00384 void CRioMMSlideShow::GoTo( RioBlock block )
00385 {
00386 }
00387
00388
00389
00390
00391
00392 bool CRioMMSlideShow::InterpretNextCommand( void )
00393 {
00394 int i;
00395 RioMMCommand command;
00396 bool status = false;
00397 TQueue args;
00398
00399 #ifdef RIO_DEBUG2
00400 RioErr << "[RioMMSlideShow]: Entrou na InterpretNextCommand" << endl;
00401 #endif
00402
00403 if( !CRioMMIndexParser::ParseCommand( LocalCommandFile, &command, args,
00404 &NextIndex, &NextCommandOffset ) )
00405 {
00406
00407
00408
00409 RioErr << "Cannot interpret invalid command syntax" << endl;
00410 status = false;
00411 }
00412 else
00413 {
00414 for( i = 0; i < NumberOfCommands; i++ )
00415 {
00416 if( command.name == CommandsList[ i ].name )
00417 {
00418 #ifdef RIO_DEBUG2
00419 RioErr << " [RioMMSlideShow]: Comando = "
00420 << command.name << endl;
00421 #endif
00422
00423 if( command.n_args != CommandsList[ i ].n_args )
00424 {
00425 RioErr << "Invalid number of parameters in call to "
00426 << command.name << endl;
00427 status = false;
00428 }
00429
00430 else if( command.arg_types != CommandsList[ i ].arg_types )
00431 {
00432 RioErr << "Invalid argument types in call to "
00433 << command.name << endl;
00434 status = false;
00435 }
00436 else
00437 {
00438 #ifdef RIO_DEBUG2
00439 RioErr << " [RioMMSlideShow]: Chamando callback" << endl;
00440 #endif
00441
00442 CommandsList[ i ].callback( this, args );
00443 status = true;
00444 }
00445 break;
00446 }
00447 }
00448 if( i == NumberOfCommands )
00449 {
00450 RioErr << "Unknown command: " << command.name << endl;
00451 }
00452 }
00453
00454 #ifdef RIO_DEBUG2
00455 RioErr << "[RioMMSlideShow]: Saiu da InterpretNextCommand" << endl;
00456 #endif
00457
00458 return status;
00459 }
00460
00461
00462
00463
00464
00465
00466 bool CRioMMSlideShow::ChangeContext( const char *file_name, int slide_number )
00467 {
00468 #ifdef RIO_DEBUG2
00469 RioErr << "[RioMMSlideShow]: Entrou na ChangeContext" << endl;
00470 #endif
00471
00472 CurrentFileName = file_name;
00473 CurrentSlideNumber = slide_number;
00474
00475 #ifdef RIO_DEBUG2
00476 RioErr << "[RioMMSlideShow]: Saiu da ChangeContext" << endl;
00477 #endif
00478 return true;
00479 }