11 #include <hilti/rt/extension-points.h> 12 #include <hilti/rt/iterator.h> 13 #include <hilti/rt/result.h> 14 #include <hilti/rt/types/integer.h> 15 #include <hilti/rt/types/string.h> 16 #include <hilti/rt/types/time.h> 17 #include <hilti/rt/types/vector.h> 18 #include <hilti/rt/util.h> 39 enum class Charset { Undef, UTF8, ASCII };
42 using B = std::string;
43 using difference_type = B::const_iterator::difference_type;
45 std::weak_ptr<B*> _control;
46 typename integer::safe<std::uint64_t> _index = 0;
51 Iterator(
typename B::size_type index,
const std::weak_ptr<B*> control)
52 : _control(control), _index(std::move(index)) {}
54 uint8_t operator*()
const {
55 if (
auto&& l = _control.lock() ) {
56 auto&& data =
static_cast<B&
>(**l);
58 if ( _index >= data.size() )
59 throw IndexError(
fmt(
"index %s out of bounds", _index));
64 throw InvalidIterator(
"bound object has expired");
68 auto& operator+=(
const hilti::rt::integer::safe<T>& n) {
69 return *
this += n.Ref();
72 auto& operator+=(uint64_t n) {
78 auto operator+(
const hilti::rt::integer::safe<T>& n)
const {
79 return *
this + n.Ref();
83 auto operator+(
const T& n)
const {
84 return Iterator{_index + n, _control};
87 explicit operator bool()
const {
return static_cast<bool>(_control.lock()); }
94 auto operator++(
int) {
101 if ( a._control.lock() != b._control.lock() )
102 throw InvalidArgument(
"cannot compare iterators into different bytes");
103 return a._index == b._index;
106 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
109 if ( a._control.lock() != b._control.lock() )
110 throw InvalidArgument(
"cannot compare iterators into different bytes");
111 return a._index < b._index;
115 if ( a._control.lock() != b._control.lock() )
116 throw InvalidArgument(
"cannot compare iterators into different bytes");
117 return a._index <= b._index;
121 if ( a._control.lock() != b._control.lock() )
122 throw InvalidArgument(
"cannot compare iterators into different bytes");
123 return a._index > b._index;
127 if ( a._control.lock() != b._control.lock() )
128 throw InvalidArgument(
"cannot compare iterators into different bytes");
129 return a._index >= b._index;
133 if ( a._control.lock() != b._control.lock() )
134 throw InvalidArgument(
"cannot perform arithmetic with iterators into different bytes");
135 return a._index - b._index;
141 inline std::ostream& operator<<(std::ostream& out,
const Iterator& ) {
142 out <<
"<bytes iterator>";
154 class Bytes :
protected std::string {
156 using Base = std::string;
158 using Base::const_reference;
159 using Base::reference;
160 using Offset = uint64_t;
161 using size_type = integer::safe<uint64_t>;
174 Bytes(std::string s, bytes::Charset cs);
176 Bytes(Base&& str) : Base(std::move(str)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
177 Bytes(
const Bytes& xs) : Base(xs), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
178 Bytes(
Bytes&& xs) : Base(std::move(xs)), _control(std::make_shared<Base*>(static_cast<Base*>(
this))) {}
188 invalidateIterators();
189 this->Base::operator=(b);
201 invalidateIterators();
202 this->Base::operator=(std::move(b));
213 void append(
const uint8_t x) { Base::append(1, x); }
216 const std::string&
str() const& {
return *
this; }
231 size_type
size()
const {
return static_cast<int64_t
>(std::string::size()); }
240 if (
auto i = Base::find(b, (n ? n - begin() : 0)); i != Base::npos )
266 return {substr(from - begin(), to - from)};
284 Bytes sub(Offset from, Offset to)
const {
return {substr(from, to - from)}; }
304 throw InvalidArgument(
"insufficient data in source");
306 memcpy(dst, data(), N);
307 return sub(N, std::string::npos);
317 std::string decode(bytes::Charset cs)
const;
330 Bytes upper(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::upper(decode(cs)), cs); }
337 Bytes lower(bytes::Charset cs)
const {
return Bytes(hilti::rt::string::lower(decode(cs)), cs); }
347 Bytes strip(
const Bytes&
set, bytes::Side side = bytes::Side::Both)
const;
356 Bytes strip(bytes::Side side = bytes::Side::Both)
const;
362 x.emplace_back(Bytes::Base(v));
370 std::tuple<Bytes, Bytes>
split1()
const {
372 return std::make_tuple(p.first, p.second);
379 x.push_back(Bytes::Base(v));
392 return std::make_tuple(p.first, p.second);
404 for (
size_t i = 0; i < parts.size(); ++i ) {
421 integer::safe<int64_t> toInt(uint64_t base = 10)
const;
430 integer::safe<uint64_t> toUInt(uint64_t base = 10)
const;
458 auto ns = ! isEmpty() ? toUInt(base) * integer::safe<uint64_t>(1
'000'000
'000) : integer::safe<uint64_t>(0); 459 return Time(ns, Time::NanosecondTag()); 469 Time toTime(hilti::rt::ByteOrder byte_order) const { 470 return Time(toUInt(byte_order) * integer::safe<uint64_t>(1'000
'000'000),
Time::NanosecondTag());
483 friend bool operator==(
const Bytes& a,
const Bytes& b) {
484 return static_cast<const Bytes::Base&
>(a) == static_cast<const Bytes::Base&>(b);
487 friend bool operator!=(
const Bytes& a,
const Bytes& b) {
return ! (a == b); }
490 friend bool operator<(
const Bytes& a,
const Bytes& b) {
491 return static_cast<const Bytes::Base&
>(a) < static_cast<const Bytes::Base&>(b);
494 friend bool operator<=(
const Bytes& a,
const Bytes& b) {
495 return static_cast<const Bytes::Base&
>(a) <= static_cast<const Bytes::Base&>(b);
498 friend bool operator>(
const Bytes& a,
const Bytes& b) {
499 return static_cast<const Bytes::Base&
>(a) > static_cast<const Bytes::Base&>(b);
502 friend bool operator>=(
const Bytes& a,
const Bytes& b) {
503 return static_cast<const Bytes::Base&
>(a) >= static_cast<const Bytes::Base&>(b);
507 return static_cast<const Bytes::Base&
>(a) + static_cast<const Bytes::Base&>(b);
512 std::shared_ptr<Base*> _control;
514 void invalidateIterators() { _control = std::make_shared<Base*>(
static_cast<Base*
>(
this)); }
517 inline std::ostream& operator<<(std::ostream& out,
const Bytes& x) {
518 out << escapeBytes(x.
str(),
false);
523 inline namespace literals {
524 inline Bytes operator"" _b(
const char* str,
size_t size) {
return Bytes(Bytes::Base(str, size)); }
529 inline std::string detail::to_string_for_print<Bytes>(
const Bytes& x) {
530 return escapeBytes(x.
str(),
false);
533 namespace detail::adl {
535 std::string
to_string(
const bytes::Side& x, adl::tag );
536 std::string
to_string(
const bytes::Charset& x, adl::tag );
ByteOrder
Definition: util.h:503
Bytes sub(const const_iterator &to) const
Definition: bytes.h:275
std::string to_string(T &&x)
Definition: extension-points.h:26
bool isEmpty() const
Definition: bytes.h:228
std::string to_string_for_print(const T &x)
Definition: extension-points.h:45
void append(const uint8_t x)
Definition: bytes.h:213
size_type size() const
Definition: bytes.h:231
Bytes & operator=(const Bytes &b)
Definition: bytes.h:187
Bytes sub(Offset from, Offset to) const
Definition: bytes.h:284
Bytes extract(unsigned char(&dst)[N]) const
Definition: bytes.h:302
Bytes sub(Offset to) const
Definition: bytes.h:292
std::tuple< Bytes, Bytes > split1(const Bytes &sep) const
Definition: bytes.h:390
Time toTime(uint64_t base=10) const
Definition: bytes.h:457
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:219
Bytes upper(bytes::Charset cs) const
Definition: bytes.h:330
const_iterator end() const
Definition: bytes.h:222
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:320
void append(const Bytes &d)
Definition: bytes.h:207
Bytes sub(const const_iterator &from, const const_iterator &to) const
Definition: bytes.h:265
const std::string & str() const &
Definition: bytes.h:216
Bytes & operator=(Bytes &&b)
Definition: bytes.h:200
Definition: extension-points.h:12
std::tuple< Bytes, Bytes > split1() const
Definition: bytes.h:370
Vector< Bytes > split() const
Definition: bytes.h:359
const_iterator find(value_type b, const const_iterator &n=const_iterator()) const
Definition: bytes.h:239
Bytes lower(bytes::Charset cs) const
Definition: bytes.h:337
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13
const_iterator at(Offset o) const
Definition: bytes.h:225
Vector< Bytes > split(const Bytes &sep) const
Definition: bytes.h:376
Bytes join(const Vector< T > &parts) const
Definition: bytes.h:401