1 /* 2 * Copyright (C) 2014 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "MidiIoWrapper" 19 #include <utils/Log.h> 20 #include <utils/RefBase.h> 21 22 #include <sys/stat.h> 23 #include <fcntl.h> 24 25 #include <media/MidiIoWrapper.h> 26 #include <media/MediaExtractorPluginApi.h> 27 28 static int readAt(void *handle, void *buffer, int pos, int size) { 29 return ((android::MidiIoWrapper*)handle)->readAt(buffer, pos, size); 30 } 31 static int size(void *handle) { 32 return ((android::MidiIoWrapper*)handle)->size(); 33 } 34 35 namespace android { 36 37 MidiIoWrapper::MidiIoWrapper(const char *path) { 38 ALOGV("MidiIoWrapper(%s)", path); 39 mFd = open(path, O_RDONLY | O_LARGEFILE); 40 mBase = 0; 41 mLength = lseek(mFd, 0, SEEK_END); 42 mDataSource = nullptr; 43 } 44 45 MidiIoWrapper::MidiIoWrapper(int fd, off64_t offset, int64_t size) { 46 ALOGV("MidiIoWrapper(fd=%d)", fd); 47 mFd = fd < 0 ? -1 : dup(fd); 48 mBase = offset; 49 mLength = size; 50 mDataSource = nullptr; 51 } 52 53 class DataSourceUnwrapper : public DataSourceBase { 54 55 public: 56 explicit DataSourceUnwrapper(CDataSource *csource) { 57 mSource = csource; 58 } 59 60 virtual ~DataSourceUnwrapper() {} 61 62 virtual status_t initCheck() const { return OK; } 63 64 // Returns the number of bytes read, or -1 on failure. It's not an error if 65 // this returns zero; it just means the given offset is equal to, or 66 // beyond, the end of the source. 67 virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 68 return mSource->readAt(mSource->handle, offset, data, size); 69 } 70 71 // May return ERROR_UNSUPPORTED. 72 virtual status_t getSize(off64_t *size) { 73 return mSource->getSize(mSource->handle, size); 74 } 75 76 virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) { 77 return false; 78 } 79 80 virtual uint32_t flags() { 81 return 0; 82 } 83 84 virtual void close() {}; 85 private: 86 CDataSource *mSource; 87 }; 88 89 MidiIoWrapper::MidiIoWrapper(CDataSource *csource) { 90 ALOGV("MidiIoWrapper(CDataSource)"); 91 mFd = -1; 92 mBase = 0; 93 mDataSource = new DataSourceUnwrapper(csource); 94 off64_t l; 95 if (mDataSource->getSize(&l) == OK) { 96 mLength = l; 97 } else { 98 mLength = 0; 99 } 100 } 101 102 MidiIoWrapper::~MidiIoWrapper() { 103 ALOGV("~MidiIoWrapper"); 104 if (mFd >= 0) { 105 close(mFd); 106 } 107 delete mDataSource; 108 } 109 110 int MidiIoWrapper::readAt(void *buffer, int offset, int size) { 111 ALOGV("readAt(%p, %d, %d)", buffer, offset, size); 112 113 if (mDataSource != NULL) { 114 return mDataSource->readAt(offset, buffer, size); 115 } 116 if (mFd < 0) { 117 errno = EBADF; 118 return -1; // as per failed read. 119 } 120 lseek(mFd, mBase + offset, SEEK_SET); 121 if (offset + size > mLength) { 122 size = mLength - offset; 123 } 124 return read(mFd, buffer, size); 125 } 126 127 int MidiIoWrapper::size() { 128 ALOGV("size() = %d", int(mLength)); 129 return mLength; 130 } 131 132 EAS_FILE_LOCATOR MidiIoWrapper::getLocator() { 133 mEasFile.handle = this; 134 mEasFile.readAt = ::readAt; 135 mEasFile.size = ::size; 136 return &mEasFile; 137 } 138 139 } // namespace android 140