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

io.gatling.commons.util.StringHelper.scala Maven / Gradle / Ivy

/*
 * Copyright 2011-2023 GatlingCorp (https://gatling.io)
 *
 * 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
 *
 *  http://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 io.gatling.commons.util

import java.{ lang => jl }
import java.nio.charset.StandardCharsets._
import java.text.Normalizer
import java.util.Locale

import io.gatling.shared.util.StringBuilderPool

import io.github.metarank.cfor._

object StringHelper {
  val Eol: String = System.lineSeparator
  val EolBytes: Array[Byte] = Eol.getBytes(US_ASCII)

  object RichString {
    private val SbPool = new StringBuilderPool
  }

  implicit class RichString(val string: String) extends AnyVal {
    def clean: String = {
      val normalized = Normalizer.normalize(string, Normalizer.Form.NFD)
      normalized.toLowerCase(Locale.ROOT).replaceAll("\\p{InCombiningDiacriticalMarks}+", "-").replaceAll("[^a-zA-Z0-9\\-]", "-")
    }

    def trimToOption: Option[String] = string.trim match {
      case "" => None
      case s  => Some(s)
    }

    def truncate(maxLength: Int): String = if (string.length <= maxLength) string else string.substring(0, maxLength) + "..."

    def leftPad(length: Int): String = leftPad(length, " ")
    def leftPad(length: Int, padder: String): String = {
      val paddingLength = length - string.length
      if (paddingLength > 0)
        padder * paddingLength + string
      else
        string
    }

    def rightPad(length: Int): String = rightPad(length, " ")
    def rightPad(length: Int, padder: String): String = {
      val paddingLength = length - string.length
      if (paddingLength > 0)
        string + padder * paddingLength
      else
        string
    }

    def replaceIf(replaced: Char => Boolean, replacement: Char): String =
      if (string.isEmpty) {
        string
      } else {
        var matchFound = false
        var sb: jl.StringBuilder = null

        cfor(0 until string.length) { i =>
          val c = string.charAt(i)
          if (replaced(c)) {
            if (!matchFound) {
              // first match
              sb = RichString.SbPool.get()
              sb.append(string, 0, i)
              matchFound = true
            }
            sb.append(replacement)
          } else if (matchFound) {
            sb.append(c)
          }
        }

        if (matchFound) {
          sb.toString
        } else {
          string
        }
      }
  }

  implicit class RichCharSequence(val source: CharSequence) extends AnyVal {
    def indexOf(target: Array[Char], fromIndex: Int): Int = {
      val sourceCount = source.length
      val targetCount = target.length

      if (fromIndex >= sourceCount) {
        if (targetCount == 0) sourceCount else -1
      } else if (targetCount == 0) {
        fromIndex
      } else {
        var i = fromIndex
        val first = target(0)
        val max = sourceCount - targetCount
        var exit = false
        while (i <= max && !exit) {
          // look for first character
          if (source.charAt(i) != first) {
            i += 1
            while (i <= max && source.charAt(i) != first) {
              i += 1
            }
          }

          // found first character, now look at the rest of target
          if (i <= max) {
            var j = i + 1
            val end = j + targetCount - 1
            var k = 1

            while (j < end && source.charAt(j) == target(k)) {
              j += 1
              k += 1
            }

            if (j == end) {
              // found whole string
              exit = true
            }
          }

          if (!exit) {
            i += 1
          }
        }
        if (exit) i else -1
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy