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#if defined(__INTEL__)
26		sum += B_SWAP_INT32(*(int32 *)buffer);
27#else
28		sum += *(int32 *)buffer;
29#endif
30		buffer += 4;
31		size -= 4;
32	}
33
34	while (size > 0) {
35		temp = (temp << 8) + *buffer++;
36		size -= 1;
37	}
38
39	return sum + temp;
40}
41
42
43/* entry_ref support functions */
44status_t
45entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref)
46{
47	if (*size < sizeof(ref->device) + sizeof(ref->directory))
48		return B_BUFFER_OVERFLOW;
49
50	memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device));
51	buffer += sizeof(ref->device);
52	memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory));
53	buffer += sizeof (ref->directory);
54	*size -= sizeof(ref->device) + sizeof(ref->directory);
55
56	size_t nameLength = 0;
57	if (ref->name) {
58		nameLength = strlen(ref->name) + 1;
59		if (*size < nameLength)
60			return B_BUFFER_OVERFLOW;
61
62		memcpy((void *)buffer, (const void *)ref->name, nameLength);
63	}
64
65	*size = sizeof(ref->device) + sizeof(ref->directory) + nameLength;
66	return B_OK;
67}
68
69
70status_t
71entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size)
72{
73	if (size < sizeof(ref->device) + sizeof(ref->directory)) {
74		*ref = entry_ref();
75		return B_BAD_VALUE;
76	}
77
78	memcpy((void  *)&ref->device, (const void *)buffer, sizeof(ref->device));
79	buffer += sizeof (ref->device);
80	memcpy((void *)&ref->directory, (const void *)buffer, sizeof(ref->directory));
81	buffer += sizeof(ref->directory);
82
83	if (ref->device != ~(dev_t)0 && size > sizeof(ref->device)
84			+ sizeof(ref->directory)) {
85		ref->set_name(buffer);
86		if (ref->name == NULL) {
87			*ref = entry_ref();
88			return B_NO_MEMORY;
89		}
90	} else
91		ref->set_name(NULL);
92
93	return B_OK;
94}
95
96
97status_t
98entry_ref_swap(char *buffer, size_t size)
99{
100	if (size < sizeof(dev_t) + sizeof(ino_t))
101		return B_BAD_VALUE;
102
103	dev_t *dev = (dev_t *)buffer;
104	*dev = B_SWAP_INT32(*dev);
105	buffer += sizeof(dev_t);
106
107	ino_t *ino = (ino_t *)buffer;
108	*ino = B_SWAP_INT64(*ino);
109
110	return B_OK;
111}
112
113} // namespace BPrivate
114