11 #include <hilti/rt/extension-points.h> 12 #include <hilti/rt/iterator.h> 13 #include <hilti/rt/result.h> 14 #include <hilti/rt/types/string.h> 15 #include <hilti/rt/types/time.h> 16 #include <hilti/rt/types/vector.h> 17 #include <hilti/rt/util.h> 38 enum class Charset { Undef, UTF8, ASCII };
41 using B = std::string;
42 using difference_type = B::const_iterator::difference_type;
44 std::weak_ptr<B*> _control;
45 typename B::size_type _index = 0;
50 Iterator(
typename B::size_type index,
const std::weak_ptr<B*> control)
51 : _control(control), _index(std::move(index)) {}
53 uint8_t operator*()
const {
54 if (
auto&& l = _control.lock() ) {
55 auto&& data =
static_cast<B&
>(**l);
57 if ( _index >= data.size() )
58 throw IndexError(
fmt(
"index %s out of bounds", _index));
63 throw InvalidIterator(
"bound object has expired");
67 auto& operator+=(
const hilti::rt::integer::safe<T>& n) {
68 return *
this += n.Ref();
71 auto& operator+=(uint64_t n) {
77 auto operator+(
const hilti::rt::integer::safe<T>& n)
const {
78 return *
this + n.Ref();
82 auto operator+(
const T& n)
const {
83 return Iterator{_index + n, _control};
86 explicit operator bool()
const {
return static_cast<bool>(_control.lock()); }
93 auto operator++(
int) {
100 if ( a._control.lock() != b._control.lock() )
101 throw InvalidArgument(
"cannot compare iterators into different bytes");
102 return a._index == b._index;
105 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
108 if ( a._control.lock() != b._control.lock() )
109 throw InvalidArgument(
"cannot compare iterators into different bytes");
110 return a._index < b._index;
114 if ( a._control.lock() != b._control.lock() )
115 throw InvalidArgument(
"cannot compare iterators into different bytes");
116 return a._index <= b._index;
120 if ( a._control.lock() != b._control.lock() )
121 throw InvalidArgument(
"cannot compare iterators into different bytes");
122 return a._index > b._index;
126 if ( a._control.lock() != b._control.lock() )
127 throw InvalidArgument(
"cannot compare iterators into different bytes");
128 return a._index >= b._index;
132 if ( a._control.lock() != b._control.lock() )
133 throw InvalidArgument(
"cannot perform arithmetic with iterators into different bytes");
134 return a._index - b._index;
140 inline std::ostream& operator<<(std::ostream& out,
const Iterator& ) {
141 out <<
"<bytes iterator>";
153 class Bytes :
protected std::string {
155 using Base = std::string;
157 using Base::const_reference;
158 using Base::reference;
159 using Offset = uint64_t;
172 Bytes(std::string s, bytes::Charset cs);
174 Bytes(Base&& str) : Base(std::move(str)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
175 Bytes(
const Bytes& xs) : Base(xs), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
176 Bytes(
Bytes&& xs) : Base(std::move(xs)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
186 invalidateIterators();
187 this->Base::operator=(b);
199 invalidateIterators();
200 this->Base::operator=(std::move(b));
211 void append(
const uint8_t x) { Base::append(1, x); }
214 const std::string&
str() const& {
return *
this; }
229 int64_t
size()
const {
return static_cast<int64_t
>(std::string::size()); }
238 if (
auto i = Base::find(b, (n ? n - begin() : 0)); i != Base::npos )
264 return {substr(from - begin(), to - from)};
282 Bytes sub(Offset from, Offset to)
const {
return {substr(from, to - from)}; }
302 throw InvalidArgument(
"insufficient data in source");
304 memcpy(dst, data(), N);
305 return sub(N, std::string::npos);
315 std::string decode(bytes::Charset cs)
const;
328 Bytes upper(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::upper(decode(cs)), cs); }
335 Bytes lower(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::lower(decode(cs)), cs); }
345 Bytes strip(
const Bytes&
set, bytes::Side side = bytes::Side::Both)
const;
354 Bytes strip(bytes::Side side = bytes::Side::Both)
const;
360 x.emplace_back(Bytes::Base(v));
368 std::tuple<Bytes, Bytes>
split1()
const {
370 return std::make_tuple(p.first, p.second);
377 x.push_back(Bytes::Base(v));
390 return std::make_tuple(p.first, p.second);
402 for (
size_t i = 0; i < parts.size(); ++i ) {
419 integer::safe<int64_t> toInt(uint64_t base = 10)
const;
428 integer::safe<uint64_t> toUInt(uint64_t base = 10)
const;
456 auto ns = ! isEmpty() ? toUInt(base) * integer::safe<uint64_t>(1
'000'000
'000) : integer::safe<uint64_t>(0); 457 return Time(ns, Time::NanosecondTag()); 467 Time toTime(hilti::rt::ByteOrder byte_order) const { 468 return Time(toUInt(byte_order) * integer::safe<uint64_t>(1'000
'000'000),
Time::NanosecondTag());
481 friend bool operator==(
const Bytes& a,
const Bytes& b) {
482 return static_cast<const Bytes::Base&
>(a) == static_cast<const Bytes::Base&>(b);
485 friend bool operator!=(
const Bytes& a,
const Bytes& b) {
return ! (a == b); }
488 friend bool operator<(
const Bytes& a,
const Bytes& b) {
489 return static_cast<const Bytes::Base&
>(a) < static_cast<const Bytes::Base&>(b);
492 friend bool operator<=(
const Bytes& a,
const Bytes& b) {
493 return static_cast<const Bytes::Base&
>(a) <= static_cast<const Bytes::Base&>(b);
496 friend bool operator>(
const Bytes& a,
const Bytes& b) {
497 return static_cast<const Bytes::Base&
>(a) > static_cast<const Bytes::Base&>(b);
500 friend bool operator>=(
const Bytes& a,
const Bytes& b) {
501 return static_cast<const Bytes::Base&
>(a) >= static_cast<const Bytes::Base&>(b);
505 return static_cast<const Bytes::Base&
>(a) + static_cast<const Bytes::Base&>(b);
510 std::shared_ptr<Base*> _control;
512 void invalidateIterators() { _control = std::make_shared<Base*>(
static_cast<Base*
>(
this)); }
515 inline std::ostream& operator<<(std::ostream& out,
const Bytes& x) {
516 out << escapeBytes(x.
str(),
false);
521 inline namespace literals {
522 inline Bytes operator"" _b(
const char* str,
size_t size) {
return Bytes(Bytes::Base(str, size)); }
527 inline std::string detail::to_string_for_print<Bytes>(
const Bytes& x) {
528 return escapeBytes(x.
str(),
false);
531 namespace detail::adl {
533 std::string
to_string(
const bytes::Side& x, adl::tag );
534 std::string
to_string(
const bytes::Charset& x, adl::tag );
ByteOrder
Definition: util.h:515
Bytes sub(const const_iterator &to) const
Definition: bytes.h:273
std::string to_string(T &&x)
Definition: extension-points.h:26
bool isEmpty() const
Definition: bytes.h:226
std::string to_string_for_print(const T &x)
Definition: extension-points.h:45
void append(const uint8_t x)
Definition: bytes.h:211
Bytes & operator=(const Bytes &b)
Definition: bytes.h:185
Bytes sub(Offset from, Offset to) const
Definition: bytes.h:282
Bytes extract(unsigned char(&dst)[N]) const
Definition: bytes.h:300
Bytes sub(Offset to) const
Definition: bytes.h:290
std::tuple< Bytes, Bytes > split1(const Bytes &sep) const
Definition: bytes.h:388
Time toTime(uint64_t base=10) const
Definition: bytes.h:455
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:200
const_iterator begin() const
Definition: bytes.h:217
int64_t size() const
Definition: bytes.h:229
Bytes upper(bytes::Charset cs) const
Definition: bytes.h:328
const_iterator end() const
Definition: bytes.h:220
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:318
void append(const Bytes &d)
Definition: bytes.h:205
Bytes sub(const const_iterator &from, const const_iterator &to) const
Definition: bytes.h:263
const std::string & str() const &
Definition: bytes.h:214
Bytes & operator=(Bytes &&b)
Definition: bytes.h:198
Definition: extension-points.h:12
std::tuple< Bytes, Bytes > split1() const
Definition: bytes.h:368
Vector< Bytes > split() const
Definition: bytes.h:357
const_iterator find(value_type b, const const_iterator &n=const_iterator()) const
Definition: bytes.h:237
Bytes lower(bytes::Charset cs) const
Definition: bytes.h:335
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13
const_iterator at(Offset o) const
Definition: bytes.h:223
Vector< Bytes > split(const Bytes &sep) const
Definition: bytes.h:374
Bytes join(const Vector< T > &parts) const
Definition: bytes.h:399