Merge "Allow data uris to be data sources"
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 70523c1..e471f73 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -16,6 +16,11 @@
 
 #include "include/AMRExtractor.h"
 #include "include/AVIExtractor.h"
+
+#if CHROMIUM_AVAILABLE
+#include "include/DataUriSource.h"
+#endif
+
 #include "include/MP3Extractor.h"
 #include "include/MPEG4Extractor.h"
 #include "include/WAVExtractor.h"
@@ -136,6 +141,10 @@
             return NULL;
         }
         source = new NuCachedSource2(httpSource);
+# if CHROMIUM_AVAILABLE
+    } else if (!strncasecmp("data:", uri, 5)) {
+        source = new DataUriSource(uri);
+#endif
     } else {
         // Assume it's a filename.
         source = new FileSource(uri);
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
index 6573e3c..63775f1 100644
--- a/media/libstagefright/chromium_http/Android.mk
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -3,8 +3,9 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=       \
-        ChromiumHTTPDataSource.cpp        \
-        support.cpp                     \
+        DataUriSource.cpp \
+        ChromiumHTTPDataSource.cpp \
+        support.cpp
 
 LOCAL_C_INCLUDES:= \
         $(JNI_H_INCLUDE) \
diff --git a/media/libstagefright/chromium_http/DataUriSource.cpp b/media/libstagefright/chromium_http/DataUriSource.cpp
new file mode 100644
index 0000000..ecf3fa1
--- /dev/null
+++ b/media/libstagefright/chromium_http/DataUriSource.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <include/DataUriSource.h>
+
+#include <net/base/data_url.h>
+#include <googleurl/src/gurl.h>
+
+
+namespace android {
+
+DataUriSource::DataUriSource(const char *uri) :
+    mDataUri(uri),
+    mInited(NO_INIT) {
+
+    // Copy1: const char *uri -> String8 mDataUri.
+    std::string mimeTypeStr, unusedCharsetStr, dataStr;
+    // Copy2: String8 mDataUri -> std::string
+    const bool ret = net::DataURL::Parse(
+            GURL(std::string(mDataUri.string())),
+            &mimeTypeStr, &unusedCharsetStr, &dataStr);
+    // Copy3: std::string dataStr -> AString mData
+    mData.setTo(dataStr.data(), dataStr.length());
+    mInited = ret ? OK : UNKNOWN_ERROR;
+
+    // The chromium data url implementation defaults to using "text/plain"
+    // if no mime type is specified. We prefer to leave this unspecified
+    // instead, since the mime type is sniffed in most cases.
+    if (mimeTypeStr != "text/plain") {
+        mMimeType = mimeTypeStr.c_str();
+    }
+}
+
+ssize_t DataUriSource::readAt(off64_t offset, void *out, size_t size) {
+    if (mInited != OK) {
+        return mInited;
+    }
+
+    const off64_t length = mData.size();
+    if (offset >= length) {
+        return UNKNOWN_ERROR;
+    }
+
+    const char *dataBuf = mData.c_str();
+    const size_t bytesToCopy =
+            offset + size >= length ? (length - offset) : size;
+
+    if (bytesToCopy > 0) {
+        memcpy(out, dataBuf + offset, bytesToCopy);
+    }
+
+    return bytesToCopy;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/include/DataUriSource.h b/media/libstagefright/include/DataUriSource.h
new file mode 100644
index 0000000..d223c06
--- /dev/null
+++ b/media/libstagefright/include/DataUriSource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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_URI_SOURCE_H_
+
+#define DATA_URI_SOURCE_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+class DataUriSource : public DataSource {
+public:
+    DataUriSource(const char *uri);
+
+    virtual status_t initCheck() const {
+        return mInited;
+    }
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+    virtual status_t getSize(off64_t *size) {
+        if (mInited != OK) {
+            return mInited;
+        }
+
+        *size = mData.size();
+        return OK;
+    }
+
+    virtual String8 getUri() {
+        return mDataUri;
+    }
+
+    virtual String8 getMIMEType() const {
+        return mMimeType;
+    }
+
+protected:
+    virtual ~DataUriSource() {
+        // Nothing to delete.
+    }
+
+private:
+    const String8 mDataUri;
+
+    String8 mMimeType;
+    // Use AString because individual bytes may not be valid UTF8 chars.
+    AString mData;
+    status_t mInited;
+
+    // Disallow copy and assign.
+    DataUriSource(const DataUriSource &);
+    DataUriSource &operator=(const DataUriSource &);
+};
+
+}  // namespace android
+
+#endif  // DATA_URI_SOURCE_H_