// 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_ENCODED_VIEW_H_ #define COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_ #include #include #include #include #include "components/zucchini/image_index.h" #include "components/zucchini/image_utils.h" namespace zucchini { // Zucchini-gen performs semantics-aware matching: // - Same-typed reference target in "old" and "new" can be associated. // Associated targets are assigned an identifier called "label" (and for // unassociated targets, label = 0). // - EncodedView maps each offset in "old" and "new" images to a "projected // value", which can be: // - Raw byte value (0-255) for non-references. // - Reference "projected value" (> 256) that depends on target {type, label} // at each reference's location (byte 0). // - Reference padding value (256) at the body of each reference (bytes 1+). // - The projected values for "old" and "new" are used to build the equivalence // map. constexpr size_t kReferencePaddingProjection = 256; constexpr size_t kBaseReferenceProjection = 257; // A Range (providing begin and end iterators) that adapts ImageIndex to make // image data appear as an Encoded Image, that is encoded data under a higher // level of abstraction than raw bytes. In particular: // - First byte of each reference become a projection of its type and label. // - Subsequent bytes of each reference becomes |kReferencePaddingProjection|. // - Non-reference raw bytes remain as raw bytes. class EncodedView { public: // RandomAccessIterator whose values are the results of Projection(). class Iterator { public: using iterator_category = std::random_access_iterator_tag; using value_type = size_t; using difference_type = ptrdiff_t; using reference = size_t; using pointer = size_t*; Iterator(const EncodedView* encoded_view, difference_type pos) : encoded_view_(encoded_view), pos_(pos) {} Iterator(const Iterator&) = default; Iterator& operator=(const Iterator&) = default; value_type operator*() const { return encoded_view_->Projection(static_cast(pos_)); } value_type operator[](difference_type n) const { return encoded_view_->Projection(static_cast(pos_ + n)); } Iterator& operator++() { ++pos_; return *this; } Iterator operator++(int) { Iterator tmp = *this; ++pos_; return tmp; } Iterator& operator--() { --pos_; return *this; } Iterator operator--(int) { Iterator tmp = *this; --pos_; return tmp; } Iterator& operator+=(difference_type n) { pos_ += n; return *this; } Iterator& operator-=(difference_type n) { pos_ -= n; return *this; } friend bool operator==(Iterator a, Iterator b) { return a.pos_ == b.pos_; } friend bool operator!=(Iterator a, Iterator b) { return !(a == b); } friend bool operator<(Iterator a, Iterator b) { return a.pos_ < b.pos_; } friend bool operator>(Iterator a, Iterator b) { return b < a; } friend bool operator<=(Iterator a, Iterator b) { return !(b < a); } friend bool operator>=(Iterator a, Iterator b) { return !(a < b); } friend difference_type operator-(Iterator a, Iterator b) { return a.pos_ - b.pos_; } friend Iterator operator+(Iterator it, difference_type n) { it += n; return it; } friend Iterator operator-(Iterator it, difference_type n) { it -= n; return it; } private: const EncodedView* encoded_view_; difference_type pos_; }; using value_type = size_t; using size_type = offset_t; using difference_type = ptrdiff_t; using const_iterator = Iterator; // |image_index| is the annotated image being adapted, and is required to // remain valid for the lifetime of the object. explicit EncodedView(const ImageIndex& image_index); EncodedView(const EncodedView&) = delete; const EncodedView& operator=(const EncodedView&) = delete; ~EncodedView(); // Projects |location| to a scalar value that describes the content at a // higher level of abstraction. value_type Projection(offset_t location) const; bool IsToken(offset_t location) const { return image_index_.IsToken(location); } // Returns the cardinality of the projection, i.e., the upper bound on // values returned by Projection(). value_type Cardinality() const; // Associates |labels| to targets for a given |pool|, replacing previous // association. Values in |labels| must be smaller than |bound|. void SetLabels(PoolTag pool, std::vector&& labels, size_t bound); const ImageIndex& image_index() const { return image_index_; } // Range functions. size_type size() const { return size_type(image_index_.size()); } const_iterator begin() const { return const_iterator{this, difference_type(0)}; } const_iterator end() const { return const_iterator{this, difference_type(size())}; } private: struct PoolInfo { PoolInfo(); PoolInfo(PoolInfo&&); ~PoolInfo(); // |labels| translates IndirectReference target_key to label. std::vector labels; size_t bound = 0; }; const ImageIndex& image_index_; std::vector pool_infos_; }; } // namespace zucchini #endif // COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_