00001 /* 00002 * Copyright 2005-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 __EXPANDABLEBUFFER_H__ 00018 #define __EXPANDABLEBUFFER_H__ 00019 00020 #include <cstring> 00021 00022 #include "../debug/DebugUtils.h" 00023 00024 namespace oasys { 00025 00031 struct ExpandableBuffer { 00032 ExpandableBuffer(size_t size = 0) 00033 : buf_(0), buf_len_(0), len_(0) 00034 { 00035 if (size != 0) { 00036 reserve(size); 00037 } 00038 } 00039 00040 ExpandableBuffer(const ExpandableBuffer& other) 00041 : buf_(0), buf_len_(0), len_(0) 00042 { 00043 if (other.buf_ == 0) { 00044 return; 00045 } 00046 00047 reserve(other.buf_len_); 00048 memcpy(buf_, other.buf_, buf_len_); 00049 len_ = other.len_; 00050 } 00051 00052 virtual ~ExpandableBuffer() { 00053 if (buf_ != 0) { 00054 free(buf_); 00055 buf_ = 0; 00056 } 00057 00058 buf_len_ = 0; 00059 len_ = 0; 00060 } 00061 00066 char* tail_buf(size_t size) { 00067 if (size < (buf_len_ - len_)) { 00068 return buf_ + len_; 00069 } 00070 00071 reserve(len_ + size); 00072 ASSERT(size <= (buf_len_ - len_)); 00073 return buf_ + len_; 00074 } 00075 00083 virtual void reserve(size_t size) { 00084 if (size > buf_len_) { 00085 buf_ = static_cast<char*>(realloc(buf_, size)); 00086 if (buf_ == 0) { 00087 PANIC("out of memory"); 00088 } 00089 buf_len_ = size; 00090 } 00091 } 00092 00094 size_t nfree() const { 00095 ASSERT(buf_len_ >= len_); 00096 return buf_len_ - len_; 00097 } 00098 00100 char* raw_buf() const { 00101 ASSERT(buf_ != 0); 00102 return buf_; 00103 } 00104 00107 char* at(size_t offset) const { 00108 ASSERT(buf_ != 0); 00109 00110 if (offset >= buf_len_) { 00111 return 0; 00112 } 00113 00114 return &buf_[offset]; 00115 } 00116 00118 char* end() const { 00119 ASSERT(buf_ != 0); 00120 ASSERT(len_ < buf_len_); 00121 return at(len_); 00122 } 00123 00125 size_t buf_len() const { 00126 return buf_len_; 00127 } 00128 00130 size_t len() const { return len_; } 00131 00133 void set_len(size_t len) { 00134 len_ = len; 00135 ASSERT(len_ <= buf_len_); 00136 } 00137 00139 void incr_len(size_t amt) { 00140 len_ += amt; 00141 ASSERT(len_ <= buf_len_); 00142 } 00143 00144 void clear() { 00145 set_len(0); 00146 } 00147 00148 protected: 00149 char* buf_; 00150 size_t buf_len_; 00151 size_t len_; 00152 }; 00153 00154 } // namespace oasys 00155 00156 #endif /* __EXPANDABLEBUFFER_H__ */