xref: /haiku/src/kits/app/MessageUtils.cpp (revision 77fb9ca3e653f72d1d15c9f1a50c3d4287f680e0)
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 
16 namespace BPrivate {
17 
18 uint32
19 CalculateChecksum(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 */
40 status_t
41 entry_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 
66 status_t
67 entry_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 
93 status_t
94 entry_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