00001 #include "stdafx.h" 00002 #include ".\cachedhttpfilesource.h" 00003 00004 CachedHTTPFileSource::CachedHTTPFileSource(void) 00005 00006 { 00007 } 00008 00009 CachedHTTPFileSource::~CachedHTTPFileSource(void) 00010 { 00011 } 00012 00013 CachedHTTPFileSource::tMapEntry CachedHTTPFileSource::findNextHoleInData(__int64 inUpto) 00014 { 00015 00016 tRangeMap::iterator locIt = mRangeMap.upper_bound(inUpto); 00017 00018 //Get the entry correspondingto this value. 00019 // The decrement is because of the stupid way the bound works in map. 00020 // The decrement of upper bound gives what you would expect a lower_bound function *should* 00021 // return... ie the thing lower than the given key. 00022 tMapEntry locEntry = *(--locIt); 00023 tMapEntry locNextEntry = *(++locIt); 00024 00025 //If we are in range, then we already have this 00026 if (inRange(locEntry, inUpto)) { 00027 bool locDone = false; 00028 00029 while (locIt != mRangeMap.end()) { 00030 //If the end of this range equals the start of the next range, then there is no hole here ! 00031 if (locEntry.second.first == (locNextEntry.first)) { 00032 locEntry = *(locIt); 00033 locNextEntry = *(++locIt); 00034 00035 } else { 00036 //There is a hole... since the end value of the current range is not the same as the start of the next range 00037 // So there is a hole from here.end+1 to next.start - 1 00038 tMapEntry retEntry; 00039 retEntry.first = locEntry.second.first + 1; 00040 retEntry.second.first = - 1; //The end becomes -1 until something goes in 00041 return retEntry; 00042 00043 } 00044 } 00045 } else { 00046 //This upto point is not in a known range. 00047 tMapEntry retEntry; 00048 retEntry.first = locEntry.second.first + 1; 00049 retEntry.second.first = - 1; //The end becomes -1 until something goes in 00050 return retEntry; 00051 00052 } 00053 } 00054 00055 bool CachedHTTPFileSource::startThread() { 00056 if (ThreadExists() == FALSE) { 00057 Create(); 00058 } 00059 CallWorker(THREAD_RUN); 00060 return true; 00061 } 00062 00063 DWORD CachedHTTPFileSource::ThreadProc(void) { 00064 //debugLog<<"ThreadProc:"<<endl; 00065 while(true) { 00066 DWORD locThreadCommand = GetRequest(); 00067 00068 switch(locThreadCommand) { 00069 case THREAD_EXIT: 00070 00071 Reply(S_OK); 00072 return S_OK; 00073 00074 00075 00076 case THREAD_RUN: 00077 00078 Reply(S_OK); 00079 DataProcessLoop(); 00080 break; 00081 } 00082 00083 00084 } 00085 return S_OK; 00086 } 00087 bool CachedHTTPFileSource::inRange(CachedHTTPFileSource::tMapEntry inTestRange, __int64 inTestValue) { 00088 00089 return ((inTestRange.first <= inTestValue) && (inTestRange.second.first >= inTestValue)); 00090 00091 00092 } 00093 00094 unsigned long CachedHTTPFileSource::seek(unsigned long inPos) { 00095 //Close the socket down 00096 //Open up a new one to the same place. 00097 //Make the partial content request. 00098 //debugLog<<"Seeking to "<<inPos<<endl; 00099 if (mReadFile.readSeek(inPos)) { 00100 return inPos; 00101 } else { 00102 return (unsigned long) -1; 00103 } 00104 00105 } 00106 00107 unsigned long CachedHTTPFileSource::read(char* outBuffer, unsigned long inNumBytes) { 00108 //Reads from the buffer, will return 0 if nothing in buffer. 00109 // If it returns 0 check the isEOF flag to see if it was the end of file or the network is just slow. 00110 00111 { //CRITICAL SECTION - PROTECTING STREAM BUFFER 00112 CAutoLock locLock(mBufferLock); 00113 00114 //debugLog<<"Read:"<<endl; 00115 if((mReadFile.bytesAvail() == 0) || mWasError) { 00116 //debugLog<<"read : Can't read is error or eof"<<endl; 00117 return 0; 00118 } else { 00119 //debugLog<<"Reading from buffer"<<endl; 00120 00121 unsigned long locNumRead = mReadFile.read((unsigned char*)outBuffer, inNumBytes); 00122 /* if (locNumRead == 0) { 00123 mStreamBuffer.clear(); 00124 }*/ 00125 00126 //debugLog<<locNumRead<<" bytes read from buffer"<<endl; 00127 return locNumRead; 00128 } 00129 } //END CRITICAL SECTION 00130 } 00131 00132 bool CachedHTTPFileSource::open(string inSourceLocation) { 00133 //Open network connection and start feeding data into a buffer 00134 // 00135 // In sourcelocation is a http url 00136 // 00137 00138 mSeenResponse = false; 00139 mLastResponse = ""; 00140 //debugLog<<"Open: "<<inSourceLocation<<endl; 00141 00142 { //CRITICAL SECTION - PROTECTING STREAM BUFFER 00143 CAutoLock locLock(mBufferLock); 00144 00145 //Init rand number generator 00146 LARGE_INTEGER locTicks; 00147 QueryPerformanceCounter(&locTicks); 00148 srand((unsigned int)locTicks.LowPart); 00149 00150 int locRand = rand(); 00151 00152 string locCacheFileName = getenv("TEMP"); 00153 //debugLog<<"Temp = "<<locCacheFileName<<endl; 00154 locCacheFileName += "\\filecache"; 00155 00156 //***************************************************** 00157 //TODO::: Need to do something about the filename... 00158 //***************************************************** 00159 locCacheFileName += StringHelper::numToString(locRand); 00160 locCacheFileName += ".ogg"; 00161 //debugLog<<"Cache file = "<<locCacheFileName<<endl; 00162 if(mReadFile.open(locCacheFileName)) { 00163 //debugLog<<"OPEN : Cach file opened"<<endl; 00164 } 00165 } //END CRITICAL SECTION 00166 00167 bool locIsOK = setupSocket(inSourceLocation); 00168 00169 if (!locIsOK) { 00170 //debugLog<<"Setup socket FAILED"<<endl; 00171 closeSocket(); 00172 return false; 00173 } 00174 00175 //debugLog<<"Sending request..."<<endl; 00176 00177 //How is filename already set ?? 00178 httpRequest(assembleRequest(mFileName)); 00179 //debugLog<<"Socket ok... starting thread"<<endl; 00180 locIsOK = startThread(); 00181 00182 00183 return locIsOK; 00184 } 00185 00186 void CachedHTTPFileSource::clear() { 00187 //Reset flags. 00188 mIsEOF = false; 00189 mWasError = false; 00190 } 00191 bool CachedHTTPFileSource::isEOF() { 00192 //{ //CRITICAL SECTION - PROTECTING STREAM BUFFER 00193 // CAutoLock locLock(mBufferLock); 00194 // //TODO::: 00195 // unsigned long locSizeBuffed = mFileCache.bytesAvail();; 00196 // 00197 00198 // //debugLog<<"isEOF : Amount Buffered avail = "<<locSizeBuffed<<endl; 00199 // if ((locSizeBuffed == 0) && mIsEOF) { 00200 // //debugLog<<"isEOF : It is EOF"<<endl; 00201 // return true; 00202 // } else { 00203 // //debugLog<<"isEOF : It's not EOF"<<endl; 00204 // return false; 00205 // } 00206 //} //END CRITICAL SECTION 00207 return false; 00208 } 00209 void CachedHTTPFileSource::close() { 00210 //Killing thread 00211 //debugLog<<"HTTPFileSource::close()"<<endl; 00212 if (ThreadExists() == TRUE) { 00213 //debugLog<<"Calling Thread to EXIT"<<endl; 00214 CallWorker(THREAD_EXIT); 00215 //debugLog<<"Killing thread..."<<endl; 00216 Close(); 00217 //debugLog<<"After Close called on CAMThread"<<endl; 00218 } 00219 00220 //debugLog<<"Closing socket..."<<endl; 00221 //Close the socket down. 00222 closeSocket(); 00223 } 00224 void CachedHTTPFileSource::DataProcessLoop() { 00225 //This loop sits here filling in holes 00226 00227 00228 //WHILE still holes 00229 // hole = findNextHoleInData(); 00230 // requestByteRange(hole) 00231 //WEND 00232 00233 00234 }