blob: d4f8167fc7e22174401ee20f204c73a8838ce425 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#ifndef BUTIL_RAW_PACK_H
#define BUTIL_RAW_PACK_H
#include "butil/sys_byteorder.h"
namespace butil {
// -------------------------------------------------------------------------
// NOTE: RawPacker/RawUnpacker is used for packing/unpacking low-level and
// hard-to-change header. If the fields are likely to be changed in future,
// use protobuf.
// -------------------------------------------------------------------------
// This utility class packs 32-bit and 64-bit integers into binary data
// that can be unpacked by RawUnpacker. Notice that the packed data is
// schemaless and user must match pack..() methods with same-width
// unpack..() methods to get the integers back.
// Example:
// char buf[16]; // 4 + 8 + 4 bytes.
// butil::RawPacker(buf).pack32(a).pack64(b).pack32(c); // buf holds packed data
//
// ... network ...
//
// // positional correspondence with pack..()
// butil::Unpacker(buf2).unpack32(a).unpack64(b).unpack32(c);
class RawPacker {
public:
// Notice: User must guarantee `stream' is as long as the packed data.
explicit RawPacker(void* stream) : _stream((char*)stream) {}
~RawPacker() {}
// Not using operator<< because some values may be packed differently from
// its type.
RawPacker& pack32(uint32_t host_value) {
*(uint32_t*)_stream = HostToNet32(host_value);
_stream += 4;
return *this;
}
RawPacker& pack64(uint64_t host_value) {
uint32_t *p = (uint32_t*)_stream;
p[0] = HostToNet32(host_value >> 32);
p[1] = HostToNet32(host_value & 0xFFFFFFFF);
_stream += 8;
return *this;
}
private:
char* _stream;
};
// This utility class unpacks 32-bit and 64-bit integers from binary data
// packed by RawPacker.
class RawUnpacker {
public:
explicit RawUnpacker(const void* stream) : _stream((const char*)stream) {}
~RawUnpacker() {}
RawUnpacker& unpack32(uint32_t & host_value) {
host_value = NetToHost32(*(const uint32_t*)_stream);
_stream += 4;
return *this;
}
RawUnpacker& unpack64(uint64_t & host_value) {
const uint32_t *p = (const uint32_t*)_stream;
host_value = (((uint64_t)NetToHost32(p[0])) << 32) | NetToHost32(p[1]);
_stream += 8;
return *this;
}
private:
const char* _stream;
};
} // namespace butil
#endif // BUTIL_RAW_PACK_H