Repository: incubator-weex Updated Branches: refs/heads/master 162d70588 -> 50ae70ce8
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/rapidjson/stringbuffer.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/rapidjson/stringbuffer.h b/weex_core/Source/rapidjson/stringbuffer.h deleted file mode 100644 index 4e38b82..0000000 --- a/weex_core/Source/rapidjson/stringbuffer.h +++ /dev/null @@ -1,121 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// 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 RAPIDJSON_STRINGBUFFER_H_ -#define RAPIDJSON_STRINGBUFFER_H_ - -#include "stream.h" -#include "internal/stack.h" - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS -#include <utility> // std::move -#endif - -#include "internal/stack.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory output stream. -/*! - \tparam Encoding Encoding of the stream. - \tparam Allocator type for allocating memory buffer. - \note implements Stream concept -*/ -template <typename Encoding, typename Allocator = CrtAllocator> -class GenericStringBuffer { -public: - typedef typename Encoding::Ch Ch; - - GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} - GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { - if (&rhs != this) - stack_ = std::move(rhs.stack_); - return *this; - } -#endif - - void Put(Ch c) { *stack_.template Push<Ch>() = c; } - void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; } - void Flush() {} - - void Clear() { stack_.Clear(); } - void ShrinkToFit() { - // Push and pop a null terminator. This is safe. - *stack_.template Push<Ch>() = '\0'; - stack_.ShrinkToFit(); - stack_.template Pop<Ch>(1); - } - - void Reserve(size_t count) { stack_.template Reserve<Ch>(count); } - Ch* Push(size_t count) { return stack_.template Push<Ch>(count); } - Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); } - void Pop(size_t count) { stack_.template Pop<Ch>(count); } - - const Ch* GetString() const { - // Push and pop a null terminator. This is safe. - *stack_.template Push<Ch>() = '\0'; - stack_.template Pop<Ch>(1); - - return stack_.template Bottom<Ch>(); - } - - //! Get the size of string in bytes in the string buffer. - size_t GetSize() const { return stack_.GetSize(); } - - //! Get the length of string in Ch in the string buffer. - size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } - - static const size_t kDefaultCapacity = 256; - mutable internal::Stack<Allocator> stack_; - -private: - // Prohibit copy constructor & assignment operator. - GenericStringBuffer(const GenericStringBuffer&); - GenericStringBuffer& operator=(const GenericStringBuffer&); -}; - -//! String buffer with UTF8 encoding -typedef GenericStringBuffer<UTF8<> > StringBuffer; - -template<typename Encoding, typename Allocator> -inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) { - stream.Reserve(count); -} - -template<typename Encoding, typename Allocator> -inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) { - stream.PutUnsafe(c); -} - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) { - std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c)); -} - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_STRINGBUFFER_H_ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/rapidjson/writer.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/rapidjson/writer.h b/weex_core/Source/rapidjson/writer.h deleted file mode 100644 index e610ebb..0000000 --- a/weex_core/Source/rapidjson/writer.h +++ /dev/null @@ -1,711 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// 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 RAPIDJSON_WRITER_H_ -#define RAPIDJSON_WRITER_H_ - -#include "stream.h" -#include "internal/meta.h" -#include "internal/stack.h" -#include "internal/strfunc.h" -#include "internal/dtoa.h" -#include "internal/itoa.h" -#include "stringbuffer.h" -#include <new> // placement new - -#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) -#include <intrin.h> -#pragma intrinsic(_BitScanForward) -#endif -#ifdef RAPIDJSON_SSE42 -#include <nmmintrin.h> -#elif defined(RAPIDJSON_SSE2) -#include <emmintrin.h> -#elif defined(RAPIDJSON_NEON) -#include <arm_neon.h> -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// WriteFlag - -/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS - \ingroup RAPIDJSON_CONFIG - \brief User-defined kWriteDefaultFlags definition. - - User can define this as any \c WriteFlag combinations. -*/ -#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS -#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags -#endif - -//! Combination of writeFlags -enum WriteFlag { - kWriteNoFlags = 0, //!< No flags are set. - kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. - kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. - kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS -}; - -//! JSON writer -/*! Writer implements the concept Handler. - It generates JSON text by events to an output os. - - User may programmatically calls the functions of a writer to generate JSON text. - - On the other side, a writer can also be passed to objects that generates events, - - for example Reader::Parse() and Document::Accept(). - - \tparam OutputStream Type of output stream. - \tparam SourceEncoding Encoding of source string. - \tparam TargetEncoding Encoding of output stream. - \tparam StackAllocator Type of allocator for allocating memory of stack. - \note implements Handler concept -*/ -template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> -class Writer { -public: - typedef typename SourceEncoding::Ch Ch; - - static const int kDefaultMaxDecimalPlaces = 324; - - //! Constructor - /*! \param os Output stream. - \param stackAllocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of stack. - */ - explicit - Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - - explicit - Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Writer(Writer&& rhs) : - os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) { - rhs.os_ = 0; - } -#endif - - //! Reset the writer with a new stream. - /*! - This function reset the writer with a new stream and default settings, - in order to make a Writer object reusable for output multiple JSONs. - - \param os New output stream. - \code - Writer<OutputStream> writer(os1); - writer.StartObject(); - // ... - writer.EndObject(); - - writer.Reset(os2); - writer.StartObject(); - // ... - writer.EndObject(); - \endcode - */ - void Reset(OutputStream& os) { - os_ = &os; - hasRoot_ = false; - level_stack_.Clear(); - } - - //! Checks whether the output is a complete JSON. - /*! - A complete JSON has a complete root object or array. - */ - bool IsComplete() const { - return hasRoot_ && level_stack_.Empty(); - } - - int GetMaxDecimalPlaces() const { - return maxDecimalPlaces_; - } - - //! Sets the maximum number of decimal places for double output. - /*! - This setting truncates the output with specified number of decimal places. - - For example, - - \code - writer.SetMaxDecimalPlaces(3); - writer.StartArray(); - writer.Double(0.12345); // "0.123" - writer.Double(0.0001); // "0.0" - writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) - writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) - writer.EndArray(); - \endcode - - The default setting does not truncate any decimal places. You can restore to this setting by calling - \code - writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); - \endcode - */ - void SetMaxDecimalPlaces(int maxDecimalPlaces) { - maxDecimalPlaces_ = maxDecimalPlaces; - } - - /*!@name Implementation of Handler - \see Handler - */ - //@{ - - bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } - bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } - bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } - bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } - bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } - bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } - - //! Writes the given \c double value to the stream - /*! - \param d The value to be written. - \return Whether it is succeed. - */ - bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } - - bool RawNumber(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kNumberType); - return EndValue(WriteString(str, length)); - } - - bool String(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kStringType); - return EndValue(WriteString(str, length)); - } - -#if RAPIDJSON_HAS_STDSTRING - bool String(const std::basic_string<Ch>& str) { - return String(str.data(), SizeType(str.size())); - } -#endif - - bool StartObject() { - Prefix(kObjectType); - new (level_stack_.template Push<Level>()) Level(false); - return WriteStartObject(); - } - - bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } - -#if RAPIDJSON_HAS_STDSTRING - bool Key(const std::basic_string<Ch>& str) - { - return Key(str.data(), SizeType(str.size())); - } -#endif - - bool EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object - RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object - RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value - level_stack_.template Pop<Level>(1); - return EndValue(WriteEndObject()); - } - - bool StartArray() { - Prefix(kArrayType); - new (level_stack_.template Push<Level>()) Level(true); - return WriteStartArray(); - } - - bool EndArray(SizeType elementCount = 0) { - (void)elementCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray); - level_stack_.template Pop<Level>(1); - return EndValue(WriteEndArray()); - } - //@} - - /*! @name Convenience extensions */ - //@{ - - //! Simpler but slower overload. - bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); } - bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); } - - //@} - - //! Write a raw JSON value. - /*! - For user to write a stringified JSON as a value. - - \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. - \param length Length of the json. - \param type Type of the root of json. - */ - bool RawValue(const Ch* json, size_t length, Type type) { - RAPIDJSON_ASSERT(json != 0); - Prefix(type); - return EndValue(WriteRawValue(json, length)); - } - - //! Flush the output stream. - /*! - Allows the user to flush the output stream immediately. - */ - void Flush() { - os_->Flush(); - } - -protected: - //! Information for each nested level - struct Level { - Level(bool inArray_) : valueCount(0), inArray(inArray_) {} - size_t valueCount; //!< number of values in this level - bool inArray; //!< true if in array, otherwise in object - }; - - static const size_t kDefaultLevelDepth = 32; - - bool WriteNull() { - PutReserve(*os_, 4); - PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; - } - - bool WriteBool(bool b) { - if (b) { - PutReserve(*os_, 4); - PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); - } - else { - PutReserve(*os_, 5); - PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); - } - return true; - } - - bool WriteInt(int i) { - char buffer[11]; - const char* end = internal::i32toa(i, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p)); - return true; - } - - bool WriteUint(unsigned u) { - char buffer[10]; - const char* end = internal::u32toa(u, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p)); - return true; - } - - bool WriteInt64(int64_t i64) { - char buffer[21]; - const char* end = internal::i64toa(i64, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p)); - return true; - } - - bool WriteUint64(uint64_t u64) { - char buffer[20]; - char* end = internal::u64toa(u64, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p)); - return true; - } - - bool WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - if (!(writeFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char buffer[25]; - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p)); - return true; - } - - bool WriteString(const Ch* str, SizeType length) { - static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - static const char escape[256] = { -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 - 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - Z16, Z16, // 30~4F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF -#undef Z16 - }; - - if (TargetEncoding::supportUnicode) - PutReserve(*os_, 2 + length * 6); // "\uxxxx..." - else - PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." - - PutUnsafe(*os_, '\"'); - GenericStringStream<SourceEncoding> is(str); - while (ScanWriteUnescapedString(is, length)) { - const Ch c = is.Peek(); - if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) { - // Unicode escaping - unsigned codepoint; - if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) - return false; - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { - PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); - } - else { - RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); - // Surrogate pair - unsigned s = codepoint - 0x010000; - unsigned lead = (s >> 10) + 0xD800; - unsigned trail = (s & 0x3FF) + 0xDC00; - PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(lead ) & 15]); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(trail ) & 15]); - } - } - else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) { - is.Take(); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(escape[static_cast<unsigned char>(c)])); - if (escape[static_cast<unsigned char>(c)] == 'u') { - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]); - PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]); - } - } - else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? - Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) : - Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_)))) - return false; - } - PutUnsafe(*os_, '\"'); - return true; - } - - bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) { - return RAPIDJSON_LIKELY(is.Tell() < length); - } - - bool WriteStartObject() { os_->Put('{'); return true; } - bool WriteEndObject() { os_->Put('}'); return true; } - bool WriteStartArray() { os_->Put('['); return true; } - bool WriteEndArray() { os_->Put(']'); return true; } - - bool WriteRawValue(const Ch* json, size_t length) { - PutReserve(*os_, length); - for (size_t i = 0; i < length; i++) { - RAPIDJSON_ASSERT(json[i] != '\0'); - PutUnsafe(*os_, json[i]); - } - return true; - } - - void Prefix(Type type) { - (void)type; - if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root - Level* level = level_stack_.template Top<Level>(); - if (level->valueCount > 0) { - if (level->inArray) - os_->Put(','); // add comma if it is not the first element in array - else // in object - os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else { - RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. - hasRoot_ = true; - } - } - - // Flush the value if it is the top level one. - bool EndValue(bool ret) { - if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text - Flush(); - return ret; - } - - OutputStream* os_; - internal::Stack<StackAllocator> level_stack_; - int maxDecimalPlaces_; - bool hasRoot_; - -private: - // Prohibit copy constructor & assignment operator. - Writer(const Writer&); - Writer& operator=(const Writer&); -}; - -// Full specialization for StringStream to prevent memory copying - -template<> -inline bool Writer<StringBuffer>::WriteInt(int i) { - char *buffer = os_->Push(11); - const char* end = internal::i32toa(i, buffer); - os_->Pop(static_cast<size_t>(11 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteUint(unsigned u) { - char *buffer = os_->Push(10); - const char* end = internal::u32toa(u, buffer); - os_->Pop(static_cast<size_t>(10 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) { - char *buffer = os_->Push(21); - const char* end = internal::i64toa(i64, buffer); - os_->Pop(static_cast<size_t>(21 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) { - char *buffer = os_->Push(20); - const char* end = internal::u64toa(u, buffer); - os_->Pop(static_cast<size_t>(20 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). - if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char *buffer = os_->Push(25); - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - os_->Pop(static_cast<size_t>(25 - (end - buffer))); - return true; -} - -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) -template<> -inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) { - if (length < 16) - return RAPIDJSON_LIKELY(is.Tell() < length); - - if (!RAPIDJSON_LIKELY(is.Tell() < length)) - return false; - - const char* p = is.src_; - const char* end = is.head_ + length; - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15)); - if (nextAligned > end) - return true; - - while (p != nextAligned) - if (*p < 0x20 || *p == '\"' || *p == '\\') { - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); - } - else - os_->PutUnsafe(*p++); - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); - - for (; p != endAligned; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - SizeType len; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - len = offset; -#else - len = static_cast<SizeType>(__builtin_ffs(r) - 1); -#endif - char* q = reinterpret_cast<char*>(os_->PushUnsafe(len)); - for (size_t i = 0; i < len; i++) - q[i] = p[i]; - - p += len; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); - } - - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); -} -#elif defined(RAPIDJSON_NEON) -template<> -inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) { - if (length < 16) - return RAPIDJSON_LIKELY(is.Tell() < length); - - if (!RAPIDJSON_LIKELY(is.Tell() < length)) - return false; - - const char* p = is.src_; - const char* end = is.head_ + length; - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15)); - if (nextAligned > end) - return true; - - while (p != nextAligned) - if (*p < 0x20 || *p == '\"' || *p == '\\') { - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); - } - else - os_->PutUnsafe(*p++); - - // The rest of string using SIMD - const uint8x16_t s0 = vmovq_n_u8('"'); - const uint8x16_t s1 = vmovq_n_u8('\\'); - const uint8x16_t s2 = vmovq_n_u8('\b'); - const uint8x16_t s3 = vmovq_n_u8(32); - - for (; p != endAligned; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p)); - uint8x16_t x = vceqq_u8(s, s0); - x = vorrq_u8(x, vceqq_u8(s, s1)); - x = vorrq_u8(x, vceqq_u8(s, s2)); - x = vorrq_u8(x, vcltq_u8(s, s3)); - - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract - uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract - - SizeType len = 0; - bool escaped = false; - if (low == 0) { - if (high != 0) { - unsigned lz = (unsigned)__builtin_clzll(high); - len = 8 + (lz >> 3); - escaped = true; - } - } else { - unsigned lz = (unsigned)__builtin_clzll(low); - len = lz >> 3; - escaped = true; - } - if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped - char* q = reinterpret_cast<char*>(os_->PushUnsafe(len)); - for (size_t i = 0; i < len; i++) - q[i] = p[i]; - - p += len; - break; - } - vst1q_u8(reinterpret_cast<uint8_t *>(os_->PushUnsafe(16)), s); - } - - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); -} -#endif // RAPIDJSON_NEON - -RAPIDJSON_NAMESPACE_END - -#ifdef _MSC_VER -RAPIDJSON_DIAG_POP -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson.c ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson.c b/weex_core/Source/wson/wson.c new file mode 100644 index 0000000..f0e7f67 --- /dev/null +++ b/weex_core/Source/wson/wson.c @@ -0,0 +1,345 @@ +// +// Created by furture on 2017/8/4. +// + +#include "wson.h" +#include <stdio.h> + + +union double_number{ + double d; + uint64_t l; + int64_t i64; +}; + +union float_number{ + float f; + uint32_t i; +}; + +#define WSON_BUFFER_SIZE 1024 + +#define WSON_BUFFER_ENSURE_SIZE(size) {if((buffer->length) < (buffer->position + size)){\ + msg_buffer_resize(buffer, size);\ + }} + +static inline void msg_buffer_resize(wson_buffer* buffer, uint32_t size){ + if(size < buffer->length){ + if(buffer->length < 1024*16){ + size = 1024*16; + }else{ + size = buffer->length; + } + }else{ + size +=WSON_BUFFER_SIZE; + } + size += buffer->length; + buffer->data = realloc(buffer->data, size); + buffer->length = size; +} + + +static inline int32_t msg_buffer_varint_Zag(uint32_t ziggedValue) +{ + int32_t value = (int32_t)ziggedValue; + return (-(value & 0x01)) ^ ((value >> 1) & ~( 1<< 31)); +} + +static inline uint32_t msg_buffer_varint_Zig(int32_t value) +{ + return (uint32_t)((value << 1) ^ (value >> 31)); + +} + + wson_buffer* wson_buffer_new(void){ + wson_buffer* ptr = malloc(sizeof(wson_buffer)); + ptr->data = malloc(sizeof(int8_t)*WSON_BUFFER_SIZE); + ptr->position = 0; + ptr->length = WSON_BUFFER_SIZE; + return ptr; +} + +wson_buffer* wson_buffer_from(void* data, uint32_t length){ + wson_buffer* ptr = malloc(sizeof(wson_buffer)); + ptr->data = data; + ptr->position = 0; + ptr->length = length; + return ptr; +} + + +inline void wson_buffer_require(wson_buffer *buffer, size_t size){ + WSON_BUFFER_ENSURE_SIZE(size*sizeof(uint8_t)); +} + + +inline void wson_push_int(wson_buffer *buffer, int32_t value){ + uint32_t num = msg_buffer_varint_Zig(value); + wson_push_uint(buffer, num); +} + +inline void wson_push_uint(wson_buffer *buffer, uint32_t num){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint32_t) + sizeof(uint8_t)); + uint8_t * data = ((uint8_t*)buffer->data + buffer->position); + int size =0; + do{ + data[size] = (uint8_t)((num & 0x7F) | 0x80); + size++; + }while((num >>= 7) != 0); + data[size - 1] &=0x7F; + buffer->position += size; +} + +inline void wson_push_byte(wson_buffer *buffer, uint8_t bt){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = bt; + buffer->position += sizeof(uint8_t); +} + +inline void wson_push_type(wson_buffer *buffer, uint8_t bt){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = bt; + buffer->position += sizeof(uint8_t); +} + + +inline void wson_push_type_boolean(wson_buffer *buffer, uint8_t value){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t) + sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + if(value){ + *data = WSON_BOOLEAN_TYPE_TRUE; + }else{ + *data = WSON_BOOLEAN_TYPE_FALSE; + } + buffer->position += sizeof(uint8_t); + } + + +inline void wson_push_type_int(wson_buffer *buffer, int32_t num){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_NUMBER_INT_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_int(buffer, num); +} + +inline void wson_push_type_double(wson_buffer *buffer, double num){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_NUMBER_DOUBLE_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_double(buffer, num); +} + +inline void wson_push_type_long(wson_buffer *buffer, int64_t num){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_NUMBER_LONG_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_ulong(buffer, num); +} + +inline void wson_push_type_string(wson_buffer *buffer, const void *src, int32_t length){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_STRING_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_uint(buffer, length); + wson_push_bytes(buffer, src, length); +} + +inline void wson_push_property(wson_buffer *buffer, const void *src, int32_t length){ + wson_push_uint(buffer, length); + wson_push_bytes(buffer, src, length); +} + +inline void wson_push_type_string_length(wson_buffer *buffer, int32_t length){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_STRING_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_uint(buffer, length); +} + +inline void wson_push_type_null(wson_buffer *buffer){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_NULL_TYPE; + buffer->position += (sizeof(uint8_t)); +} + +inline void wson_push_type_map(wson_buffer *buffer, uint32_t size){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_MAP_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_uint(buffer, size); +} + +inline void wson_push_type_array(wson_buffer *buffer, uint32_t size){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_ARRAY_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_uint(buffer, size); +} + + +inline void wson_push_type_extend(wson_buffer *buffer, const void *src, int32_t length){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + *data = WSON_EXTEND_TYPE; + buffer->position += (sizeof(uint8_t)); + wson_push_uint(buffer, length); + wson_push_bytes(buffer, src, length); +} + +inline void wson_push_ensure_size(wson_buffer *buffer, uint32_t dataSize){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint8_t)*dataSize); +} + +inline void wson_push_ulong(wson_buffer *buffer, uint64_t num){ + WSON_BUFFER_ENSURE_SIZE(sizeof(uint64_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + data[7] = (uint8_t)(num & 0xFF); + data[6] = (uint8_t)((num >> 8) & 0xFF); + data[5] = (uint8_t)((num >> 16) & 0xFF); + data[4] = (uint8_t)((num >> 24) & 0xFF); + data[3] = (uint8_t)((num >> 32) & 0xFF); + data[2] = (uint8_t)((num >> 40) & 0xFF); + data[1] = (uint8_t)((num >> 48) & 0xFF); + data[0] = (uint8_t)((num >> 56) & 0xFF); + buffer->position += sizeof(uint64_t); +} + +void wson_push_double(wson_buffer *buffer, double num){ + union double_number ld; + ld.d = num; + wson_push_ulong(buffer, ld.l); +} + +void wson_push_float(wson_buffer *buffer, float f){ + union float_number fn; + fn.f = f; + uint32_t num = fn.i; + WSON_BUFFER_ENSURE_SIZE(sizeof(uint32_t)); + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + data[3] = (uint8_t)(num & 0xFF); + data[2] = (uint8_t)((num >> 8) & 0xFF); + data[1] = (uint8_t)((num >> 16) & 0xFF); + data[0] = (uint8_t)((num >> 24) & 0xFF); + buffer->position += sizeof(uint32_t); +} + + +inline void wson_push_bytes(wson_buffer *buffer, const void *src, int32_t length){ + WSON_BUFFER_ENSURE_SIZE(length); + void* dst = ((uint8_t*)buffer->data + buffer->position); + memcpy(dst, src, length); + buffer->position += length; +} + +inline int8_t wson_next_type(wson_buffer *buffer){ + int8_t* ptr = (int8_t*)((uint8_t*)buffer->data + buffer->position); + buffer->position += sizeof(int8_t); + return *ptr; +} + +inline int8_t wson_next_byte(wson_buffer *buffer){ + int8_t* ptr = (int8_t*)(((uint8_t*)buffer->data + buffer->position)); + buffer->position += sizeof(int8_t); + return *ptr; +} + + +int32_t wson_next_int(wson_buffer *buffer){ + return msg_buffer_varint_Zag(wson_next_uint(buffer)); +} + +uint32_t wson_next_uint(wson_buffer *buffer){ + uint8_t * ptr = ((uint8_t*)buffer->data + buffer->position); + uint32_t num = *ptr; + if((num & 0x80) == 0){ + buffer->position +=1; + return num; + } + num &=0x7F; + uint8_t chunk = ptr[1]; + num |= (chunk & 0x7F) << 7; + if((chunk & 0x80) == 0){ + buffer->position += 2; + return num; + } + chunk = ptr[2]; + num |= (chunk & 0x7F) << 14; + if((chunk & 0x80) == 0){ + buffer->position += 3; + return num; + } + + chunk = ptr[3]; + num |= (chunk & 0x7F) << 21; + if((chunk & 0x80) == 0){ + buffer->position += 4; + return num; + } + chunk = ptr[4]; + num |= (chunk & 0x0F) << 28; + buffer->position += 5; + return num; +} + +int64_t wson_next_long(wson_buffer *buffer){ + return wson_next_ulong(buffer); +} + +inline uint64_t wson_next_ulong(wson_buffer *buffer){ + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + buffer->position += sizeof(uint64_t); + return (((uint64_t)data[7]) & 0xFF) + + ((((uint64_t)data[6]) & 0xFF) << 8) + + ((((uint64_t)data[5]) & 0xFF) << 16) + + ((((uint64_t)data[4]) & 0xFF) << 24) + + ((((uint64_t)data[3]) & 0xFF) << 32) + + ((((uint64_t)data[2]) & 0xFF) << 40) + + ((((uint64_t)data[1]) & 0xFF) << 48) + + ((((uint64_t)data[0]) & 0xFF) << 56); +} + +double wson_next_double(wson_buffer *buffer){ + union double_number ld; + ld.l = wson_next_long(buffer); + return ld.d; +} + +inline float wson_next_float(wson_buffer *buffer){ + union float_number fn; + uint8_t* data = ((uint8_t*)buffer->data + buffer->position); + fn.i = ((data[3]) & 0xFF) + + (((data[2]) & 0xFF) << 8) + + (((data[1]) & 0xFF) << 16) + + (((data[0]) & 0xFF) << 24); + buffer->position += sizeof(uint32_t); + return fn.f; +} + + +inline uint8_t* wson_next_bts(wson_buffer *buffer, uint32_t length){ + uint8_t * ptr = ((uint8_t*)buffer->data + buffer->position); + buffer->position += length; + return ptr; +} + +void wson_buffer_free(wson_buffer *buffer){ + if(buffer->data){ + free(buffer->data); + buffer->data = NULL; + } + if(buffer){ + free(buffer); + buffer = NULL; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson.h b/weex_core/Source/wson/wson.h new file mode 100644 index 0000000..446c345 --- /dev/null +++ b/weex_core/Source/wson/wson.h @@ -0,0 +1,127 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +// +// Created by furture on 2017/8/4. +// + +#ifndef WSON_H +#define WSON_H + +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct wson_buffer{ + void* data; + uint32_t position; + uint32_t length; +} wson_buffer; + + + + +/** + * wson data type + * */ +#define WSON_NULL_TYPE '0' +#define WSON_STRING_TYPE 's' +#define WSON_BOOLEAN_TYPE_TRUE 't' +#define WSON_BOOLEAN_TYPE_FALSE 'f' +#define WSON_NUMBER_INT_TYPE 'i' +#define WSON_NUMBER_FLOAT_TYPE 'F' +#define WSON_NUMBER_DOUBLE_TYPE 'd' +#define WSON_NUMBER_LONG_TYPE 'l' +#define WSON_NUMBER_BIG_INT_TYPE 'g' +#define WSON_NUMBER_BIG_DECIMAL_TYPE 'e' +#define WSON_ARRAY_TYPE '[' +#define WSON_MAP_TYPE '{' +#define WSON_EXTEND_TYPE 'b' + +/** + * create wson buffer + * */ +wson_buffer* wson_buffer_new(void); + +void wson_buffer_require(wson_buffer *buffer, size_t size); +/** + * push value with type signature; 1 true, 0 false, with type WSON_BOOLEAN_TYPE + * signature + byte + */ +void wson_push_type_boolean(wson_buffer *buffer, uint8_t value); +void wson_push_type_int(wson_buffer *buffer, int32_t num); +void wson_push_type_long(wson_buffer *buffer, int64_t num); +void wson_push_type_double(wson_buffer *buffer, double num); +void wson_push_type_string(wson_buffer *buffer, const void *src, int32_t length); +void wson_push_type_null(wson_buffer *buffer); +void wson_push_type_map(wson_buffer *buffer, uint32_t size); +void wson_push_type_array(wson_buffer *buffer, uint32_t size); +void wson_push_type_extend(wson_buffer *buffer, const void *src, int32_t length); +void wson_push_ensure_size(wson_buffer *buffer, uint32_t dataSize); +void wson_push_type_string_length(wson_buffer *buffer, int32_t length); +void wson_push_property(wson_buffer *buffer, const void *src, int32_t length); + +/** + * push int, varint uint byte int double bts to buffer, without type signature + * */ +void wson_push_int(wson_buffer *buffer, int32_t num); +void wson_push_uint(wson_buffer *buffer, uint32_t num); +void wson_push_byte(wson_buffer *buffer, uint8_t bt); +void wson_push_type(wson_buffer *buffer, uint8_t bt); +void wson_push_double(wson_buffer *buffer, double num); +void wson_push_float(wson_buffer *buffer, float num); +void wson_push_ulong(wson_buffer *buffer, uint64_t num); +void wson_push_bytes(wson_buffer *buffer, const void *src, int32_t length); + + +/** + * free buffer + * */ +void wson_buffer_free(wson_buffer *buffer); + + +/** + * parse buffer, return data from current position not include signature + * */ +int8_t wson_next_byte(wson_buffer *buffer); +int8_t wson_next_type(wson_buffer *buffer); +int32_t wson_next_int(wson_buffer *buffer); +uint32_t wson_next_uint(wson_buffer *buffer); +double wson_next_double(wson_buffer *buffer); +float wson_next_float(wson_buffer *buffer); +int64_t wson_next_long(wson_buffer *buffer); +uint64_t wson_next_ulong(wson_buffer *buffer); +uint8_t* wson_next_bts(wson_buffer *buffer, uint32_t length); +inline bool wson_has_next(wson_buffer *buffer){ + return buffer->position < buffer->length; +} + +/** constructor with data */ +wson_buffer* wson_buffer_from(void* data, uint32_t length); + +#ifdef __cplusplus +} +#endif + +#endif //WSON_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson_parser.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson_parser.cpp b/weex_core/Source/wson/wson_parser.cpp new file mode 100644 index 0000000..7e1c7f2 --- /dev/null +++ b/weex_core/Source/wson/wson_parser.cpp @@ -0,0 +1,306 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +// +// Created by furture on 2018/5/15. +// + +#include "wson_parser.h" +#include "wson.h" +#include "wson_util.h" + +wson_parser::wson_parser(const char *data) { + + this->wsonBuffer = wson_buffer_from((void *) data, 1024*1024); +} + +wson_parser::wson_parser(const char *data, int length) { + this->wsonBuffer = wson_buffer_from((void *) data, length); +} + +wson_parser::~wson_parser() { + if(wsonBuffer){ + wsonBuffer->data = nullptr; + free(wsonBuffer); + wsonBuffer = NULL; + } + if(decodingBuffer != nullptr && decodingBufferSize > 0){ + delete [] decodingBuffer; + decodingBuffer = nullptr; + } +} + +std::string wson_parser::nextMapKeyUTF8(){ + int keyLength = wson_next_uint(wsonBuffer); + uint16_t * utf16 = ( uint16_t *)wson_next_bts(wsonBuffer, keyLength); + std::string str; + wson::utf16_convert_to_utf8_string(utf16, keyLength/sizeof(uint16_t), requireDecodingBuffer(keyLength*2), str); + return str; +} + + + +char* wson_parser::requireDecodingBuffer(int length){ + if(decodingBufferSize <= 0 || decodingBufferSize < length){ + if(decodingBuffer != nullptr && decodingBufferSize > 0){ + delete [] decodingBuffer; + decodingBuffer = nullptr; + } + decodingBuffer = new char[length]; + decodingBufferSize = length; + }else{ + return decodingBuffer; + } + return decodingBuffer; +} + + +void wson_parser::toJSONtring(std::string &builder){ + uint8_t type = wson_next_type(wsonBuffer); + switch (type) { + case WSON_STRING_TYPE: + case WSON_NUMBER_BIG_INT_TYPE: + case WSON_NUMBER_BIG_DECIMAL_TYPE: { + int size = wson_next_uint(wsonBuffer); + uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); + wson::utf16_convert_to_utf8_quote_string(utf16, size / sizeof(uint16_t), requireDecodingBuffer(size*2), builder); + } + return; + case WSON_NULL_TYPE: + builder.append("\"\""); + break; + case WSON_NUMBER_INT_TYPE: { + int32_t num = wson_next_int(wsonBuffer); + wson::str_append_number(builder, num); + } + return; + case WSON_NUMBER_FLOAT_TYPE: { + float num = wson_next_float(wsonBuffer); + wson::str_append_number(builder, num); + } + return; + case WSON_NUMBER_DOUBLE_TYPE: { + double num = wson_next_double(wsonBuffer); + wson::str_append_number(builder, num); + } + return; + case WSON_NUMBER_LONG_TYPE: { + int64_t num = wson_next_long(wsonBuffer); + wson::str_append_number(builder, num); + } + return; + case WSON_BOOLEAN_TYPE_TRUE: + builder.append("true"); + return; + case WSON_BOOLEAN_TYPE_FALSE: + builder.append("false"); + return; + case WSON_MAP_TYPE:{ + int length = wson_next_uint(wsonBuffer); + builder.append("{"); + for(int i=0; i<length; i++){ + int keyLength = wson_next_uint(wsonBuffer); + uint16_t * utf16 = ( uint16_t *)wson_next_bts(wsonBuffer, keyLength); + wson::utf16_convert_to_utf8_quote_string(utf16, keyLength/sizeof(uint16_t), requireDecodingBuffer(keyLength*2), builder); + builder.append(":"); + toJSONtring(builder); + if(i != (length - 1)){ + builder.append(","); + } + } + builder.append("}"); + } + return; + case WSON_ARRAY_TYPE:{ + builder.append("["); + int length = wson_next_uint(wsonBuffer); + for(int i=0; i<length; i++){ + toJSONtring(builder); + if(i != (length - 1)){ + builder.append(","); + } + } + builder.append("]"); + } + return; + default: + break; + } +} + +std::string wson_parser::nextStringUTF8(uint8_t type) { + std::string str; + switch (type) { + case WSON_STRING_TYPE: + case WSON_NUMBER_BIG_INT_TYPE: + case WSON_NUMBER_BIG_DECIMAL_TYPE: { + int size = wson_next_uint(wsonBuffer); + uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); + wson::utf16_convert_to_utf8_string(utf16, size / sizeof(uint16_t), requireDecodingBuffer(size*2), str); + return str; + } + case WSON_NULL_TYPE: + str.append(""); + break; + case WSON_NUMBER_INT_TYPE: { + int32_t num = wson_next_int(wsonBuffer);; + wson::str_append_number(str, num); + } + return str; + case WSON_NUMBER_FLOAT_TYPE: { + float num = wson_next_float(wsonBuffer); + wson::str_append_number(str, num); + } + return str; + case WSON_NUMBER_DOUBLE_TYPE: { + double num = wson_next_double(wsonBuffer); + wson::str_append_number(str, num); + } + return str; + case WSON_NUMBER_LONG_TYPE: { + int64_t num = wson_next_long(wsonBuffer); + wson::str_append_number(str, num); + } + return str; + case WSON_BOOLEAN_TYPE_TRUE: + str.append("true"); + return str; + case WSON_BOOLEAN_TYPE_FALSE: + str.append("false"); + return str; + case WSON_MAP_TYPE: + case WSON_ARRAY_TYPE: + wsonBuffer->position--; + toJSONtring(str); + default: + break; + } + return str; +} + +double wson_parser::nextNumber(uint8_t type) { + switch (type) { + case WSON_STRING_TYPE: + case WSON_NUMBER_BIG_INT_TYPE: + case WSON_NUMBER_BIG_DECIMAL_TYPE: { + int size = wson_next_uint(wsonBuffer); + std::string str; + wson_next_bts(wsonBuffer, size); + uint16_t *utf16 = (uint16_t *) wson_next_bts(wsonBuffer, size); + wson::utf16_convert_to_utf8_string(utf16, size/sizeof(uint16_t), requireDecodingBuffer(size*2),str); + return atof(str.c_str()); + } + case WSON_NULL_TYPE: + return 0; + case WSON_NUMBER_INT_TYPE:{ + int32_t num = wson_next_int(wsonBuffer); + return num; + } + break; + case WSON_NUMBER_FLOAT_TYPE:{ + float num = wson_next_float(wsonBuffer); + return num; + } + break; + case WSON_NUMBER_DOUBLE_TYPE:{ + double num = wson_next_double(wsonBuffer); + return num; + } + break; + case WSON_NUMBER_LONG_TYPE:{ + int64_t num = wson_next_long(wsonBuffer); + return num; + } + break; + case WSON_BOOLEAN_TYPE_TRUE: + return 1; + case WSON_BOOLEAN_TYPE_FALSE: + return 0; + case WSON_MAP_TYPE: + case WSON_ARRAY_TYPE: + default: + break; + } + skipValue(type); + return 0; +} + +bool wson_parser::nextBool(uint8_t type) { + if(type == WSON_BOOLEAN_TYPE_FALSE || type == WSON_NULL_TYPE){ + return false; + } + skipValue(type); + return true; +} + +void wson_parser::skipValue(uint8_t type) { + switch (type) { + case WSON_STRING_TYPE: + case WSON_NUMBER_BIG_INT_TYPE: + case WSON_NUMBER_BIG_DECIMAL_TYPE: { + int size = wson_next_uint(wsonBuffer); + wson_next_bts(wsonBuffer, size); + return; + } + case WSON_NULL_TYPE: + break; + case WSON_NUMBER_INT_TYPE: + wson_next_int(wsonBuffer); + return; + case WSON_NUMBER_FLOAT_TYPE: + wson_next_float(wsonBuffer); + return; + case WSON_NUMBER_DOUBLE_TYPE: + wson_next_double(wsonBuffer); + return; + case WSON_NUMBER_LONG_TYPE: + wson_next_long(wsonBuffer); + return; + case WSON_BOOLEAN_TYPE_TRUE: + return; + case WSON_BOOLEAN_TYPE_FALSE: + return; + case WSON_MAP_TYPE:{ + int length = wson_next_uint(wsonBuffer); + for(int i=0; i<length; i++){ + int keyLength = wson_next_uint(wsonBuffer); + wson_next_bts(wsonBuffer, keyLength); + skipValue(wson_next_type(wsonBuffer)); + } + } + return; + case WSON_ARRAY_TYPE:{ + int length = wson_next_uint(wsonBuffer); + for(int i=0; i<length; i++){ + skipValue(wson_next_type(wsonBuffer)); + } + } + return; + default: + break; + } +} + + +std::string wson_parser::toStringUTF8() { + int position = this->wsonBuffer->position; + this->wsonBuffer->position = 0; + std::string json = nextStringUTF8(nextType()); + this->wsonBuffer->position = position; + return json; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson_parser.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson_parser.h b/weex_core/Source/wson/wson_parser.h new file mode 100644 index 0000000..98d34ce --- /dev/null +++ b/weex_core/Source/wson/wson_parser.h @@ -0,0 +1,194 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/** + * c++ friendly interface for wson + * */ +// +// Created by furture on 2018/5/15. +// + +#ifndef WSON_PARSER_H +#define WSON_PARSER_H + +#include "wson.h" + +#include <vector> +#include <string> + +typedef std::basic_string<uint16_t, std::char_traits<uint16_t>, std::allocator<uint16_t> > u16string; + +/** utf16 support which is so fast and cross javascriptcore java and c plus*/ +class wson_parser { + +public: + wson_parser(const char* data); + wson_parser(const char* data, int length); + ~wson_parser(); + + /** + * has next type + * */ + inline bool hasNext(){ + return wson_has_next(this->wsonBuffer); + } + + /** + * return value type + * */ + inline uint8_t nextType(){ + if(wsonBuffer->data && wson_has_next(wsonBuffer)){ + return wson_next_type(wsonBuffer); + } + return WSON_NULL_TYPE; + } + + /** + * return back type, move parse postion--; + * */ + inline void backType(){ + if(wsonBuffer && wsonBuffer->position > 0){ + wsonBuffer->position--; + } + } + + /** + * return is map object + * */ + inline bool isMap(uint8_t type){ + return type == WSON_MAP_TYPE; + } + + /** + * return is array object + * */ + inline bool isArray(uint8_t type){ + return type == WSON_ARRAY_TYPE; + } + + /** + * return is string object + * */ + inline bool isString(uint8_t type){ + return type == WSON_STRING_TYPE + || type == WSON_NUMBER_BIG_INT_TYPE + || type == WSON_NUMBER_BIG_DECIMAL_TYPE; + } + + /** + * return is bool object + * */ + inline bool isBool(uint8_t type){ + return type == WSON_BOOLEAN_TYPE_FALSE || type == WSON_BOOLEAN_TYPE_TRUE; + } + + /** + * return is number object + * */ + inline bool isNumber(uint8_t type){ + return type == WSON_NUMBER_INT_TYPE + || type == WSON_NUMBER_FLOAT_TYPE + || type == WSON_NUMBER_LONG_TYPE + || type == WSON_NUMBER_DOUBLE_TYPE; + } + + /** + * return is null object + * */ + inline bool isNull(uint8_t type){ + return type == WSON_NULL_TYPE; + } + + /** + * return map size + * */ + inline int nextMapSize(){ + return wson_next_uint(wsonBuffer); + } + + /** + * return array size + * */ + inline int nextArraySize(){ + return wson_next_uint(wsonBuffer); + } + + /** + * auto convert utf-16 string number to utf-8 string + * */ + std::string nextMapKeyUTF8(); + + /** + * auto convert object or number to string + * */ + std::string nextStringUTF8(uint8_t type); + + /** + * return number value, if type is string convert to number + * */ + double nextNumber(uint8_t type); + + /** return bool value */ + bool nextBool(uint8_t type); + + /** + * skip current value type + * */ + void skipValue(uint8_t type); + + + /** + * reset to start position + * */ + inline void resetState(){ + if(this->wsonBuffer){ + this->wsonBuffer->position = 0; + } + } + + /** + * get current state position + * */ + inline int getState(){ + return this->wsonBuffer->position; + } + + /**restore parse to state */ + inline int restoreToState(int state){ + return this->wsonBuffer->position = state; + } + + /** conver wson to json string */ + std::string toStringUTF8(); + + +private: + wson_buffer* wsonBuffer; + void toJSONtring(std::string &builder); + + /**reuse buffer for decoding */ + char *requireDecodingBuffer(int length); + char* decodingBuffer = nullptr; + int decodingBufferSize = 0; +}; + + + + +#endif //WEEX_PROJECT_WSON_PARSER_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson_util.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson_util.cpp b/weex_core/Source/wson/wson_util.cpp new file mode 100644 index 0000000..9713caa --- /dev/null +++ b/weex_core/Source/wson/wson_util.cpp @@ -0,0 +1,270 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +// +// Created by furture on 2018/5/15. +// + +#include "wson_util.h" +#include <stdio.h> + + +namespace wson { + + /** + * see java jdk source to handle handle utf-16 in 4 byte + * */ + static const u_int16_t MIN_HIGH_SURROGATE = 0xD800; + + static const u_int16_t MAX_HIGH_SURROGATE = 0xDBFF; + + static const u_int16_t MIN_LOW_SURROGATE = 0xDC00; + + static const u_int16_t MAX_LOW_SURROGATE = 0xDFFF; + + static const u_int32_t MIN_SUPPLEMENTARY_CODE_POINT = 0x010000; + + inline bool isHighSurrogate(u_int16_t ch) { + return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1); + } + + inline bool isLowSurrogate(u_int16_t ch) { + return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1); + } + + inline u_int32_t toCodePoint(u_int16_t high, u_int16_t low) { + // Optimized form of: + // return ((high - MIN_HIGH_SURROGATE) << 10) + // + (low - MIN_LOW_SURROGATE) + // + MIN_SUPPLEMENTARY_CODE_POINT; + return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT + - (MIN_HIGH_SURROGATE << 10) + - MIN_LOW_SURROGATE); + } + + + static inline int utf16_char_convert_to_utf8_cstr(u_int32_t codePoint, char* utf8){ + if (codePoint <= 0x7F) + { + // Plain single-byte ASCII. + utf8[0] = ((char)codePoint); + return 1; + } + else if (codePoint <= 0x7FF) + { + // Two bytes. + utf8[0] = (0xC0 | (codePoint >> 6)); + utf8[1] = (0x80 | ((codePoint) & 0x3F)); + return 2; + } + else if (codePoint <= 0xFFFF) + { + // Three bytes. + utf8[0] = (0xE0 | (codePoint >> 12)); + utf8[1] = ((0x80 | ((codePoint >> 6) & 0x3F))); + utf8[2] = ((0x80 | ((codePoint) & 0x3F))); + return 3; + } + else if (codePoint <= 0x1FFFFF) + { + // Four bytes. + utf8[0] = (0xF0 | (codePoint >> 18)); + utf8[1] = (0x80 | ((codePoint >> 12) & 0x3F)); + utf8[2] = (0x80 | ((codePoint >> 6) & 0x3F)); + utf8[3] = (0x80 | ((codePoint) & 0x3F)); + return 4; + } + else if (codePoint <= 0x3FFFFFF) + { + // Five bytes. + utf8[0] = (0xF8 | (codePoint >> 24)); + utf8[1] = (0x80 | ((codePoint >> 18) & 0x3F)); + utf8[2] = (0x80 | ((codePoint >> 12) & 0x3F)); + utf8[3] = (0x80 | ((codePoint >> 6) & 0x3F)); + utf8[4] = (0x80 | ((codePoint) & 0x3F)); + return 5; + } + else if (codePoint <= 0x7FFFFFFF) + { + // Six bytes. + utf8[0] = (0xFC | (codePoint >> 30)); + utf8[1] = (0x80 | ((codePoint >> 24) & 0x3F)); + utf8[2] = (0x80 | ((codePoint >> 18) & 0x3F)); + utf8[3] = (0x80 | ((codePoint >> 12) & 0x3F)); + utf8[4] = (0x80 | ((codePoint >> 6) & 0x3F)); + utf8[5] = (0x80 | ((codePoint) & 0x3F)); + return 6; + } + return 0; + } + + void utf16_convert_to_utf8_string(uint16_t * utf16, int length, std::string& utf8){ + char* dest = new char[length*4 + 4]; + utf16_convert_to_utf8_string(utf16, length, dest, utf8); + delete [] dest; + } + + void utf16_convert_to_utf8_quote_string(uint16_t *utf16, int length, std::string& utf8){ + char* dest = new char[length*4 + 4]; + utf16_convert_to_utf8_quote_string(utf16, length, dest, utf8); + delete [] dest; + } + + + void utf16_convert_to_utf8_string(uint16_t *utf16, int length, char* decodingBuffer, std::string& utf8){ + int count = utf16_convert_to_utf8_cstr(utf16, length, decodingBuffer); + utf8.append(decodingBuffer, count); + } + void utf16_convert_to_utf8_quote_string(uint16_t *utf16, int length, char* decodingBuffer, std::string& utf8){ + int count = utf16_convert_to_utf8_quote_cstr(utf16, length, decodingBuffer); + utf8.append(decodingBuffer, count); + } + + int utf16_convert_to_utf8_cstr(uint16_t * utf16, int length, char* buffer){ + char* src = buffer; + register int count =0; + for(int i=0; i<length;){ + u_int16_t c1 = utf16[i++]; + if(isHighSurrogate(c1)){ + i++; + if(i < length){ + u_int16_t c2 = utf16[i]; + if (isLowSurrogate(c2)) { + u_int32_t codePoint = toCodePoint(c1, c2); + count += utf16_char_convert_to_utf8_cstr(codePoint, src + count); + continue; + }else{ + i--; + } + } + } + count += utf16_char_convert_to_utf8_cstr(c1, src + count); + } + src[count] = '\0'; + return count; + } + + int utf16_convert_to_utf8_quote_cstr(uint16_t *utf16, int length, char* buffer){ + register int count =0; + + char* src = buffer; + src[count++] = '"'; + for(int i=0; i<length;){ + u_int16_t c1 = utf16[i++]; + if(isHighSurrogate(c1)){ + i++; + if(i < length){ + u_int16_t c2 = utf16[i]; + if (isLowSurrogate(c2)) { + u_int32_t codePoint = toCodePoint(c1, c2); + count += utf16_char_convert_to_utf8_cstr(codePoint, src + count); + continue; + }else{ + i--; + } + } + } + if(c1 < 0x5D){ // 0X5C is '\' + if(c1 == '"' || c1 == '\\'){ + src[count++] = '\\'; + }else{ + if(c1 <= 0x1F){ //max control latter + switch (c1){ + case '\t': + src[count++] = '\\'; + src[count++] = 't'; + continue; + case '\r': + src[count++] = '\\'; + src[count++] = 'r'; + continue; + case '\n': + src[count++] = '\\'; + src[count++] = 'n'; + continue; + case '\f': + src[count++] = '\\'; + src[count++] = 'f'; + continue; + case '\b': + src[count++] = '\\'; + src[count++] = 'b'; + continue; + } + } + } + } + count += utf16_char_convert_to_utf8_cstr(c1, src + count); + } + src[count++] = '"'; + src[count] = '\0'; + return count; + } + + + /** min size is 32 + 1 = 33 */ + inline void number_to_buffer(char* buffer, int32_t num){ + snprintf(buffer, 32,"%d", num); + } + + /** min size is 64 + 1 = 65 */ + inline void number_to_buffer(char* buffer, float num){ + snprintf(buffer, 64, "%f", num); + } + + /** min size is 64 + 1 = 65 */ + inline void number_to_buffer(char* buffer, double num){ + snprintf(buffer, 64, "%f", num); + } + + /** min size is 64 + 1 = 65 */ + inline void number_to_buffer(char* buffer, int64_t num){ + snprintf(buffer, 64, "%lld", num); + } + + + void str_append_number(std::string& str, double num){ + char src[64 + 2]; + char* buffer = src; + number_to_buffer(buffer, num); + str.append(src); + } + + void str_append_number(std::string& str, float num){ + char src[64 + 2]; + char* buffer = src; + number_to_buffer(buffer, num); + str.append(src); + } + + void str_append_number(std::string& str, int32_t num){ + char src[32 + 2]; + char* buffer = src; + number_to_buffer(buffer, num); + str.append(src); + } + + void str_append_number(std::string& str, int64_t num){ + char src[64 + 2]; + char* buffer = src; + number_to_buffer(buffer, num); + str.append(src); + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/Source/wson/wson_util.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/wson/wson_util.h b/weex_core/Source/wson/wson_util.h new file mode 100644 index 0000000..6ebd950 --- /dev/null +++ b/weex_core/Source/wson/wson_util.h @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +// +// Created by furture on 2018/5/15. +// + +#ifndef WSON_UTIL_H +#define WSON_UTIL_H + +#include <cstdint> +#include <string> + +namespace wson{ + + /** + * unicode to utf8 convertor with zero dependency inspired by java sdk character source + * */ + void utf16_convert_to_utf8_string(uint16_t *utf16, int length, char* decodingBuffer, std::string& utf8); + void utf16_convert_to_utf8_quote_string(uint16_t *utf16, int length, char* decodingBuffer, std::string& utf8); + + /** + * unicode to utf8 convertor with zero dependency inspired by java sdk character source + * */ + void utf16_convert_to_utf8_string(uint16_t *utf16, int length, std::string& utf8); + void utf16_convert_to_utf8_quote_string(uint16_t *utf16, int length, std::string& utf8); + /** + * return byte count in utf8, buffer size should can contains convert values + * */ + int utf16_convert_to_utf8_cstr(uint16_t *utf16, int length, char* buffer); + int utf16_convert_to_utf8_quote_cstr(uint16_t *utf16, int length, char* buffer); + + /** + * append support double float int32 int64 + * */ + void str_append_number(std::string& str, double num); + void str_append_number(std::string& str, float num); + void str_append_number(std::string& str, int32_t num); + void str_append_number(std::string& str, int64_t num); +} + + +#endif http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/debug.sh ---------------------------------------------------------------------- diff --git a/weex_core/debug.sh b/weex_core/debug.sh index c3b6c5f..1896fb7 100755 --- a/weex_core/debug.sh +++ b/weex_core/debug.sh @@ -1,2 +1,6 @@ -## show c plus plus crash stack -adb logcat | $NDK/ndk-stack -sym ../android/sdk/build/intermediates/cmake/debug/obj/armeabi-v7a +cd ../android/sdk +gradle compileDebugSources +cd .. +cp sdk/build/intermediates/cmake/debug/obj/armeabi/libweexjsc.so sdk/libs/armeabi/libweexjsc.so +cp sdk/build/intermediates/cmake/debug/obj/armeabi-v7a/libweexjsc.so sdk/libs/armeabi-v7a/libweexjsc.so +cp sdk/build/intermediates/cmake/debug/obj/x86/libweexjsc.so sdk/libs/x86/libweexjsc.so http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/release.sh ---------------------------------------------------------------------- diff --git a/weex_core/release.sh b/weex_core/release.sh new file mode 100644 index 0000000..3cbb4b3 --- /dev/null +++ b/weex_core/release.sh @@ -0,0 +1,6 @@ +cd ../android +rm -rf sdk/build/intermediates/bundles/release/jni/* +./gradlew clean assemble +cp sdk/build/intermediates/bundles/release/jni/armeabi/libweexjsc.so sdk/libs/armeabi/libweexjsc.so +cp sdk/build/intermediates/bundles/release/jni/armeabi-v7a/libweexjsc.so sdk/libs/armeabi-v7a/libweexjsc.so +cp sdk/build/intermediates/bundles/release/jni/x86/libweexjsc.so sdk/libs/x86/libweexjsc.so http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/50ae70ce/weex_core/trace.sh ---------------------------------------------------------------------- diff --git a/weex_core/trace.sh b/weex_core/trace.sh new file mode 100755 index 0000000..c3b6c5f --- /dev/null +++ b/weex_core/trace.sh @@ -0,0 +1,2 @@ +## show c plus plus crash stack +adb logcat | $NDK/ndk-stack -sym ../android/sdk/build/intermediates/cmake/debug/obj/armeabi-v7a
