All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.cel.common.internal.CelCodePointArray Maven / Gradle / Ivy

The newest version!
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cel.common.internal;

import static com.google.common.base.Strings.isNullOrEmpty;

import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.Immutable;
import dev.cel.common.annotations.Internal;
import java.util.PrimitiveIterator;

/**
 * Represents an in-memory read-only contiguous source of Unicode code points.
 *
 * 

CEL Library Internals. Do Not Use. */ @Immutable @Internal public abstract class CelCodePointArray { // Package-private default constructor to prevent extensions outside of the codebase. CelCodePointArray() {} /** Returns a new {@link CelCodePointArray} that is a subview of this between [i, j). */ public abstract CelCodePointArray slice(int i, int j); /** Get the code point at the given index. */ public abstract int get(int index); /** Returns the number of code points. */ public abstract int size(); /** Returns the line offsets. */ public abstract ImmutableList lineOffsets(); public final int length() { return size(); } /** Returns true if empty, false otherwise. */ public boolean isEmpty() { return length() == 0; } @Override public abstract String toString(); public static CelCodePointArray fromString(String text) { if (isNullOrEmpty(text)) { return EmptyCodePointArray.INSTANCE; } PrimitiveIterator.OfInt codePoints = text.codePoints().iterator(); byte[] byteArray = new byte[text.length()]; int byteIndex = 0; LineOffsetContext lineOffsetContext = new LineOffsetContext(); while (codePoints.hasNext()) { int codePoint = codePoints.nextInt(); lineOffsetContext.process(codePoint); if (codePoint <= 0xff) { byteArray[byteIndex++] = (byte) codePoint; continue; } if (codePoint <= 0xffff) { char[] charArray = new char[text.length()]; int charIndex = 0; for (; charIndex < byteIndex; charIndex++) { charArray[charIndex] = (char) (byteArray[charIndex] & 0xff); } byteArray = null; charArray[charIndex++] = (char) codePoint; while (codePoints.hasNext()) { codePoint = codePoints.nextInt(); lineOffsetContext.process(codePoint); if (codePoint <= 0xffff) { charArray[charIndex++] = (char) codePoint; continue; } int[] intArray = new int[text.length()]; int intIndex = 0; for (; intIndex < charIndex; intIndex++) { intArray[intIndex] = charArray[intIndex] & 0xffff; } charArray = null; intArray[intIndex++] = codePoint; while (codePoints.hasNext()) { codePoint = codePoints.nextInt(); lineOffsetContext.process(codePoint); intArray[intIndex++] = codePoint; } return SupplementalCodePointArray.create( intArray, intIndex, lineOffsetContext.buildLineOffsets()); } return BasicCodePointArray.create( charArray, charIndex, lineOffsetContext.buildLineOffsets()); } int[] intArray = new int[text.length()]; int intIndex = 0; for (; intIndex < byteIndex; intIndex++) { intArray[intIndex] = byteArray[intIndex] & 0xff; } byteArray = null; intArray[intIndex++] = codePoint; while (codePoints.hasNext()) { codePoint = codePoints.nextInt(); lineOffsetContext.process(codePoint); intArray[intIndex++] = codePoint; } return SupplementalCodePointArray.create( intArray, intIndex, lineOffsetContext.buildLineOffsets()); } return Latin1CodePointArray.create(byteArray, byteIndex, lineOffsetContext.buildLineOffsets()); } private static class LineOffsetContext { private static final int NEWLINE_CODE_POINT = 10; private final ImmutableList.Builder lineOffsetBuilder; private int lineOffsetCodePoints; private void process(int codePoint) { lineOffsetCodePoints++; if (codePoint == NEWLINE_CODE_POINT) { lineOffsetBuilder.add(lineOffsetCodePoints); } } private ImmutableList buildLineOffsets() { return lineOffsetBuilder.add(lineOffsetCodePoints + 1).build(); } private LineOffsetContext() { this.lineOffsetBuilder = ImmutableList.builder(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy