// // mp::byte_array // // Copyright (C) 2008 FURUHASHI Sadayuki // // Licensed 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 MP_BYTE_ARRAY_IMPL_H__ #define MP_BYTE_ARRAY_IMPL_H__ #include #include #include #include "mp/serialize.h" namespace mp { template byte_array::byte_array(size_type initial_size) : storage(get_allocator().allocate(initial_size)), start(storage), finish(storage), allocated_end(storage + initial_size) { } template byte_array::~byte_array() { get_allocator().deallocate(storage, allocated_size()); } template typename byte_array::iterator byte_array::begin() { return start; } template typename byte_array::const_iterator byte_array::begin() const { return start; } template typename byte_array::iterator byte_array::end() { return finish; } template typename byte_array::const_iterator byte_array::end() const { return finish; } template bool byte_array::empty() const { return finish == start; } template typename byte_array::size_type byte_array::size() const { return finish - start; } template typename byte_array::size_type byte_array::capacity() const { return allocated_end - start; } template void byte_array::produced(size_type produced_size) { finish += produced_size; } template void byte_array::consumed(size_type consumed_size) { if(consumed_size == size()) { clear(); } else { start += consumed_size; } } template void byte_array::clear() { start = finish = storage; } template typename byte_array::size_type byte_array::space() const { return allocated_end - finish; } template void byte_array::reserve(size_type new_size) { if(capacity() >= new_size) { return; } size_type size_save = size(); if(allocated_size() >= new_size) { ::memmove(storage, start, size_save); } else { char* tmp = get_allocator().allocate(new_size); ::memcpy(tmp, start, size_save); get_allocator().deallocate(storage, allocated_size()); storage = tmp; } start = storage; finish = start + size_save; } template void byte_array::reserve_space(size_type required_size) { reserve(size() + required_size); } template typename byte_array::size_type byte_array::allocated_size() const { return allocated_end - storage; } template typename byte_array::allocator_type byte_array::get_allocator() const { return allocator_type(); } template void byte_array::swap(byte_array& other) { std::swap(storage, other.storage); std::swap(start, other.start); std::swap(finish, other.finish); std::swap(allocated_end, other.allocated_end); } template void byte_array::read(void* buffer, size_type size) { ::memcpy(buffer, begin(), size); consumed(size); } template void byte_array::write(const void* buffer, size_type size) { reserve_space(size); ::memcpy(end(), buffer, size); produced(size); } MP_ARGS_BEGIN template template void byte_array::read(MP_ARGS_PARAMS_PTR) { size_t req_size = 0 MP_ARGS_ITERATOR_BEGIN + sizeof(MP_ARGS_ITERATOR_TYPE) MP_ARGS_ITERATOR_END ; load(begin(), MP_ARGS_FUNC); consumed(req_size); } MP_ARGS_END MP_ARGS_BEGIN template template void byte_array::write(MP_ARGS_PARAMS) { size_t req_size = 0 MP_ARGS_ITERATOR_BEGIN + sizeof(MP_ARGS_ITERATOR_TYPE) MP_ARGS_ITERATOR_END ; reserve_space(req_size); dump(end(), MP_ARGS_FUNC); produced(req_size); } MP_ARGS_END } // namespace mp #endif /* mp/byte_array.h */