diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/dialogs/NicklistDialog.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/dialogs/NicklistDialog.kt index 1ef3ba47f..7e9f66936 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/dialogs/NicklistDialog.kt +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/dialogs/NicklistDialog.kt @@ -34,7 +34,7 @@ class NicklistDialog : ListDialog(), this.buffer = buffer this.title = buffer.shortName this.adapter = NicklistAdapter(requireContext()) { - Events.SendMessageEvent.fire("input 0x%x /query -noswitch %s", buffer.pointer, it.name) + Events.SendMessageEvent.fireInput(buffer, "/query -noswitch ${it.name}") dismiss() } } diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Buffer.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Buffer.kt index 67ef7adf3..e01e2a9fe 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Buffer.kt +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Buffer.kt @@ -198,8 +198,8 @@ class Buffer @WorkerThread constructor( @MainThread @Synchronized fun moveReadMarkerToEnd() { lines.moveReadMarkerToEnd() if (P.hotlistSync) Events.SendMessageEvent.fire( - "input 0x%1${"$"}x /buffer set hotlist -1\n" + - "input 0x%1${"$"}x /input set_unread_current_buffer", pointer) + "input ${pointer.as0x} /buffer set hotlist -1\n" + + "input ${pointer.as0x} /input set_unread_current_buffer") } val hotCount: Int diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Line.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Line.kt index 9003c7797..3a1d67030 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Line.kt +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/Line.kt @@ -19,7 +19,6 @@ import com.ubergeek42.WeechatAndroid.utils.SHOULD_EMOJIFY import com.ubergeek42.WeechatAndroid.utils.emojify import com.ubergeek42.weechat.Color import com.ubergeek42.weechat.ColorScheme -import java.lang.Long.toHexString open class Line constructor( @@ -104,5 +103,5 @@ open class Line constructor( val timestampedIrcLikeString: String get() = timestampString?.let { timestamp -> "$timestamp $ircLikeString" } ?: ircLikeString - override fun toString() = "Line(0x${toHexString(pointer)}: $ircLikeString)" + override fun toString() = "Line(${pointer.as0x}): $ircLikeString)" } diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/RelayUtils.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/RelayUtils.kt index 389d6433d..6ed452e50 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/RelayUtils.kt +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/relay/RelayUtils.kt @@ -56,8 +56,8 @@ inline fun Hdata.forEachExistingBuffer(block: (spec: BufferSpec, buffer: Buffer) } -val Long.as0x get() = "0x" + java.lang.Long.toHexString(this) +val Long.as0x get() = "0x" + java.lang.Long.toUnsignedString(this, 16) -val String.from0x: Long get() = java.lang.Long.decode(this) +val String.from0x: Long get() = java.lang.Long.parseUnsignedLong(this.substring(2), 16) val String.from0xOrNull get() = try { from0x } catch (e: NumberFormatException) { null } \ No newline at end of file diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.java b/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.java deleted file mode 100644 index 8fbf4c959..000000000 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.java +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. - -package com.ubergeek42.WeechatAndroid.service; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.text.TextUtils; - -import com.ubergeek42.WeechatAndroid.relay.Buffer; -import com.ubergeek42.WeechatAndroid.service.RelayService.STATE; - -import org.greenrobot.eventbus.EventBus; - -import java.util.EnumSet; -import java.util.Locale; - -import static com.ubergeek42.WeechatAndroid.utils.Assert.assertThat; - - -public class Events { - - public static class StateChangedEvent { - final public EnumSet state; - - public StateChangedEvent(EnumSet state) { - this.state = state; - } - - @Override public @NonNull String toString() { - return "StateChangedEvent(state=" + state + ")"; - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - - public static class ExceptionEvent { - final public Exception e; - - ExceptionEvent(Exception e) { - this.e = e; - } - - @Override public @NonNull String toString() { - return "ExceptionEvent(e=" + e + ")"; - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////// - - public static class SendMessageEvent { - final public String message; - - private SendMessageEvent(String message) { - this.message = message; - } - - public static void fire(@NonNull String message) { - assertThat(message.endsWith("\n")).isFalse(); - EventBus.getDefault().post(new SendMessageEvent(message)); - } - - public static void fire(@NonNull String message, @NonNull Object... args) { - fire(String.format(Locale.ROOT, message, args)); - } - - public static void fireInput(@NonNull Buffer buffer, @Nullable String input) { - if (TextUtils.isEmpty(input)) return; - P.addSentMessage(input); - //noinspection ConstantConditions -- linter doesn't see the call to isEmpty - for (String line : input.split("\n")) - if (!TextUtils.isEmpty(line)) - fire("input 0x%x %s", buffer.pointer, line); - } - - @Override public @NonNull String toString() { - return "SendMessageEvent(message=" + message + ")"; - } - } -} diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.kt new file mode 100644 index 000000000..12980fe72 --- /dev/null +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/service/Events.kt @@ -0,0 +1,36 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. + +package com.ubergeek42.WeechatAndroid.service + +import com.ubergeek42.WeechatAndroid.relay.Buffer +import com.ubergeek42.WeechatAndroid.relay.as0x +import com.ubergeek42.WeechatAndroid.utils.Assert +import org.greenrobot.eventbus.EventBus +import java.util.EnumSet +import java.util.Locale + +class Events { + data class StateChangedEvent(@JvmField val state: EnumSet) + + data class ExceptionEvent(@JvmField val e: Exception) + + data class SendMessageEvent(@JvmField val message: String) { + companion object { + fun fire(message: String) { + Assert.assertThat(message.endsWith("\n")).isFalse() + EventBus.getDefault().post(SendMessageEvent(message)) + } + + fun fireInput(buffer: Buffer, input: String?) { + if (input.isNullOrEmpty()) return + + P.addSentMessage(input) + + input.lineSequence().filter(String::isNotEmpty).forEach { line -> + fire("input ${buffer.pointer.as0x} $line") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/tabcomplete/OnlineTabCompleter.kt b/app/src/main/java/com/ubergeek42/WeechatAndroid/tabcomplete/OnlineTabCompleter.kt index e39293df9..f27c24741 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/tabcomplete/OnlineTabCompleter.kt +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/tabcomplete/OnlineTabCompleter.kt @@ -4,6 +4,7 @@ import android.widget.EditText import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope import com.ubergeek42.WeechatAndroid.relay.Buffer +import com.ubergeek42.WeechatAndroid.relay.as0x import com.ubergeek42.WeechatAndroid.upload.suppress import com.ubergeek42.weechat.relay.protocol.Hdata import com.ubergeek42.weechat.relay.protocol.RelayObject @@ -45,7 +46,7 @@ class OnlineTabCompleter( // so instead we rely on base word, assuming that it ends on selection end private suspend fun fetchCompletions(): Iterator { val selectionStart = input.selectionStart - val message = "completion 0x%x %d %s".format(buffer.pointer, selectionStart, input.text) + val message = "completion ${buffer.pointer.as0x} $selectionStart ${input.text}" val (completions, baseWord, addSpace) = queryWeechat(message).asCompletions() ?: return EmptyReplacements diff --git a/app/src/main/java/com/ubergeek42/WeechatAndroid/utils/Utils.java b/app/src/main/java/com/ubergeek42/WeechatAndroid/utils/Utils.java index 098022c81..ff5d98bc5 100644 --- a/app/src/main/java/com/ubergeek42/WeechatAndroid/utils/Utils.java +++ b/app/src/main/java/com/ubergeek42/WeechatAndroid/utils/Utils.java @@ -180,12 +180,12 @@ public interface Predicate { } public static String pointerToString(long pointer) { - return Long.toHexString(pointer); + return Long.toUnsignedString(pointer, 16); } public static long pointerFromString(String strPointer) { try { - return Long.parseLong(strPointer, 16); + return Long.parseUnsignedLong(strPointer, 16); } catch (NumberFormatException ignored) { return 0; } diff --git a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/Data.java b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/Data.java index ac3abdc18..23bd7b1c9 100644 --- a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/Data.java +++ b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/Data.java @@ -60,7 +60,8 @@ public char getChar() { return (char) getByte(); } - // Might have to change to a BigInteger... + // What we are given directly corresponds to a regular signed long. + // https://weechat.org/files/doc/stable/weechat_relay_protocol.en.html#object_long_integer public long getLongInteger() { int length = getByte(); if (pointer + length > data.length) { @@ -129,17 +130,13 @@ public String getPointer() { throw new IndexOutOfBoundsException("Not enough data"); } - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder("0x"); + for (int i = 0; i < length; i++) { sb.append(getChar()); } - if (length == 1 && Long.parseLong(sb.toString().toUpperCase(Locale.ENGLISH), 16) == 0) { - // Null Pointer - return "0x0"; - } - - return "0x" + sb.toString(); + return sb.toString(); } // Maybe return a reasonable "Date" object or similar diff --git a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/HdataEntry.java b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/HdataEntry.java index 132e37595..5024a5dc5 100644 --- a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/HdataEntry.java +++ b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/HdataEntry.java @@ -25,8 +25,8 @@ * */ public class HdataEntry extends RelayObject { - private ArrayList pointers = new ArrayList(); - private HashMap data = new HashMap(); + private final ArrayList pointers = new ArrayList(); + private final HashMap data = new HashMap(); protected void addPointer(String pointer) { pointers.add(pointer); @@ -83,7 +83,7 @@ public String getPointer() { public long getPointerLong() { try { - return Long.parseLong(getPointer().substring(2), 16); + return Long.parseUnsignedLong(getPointer().substring(2), 16); } catch (Exception e) { return -1; } @@ -102,7 +102,7 @@ public String getPointer(int index) { public long getPointerLong(int index) { try { - return Long.parseLong(getPointer(index).substring(2), 16); + return Long.parseUnsignedLong(getPointer(index).substring(2), 16); } catch (Exception e) { return -1; } diff --git a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/RelayObject.java b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/RelayObject.java index 61d388ec6..90b7fa10d 100644 --- a/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/RelayObject.java +++ b/relay/src/main/java/com/ubergeek42/weechat/relay/protocol/RelayObject.java @@ -157,7 +157,7 @@ public String asPointer() { public long asPointerLong() { try { - return Long.parseLong(asPointer().substring(2), 16); + return Long.parseUnsignedLong(asPointer().substring(2), 16); } catch (Exception e) { return -1; }