You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2018/04/28 06:53:49 UTC

[21/48] incubator-weex git commit: * [android] Merge WeexCore-master to master.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCHandler.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCHandler.h b/weex_core/Source/IPC/IPCHandler.h
new file mode 100644
index 0000000..a3fbebe
--- /dev/null
+++ b/weex_core/Source/IPC/IPCHandler.h
@@ -0,0 +1,18 @@
+#ifndef IPCHANDLER_H
+#define IPCHANDLER_H
+#include <functional>
+#include <memory>
+#include <stdint.h>
+
+class IPCResult;
+class IPCArguments;
+
+class IPCHandler {
+public:
+    virtual ~IPCHandler() = default;
+    virtual std::unique_ptr<IPCResult> handle(uint32_t msg, IPCArguments*) = 0;
+    virtual void registerHandler(int msg, const std::function<std::unique_ptr<IPCResult>(IPCArguments*)>& handler) = 0;
+};
+
+std::unique_ptr<IPCHandler> createIPCHandler();
+#endif /* IPCHANDLER_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCListener.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCListener.cpp b/weex_core/Source/IPC/IPCListener.cpp
new file mode 100644
index 0000000..6804591
--- /dev/null
+++ b/weex_core/Source/IPC/IPCListener.cpp
@@ -0,0 +1,60 @@
+#include "IPCListener.h"
+#include "Buffering/IPCBuffer.h"
+#include "IPCArguments.h"
+#include "IPCCommunicator.h"
+#include "IPCException.h"
+#include "IPCHandler.h"
+#include "IPCResult.h"
+#include "IPCType.h"
+#include <unistd.h>
+
+namespace {
+class IPCListenerImpl : public IPCCommunicator,
+                        public IPCListener {
+public:
+    IPCListenerImpl(IPCFutexPageQueue* futexPageQueue, IPCHandler* handler);
+    ~IPCListenerImpl() override;
+    void listen() override;
+
+private:
+    int m_fd;
+    IPCHandler* m_handler;
+};
+
+IPCListenerImpl::IPCListenerImpl(IPCFutexPageQueue* futexPageQueue, IPCHandler* handler)
+    : IPCCommunicator(futexPageQueue)
+    , m_handler(handler)
+{
+}
+
+IPCListenerImpl::~IPCListenerImpl()
+{
+}
+
+void IPCListenerImpl::listen()
+{
+    while (true) {
+        uint32_t msg = doReadPackage();
+        bool isAsync = !!(msg & MSG_FLAG_ASYNC);
+        msg &= MSG_MASK;
+        if (msg == MSG_END)
+            throw IPCException("unexpected MSG_END");
+        else if (msg == MSG_TERMINATE) {
+            releaseBlob();
+            throw IPCException("peer terminates");
+        }
+        std::unique_ptr<IPCArguments> arguments = assembleArguments();
+        releaseBlob();
+        std::unique_ptr<IPCResult> sendBack = m_handler->handle(msg, arguments.get());
+        if (!isAsync) {
+            std::unique_ptr<IPCBuffer> resultBuffer = generateResultBuffer(sendBack.get());
+            doSendBufferOnly(resultBuffer.get());
+        }
+    }
+}
+}
+
+std::unique_ptr<IPCListener> createIPCListener(IPCFutexPageQueue* futexPageQueue, IPCHandler* handler)
+{
+    return std::unique_ptr<IPCListener>(new IPCListenerImpl(futexPageQueue, handler));
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCListener.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCListener.h b/weex_core/Source/IPC/IPCListener.h
new file mode 100644
index 0000000..4ae3f77
--- /dev/null
+++ b/weex_core/Source/IPC/IPCListener.h
@@ -0,0 +1,14 @@
+#ifndef IPCLISTENER_H
+#define IPCLISTENER_H
+#include <memory>
+class IPCHandler;
+class IPCFutexPageQueue;
+
+class IPCListener {
+public:
+    virtual ~IPCListener() = default;
+    virtual void listen() = 0;
+};
+
+std::unique_ptr<IPCListener> createIPCListener(IPCFutexPageQueue*, IPCHandler* handler);
+#endif /* IPCLISTENER_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCLog.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCLog.h b/weex_core/Source/IPC/IPCLog.h
new file mode 100644
index 0000000..2707257
--- /dev/null
+++ b/weex_core/Source/IPC/IPCLog.h
@@ -0,0 +1,12 @@
+#ifndef IPCLOG_H
+#define IPCLOG_H
+#include <android/log.h>
+#define TAG "linzj_IPC"
+#define IPC_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+
+#if defined(ENABLE_IPC_DEBUG_LOG) && ENABLE_IPC_DEBUG_LOG
+#define IPC_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
+#else
+#define IPC_LOGD(...)
+#endif
+#endif /* IPCLOG_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCMessageJS.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCMessageJS.h b/weex_core/Source/IPC/IPCMessageJS.h
new file mode 100644
index 0000000..a193aa7
--- /dev/null
+++ b/weex_core/Source/IPC/IPCMessageJS.h
@@ -0,0 +1,41 @@
+#ifndef IPCMESSAGEJS_H
+#define IPCMESSAGEJS_H
+
+enum class IPCJSMsg {
+    INITFRAMEWORK,
+    EXECJSSERVICE,
+    TAKEHEAPSNAPSHOT,
+    EXECJS,
+	CREATEINSTANCE,
+    DESTORYINSTANCE,
+    EXECJSONINSTANCE,
+    EXECJSWITHRESULT,
+    UPDATEGLOBALCONFIG,
+    EXECTIMERCALLBACK,
+};
+
+enum class IPCProxyMsg {
+    SETJSFVERSION,
+    REPORTEXCEPTION,
+    CALLNATIVE,
+    CALLNATIVEMODULE,
+    CALLNATIVECOMPONENT,
+    CALLADDELEMENT,
+    SETTIMEOUT,
+    NATIVELOG,
+    CALLCREATEBODY,
+    CALLUPDATEFINISH,
+    CALLCREATEFINISH,
+    CALLREFRESHFINISH,
+    CALLUPDATEATTRS,
+    CALLUPDATESTYLE,
+    CALLREMOVEELEMENT,
+    CALLMOVEELEMENT,
+    CALLADDEVENT,
+    CALLREMOVEEVENT,
+    CALLGCANVASLINK,
+	CALLT3DLINK,
+    SETINTERVAL,
+    CLEARINTERVAL,
+};
+#endif /* IPCMESSAGEJS_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCResult.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCResult.cpp b/weex_core/Source/IPC/IPCResult.cpp
new file mode 100644
index 0000000..b2d6106
--- /dev/null
+++ b/weex_core/Source/IPC/IPCResult.cpp
@@ -0,0 +1,347 @@
+#include "IPCResult.h"
+
+#include <cstdlib>
+
+namespace {
+class VoidResult : public IPCResult {
+public:
+    const void* getData() override;
+    IPCType getType() override;
+    const uint16_t* getStringContent() override;
+    size_t getStringLength() override;
+    const char* getByteArrayContent() override;
+    size_t getByteArrayLength() override;
+};
+
+template <typename T>
+struct TypeTrait {
+};
+
+template <>
+struct TypeTrait<int32_t> {
+    static const IPCType s_type = IPCType::INT32;
+};
+
+template <>
+struct TypeTrait<double> {
+    static const IPCType s_type = IPCType::DOUBLE;
+};
+
+template <typename T>
+class ValueResult : public IPCResult {
+public:
+    explicit ValueResult(T val);
+    const void* getData() override;
+    IPCType getType() override;
+    const uint16_t* getStringContent() override;
+    size_t getStringLength() override;
+    const char* getByteArrayContent() override;
+    size_t getByteArrayLength() override;
+
+private:
+    typedef T value_type;
+    typedef TypeTrait<value_type> trait_type;
+
+    value_type m_value;
+    static const IPCType s_type = trait_type::s_type;
+};
+
+class StringResult : public IPCResult {
+public:
+    StringResult(JNIEnv* env, jstring val);
+    ~StringResult();
+
+    const void* getData() override;
+    IPCType getType() override;
+    const uint16_t* getStringContent() override;
+    size_t getStringLength() override;
+    const char* getByteArrayContent() override;
+    size_t getByteArrayLength() override;
+    void setJSON();
+
+private:
+    JNIEnv* m_env;
+    jstring m_value;
+    const jchar* m_cvalue{ nullptr };
+    size_t m_length{ 0U };
+    bool m_isJSON{ false };
+};
+
+
+class ByteArrayResult: public IPCResult{
+public:
+    ByteArrayResult(const char* data, size_t length);
+    ~ByteArrayResult();
+
+    const void* getData() override;
+    IPCType getType() override;
+    const uint16_t* getStringContent() override;
+    size_t getStringLength() override;
+    const char* getByteArrayContent() override;
+    size_t getByteArrayLength() override;
+private:
+    char* m_data;
+    size_t m_length;
+};
+
+const void*
+VoidResult::getData()
+{
+    return nullptr;
+}
+
+IPCType VoidResult::getType()
+{
+    return IPCType::VOID;
+}
+
+const uint16_t* VoidResult::getStringContent()
+{
+    return nullptr;
+}
+
+size_t VoidResult::getStringLength()
+{
+    return 0U;
+}
+
+const char* VoidResult::getByteArrayContent()
+{
+    return nullptr;
+}
+
+size_t VoidResult::getByteArrayLength()
+{
+    return 0U;
+}
+
+template <typename T>
+ValueResult<T>::ValueResult(T val)
+    : m_value(val)
+{
+}
+
+template <typename T>
+const void* ValueResult<T>::getData()
+{
+    return &m_value;
+}
+
+template <typename T>
+IPCType ValueResult<T>::getType()
+{
+    return s_type;
+}
+
+template <typename T>
+const uint16_t* ValueResult<T>::getStringContent()
+{
+    return nullptr;
+}
+
+template <typename T>
+size_t ValueResult<T>::getStringLength()
+{
+    return 0U;
+}
+
+template <typename T>
+const char* ValueResult<T>::getByteArrayContent()
+{
+    return nullptr;
+}
+
+template <typename T>
+size_t ValueResult<T>::getByteArrayLength()
+{
+    return 0U;
+}
+
+StringResult::StringResult(JNIEnv* env, jstring val)
+    : m_env(env)
+    , m_value(static_cast<jstring>(env->NewLocalRef(val)))
+{
+    m_cvalue = env->GetStringChars(m_value, nullptr);
+    m_length = env->GetStringLength(m_value);
+}
+
+StringResult::~StringResult()
+{
+    if (m_cvalue)
+        m_env->ReleaseStringChars(m_value, m_cvalue);
+    m_env->DeleteLocalRef(m_value);
+}
+
+const void* StringResult::getData()
+{
+    return nullptr;
+}
+
+IPCType StringResult::getType()
+{
+    return m_isJSON ? IPCType::JSONSTRING : IPCType::STRING;
+}
+
+const uint16_t* StringResult::getStringContent()
+{
+    return m_cvalue;
+}
+
+size_t StringResult::getStringLength()
+{
+    return m_length;
+}
+
+const char* StringResult::getByteArrayContent()
+{
+    return nullptr;
+}
+
+size_t StringResult::getByteArrayLength()
+{
+    return 0U;
+}
+
+void StringResult::setJSON()
+{
+    m_isJSON = true;
+}
+
+ByteArrayResult::ByteArrayResult(const char* data, size_t length):m_length(length)
+{
+    if(length > 0){
+        m_data = (char*)malloc(length*sizeof(char));
+        memcpy(m_data,  data, length);
+    }else{
+        m_data = nullptr;
+    }
+}
+IPCType  ByteArrayResult::getType()
+{
+    return IPCType::BYTEARRAY;
+}
+
+const void* ByteArrayResult::getData()
+{
+    return nullptr;
+}
+
+const uint16_t* ByteArrayResult::getStringContent(){
+    return nullptr;
+}
+
+size_t ByteArrayResult::getStringLength(){
+    return 0l;
+}
+
+const char* ByteArrayResult::getByteArrayContent(){
+    return  m_data;
+}
+
+size_t ByteArrayResult::getByteArrayLength(){
+    return m_length;
+}
+ByteArrayResult::~ByteArrayResult()
+{
+    if (m_data){
+        free(m_data);
+        m_data= NULL;
+    }
+    m_length = 0;
+}
+
+}
+
+
+
+
+std::unique_ptr<IPCResult> createVoidResult()
+{
+    return std::unique_ptr<IPCResult>(new VoidResult);
+}
+
+std::unique_ptr<IPCResult> createInt32Result(int32_t val)
+{
+    return std::unique_ptr<IPCResult>(new ValueResult<int32_t>(val));
+}
+
+std::unique_ptr<IPCResult> createDoubleResult(double val)
+{
+    return std::unique_ptr<IPCResult>(new ValueResult<double>(val));
+}
+
+std::unique_ptr<IPCResult> createStringResult(JNIEnv* env, jstring str)
+{
+    return std::unique_ptr<IPCResult>(new StringResult(env, str));
+}
+
+std::unique_ptr<IPCResult> createJSONStringResult(JNIEnv* env, jstring str)
+{
+    std::unique_ptr<StringResult> result(new StringResult(env, str));
+    result->setJSON();
+    return std::unique_ptr<IPCResult>(result.release());
+}
+
+std::unique_ptr<IPCResult> createByteArrayResult(const char* data, size_t length){
+    return std::unique_ptr<IPCResult>(new ByteArrayResult(data, length));
+}
+
+class CharArrayResult : public IPCResult {
+public:
+    CharArrayResult(char* chars);
+    // ByteArrayResult(const char* data);
+    ~CharArrayResult();
+
+    const void* getData() override;
+    IPCType getType() override;
+    const uint16_t* getStringContent() override;
+    size_t getStringLength() override;
+    const char* getByteArrayContent() override;
+    size_t getByteArrayLength() override;
+
+private:
+    char*  m_char;
+    size_t m_length{ 0U };
+};
+
+CharArrayResult::CharArrayResult(char* chars)
+    : m_char(chars) {
+    m_length = strlen(m_char);
+}
+
+CharArrayResult::~CharArrayResult() {
+    delete[] m_char;
+}
+
+const void* CharArrayResult::getData()
+{
+    return m_char;
+}
+
+IPCType CharArrayResult::getType()
+{
+    return IPCType::CHARARRAY;
+}
+
+const uint16_t* CharArrayResult::getStringContent()
+{
+    return nullptr;
+}
+
+size_t CharArrayResult::getStringLength()
+{
+    return m_length;
+}
+
+const char* CharArrayResult::getByteArrayContent() {
+    return nullptr;
+}
+
+size_t CharArrayResult::getByteArrayLength() {
+
+    return 0U;
+}
+
+std::unique_ptr<IPCResult> createCharArrayResult(char* bytes) {
+    return std::unique_ptr<IPCResult>(new CharArrayResult(bytes));
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCResult.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCResult.h b/weex_core/Source/IPC/IPCResult.h
new file mode 100644
index 0000000..d261450
--- /dev/null
+++ b/weex_core/Source/IPC/IPCResult.h
@@ -0,0 +1,34 @@
+#ifndef IPCRESULT_H
+#define IPCRESULT_H
+#include "IPCType.h"
+#include <jni.h>
+#include <memory>
+#include "IPCByteArray.h"
+
+struct IPCString;
+class IPCResult {
+public:
+    virtual ~IPCResult() = default;
+    template <typename T>
+    T get()
+    {
+        return *static_cast<const T*>(getData());
+    }
+
+    virtual const void* getData() = 0;
+    virtual IPCType getType() = 0;
+    virtual const uint16_t* getStringContent() = 0;
+    virtual size_t getStringLength() = 0;
+    virtual const char* getByteArrayContent() = 0;
+    virtual size_t getByteArrayLength() = 0;
+};
+
+std::unique_ptr<IPCResult> createVoidResult();
+std::unique_ptr<IPCResult> createInt32Result(int32_t val);
+std::unique_ptr<IPCResult> createDoubleResult(double val);
+std::unique_ptr<IPCResult> createStringResult(JNIEnv* env, jstring str);
+std::unique_ptr<IPCResult> createJSONStringResult(JNIEnv* env, jstring str);
+std::unique_ptr<IPCResult> createCharArrayResult(char* bytes);
+std::unique_ptr<IPCResult> createByteArrayResult(const char* data, size_t length);
+
+#endif /* IPCRESULT_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCSender.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCSender.cpp b/weex_core/Source/IPC/IPCSender.cpp
new file mode 100644
index 0000000..24b47e2
--- /dev/null
+++ b/weex_core/Source/IPC/IPCSender.cpp
@@ -0,0 +1,76 @@
+#include "IPCSender.h"
+#include "Buffering/IPCBuffer.h"
+#include "IPCArguments.h"
+#include "IPCByteArray.h"
+#include "IPCCheck.h"
+#include "IPCCommunicator.h"
+#include "IPCException.h"
+#include "IPCHandler.h"
+#include "IPCResult.h"
+#include "IPCString.h"
+#include "Serializing/IPCSerializer.h"
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <vector>
+
+namespace {
+class IPCSenderImpl : public IPCCommunicator, public IPCSender {
+public:
+    IPCSenderImpl(IPCFutexPageQueue*, IPCHandler* handler);
+    ~IPCSenderImpl();
+    std::unique_ptr<IPCResult> send(IPCBuffer*) override;
+
+private:
+    bool checkBufferAsync(IPCBuffer* buffer);
+    IPCHandler* m_handler;
+};
+
+IPCSenderImpl::IPCSenderImpl(IPCFutexPageQueue* futexPageQueue, IPCHandler* handler)
+    : IPCCommunicator(futexPageQueue)
+    , m_handler(handler)
+{
+}
+
+IPCSenderImpl::~IPCSenderImpl()
+{
+}
+
+std::unique_ptr<IPCResult> IPCSenderImpl::send(IPCBuffer* buffer)
+{
+    doSendBufferOnly(buffer);
+    if (checkBufferAsync(buffer))
+        return createVoidResult();
+    while (true) {
+        uint32_t msg = doReadPackage();
+        bool isAsync = !!(msg & MSG_FLAG_ASYNC);
+        msg &= MSG_MASK;
+        if (msg == MSG_END) {
+            std::unique_ptr<IPCResult> result = assembleResult();
+            releaseBlob();
+            return result;
+        } else if (msg == MSG_TERMINATE) {
+            releaseBlob();
+            throw IPCException("peer terminates");
+        }
+        std::unique_ptr<IPCArguments> arguments = assembleArguments();
+        releaseBlob();
+        std::unique_ptr<IPCResult> sendBack = m_handler->handle(msg, arguments.get());
+        if (!isAsync) {
+            std::unique_ptr<IPCBuffer> resultBuffer = generateResultBuffer(sendBack.get());
+            doSendBufferOnly(resultBuffer.get());
+        }
+    }
+}
+
+bool IPCSenderImpl::checkBufferAsync(IPCBuffer* buffer)
+{
+    uint32_t msg = *static_cast<const uint32_t*>(buffer->get());
+    return !!(msg & MSG_FLAG_ASYNC);
+}
+}
+
+std::unique_ptr<IPCSender> createIPCSender(IPCFutexPageQueue* futexPageQueue, IPCHandler* handler)
+{
+    return std::unique_ptr<IPCSender>(new IPCSenderImpl(futexPageQueue, handler));
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCSender.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCSender.h b/weex_core/Source/IPC/IPCSender.h
new file mode 100644
index 0000000..8df1ad4
--- /dev/null
+++ b/weex_core/Source/IPC/IPCSender.h
@@ -0,0 +1,15 @@
+#ifndef IPCSENDER_H
+#define IPCSENDER_H
+#include <memory>
+class IPCBuffer;
+class IPCResult;
+class IPCHandler;
+class IPCFutexPageQueue;
+
+class IPCSender {
+public:
+    virtual ~IPCSender() = default;
+    virtual std::unique_ptr<IPCResult> send(IPCBuffer* buffer) = 0;
+};
+std::unique_ptr<IPCSender> createIPCSender(IPCFutexPageQueue*, IPCHandler* handler);
+#endif /* IPCSENDER_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCString.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCString.h b/weex_core/Source/IPC/IPCString.h
new file mode 100644
index 0000000..eed08c2
--- /dev/null
+++ b/weex_core/Source/IPC/IPCString.h
@@ -0,0 +1,7 @@
+#ifndef IPCSTRING_H
+#define IPCSTRING_H
+struct IPCString {
+    uint32_t length;
+    uint16_t content[1];
+};
+#endif /* IPCSTRING_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/IPCType.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/IPCType.h b/weex_core/Source/IPC/IPCType.h
new file mode 100644
index 0000000..9599d58
--- /dev/null
+++ b/weex_core/Source/IPC/IPCType.h
@@ -0,0 +1,29 @@
+#ifndef IPCTYPE_H
+#define IPCTYPE_H
+#include <stdint.h>
+struct IPCPackage {
+    uint32_t packageSize;
+    uint32_t msg;
+    uint32_t type[1];
+};
+
+enum class IPCType {
+    INT32,
+    INT64,
+    FLOAT,
+    DOUBLE,
+    JSONSTRING,
+    STRING,
+    BYTEARRAY, /* terminated with zero. */
+    CHARARRAY,
+    VOID,
+    JSUNDEFINED,
+    END,
+};
+
+static const uint32_t MSG_MASK = (1U << 31) - 1;
+static const uint32_t MSG_END = static_cast<uint32_t>(-1) & MSG_MASK;
+static const uint32_t MSG_TERMINATE = static_cast<uint32_t>(-2) & MSG_MASK;
+static const uint32_t MSG_NOT_SET = static_cast<uint32_t>(-3) & MSG_MASK;
+static const uint32_t MSG_FLAG_ASYNC = 1U << 31;
+#endif /* IPCTYPE_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/Serializing/IPCSerializer.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/Serializing/IPCSerializer.cpp b/weex_core/Source/IPC/Serializing/IPCSerializer.cpp
new file mode 100644
index 0000000..5a97b32
--- /dev/null
+++ b/weex_core/Source/IPC/Serializing/IPCSerializer.cpp
@@ -0,0 +1,206 @@
+#include "IPCSerializer.h"
+#include "../Buffering/IPCBuffer.h"
+#include "../IPCByteArray.h"
+#include "../IPCCheck.h"
+#include "../IPCString.h"
+#include "../IPCType.h"
+#include <sstream>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+namespace {
+class IPCSerializerImpl : public IPCSerializer {
+public:
+    void setMsg(uint32_t msg) override;
+    void add(int32_t) override;
+    void add(int64_t) override;
+    void add(float) override;
+    void add(double) override;
+    void add(const uint16_t* data, size_t len) override;
+    void addJSON(const uint16_t* data, size_t len) override;
+    void add(const char* data, size_t len) override;
+    void add(const IPCByteArray* bytes) override;
+    void addJSUndefined() override;
+    void addVoid() override;
+    std::unique_ptr<IPCBuffer> finish() override;
+
+private:
+    uint32_t m_msg{ MSG_END };
+    std::vector<uint32_t> m_types;
+    std::vector<std::unique_ptr<char[]>> m_datas;
+};
+
+class StringBasedIPCBufferImpl : public IPCBuffer {
+public:
+    explicit StringBasedIPCBufferImpl(std::string&& s);
+    const void* get() override;
+    size_t length() override;
+
+private:
+    std::string m_str;
+};
+
+void IPCSerializerImpl::setMsg(uint32_t msg)
+{
+    m_msg = msg;
+}
+
+void IPCSerializerImpl::add(int32_t n)
+{
+    std::unique_ptr<char[]> buffer(new char[sizeof(n)]);
+    *reinterpret_cast<int32_t*>(buffer.get()) = n;
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::INT32));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(int64_t n)
+{
+    std::unique_ptr<char[]> buffer(new char[sizeof(n)]);
+    *reinterpret_cast<int64_t*>(buffer.get()) = n;
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::INT64));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(float n)
+{
+    std::unique_ptr<char[]> buffer(new char[sizeof(n)]);
+    *reinterpret_cast<float*>(buffer.get()) = n;
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::FLOAT));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(double n)
+{
+    std::unique_ptr<char[]> buffer(new char[sizeof(n)]);
+    *reinterpret_cast<double*>(buffer.get()) = n;
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::DOUBLE));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(const uint16_t* data, size_t len)
+{
+    size_t byteLength = len * sizeof(uint16_t);
+    std::unique_ptr<char[]> buffer(new char[byteLength + sizeof(IPCString)]);
+    IPCString* s = reinterpret_cast<IPCString*>(buffer.get());
+    s->length = len;
+    memcpy(s->content, data, byteLength);
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::STRING));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::addJSON(const uint16_t* data, size_t len)
+{
+    size_t byteLength = len * sizeof(uint16_t);
+    std::unique_ptr<char[]> buffer(new char[byteLength + sizeof(IPCString)]);
+    IPCString* s = reinterpret_cast<IPCString*>(buffer.get());
+    s->length = len;
+    memcpy(s->content, data, byteLength);
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::JSONSTRING));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(const char* data, size_t len)
+{
+    size_t byteLength = len;
+    std::unique_ptr<char[]> buffer(new char[byteLength + sizeof(IPCByteArray)]);
+    IPCByteArray* s = reinterpret_cast<IPCByteArray*>(buffer.get());
+    s->length = len;
+    memcpy(s->content, data, byteLength);
+    s->content[byteLength] = '\0';
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::BYTEARRAY));
+    m_datas.emplace_back(std::move(buffer));
+}
+
+void IPCSerializerImpl::add(const IPCByteArray* bytes) {
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::BYTEARRAY));
+    // m_datas.emplace_back(std::move((std::unique_ptr<char[]>)bytes));
+}
+
+void IPCSerializerImpl::addJSUndefined()
+{
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::JSUNDEFINED));
+    m_datas.emplace_back();
+}
+
+void IPCSerializerImpl::addVoid()
+{
+    m_types.emplace_back(static_cast<uint32_t>(IPCType::VOID));
+    m_datas.emplace_back();
+}
+
+std::unique_ptr<IPCBuffer> IPCSerializerImpl::finish()
+{
+    IPC_DCHECK(m_types.size() > 0);
+    IPC_DCHECK(m_msg != MSG_NOT_SET);
+    std::ostringstream oss;
+    oss.write(reinterpret_cast<const char*>(&m_msg), sizeof(m_msg));
+    for (auto& type : m_types) {
+        oss.write(reinterpret_cast<const char*>(&type), sizeof(type));
+    }
+    uint32_t endOfType = static_cast<uint32_t>(IPCType::END);
+    oss.write(reinterpret_cast<const char*>(&endOfType), sizeof(endOfType));
+
+    int i = 0;
+    for (auto& data : m_datas) {
+        switch (static_cast<IPCType>(m_types[i])) {
+        case IPCType::INT32: {
+            oss.write(data.get(), sizeof(int32_t));
+        } break;
+        case IPCType::INT64: {
+            oss.write(data.get(), sizeof(int64_t));
+        } break;
+        case IPCType::FLOAT: {
+            oss.write(data.get(), sizeof(float));
+        } break;
+        case IPCType::DOUBLE: {
+            oss.write(data.get(), sizeof(double));
+        } break;
+        case IPCType::BYTEARRAY: {
+            IPCByteArray* a = reinterpret_cast<IPCByteArray*>(data.get());
+            size_t byteLength = a->length;
+            oss.write(reinterpret_cast<const char*>(&a->length), sizeof(a->length));
+            oss.write(reinterpret_cast<const char*>(a->content), byteLength);
+        } break;
+        case IPCType::JSONSTRING:
+        case IPCType::STRING: {
+            IPCString* s = reinterpret_cast<IPCString*>(data.get());
+            size_t byteLength = s->length * sizeof(uint16_t);
+            oss.write(reinterpret_cast<const char*>(&s->length), sizeof(s->length));
+            oss.write(reinterpret_cast<const char*>(s->content), byteLength);
+        } break;
+        case IPCType::JSUNDEFINED:
+        case IPCType::VOID:
+            break;
+        default:
+            IPC_UNREACHABLE();
+        }
+        ++i;
+    }
+    m_types.clear();
+    m_datas.clear();
+    m_msg = MSG_NOT_SET;
+    std::unique_ptr<StringBasedIPCBufferImpl> bufferReturn(new StringBasedIPCBufferImpl(std::move(oss.str())));
+    return std::unique_ptr<IPCBuffer>(bufferReturn.release());
+}
+
+StringBasedIPCBufferImpl::StringBasedIPCBufferImpl(std::string&& s)
+    : m_str(std::move(s))
+{
+}
+
+const void* StringBasedIPCBufferImpl::get()
+{
+    return m_str.data();
+}
+
+size_t StringBasedIPCBufferImpl::length()
+{
+    return m_str.length();
+}
+}
+
+std::unique_ptr<IPCSerializer> createIPCSerializer()
+{
+    return std::unique_ptr<IPCSerializer>(new IPCSerializerImpl);
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/Serializing/IPCSerializer.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/Serializing/IPCSerializer.h b/weex_core/Source/IPC/Serializing/IPCSerializer.h
new file mode 100644
index 0000000..4c56d86
--- /dev/null
+++ b/weex_core/Source/IPC/Serializing/IPCSerializer.h
@@ -0,0 +1,26 @@
+#ifndef IPCSERIALIZER_H
+#define IPCSERIALIZER_H
+#include <memory>
+#include <stdint.h>
+#include "IPCByteArray.h"
+
+class IPCBuffer;
+class IPCSerializer {
+public:
+    virtual ~IPCSerializer() = default;
+    virtual void setMsg(uint32_t msg) = 0;
+    virtual void add(int32_t) = 0;
+    virtual void add(int64_t) = 0;
+    virtual void add(float) = 0;
+    virtual void add(double) = 0;
+    virtual void add(const uint16_t* data, size_t len) = 0;
+    virtual void addJSON(const uint16_t* data, size_t len) = 0;
+    virtual void add(const char* data, size_t len) = 0;
+    virtual void add(const IPCByteArray* bytes) = 0;
+    virtual void addJSUndefined() = 0;
+    virtual void addVoid() = 0;
+    virtual std::unique_ptr<IPCBuffer> finish() = 0;
+};
+
+std::unique_ptr<IPCSerializer> createIPCSerializer();
+#endif /* IPCSERIALIZER_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/ashmem.c
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/ashmem.c b/weex_core/Source/IPC/ashmem.c
new file mode 100644
index 0000000..e01a5db
--- /dev/null
+++ b/weex_core/Source/IPC/ashmem.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/*
+ * Implementation of the user-space ashmem API for devices, which have our
+ * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
+ * used by the simulator.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ashmem.h"
+#include <linux/ashmem.h>
+
+#define ASHMEM_DEVICE "/dev/ashmem"
+
+/*
+ * ashmem_create_region - creates a new ashmem region and returns the file
+ * descriptor, or <0 on error
+ *
+ * `name' is an optional label to give the region (visible in /proc/pid/maps)
+ * `size' is the size of the region, in page-aligned bytes
+ */
+int ashmem_create_region(const char* name, size_t size)
+{
+    int fd, ret;
+
+    fd = open(ASHMEM_DEVICE, O_RDWR);
+    if (fd < 0)
+        return fd;
+
+    if (name) {
+        char buf[ASHMEM_NAME_LEN];
+
+        strlcpy(buf, name, sizeof(buf));
+        ret = ioctl(fd, ASHMEM_SET_NAME, buf);
+        if (ret < 0)
+            goto error;
+    }
+
+    ret = ioctl(fd, ASHMEM_SET_SIZE, size);
+    if (ret < 0)
+        goto error;
+
+    return fd;
+
+error:
+    close(fd);
+    return ret;
+}
+
+int ashmem_set_prot_region(int fd, int prot)
+{
+    return ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
+}
+
+int ashmem_pin_region(int fd, size_t offset, size_t len)
+{
+    struct ashmem_pin pin = { offset, len };
+    return ioctl(fd, ASHMEM_PIN, &pin);
+}
+
+int ashmem_unpin_region(int fd, size_t offset, size_t len)
+{
+    struct ashmem_pin pin = { offset, len };
+    return ioctl(fd, ASHMEM_UNPIN, &pin);
+}
+
+int ashmem_get_size_region(int fd)
+{
+    return ioctl(fd, ASHMEM_GET_SIZE, NULL);
+}
+
+int ashmem_purge_all(void)
+{
+    const int fd = open(ASHMEM_DEVICE, O_RDWR);
+    if (fd < 0)
+        return fd;
+    const int ret = ioctl(fd, ASHMEM_PURGE_ALL_CACHES, 0);
+    close(fd);
+    return ret;
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/ashmem.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/ashmem.h b/weex_core/Source/IPC/ashmem.h
new file mode 100644
index 0000000..a79ea67
--- /dev/null
+++ b/weex_core/Source/IPC/ashmem.h
@@ -0,0 +1,46 @@
+/* third_party/ashmem/ashmem.h
+ **
+ ** Copyright 2008 The Android Open Source Project
+ **
+ ** This file is dual licensed.  It may be redistributed and/or modified
+ ** under the terms of the Apache 2.0 License OR version 2 of the GNU
+ ** General Public License.
+ */
+
+#ifndef _THIRD_PARTY_ASHMEM_H
+#define _THIRD_PARTY_ASHMEM_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ashmem_create_region(const char* name, size_t size);
+int ashmem_set_prot_region(int fd, int prot);
+int ashmem_pin_region(int fd, size_t offset, size_t len);
+int ashmem_unpin_region(int fd, size_t offset, size_t len);
+int ashmem_get_size_region(int fd);
+int ashmem_purge_all(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef __ASHMEMIOC /* in case someone included <linux/ashmem.h> too */
+
+#define ASHMEM_NAME_LEN 256
+
+#define ASHMEM_NAME_DEF "dev/ashmem"
+
+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
+#define ASHMEM_NOT_PURGED 0
+#define ASHMEM_WAS_PURGED 1
+
+/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */
+#define ASHMEM_IS_UNPINNED 0
+#define ASHMEM_IS_PINNED 1
+
+#endif /* ! __ASHMEMIOC */
+
+#endif /* _THIRD_PARTY_ASHMEM_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/IPC/futex.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/IPC/futex.h b/weex_core/Source/IPC/futex.h
new file mode 100644
index 0000000..f6bb4ee
--- /dev/null
+++ b/weex_core/Source/IPC/futex.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BIONIC_FUTEX_H
+#define _BIONIC_FUTEX_H
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <sys/cdefs.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_FD 2
+#define FUTEX_REQUEUE 3
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_CMP_REQUEUE_PI 12
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
+#define FUTEX_TID_MASK 0x3fffffff
+#define FUTEX_OWNER_DIED 0x40000000
+#define FUTEX_WAITERS 0x80000000
+
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
+#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
+#ifndef __predict_false
+#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
+#endif // __predict_false
+
+struct timespec;
+
+static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout)
+{
+    // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
+    int result = syscall(__NR_futex, ftx, op, value, timeout);
+    return result;
+}
+
+static inline int __futex_wake(volatile void* ftx, int count)
+{
+    return __futex(ftx, FUTEX_WAKE, count, NULL);
+}
+
+static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count)
+{
+    return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
+}
+
+static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout)
+{
+    return __futex(ftx, FUTEX_WAIT, value, timeout);
+}
+
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout)
+{
+    return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout);
+}
+
+#endif /* _BIONIC_FUTEX_H */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/__init__.py
----------------------------------------------------------------------
diff --git a/weex_core/Source/__init__.py b/weex_core/Source/__init__.py
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/__init__.py
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/__init__.py b/weex_core/Source/android/__init__.py
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/base64/base64.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/base64/base64.cpp b/weex_core/Source/android/base/base64/base64.cpp
new file mode 100644
index 0000000..6972564
--- /dev/null
+++ b/weex_core/Source/android/base/base64/base64.cpp
@@ -0,0 +1,33 @@
+
+#include "./base64.h"
+#include <string.h>
+
+bool Base64Encode(const std::string &input, std::string *output) {
+  std::string temp;
+  temp.resize(modp_b64_encode_len(input.size()));  // makes room for null byte
+
+  // null terminates result since result is base64 text!
+  int input_size = static_cast<int>(input.size());
+  int output_size = modp_b64_encode(&(temp[0]), input.data(), input_size);
+  if (output_size < 0)
+    return false;
+
+  temp.resize(output_size);  // strips off null byte
+  output->swap(temp);
+  return true;
+}
+
+bool Base64Decode(const std::string &input, std::string *output) {
+  std::string temp;
+  temp.resize(modp_b64_decode_len(input.size()));
+
+  // does not null terminate result since result is binary data!
+  int input_size = static_cast<int>(input.size());
+  int output_size = modp_b64_decode(&(temp[0]), input.data(), input_size);
+  if (output_size < 0)
+    return false;
+
+  temp.resize(output_size);
+  output->swap(temp);
+  return true;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/base64/base64.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/base64/base64.h b/weex_core/Source/android/base/base64/base64.h
new file mode 100644
index 0000000..d6ae70b
--- /dev/null
+++ b/weex_core/Source/android/base/base64/base64.h
@@ -0,0 +1,9 @@
+#include "./modp_base64/modp_b64.h"
+
+// Encodes the input string in base64.  Returns true if successful and false
+// otherwise.  The output string is only modified if successful.
+bool Base64Encode(const std::string &input, std::string *output);
+
+// Decodes the base64 input string.  Returns true if successful and false
+// otherwise.  The output string is only modified if successful.
+bool Base64Decode(const std::string &input, std::string *output);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc b/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc
new file mode 100644
index 0000000..f230983
--- /dev/null
+++ b/weex_core/Source/android/base/base64/modp_base64/modp_b64.cc
@@ -0,0 +1,265 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
+/* vi: set expandtab shiftwidth=4 tabstop=4: */
+/**
+ * \file
+ * <PRE>
+ * MODP_B64 - High performance base64 encoder/decoder
+ * Version 1.3 -- 17-Mar-2006
+ * http://modp.com/release/base64
+ *
+ * Copyright &copy; 2005, 2006  Nick Galbreath -- nickg [at] modp [dot] com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ *   Neither the name of the modp.com nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This is the standard "new" BSD license:
+ * http://www.opensource.org/licenses/bsd-license.php
+ * </PRE>
+ */
+
+/* public header */
+#include "modp_b64.h"
+
+/*
+ * If you are ripping this out of the library, comment out the next
+ * line and uncomment the next lines as approrpiate
+ */
+//#include "config.h"
+
+/* if on motoral, sun, ibm; uncomment this */
+/* #define WORDS_BIGENDIAN 1 */
+/* else for Intel, Amd; uncomment this */
+/* #undef WORDS_BIGENDIAN */
+
+#include "modp_b64_data.h"
+
+#define BADCHAR 0x01FFFFFF
+
+/**
+ * you can control if we use padding by commenting out this
+ * next line.  However, I highly recommend you use padding and not
+ * using it should only be for compatability with a 3rd party.
+ * Also, 'no padding' is not tested!
+ */
+#define DOPAD 1
+
+/*
+ * if we aren't doing padding
+ * set the pad character to NULL
+ */
+#ifndef DOPAD
+#undef CHARPAD
+#define CHARPAD '\0'
+#endif
+
+int modp_b64_encode(char *dest, const char *str, int len) {
+  int i;
+  uint8_t *p = (uint8_t *) dest;
+
+  /* unsigned here is important! */
+  uint8_t t1, t2, t3;
+
+  for (i = 0; i < len - 2; i += 3) {
+    t1 = str[i];
+    t2 = str[i + 1];
+    t3 = str[i + 2];
+    *p++ = e0[t1];
+    *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
+    *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
+    *p++ = e2[t3];
+  }
+
+  switch (len - i) {
+    case 0:
+      break;
+    case 1:
+      t1 = str[i];
+      *p++ = e0[t1];
+      *p++ = e1[(t1 & 0x03) << 4];
+      *p++ = CHARPAD;
+      *p++ = CHARPAD;
+      break;
+    default: /* case 2 */
+      t1 = str[i];
+      t2 = str[i + 1];
+      *p++ = e0[t1];
+      *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
+      *p++ = e2[(t2 & 0x0F) << 2];
+      *p++ = CHARPAD;
+  }
+
+  *p = '\0';
+  return p - (uint8_t *) dest;
+}
+
+#ifdef WORDS_BIGENDIAN   /* BIG ENDIAN -- SUN / IBM / MOTOROLA */
+int modp_b64_decode(char* dest, const char* src, int len)
+{
+    if (len == 0) return 0;
+
+#ifdef DOPAD
+    /* if padding is used, then the message must be at least
+       4 chars and be a multiple of 4.
+       there can be at most 2 pad chars at the end */
+    if (len < 4 || (len % 4 != 0)) return -1;
+    if (src[len-1] == CHARPAD) {
+        len--;
+        if (src[len -1] == CHARPAD) {
+            len--;
+        }
+    }
+#endif  /* DOPAD */
+
+    int i;
+    int leftover = len % 4;
+    int chunks = (leftover == 0) ? len / 4 - 1 : len /4;
+
+    uint8_t* p = (uint8_t*) dest;
+    uint32_t x = 0;
+    uint32_t* destInt = (uint32_t*) p;
+    uint32_t* srcInt = (uint32_t*) src;
+    uint32_t y = *srcInt++;
+    for (i = 0; i < chunks; ++i) {
+        x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
+            d2[y >> 8 & 0xff] | d3[y & 0xff];
+
+        if (x >= BADCHAR)  return -1;
+        *destInt = x << 8;
+        p += 3;
+        destInt = (uint32_t*)p;
+        y = *srcInt++;
+    }
+
+    switch (leftover) {
+    case 0:
+        x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] |
+            d2[y >>  8 & 0xff] | d3[y & 0xff];
+        if (x >= BADCHAR)  return -1;
+        *p++ = ((uint8_t*)&x)[1];
+        *p++ = ((uint8_t*)&x)[2];
+        *p = ((uint8_t*)&x)[3];
+        return (chunks+1)*3;
+    case 1:
+        x = d3[y >> 24];
+        *p =  (uint8_t)x;
+        break;
+    case 2:
+        x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff];
+        *p =  (uint8_t)(x >> 4);
+        break;
+    default:  /* case 3 */
+        x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 +
+            d3[(y >> 8) & 0xff];
+        *p++ = (uint8_t) (x >> 10);
+        *p = (uint8_t) (x >> 2);
+        break;
+    }
+
+    if (x >= BADCHAR) return -1;
+    return 3*chunks + (6*leftover)/8;
+}
+
+#else /* LITTLE  ENDIAN -- INTEL AND FRIENDS */
+
+int modp_b64_decode(char *dest, const char *src, int len) {
+  if (len == 0) return 0;
+
+#ifdef DOPAD
+  /*
+   * if padding is used, then the message must be at least
+   * 4 chars and be a multiple of 4
+   */
+  if (len < 4 || (len % 4 != 0)) return -1; /* error */
+  /* there can be at most 2 pad chars at the end */
+  if (src[len - 1] == CHARPAD) {
+    len--;
+    if (src[len - 1] == CHARPAD) {
+      len--;
+    }
+  }
+#endif
+
+  int i;
+  int leftover = len % 4;
+  int chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
+
+  uint8_t *p = (uint8_t *) dest;
+  uint32_t x = 0;
+  uint32_t *destInt = (uint32_t *) p;
+  uint32_t *srcInt = (uint32_t *) src;
+  uint32_t y = *srcInt++;
+  for (i = 0; i < chunks; ++i) {
+    x = d0[y & 0xff] |
+        d1[(y >> 8) & 0xff] |
+        d2[(y >> 16) & 0xff] |
+        d3[(y >> 24) & 0xff];
+
+    if (x >= BADCHAR) return -1;
+    *destInt = x;
+    p += 3;
+    destInt = (uint32_t *) p;
+    y = *srcInt++;
+  }
+
+
+  switch (leftover) {
+    case 0:
+      x = d0[y & 0xff] |
+          d1[(y >> 8) & 0xff] |
+          d2[(y >> 16) & 0xff] |
+          d3[(y >> 24) & 0xff];
+
+      if (x >= BADCHAR) return -1;
+      *p++ = ((uint8_t *) (&x))[0];
+      *p++ = ((uint8_t *) (&x))[1];
+      *p = ((uint8_t *) (&x))[2];
+      return (chunks + 1) * 3;
+      break;
+    case 1:  /* with padding this is an impossible case */
+      x = d0[y & 0xff];
+      *p = *((uint8_t *) (&x)); // i.e. first char/byte in int
+      break;
+    case 2: // * case 2, 1  output byte */
+      x = d0[y & 0xff] | d1[y >> 8 & 0xff];
+      *p = *((uint8_t *) (&x)); // i.e. first char
+      break;
+    default: /* case 3, 2 output bytes */
+      x = d0[y & 0xff] |
+          d1[y >> 8 & 0xff] |
+          d2[y >> 16 & 0xff];  /* 0x3c */
+      *p++ = ((uint8_t *) (&x))[0];
+      *p = ((uint8_t *) (&x))[1];
+      break;
+  }
+
+  if (x >= BADCHAR) return -1;
+
+  return 3 * chunks + (6 * leftover) / 8;
+}
+
+#endif  /* if bigendian / else / endif */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/base64/modp_base64/modp_b64.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/base64/modp_base64/modp_b64.h b/weex_core/Source/android/base/base64/modp_base64/modp_b64.h
new file mode 100644
index 0000000..1d18741
--- /dev/null
+++ b/weex_core/Source/android/base/base64/modp_base64/modp_b64.h
@@ -0,0 +1,165 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
+/* vi: set expandtab shiftwidth=4 tabstop=4: */
+
+/**
+ * \file
+ * <PRE>
+ * High performance base64 encoder / decoder
+ * Version 1.3 -- 17-Mar-2006
+ *
+ * Copyright &copy; 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
+ * All rights reserved.
+ *
+ * http://modp.com/release/base64
+ *
+ * Released under bsd license.  See modp_b64.c for details.
+ * </pre>
+ *
+ * The default implementation is the standard b64 encoding with padding.
+ * It's easy to change this to use "URL safe" characters and to remove
+ * padding.  See the modp_b64.c source code for details.
+ *
+ */
+
+#ifndef MODP_B64
+#define MODP_B64
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Encode a raw binary string into base 64.
+ * src contains the bytes
+ * len contains the number of bytes in the src
+ * dest should be allocated by the caller to contain
+ *   at least modp_b64_encode_len(len) bytes (see below)
+ *   This will contain the null-terminated b64 encoded result
+ * returns length of the destination string plus the ending null byte
+ *    i.e.  the result will be equal to strlen(dest) + 1
+ *
+ * Example
+ * 
+ * \code
+ * char* src = ...;
+ * int srclen = ...; //the length of number of bytes in src
+ * char* dest = (char*) malloc(modp_b64_encode_len);
+ * int len = modp_b64_encode(dest, src, sourcelen);
+ * if (len == -1) {
+ *   printf("Error\n");
+ * } else {
+ *   printf("b64 = %s\n", dest);
+ * }
+ * \endcode
+ *
+ */
+int modp_b64_encode(char *dest, const char *str, int len);
+
+/**
+ * Decode a base64 encoded string
+ *
+ * src should contain exactly len bytes of b64 characters.
+ *     if src contains -any- non-base characters (such as white
+ *     space, -1 is returned.
+ *
+ * dest should be allocated by the caller to contain at least
+ *    len * 3 / 4 bytes.
+ *
+ * Returns the length (strlen) of the output, or -1 if unable to
+ * decode
+ *
+ * \code
+ * char* src = ...;
+ * int srclen = ...; // or if you don't know use strlen(src)
+ * char* dest = (char*) malloc(modp_b64_decode_len(srclen));
+ * int len = modp_b64_decode(dest, src, sourcelen);
+ * if (len == -1) { error }
+ * \endcode
+ */
+int modp_b64_decode(char *dest, const char *src, int len);
+
+/**
+ * Given a source string of length len, this returns the amount of
+ * memory the destination string should have.
+ *
+ * remember, this is integer math
+ * 3 bytes turn into 4 chars
+ * ceiling[len / 3] * 4 + 1
+ *
+ * +1 is for any extra null.
+ */
+#define modp_b64_encode_len(A) ((A+2)/3 * 4 + 1)
+
+/**
+ * Given a base64 string of length len,
+ *   this returns the amount of memory required for output string
+ *  It maybe be more than the actual number of bytes written.
+ * NOTE: remember this is integer math
+ * this allocates a bit more memory than traditional versions of b64
+ * decode  4 chars turn into 3 bytes
+ * floor[len * 3/4] + 2
+ */
+#define modp_b64_decode_len(A) (A / 4 * 3 + 2)
+
+/**
+ * Will return the strlen of the output from encoding.
+ * This may be less than the required number of bytes allocated.
+ *
+ * This allows you to 'deserialized' a struct
+ * \code
+ * char* b64encoded = "...";
+ * int len = strlen(b64encoded);
+ *
+ * struct datastuff foo;
+ * if (modp_b64_encode_strlen(sizeof(struct datastuff)) != len) {
+ *    // wrong size
+ *    return false;
+ * } else {
+ *    // safe to do;
+ *    if (modp_b64_decode((char*) &foo, b64encoded, len) == -1) {
+ *      // bad characters
+ *      return false;
+ *    }
+ * }
+ * // foo is filled out now
+ * \endcode
+ */
+#define modp_b64_encode_strlen(A) ((A + 2)/ 3 * 4)
+
+#ifdef __cplusplus
+}
+
+#include <string>
+
+inline std::string &modp_b64_encode(std::string &s) {
+  std::string x(modp_b64_encode_len(s.size()), '\0');
+  int d = modp_b64_encode(const_cast<char *>(x.data()), s.data(), s.size());
+  x.erase(d, std::string::npos);
+  s.swap(x);
+  return s;
+}
+
+/**
+ * base 64 decode a string (self-modifing)
+ * On failure, the string is empty.
+ *
+ * This function is for C++ only (duh)
+ *
+ * \param[in,out] s the string to be decoded
+ * \return a reference to the input string
+ */
+inline std::string &modp_b64_decode(std::string &s) {
+  std::string x(modp_b64_decode_len(s.size()), '\0');
+  int d = modp_b64_decode(const_cast<char *>(x.data()), s.data(), s.size());
+  if (d < 0) {
+    x.clear();
+  } else {
+    x.erase(d, std::string::npos);
+  }
+  s.swap(x);
+  return s;
+}
+
+#endif /* __cplusplus */
+
+#endif /* MODP_B64 */

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/base64/modp_base64/modp_b64_data.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/base64/modp_base64/modp_b64_data.h b/weex_core/Source/android/base/base64/modp_base64/modp_b64_data.h
new file mode 100644
index 0000000..434f692
--- /dev/null
+++ b/weex_core/Source/android/base/base64/modp_base64/modp_b64_data.h
@@ -0,0 +1,285 @@
+// VC8 doesn't have stdint.h.  On the other hand, some compilers don't like
+// the below code, because basictypes.h itself includes stdint.h and the
+// typedefs below can cause conflicts.
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+
+#define CHAR62 '+'
+#define CHAR63 '/'
+#define CHARPAD '='
+static const char e0[256] = {
+ 'A',  'A',  'A',  'A',  'B',  'B',  'B',  'B',  'C',  'C',
+ 'C',  'C',  'D',  'D',  'D',  'D',  'E',  'E',  'E',  'E',
+ 'F',  'F',  'F',  'F',  'G',  'G',  'G',  'G',  'H',  'H',
+ 'H',  'H',  'I',  'I',  'I',  'I',  'J',  'J',  'J',  'J',
+ 'K',  'K',  'K',  'K',  'L',  'L',  'L',  'L',  'M',  'M',
+ 'M',  'M',  'N',  'N',  'N',  'N',  'O',  'O',  'O',  'O',
+ 'P',  'P',  'P',  'P',  'Q',  'Q',  'Q',  'Q',  'R',  'R',
+ 'R',  'R',  'S',  'S',  'S',  'S',  'T',  'T',  'T',  'T',
+ 'U',  'U',  'U',  'U',  'V',  'V',  'V',  'V',  'W',  'W',
+ 'W',  'W',  'X',  'X',  'X',  'X',  'Y',  'Y',  'Y',  'Y',
+ 'Z',  'Z',  'Z',  'Z',  'a',  'a',  'a',  'a',  'b',  'b',
+ 'b',  'b',  'c',  'c',  'c',  'c',  'd',  'd',  'd',  'd',
+ 'e',  'e',  'e',  'e',  'f',  'f',  'f',  'f',  'g',  'g',
+ 'g',  'g',  'h',  'h',  'h',  'h',  'i',  'i',  'i',  'i',
+ 'j',  'j',  'j',  'j',  'k',  'k',  'k',  'k',  'l',  'l',
+ 'l',  'l',  'm',  'm',  'm',  'm',  'n',  'n',  'n',  'n',
+ 'o',  'o',  'o',  'o',  'p',  'p',  'p',  'p',  'q',  'q',
+ 'q',  'q',  'r',  'r',  'r',  'r',  's',  's',  's',  's',
+ 't',  't',  't',  't',  'u',  'u',  'u',  'u',  'v',  'v',
+ 'v',  'v',  'w',  'w',  'w',  'w',  'x',  'x',  'x',  'x',
+ 'y',  'y',  'y',  'y',  'z',  'z',  'z',  'z',  '0',  '0',
+ '0',  '0',  '1',  '1',  '1',  '1',  '2',  '2',  '2',  '2',
+ '3',  '3',  '3',  '3',  '4',  '4',  '4',  '4',  '5',  '5',
+ '5',  '5',  '6',  '6',  '6',  '6',  '7',  '7',  '7',  '7',
+ '8',  '8',  '8',  '8',  '9',  '9',  '9',  '9',  '+',  '+',
+ '+',  '+',  '/',  '/',  '/',  '/'
+};
+
+static const char e1[256] = {
+ 'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H',  'I',  'J',
+ 'K',  'L',  'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',
+ 'U',  'V',  'W',  'X',  'Y',  'Z',  'a',  'b',  'c',  'd',
+ 'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',
+ 'o',  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',
+ 'y',  'z',  '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
+ '8',  '9',  '+',  '/',  'A',  'B',  'C',  'D',  'E',  'F',
+ 'G',  'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',  'P',
+ 'Q',  'R',  'S',  'T',  'U',  'V',  'W',  'X',  'Y',  'Z',
+ 'a',  'b',  'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',
+ 'k',  'l',  'm',  'n',  'o',  'p',  'q',  'r',  's',  't',
+ 'u',  'v',  'w',  'x',  'y',  'z',  '0',  '1',  '2',  '3',
+ '4',  '5',  '6',  '7',  '8',  '9',  '+',  '/',  'A',  'B',
+ 'C',  'D',  'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L',
+ 'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',  'U',  'V',
+ 'W',  'X',  'Y',  'Z',  'a',  'b',  'c',  'd',  'e',  'f',
+ 'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',  'p',
+ 'q',  'r',  's',  't',  'u',  'v',  'w',  'x',  'y',  'z',
+ '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',
+ '+',  '/',  'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H',
+ 'I',  'J',  'K',  'L',  'M',  'N',  'O',  'P',  'Q',  'R',
+ 'S',  'T',  'U',  'V',  'W',  'X',  'Y',  'Z',  'a',  'b',
+ 'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',
+ 'm',  'n',  'o',  'p',  'q',  'r',  's',  't',  'u',  'v',
+ 'w',  'x',  'y',  'z',  '0',  '1',  '2',  '3',  '4',  '5',
+ '6',  '7',  '8',  '9',  '+',  '/'
+};
+
+static const char e2[256] = {
+ 'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H',  'I',  'J',
+ 'K',  'L',  'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',
+ 'U',  'V',  'W',  'X',  'Y',  'Z',  'a',  'b',  'c',  'd',
+ 'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',
+ 'o',  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',
+ 'y',  'z',  '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
+ '8',  '9',  '+',  '/',  'A',  'B',  'C',  'D',  'E',  'F',
+ 'G',  'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',  'P',
+ 'Q',  'R',  'S',  'T',  'U',  'V',  'W',  'X',  'Y',  'Z',
+ 'a',  'b',  'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',
+ 'k',  'l',  'm',  'n',  'o',  'p',  'q',  'r',  's',  't',
+ 'u',  'v',  'w',  'x',  'y',  'z',  '0',  '1',  '2',  '3',
+ '4',  '5',  '6',  '7',  '8',  '9',  '+',  '/',  'A',  'B',
+ 'C',  'D',  'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L',
+ 'M',  'N',  'O',  'P',  'Q',  'R',  'S',  'T',  'U',  'V',
+ 'W',  'X',  'Y',  'Z',  'a',  'b',  'c',  'd',  'e',  'f',
+ 'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',  'p',
+ 'q',  'r',  's',  't',  'u',  'v',  'w',  'x',  'y',  'z',
+ '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',
+ '+',  '/',  'A',  'B',  'C',  'D',  'E',  'F',  'G',  'H',
+ 'I',  'J',  'K',  'L',  'M',  'N',  'O',  'P',  'Q',  'R',
+ 'S',  'T',  'U',  'V',  'W',  'X',  'Y',  'Z',  'a',  'b',
+ 'c',  'd',  'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',
+ 'm',  'n',  'o',  'p',  'q',  'r',  's',  't',  'u',  'v',
+ 'w',  'x',  'y',  'z',  '0',  '1',  '2',  '3',  '4',  '5',
+ '6',  '7',  '8',  '9',  '+',  '/'
+};
+
+
+/* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */
+
+static const uint32_t d0[256] = {
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc,
+0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4,
+0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
+0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018,
+0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030,
+0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048,
+0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060,
+0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078,
+0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090,
+0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8,
+0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0,
+0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
+};
+
+
+static const uint32_t d1[256] = {
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003,
+0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003,
+0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
+0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
+0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
+0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001,
+0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001,
+0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001,
+0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002,
+0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002,
+0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003,
+0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
+};
+
+
+static const uint32_t d2[256] = {
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00,
+0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00,
+0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
+0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100,
+0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300,
+0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400,
+0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600,
+0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700,
+0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900,
+0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00,
+0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00,
+0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
+};
+
+
+static const uint32_t d3[256] = {
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000,
+0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000,
+0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000,
+0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000,
+0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000,
+0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000,
+0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000,
+0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000,
+0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000,
+0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000,
+0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000,
+0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
+0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/jni/android_jni.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/jni/android_jni.cpp b/weex_core/Source/android/base/jni/android_jni.cpp
new file mode 100644
index 0000000..2083079
--- /dev/null
+++ b/weex_core/Source/android/base/jni/android_jni.cpp
@@ -0,0 +1,90 @@
+
+#include "android_jni.h"
+
+namespace {
+JavaVM *g_jvm = nullptr;
+}
+
+namespace base {
+namespace android {
+
+void InitVM(JavaVM *vm) {
+  g_jvm = vm;
+}
+
+JNIEnv *AttachCurrentThread() {
+  JNIEnv *env = nullptr;
+  jint ret = g_jvm->AttachCurrentThread(&env, nullptr);
+  return env;
+}
+
+void DetachFromVM() {
+  if (g_jvm) {
+    g_jvm->DetachCurrentThread();
+  }
+}
+
+ScopedLocalJavaRef<jclass> GetClass(JNIEnv *env, const char *class_name) {
+  jclass clazz;
+  clazz = env->FindClass(class_name);
+  return ScopedLocalJavaRef<jclass>(env, clazz);
+}
+
+jclass GetClass(JNIEnv *env, const char *class_name, intptr_t *class_id) {
+  if (*class_id) {
+    return reinterpret_cast<jclass>(*class_id);
+  }
+  ScopedGlobalJavaRef<jclass> clazz;
+  clazz.Reset(env, GetClass(env, class_name));
+  *class_id = reinterpret_cast<intptr_t>(clazz.Release());
+}
+
+jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type,
+                    const char *method_name, const char *jni_signature) {
+  if (type == STATIC_METHOD) {
+    return env->GetStaticMethodID(clazz, method_name, jni_signature);
+  } else if (type == INSTANCE_METHOD) {
+    return env->GetMethodID(clazz, method_name, jni_signature);
+  }
+  return 0;
+}
+
+jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type,
+                    const char *method_name, const char *jni_signature, intptr_t *method_id) {
+  if (*method_id) {
+    return reinterpret_cast<jmethodID>(*method_id);
+  }
+  *method_id = reinterpret_cast<intptr_t>(GetMethod(env,
+                                                    clazz, type, method_name, jni_signature));
+  return reinterpret_cast<jmethodID>(*method_id);
+}
+
+bool HasException(JNIEnv *env) {
+  return env->ExceptionCheck() != JNI_FALSE;
+}
+
+bool ClearException(JNIEnv *env) {
+  if (!HasException(env))
+    return false;
+  env->ExceptionDescribe();
+  env->ExceptionClear();
+  return true;
+}
+
+void CheckException(JNIEnv *env) {
+  if (!HasException(env))
+    return;
+
+  // Exception has been found, might as well tell breakpad about it.
+  jthrowable java_throwable = env->ExceptionOccurred();
+  if (java_throwable) {
+    // Clear the pending exception, since a local reference is now held.
+    env->ExceptionDescribe();
+    env->ExceptionClear();
+  }
+
+  // Now, feel good about it and die.
+  // CHECK(false) << "Please include Java exception stack in crash report";
+}
+}  // namespace android
+}  // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/jni/android_jni.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/jni/android_jni.h b/weex_core/Source/android/base/jni/android_jni.h
new file mode 100644
index 0000000..16eef76
--- /dev/null
+++ b/weex_core/Source/android/base/jni/android_jni.h
@@ -0,0 +1,45 @@
+
+
+#ifndef WEEXCORE_BASE_ANDROID_ANDROID_JNI_H_
+#define WEEXCORE_BASE_ANDROID_ANDROID_JNI_H_
+
+#include <cstdint>
+#include <jni.h>
+
+#include "scoped_java_ref.h"
+
+namespace base {
+namespace android {
+
+void InitVM(JavaVM *vm);
+
+JNIEnv *AttachCurrentThread();
+
+void DetachFromVM();
+
+ScopedLocalJavaRef<jclass> GetClass(JNIEnv *env, const char *class_name);
+
+jclass GetClass(JNIEnv *env, const char *class_name, intptr_t *class_id);
+
+enum MethodType {
+    STATIC_METHOD,
+    INSTANCE_METHOD,
+};
+
+jmethodID GetMethod(JNIEnv *env, jclass clazz,
+                    MethodType type, const char *method_name, const char *jni_signature);
+
+jmethodID GetMethod(JNIEnv *env, jclass clazz,
+                    MethodType type, const char *method_name,
+                    const char *jni_signature, intptr_t *method_id);
+
+bool HasException(JNIEnv *env);
+
+bool ClearException(JNIEnv *env);
+
+void CheckException(JNIEnv *env);
+}  // namespace android
+}  // namespace base
+
+
+#endif  // WEEXCORE_BASE_ANDROID_ANDROID_JNI_H_

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/jni/scoped_java_ref.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/jni/scoped_java_ref.cpp b/weex_core/Source/android/base/jni/scoped_java_ref.cpp
new file mode 100644
index 0000000..db39bff
--- /dev/null
+++ b/weex_core/Source/android/base/jni/scoped_java_ref.cpp
@@ -0,0 +1,57 @@
+// Copyright 2017 The Weex Authors. All rights reserved.
+
+#include "android_jni.h"
+#include "scoped_java_ref.h"
+
+namespace base {
+namespace android {
+
+JavaRef::JavaRef() : obj_(nullptr) {}
+
+JavaRef::JavaRef(JNIEnv *env, jobject obj) : obj_(obj) {}
+
+void JavaRef::ResetNewLocalRef(JNIEnv *env, jobject obj) {
+  if (!env) {
+    env = AttachCurrentThread();
+  }
+  if (obj) {
+    obj = env->NewLocalRef(obj);
+  }
+
+  if (obj_)
+    env->DeleteLocalRef(obj_);
+  obj_ = obj;
+}
+
+void JavaRef::ReleaseLocalRef(JNIEnv *env) {
+  if (!env) {
+    env = AttachCurrentThread();
+  }
+  env->DeleteLocalRef(obj_);
+}
+
+void JavaRef::ResetNewGlobalRef(JNIEnv *env, jobject obj) {
+  if (!env) {
+    env = AttachCurrentThread();
+  }
+  if (obj)
+    obj = env->NewGlobalRef(obj);
+  if (obj_)
+    env->DeleteGlobalRef(obj_);
+  obj_ = obj;
+}
+
+void JavaRef::ReleaseGlobalRef(JNIEnv *env) {
+  if (!env) {
+    env = AttachCurrentThread();
+  }
+  env->DeleteGlobalRef(obj_);
+}
+
+jobject JavaRef::Release() {
+  jobject obj = obj_;
+  obj_ = nullptr;
+  return obj;
+}
+}  // namespace android
+}  // namespace base

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/jni/scoped_java_ref.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/jni/scoped_java_ref.h b/weex_core/Source/android/base/jni/scoped_java_ref.h
new file mode 100644
index 0000000..0e2d2c6
--- /dev/null
+++ b/weex_core/Source/android/base/jni/scoped_java_ref.h
@@ -0,0 +1,104 @@
+// Copyright 2017 The WeexCore Authors. All rights reserved.
+
+#ifndef WeexCore_BASE_ANDROID_SCOPED_JAVA_REF_H_
+#define WeexCore_BASE_ANDROID_SCOPED_JAVA_REF_H_
+
+#include <jni.h>
+
+namespace base {
+namespace android {
+class JavaRef {
+public:
+    JavaRef();
+
+    JavaRef(JNIEnv *env, jobject obj);
+
+    ~JavaRef() {}
+
+    void ResetNewLocalRef(JNIEnv *env, jobject obj);
+
+    void ReleaseLocalRef(JNIEnv *env);
+
+    void ResetNewGlobalRef(JNIEnv *env, jobject obj);
+
+    void ReleaseGlobalRef(JNIEnv *env);
+
+    jobject Release();
+
+    jobject Get() const { return obj_; }
+
+    bool IsNull() const { return obj_ == nullptr; }
+
+protected:
+    jobject obj_;
+};
+
+template<typename T>
+class ScopedLocalJavaRef : public JavaRef {
+public:
+    ScopedLocalJavaRef() : env_(nullptr) {}
+
+    ScopedLocalJavaRef(JNIEnv *env, T obj) : env_(env), JavaRef(env, obj) {
+    }
+
+    ScopedLocalJavaRef(const ScopedLocalJavaRef<T> &other) : env_(other.env_) {
+      Reset(env_, other.Get());
+    }
+
+    void operator=(const ScopedLocalJavaRef<T> &other) {
+      env_ = other.env_;
+      Reset(env_, other.Get());
+    }
+
+    ~ScopedLocalJavaRef() {
+      ReleaseLocalRef(env_);
+    }
+
+    void Reset(JNIEnv *env, jobject obj) {
+      ResetNewLocalRef(env, obj);
+    }
+
+private:
+    JNIEnv *env_;
+};
+
+template<typename T>
+class ScopedGlobalJavaRef : public JavaRef {
+public:
+    ScopedGlobalJavaRef() {}
+
+    ScopedGlobalJavaRef(JNIEnv *env, T obj) {
+      Reset(env, obj);
+    }
+
+    ScopedGlobalJavaRef(const ScopedGlobalJavaRef<T> &other) {
+      Reset(nullptr, other.Get());
+    }
+
+    ScopedGlobalJavaRef(
+            const ScopedLocalJavaRef<T> &other) {
+      Reset(nullptr, other.Get());
+    }
+
+    ~ScopedGlobalJavaRef() {
+      ReleaseGlobalRef(nullptr);
+    }
+
+    void operator=(const ScopedGlobalJavaRef<T> &other) {
+      Reset(nullptr, other.Get());
+    }
+
+    void Reset(JNIEnv *env, const ScopedLocalJavaRef<T> &other) {
+      ResetNewGlobalRef(env, other.Get());
+    }
+
+    void Reset(JNIEnv *env, jobject obj) {
+      ResetNewGlobalRef(env, obj);
+    }
+};
+
+}  // namespace android
+}  // namespace base
+
+
+#endif  // WeexCore_BASE_ANDROID_SCOPED_JAVA_REF_H_

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/log_utils.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/log_utils.h b/weex_core/Source/android/base/log_utils.h
new file mode 100644
index 0000000..4b053c9
--- /dev/null
+++ b/weex_core/Source/android/base/log_utils.h
@@ -0,0 +1,37 @@
+#ifndef _LOG_UTILS_H_
+#define _LOG_UTILS_H_
+
+#include <android/log.h>
+
+#define LOG_TAG "WeexCore"
+
+#define LOGE(...)    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#define LOGA(...)    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define LOGD(...)    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+//#define DEBUG
+
+#ifdef DEBUG
+
+#define LOGV(...) 	__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
+#define LOGD(...) 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+#define LOGI(...) 	__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
+#define LOG_LINE LOGV("%s, %d", __func__, __LINE__)
+
+#else
+
+#define LOGV(...) ((void) 0)
+#define LOGD(...) ((void) 0)
+#define LOGI(...) ((void) 0)
+#define LOGW(...) ((void) 0)
+#define LOG_LINE
+
+#endif
+
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName)  \
+  TypeName(const TypeName&) = delete;      \
+  void operator=(const TypeName&) = delete
+#endif
+
+#endif //_LOG_UTILS_H_

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/string/scoped_jstring.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/scoped_jstring.cpp b/weex_core/Source/android/base/string/scoped_jstring.cpp
new file mode 100644
index 0000000..d3da6aa
--- /dev/null
+++ b/weex_core/Source/android/base/string/scoped_jstring.cpp
@@ -0,0 +1,29 @@
+#include "scoped_jstring.h"
+
+namespace WeexCore {
+
+ScopedJString::ScopedJString(JNIEnv *env, jstring _jstring)
+        : m_env(env), m_jstring(_jstring), m_chars(nullptr), m_len(0) {
+}
+
+ScopedJString::~ScopedJString() {
+  if (m_chars)
+    m_env->ReleaseStringChars(m_jstring, m_chars);
+}
+
+const jchar *ScopedJString::getChars() {
+  if (m_chars)
+    return m_chars;
+  m_chars = m_env->GetStringChars(m_jstring, nullptr);
+  m_len = m_env->GetStringLength(m_jstring);
+  return m_chars;
+}
+
+size_t ScopedJString::getCharsLength() {
+  if (m_chars)
+    return m_len;
+  m_len = m_env->GetStringLength(m_jstring);
+  return m_len;
+}
+
+} //WeexCore
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/string/scoped_jstring.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/scoped_jstring.h b/weex_core/Source/android/base/string/scoped_jstring.h
new file mode 100644
index 0000000..f66216a
--- /dev/null
+++ b/weex_core/Source/android/base/string/scoped_jstring.h
@@ -0,0 +1,27 @@
+#ifndef _SCOPED_JSTRING_H_
+#define _SCOPED_JSTRING_H_
+
+#include "../base64/base64.h"
+#include <jni.h>
+
+namespace WeexCore {
+
+class ScopedJString {
+public:
+    ScopedJString(JNIEnv *env, jstring);
+
+    ~ScopedJString();
+
+    const jchar *getChars();
+
+    size_t getCharsLength();
+
+private:
+    JNIEnv *m_env;
+    jstring m_jstring;
+    const uint16_t *m_chars;
+    size_t m_len;
+};
+
+}
+#endif //_SCOPED_JSTRING_H_

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/string/scoped_jstring_utf8.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/scoped_jstring_utf8.cpp b/weex_core/Source/android/base/string/scoped_jstring_utf8.cpp
new file mode 100644
index 0000000..74f1a9c
--- /dev/null
+++ b/weex_core/Source/android/base/string/scoped_jstring_utf8.cpp
@@ -0,0 +1,20 @@
+#include "scoped_jstring_utf8.h"
+
+namespace WeexCore {
+ScopedJStringUTF8::ScopedJStringUTF8(JNIEnv *env, jstring _jstring)
+        : m_env(env), m_jstring(_jstring), m_chars(nullptr) {
+}
+
+ScopedJStringUTF8::~ScopedJStringUTF8() {
+  if (m_chars)
+    m_env->ReleaseStringUTFChars(m_jstring, m_chars);
+}
+
+const char *ScopedJStringUTF8::getChars() {
+  if (m_chars)
+    return m_chars;
+  m_chars = m_env->GetStringUTFChars(m_jstring, nullptr);
+  return m_chars;
+}
+
+} //WeexCore
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/android/base/string/scoped_jstring_utf8.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/android/base/string/scoped_jstring_utf8.h b/weex_core/Source/android/base/string/scoped_jstring_utf8.h
new file mode 100644
index 0000000..ee62e2f
--- /dev/null
+++ b/weex_core/Source/android/base/string/scoped_jstring_utf8.h
@@ -0,0 +1,31 @@
+#ifndef _SCOPED_JSTRING_UTF_8_H_
+#define _SCOPED_JSTRING_UTF_8_H_
+
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <thread>
+#include <type_traits>
+#include "../base64/base64.h"
+#include <jni.h>
+
+namespace WeexCore {
+
+class ScopedJStringUTF8 {
+public:
+    ScopedJStringUTF8(JNIEnv *env, jstring);
+
+    ~ScopedJStringUTF8();
+
+    const char *getChars();
+
+private:
+    JNIEnv *m_env;
+    jstring m_jstring;
+    const char *m_chars;
+};
+
+}
+#endif //_SCOPED_JSTRING_UTF_8_H_