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(fBuffer, fBufferCount); 73 if (fBuffer == NULL) 74 debugger("InsertItemsAt(): reallocation failed"); 75 } 76 77 T* loc = fBuffer + inAtIndex; 78 memmove(loc + inNumItems, loc, (fItemCount - inAtIndex) * sizeof(T)); 79 memcpy(loc, inItem, delta); 80 81 fItemCount += inNumItems; 82 } 83 84 85 template <class T> 86 void 87 _BTextViewSupportBuffer_<T>::RemoveItemsAt(int32 inNumItems, 88 int32 inAtIndex) 89 { 90 if (inNumItems < 1) 91 return; 92 93 inAtIndex = (inAtIndex > fItemCount - 1) ? (fItemCount - 1) : inAtIndex; 94 inAtIndex = (inAtIndex < 0) ? 0 : inAtIndex; 95 96 T* loc = fBuffer + inAtIndex; 97 memmove(loc, loc + inNumItems, 98 (fItemCount - (inNumItems + inAtIndex)) * sizeof(T)); 99 100 int32 delta = inNumItems * sizeof(T); 101 int32 logSize = fItemCount * sizeof(T); 102 uint32 extraSize = fBufferCount - (logSize - delta); 103 if (extraSize > (fExtraCount * sizeof(T))) { 104 fBufferCount = (logSize - delta) + (fExtraCount * sizeof(T)); 105 fBuffer = (T*)realloc(fBuffer, fBufferCount); 106 if (fBuffer == NULL) 107 debugger("RemoveItemsAt(): reallocation failed"); 108 } 109 110 fItemCount -= inNumItems; 111 } 112 113 114 template<class T> 115 inline int32 116 _BTextViewSupportBuffer_<T>::ItemCount() const 117 { 118 return fItemCount; 119 } 120 121 122 #endif // __TEXT_VIEW_SUPPORT_BUFFER__H__ 123