1/*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Pawe�� Dziepak, pdziepak@quarnos.org
7 */
8
9
10#include "ReplyBuilder.h"
11
12#include "NFS4Defs.h"
13#include "RPCCallbackReply.h"
14
15
16ReplyBuilder::ReplyBuilder(uint32 xid)
17	:
18	fStatus(B_OK),
19	fOpCount(0),
20	fReply(RPC::CallbackReply::Create(xid))
21{
22	_InitHeader();
23}
24
25
26ReplyBuilder::~ReplyBuilder()
27{
28	delete fReply;
29}
30
31
32void
33ReplyBuilder::_InitHeader()
34{
35	fStatusPosition = fReply->Stream().Current();
36	fReply->Stream().AddUInt(0);
37
38	fReply->Stream().AddOpaque(NULL, 0);
39
40	fOpCountPosition = fReply->Stream().Current();
41	fReply->Stream().AddUInt(0);
42
43}
44
45
46RPC::CallbackReply*
47ReplyBuilder::Reply()
48{
49	if (fReply == NULL)
50		return NULL;
51
52	fReply->Stream().InsertUInt(fStatusPosition, _HaikuErrorToNFS4(fStatus));
53	fReply->Stream().InsertUInt(fOpCountPosition, fOpCount);
54
55	if (fReply->Stream().Error() == B_OK)
56		return fReply;
57	else
58		return NULL;
59}
60
61
62status_t
63ReplyBuilder::GetAttr(status_t status, int mask, uint64 size, uint64 change)
64{
65	if (fStatus != B_OK)
66		return B_ERROR;
67
68	fReply->Stream().AddUInt(OpCallbackGetAttr);
69	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
70	fStatus = status;
71
72	if (status == B_OK) {
73		uint32 bitmap = 0;
74		if ((mask & CallbackAttrChange) != 0)
75			bitmap |= 1 << FATTR4_CHANGE;
76		if ((mask & CallbackAttrSize) != 0)
77			bitmap |= 1 << FATTR4_SIZE;
78		fReply->Stream().AddUInt(1);
79		fReply->Stream().AddUInt(bitmap);
80
81		XDR::WriteStream str;
82		if ((mask & CallbackAttrChange) != 0)
83			str.AddUHyper(change);
84
85		if ((mask & CallbackAttrSize) != 0)
86			str.AddUHyper(size);
87		fReply->Stream().AddOpaque(str);
88	}
89
90	fOpCount++;
91
92	return B_OK;
93}
94
95
96status_t
97ReplyBuilder::Recall(status_t status)
98{
99	if (fStatus != B_OK)
100		return B_ERROR;
101
102	fReply->Stream().AddUInt(OpCallbackRecall);
103	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
104	fStatus = status;
105
106	fOpCount++;
107
108	return B_OK;
109}
110
111
112uint32
113ReplyBuilder::_HaikuErrorToNFS4(status_t error)
114{
115	switch (error) {
116		case B_OK:				return NFS4_OK;
117		case B_ENTRY_NOT_FOUND:	return NFS4ERR_BADHANDLE;
118		case B_NOT_SUPPORTED:	return NFS4ERR_OP_ILLEGAL;
119		default:				return NFS4ERR_RESOURCE;
120	}
121}
122
123