xref: /haiku/src/kits/app/MessageUtils.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 #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 */
44 status_t
45 entry_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 
70 status_t
71 entry_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 
97 status_t
98 entry_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