00001 /* 00002 * Copyright 2004-2006 Intel Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __STATIC_SCRATCH_BUFFER__ 00018 #define __STATIC_SCRATCH_BUFFER__ 00019 00020 #include <cstdlib> 00021 #include <cstring> 00022 00023 #include "../debug/DebugUtils.h" 00024 #include "../util/ExpandableBuffer.h" 00025 00026 namespace oasys { 00027 00038 template<typename _memory_t = void*, size_t _static_size = 0> 00039 class ScratchBuffer; 00040 00044 template<typename _memory_t> 00045 class ScratchBuffer<_memory_t, 0> : public ExpandableBuffer { 00046 public: 00047 ScratchBuffer(size_t size = 0) : ExpandableBuffer(size) {} 00048 ScratchBuffer(const ScratchBuffer& other) : ExpandableBuffer(other) {} 00049 00051 _memory_t buf(size_t size = 0) { 00052 if (size > buf_len_) { 00053 reserve(size); 00054 } 00055 return reinterpret_cast<_memory_t>(buf_); 00056 } 00057 00059 const _memory_t buf() const { 00060 return reinterpret_cast<const _memory_t>(buf_); 00061 } 00062 00063 }; 00064 00069 template<typename _memory_t, size_t _static_size> 00070 class ScratchBuffer : public ExpandableBuffer { 00071 public: 00073 ScratchBuffer(size_t size = 0) 00074 : ExpandableBuffer(0) 00075 { 00076 buf_ = static_buf_; 00077 buf_len_ = _static_size; 00078 00079 if (size > buf_len_) { 00080 reserve(size); 00081 } 00082 } 00083 00086 ScratchBuffer(const ScratchBuffer& other) 00087 : ExpandableBuffer(0) 00088 { 00089 buf_ = static_buf_; 00090 buf_len_ = _static_size; 00091 00092 reserve(other.buf_len_); 00093 memcpy(buf_, other.buf_, other.buf_len_); 00094 len_ = other.len_; 00095 00096 ASSERT(using_malloc() == other.using_malloc()); 00097 } 00098 00101 virtual ~ScratchBuffer() { 00102 if (! using_malloc()) { 00103 buf_ = 0; 00104 } 00105 } 00106 00108 _memory_t buf(size_t size = 0) { 00109 if (size != 0) { 00110 reserve(size); 00111 } 00112 return reinterpret_cast<_memory_t>(buf_); 00113 } 00114 00116 const _memory_t buf() const { 00117 return reinterpret_cast<const _memory_t>(buf_); 00118 } 00119 00121 virtual void reserve(size_t size = 0) { 00122 if (size == 0) { 00123 size = (buf_len_ == 0) ? 1 : (buf_len_ * 2); 00124 } 00125 00126 if (size <= buf_len_) { 00127 return; 00128 } 00129 00130 if (! using_malloc()) 00131 { 00132 ASSERT(size > _static_size); 00133 buf_ = 0; 00134 size_t old_buf_len = buf_len_; 00135 00136 ExpandableBuffer::reserve(size); 00137 memcpy(buf_, static_buf_, old_buf_len); 00138 } 00139 else 00140 { 00141 ExpandableBuffer::reserve(size); 00142 } 00143 } 00144 00145 private: 00146 char static_buf_[_static_size]; 00147 bool using_malloc() const { 00148 return buf_ != static_buf_; 00149 } 00150 }; 00151 00152 } // namespace oasys 00153 00154 #endif //__STATIC_SCRATCH_BUFFER_H__