headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / kernel / disk_device_manager / UserDataWriter.cpp
blob9dd757ea45a06c87f3cfa03178c7a1e387060480
1 // UserDataWriter.cpp
3 #include <util/kernel_cpp.h>
4 #include <ddm_userland_interface.h>
5 #include <Vector.h>
7 #include "UserDataWriter.h"
9 using namespace std;
11 typedef uint8 *addr;
13 // RelocationEntryList
14 struct UserDataWriter::RelocationEntryList : Vector<addr*> {};
16 // constructor
17 UserDataWriter::UserDataWriter()
18 : fBuffer(NULL),
19 fBufferSize(0),
20 fAllocatedSize(0),
21 fRelocationEntries(NULL)
25 // constructor
26 UserDataWriter::UserDataWriter(user_disk_device_data *buffer,
27 size_t bufferSize)
28 : fBuffer(NULL),
29 fBufferSize(0),
30 fAllocatedSize(0),
31 fRelocationEntries(NULL)
33 SetTo(buffer, bufferSize);
36 // destructor
37 UserDataWriter::~UserDataWriter()
39 delete fRelocationEntries;
42 // SetTo
43 status_t
44 UserDataWriter::SetTo(user_disk_device_data *buffer, size_t bufferSize)
46 Unset();
47 fBuffer = buffer;
48 fBufferSize = bufferSize;
49 fAllocatedSize = 0;
50 if (fBuffer && fBufferSize > 0) {
51 fRelocationEntries = new(nothrow) RelocationEntryList;
52 if (!fRelocationEntries)
53 return B_NO_MEMORY;
55 return B_OK;
58 // Unset
59 void
60 UserDataWriter::Unset()
62 delete fRelocationEntries;
63 fBuffer = NULL;
64 fBufferSize = 0;
65 fAllocatedSize = 0;
66 fRelocationEntries = NULL;
69 // AllocateData
70 void *
71 UserDataWriter::AllocateData(size_t size, size_t align)
73 // handles size == 0 gracefully
74 // get a properly aligned offset
75 size_t offset = fAllocatedSize;
76 if (align > 1)
77 offset = (fAllocatedSize + align - 1) / align * align;
78 // get the result pointer
79 void *result = NULL;
80 if (fBuffer && offset + size <= fBufferSize)
81 result = (uint8*)fBuffer + offset;
82 // always update the allocated size, even if there wasn't enough space
83 fAllocatedSize = offset + size;
84 return result;
87 // AllocatePartitionData
88 user_partition_data *
89 UserDataWriter::AllocatePartitionData(size_t childCount)
91 return (user_partition_data*)AllocateData(
92 sizeof(user_partition_data)
93 + sizeof(user_partition_data*) * ((int32)childCount - 1),
94 sizeof(int));
97 // AllocateDeviceData
98 user_disk_device_data *
99 UserDataWriter::AllocateDeviceData(size_t childCount)
101 return (user_disk_device_data*)AllocateData(
102 sizeof(user_disk_device_data)
103 + sizeof(user_partition_data*) * ((int32)childCount - 1),
104 sizeof(int));
107 // PlaceString
108 char *
109 UserDataWriter::PlaceString(const char *str)
111 if (!str)
112 return NULL;
113 size_t len = strlen(str) + 1;
114 char *data = (char*)AllocateData(len);
115 if (data)
116 memcpy(data, str, len);
117 return data;
120 // AllocatedSize
121 size_t
122 UserDataWriter::AllocatedSize() const
124 return fAllocatedSize;
127 // AddRelocationEntry
128 status_t
129 UserDataWriter::AddRelocationEntry(void *address)
131 if (fRelocationEntries && (addr)address >= (addr)fBuffer
132 && (addr)address < (addr)fBuffer + fBufferSize - sizeof(void*)) {
133 return fRelocationEntries->PushBack((addr*)address);
135 return B_ERROR;
138 // Relocate
139 status_t
140 UserDataWriter::Relocate(void *address)
142 if (!fRelocationEntries || !fBuffer)
143 return B_BAD_VALUE;
144 int32 count = fRelocationEntries->Count();
145 for (int32 i = 0; i < count; i++) {
146 addr *entry = fRelocationEntries->ElementAt(i);
147 if (*entry)
148 *entry += (addr)address - (addr)fBuffer;
150 return B_OK;