private String readNonControlCharacters()

in core/src/com/jediterm/terminal/emulator/JediEmulator.java [96:129]


  private String readNonControlCharacters(int maxChars, boolean ambiguousAreDWC) throws IOException {
    var result = myDataStream.readNonControlCharacters(maxChars);
    var visualLength = 0;
    var end = 0;
    for (int i = 0; i < result.length(); ++i) {
      // TODO surrogate pair support missing, but it must be implemented in the entire library at once
      var c = result.charAt(i);
      var sourceLength = i + 1;
      visualLength += CharUtils.isDoubleWidthCharacter(c, ambiguousAreDWC) ? 2 : 1;
      // Three cases:
      if (visualLength == maxChars) {
        end = sourceLength; // 1) found exactly maxChars
        break;
      }
      else if (visualLength < maxChars) {
        end = sourceLength; // 2) found less, continue searching
      }
      else { // visualLength > maxChars
        break; // 3) found less on the previous iteration, but now it's too many (1 char of space left, but a DWC is found)
      }
    }
    boolean nextIsDWC = false;
    if (end < result.length()) {
      var pushBack = new char[result.length() - end];
      result.getChars(end, result.length(), pushBack, 0);
      nextIsDWC = CharUtils.isDoubleWidthCharacter(pushBack[0], ambiguousAreDWC);
      myDataStream.pushBackBuffer(pushBack, pushBack.length);
    }
    // A special case: if the next char is DWC, but it doesn't fit on this line (case 3 above),
    // then we must fill the line with an additional space to trigger line wrapping.
    // Otherwise, it'll be an endless loop: read, realize it doesn't fit, push back, read again...
    if (end == maxChars - 1 && nextIsDWC) return result.substring(0, end) + " ";
    return result.substring(0, end);
  }