vitess.io/vitess@v0.16.2/go/mysql/collations/internal/uca/iter_legacy.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package uca
    18  
    19  import (
    20  	"vitess.io/vitess/go/mysql/collations/internal/charset"
    21  )
    22  
    23  type WeightIteratorLegacy struct {
    24  	// Constant
    25  	CollationLegacy
    26  
    27  	// Internal state
    28  	codepoint codepointIteratorLegacy
    29  	input     []byte
    30  	length    int
    31  }
    32  
    33  type codepointIteratorLegacy struct {
    34  	weights []uint16
    35  	scratch [2]uint16
    36  }
    37  
    38  func (it *codepointIteratorLegacy) next() (uint16, bool) {
    39  	if len(it.weights) == 0 {
    40  		return 0, false
    41  	}
    42  	weight := it.weights[0]
    43  	it.weights = it.weights[1:]
    44  	return weight, weight != 0x0
    45  }
    46  
    47  func (it *codepointIteratorLegacy) init(table Weights, cp rune) {
    48  	p, offset := PageOffset(cp)
    49  	page := table[p]
    50  	if page == nil {
    51  		UnicodeImplicitWeightsLegacy(it.scratch[:2], cp)
    52  		it.weights = it.scratch[:2]
    53  		return
    54  	}
    55  
    56  	stride := int((*page)[0])
    57  	position := 1 + stride*offset
    58  	it.weights = (*page)[position : position+stride]
    59  }
    60  
    61  func (it *codepointIteratorLegacy) initContraction(weights []uint16) {
    62  	it.weights = weights
    63  }
    64  
    65  func (it *WeightIteratorLegacy) reset(input []byte) {
    66  	it.input = input
    67  	it.length = 0
    68  	it.codepoint.weights = nil
    69  }
    70  
    71  func (it *WeightIteratorLegacy) Done() {
    72  	it.input = nil
    73  	it.iterpool.Put(it)
    74  }
    75  
    76  func (it *WeightIteratorLegacy) DebugCodepoint() (rune, int) {
    77  	return it.charset.DecodeRune(it.input)
    78  }
    79  
    80  func (it *WeightIteratorLegacy) Next() (uint16, bool) {
    81  	for {
    82  		if w, ok := it.codepoint.next(); ok {
    83  			return w, true
    84  		}
    85  
    86  		cp, width := it.charset.DecodeRune(it.input)
    87  		if cp == charset.RuneError && width < 3 {
    88  			return 0, false
    89  		}
    90  		it.input = it.input[width:]
    91  		it.length++
    92  
    93  		if cp > it.maxCodepoint {
    94  			return 0xFFFD, true
    95  		}
    96  		if it.contract != nil {
    97  			if weights, remainder, skip := it.contract.Find(it.charset, cp, it.input); weights != nil {
    98  				it.codepoint.initContraction(weights)
    99  				it.input = remainder
   100  				it.length += skip
   101  				continue
   102  			}
   103  		}
   104  		it.codepoint.init(it.table, cp)
   105  	}
   106  }
   107  
   108  func (it *WeightIteratorLegacy) Length() int {
   109  	return it.length
   110  }