11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
28PROMEKI_NAMESPACE_BEGIN
106 using List = ::promeki::List<Buffer>;
112 static size_t getPageSize();
115 static const size_t DefaultAlign;
135 Buffer(
size_t sz,
size_t an = DefaultAlign,
const MemSpace &ms = MemSpace::Default)
136 : _d(makeBufferImpl(ms, sz, an)) {}
153 static Buffer wrapHost(
void *p,
size_t sz,
size_t an = 0,
const MemSpace &ms = MemSpace::Default);
161 static Buffer fromImpl(BufferImpl *impl) {
163 if (impl !=
nullptr) b._d = BufferImplPtr::takeOwnership(impl);
185 static Result<Buffer> fromHex(
const String &hex);
200 String toHex(
const String &sep)
const;
203 String toHex()
const;
211 bool isValid()
const {
return _d.isValid() && _d->allocSize() > 0; }
233 if (!_d.isValid())
return nullptr;
234 void *base = _d->mappedHostData();
235 if (base ==
nullptr)
return nullptr;
236 return static_cast<uint8_t *
>(base) + _d->shift();
240 const void *data()
const {
241 if (!_d.isValid())
return nullptr;
242 const void *base = _d->mappedHostData();
243 if (base ==
nullptr)
return nullptr;
244 return static_cast<const uint8_t *
>(base) + _d->shift();
257 if (!_d.isValid())
return nullptr;
258 return _d->mappedHostData();
262 const void *odata()
const {
263 if (!_d.isValid())
return nullptr;
264 return _d->mappedHostData();
273 size_t size()
const {
return _d.isValid() ? _d->logicalSize() : 0; }
283 void setSize(
size_t s)
const {
284 assert(s <= availSize());
285 if (_d.isValid()) _d->setLogicalSize(s);
296 size_t availSize()
const {
297 if (!_d.isValid())
return 0;
298 size_t total = _d->allocSize();
299 size_t shift = _d->shift();
300 return shift > total ? 0 : total - shift;
304 size_t allocSize()
const {
return _d.isValid() ? _d->allocSize() : 0; }
307 size_t align()
const {
return _d.isValid() ? _d->align() : 0; }
315 MemSpace memSpace()
const {
return _d.isValid() ? _d->memSpace() : MemSpace(MemSpace::System); }
328 void shiftData(
size_t bytes) {
329 assert(_d.isValid());
330 assert(bytes <= _d->allocSize());
331 _d.modify()->setShift(bytes);
337 size_t shift()
const {
return _d.isValid() ? _d->shift() : 0; }
345 bool isMapped(MemDomain domain = MemDomain::Host)
const {
346 return _d.isValid() && _d->isMapped(domain);
354 bool isHostAccessible()
const {
return isMapped(MemDomain::Host); }
367 BufferRequest mapAcquire(MemDomain domain = MemDomain::Host, MapFlags flags = MapFlags::Read) {
368 if (!_d.isValid())
return BufferRequest::resolved(Error::Invalid);
369 return _d.modify()->mapAcquire(domain, flags);
382 BufferRequest mapRelease(MemDomain domain = MemDomain::Host) {
383 if (!_d.isValid())
return BufferRequest::resolved(Error::Invalid);
384 return _d.modify()->mapRelease(domain);
397 Error fill(
char value)
const {
398 if (!_d.isValid())
return Error::Invalid;
399 return _d.modify()->fill(value, _d->shift(), availSize());
414 Error copyFrom(
const void *src,
size_t bytes,
size_t offset = 0)
const;
438 BufferRequest copyTo(Buffer &dst,
size_t bytes,
size_t srcOffset = 0,
size_t dstOffset = 0)
const;
452 void ensureExclusive() {
453 if (!_d.isValid())
return;
454 if (_d.referenceCount() < 2)
return;
455 if (!_d->canClone())
return;
468 Error ensureExclusiveError() {
469 if (!_d.isValid())
return Error::Invalid;
470 if (_d.referenceCount() < 2)
return Error::Ok;
471 if (!_d->canClone())
return Error::NotSupported;
477 bool isExclusive()
const {
return _d.isValid() && _d.referenceCount() < 2; }
488 bool isShared()
const {
return _d.isValid() && _d.referenceCount() >= 2; }
511 [[nodiscard]] Error seal()
const {
512 if (!_d.isValid())
return Error::Invalid;
525 size_t residentBytes()
const {
526 return _d.isValid() ? _d->residentBytes() : 0;
540 bool isCowBacked()
const {
541 return _d.isValid() && _d->isCowBacked();
551 const BufferImplPtr &impl()
const {
return _d; }
571 bool operator==(
const Buffer &o)
const;
574 bool operator!=(
const Buffer &o)
const {
return !(*
this == o); }
577 explicit operator bool()
const {
return _d.isValid(); }
586 mutable BufferImplPtr _d;