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