cleanup, WEB-18801 IndexOutOfBoundsException on opening file with SVG on built-in...
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Wed, 28 Oct 2015 12:43:47 +0000 (13:43 +0100)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Wed, 28 Oct 2015 12:45:55 +0000 (13:45 +0100)
15 files changed:
platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/StaticFileHandler.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/ExpressionParseTree.java
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiCommand.java [deleted file]
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiConditional.java
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiFsize.java
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiProcessor.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiStopProcessingException.java [deleted file]
platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt
platform/configuration-store-impl/src/StateStorageManagerImpl.kt
platform/platform-impl/src/io/netty/buffer/ByteBufUtf8Writer.java
platform/platform-impl/src/io/netty/buffer/ByteBufUtilEx.java
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.kt
plugins/settings-repository/src/git/commit.kt

index 8b4989c6da681bf3202095b54db657335086eefd..f85783d9e107c38e647958b078498abe002e8374 100644 (file)
@@ -73,7 +73,7 @@ class BuiltInWebServer : HttpRequestHandler() {
           // WEB-17839 Internal web server reports 404 when serving files from project with slashes in name
           if (decodedPath.regionMatches(1, name, 0, name.length, !SystemInfoRt.isFileSystemCaseSensitive)) {
             var emptyPathCandidate = decodedPath.length == (name.length + 1)
-            if (emptyPathCandidate || decodedPath.charAt(name.length + 1) == '/') {
+            if (emptyPathCandidate || decodedPath[name.length + 1] == '/') {
               projectName = name
               offset = name.length + 1
               emptyPath = emptyPathCandidate
@@ -128,7 +128,7 @@ class BuiltInWebServer : HttpRequestHandler() {
     }
 
     val projectName: String?
-    val isIpv6 = host.charAt(0) == '[' && host.length > 2 && host.charAt(host.length - 1) == ']'
+    val isIpv6 = host[0] == '[' && host.length > 2 && host[host.length - 1] == ']'
     if (isIpv6) {
       host = host.substring(1, host.length - 1)
     }
@@ -148,7 +148,7 @@ class BuiltInWebServer : HttpRequestHandler() {
 
 fun compareNameAndProjectBasePath(projectName: String, project: Project): Boolean {
   val basePath = project.basePath
-  return basePath != null && basePath.length > projectName.length && basePath.endsWith(projectName) && basePath.charAt(basePath.length - projectName.length - 1) == '/'
+  return basePath != null && basePath.length > projectName.length && basePath.endsWith(projectName) && basePath[basePath.length - projectName.length - 1] == '/'
 }
 
 fun findIndexFile(basedir: VirtualFile): VirtualFile? {
index 3fda9d90b439d76269edca849ebd805cbff200a3..622089dbc626abd2e9368c2bf4b354aa1afc82c3 100644 (file)
@@ -1,7 +1,6 @@
 package org.jetbrains.builtInWebServer
 
 import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.io.FileUtil
 import com.intellij.openapi.util.text.StringUtilRt
 import com.intellij.util.PathUtilRt
 import io.netty.buffer.ByteBufUtf8Writer
@@ -74,7 +73,7 @@ private class StaticFileHandler : WebServerFileHandler() {
     val keepAlive: Boolean
     var releaseBuffer = true
     try {
-      val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parentFile), FileUtil.loadFile(file), file.lastModified(), ByteBufUtf8Writer(buffer))
+      val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parentFile), file, ByteBufUtf8Writer(buffer))
       val response = FileResponses.prepareSend(request, channel, lastModified, file.path) ?: return
       keepAlive = Responses.addKeepAliveIfNeed(response, request)
       if (request.method() != HttpMethod.HEAD) {
index e11ad6e45136f5128dbb7ffe1ef72bfb7f3782b8..cfdb60d547d5397015c9c784e2a10efe15a63204 100644 (file)
@@ -45,14 +45,14 @@ final class ExpressionParseTree {
   /**
    * The SSIMediator to use when evaluating the expressions.
    */
-  private final SsiProcessingState mySsiProcessingState;
+  private final SsiProcessingState ssiProcessingState;
 
   /**
    * Creates a new parse tree for the specified expression.
    */
   public ExpressionParseTree(String expr, SsiProcessingState ssiProcessingState)
     throws ParseException {
-    this.mySsiProcessingState = ssiProcessingState;
+    this.ssiProcessingState = ssiProcessingState;
     parseExpression(expr);
   }
 
@@ -73,7 +73,7 @@ final class ExpressionParseTree {
   private void pushOpp(OppNode node) {
     // If node is null then it's just a group marker
     if (node == null) {
-      oppStack.add(0, node);
+      oppStack.add(0, null);
       return;
     }
     while (true) {
@@ -229,7 +229,7 @@ final class ExpressionParseTree {
      */
     public String getValue() {
       if (resolved == null) {
-        resolved = mySsiProcessingState.substituteVariables(value.toString());
+        resolved = ssiProcessingState.substituteVariables(value.toString());
       }
       return resolved;
     }
@@ -381,7 +381,7 @@ final class ExpressionParseTree {
           }
         }
         catch (PatternSyntaxException e) {
-          SsiProcessor.LOG.warn("Invalid expression: " + expr, e);
+          SsiProcessorKt.getLOG().warn("Invalid expression: " + expr, e);
           return 0;
         }
       }
diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiCommand.java b/platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiCommand.java
deleted file mode 100644 (file)
index 448bbea..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2000-2015 JetBrains s.r.o.
- *
- * 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 org.jetbrains.builtInWebServer.ssi;
-
-import io.netty.buffer.ByteBufUtf8Writer;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-public interface SsiCommand {
-  long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer);
-}
\ No newline at end of file
index 52f727cb5a38f9223d6c635298bb7250ae646cbb..0aba822c34097b2c21f56f4e28189625565abd32 100644 (file)
@@ -31,7 +31,7 @@ import java.util.List;
 public class SsiConditional implements SsiCommand {
   @SuppressWarnings("SpellCheckingInspection")
   @Override
-  public long process(@NotNull SsiProcessingState ssiProcessingState, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
+  public long process(@NotNull SsiProcessingState ssiProcessingState, @NotNull String commandName, @NotNull List<? extends String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
     // Assume anything using conditionals was modified by it
     long lastModified = System.currentTimeMillis();
     // Retrieve the current state information
@@ -111,7 +111,7 @@ public class SsiConditional implements SsiCommand {
   /**
    * Retrieves the expression from the specified arguments and performs the necessary evaluation steps.
    */
-  private static boolean evaluateArguments(@NotNull List<String> names, @NotNull String[] values, @NotNull SsiProcessingState ssiProcessingState) {
+  private static boolean evaluateArguments(@NotNull List<? extends String> names, @NotNull String[] values, @NotNull SsiProcessingState ssiProcessingState) {
     String expression = "expr".equalsIgnoreCase(names.get(0)) ? values[0] : null;
     if (expression == null) {
       throw new SsiStopProcessingException();
index 1d436117f783b233fd9d5a04be132fe2466b57c7..d1346c19350f37441e425b86504a88f6cede3e78 100644 (file)
@@ -35,7 +35,7 @@ final class SsiFsize implements SsiCommand {
   private static final int ONE_MEGABYTE = 1024 * 1024;
 
   @Override
-  public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
+  public long process(@NotNull SsiProcessingState state, @NotNull String commandName, @NotNull List<? extends String> paramNames, @NotNull String[] paramValues, @NotNull ByteBufUtf8Writer writer) {
     long lastModified = 0;
     String configErrMsg = state.configErrorMessage;
     for (int i = 0; i < paramNames.size(); i++) {
@@ -48,7 +48,7 @@ final class SsiFsize implements SsiCommand {
         writer.write(formatSize(state.ssiExternalResolver.getFileSize(substitutedValue, virtual), state.configSizeFmt));
       }
       else {
-        SsiProcessor.LOG.info("#fsize--Invalid attribute: " + paramName);
+        SsiProcessorKt.getLOG().info("#fsize--Invalid attribute: " + paramName);
         writer.write(configErrMsg);
       }
     }
index 439e0b0942478605c597fd04713394b38c889fb2..70d12f81c71e3c8168674bb66e9d3555ee12c289 100644 (file)
 package org.jetbrains.builtInWebServer.ssi
 
 import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.util.io.FileUtilRt
 import com.intellij.util.SmartList
+import com.intellij.util.text.CharArrayUtil
 import gnu.trove.THashMap
 import io.netty.buffer.ByteBufUtf8Writer
+import java.io.File
 import java.io.FileInputStream
 import java.io.IOException
 import java.util.*
@@ -32,6 +35,8 @@ interface SsiCommand {
   fun process(state: SsiProcessingState, commandName: String, paramNames: List<String>, paramValues: Array<String>, writer: ByteBufUtf8Writer): Long
 }
 
+class SsiStopProcessingException : RuntimeException()
+
 class SsiProcessor(allowExec: Boolean) {
   private val commands: MutableMap<String, SsiCommand> = THashMap()
 
@@ -226,14 +231,16 @@ class SsiProcessor(allowExec: Boolean) {
   /**
    * @return the most current modified date resulting from any SSI commands
    */
-  fun process(ssiExternalResolver: SsiExternalResolver, fileContents: String, lastModifiedDate: Long, writer: ByteBufUtf8Writer): Long {
-    var resultLastModifiedDate = lastModifiedDate
-    val ssiProcessingState = SsiProcessingState(ssiExternalResolver, resultLastModifiedDate)
+  fun process(ssiExternalResolver: SsiExternalResolver, file: File, writer: ByteBufUtf8Writer): Long {
+    val fileContents = FileUtilRt.loadFileText(file)
+    var lastModifiedDate = file.lastModified()
+    val ssiProcessingState = SsiProcessingState(ssiExternalResolver, lastModifiedDate)
     var index = 0
     var inside = false
     val command = StringBuilder()
+    writer.ensureWritable(file.length().toInt())
     try {
-      while (index < fileContents.length) {
+      while (index < fileContents.size) {
         val c = fileContents[index]
         if (inside) {
           if (c == COMMAND_END[0] && charCmp(fileContents, index, COMMAND_END)) {
@@ -250,20 +257,20 @@ class SsiProcessor(allowExec: Boolean) {
             val ssiCommand = commands[commandName.toLowerCase(Locale.ENGLISH)]
             var errorMessage: String? = null
             if (ssiCommand == null) {
-              errorMessage = "Unknown command: " + commandName
+              errorMessage = "Unknown command: $commandName"
             }
             else if (paramValues == null) {
               errorMessage = "Error parsing directive parameters."
             }
             else if (paramNames.size != paramValues.size) {
-              errorMessage = "Parameter names count does not match parameter values count on command: " + commandName
+              errorMessage = "Parameter names count does not match parameter values count on command: $commandName"
             }
             else {
               // don't process the command if we are processing conditional commands only and the command is not conditional
               if (!ssiProcessingState.conditionalState.processConditionalCommandsOnly || ssiCommand is SsiConditional) {
                 val newLastModified = ssiCommand.process(ssiProcessingState, commandName, paramNames, paramValues, writer)
-                if (newLastModified > resultLastModifiedDate) {
-                  resultLastModifiedDate = newLastModified
+                if (newLastModified > lastModifiedDate) {
+                  lastModifiedDate = newLastModified
                 }
               }
             }
@@ -284,7 +291,7 @@ class SsiProcessor(allowExec: Boolean) {
         }
         else {
           if (!ssiProcessingState.conditionalState.processConditionalCommandsOnly) {
-            writer.write(c.toInt())
+            writer.append(c)
           }
           index++
         }
@@ -294,7 +301,7 @@ class SsiProcessor(allowExec: Boolean) {
       //If we are here, then we have already stopped processing, so all is good
     }
 
-    return resultLastModifiedDate
+    return lastModifiedDate
   }
 
   protected fun parseParamNames(command: StringBuilder, start: Int): List<String> {
@@ -423,7 +430,7 @@ class SsiProcessor(allowExec: Boolean) {
     return if (firstLetter == -1) "" else instruction.substring(firstLetter, lastLetter + 1)
   }
 
-  protected fun charCmp(buf: String, index: Int, command: String) = buf.regionMatches(index, command, 0, command.length)
+  protected fun charCmp(buf: CharArray, index: Int, command: String) = CharArrayUtil.regionMatches(buf, index, index + command.length, command)
 
   protected fun isSpace(c: Char) = c == ' ' || c == '\n' || c == '\t' || c == '\r'
 
diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiStopProcessingException.java b/platform/built-in-server/src/org/jetbrains/builtInWebServer/ssi/SsiStopProcessingException.java
deleted file mode 100644 (file)
index fd02896..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jetbrains.builtInWebServer.ssi;
-
-
-/**
- * Exception used to tell SSIProcessor that it should stop processing SSI
- * commands. This is used to mimic the Apache behavior in #set with invalid
- * attributes.
- *
- * @author Paul Speed
- * @author Dan Sandberg
- */
-public class SsiStopProcessingException extends RuntimeException {
-}
\ No newline at end of file
index f1ba60f87e3e337c0e5b76886bc1f7fa4f072513..6e59bbdc6844e9accb210bf5bba9bc25220743b7 100644 (file)
@@ -110,12 +110,12 @@ internal class FastCgiDecoder(private val errorOutputConsumer: Consumer<String>,
       RecordType.END_REQUEST -> {
         val appStatus = buffer.readInt()
         val protocolStatus = buffer.readUnsignedByte().toInt()
-        if (appStatus != 0 || protocolStatus != ProtocolStatus.REQUEST_COMPLETE.ordinal()) {
+        if (appStatus != 0 || protocolStatus != ProtocolStatus.REQUEST_COMPLETE.ordinal) {
           LOG.warn("Protocol status $protocolStatus")
           dataBuffers.remove(id)
           responseHandler.responseReceived(id, null)
         }
-        else if (protocolStatus == ProtocolStatus.REQUEST_COMPLETE.ordinal()) {
+        else if (protocolStatus == ProtocolStatus.REQUEST_COMPLETE.ordinal) {
           responseHandler.responseReceived(id, dataBuffers.remove(id))
         }
       }
index f678b6425e776dbcfc56179f4076c5a8aee3c71d..6a21aa2e4bf0922eac15cb610da9c55a7b1a2e40 100644 (file)
@@ -142,7 +142,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
   fun getOrCreateStorage(collapsedPath: String,
                          roamingType: RoamingType = RoamingType.DEFAULT,
                          storageClass: Class<out StateStorage> = StateStorage::class.java,
-                         @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") @SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter> = StateSplitterEx::class.java): StateStorage {
+                         @Suppress("DEPRECATION") @SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter> = StateSplitterEx::class.java): StateStorage {
     val normalizedCollapsedPath = normalizeFileSpec(collapsedPath)
     val key = if (storageClass == StateStorage::class.java) normalizedCollapsedPath else storageClass.name
     storageLock.withLock {
@@ -181,7 +181,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
   protected open fun createStateStorage(storageClass: Class<out StateStorage>,
                                         collapsedPath: String,
                                         roamingType: RoamingType,
-                                        @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") stateSplitter: Class<out StateSplitter>): StateStorage {
+                                        @Suppress("DEPRECATION") stateSplitter: Class<out StateSplitter>): StateStorage {
     if (storageClass != StateStorage::class.java) {
       val constructor = storageClass.constructors[0]!!
       constructor.isAccessible = true
@@ -193,7 +193,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
     }
 
     val filePath = expandMacros(collapsedPath)
-    @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
+    @Suppress("DEPRECATION")
     if (stateSplitter != StateSplitter::class.java && stateSplitter != StateSplitterEx::class.java) {
       val storage = MyDirectoryStorage(this, File(filePath), ReflectionUtil.newInstance(stateSplitter))
       virtualFileTracker?.put(filePath, storage)
@@ -212,7 +212,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
     return storage
   }
 
-  private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: File, @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") splitter: StateSplitter) :
+  private class MyDirectoryStorage(override val storageManager: StateStorageManagerImpl, file: File, @Suppress("DEPRECATION") splitter: StateSplitter) :
     DirectoryBasedStorage(file, splitter, storageManager.pathMacroSubstitutor), StorageVirtualFileTracker.TrackedStorage
 
   private class MyFileStorage(override val storageManager: StateStorageManagerImpl,
@@ -370,7 +370,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
       }
 
       var saveSessions: MutableList<SaveSession>? = null
-      val externalizationSessions = sessions.values()
+      val externalizationSessions = sessions.values
       for (session in externalizationSessions) {
         val saveSession = session.createSaveSession()
         if (saveSession != null) {
@@ -389,7 +389,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
 
   override fun getOldStorage(component: Any, componentName: String, operation: StateStorageOperation): StateStorage? {
     val oldStorageSpec = getOldStorageSpec(component, componentName, operation) ?: return null
-    @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
+    @Suppress("DEPRECATION")
     return getOrCreateStorage(oldStorageSpec, if (component is com.intellij.openapi.util.RoamingTypeDisabled) RoamingType.DISABLED else RoamingType.DEFAULT)
   }
 
@@ -398,5 +398,5 @@ open class StateStorageManagerImpl(private val rootTagName: String,
 
 fun String.startsWithMacro(macro: String): Boolean {
   val i = macro.length
-  return length > i && charAt(i) == '/' && startsWith(macro)
+  return length > i && this[i] == '/' && startsWith(macro)
 }
\ No newline at end of file
index 788291746672c906cea51fb8d1ceef87467788e1..d68b7740cae237c052b5cbb7eddf8c9ec1b7f413 100644 (file)
@@ -33,23 +33,13 @@ public final class ByteBufUtf8Writer extends Writer {
     buffer.writeBytes(inputStream, length);
   }
 
+  public void ensureWritable(int minWritableBytes) {
+    buffer.ensureWritable(minWritableBytes);
+  }
+
   @Override
   public void write(int c) {
-    AbstractByteBuf buffer = ByteBufUtilEx.getBuf(this.buffer);
-    int writerIndex = this.buffer.writerIndex();
-    if (c < 0x80) {
-      buffer._setByte(writerIndex++, (byte)c);
-    }
-    else if (c < 0x800) {
-      buffer._setByte(writerIndex++, (byte)(0xc0 | (c >> 6)));
-      buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
-    }
-    else {
-      buffer._setByte(writerIndex++, (byte)(0xe0 | (c >> 12)));
-      buffer._setByte(writerIndex++, (byte)(0x80 | ((c >> 6) & 0x3f)));
-      buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
-    }
-    this.buffer.writerIndex(writerIndex);
+    buffer.writerIndex(ByteBufUtilEx.writeChar(ByteBufUtilEx.getBuf(buffer), buffer.writerIndex(), c));
   }
 
   @Override
index e3d46db36fd5c11bcfeb95e73395da9f452a3d53..72252ed51b8238b68136ae81e0fceac4c1e59939 100644 (file)
@@ -64,19 +64,7 @@ public class ByteBufUtilEx {
     // We can use the _set methods as these not need to do any index checks and reference checks.
     // This is possible as we called ensureWritable(...) before.
     for (int i = start; i < end; i++) {
-      char c = seq.charAt(i);
-      if (c < 0x80) {
-        buffer._setByte(writerIndex++, (byte)c);
-      }
-      else if (c < 0x800) {
-        buffer._setByte(writerIndex++, (byte)(0xc0 | (c >> 6)));
-        buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
-      }
-      else {
-        buffer._setByte(writerIndex++, (byte)(0xe0 | (c >> 12)));
-        buffer._setByte(writerIndex++, (byte)(0x80 | ((c >> 6) & 0x3f)));
-        buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
-      }
+      writerIndex = writeChar(buffer, writerIndex, seq.charAt(i));
     }
 
     // update the writerIndex without any extra checks for performance reasons
@@ -89,6 +77,22 @@ public class ByteBufUtilEx {
     return writerIndex - oldWriterIndex;
   }
 
+  static int writeChar(AbstractByteBuf buffer, int writerIndex, int c) {
+    if (c < 0x80) {
+      buffer._setByte(writerIndex++, (byte)c);
+    }
+    else if (c < 0x800) {
+      buffer._setByte(writerIndex++, (byte)(0xc0 | (c >> 6)));
+      buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
+    }
+    else {
+      buffer._setByte(writerIndex++, (byte)(0xe0 | (c >> 12)));
+      buffer._setByte(writerIndex++, (byte)(0x80 | ((c >> 6) & 0x3f)));
+      buffer._setByte(writerIndex++, (byte)(0x80 | (c & 0x3f)));
+    }
+    return writerIndex;
+  }
+
   @SuppressWarnings("SpellCheckingInspection")
   public static void readUtf8(@NotNull ByteBuf buf, int byteCount, @NotNull CharBuffer charBuffer) throws IOException {
     AbstractByteBuf buffer = getBuf(buf);
index a1dda826657184a24816e0e2b16acb198e9c9562..054af40e376bf3e59038d45e1d948d9609ccae70 100644 (file)
@@ -242,7 +242,7 @@ class VariableView(name: String, private val variable: Variable, private val con
     }
 
     while (count > 0) {
-      if (Character.isDigit(variables.get(count - 1).name.charAt(0))) {
+      if (Character.isDigit(variables.get(count - 1).name[0])) {
         break
       }
       count--
@@ -457,10 +457,10 @@ internal fun trimFunctionDescription(value: Value): String {
   val presentableValue = value.valueString ?: return ""
 
   var endIndex = 0
-  while (endIndex < presentableValue.length && !StringUtil.isLineBreak(presentableValue.charAt(endIndex))) {
+  while (endIndex < presentableValue.length && !StringUtil.isLineBreak(presentableValue[endIndex])) {
     endIndex++
   }
-  while (endIndex > 0 && Character.isWhitespace(presentableValue.charAt(endIndex - 1))) {
+  while (endIndex > 0 && Character.isWhitespace(presentableValue[endIndex - 1])) {
     endIndex--
   }
   return presentableValue.substring(0, endIndex)
index 6dbce6075ad44845e5681d4e898993f5de5ec9a0..bede51561545c17225183350456dea87060d9abb 100644 (file)
@@ -163,8 +163,8 @@ private fun naturalCompare(string1: String?, string2: String?): Int {
   var i = 0
   var j = 0
   while (i < string1Length && j < string2Length) {
-    var ch1 = string1.charAt(i)
-    var ch2 = string2.charAt(j)
+    var ch1 = string1[i]
+    var ch2 = string2[j]
     if ((StringUtil.isDecimalDigit(ch1) || ch1 == ' ') && (StringUtil.isDecimalDigit(ch2) || ch2 == ' ')) {
       var startNum1 = i
       while (ch1 == ' ' || ch1 == '0') {
@@ -173,7 +173,7 @@ private fun naturalCompare(string1: String?, string2: String?): Int {
         if (startNum1 >= string1Length) {
           break
         }
-        ch1 = string1.charAt(startNum1)
+        ch1 = string1[startNum1]
       }
       var startNum2 = j
       while (ch2 == ' ' || ch2 == '0') {
@@ -182,15 +182,15 @@ private fun naturalCompare(string1: String?, string2: String?): Int {
         if (startNum2 >= string2Length) {
           break
         }
-        ch2 = string2.charAt(startNum2)
+        ch2 = string2[startNum2]
       }
       i = startNum1
       j = startNum2
       // find end index of number
-      while (i < string1Length && StringUtil.isDecimalDigit(string1.charAt(i))) {
+      while (i < string1Length && StringUtil.isDecimalDigit(string1[i])) {
         i++
       }
-      while (j < string2Length && StringUtil.isDecimalDigit(string2.charAt(j))) {
+      while (j < string2Length && StringUtil.isDecimalDigit(string2[j])) {
         j++
       }
       val lengthDiff = (i - startNum1) - (j - startNum2)
@@ -200,7 +200,7 @@ private fun naturalCompare(string1: String?, string2: String?): Int {
       }
       while (startNum1 < i) {
         // compare numbers with equal digit count
-        val diff = string1.charAt(startNum1) - string2.charAt(startNum2)
+        val diff = string1[startNum1] - string2[startNum2]
         if (diff != 0) {
           return diff
         }
@@ -244,7 +244,7 @@ fun createVariablesList(variables: List<Variable>, from: Int, to: Int, variableC
   val list = XValueChildrenList(to - from)
   var getterOrSetterContext: VariableContext? = null
   for (i in from..to - 1) {
-    val variable = variables.get(i)
+    val variable = variables[i]
     val normalizedName = if (memberFilter == null) variable.name else memberFilter.rawNameToSource(variable)
     list.add(VariableView(normalizedName, variable, variableContext))
     if (variable is ObjectProperty) {
index 99d6f69affd0b16b7cd70518e9646381ea4e8ee2..281edddba5f2c100340132b8098cdb8fcc3ef5ed 100644 (file)
@@ -94,7 +94,7 @@ private fun StringBuilder.addList(name: String, list: Collection<String>, compac
   }
 
   if (compact) {
-    if (length != 0 && charAt(length - 1) != ' ') {
+    if (length != 0 && this[length - 1] != ' ') {
       append('\t')
     }
     append(name)