From 06f1ae9aaca969ee95ef840f22b6b461c304542d Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 13 Mar 2018 18:19:34 +0000 Subject: [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 Reviewed-by: Jochen Eisinger Reviewed-by: Samuel Huang Commit-Queue: Samuel Huang Cr-Commit-Position: refs/heads/master@{#542857} NOKEYCHECK=True GitOrigin-RevId: 577ef6c435e8d43be6e3e60ccbcbd1881780f4ec --- buffer_source.h | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 buffer_source.h (limited to 'buffer_source.h') 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 +#include + +#include +#include + +#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(&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 + bool CheckNextValue(const T& value) const { + static_assert(std::is_integral::value, + "Value type must be an integral type"); + DCHECK_NE(begin(), nullptr); + if (Remaining() < sizeof(T)) + return false; + return value == *reinterpret_cast(begin()); + } + + // Returns true if the next bytes.size() bytes at the cursor match those in + // |bytes|. + bool CheckNextBytes(std::initializer_list bytes) const; + + // Same as CheckNextBytes(), but moves the cursor by bytes.size() if read is + // successfull. + bool ConsumeBytes(std::initializer_list 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 + bool GetValue(T* value) { + static_assert(std::is_standard_layout::value, + "Value type must be a standard layout type"); + + DCHECK_NE(begin(), nullptr); + if (Remaining() < sizeof(T)) + return false; + *value = *reinterpret_cast(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 + const T* GetPointer() { + static_assert(std::is_standard_layout::value, + "Value type must be a standard layout type"); + + DCHECK_NE(begin(), nullptr); + if (Remaining() < sizeof(T)) + return nullptr; + const T* ptr = reinterpret_cast(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 + const T* GetArray(size_t count) { + static_assert(std::is_standard_layout::value, + "Value type must be a standard layout type"); + + if (Remaining() / sizeof(T) < count) + return nullptr; + const T* array = reinterpret_cast(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_ -- cgit v1.2.3