#ifndef __CEPH_DECODE_H #define __CEPH_DECODE_H #include /* * in all cases, * void **p pointer to position pointer * void *end pointer to end of buffer (last byte + 1) */ /* * bounds check input. */ #define ceph_decode_need(p, end, n, bad) \ do { \ if (unlikely(*(p) + (n) > (end))) \ goto bad; \ } while (0) #define ceph_decode_64(p, v) \ do { \ v = get_unaligned_le64(*(p)); \ *(p) += sizeof(u64); \ } while (0) #define ceph_decode_32(p, v) \ do { \ v = get_unaligned_le32(*(p)); \ *(p) += sizeof(u32); \ } while (0) #define ceph_decode_16(p, v) \ do { \ v = get_unaligned_le16(*(p)); \ *(p) += sizeof(u16); \ } while (0) #define ceph_decode_8(p, v) \ do { \ v = *(u8 *)*(p); \ (*p)++; \ } while (0) #define ceph_decode_copy(p, pv, n) \ do { \ memcpy(pv, *(p), n); \ *(p) += n; \ } while (0) /* bounds check too */ #define ceph_decode_64_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u64), bad); \ ceph_decode_64(p, v); \ } while (0) #define ceph_decode_32_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u32), bad); \ ceph_decode_32(p, v); \ } while (0) #define ceph_decode_16_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u16), bad); \ ceph_decode_16(p, v); \ } while (0) #define ceph_decode_copy_safe(p, end, pv, n, bad) \ do { \ ceph_decode_need(p, end, n, bad); \ ceph_decode_copy(p, pv, n); \ } while (0) /* * struct ceph_timespec <-> struct timespec */ #define ceph_decode_timespec(ts, tv) \ do { \ (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \ (ts)->tv_nsec = le32_to_cpu((tv)->tv_nsec); \ } while (0) #define ceph_encode_timespec(tv, ts) \ do { \ (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \ (tv)->tv_nsec = cpu_to_le32((ts)->tv_nsec); \ } while (0) /* * encoders */ #define ceph_encode_64(p, v) \ do { \ put_unaligned_le64(v, (__le64 *)*(p)); \ *(p) += sizeof(u64); \ } while (0) #define ceph_encode_32(p, v) \ do { \ put_unaligned_le32(v, (__le32 *)*(p)); \ *(p) += sizeof(u32); \ } while (0) #define ceph_encode_16(p, v) \ do { \ put_unaligned_le16(v), (__le16 *)*(p)); \ *(p) += sizeof(u16); \ } while (0) #define ceph_encode_8(p, v) \ do { \ *(u8 *)*(p) = v; \ (*(p))++; \ } while (0) /* * filepath, string encoders */ static inline void ceph_encode_filepath(void **p, void *end, u64 ino, const char *path) { u32 len = path ? strlen(path) : 0; BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); ceph_encode_64(p, ino); ceph_encode_32(p, len); if (len) memcpy(*p, path, len); *p += len; } static inline void ceph_encode_string(void **p, void *end, const char *s, u32 len) { BUG_ON(*p + sizeof(len) + len > end); ceph_encode_32(p, len); if (len) memcpy(*p, s, len); *p += len; } #endif