1 package org
.asamk
.signal
.manager
.util
;
3 import org
.slf4j
.Logger
;
4 import org
.slf4j
.LoggerFactory
;
5 import org
.whispersystems
.signalservice
.api
.messages
.SignalServiceEnvelope
;
6 import org
.whispersystems
.signalservice
.api
.push
.ServiceId
;
7 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
8 import org
.whispersystems
.signalservice
.api
.util
.UuidUtil
;
10 import java
.io
.DataInputStream
;
11 import java
.io
.DataOutputStream
;
13 import java
.io
.FileInputStream
;
14 import java
.io
.FileOutputStream
;
15 import java
.io
.IOException
;
16 import java
.util
.Optional
;
18 public class MessageCacheUtils
{
20 private final static Logger logger
= LoggerFactory
.getLogger(MessageCacheUtils
.class);
22 final static int CURRENT_VERSION
= 8;
24 public static SignalServiceEnvelope
loadEnvelope(File file
) throws IOException
{
25 try (var f
= new FileInputStream(file
)) {
26 var in = new DataInputStream(f
);
27 var version
= in.readInt();
28 logger
.trace("Reading cached envelope file with version {} (current: {})", version
, CURRENT_VERSION
);
29 if (version
> CURRENT_VERSION
) {
30 logger
.warn("Unsupported envelope version {} (current: {})", version
, CURRENT_VERSION
);
31 // Unsupported envelope version
34 var type
= in.readInt();
35 var source
= in.readUTF();
36 ServiceId sourceServiceId
= null;
38 sourceServiceId
= ServiceId
.parseOrNull(in.readUTF());
40 var sourceDevice
= in.readInt();
42 // read legacy relay field
45 String destinationUuid
= null;
47 destinationUuid
= in.readUTF();
49 var timestamp
= in.readLong();
50 byte[] content
= null;
51 var contentLen
= in.readInt();
53 content
= new byte[contentLen
];
54 in.readFully(content
);
56 var legacyMessageLen
= in.readInt();
57 if (legacyMessageLen
> 0) {
58 byte[] legacyMessage
= new byte[legacyMessageLen
];
59 in.readFully(legacyMessage
);
61 long serverReceivedTimestamp
= 0;
64 serverReceivedTimestamp
= in.readLong();
66 if ("".equals(uuid
)) {
70 long serverDeliveredTimestamp
= 0;
72 serverDeliveredTimestamp
= in.readLong();
74 boolean isUrgent
= true;
76 isUrgent
= in.readBoolean();
78 boolean isStory
= true;
80 isStory
= in.readBoolean();
82 String updatedPni
= null;
84 updatedPni
= in.readUTF();
86 Optional
<SignalServiceAddress
> addressOptional
= sourceServiceId
== null
88 : Optional
.of(new SignalServiceAddress(sourceServiceId
, source
));
89 return new SignalServiceEnvelope(type
,
94 serverReceivedTimestamp
,
95 serverDeliveredTimestamp
,
97 destinationUuid
== null ? UuidUtil
.UNKNOWN_UUID
.toString() : destinationUuid
,
99 updatedPni
== null ?
"" : updatedPni
,
104 public static void storeEnvelope(SignalServiceEnvelope envelope
, File file
) throws IOException
{
105 try (var f
= new FileOutputStream(file
)) {
106 try (var out
= new DataOutputStream(f
)) {
107 out
.writeInt(CURRENT_VERSION
); // version
108 out
.writeInt(envelope
.getType());
109 out
.writeUTF(""); // legacy number
110 out
.writeUTF(envelope
.getSourceUuid().isPresent() ? envelope
.getSourceUuid().get() : "");
111 out
.writeInt(envelope
.getSourceDevice());
112 out
.writeUTF(envelope
.getDestinationUuid() == null ?
"" : envelope
.getDestinationUuid());
113 out
.writeLong(envelope
.getTimestamp());
114 if (envelope
.hasContent()) {
115 out
.writeInt(envelope
.getContent().length
);
116 out
.write(envelope
.getContent());
120 out
.writeInt(0); // legacy message
121 out
.writeLong(envelope
.getServerReceivedTimestamp());
122 var uuid
= envelope
.getServerGuid();
123 out
.writeUTF(uuid
== null ?
"" : uuid
);
124 out
.writeLong(envelope
.getServerDeliveredTimestamp());
125 out
.writeBoolean(envelope
.isUrgent());
126 out
.writeBoolean(envelope
.isStory());
127 out
.writeUTF(envelope
.getUpdatedPni() == null ?
"" : envelope
.getUpdatedPni());