xref: /haiku/src/add-ons/kernel/file_systems/netfs/headers/shared/RequestMemberArray.h (revision 5a1d355fdf2747f80f8c46e2539f844a0b813346)
1 // RequestMemberArray.h
2 
3 #ifndef NET_FS_REQUEST_MEMBER_ARRAY_H
4 #define NET_FS_REQUEST_MEMBER_ARRAY_H
5 
6 #include <new>
7 
8 #include <stdlib.h>
9 
10 #include "Request.h"
11 #include "RequestFlattener.h"
12 #include "RequestUnflattener.h"
13 
14 template<typename Member>
15 class RequestMemberArray : public FlattenableRequestMember {
16 public:
RequestMemberArray()17 	RequestMemberArray()
18 		: fElements(NULL),
19 		  fSize(0),
20 		  fCapacity(0)
21 	{
22 	}
23 
~RequestMemberArray()24 	virtual ~RequestMemberArray()
25 	{
26 		for (int32 i = 0; i < fSize; i++)
27 			fElements[i].~Member();
28 		free(fElements);
29 	}
30 
ShowAround(RequestMemberVisitor * visitor)31 	virtual void ShowAround(RequestMemberVisitor* visitor)
32 	{
33 		visitor->Visit(this, fSize);
34 		for (int32 i = 0; i < fSize; i++)
35 			visitor->Visit(this, fElements[i]);
36 	}
37 
Flatten(RequestFlattener * flattener)38 	virtual status_t Flatten(RequestFlattener* flattener)
39 	{
40 		if (flattener->WriteInt32(fSize) != B_OK)
41 			return flattener->GetStatus();
42 
43 		for (int32 i = 0; i < fSize; i++)
44 			flattener->Visit(this, fElements[i]);
45 
46 		return flattener->GetStatus();
47 	}
48 
Unflatten(RequestUnflattener * unflattener)49 	virtual status_t Unflatten(RequestUnflattener* unflattener)
50 	{
51 		if (fSize > 0) {
52 			for (int32 i = 0; i < fSize; i++)
53 				fElements[i].~Member();
54 			fSize = 0;
55 		}
56 
57 		int32 size;
58 		if (unflattener->ReadInt32(size) != B_OK)
59 			return unflattener->GetStatus();
60 
61 		status_t error = _EnsureCapacity(size);
62 		if (error != B_OK)
63 			return error;
64 
65 		for (int32 i = 0; i < size; i++) {
66 			Member* element = new(fElements + i) Member;
67 			fSize = i + 1;
68 			unflattener->Visit(this, *element);
69 		}
70 
71 		return unflattener->GetStatus();
72 	}
73 
Append(const Member & element)74 	status_t Append(const Member& element)
75 	{
76 		status_t error = _EnsureCapacity(fSize + 1);
77 		if (error != B_OK)
78 			return error;
79 		new(fElements + fSize) Member(element);
80 		fSize++;
81 		return B_OK;
82 	}
83 
CountElements()84 	int32 CountElements() const
85 	{
86 		return fSize;
87 	}
88 
GetElements()89 	Member* GetElements() const
90 	{
91 		return fElements;
92 	}
93 
94 private:
_EnsureCapacity(int32 capacity)95 	status_t _EnsureCapacity(int32 capacity)
96 	{
97 		const int32 kMinCapacity = 10;
98 		if (capacity < kMinCapacity)
99 			capacity = kMinCapacity;
100 
101 		if (capacity > fCapacity) {
102 			if (capacity < 2 * fCapacity)
103 				capacity = 2 * fCapacity;
104 
105 			Member* elements
106 				= (Member*)realloc(fElements, capacity * sizeof(Member));
107 			if (!elements)
108 				return B_NO_MEMORY;
109 
110 			fElements = elements;
111 			fCapacity = capacity;
112 		}
113 
114 		return B_OK;
115 	}
116 
117 private:
118 	Member*	fElements;
119 	int32	fSize;
120 	int32	fCapacity;
121 };
122 
123 #endif	// NET_FS_REQUEST_MEMBER_ARRAY_H
124