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