1/* 2 * Copyright 2001-2010, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#ifndef __TEXT_VIEW_SUPPORT_BUFFER__H__ 7#define __TEXT_VIEW_SUPPORT_BUFFER__H__ 8 9#include <cstdlib> 10#include <cstring> 11 12#include <OS.h> 13#include <SupportDefs.h> 14 15 16// _BTextViewSupportBuffer_ class ---------------------------------------------- 17template <class T> 18class _BTextViewSupportBuffer_ { 19 20public: 21 _BTextViewSupportBuffer_(int32 inExtraCount = 0, int32 inCount = 0); 22virtual ~_BTextViewSupportBuffer_(); 23 24 void InsertItemsAt(int32 inNumItems, int32 inAtIndex, const T* inItem); 25 void RemoveItemsAt(int32 inNumItems, int32 inAtIndex); 26 27 int32 ItemCount() const; 28 29protected: 30 int32 fExtraCount; 31 int32 fItemCount; 32 int32 fBufferCount; 33 T* fBuffer; 34}; 35 36 37template <class T> 38_BTextViewSupportBuffer_<T>::_BTextViewSupportBuffer_(int32 inExtraCount, 39 int32 inCount) 40 : fExtraCount(inExtraCount), 41 fItemCount(inCount), 42 fBufferCount(fExtraCount + fItemCount), 43 fBuffer(NULL) 44{ 45 fBuffer = (T*)calloc(fExtraCount + fItemCount, sizeof(T)); 46} 47 48 49template <class T> 50_BTextViewSupportBuffer_<T>::~_BTextViewSupportBuffer_() 51{ 52 free(fBuffer); 53} 54 55 56template <class T> 57void 58_BTextViewSupportBuffer_<T>::InsertItemsAt(int32 inNumItems, 59 int32 inAtIndex, 60 const T* inItem) 61{ 62 if (inNumItems < 1) 63 return; 64 65 inAtIndex = (inAtIndex > fItemCount) ? fItemCount : inAtIndex; 66 inAtIndex = (inAtIndex < 0) ? 0 : inAtIndex; 67 68 int32 delta = inNumItems * sizeof(T); 69 int32 logSize = fItemCount * sizeof(T); 70 if ((logSize + delta) >= fBufferCount) { 71 fBufferCount = logSize + delta + (fExtraCount * sizeof(T)); 72 fBuffer = (T*)realloc((void*)fBuffer, fBufferCount); 73 if (fBuffer == NULL) 74 debugger("InsertItemsAt(): reallocation failed"); 75 } 76 77 T* loc = fBuffer + inAtIndex; 78 memmove((void*)(loc + inNumItems), (void*)loc, 79 (fItemCount - inAtIndex) * sizeof(T)); 80 memcpy((void*)loc, (void*)inItem, delta); 81 82 fItemCount += inNumItems; 83} 84 85 86template <class T> 87void 88_BTextViewSupportBuffer_<T>::RemoveItemsAt(int32 inNumItems, 89 int32 inAtIndex) 90{ 91 if (inNumItems < 1) 92 return; 93 94 inAtIndex = (inAtIndex > fItemCount - 1) ? (fItemCount - 1) : inAtIndex; 95 inAtIndex = (inAtIndex < 0) ? 0 : inAtIndex; 96 97 T* loc = fBuffer + inAtIndex; 98 memmove(loc, loc + inNumItems, 99 (fItemCount - (inNumItems + inAtIndex)) * sizeof(T)); 100 101 int32 delta = inNumItems * sizeof(T); 102 int32 logSize = fItemCount * sizeof(T); 103 uint32 extraSize = fBufferCount - (logSize - delta); 104 if (extraSize > (fExtraCount * sizeof(T))) { 105 fBufferCount = (logSize - delta) + (fExtraCount * sizeof(T)); 106 fBuffer = (T*)realloc(fBuffer, fBufferCount); 107 if (fBuffer == NULL) 108 debugger("RemoveItemsAt(): reallocation failed"); 109 } 110 111 fItemCount -= inNumItems; 112} 113 114 115template<class T> 116inline int32 117_BTextViewSupportBuffer_<T>::ItemCount() const 118{ 119 return fItemCount; 120} 121 122 123#endif // __TEXT_VIEW_SUPPORT_BUFFER__H__ 124