1193326Sed/*
2193326Sed * Copyright 2001-2010, Haiku, Inc.
3193326Sed * Distributed under the terms of the MIT License.
4193326Sed */
5193326Sed
6193326Sed#ifndef __TEXT_VIEW_SUPPORT_BUFFER__H__
7193326Sed#define __TEXT_VIEW_SUPPORT_BUFFER__H__
8193326Sed
9193326Sed#include <cstdlib>
10193326Sed#include <cstring>
11193326Sed
12212904Sdim#include <OS.h>
13193326Sed#include <SupportDefs.h>
14193326Sed
15193326Sed
16193326Sed// _BTextViewSupportBuffer_ class ----------------------------------------------
17206084Srdivackytemplate <class T>
18193326Sedclass _BTextViewSupportBuffer_ {
19200583Srdivacky
20205219Srdivackypublic:
21198092Srdivacky				_BTextViewSupportBuffer_(int32 inExtraCount = 0, int32 inCount = 0);
22249423Sdimvirtual			~_BTextViewSupportBuffer_();
23249423Sdim
24249423Sdim		void	InsertItemsAt(int32 inNumItems, int32 inAtIndex, const T* inItem);
25193326Sed		void	RemoveItemsAt(int32 inNumItems, int32 inAtIndex);
26193326Sed
27193326Sed		int32	ItemCount() const;
28263508Sdim
29263508Sdimprotected:
30263508Sdim		int32	fExtraCount;
31263508Sdim		int32	fItemCount;
32263508Sdim		int32	fBufferCount;
33263508Sdim		T*		fBuffer;
34263508Sdim};
35263508Sdim
36263508Sdim
37263508Sdimtemplate <class T>
38263508Sdim_BTextViewSupportBuffer_<T>::_BTextViewSupportBuffer_(int32 inExtraCount,
39205219Srdivacky													  int32 inCount)
40205219Srdivacky	:	fExtraCount(inExtraCount),
41219077Sdim		fItemCount(inCount),
42219077Sdim		fBufferCount(fExtraCount + fItemCount),
43226633Sdim		fBuffer(NULL)
44219077Sdim{
45226633Sdim	fBuffer = (T*)calloc(fExtraCount + fItemCount, sizeof(T));
46219077Sdim}
47226633Sdim
48219077Sdim
49205219Srdivackytemplate <class T>
50226633Sdim_BTextViewSupportBuffer_<T>::~_BTextViewSupportBuffer_()
51219077Sdim{
52205219Srdivacky	free(fBuffer);
53205219Srdivacky}
54205219Srdivacky
55205219Srdivacky
56205219Srdivackytemplate <class T>
57219077Sdimvoid
58219077Sdim_BTextViewSupportBuffer_<T>::InsertItemsAt(int32 inNumItems,
59226633Sdim												int32 inAtIndex,
60219077Sdim												const T* inItem)
61226633Sdim{
62219077Sdim	if (inNumItems < 1)
63226633Sdim		return;
64219077Sdim
65205219Srdivacky	inAtIndex = (inAtIndex > fItemCount) ? fItemCount : inAtIndex;
66226633Sdim	inAtIndex = (inAtIndex < 0) ? 0 : inAtIndex;
67219077Sdim
68205219Srdivacky	int32 delta = inNumItems * sizeof(T);
69205219Srdivacky	int32 logSize = fItemCount * sizeof(T);
70205219Srdivacky	if ((logSize + delta) >= fBufferCount) {
71234353Sdim		fBufferCount = logSize + delta + (fExtraCount * sizeof(T));
72234353Sdim		fBuffer = (T*)realloc((void*)fBuffer, fBufferCount);
73234353Sdim		if (fBuffer == NULL)
74249423Sdim			debugger("InsertItemsAt(): reallocation failed");
75249423Sdim	}
76249423Sdim
77249423Sdim	T* loc = fBuffer + inAtIndex;
78249423Sdim	memmove((void*)(loc + inNumItems), (void*)loc,
79249423Sdim		(fItemCount - inAtIndex) * sizeof(T));
80249423Sdim	memcpy((void*)loc, (void*)inItem, delta);
81249423Sdim
82249423Sdim	fItemCount += inNumItems;
83249423Sdim}
84249423Sdim
85249423Sdim
86249423Sdimtemplate <class T>
87249423Sdimvoid
88249423Sdim_BTextViewSupportBuffer_<T>::RemoveItemsAt(int32 inNumItems,
89249423Sdim												int32 inAtIndex)
90249423Sdim{
91249423Sdim	if (inNumItems < 1)
92249423Sdim		return;
93249423Sdim
94249423Sdim	inAtIndex = (inAtIndex > fItemCount - 1) ? (fItemCount - 1) : inAtIndex;
95249423Sdim	inAtIndex = (inAtIndex < 0) ? 0 : inAtIndex;
96249423Sdim
97249423Sdim	T* loc = fBuffer + inAtIndex;
98249423Sdim	memmove(loc, loc + inNumItems,
99249423Sdim			(fItemCount - (inNumItems + inAtIndex)) * sizeof(T));
100249423Sdim
101249423Sdim	int32 delta = inNumItems * sizeof(T);
102249423Sdim	int32 logSize = fItemCount * sizeof(T);
103249423Sdim	uint32 extraSize = fBufferCount - (logSize - delta);
104249423Sdim	if (extraSize > (fExtraCount * sizeof(T))) {
105249423Sdim		fBufferCount = (logSize - delta) + (fExtraCount * sizeof(T));
106249423Sdim		fBuffer = (T*)realloc(fBuffer, fBufferCount);
107249423Sdim		if (fBuffer == NULL)
108249423Sdim			debugger("RemoveItemsAt(): reallocation failed");
109249423Sdim	}
110249423Sdim
111249423Sdim	fItemCount -= inNumItems;
112249423Sdim}
113249423Sdim
114249423Sdim
115249423Sdimtemplate<class T>
116249423Sdiminline int32
117249423Sdim_BTextViewSupportBuffer_<T>::ItemCount() const
118249423Sdim{
119249423Sdim	return fItemCount;
120249423Sdim}
121249423Sdim
122249423Sdim
123249423Sdim#endif // __TEXT_VIEW_SUPPORT_BUFFER__H__
124249423Sdim