1 /*
2  * Copyright (C) 2009 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 #ifndef DATA_SOURCE_BASE_H_
18 
19 #define DATA_SOURCE_BASE_H_
20 
21 #include <media/stagefright/foundation/ByteUtils.h>
22 #include <media/stagefright/MediaErrors.h>
23 #include <sys/types.h>
24 #include <utils/Errors.h>
25 
26 namespace android {
27 
28 class String8;
29 
30 class DataSourceBase {
31 public:
32     enum Flags {
33         kWantsPrefetching      = 1,
34         kStreamedFromLocalHost = 2,
35         kIsCachingDataSource   = 4,
36         kIsHTTPBasedSource     = 8,
37         kIsLocalFileSource     = 16,
38     };
39 
DataSourceBase()40     DataSourceBase() {}
41 
42     virtual status_t initCheck() const = 0;
43 
44     // Returns the number of bytes read, or -1 on failure. It's not an error if
45     // this returns zero; it just means the given offset is equal to, or
46     // beyond, the end of the source.
47     virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
48 
49     // Convenience methods:
getUInt16(off64_t offset,uint16_t * x)50     bool getUInt16(off64_t offset, uint16_t *x) {
51         *x = 0;
52 
53         uint8_t byte[2];
54         if (readAt(offset, byte, 2) != 2) {
55             return false;
56         }
57 
58         *x = (byte[0] << 8) | byte[1];
59 
60         return true;
61     }
62     // 3 byte int, returned as a 32-bit int
getUInt24(off64_t offset,uint32_t * x)63     bool getUInt24(off64_t offset, uint32_t *x) {
64         *x = 0;
65 
66         uint8_t byte[3];
67         if (readAt(offset, byte, 3) != 3) {
68             return false;
69         }
70 
71         *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
72 
73         return true;
74     }
getUInt32(off64_t offset,uint32_t * x)75     bool getUInt32(off64_t offset, uint32_t *x) {
76         *x = 0;
77 
78         uint32_t tmp;
79         if (readAt(offset, &tmp, 4) != 4) {
80             return false;
81         }
82 
83         *x = ntohl(tmp);
84 
85         return true;
86     }
getUInt64(off64_t offset,uint64_t * x)87     bool getUInt64(off64_t offset, uint64_t *x) {
88         *x = 0;
89 
90         uint64_t tmp;
91         if (readAt(offset, &tmp, 8) != 8) {
92             return false;
93         }
94 
95         *x = ntoh64(tmp);
96 
97         return true;
98     }
99 
100     // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
getUInt16Var(off64_t offset,uint16_t * x,size_t size)101     bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
102         if (size == 2) {
103             return getUInt16(offset, x);
104         }
105         if (size == 1) {
106             uint8_t tmp;
107             if (readAt(offset, &tmp, 1) == 1) {
108                 *x = tmp;
109                 return true;
110             }
111         }
112         return false;
113     }
getUInt32Var(off64_t offset,uint32_t * x,size_t size)114     bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
115         if (size == 4) {
116             return getUInt32(offset, x);
117         }
118         if (size == 2) {
119             uint16_t tmp;
120             if (getUInt16(offset, &tmp)) {
121                 *x = tmp;
122                 return true;
123             }
124         }
125         return false;
126     }
getUInt64Var(off64_t offset,uint64_t * x,size_t size)127     bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
128         if (size == 8) {
129             return getUInt64(offset, x);
130         }
131         if (size == 4) {
132             uint32_t tmp;
133             if (getUInt32(offset, &tmp)) {
134                 *x = tmp;
135                 return true;
136             }
137         }
138         return false;
139     }
140 
141     // May return ERROR_UNSUPPORTED.
getSize(off64_t * size)142     virtual status_t getSize(off64_t *size) {
143         *size = 0;
144         return ERROR_UNSUPPORTED;
145     }
146 
getUri(char *,size_t)147     virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) {
148         return false;
149     }
150 
flags()151     virtual uint32_t flags() {
152         return 0;
153     }
154 
close()155     virtual void close() {};
156 
getAvailableSize(off64_t,off64_t *)157     virtual status_t getAvailableSize(off64_t /*offset*/, off64_t * /*size*/) {
158         return -1;
159     }
160 
161 protected:
~DataSourceBase()162     virtual ~DataSourceBase() {}
163 
164 private:
165     DataSourceBase(const DataSourceBase &);
166     DataSourceBase &operator=(const DataSourceBase &);
167 };
168 
169 }  // namespace android
170 
171 #endif  // DATA_SOURCE_BASE_H_
172