this repo has no description
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */
2#pragma once
3
4#include "globals.h"
5#include "handles.h"
6#include "objects.h"
7
8namespace py {
9
10// A generic handle allowing uniform use of bytes-like objects, which are
11// objects that implement the buffer protocol in CPython.
12class Byteslike {
13 public:
14 // Initialize handle. It is allowed to pass a non-byteslike object and then
15 // use `isValid()` to test. The other methods must only be called when a
16 // byteslike object was used in the constructor.
17 Byteslike(HandleScope* scope, Thread* thread, RawObject object);
18 ~Byteslike();
19
20 uword address() const;
21
22 byte byteAt(word index) const;
23
24 void copyTo(byte* dst, word length) const;
25
26 void copyToStartAt(byte* dst, word length, word index) const;
27
28 bool isValid() const;
29
30 word length() const;
31
32 private:
33 void initWithLargeBytes(HandleScope* scope, RawLargeBytes bytes, word length);
34 void initWithMemory(byte* data, word length);
35 void initWithSmallData(RawSmallBytes bytes, word length);
36
37 union {
38 uword reference;
39 struct {
40 RawObject object;
41 Thread* thread;
42 } handle;
43 struct {
44 uword reference;
45 RawSmallBytes small_storage;
46 } small;
47 } d_;
48 Handle<RawObject>* next_;
49 word length_;
50};
51
52inline Byteslike::~Byteslike() {
53 if (next_ != nullptr) {
54 d_.handle.thread->handles()->pop(next_);
55 }
56}
57
58inline uword Byteslike::address() const {
59 return d_.reference - RawObject::kHeapObjectTag;
60}
61
62inline byte Byteslike::byteAt(word index) const {
63 DCHECK_INDEX(index, length());
64 return *reinterpret_cast<byte*>(address() + index);
65}
66
67inline void Byteslike::copyTo(byte* dst, word length) const {
68 DCHECK_BOUND(length, this->length());
69 std::memcpy(dst, reinterpret_cast<void*>(address()), length);
70}
71
72inline void Byteslike::copyToStartAt(byte* dst, word length, word index) const {
73 DCHECK_BOUND(index + length, this->length());
74 std::memcpy(dst, reinterpret_cast<void*>(address() + index), length);
75}
76
77inline bool Byteslike::isValid() const {
78 return !d_.handle.object.isErrorError();
79}
80
81inline word Byteslike::length() const { return length_; }
82
83// Converts byteslike into a string representation.
84// Scans bytes to select an appropriate delimiter (single or double quotes).
85RawObject byteslikeReprSmartQuotes(Thread* thread, const Byteslike& byteslike);
86
87} // namespace py