1 /* 2 * Copyright 2016, Dario Casalinuovo 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "HTTPMediaIO.h" 8 9 #include <Handler.h> 10 #include <UrlProtocolRoster.h> 11 12 #include <stdio.h> 13 14 15 class FileListener : public BUrlProtocolAsynchronousListener { 16 public: 17 FileListener(BAdapterIO* owner) 18 : 19 BUrlProtocolAsynchronousListener(true), 20 fRequest(NULL), 21 fAdapterIO(owner), 22 fTotalSize(0) 23 { 24 fInputAdapter = fAdapterIO->BuildInputAdapter(); 25 } 26 27 virtual ~FileListener() {}; 28 29 bool ConnectionSuccessful() const 30 { 31 return fRequest != NULL; 32 } 33 34 void ConnectionOpened(BUrlRequest* request) 35 { 36 if (fRequest != NULL) 37 fRequest->Stop(); 38 39 fRequest = request; 40 fTotalSize = request->Result().Length(); 41 } 42 43 void DataReceived(BUrlRequest* request, const char* data, 44 off_t position, ssize_t size) 45 { 46 if (request != fRequest) 47 delete request; 48 49 fInputAdapter->Write(data, size); 50 } 51 52 void RequestCompleted(BUrlRequest* request, bool success) 53 { 54 if (request != fRequest) 55 return; 56 57 fRequest = NULL; 58 delete request; 59 } 60 61 off_t TotalSize() const 62 { 63 return fTotalSize; 64 } 65 66 private: 67 BUrlRequest* fRequest; 68 BAdapterIO* fAdapterIO; 69 BInputAdapter* fInputAdapter; 70 off_t fTotalSize; 71 }; 72 73 74 HTTPMediaIO::HTTPMediaIO(BUrl url) 75 : 76 BAdapterIO(B_MEDIA_STREAMING | B_MEDIA_SEEK_BACKWARD, B_INFINITE_TIMEOUT), 77 fContext(NULL), 78 fReq(NULL), 79 fListener(NULL), 80 fUrl(url) 81 { 82 } 83 84 85 HTTPMediaIO::~HTTPMediaIO() 86 { 87 } 88 89 90 ssize_t 91 HTTPMediaIO::WriteAt(off_t position, const void* buffer, size_t size) 92 { 93 return B_NOT_SUPPORTED; 94 } 95 96 97 status_t 98 HTTPMediaIO::SetSize(off_t size) 99 { 100 return B_NOT_SUPPORTED; 101 } 102 103 104 status_t 105 HTTPMediaIO::GetSize(off_t* size) const 106 { 107 *size = fListener->TotalSize(); 108 return B_OK; 109 } 110 111 112 status_t 113 HTTPMediaIO::Open() 114 { 115 fContext = new BUrlContext(); 116 fContext->AcquireReference(); 117 118 fListener = new FileListener(this); 119 120 fReq = BUrlProtocolRoster::MakeRequest(fUrl, 121 fListener, fContext); 122 123 if (fReq == NULL) 124 return B_ERROR; 125 126 if (fReq->Run() < 0) 127 return B_ERROR; 128 129 return BAdapterIO::Open(); 130 } 131 132 133 void 134 HTTPMediaIO::Close() 135 { 136 delete fReq; 137 delete fListener; 138 139 fContext->ReleaseReference(); 140 delete fContext; 141 142 BAdapterIO::Close(); 143 } 144 145 146 status_t 147 HTTPMediaIO::SeekRequested(off_t position) 148 { 149 return BAdapterIO::SeekRequested(position); 150 } 151