aboutsummaryrefslogtreecommitdiff
path: root/buffer_source.h
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2018-03-13 18:19:34 +0000
committerEdward Lesmes <ehmaldonado@google.com>2021-07-23 21:50:59 +0000
commit06f1ae9aaca969ee95ef840f22b6b461c304542d (patch)
treef1e5c6624e70628e81fbf38d6cd14b974abe5d93 /buffer_source.h
downloadzucchini-06f1ae9aaca969ee95ef840f22b6b461c304542d.tar.gz
[Zucchini] Move Zucchini from /chrome/installer/ to /components/.
(Use "git log --follow" to see older revisions of files). /components/ is the most logical place to put Zucchini, which only depends on /base and /testing/gtest. This move also enables Zucchini to be used by the Component Updater. Details: - Move all files; run the following to change deps and guards: sed 's/chrome\/installer/components/' *.cc *.h -i sed 's/CHROME_INSTALLER/COMPONENTS/' *.cc *.h -i - Sorting works out pretty well! - Change all 'chrome/installer/zucchini' to 'components/zucchini' throughout other parts of the repo; sort if necessary. - Fix 6 'git cl lint' errors. - Change 1 Bind() usage to BindRepeated(). - Update OWNER. Bug: 729154 Change-Id: I50c5a7d411ea85f707b5994ab319dfb2a1acccf7 Reviewed-on: https://chromium-review.googlesource.com/954923 Reviewed-by: Greg Thompson <grt@chromium.org> Reviewed-by: Jochen Eisinger <jochen@chromium.org> Reviewed-by: Samuel Huang <huangs@chromium.org> Commit-Queue: Samuel Huang <huangs@chromium.org> Cr-Commit-Position: refs/heads/master@{#542857} NOKEYCHECK=True GitOrigin-RevId: 577ef6c435e8d43be6e3e60ccbcbd1881780f4ec
Diffstat (limited to 'buffer_source.h')
-rw-r--r--buffer_source.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/buffer_source.h b/buffer_source.h
new file mode 100644
index 0000000..d2a05b0
--- /dev/null
+++ b/buffer_source.h
@@ -0,0 +1,141 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_ZUCCHINI_BUFFER_SOURCE_H_
+#define COMPONENTS_ZUCCHINI_BUFFER_SOURCE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <initializer_list>
+#include <type_traits>
+
+#include "base/logging.h"
+#include "components/zucchini/buffer_view.h"
+
+namespace zucchini {
+
+// BufferSource acts like an input stream with convenience methods to parse data
+// from a contiguous sequence of raw data. The underlying ConstBufferView
+// emulates a cursor to track current read position, and guards against buffer
+// overrun. Where applicable, BufferSource should be passed by pointer to
+// maintain cursor progress across reads.
+class BufferSource : public ConstBufferView {
+ public:
+ // LEB128 info: http://dwarfstd.org/doc/dwarf-2.0.0.pdf , Section 7.6.
+ enum : size_t { kMaxLeb128Size = 5 };
+
+ static BufferSource FromRange(const_iterator first, const_iterator last) {
+ return BufferSource(ConstBufferView::FromRange(first, last));
+ }
+
+ using ConstBufferView::ConstBufferView;
+ BufferSource() = default;
+ explicit BufferSource(ConstBufferView buffer);
+ BufferSource(const BufferSource&) = default;
+ BufferSource& operator=(BufferSource&&) = default;
+
+ // Moves the cursor forward by |n| bytes, or to the end if data is exhausted.
+ // Returns a reference to *this, to allow chaining, e.g.:
+ // if (!buffer_source.Skip(1024).GetValue<uint32_t>(&value)) {
+ // ... // Handle error.
+ // }
+ // Notice that Skip() defers error handling to GetValue().
+ BufferSource& Skip(size_type n);
+
+ // Returns true if |value| matches data starting at the cursor when
+ // reinterpreted as the integral type |T|.
+ template <class T>
+ bool CheckNextValue(const T& value) const {
+ static_assert(std::is_integral<T>::value,
+ "Value type must be an integral type");
+ DCHECK_NE(begin(), nullptr);
+ if (Remaining() < sizeof(T))
+ return false;
+ return value == *reinterpret_cast<const T*>(begin());
+ }
+
+ // Returns true if the next bytes.size() bytes at the cursor match those in
+ // |bytes|.
+ bool CheckNextBytes(std::initializer_list<uint8_t> bytes) const;
+
+ // Same as CheckNextBytes(), but moves the cursor by bytes.size() if read is
+ // successfull.
+ bool ConsumeBytes(std::initializer_list<uint8_t> bytes);
+
+ // Tries to reinterpret data as type |T|, starting at the cursor and to write
+ // the result into |value|, while moving the cursor forward by sizeof(T).
+ // Returns true if sufficient data is available, and false otherwise.
+ template <class T>
+ bool GetValue(T* value) {
+ static_assert(std::is_standard_layout<T>::value,
+ "Value type must be a standard layout type");
+
+ DCHECK_NE(begin(), nullptr);
+ if (Remaining() < sizeof(T))
+ return false;
+ *value = *reinterpret_cast<const T*>(begin());
+ remove_prefix(sizeof(T));
+ return true;
+ }
+
+ // Tries to reinterpret data as type |T| at the cursor and to return a
+ // reinterpreted pointer of type |T| pointing into the underlying data, while
+ // moving the cursor forward by sizeof(T). Returns nullptr if insufficient
+ // data is available.
+ template <class T>
+ const T* GetPointer() {
+ static_assert(std::is_standard_layout<T>::value,
+ "Value type must be a standard layout type");
+
+ DCHECK_NE(begin(), nullptr);
+ if (Remaining() < sizeof(T))
+ return nullptr;
+ const T* ptr = reinterpret_cast<const T*>(begin());
+ remove_prefix(sizeof(T));
+ return ptr;
+ }
+
+ // Tries to reinterpret data as an array of type |T| with |count| elements,
+ // starting at the cursor, and to return a reinterpreted pointer of type |T|
+ // pointing into the underlying data, while advancing the cursor beyond the
+ // array. Returns nullptr if insufficient data is available.
+ template <class T>
+ const T* GetArray(size_t count) {
+ static_assert(std::is_standard_layout<T>::value,
+ "Value type must be a standard layout type");
+
+ if (Remaining() / sizeof(T) < count)
+ return nullptr;
+ const T* array = reinterpret_cast<const T*>(begin());
+ remove_prefix(count * sizeof(T));
+ return array;
+ }
+
+ // If sufficient data is available, assigns |buffer| to point to a region of
+ // |size| bytes starting at the cursor, while advancing the cursor beyond the
+ // region, and returns true. Otherwise returns false.
+ bool GetRegion(size_type size, ConstBufferView* buffer);
+
+ // Reads an Unsigned Little Endian Base 128 (uleb128) int at |first_|. If
+ // successful, writes the result to |value|, advances |first_|, and returns
+ // true. Otherwise returns false.
+ bool GetUleb128(uint32_t* value);
+
+ // Reads a Signed Little Endian Base 128 (sleb128) int at |first_|. If
+ // successful, writes the result to |value|, advances |first_|, and returns
+ // true. Otherwise returns false.
+ bool GetSleb128(int32_t* value);
+
+ // Reads uleb128 / sleb128 at |first_| but discards the result. If successful,
+ // advances |first_| and returns true. Otherwise returns false.
+ bool SkipLeb128();
+
+ // Returns the number of bytes remaining from cursor until end.
+ size_type Remaining() const { return size(); }
+};
+
+} // namespace zucchini
+
+#endif // COMPONENTS_ZUCCHINI_BUFFER_SOURCE_H_