Browse Source

Support for tsirc alongside message tags. Close #149

pull/150/head
Shane Mc Cormack 7 years ago
parent
commit
0a45b60a1e

+ 6
- 3
irc/src/main/java/com/dmdirc/parser/irc/IRCParser.java View File

@@ -929,17 +929,20 @@ public class IRCParser extends BaseSocketAwareParser implements SecureParser, En
929 929
         // Check for IRC Tags.
930 930
         if (line.charAt(0) == '@') {
931 931
             // We have tags.
932
+            boolean hasIRCv3Tags = true;
932 933
             tokens = line.split(" ", 2);
933 934
             final int tsEnd = tokens[0].indexOf('@', 1);
934
-            boolean hasTSIRCDate = false;
935 935
             if (tsEnd > -1) {
936 936
                 try {
937 937
                     final long ts = Long.parseLong(tokens[0].substring(1, tsEnd));
938
-                    hasTSIRCDate = true;
938
+
939
+                    // We might have both IRCv3 tags and TSIRC, with TSIRC first, eg:
940
+                    // @123@@tag=value :test ing
941
+                    hasIRCv3Tags = tokens[0].length() > tsEnd && tokens[0].charAt(tsEnd) == '@';
939 942
                 } catch (final NumberFormatException nfe) { /* Not a timestamp. */ }
940 943
             }
941 944
 
942
-            if (!hasTSIRCDate) {
945
+            if (hasIRCv3Tags) {
943 946
                 // IRCv3 Tags, last arg is actually the second " :"
944 947
                 lastarg = line.indexOf(" :", lastarg+1);
945 948
             }

+ 33
- 12
irc/src/main/java/com/dmdirc/parser/irc/IRCReader.java View File

@@ -32,6 +32,7 @@ import java.nio.charset.CharacterCodingException;
32 32
 import java.nio.charset.Charset;
33 33
 import java.nio.charset.CharsetDecoder;
34 34
 import java.nio.charset.CodingErrorAction;
35
+import java.util.Arrays;
35 36
 import java.util.HashMap;
36 37
 import java.util.Map;
37 38
 
@@ -251,30 +252,50 @@ public class IRCReader implements Closeable {
251 252
             this.line = line;
252 253
 
253 254
             String[] tokens = lineTokens;
255
+
256
+            // In the case where TSIRC and message tags are used, the TSIRC tag can appear in 1 of 2 places depending
257
+            // on interpretation of the spec - Either right at the start of the line, or as part of the actual message.
258
+            // EG:
259
+            // @123@@tag=value :test ing
260
+            // @tag=value @123@:test ing
261
+            //
262
+            // are both functionally equivalent.
263
+
264
+            // Look for old-style TSIRC timestamp first.
254 265
             if (!tokens[0].isEmpty() && tokens[0].charAt(0) == '@') {
255
-                // Look for old-style TSIRC timestamp first.
256 266
                 final int tsEnd = tokens[0].indexOf('@', 1);
257
-                boolean hasTSIRCDate = false;
258 267
                 if (tsEnd > -1) {
259 268
                     try {
260 269
                         final long ts = Long.parseLong(tokens[0].substring(1, tsEnd));
261 270
                         tags.put("tsirc date", tokens[0].substring(1, tsEnd));
262
-                        hasTSIRCDate = true;
263 271
                         tokens[0] = tokens[0].substring(tsEnd + 1);
264 272
                     } catch (final NumberFormatException nfe) { /* Not a timestamp. */ }
265 273
                 }
274
+            }
266 275
 
267
-                if (!hasTSIRCDate) {
268
-                    final String[] lineTags = tokens[0].substring(1).split(";");
269
-                    for (final String keyVal : lineTags) {
270
-                        if (!keyVal.isEmpty()) {
271
-                            final String[] keyValue = keyVal.split("=", 2);
272
-                            tags.put(keyValue[0], keyValue.length > 1 ? keyValue[1] : "");
273
-                        }
276
+            // Now look for message tags.
277
+            if (!tokens[0].isEmpty() && tokens[0].charAt(0) == '@') {
278
+                final String[] lineTags = tokens[0].substring(1).split(";");
279
+                for (final String keyVal : lineTags) {
280
+                    if (!keyVal.isEmpty()) {
281
+                        final String[] keyValue = keyVal.split("=", 2);
282
+                        tags.put(keyValue[0], keyValue.length > 1 ? keyValue[1] : "");
274 283
                     }
284
+                }
285
+
286
+                tokens = new String[lineTokens.length - 1];
287
+                System.arraycopy(lineTokens, 1, tokens, 0, lineTokens.length - 1);
288
+            }
275 289
 
276
-                    tokens = new String[lineTokens.length - 1];
277
-                    System.arraycopy(lineTokens, 1, tokens, 0, lineTokens.length - 1);
290
+            // Look again for tsirc, as it may be after the message tags.
291
+            if (!tokens[0].isEmpty() && tokens[0].charAt(0) == '@') {
292
+                final int tsEnd = tokens[0].indexOf('@', 1);
293
+                if (tsEnd > -1) {
294
+                    try {
295
+                        final long ts = Long.parseLong(tokens[0].substring(1, tsEnd));
296
+                        tags.put("tsirc date", tokens[0].substring(1, tsEnd));
297
+                        tokens[0] = tokens[0].substring(tsEnd + 1);
298
+                    } catch (final NumberFormatException nfe) { /* Not a timestamp. */ }
278 299
                 }
279 300
             }
280 301
 

+ 22
- 0
irc/src/test/java/com/dmdirc/parser/irc/IRCReaderTest.java View File

@@ -208,6 +208,28 @@ public class IRCReaderTest {
208 208
         assertNull(line.getTags().get("time"));
209 209
     }
210 210
 
211
+    /** Verify tokeniser with TSIRC Time Stamp and Message Tags (tags first). */
212
+    @Test
213
+    public void testReadLineTSIRCandTag() throws IOException {
214
+        final ReadLine line = new ReadLine("", IRCParser.tokeniseLine("@tag=value @123@:test ing"));
215
+
216
+        assertEquals(":test", line.getTokens()[0]);
217
+        assertEquals("ing", line.getTokens()[1]);
218
+        assertEquals("123", line.getTags().get("tsirc date"));
219
+        assertEquals("value", line.getTags().get("tag"));
220
+    }
221
+
222
+    /** Verify tokeniser with TSIRC Time Stamp and Message Tags (tags second). */
223
+    @Test
224
+    public void testReadLineTSIRCandTag2() throws IOException {
225
+        final ReadLine line = new ReadLine("", IRCParser.tokeniseLine("@123@@tag=value :test ing"));
226
+
227
+        assertEquals(":test", line.getTokens()[0]);
228
+        assertEquals("ing", line.getTokens()[1]);
229
+        assertEquals("123", line.getTags().get("tsirc date"));
230
+        assertEquals("value", line.getTags().get("tag"));
231
+    }
232
+
211 233
     /** Verify tokeniser with IRCv3 tags */
212 234
     @Test
213 235
     public void testReadLineIRCv3TS() throws IOException {

Loading…
Cancel
Save