Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / SharedBuffer.cpp
index ef29b83..253a4cb 100644 (file)
@@ -27,8 +27,6 @@
 #include "config.h"
 #include "platform/SharedBuffer.h"
 
-#include "platform/PurgeableBuffer.h"
-#include "wtf/PassOwnPtr.h"
 #include "wtf/unicode/Unicode.h"
 #include "wtf/unicode/UTF8.h"
 
@@ -39,9 +37,7 @@
 #include "wtf/MainThread.h"
 #endif
 
-using namespace std;
-
-namespace WebCore {
+namespace blink {
 
 static const unsigned segmentSize = 0x1000;
 static const unsigned segmentPositionMask = 0x0FFF;
@@ -143,6 +139,7 @@ static void willDestroySharedBuffer(SharedBuffer* buffer)
 
 SharedBuffer::SharedBuffer()
     : m_size(0)
+    , m_buffer(PurgeableVector::NotPurgeable)
 {
 #ifdef SHARED_BUFFER_STATS
     didCreateSharedBuffer(this);
@@ -151,8 +148,10 @@ SharedBuffer::SharedBuffer()
 
 SharedBuffer::SharedBuffer(size_t size)
     : m_size(size)
-    , m_buffer(size)
+    , m_buffer(PurgeableVector::NotPurgeable)
 {
+    m_buffer.reserveCapacity(size);
+    m_buffer.grow(size);
 #ifdef SHARED_BUFFER_STATS
     didCreateSharedBuffer(this);
 #endif
@@ -160,6 +159,7 @@ SharedBuffer::SharedBuffer(size_t size)
 
 SharedBuffer::SharedBuffer(const char* data, int size)
     : m_size(0)
+    , m_buffer(PurgeableVector::NotPurgeable)
 {
     // FIXME: Use unsigned consistently, and check for invalid casts when calling into SharedBuffer from other code.
     if (size < 0)
@@ -172,8 +172,20 @@ SharedBuffer::SharedBuffer(const char* data, int size)
 #endif
 }
 
+SharedBuffer::SharedBuffer(const char* data, unsigned size, PurgeableVector::PurgeableOption purgeable)
+    : m_size(0)
+    , m_buffer(purgeable)
+{
+    append(data, size);
+
+#ifdef SHARED_BUFFER_STATS
+    didCreateSharedBuffer(this);
+#endif
+}
+
 SharedBuffer::SharedBuffer(const unsigned char* data, int size)
     : m_size(0)
+    , m_buffer(PurgeableVector::NotPurgeable)
 {
     // FIXME: Use unsigned consistently, and check for invalid casts when calling into SharedBuffer from other code.
     if (size < 0)
@@ -198,74 +210,23 @@ SharedBuffer::~SharedBuffer()
 PassRefPtr<SharedBuffer> SharedBuffer::adoptVector(Vector<char>& vector)
 {
     RefPtr<SharedBuffer> buffer = create();
-    buffer->m_buffer.swap(vector);
+    buffer->m_buffer.adopt(vector);
     buffer->m_size = buffer->m_buffer.size();
     return buffer.release();
 }
 
-PassRefPtr<SharedBuffer> SharedBuffer::adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer> purgeableBuffer)
-{
-    ASSERT(!purgeableBuffer->isPurgeable());
-    RefPtr<SharedBuffer> buffer = create();
-    buffer->m_purgeableBuffer = purgeableBuffer;
-    return buffer.release();
-}
-
 unsigned SharedBuffer::size() const
 {
-    if (m_purgeableBuffer)
-        return m_purgeableBuffer->size();
-
     return m_size;
 }
 
-void SharedBuffer::createPurgeableBuffer() const
-{
-    if (m_purgeableBuffer)
-        return;
-
-    m_purgeableBuffer = PurgeableBuffer::create(buffer().data(), m_size);
-}
-
 const char* SharedBuffer::data() const
 {
-    if (m_purgeableBuffer)
-        return m_purgeableBuffer->data();
-
-    return this->buffer().data();
+    mergeSegmentsIntoBuffer();
+    return m_buffer.data();
 }
 
-void SharedBuffer::moveTo(Vector<char>& result)
-{
-    ASSERT(result.isEmpty());
-    if (m_purgeableBuffer) {
-        result.reserveCapacity(m_purgeableBuffer->size());
-        result.append(m_purgeableBuffer->data(), m_purgeableBuffer->size());
-        clear();
-        return;
-    }
-
-    unsigned bufferSize = m_buffer.size();
-    if (m_size == bufferSize) {
-        m_buffer.swap(result);
-        clear();
-        return;
-    }
-
-    result.reserveCapacity(m_size);
-
-    const char* segment = 0;
-    unsigned position = 0;
-    while (unsigned segmentSize = getSomeData(segment, position)) {
-        result.append(segment, segmentSize);
-        position += segmentSize;
-    }
-    ASSERT(result.size() == m_size);
-    clear();
-    return;
-}
-
-void SharedBuffer::append(SharedBuffer* data)
+void SharedBuffer::append(PassRefPtr<SharedBuffer> data)
 {
     const char* segment;
     size_t position = 0;
@@ -277,17 +238,16 @@ void SharedBuffer::append(SharedBuffer* data)
 
 void SharedBuffer::append(const char* data, unsigned length)
 {
-    ASSERT(!m_purgeableBuffer);
+    ASSERT(isLocked());
     if (!length)
         return;
 
+    ASSERT(m_size >= m_buffer.size());
     unsigned positionInSegment = offsetInSegment(m_size - m_buffer.size());
     m_size += length;
 
     if (m_size <= segmentSize) {
-        // No need to use segments for small resource data
-        if (m_buffer.isEmpty())
-            m_buffer.reserveInitialCapacity(length);
+        // No need to use segments for small resource data.
         m_buffer.append(data, length);
         return;
     }
@@ -300,7 +260,7 @@ void SharedBuffer::append(const char* data, unsigned length)
         segment = m_segments.last() + positionInSegment;
 
     unsigned segmentFreeSpace = segmentSize - positionInSegment;
-    unsigned bytesToCopy = min(length, segmentFreeSpace);
+    unsigned bytesToCopy = std::min(length, segmentFreeSpace);
 
     for (;;) {
         memcpy(segment, data, bytesToCopy);
@@ -311,7 +271,7 @@ void SharedBuffer::append(const char* data, unsigned length)
         data += bytesToCopy;
         segment = allocateSegment();
         m_segments.append(segment);
-        bytesToCopy = min(length, segmentSize);
+        bytesToCopy = std::min(length, segmentSize);
     }
 }
 
@@ -327,19 +287,12 @@ void SharedBuffer::clear()
 
     m_segments.clear();
     m_size = 0;
-
     m_buffer.clear();
-    m_purgeableBuffer.clear();
 }
 
 PassRefPtr<SharedBuffer> SharedBuffer::copy() const
 {
     RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
-    if (m_purgeableBuffer) {
-        clone->append(data(), size());
-        return clone.release();
-    }
-
     clone->m_size = m_size;
     clone->m_buffer.reserveCapacity(m_size);
     clone->m_buffer.append(m_buffer.data(), m_buffer.size());
@@ -355,45 +308,31 @@ PassRefPtr<SharedBuffer> SharedBuffer::copy() const
     return clone.release();
 }
 
-PassOwnPtr<PurgeableBuffer> SharedBuffer::releasePurgeableBuffer()
-{
-    ASSERT(hasOneRef());
-    return m_purgeableBuffer.release();
-}
-
-const Vector<char>& SharedBuffer::buffer() const
+void SharedBuffer::mergeSegmentsIntoBuffer() const
 {
     unsigned bufferSize = m_buffer.size();
     if (m_size > bufferSize) {
-        m_buffer.resize(m_size);
-        char* destination = m_buffer.data() + bufferSize;
+        m_buffer.reserveCapacity(m_size);
         unsigned bytesLeft = m_size - bufferSize;
         for (unsigned i = 0; i < m_segments.size(); ++i) {
-            unsigned bytesToCopy = min(bytesLeft, segmentSize);
-            memcpy(destination, m_segments[i], bytesToCopy);
-            destination += bytesToCopy;
+            unsigned bytesToCopy = std::min(bytesLeft, segmentSize);
+            m_buffer.append(m_segments[i], bytesToCopy);
             bytesLeft -= bytesToCopy;
             freeSegment(m_segments[i]);
         }
         m_segments.clear();
     }
-    return m_buffer;
 }
 
 unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
 {
+    ASSERT(isLocked());
     unsigned totalSize = size();
     if (position >= totalSize) {
         someData = 0;
         return 0;
     }
 
-    if (m_purgeableBuffer) {
-        ASSERT_WITH_SECURITY_IMPLICATION(position < size());
-        someData = data() + position;
-        return totalSize - position;
-    }
-
     ASSERT_WITH_SECURITY_IMPLICATION(position < m_size);
     unsigned consecutiveSize = m_buffer.size();
     if (position < consecutiveSize) {
@@ -407,7 +346,7 @@ unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) con
     unsigned segment = segmentIndex(position);
     if (segment < segments) {
         unsigned bytesLeft = totalSize - consecutiveSize;
-        unsigned segmentedSize = min(maxSegmentedSize, bytesLeft);
+        unsigned segmentedSize = std::min(maxSegmentedSize, bytesLeft);
 
         unsigned positionInSegment = offsetInSegment(position);
         someData = m_segments[segment] + positionInSegment;
@@ -421,6 +360,9 @@ PassRefPtr<ArrayBuffer> SharedBuffer::getAsArrayBuffer() const
 {
     RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::createUninitialized(static_cast<unsigned>(size()), 1);
 
+    if (!arrayBuffer)
+        return nullptr;
+
     const char* segment = 0;
     unsigned position = 0;
     while (unsigned segmentSize = getSomeData(segment, position)) {
@@ -431,10 +373,46 @@ PassRefPtr<ArrayBuffer> SharedBuffer::getAsArrayBuffer() const
     if (position != arrayBuffer->byteLength()) {
         ASSERT_NOT_REACHED();
         // Don't return the incomplete ArrayBuffer.
-        return 0;
+        return nullptr;
     }
 
     return arrayBuffer;
 }
 
-} // namespace WebCore
+PassRefPtr<SkData> SharedBuffer::getAsSkData() const
+{
+    unsigned bufferLength = size();
+    SkData* data = SkData::NewUninitialized(bufferLength);
+    char* buffer = static_cast<char*>(data->writable_data());
+    const char* segment = 0;
+    unsigned position = 0;
+    while (unsigned segmentSize = getSomeData(segment, position)) {
+        memcpy(buffer + position, segment, segmentSize);
+        position += segmentSize;
+    }
+
+    if (position != bufferLength) {
+        ASSERT_NOT_REACHED();
+        // Don't return the incomplete SkData.
+        return nullptr;
+    }
+    return adoptRef(data);
+}
+
+bool SharedBuffer::lock()
+{
+    return m_buffer.lock();
+}
+
+void SharedBuffer::unlock()
+{
+    mergeSegmentsIntoBuffer();
+    m_buffer.unlock();
+}
+
+bool SharedBuffer::isLocked() const
+{
+    return m_buffer.isLocked();
+}
+
+} // namespace blink