- add sources.
[platform/framework/web/crosswalk.git] / src / mojo / public / bindings / lib / buffer.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/bindings/lib/buffer.h"
6
7 #include <assert.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include <algorithm>
12
13 #include "mojo/public/bindings/lib/bindings_serialization.h"
14
15 namespace mojo {
16
17 //-----------------------------------------------------------------------------
18
19 ScratchBuffer::ScratchBuffer()
20     : overflow_(NULL) {
21   fixed_.next = NULL;
22   fixed_.cursor = fixed_data_;
23   fixed_.end = fixed_data_ + kMinSegmentSize;
24 }
25
26 ScratchBuffer::~ScratchBuffer() {
27   while (overflow_) {
28     Segment* doomed = overflow_;
29     overflow_ = overflow_->next;
30     free(doomed);
31   }
32 }
33
34 void* ScratchBuffer::Allocate(size_t delta) {
35   delta = internal::Align(delta);
36
37   void* result =
38       AllocateInSegment((overflow_ != NULL) ? overflow_ : &fixed_, delta);
39   if (result)
40     return result;
41
42   AddOverflowSegment(delta);
43   return Allocate(delta);
44 }
45
46 void* ScratchBuffer::AllocateInSegment(Segment* segment, size_t delta) {
47   void* result;
48   if (static_cast<size_t>(segment->end - segment->cursor) >= delta) {
49     result = segment->cursor;
50     memset(result, 0, delta);
51     segment->cursor += delta;
52   } else {
53     result = NULL;
54   }
55   return result;
56 }
57
58 void ScratchBuffer::AddOverflowSegment(size_t delta) {
59   if (delta < kMinSegmentSize)
60     delta = kMinSegmentSize;
61
62   // Ensure segment buffer is aligned.
63   size_t segment_size = internal::Align(sizeof(Segment)) + delta;
64
65   Segment* segment = static_cast<Segment*>(malloc(segment_size));
66   segment->next = overflow_;
67   segment->cursor = reinterpret_cast<char*>(segment + 1);
68   segment->end = segment->cursor + delta;
69
70   overflow_ = segment;
71 }
72
73 //-----------------------------------------------------------------------------
74
75 FixedBuffer::FixedBuffer(size_t size)
76     : ptr_(NULL),
77       cursor_(0),
78       size_(internal::Align(size)) {
79   ptr_ = static_cast<char*>(calloc(size_, 1));
80 }
81
82 FixedBuffer::~FixedBuffer() {
83   free(ptr_);
84 }
85
86 void* FixedBuffer::Allocate(size_t delta) {
87   delta = internal::Align(delta);
88
89   // TODO(darin): Using <assert.h> is probably not going to cut it.
90   assert(delta > 0);
91   assert(cursor_ + delta <= size_);
92   if (cursor_ + delta > size_)
93     return NULL;
94
95   char* result = ptr_ + cursor_;
96   cursor_ += delta;
97
98   return result;
99 }
100
101 void* FixedBuffer::Leak() {
102   char* ptr = ptr_;
103   ptr_ = NULL;
104   cursor_ = 0;
105   size_ = 0;
106   return ptr;
107 }
108
109 }  // namespace mojo