/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DATA_SOURCE_H_

#define DATA_SOURCE_H_

#include <sys/types.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <drm/DrmManagerClient.h>

namespace android {

struct AMessage;
struct AString;
class  IDataSource;
struct IMediaHTTPService;
class String8;
struct HTTPBase;

class DataSource : public RefBase {
public:
    enum Flags {
        kWantsPrefetching      = 1,
        kStreamedFromLocalHost = 2,
        kIsCachingDataSource   = 4,
        kIsHTTPBasedSource     = 8,
        kIsLocalFileSource     = 16,
    };

    static sp<DataSource> CreateFromURI(
            const sp<IMediaHTTPService> &httpService,
            const char *uri,
            const KeyedVector<String8, String8> *headers = NULL,
            String8 *contentType = NULL,
            HTTPBase *httpSource = NULL);

    static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
    static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);
    static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);

    DataSource() {}

    virtual status_t initCheck() const = 0;

    // Returns the number of bytes read, or -1 on failure. It's not an error if
    // this returns zero; it just means the given offset is equal to, or
    // beyond, the end of the source.
    virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;

    // Convenience methods:
    bool getUInt16(off64_t offset, uint16_t *x);
    bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
    bool getUInt32(off64_t offset, uint32_t *x);
    bool getUInt64(off64_t offset, uint64_t *x);

    // Reads in "count" entries of type T into vector *x.
    // Returns true if "count" entries can be read.
    // If fewer than "count" entries can be read, return false. In this case,
    // the output vector *x will still have those entries that were read. Call
    // x->size() to obtain the number of entries read.
    // The optional parameter chunkSize specifies how many entries should be
    // read from the data source at one time into a temporary buffer. Increasing
    // chunkSize can improve the performance at the cost of extra memory usage.
    // The default value for chunkSize is set to read at least 4k bytes at a
    // time, depending on sizeof(T).
    template <typename T>
    bool getVector(off64_t offset, Vector<T>* x, size_t count,
                   size_t chunkSize = (4095 / sizeof(T)) + 1);

    // May return ERROR_UNSUPPORTED.
    virtual status_t getSize(off64_t *size);

    virtual uint32_t flags() {
        return 0;
    }

    virtual String8 toString() {
        return String8("<unspecified>");
    }

    virtual status_t reconnectAtOffset(off64_t /*offset*/) {
        return ERROR_UNSUPPORTED;
    }

    ////////////////////////////////////////////////////////////////////////////

    // for DRM
    virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
        return NULL;
    }
    virtual void getDrmInfo(sp<DecryptHandle> &/*handle*/, DrmManagerClient ** /*client*/) {};

    virtual String8 getUri() {
        return String8();
    }

    virtual String8 getMIMEType() const;

    virtual void close() {};

    // creates an IDataSource wrapper to the DataSource.
    virtual sp<IDataSource> asIDataSource();

    // returns a pointer to IDataSource if it is wrapped.
    virtual sp<IDataSource> getIDataSource() const;

protected:
    virtual ~DataSource() {}

private:
    DataSource(const DataSource &);
    DataSource &operator=(const DataSource &);
};

template <typename T>
bool DataSource::getVector(off64_t offset, Vector<T>* x, size_t count,
                           size_t chunkSize)
{
    x->clear();
    if (chunkSize == 0) {
        return false;
    }
    if (count == 0) {
        return true;
    }

    T tmp[chunkSize];
    ssize_t numBytesRead;
    size_t numBytesPerChunk = chunkSize * sizeof(T);
    size_t i;

    for (i = 0; i + chunkSize < count; i += chunkSize) {
        // This loops is executed when more than chunkSize records need to be
        // read.
        numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
        if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
            return false;
        }
        if (numBytesRead < numBytesPerChunk) {
            // This case is triggered when the stream ends before the whole
            // chunk is read.
            x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
            return false;
        }
        x->appendArray(tmp, chunkSize);
        offset += numBytesPerChunk;
    }

    // There are (count - i) more records to read.
    // Right now, (count - i) <= chunkSize.
    // We do the same thing as above, but with chunkSize replaced by count - i.
    numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
    if (numBytesRead == -1) {
        return false;
    }
    x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
    return x->size() == count;
}

}  // namespace android

#endif  // DATA_SOURCE_H_
