docs: public MessagePacker packString(String s)
              throws IOException
      {
          if (s.length() <= 0) {
              packRawStringHeader(0);
              return this;
          }
          else if (CORRUPTED_CHARSET_ENCODER || s.length() < smallStringOptimizationThreshold) {
              // Using String.getBytes is generally faster for small strings.
              // Also, when running on a platform that has a corrupted CharsetEncoder (i.e. Android 4.x), avoid using it.
              packStringWithGetBytes(s);
              return this;
          }
          else if (s.length() < (1 << 8)) {
              // ensure capacity for 2-byte raw string header + the maximum string size (+ 1 byte for falback code)
              ensureCapacity(2 + s.length() * UTF_8_MAX_CHAR_SIZE + 1);
              // keep 2-byte header region and write raw string
              int written = encodeStringToBufferAt(position + 2, s);
              if (written >= 0) {
                  if (str8FormatSupport && written < (1 << 8)) {
                      buffer.putByte(position++, STR8);
                      buffer.putByte(position++, (byte) written);
                      position += written;
                  }
                  else {
                      if (written >= (1 << 16)) {
                          // this must not happen because s.length() is less than 2^8 and (2^8) * UTF_8_MAX_CHAR_SIZE is less than 2^16
                          throw new IllegalArgumentException("Unexpected UTF-8 encoder state");
                      }
                      // move 1 byte backward to expand 3-byte header region to 3 bytes
                      buffer.putMessageBuffer(position + 3, buffer, position + 2, written);
                      // write 3-byte header
                      buffer.putByte(position++, STR16);
                      buffer.putShort(position, (short) written);
                      position += 2;
                      position += written;
                  }
                  return this;
              }
          }
          else if (s.length() < (1 << 16)) {
              // ensure capacity for 3-byte raw string header + the maximum string size (+ 2 bytes for fallback code)
              ensureCapacity(3 + s.length() * UTF_8_MAX_CHAR_SIZE + 2);
              // keep 3-byte header region and write raw string
              int written = encodeStringToBufferAt(position + 3, s);
              if (written >= 0) {
                  if (written < (1 << 16)) {
                      buffer.putByte(position++, STR16);
                      buffer.putShort(position, (short) written);
                      position += 2;
                      position += written;
                  }
                  else {
                      if (written >= (1L << 32)) {  // this check does nothing because (1L << 32) is larger than Integer.MAX_VALUE
                          // this must not happen because s.length() is less than 2^16 and (2^16) * UTF_8_MAX_CHAR_SIZE is less than 2^32
                          throw new IllegalArgumentException("Unexpected UTF-8 encoder state");
                      }
                      // move 2 bytes backward to expand 3-byte header region to 5 bytes
                      buffer.putMessageBuffer(position + 5, buffer, position + 3, written);
                      // write 3-byte header header
                      buffer.putByte(position++, STR32);
                      buffer.putInt(position, written);
                      position += 4;
                      position += written;
                  }
                  return this;
              }
          }
  
          // Here doesn't use above optimized code for s.length() < (1 << 32) so that
          // ensureCapacity is not called with an integer larger than (3 + ((1 << 16) * UTF_8_MAX_CHAR_SIZE) + 2).
          // This makes it sure that MessageBufferOutput.next won't be called a size larger than
          // 384KB, which is OK size to keep in memory.
  
          // fallback
          packStringWithGetBytes(s);
          return this;
      }