runtime/byteslike.h (59 lines of code) (raw):

/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */ #pragma once #include "globals.h" #include "handles.h" #include "objects.h" namespace py { // A generic handle allowing uniform use of bytes-like objects, which are // objects that implement the buffer protocol in CPython. class Byteslike { public: // Initialize handle. It is allowed to pass a non-byteslike object and then // use `isValid()` to test. The other methods must only be called when a // byteslike object was used in the constructor. Byteslike(HandleScope* scope, Thread* thread, RawObject object); ~Byteslike(); uword address() const; byte byteAt(word index) const; void copyTo(byte* dst, word length) const; void copyToStartAt(byte* dst, word length, word index) const; bool isValid() const; word length() const; private: void initWithLargeBytes(HandleScope* scope, RawLargeBytes bytes, word length); void initWithMemory(byte* data, word length); void initWithSmallData(RawSmallBytes bytes, word length); union { uword reference; struct { RawObject object; Thread* thread; } handle; struct { uword reference; RawSmallBytes small_storage; } small; } d_; Handle<RawObject>* next_; word length_; }; inline Byteslike::~Byteslike() { if (next_ != nullptr) { d_.handle.thread->handles()->pop(next_); } } inline uword Byteslike::address() const { return d_.reference - RawObject::kHeapObjectTag; } inline byte Byteslike::byteAt(word index) const { DCHECK_INDEX(index, length()); return *reinterpret_cast<byte*>(address() + index); } inline void Byteslike::copyTo(byte* dst, word length) const { DCHECK_BOUND(length, this->length()); std::memcpy(dst, reinterpret_cast<void*>(address()), length); } inline void Byteslike::copyToStartAt(byte* dst, word length, word index) const { DCHECK_BOUND(index + length, this->length()); std::memcpy(dst, reinterpret_cast<void*>(address() + index), length); } inline bool Byteslike::isValid() const { return !d_.handle.object.isErrorError(); } inline word Byteslike::length() const { return length_; } // Converts byteslike into a string representation. // Scans bytes to select an appropriate delimiter (single or double quotes). RawObject byteslikeReprSmartQuotes(Thread* thread, const Byteslike& byteslike); } // namespace py