1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #ifndef PVMF_PROTOCOLENGINE_PROGRESSIVE_DOWNLOAD_H_INCLUDED 19 #define PVMF_PROTOCOLENGINE_PROGRESSIVE_DOWNLOAD_H_INCLUDED 20 21 #ifndef PVMF_PROTOCOLENGINE_DOWNLOAD_COMMON_H_INCLUDED 22 #include "pvmf_protocol_engine_download_common.h" 23 #endif 24 25 #define DEFAULT_STATE_NUMBER_FOR_DOWNLOAD_GET_REQUEST 1 // for progressive streaming or shoutcast 26 27 28 class ProgressiveDownloadState_HEAD : public DownloadState 29 { 30 public: 31 bool isCurrentStateOptional() 32 { 33 return true; 34 } 35 36 private: 37 // To compose a request, the only difference is HEAD method 38 OSCL_IMPORT_REF void setRequestBasics(); 39 OSCL_IMPORT_REF bool setHeaderFields(); 40 OSCL_IMPORT_REF int32 checkParsingStatus(int32 parsingStatus); 41 int32 updateDownloadStatistics() 42 { 43 return 0; 44 } 45 46 // From HttpParsingBasicObjectObserver 47 OSCL_IMPORT_REF int32 OutputDataAvailable(OUTPUT_DATA_QUEUE *aOutputQueue, const bool isHttpHeader); 48 }; 49 50 class ProgressiveDownloadState_GET : public DownloadState 51 { 52 public: 53 ProgressiveDownloadState_GET() : iSendEndOfMessageTruncate(false), iRangeHeaderSupported(true) 54 { 55 ; 56 } 57 // virtual destructor, let internal objects destruct automatically 58 virtual ~ProgressiveDownloadState_GET() 59 { 60 iOutputDataQueue.clear(); 61 } 62 63 void stop(const bool isAfterEOS = false) 64 { 65 OSCL_UNUSED_ARG(isAfterEOS); 66 reset(); 67 sendRequest(); 68 } 69 70 void reset() 71 { 72 iSendEndOfMessageTruncate = false; 73 DownloadState::reset(); 74 } 75 76 protected: 77 OSCL_IMPORT_REF int32 processMicroStateGetResponsePreCheck(); 78 OSCL_IMPORT_REF virtual bool setHeaderFields(); 79 OSCL_IMPORT_REF bool setRangeHeaderFields(); 80 // From HttpParsingBasicObjectObserver 81 OSCL_IMPORT_REF int32 OutputDataAvailable(OUTPUT_DATA_QUEUE *aOutputQueue, const bool isHttpHeader); 82 OSCL_IMPORT_REF void updateOutputDataQueue(OUTPUT_DATA_QUEUE *aOutputQueue); 83 bool isDownloadStreamingDoneState() 84 { 85 return true; 86 } 87 bool isLastState() 88 { 89 return true; 90 } 91 OSCL_IMPORT_REF void getStartFragmentInNewDownloadData(OUTPUT_DATA_QUEUE &aOutputQueue, 92 bool &aUseAllNewDownloadData, 93 uint32 &aStartFragsNo, 94 uint32 &aStartFragOffset); 95 OSCL_IMPORT_REF void getEndFragmentInNewDownloadData(OUTPUT_DATA_QUEUE &aOutputQueue, 96 uint32 &aEndFragNo, 97 uint32 &aEndFragValidLen); 98 OSCL_IMPORT_REF int32 checkContentInfoMatchingForResumeDownload(); 99 OSCL_IMPORT_REF virtual int32 checkParsingStatus(int32 parsingStatus); 100 OSCL_IMPORT_REF int32 updateDownloadStatistics(); 101 102 protected: 103 bool iSendEndOfMessageTruncate; 104 bool iRangeHeaderSupported; 105 }; 106 107 // Progressive Streaming is a special form of progressive download 108 class ProgressiveStreamingState_GET : public ProgressiveDownloadState_GET 109 { 110 public: 111 virtual void seek(const uint32 aSeekPosition) 112 { 113 iCfgFile->SetCurrentFileSize(aSeekPosition); 114 iNeedGetResponsePreCheck = true; // reset the parser 115 } 116 117 protected: 118 OSCL_IMPORT_REF int32 checkParsingStatus(int32 parsingStatus); 119 void saveConfig() 120 { 121 ; 122 } 123 }; 124 125 // Http progressive download, do state transition 126 class ProgressiveDownload : public HttpBasedProtocol 127 { 128 public: 129 // create states of state machine 130 ProgressiveDownload() 131 { 132 iState[0] = OSCL_NEW(ProgressiveDownloadState_HEAD, ()); 133 iState[1] = OSCL_NEW(ProgressiveDownloadState_GET, ()); 134 iInitStateNum = 0; 135 iCurrStateNum = iInitStateNum; 136 iCurrState = iState[iCurrStateNum]; 137 138 // create iComposer and iParser 139 iComposer = HTTPComposer::create(); 140 iParser = HttpParsingBasicObject::create(); 141 } 142 143 // destructor 144 virtual ~ProgressiveDownload() 145 { 146 uint32 i = 0; 147 for (i = 0; i < NUM_PROGRESSIVE_DOWNLOAD_STATE; i++) 148 { 149 if (iState[i]) OSCL_DELETE(iState[i]); 150 iState[i] = NULL; 151 } 152 153 OSCL_DELETE(iComposer); 154 OSCL_DELETE(iParser); 155 } 156 157 void setConfigInfo(OsclAny* aConfigInfo) 158 { 159 iCfgFile = *((OsclSharedPtr<PVDlCfgFile> *)aConfigInfo); 160 HttpBasedProtocol::setConfigInfo(aConfigInfo); 161 } 162 163 164 void initialize() 165 { 166 // pass iComposer and iParser down to each state 167 uint32 i = 0; 168 for (i = 0; i < NUM_PROGRESSIVE_DOWNLOAD_STATE; i++) 169 { 170 iState[i]->setObserver(this); 171 iState[i]->setComposer(iComposer); 172 iState[i]->setParser(iParser); 173 } 174 if (iCfgFile.GetRep()) 175 { 176 if (iCfgFile->getHttpHeadRequestDisabled()) 177 { 178 iInitStateNum = 1; 179 iCurrStateNum = iInitStateNum; 180 iCurrState = iState[iCurrStateNum]; 181 } 182 } 183 } 184 185 void reset() 186 { 187 HttpBasedProtocol::reset(); 188 iCurrStateNum = 0; 189 iCurrState = iState[iCurrStateNum]; 190 } 191 192 protected: 193 // state transition 194 ProtocolState* getNextState() 195 { 196 // release the memory for the current state 197 if (++iCurrStateNum >= NUM_PROGRESSIVE_DOWNLOAD_STATE) iCurrStateNum = iInitStateNum; 198 return iState[iCurrStateNum]; 199 } 200 201 protected: 202 DownloadState *iState[NUM_PROGRESSIVE_DOWNLOAD_STATE]; 203 uint32 iCurrStateNum; 204 OsclSharedPtr<PVDlCfgFile> iCfgFile; 205 uint32 iInitStateNum; 206 }; 207 208 class ProgressiveStreaming : public ProgressiveDownload 209 { 210 public: 211 ProgressiveStreaming(): ProgressiveDownload() 212 { 213 214 OSCL_DELETE(iState[DEFAULT_STATE_NUMBER_FOR_DOWNLOAD_GET_REQUEST]); 215 iState[DEFAULT_STATE_NUMBER_FOR_DOWNLOAD_GET_REQUEST] = OSCL_NEW(ProgressiveStreamingState_GET, ()); 216 if (iParser) iParser->setNumRetry(MAX_NUM_EOS_MESSAGES_FOR_SAME_REQUEST + 1); // +1 for testing purpose (i.e., insert an EOS) 217 } 218 219 virtual void seek(const uint32 aSeekPosition) 220 { 221 HttpBasedProtocol::seek(aSeekPosition); 222 223 // reset EOS related variables inside the parser 224 if (iParser) iParser->resetForBadConnectionDetection(); 225 } 226 }; 227 228 #endif // PVMF_PROTOCOLENGINE_PROGRESSIVE_DOWNLOAD_H_INCLUDED 229 230