1/*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "SymLink.h"
8
9#include <string.h>
10
11#include "Block.h"
12#include "DebugSupport.h"
13
14
15static const size_t kSymLinkDataOffset	= sizeof(checksumfs_node);
16static const size_t kMaxSymLinkSize		= B_PAGE_SIZE - kSymLinkDataOffset;
17
18
19SymLink::SymLink(Volume* volume, uint64 blockIndex,
20	const checksumfs_node& nodeData)
21	:
22	Node(volume, blockIndex, nodeData)
23{
24}
25
26
27SymLink::SymLink(Volume* volume, mode_t mode)
28	:
29	Node(volume, mode)
30{
31}
32
33
34SymLink::~SymLink()
35{
36}
37
38
39status_t
40SymLink::ReadSymLink(char* buffer, size_t toRead, size_t& _bytesRead)
41{
42	uint64 size = Size();
43	if (size > kMaxSymLinkSize)
44		RETURN_ERROR(B_BAD_DATA);
45
46	if (toRead > size)
47		toRead = size;
48
49	if (toRead == 0) {
50		_bytesRead = 0;
51		return B_OK;
52	}
53
54	// get the block
55	Block block;
56	if (!block.GetReadable(GetVolume(), BlockIndex()))
57		RETURN_ERROR(B_ERROR);
58
59	const char* data = (char*)block.Data() + kSymLinkDataOffset;
60	memcpy(buffer, data, toRead);
61
62	_bytesRead = toRead;
63	return B_OK;
64}
65
66
67status_t
68SymLink::WriteSymLink(const char* buffer, size_t toWrite,
69	Transaction& transaction)
70{
71	uint64 size = Size();
72	if (size > kMaxSymLinkSize)
73		RETURN_ERROR(B_BAD_DATA);
74
75	if (toWrite > kMaxSymLinkSize)
76		RETURN_ERROR(B_NAME_TOO_LONG);
77
78	if (toWrite == 0) {
79		SetSize(0);
80		return B_OK;
81	}
82
83	Block block;
84	if (!block.GetWritable(GetVolume(), BlockIndex(), transaction))
85		return B_ERROR;
86
87	char* data = (char*)block.Data() + kSymLinkDataOffset;
88	memcpy(data, buffer, toWrite);
89	SetSize(toWrite);
90
91	return B_OK;
92}
93