xref: /aosp_15_r20/frameworks/av/media/libdatasource/DataURISource.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker #include <datasource/DataURISource.h>
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABuffer.h>
19*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/base64.h>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker namespace android {
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker // static
Create(const char * uri)25*ec779b8eSAndroid Build Coastguard Worker sp<DataURISource> DataURISource::Create(const char *uri) {
26*ec779b8eSAndroid Build Coastguard Worker     if (strncasecmp("data:", uri, 5)) {
27*ec779b8eSAndroid Build Coastguard Worker         return NULL;
28*ec779b8eSAndroid Build Coastguard Worker     }
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker     const char *commaPos = strrchr(uri, ',');
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker     if (commaPos == NULL) {
33*ec779b8eSAndroid Build Coastguard Worker         return NULL;
34*ec779b8eSAndroid Build Coastguard Worker     }
35*ec779b8eSAndroid Build Coastguard Worker 
36*ec779b8eSAndroid Build Coastguard Worker     sp<ABuffer> buffer;
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker     AString tmp(&uri[5], commaPos - &uri[5]);
39*ec779b8eSAndroid Build Coastguard Worker 
40*ec779b8eSAndroid Build Coastguard Worker     if (tmp.endsWith(";base64")) {
41*ec779b8eSAndroid Build Coastguard Worker 
42*ec779b8eSAndroid Build Coastguard Worker         // strip all CR and LF characters.
43*ec779b8eSAndroid Build Coastguard Worker         const char *src = commaPos+1;
44*ec779b8eSAndroid Build Coastguard Worker         int len = strlen(src) + 1;
45*ec779b8eSAndroid Build Coastguard Worker         char *cleansed = (char *) malloc(len);
46*ec779b8eSAndroid Build Coastguard Worker         if (cleansed == NULL) return NULL;
47*ec779b8eSAndroid Build Coastguard Worker         char *keeping = cleansed;
48*ec779b8eSAndroid Build Coastguard Worker         int left = len;
49*ec779b8eSAndroid Build Coastguard Worker         for (int i = 0; i < len ; i++)
50*ec779b8eSAndroid Build Coastguard Worker         {
51*ec779b8eSAndroid Build Coastguard Worker             const char c = *src++;
52*ec779b8eSAndroid Build Coastguard Worker             if (c == '\r' || c == '\n') {
53*ec779b8eSAndroid Build Coastguard Worker                 continue;
54*ec779b8eSAndroid Build Coastguard Worker             }
55*ec779b8eSAndroid Build Coastguard Worker             *keeping++ = c;
56*ec779b8eSAndroid Build Coastguard Worker             left--;
57*ec779b8eSAndroid Build Coastguard Worker         }
58*ec779b8eSAndroid Build Coastguard Worker         memset(keeping, 0, left);
59*ec779b8eSAndroid Build Coastguard Worker 
60*ec779b8eSAndroid Build Coastguard Worker         AString encoded(cleansed);
61*ec779b8eSAndroid Build Coastguard Worker         free(cleansed);
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker         buffer = decodeBase64(encoded);
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker         if (buffer == NULL) {
66*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Malformed base64 encoded content found.");
67*ec779b8eSAndroid Build Coastguard Worker             return NULL;
68*ec779b8eSAndroid Build Coastguard Worker         }
69*ec779b8eSAndroid Build Coastguard Worker     } else {
70*ec779b8eSAndroid Build Coastguard Worker #if 0
71*ec779b8eSAndroid Build Coastguard Worker         size_t dataLen = strlen(uri) - tmp.size() - 6;
72*ec779b8eSAndroid Build Coastguard Worker         buffer = new ABuffer(dataLen);
73*ec779b8eSAndroid Build Coastguard Worker         memcpy(buffer->data(), commaPos + 1, dataLen);
74*ec779b8eSAndroid Build Coastguard Worker 
75*ec779b8eSAndroid Build Coastguard Worker         // unescape
76*ec779b8eSAndroid Build Coastguard Worker #else
77*ec779b8eSAndroid Build Coastguard Worker         // MediaPlayer doesn't care for this right now as we don't
78*ec779b8eSAndroid Build Coastguard Worker         // play any text-based media.
79*ec779b8eSAndroid Build Coastguard Worker         return NULL;
80*ec779b8eSAndroid Build Coastguard Worker #endif
81*ec779b8eSAndroid Build Coastguard Worker     }
82*ec779b8eSAndroid Build Coastguard Worker 
83*ec779b8eSAndroid Build Coastguard Worker     // We don't really care about charset or mime type.
84*ec779b8eSAndroid Build Coastguard Worker 
85*ec779b8eSAndroid Build Coastguard Worker     return new DataURISource(buffer);
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker 
DataURISource(const sp<ABuffer> & buffer)88*ec779b8eSAndroid Build Coastguard Worker DataURISource::DataURISource(const sp<ABuffer> &buffer)
89*ec779b8eSAndroid Build Coastguard Worker     : mBuffer(buffer) {
90*ec779b8eSAndroid Build Coastguard Worker }
91*ec779b8eSAndroid Build Coastguard Worker 
~DataURISource()92*ec779b8eSAndroid Build Coastguard Worker DataURISource::~DataURISource() {
93*ec779b8eSAndroid Build Coastguard Worker }
94*ec779b8eSAndroid Build Coastguard Worker 
initCheck() const95*ec779b8eSAndroid Build Coastguard Worker status_t DataURISource::initCheck() const {
96*ec779b8eSAndroid Build Coastguard Worker     return OK;
97*ec779b8eSAndroid Build Coastguard Worker }
98*ec779b8eSAndroid Build Coastguard Worker 
readAt(off64_t offset,void * data,size_t size)99*ec779b8eSAndroid Build Coastguard Worker ssize_t DataURISource::readAt(off64_t offset, void *data, size_t size) {
100*ec779b8eSAndroid Build Coastguard Worker     if ((offset < 0) || (offset >= (off64_t)mBuffer->size())) {
101*ec779b8eSAndroid Build Coastguard Worker         return 0;
102*ec779b8eSAndroid Build Coastguard Worker     }
103*ec779b8eSAndroid Build Coastguard Worker 
104*ec779b8eSAndroid Build Coastguard Worker     size_t copy = mBuffer->size() - offset;
105*ec779b8eSAndroid Build Coastguard Worker     if (copy > size) {
106*ec779b8eSAndroid Build Coastguard Worker         copy = size;
107*ec779b8eSAndroid Build Coastguard Worker     }
108*ec779b8eSAndroid Build Coastguard Worker 
109*ec779b8eSAndroid Build Coastguard Worker     memcpy(data, mBuffer->data() + offset, copy);
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker     return copy;
112*ec779b8eSAndroid Build Coastguard Worker }
113*ec779b8eSAndroid Build Coastguard Worker 
getSize(off64_t * size)114*ec779b8eSAndroid Build Coastguard Worker status_t DataURISource::getSize(off64_t *size) {
115*ec779b8eSAndroid Build Coastguard Worker     *size = mBuffer->size();
116*ec779b8eSAndroid Build Coastguard Worker 
117*ec779b8eSAndroid Build Coastguard Worker     return OK;
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker 
120*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
121*ec779b8eSAndroid Build Coastguard Worker 
122