1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved. 2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be 3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file. 4*a03ca8b9SKrzysztof Kosiński 5*a03ca8b9SKrzysztof Kosiński #ifndef COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_ 6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_ 7*a03ca8b9SKrzysztof Kosiński 8*a03ca8b9SKrzysztof Kosiński #include <stddef.h> 9*a03ca8b9SKrzysztof Kosiński #include <stdint.h> 10*a03ca8b9SKrzysztof Kosiński 11*a03ca8b9SKrzysztof Kosiński #include <iterator> 12*a03ca8b9SKrzysztof Kosiński #include <vector> 13*a03ca8b9SKrzysztof Kosiński 14*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_index.h" 15*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_utils.h" 16*a03ca8b9SKrzysztof Kosiński 17*a03ca8b9SKrzysztof Kosiński namespace zucchini { 18*a03ca8b9SKrzysztof Kosiński 19*a03ca8b9SKrzysztof Kosiński // Zucchini-gen performs semantics-aware matching: 20*a03ca8b9SKrzysztof Kosiński // - Same-typed reference target in "old" and "new" can be associated. 21*a03ca8b9SKrzysztof Kosiński // Associated targets are assigned an identifier called "label" (and for 22*a03ca8b9SKrzysztof Kosiński // unassociated targets, label = 0). 23*a03ca8b9SKrzysztof Kosiński // - EncodedView maps each offset in "old" and "new" images to a "projected 24*a03ca8b9SKrzysztof Kosiński // value", which can be: 25*a03ca8b9SKrzysztof Kosiński // - Raw byte value (0-255) for non-references. 26*a03ca8b9SKrzysztof Kosiński // - Reference "projected value" (> 256) that depends on target {type, label} 27*a03ca8b9SKrzysztof Kosiński // at each reference's location (byte 0). 28*a03ca8b9SKrzysztof Kosiński // - Reference padding value (256) at the body of each reference (bytes 1+). 29*a03ca8b9SKrzysztof Kosiński // - The projected values for "old" and "new" are used to build the equivalence 30*a03ca8b9SKrzysztof Kosiński // map. 31*a03ca8b9SKrzysztof Kosiński 32*a03ca8b9SKrzysztof Kosiński constexpr size_t kReferencePaddingProjection = 256; 33*a03ca8b9SKrzysztof Kosiński constexpr size_t kBaseReferenceProjection = 257; 34*a03ca8b9SKrzysztof Kosiński 35*a03ca8b9SKrzysztof Kosiński // A Range (providing begin and end iterators) that adapts ImageIndex to make 36*a03ca8b9SKrzysztof Kosiński // image data appear as an Encoded Image, that is encoded data under a higher 37*a03ca8b9SKrzysztof Kosiński // level of abstraction than raw bytes. In particular: 38*a03ca8b9SKrzysztof Kosiński // - First byte of each reference become a projection of its type and label. 39*a03ca8b9SKrzysztof Kosiński // - Subsequent bytes of each reference becomes |kReferencePaddingProjection|. 40*a03ca8b9SKrzysztof Kosiński // - Non-reference raw bytes remain as raw bytes. 41*a03ca8b9SKrzysztof Kosiński class EncodedView { 42*a03ca8b9SKrzysztof Kosiński public: 43*a03ca8b9SKrzysztof Kosiński // RandomAccessIterator whose values are the results of Projection(). 44*a03ca8b9SKrzysztof Kosiński class Iterator { 45*a03ca8b9SKrzysztof Kosiński public: 46*a03ca8b9SKrzysztof Kosiński using iterator_category = std::random_access_iterator_tag; 47*a03ca8b9SKrzysztof Kosiński using value_type = size_t; 48*a03ca8b9SKrzysztof Kosiński using difference_type = ptrdiff_t; 49*a03ca8b9SKrzysztof Kosiński using reference = size_t; 50*a03ca8b9SKrzysztof Kosiński using pointer = size_t*; 51*a03ca8b9SKrzysztof Kosiński Iterator(const EncodedView * encoded_view,difference_type pos)52*a03ca8b9SKrzysztof Kosiński Iterator(const EncodedView* encoded_view, difference_type pos) 53*a03ca8b9SKrzysztof Kosiński : encoded_view_(encoded_view), pos_(pos) {} 54*a03ca8b9SKrzysztof Kosiński 55*a03ca8b9SKrzysztof Kosiński Iterator(const Iterator&) = default; 56*a03ca8b9SKrzysztof Kosiński 57*a03ca8b9SKrzysztof Kosiński Iterator& operator=(const Iterator&) = default; 58*a03ca8b9SKrzysztof Kosiński 59*a03ca8b9SKrzysztof Kosiński value_type operator*() const { 60*a03ca8b9SKrzysztof Kosiński return encoded_view_->Projection(static_cast<offset_t>(pos_)); 61*a03ca8b9SKrzysztof Kosiński } 62*a03ca8b9SKrzysztof Kosiński 63*a03ca8b9SKrzysztof Kosiński value_type operator[](difference_type n) const { 64*a03ca8b9SKrzysztof Kosiński return encoded_view_->Projection(static_cast<offset_t>(pos_ + n)); 65*a03ca8b9SKrzysztof Kosiński } 66*a03ca8b9SKrzysztof Kosiński 67*a03ca8b9SKrzysztof Kosiński Iterator& operator++() { 68*a03ca8b9SKrzysztof Kosiński ++pos_; 69*a03ca8b9SKrzysztof Kosiński return *this; 70*a03ca8b9SKrzysztof Kosiński } 71*a03ca8b9SKrzysztof Kosiński 72*a03ca8b9SKrzysztof Kosiński Iterator operator++(int) { 73*a03ca8b9SKrzysztof Kosiński Iterator tmp = *this; 74*a03ca8b9SKrzysztof Kosiński ++pos_; 75*a03ca8b9SKrzysztof Kosiński return tmp; 76*a03ca8b9SKrzysztof Kosiński } 77*a03ca8b9SKrzysztof Kosiński 78*a03ca8b9SKrzysztof Kosiński Iterator& operator--() { 79*a03ca8b9SKrzysztof Kosiński --pos_; 80*a03ca8b9SKrzysztof Kosiński return *this; 81*a03ca8b9SKrzysztof Kosiński } 82*a03ca8b9SKrzysztof Kosiński 83*a03ca8b9SKrzysztof Kosiński Iterator operator--(int) { 84*a03ca8b9SKrzysztof Kosiński Iterator tmp = *this; 85*a03ca8b9SKrzysztof Kosiński --pos_; 86*a03ca8b9SKrzysztof Kosiński return tmp; 87*a03ca8b9SKrzysztof Kosiński } 88*a03ca8b9SKrzysztof Kosiński 89*a03ca8b9SKrzysztof Kosiński Iterator& operator+=(difference_type n) { 90*a03ca8b9SKrzysztof Kosiński pos_ += n; 91*a03ca8b9SKrzysztof Kosiński return *this; 92*a03ca8b9SKrzysztof Kosiński } 93*a03ca8b9SKrzysztof Kosiński 94*a03ca8b9SKrzysztof Kosiński Iterator& operator-=(difference_type n) { 95*a03ca8b9SKrzysztof Kosiński pos_ -= n; 96*a03ca8b9SKrzysztof Kosiński return *this; 97*a03ca8b9SKrzysztof Kosiński } 98*a03ca8b9SKrzysztof Kosiński 99*a03ca8b9SKrzysztof Kosiński friend bool operator==(Iterator a, Iterator b) { return a.pos_ == b.pos_; } 100*a03ca8b9SKrzysztof Kosiński 101*a03ca8b9SKrzysztof Kosiński friend bool operator!=(Iterator a, Iterator b) { return !(a == b); } 102*a03ca8b9SKrzysztof Kosiński 103*a03ca8b9SKrzysztof Kosiński friend bool operator<(Iterator a, Iterator b) { return a.pos_ < b.pos_; } 104*a03ca8b9SKrzysztof Kosiński 105*a03ca8b9SKrzysztof Kosiński friend bool operator>(Iterator a, Iterator b) { return b < a; } 106*a03ca8b9SKrzysztof Kosiński 107*a03ca8b9SKrzysztof Kosiński friend bool operator<=(Iterator a, Iterator b) { return !(b < a); } 108*a03ca8b9SKrzysztof Kosiński 109*a03ca8b9SKrzysztof Kosiński friend bool operator>=(Iterator a, Iterator b) { return !(a < b); } 110*a03ca8b9SKrzysztof Kosiński 111*a03ca8b9SKrzysztof Kosiński friend difference_type operator-(Iterator a, Iterator b) { 112*a03ca8b9SKrzysztof Kosiński return a.pos_ - b.pos_; 113*a03ca8b9SKrzysztof Kosiński } 114*a03ca8b9SKrzysztof Kosiński 115*a03ca8b9SKrzysztof Kosiński friend Iterator operator+(Iterator it, difference_type n) { 116*a03ca8b9SKrzysztof Kosiński it += n; 117*a03ca8b9SKrzysztof Kosiński return it; 118*a03ca8b9SKrzysztof Kosiński } 119*a03ca8b9SKrzysztof Kosiński 120*a03ca8b9SKrzysztof Kosiński friend Iterator operator-(Iterator it, difference_type n) { 121*a03ca8b9SKrzysztof Kosiński it -= n; 122*a03ca8b9SKrzysztof Kosiński return it; 123*a03ca8b9SKrzysztof Kosiński } 124*a03ca8b9SKrzysztof Kosiński 125*a03ca8b9SKrzysztof Kosiński private: 126*a03ca8b9SKrzysztof Kosiński const EncodedView* encoded_view_; 127*a03ca8b9SKrzysztof Kosiński difference_type pos_; 128*a03ca8b9SKrzysztof Kosiński }; 129*a03ca8b9SKrzysztof Kosiński 130*a03ca8b9SKrzysztof Kosiński using value_type = size_t; 131*a03ca8b9SKrzysztof Kosiński using size_type = offset_t; 132*a03ca8b9SKrzysztof Kosiński using difference_type = ptrdiff_t; 133*a03ca8b9SKrzysztof Kosiński using const_iterator = Iterator; 134*a03ca8b9SKrzysztof Kosiński 135*a03ca8b9SKrzysztof Kosiński // |image_index| is the annotated image being adapted, and is required to 136*a03ca8b9SKrzysztof Kosiński // remain valid for the lifetime of the object. 137*a03ca8b9SKrzysztof Kosiński explicit EncodedView(const ImageIndex& image_index); 138*a03ca8b9SKrzysztof Kosiński EncodedView(const EncodedView&) = delete; 139*a03ca8b9SKrzysztof Kosiński const EncodedView& operator=(const EncodedView&) = delete; 140*a03ca8b9SKrzysztof Kosiński ~EncodedView(); 141*a03ca8b9SKrzysztof Kosiński 142*a03ca8b9SKrzysztof Kosiński // Projects |location| to a scalar value that describes the content at a 143*a03ca8b9SKrzysztof Kosiński // higher level of abstraction. 144*a03ca8b9SKrzysztof Kosiński value_type Projection(offset_t location) const; 145*a03ca8b9SKrzysztof Kosiński IsToken(offset_t location)146*a03ca8b9SKrzysztof Kosiński bool IsToken(offset_t location) const { 147*a03ca8b9SKrzysztof Kosiński return image_index_.IsToken(location); 148*a03ca8b9SKrzysztof Kosiński } 149*a03ca8b9SKrzysztof Kosiński 150*a03ca8b9SKrzysztof Kosiński // Returns the cardinality of the projection, i.e., the upper bound on 151*a03ca8b9SKrzysztof Kosiński // values returned by Projection(). 152*a03ca8b9SKrzysztof Kosiński value_type Cardinality() const; 153*a03ca8b9SKrzysztof Kosiński 154*a03ca8b9SKrzysztof Kosiński // Associates |labels| to targets for a given |pool|, replacing previous 155*a03ca8b9SKrzysztof Kosiński // association. Values in |labels| must be smaller than |bound|. 156*a03ca8b9SKrzysztof Kosiński void SetLabels(PoolTag pool, std::vector<uint32_t>&& labels, size_t bound); image_index()157*a03ca8b9SKrzysztof Kosiński const ImageIndex& image_index() const { return image_index_; } 158*a03ca8b9SKrzysztof Kosiński 159*a03ca8b9SKrzysztof Kosiński // Range functions. size()160*a03ca8b9SKrzysztof Kosiński size_type size() const { return size_type(image_index_.size()); } begin()161*a03ca8b9SKrzysztof Kosiński const_iterator begin() const { 162*a03ca8b9SKrzysztof Kosiński return const_iterator{this, difference_type(0)}; 163*a03ca8b9SKrzysztof Kosiński } end()164*a03ca8b9SKrzysztof Kosiński const_iterator end() const { 165*a03ca8b9SKrzysztof Kosiński return const_iterator{this, difference_type(size())}; 166*a03ca8b9SKrzysztof Kosiński } 167*a03ca8b9SKrzysztof Kosiński 168*a03ca8b9SKrzysztof Kosiński private: 169*a03ca8b9SKrzysztof Kosiński struct PoolInfo { 170*a03ca8b9SKrzysztof Kosiński PoolInfo(); 171*a03ca8b9SKrzysztof Kosiński PoolInfo(PoolInfo&&); 172*a03ca8b9SKrzysztof Kosiński ~PoolInfo(); 173*a03ca8b9SKrzysztof Kosiński 174*a03ca8b9SKrzysztof Kosiński // |labels| translates IndirectReference target_key to label. 175*a03ca8b9SKrzysztof Kosiński std::vector<uint32_t> labels; 176*a03ca8b9SKrzysztof Kosiński size_t bound = 0; 177*a03ca8b9SKrzysztof Kosiński }; 178*a03ca8b9SKrzysztof Kosiński 179*a03ca8b9SKrzysztof Kosiński const ImageIndex& image_index_; 180*a03ca8b9SKrzysztof Kosiński std::vector<PoolInfo> pool_infos_; 181*a03ca8b9SKrzysztof Kosiński }; 182*a03ca8b9SKrzysztof Kosiński 183*a03ca8b9SKrzysztof Kosiński } // namespace zucchini 184*a03ca8b9SKrzysztof Kosiński 185*a03ca8b9SKrzysztof Kosiński #endif // COMPONENTS_ZUCCHINI_ENCODED_VIEW_H_ 186