| | |
| | | //*/ |
| | | const uint32_t kMsgTag = 0xf1e2d3c4; |
| | | |
| | | void *MsgI::Alloc(SharedMemory &shm, const size_t size) |
| | | { |
| | | void *p = shm.Alloc(sizeof(Meta) + size); |
| | | if (p) { |
| | | auto pmeta = new (p) Meta; |
| | | p = pmeta + 1; |
| | | } |
| | | return p; |
| | | } |
| | | void MsgI::Free(SharedMemory &shm) |
| | | { |
| | | assert(valid()); |
| | | shm.Dealloc(meta()); |
| | | ptr_ = nullptr; |
| | | assert(!valid()); |
| | | } |
| | | |
| | | void *MsgI::Pack(SharedMemory &shm, |
| | | const uint32_t head_len, const ToArray &headToArray, |
| | | const uint32_t body_len, const ToArray &bodyToArray) |
| | | { |
| | | void *addr = shm.Alloc(sizeof(head_len) + head_len + sizeof(body_len) + body_len); |
| | | void *addr = Alloc(shm, sizeof(head_len) + head_len + sizeof(body_len) + body_len); |
| | | if (addr) { |
| | | auto p = static_cast<char *>(addr); |
| | | auto Pack1 = [&p](auto len, auto &writer) { |
| | |
| | | |
| | | bool MsgI::ParseHead(BHMsgHead &head) const |
| | | { |
| | | auto p = static_cast<char *>(ptr_.get()); |
| | | auto p = get<char>(); |
| | | assert(p); |
| | | uint32_t msg_size = Get32(p); |
| | | p += 4; |
| | | return head.ParseFromArray(p, msg_size); |
| | | } |
| | | |
| | | // with ref count; |
| | | bool MsgI::MakeRC(SharedMemory &shm, void *p) |
| | | { |
| | | if (!p) { |
| | | return false; |
| | | } |
| | | RefCount *rc = shm.New<RefCount>(); |
| | | if (!rc) { |
| | | shm.Dealloc(p); |
| | | return false; |
| | | } |
| | | MsgI(p, rc).swap(*this); |
| | | return true; |
| | | } |
| | | |
| | | bool MsgI::Make(SharedMemory &shm, void *p) |
| | |
| | | if (!p) { |
| | | return false; |
| | | } |
| | | MsgI(p, 0).swap(*this); |
| | | MsgI(p).swap(*this); |
| | | return true; |
| | | } |
| | | |
| | | bool MsgI::EnableRefCount(SharedMemory &shm) |
| | | { |
| | | if (!IsCounted()) { |
| | | count_ = shm.New<RefCount>(); |
| | | } |
| | | return IsCounted(); |
| | | } |
| | | |
| | | int MsgI::Release(SharedMemory &shm) |
| | | { |
| | | if (IsCounted()) { |
| | | const int n = count_->Dec(); |
| | | if (n != 0) { |
| | | return n; |
| | | } |
| | | if (!valid()) { |
| | | return 0; |
| | | } |
| | | // free data |
| | | shm.Dealloc(ptr_); |
| | | ptr_ = 0; |
| | | shm.Delete(count_); |
| | | count_ = 0; |
| | | return 0; |
| | | auto n = meta()->count_.Dec(); |
| | | if (n == 0) { |
| | | Free(shm); |
| | | } |
| | | return n; |
| | | } |
| | | |
| | | } // namespace bhome_msg |