1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _MESSAGE_BUF_H_ 18 #define _MESSAGE_BUF_H_ 19 20 #include <endian.h> 21 #include <cstring> 22 23 namespace android { 24 25 namespace nanohub { 26 27 /* 28 * Marshaling helper; 29 * deals with alignment and endianness. 30 * Assumption is: 31 * read*() parse buffer from device in LE format; 32 * return host endianness, aligned data 33 * write*() primitives take host endinnness, aligned data, 34 * generate buffer to be passed to device in LE format 35 * 36 * Primitives do minimal error checking, only to ensure buffer read/write 37 * safety. Caller is responsible for making sure correct amount of data 38 * has been processed. 39 */ 40 class MessageBuf { 41 char *data; 42 size_t size; 43 size_t pos; 44 bool readOnly; 45 public: 46 MessageBuf(char *buf, size_t bufSize) { 47 size = bufSize; 48 pos = 0; 49 data = buf; 50 readOnly = false; 51 } 52 MessageBuf(const char *buf, size_t bufSize) { 53 size = bufSize; 54 pos = 0; 55 data = const_cast<char *>(buf); 56 readOnly = true; 57 } 58 const char *getData() const { return data; } 59 size_t getSize() const { return size; } 60 size_t getPos() const { return pos; } 61 size_t getRoom() const { return size - pos; } 62 uint8_t readU8() { 63 if (pos == size) { 64 return 0; 65 } 66 return data[pos++]; 67 } 68 void writeU8(uint8_t val) { 69 if (pos == size || readOnly) 70 return; 71 data[pos++] = val; 72 } 73 uint16_t readU16() { 74 if (pos > (size - sizeof(uint16_t))) { 75 return 0; 76 } 77 uint16_t val; 78 memcpy(&val, &data[pos], sizeof(val)); 79 pos += sizeof(val); 80 return le16toh(val); 81 } 82 void writeU16(uint16_t val) { 83 if (pos > (size - sizeof(uint16_t)) || readOnly) { 84 return; 85 } 86 uint16_t tmp = htole16(val); 87 memcpy(&data[pos], &tmp, sizeof(tmp)); 88 pos += sizeof(tmp); 89 } 90 uint32_t readU32() { 91 if (pos > (size - sizeof(uint32_t))) { 92 return 0; 93 } 94 uint32_t val; 95 memcpy(&val, &data[pos], sizeof(val)); 96 pos += sizeof(val); 97 return le32toh(val); 98 } 99 void writeU32(uint32_t val) { 100 if (pos > (size - sizeof(uint32_t)) || readOnly) { 101 return; 102 } 103 uint32_t tmp = htole32(val); 104 memcpy(&data[pos], &tmp, sizeof(tmp)); 105 pos += sizeof(tmp); 106 } 107 uint64_t readU64() { 108 if (pos > (size - sizeof(uint64_t))) { 109 return 0; 110 } 111 uint64_t val; 112 memcpy(&val, &data[pos], sizeof(val)); 113 pos += sizeof(val); 114 return le32toh(val); 115 } 116 void writeU64(uint64_t val) { 117 if (pos > (size - sizeof(uint64_t)) || readOnly) { 118 return; 119 } 120 uint64_t tmp = htole64(val); 121 memcpy(&data[pos], &tmp, sizeof(tmp)); 122 pos += sizeof(tmp); 123 } 124 const void *readRaw(size_t bufSize) { 125 if (pos > (size - bufSize)) { 126 return nullptr; 127 } 128 const void *buf = &data[pos]; 129 pos += bufSize; 130 return buf; 131 } 132 void writeRaw(const void *buf, size_t bufSize) { 133 if (pos > (size - bufSize) || readOnly) { 134 return; 135 } 136 memcpy(&data[pos], buf, bufSize); 137 pos += bufSize; 138 } 139 }; 140 141 }; // namespace nanohub 142 143 }; // namespace android 144 145 #endif 146 147