1// FSInfo.h
2
3#ifndef USERLAND_FS_FS_INFO_H
4#define USERLAND_FS_FS_INFO_H
5
6#include <new>
7
8#include <string.h>
9
10#include <Message.h>
11
12#include "Port.h"
13#include "String.h"
14
15namespace UserlandFS {
16
17// FSInfo
18class FSInfo {
19public:
20	FSInfo()
21		: fInfos(NULL),
22		  fCount(0)
23	{
24	}
25
26	FSInfo(const char* fsName, const Port::Info* infos, int32 count)
27		: fName(),
28		  fInfos(NULL),
29		  fCount(0)
30	{
31		SetTo(fsName, infos, count);
32	}
33
34	FSInfo(const BMessage* message)
35		: fName(),
36		  fInfos(NULL),
37		  fCount(0)
38	{
39		SetTo(message);
40	}
41
42	FSInfo(const FSInfo& other)
43		: fName(),
44		  fInfos(NULL),
45		  fCount(0)
46	{
47		SetTo(other.GetName(), other.fInfos, other.fCount);
48	}
49
50	~FSInfo()
51	{
52		Unset();
53	}
54
55	status_t SetTo(const char* fsName, const Port::Info* infos, int32 count)
56	{
57		Unset();
58		if (!fsName || !infos || count <= 0)
59			return B_BAD_VALUE;
60		if (!fName.SetTo(fsName))
61			return B_NO_MEMORY;
62		fInfos = new(nothrow) Port::Info[count];
63		if (!fInfos)
64			return B_NO_MEMORY;
65		memcpy(fInfos, infos, sizeof(Port::Info) * count);
66		fCount = count;
67		return B_OK;
68	}
69
70	status_t SetTo(const BMessage* message)
71	{
72		Unset();
73		if (!message)
74			return B_BAD_VALUE;
75		const void* infos;
76		ssize_t size;
77		const char* fsName;
78		if (message->FindData("infos", B_RAW_TYPE, &infos, &size) != B_OK
79			|| size < 0 || message->FindString("fsName", &fsName) != B_OK) {
80			return B_BAD_VALUE;
81		}
82		return SetTo(fsName, (const Port::Info*)infos,
83			size / sizeof(Port::Info));
84	}
85
86	void Unset()
87	{
88		fName.Unset();
89		delete[] fInfos;
90		fInfos = NULL;
91		fCount = 0;
92	}
93
94	const char* GetName() const
95	{
96		return fName.GetString();
97	}
98
99	Port::Info* GetInfos() const
100	{
101		return fInfos;
102	}
103
104	int32 CountInfos() const
105	{
106		return fCount;
107	}
108
109	int32 GetSize() const
110	{
111		return fCount * sizeof(Port::Info);
112	}
113
114	status_t Archive(BMessage* archive)
115	{
116		if (!fName.GetString() || !fInfos)
117			return B_NO_INIT;
118		status_t error = archive->AddString("fsName", fName.GetString());
119		if (error != B_OK)
120			return error;
121		return archive->AddData("infos", B_RAW_TYPE, fInfos,
122			fCount * sizeof(Port::Info));
123	}
124
125private:
126	String			fName;
127	Port::Info*		fInfos;
128	int32			fCount;
129};
130
131}	// namespace UserlandFS
132
133using UserlandFS::FSInfo;
134
135#endif	// USERLAND_FS_FS_INFO_H
136