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 void reset() { pos = 0; } 59 const char *getData() const { return data; } 60 size_t getSize() const { return size; } 61 size_t getPos() const { return pos; } 62 size_t getRoom() const { return size - pos; } 63 uint8_t readU8() { 64 if (pos == size) { 65 return 0; 66 } 67 return data[pos++]; 68 } 69 void writeU8(uint8_t val) { 70 if (pos == size || readOnly) 71 return; 72 data[pos++] = val; 73 } 74 uint16_t readU16() { 75 if (pos > (size - sizeof(uint16_t))) { 76 return 0; 77 } 78 uint16_t val; 79 memcpy(&val, &data[pos], sizeof(val)); 80 pos += sizeof(val); 81 return le16toh(val); 82 } 83 void writeU16(uint16_t val) { 84 if (pos > (size - sizeof(uint16_t)) || readOnly) { 85 return; 86 } 87 uint16_t tmp = htole16(val); 88 memcpy(&data[pos], &tmp, sizeof(tmp)); 89 pos += sizeof(tmp); 90 } 91 uint32_t readU32() { 92 if (pos > (size - sizeof(uint32_t))) { 93 return 0; 94 } 95 uint32_t val; 96 memcpy(&val, &data[pos], sizeof(val)); 97 pos += sizeof(val); 98 return le32toh(val); 99 } 100 void writeU32(uint32_t val) { 101 if (pos > (size - sizeof(uint32_t)) || readOnly) { 102 return; 103 } 104 uint32_t tmp = htole32(val); 105 memcpy(&data[pos], &tmp, sizeof(tmp)); 106 pos += sizeof(tmp); 107 } 108 uint64_t readU64() { 109 if (pos > (size - sizeof(uint64_t))) { 110 return 0; 111 } 112 uint64_t val; 113 memcpy(&val, &data[pos], sizeof(val)); 114 pos += sizeof(val); 115 return le32toh(val); 116 } 117 void writeU64(uint64_t val) { 118 if (pos > (size - sizeof(uint64_t)) || readOnly) { 119 return; 120 } 121 uint64_t tmp = htole64(val); 122 memcpy(&data[pos], &tmp, sizeof(tmp)); 123 pos += sizeof(tmp); 124 } 125 const void *readRaw(size_t bufSize) { 126 if (pos > (size - bufSize)) { 127 return nullptr; 128 } 129 const void *buf = &data[pos]; 130 pos += bufSize; 131 return buf; 132 } 133 void writeRaw(const void *buf, size_t bufSize) { 134 if (pos > (size - bufSize) || readOnly) { 135 return; 136 } 137 memcpy(&data[pos], buf, bufSize); 138 pos += bufSize; 139 } 140 }; 141 142 }; // namespace nanohub 143 144 }; // namespace android 145 146 #endif 147 148