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 63 return B_OK; 64 } 65 66 67 status_t 68 entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size) 69 { 70 if (size < sizeof(ref->device) + sizeof(ref->directory)) { 71 *ref = entry_ref(); 72 return B_BAD_VALUE; 73 } 74 75 memcpy((void *)&ref->device, (const void *)buffer, sizeof(ref->device)); 76 buffer += sizeof(ref->device); 77 memcpy((void *)&ref->directory, (const void *)buffer, 78 sizeof(ref->directory)); 79 buffer += sizeof(ref->directory); 80 81 if (ref->device != ~(dev_t)0 && size > sizeof(ref->device) 82 + sizeof(ref->directory)) { 83 ref->set_name(buffer); 84 if (ref->name == NULL) { 85 *ref = entry_ref(); 86 return B_NO_MEMORY; 87 } 88 } else 89 ref->set_name(NULL); 90 91 return B_OK; 92 } 93 94 95 status_t 96 entry_ref_swap(char *buffer, size_t size) 97 { 98 if (size < sizeof(dev_t) + sizeof(ino_t)) 99 return B_BAD_VALUE; 100 101 dev_t *dev = (dev_t *)buffer; 102 *dev = B_SWAP_INT32(*dev); 103 buffer += sizeof(dev_t); 104 105 ino_t *ino = (ino_t *)buffer; 106 *ino = B_SWAP_INT64(*ino); 107 108 return B_OK; 109 } 110 111 112 /* node_ref support functions */ 113 status_t 114 node_ref_flatten(char *buffer, size_t *size, const node_ref *ref) 115 { 116 if (*size < sizeof(dev_t) + sizeof(ino_t)) 117 return B_BUFFER_OVERFLOW; 118 119 memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device)); 120 buffer += sizeof(ref->device); 121 memcpy((void *)buffer, (const void *)&ref->node, sizeof(ref->node)); 122 buffer += sizeof(ref->node); 123 124 return B_OK; 125 } 126 127 128 status_t 129 node_ref_unflatten(node_ref *ref, const char *buffer, size_t size) 130 { 131 if (size < sizeof(dev_t) + sizeof(ino_t)) { 132 *ref = node_ref(); 133 return B_BAD_VALUE; 134 } 135 136 memcpy((void *)&ref->device, (const void *)buffer, sizeof(dev_t)); 137 buffer += sizeof(dev_t); 138 memcpy((void *)&ref->node, (const void *)buffer, sizeof(ino_t)); 139 buffer += sizeof(ino_t); 140 141 return B_OK; 142 } 143 144 145 status_t 146 node_ref_swap(char *buffer, size_t size) 147 { 148 if (size < sizeof(dev_t) + sizeof(ino_t)) 149 return B_BAD_VALUE; 150 151 dev_t *dev = (dev_t *)buffer; 152 *dev = B_SWAP_INT32(*dev); 153 buffer += sizeof(dev_t); 154 155 ino_t *ino = (ino_t *)buffer; 156 *ino = B_SWAP_INT64(*ino); 157 158 return B_OK; 159 } 160 161 } // namespace BPrivate 162