11 #include <hilti/rt/extension-points.h> 12 #include <hilti/rt/iterator.h> 13 #include <hilti/rt/json-fwd.h> 14 #include <hilti/rt/result.h> 15 #include <hilti/rt/types/integer.h> 16 #include <hilti/rt/types/string.h> 17 #include <hilti/rt/types/time.h> 18 #include <hilti/rt/types/vector.h> 19 #include <hilti/rt/util.h> 33 enum class Side : int64_t {
40 enum class Charset : int64_t { Undef, UTF8, ASCII };
43 using B = std::string;
44 using difference_type = B::const_iterator::difference_type;
46 std::weak_ptr<B*> _control;
47 typename integer::safe<std::uint64_t> _index = 0;
52 Iterator(
typename B::size_type index,
const std::weak_ptr<B*> control)
53 : _control(control), _index(std::move(index)) {}
55 uint8_t operator*()
const {
56 if (
auto&& l = _control.lock() ) {
57 auto&& data =
static_cast<B&
>(**l);
59 if ( _index >= data.size() )
60 throw IndexError(
fmt(
"index %s out of bounds", _index));
65 throw InvalidIterator(
"bound object has expired");
69 auto& operator+=(
const hilti::rt::integer::safe<T>& n) {
70 return *
this += n.Ref();
73 auto& operator+=(uint64_t n) {
79 auto operator+(
const hilti::rt::integer::safe<T>& n)
const {
80 return *
this + n.Ref();
84 auto operator+(
const T& n)
const {
85 return Iterator{_index + n, _control};
88 explicit operator bool()
const {
return static_cast<bool>(_control.lock()); }
95 const auto operator++(
int) {
102 if ( a._control.lock() != b._control.lock() )
103 throw InvalidArgument(
"cannot compare iterators into different bytes");
104 return a._index == b._index;
107 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
110 if ( a._control.lock() != b._control.lock() )
111 throw InvalidArgument(
"cannot compare iterators into different bytes");
112 return a._index < b._index;
116 if ( a._control.lock() != b._control.lock() )
117 throw InvalidArgument(
"cannot compare iterators into different bytes");
118 return a._index <= b._index;
122 if ( a._control.lock() != b._control.lock() )
123 throw InvalidArgument(
"cannot compare iterators into different bytes");
124 return a._index > b._index;
128 if ( a._control.lock() != b._control.lock() )
129 throw InvalidArgument(
"cannot compare iterators into different bytes");
130 return a._index >= b._index;
134 if ( a._control.lock() != b._control.lock() )
135 throw InvalidArgument(
"cannot perform arithmetic with iterators into different bytes");
136 return a._index - b._index;
142 inline std::ostream& operator<<(std::ostream& out,
const Iterator& ) {
143 out <<
"<bytes iterator>";
155 class Bytes :
protected std::string {
157 using Base = std::string;
159 using Base::const_reference;
160 using Base::reference;
161 using Offset = uint64_t;
162 using size_type = integer::safe<uint64_t>;
175 Bytes(std::string s, bytes::Charset cs);
177 Bytes(Base&& str) : Base(std::move(str)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
178 Bytes(
const Bytes& xs) : Base(xs), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
179 Bytes(
Bytes&& xs) : Base(std::move(xs)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
189 invalidateIterators();
190 this->Base::operator=(b);
202 invalidateIterators();
203 this->Base::operator=(std::move(b));
214 void append(
const uint8_t x) { Base::append(1, x); }
217 const std::string&
str() const& {
return *
this; }
232 size_type
size()
const {
return static_cast<int64_t
>(std::string::size()); }
241 if (
auto i = Base::find(b, (n ? n - begin() : 0)); i != Base::npos )
267 return {substr(from - begin(), to - from)};
285 Bytes sub(Offset from, Offset to)
const {
return {substr(from, to - from)}; }
305 throw InvalidArgument(
"insufficient data in source");
307 memcpy(dst, data(), N);
308 return sub(N, std::string::npos);
318 std::string decode(bytes::Charset cs)
const;
331 Bytes upper(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::upper(decode(cs)), cs); }
338 Bytes lower(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::lower(decode(cs)), cs); }
348 Bytes strip(
const Bytes&
set, bytes::Side side = bytes::Side::Both)
const;
357 Bytes strip(bytes::Side side = bytes::Side::Both)
const;
363 x.emplace_back(Bytes::Base(v));
371 std::tuple<Bytes, Bytes>
split1()
const {
373 return std::make_tuple(p.first, p.second);
380 x.push_back(Bytes::Base(v));
393 return std::make_tuple(p.first, p.second);
405 for (
size_t i = 0; i < parts.size(); ++i ) {
422 integer::safe<int64_t> toInt(uint64_t base = 10)
const;
431 integer::safe<uint64_t> toUInt(uint64_t base = 10)
const;
459 auto ns = ! isEmpty() ? toUInt(base) * integer::safe<uint64_t>(1
'000'000
'000) : integer::safe<uint64_t>(0); 460 return Time(ns, Time::NanosecondTag()); 470 Time toTime(hilti::rt::ByteOrder byte_order) const { 471 return Time(toUInt(byte_order) * integer::safe<uint64_t>(1'000
'000'000),
Time::NanosecondTag());
484 friend bool operator==(
const Bytes& a,
const Bytes& b) {
485 return static_cast<const Bytes::Base&
>(a) == static_cast<const Bytes::Base&>(b);
488 friend bool operator!=(
const Bytes& a,
const Bytes& b) {
return ! (a == b); }
491 friend bool operator<(
const Bytes& a,
const Bytes& b) {
492 return static_cast<const Bytes::Base&
>(a) < static_cast<const Bytes::Base&>(b);
495 friend bool operator<=(
const Bytes& a,
const Bytes& b) {
496 return static_cast<const Bytes::Base&
>(a) <= static_cast<const Bytes::Base&>(b);
499 friend bool operator>(
const Bytes& a,
const Bytes& b) {
500 return static_cast<const Bytes::Base&
>(a) > static_cast<const Bytes::Base&>(b);
503 friend bool operator>=(
const Bytes& a,
const Bytes& b) {
504 return static_cast<const Bytes::Base&
>(a) >= static_cast<const Bytes::Base&>(b);
508 return static_cast<const Bytes::Base&
>(a) + static_cast<const Bytes::Base&>(b);
513 std::shared_ptr<Base*> _control;
515 void invalidateIterators() { _control = std::make_shared<Base*>(
static_cast<Base*
>(
this)); }
518 inline std::ostream& operator<<(std::ostream& out,
const Bytes& x) {
519 out << escapeBytes(x.
str(),
false);
524 inline namespace literals {
525 inline Bytes operator"" _b(
const char* str,
size_t size) {
return Bytes(Bytes::Base(str, size)); }
530 inline std::string detail::to_string_for_print<Bytes>(
const Bytes& x) {
531 return escapeBytes(x.
str(),
false);
534 namespace detail::adl {
536 std::string
to_string(
const bytes::Side& x, adl::tag );
537 std::string
to_string(
const bytes::Charset& x, adl::tag );
550 struct adl_serializer<
hilti::rt::Bytes> {};
Bytes sub(const const_iterator &to) const
Definition: bytes.h:276
std::string to_string(T &&x)
Definition: extension-points.h:26
bool isEmpty() const
Definition: bytes.h:229
std::string to_string_for_print(const T &x)
Definition: extension-points.h:45
void append(const uint8_t x)
Definition: bytes.h:214
size_type size() const
Definition: bytes.h:232
Bytes & operator=(const Bytes &b)
Definition: bytes.h:188
Bytes sub(Offset from, Offset to) const
Definition: bytes.h:285
Bytes extract(unsigned char(&dst)[N]) const
Definition: bytes.h:303
Bytes sub(Offset to) const
Definition: bytes.h:293
std::tuple< Bytes, Bytes > split1(const Bytes &sep) const
Definition: bytes.h:391
Time toTime(uint64_t base=10) const
Definition: bytes.h:458
std::pair< std::string, std::string > split1(std::string s)
Definition: util.cc:156
bool startsWith(const std::string &s, const std::string &prefix)
Definition: util.h:201
const_iterator begin() const
Definition: bytes.h:220
Bytes upper(bytes::Charset cs) const
Definition: bytes.h:331
Definition: stream.h:1001
const_iterator end() const
Definition: bytes.h:223
std::vector< std::string_view > split(std::string_view s, std::string_view delim)
Definition: util.cc:112
bool startsWith(const Bytes &b) const
Definition: bytes.h:321
void append(const Bytes &d)
Definition: bytes.h:208
ByteOrder
Definition: util.h:504
Bytes sub(const const_iterator &from, const const_iterator &to) const
Definition: bytes.h:266
const std::string & str() const &
Definition: bytes.h:217
Bytes & operator=(Bytes &&b)
Definition: bytes.h:201
Definition: extension-points.h:12
std::tuple< Bytes, Bytes > split1() const
Definition: bytes.h:371
Vector< Bytes > split() const
Definition: bytes.h:360
const_iterator find(value_type b, const const_iterator &n=const_iterator()) const
Definition: bytes.h:240
Bytes lower(bytes::Charset cs) const
Definition: bytes.h:338
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13
const_iterator at(Offset o) const
Definition: bytes.h:226
Vector< Bytes > split(const Bytes &sep) const
Definition: bytes.h:377
Bytes join(const Vector< T > &parts) const
Definition: bytes.h:402