]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/util/MessageCacheUtils.java
43badfa6771bbb19d99aeede9aae833e338254d9
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / util / MessageCacheUtils.java
1 package org.asamk.signal.manager.util;
2
3 import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
4 import org.whispersystems.signalservice.api.push.ServiceId;
5 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
6 import org.whispersystems.signalservice.api.util.UuidUtil;
7
8 import java.io.DataInputStream;
9 import java.io.DataOutputStream;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileOutputStream;
13 import java.io.IOException;
14 import java.util.Optional;
15
16 public class MessageCacheUtils {
17
18 public static SignalServiceEnvelope loadEnvelope(File file) throws IOException {
19 try (var f = new FileInputStream(file)) {
20 var in = new DataInputStream(f);
21 var version = in.readInt();
22 if (version > 6) {
23 // Unsupported envelope version
24 return null;
25 }
26 var type = in.readInt();
27 var source = in.readUTF();
28 ServiceId sourceServiceId = null;
29 if (version >= 3) {
30 sourceServiceId = ServiceId.parseOrNull(in.readUTF());
31 }
32 var sourceDevice = in.readInt();
33 if (version == 1) {
34 // read legacy relay field
35 in.readUTF();
36 }
37 String destinationUuid = null;
38 if (version >= 5) {
39 destinationUuid = in.readUTF();
40 }
41 var timestamp = in.readLong();
42 byte[] content = null;
43 var contentLen = in.readInt();
44 if (contentLen > 0) {
45 content = new byte[contentLen];
46 in.readFully(content);
47 }
48 byte[] legacyMessage = null;
49 var legacyMessageLen = in.readInt();
50 if (legacyMessageLen > 0) {
51 legacyMessage = new byte[legacyMessageLen];
52 in.readFully(legacyMessage);
53 }
54 long serverReceivedTimestamp = 0;
55 String uuid = null;
56 if (version >= 2) {
57 serverReceivedTimestamp = in.readLong();
58 uuid = in.readUTF();
59 if ("".equals(uuid)) {
60 uuid = null;
61 }
62 }
63 long serverDeliveredTimestamp = 0;
64 if (version >= 4) {
65 serverDeliveredTimestamp = in.readLong();
66 }
67 boolean isUrgent = true;
68 if (version >= 6) {
69 isUrgent = in.readBoolean();
70 }
71 Optional<SignalServiceAddress> addressOptional = sourceServiceId == null
72 ? Optional.empty()
73 : Optional.of(new SignalServiceAddress(sourceServiceId, source));
74 return new SignalServiceEnvelope(type,
75 addressOptional,
76 sourceDevice,
77 timestamp,
78 legacyMessage,
79 content,
80 serverReceivedTimestamp,
81 serverDeliveredTimestamp,
82 uuid,
83 destinationUuid == null ? UuidUtil.UNKNOWN_UUID.toString() : destinationUuid,
84 isUrgent);
85 }
86 }
87
88 public static void storeEnvelope(SignalServiceEnvelope envelope, File file) throws IOException {
89 try (var f = new FileOutputStream(file)) {
90 try (var out = new DataOutputStream(f)) {
91 out.writeInt(6); // version
92 out.writeInt(envelope.getType());
93 out.writeUTF(envelope.getSourceE164().isPresent() ? envelope.getSourceE164().get() : "");
94 out.writeUTF(envelope.getSourceUuid().isPresent() ? envelope.getSourceUuid().get() : "");
95 out.writeInt(envelope.getSourceDevice());
96 out.writeUTF(envelope.getDestinationUuid() == null ? "" : envelope.getDestinationUuid());
97 out.writeLong(envelope.getTimestamp());
98 if (envelope.hasContent()) {
99 out.writeInt(envelope.getContent().length);
100 out.write(envelope.getContent());
101 } else {
102 out.writeInt(0);
103 }
104 if (envelope.hasLegacyMessage()) {
105 out.writeInt(envelope.getLegacyMessage().length);
106 out.write(envelope.getLegacyMessage());
107 } else {
108 out.writeInt(0);
109 }
110 out.writeLong(envelope.getServerReceivedTimestamp());
111 var uuid = envelope.getServerGuid();
112 out.writeUTF(uuid == null ? "" : uuid);
113 out.writeLong(envelope.getServerDeliveredTimestamp());
114 out.writeBoolean(envelope.isUrgent());
115 }
116 }
117 }
118 }