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 ---------------------------------------------- 17 template <class T> 18 class _BTextViewSupportBuffer_ { 19 20 public: 21 _BTextViewSupportBuffer_(int32 inExtraCount = 0, int32 inCount = 0); 22 virtual ~_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 29 protected: 30 int32 fExtraCount; 31 int32 fItemCount; 32 int32 fBufferCount; 33 T* fBuffer; 34 }; 35 36 37 template <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 49 template <class T> 50 _BTextViewSupportBuffer_<T>::~_BTextViewSupportBuffer_() 51 { 52 free(fBuffer); 53 } 54 55 56 template <class T> 57 void 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 86 template <class T> 87 void 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 115 template<class T> 116 inline int32 117 _BTextViewSupportBuffer_<T>::ItemCount() const 118 { 119 return fItemCount; 120 } 121 122 123 #endif // __TEXT_VIEW_SUPPORT_BUFFER__H__ 124