1/*
2 * Copyright 2001-2005, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Erik Jaesler (erik@cgsoftware.com)
7 */
8
9/**	Extra messaging utility functions */
10
11#include <string.h>
12#include <ByteOrder.h>
13
14#include <MessageUtils.h>
15
16namespace BPrivate {
17
18uint32
19CalculateChecksum(const uint8 *buffer, int32 size)
20{
21	uint32 sum = 0;
22	uint32 temp = 0;
23
24	while (size > 3) {
25		sum += B_BENDIAN_TO_HOST_INT32(*(int32 *)buffer);
26		buffer += 4;
27		size -= 4;
28	}
29
30	while (size > 0) {
31		temp = (temp << 8) + *buffer++;
32		size -= 1;
33	}
34
35	return sum + temp;
36}
37
38
39/* entry_ref support functions */
40status_t
41entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref)
42{
43	if (*size < sizeof(ref->device) + sizeof(ref->directory))
44		return B_BUFFER_OVERFLOW;
45
46	memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device));
47	buffer += sizeof(ref->device);
48	memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory));
49	buffer += sizeof (ref->directory);
50	*size -= sizeof(ref->device) + sizeof(ref->directory);
51
52	size_t nameLength = 0;
53	if (ref->name) {
54		nameLength = strlen(ref->name) + 1;
55		if (*size < nameLength)
56			return B_BUFFER_OVERFLOW;
57
58		memcpy((void *)buffer, (const void *)ref->name, nameLength);
59	}
60
61	*size = sizeof(ref->device) + sizeof(ref->directory) + nameLength;
62	return B_OK;
63}
64
65
66status_t
67entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size)
68{
69	if (size < sizeof(ref->device) + sizeof(ref->directory)) {
70		*ref = entry_ref();
71		return B_BAD_VALUE;
72	}
73
74	memcpy((void  *)&ref->device, (const void *)buffer, sizeof(ref->device));
75	buffer += sizeof (ref->device);
76	memcpy((void *)&ref->directory, (const void *)buffer, sizeof(ref->directory));
77	buffer += sizeof(ref->directory);
78
79	if (ref->device != ~(dev_t)0 && size > sizeof(ref->device)
80			+ sizeof(ref->directory)) {
81		ref->set_name(buffer);
82		if (ref->name == NULL) {
83			*ref = entry_ref();
84			return B_NO_MEMORY;
85		}
86	} else
87		ref->set_name(NULL);
88
89	return B_OK;
90}
91
92
93status_t
94entry_ref_swap(char *buffer, size_t size)
95{
96	if (size < sizeof(dev_t) + sizeof(ino_t))
97		return B_BAD_VALUE;
98
99	dev_t *dev = (dev_t *)buffer;
100	*dev = B_SWAP_INT32(*dev);
101	buffer += sizeof(dev_t);
102
103	ino_t *ino = (ino_t *)buffer;
104	*ino = B_SWAP_INT64(*ino);
105
106	return B_OK;
107}
108
109} // namespace BPrivate
110