import org.asamk.signal.storage.contacts.JsonContactsStore;
import org.asamk.signal.storage.groups.GroupInfo;
import org.asamk.signal.storage.groups.JsonGroupStore;
+import org.asamk.signal.storage.profiles.ProfileStore;
import org.asamk.signal.storage.protocol.JsonIdentityKeyStore;
import org.asamk.signal.storage.protocol.JsonSignalProtocolStore;
import org.asamk.signal.storage.protocol.RecipientStore;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.util.Base64;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.Channels;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Collection;
private JsonGroupStore groupStore;
private JsonContactsStore contactStore;
private RecipientStore recipientStore;
+ private ProfileStore profileStore;
private SignalAccount(final FileChannel fileChannel, final FileLock lock) {
this.fileChannel = fileChannel;
this.lock = lock;
jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); // disable autodetect
jsonProcessor.enable(SerializationFeature.INDENT_OUTPUT); // for pretty print, you can disable it.
- jsonProcessor.enable(SerializationFeature.WRITE_NULL_MAP_VALUES);
jsonProcessor.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
jsonProcessor.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
account.groupStore = new JsonGroupStore();
account.contactStore = new JsonContactsStore();
account.recipientStore = new RecipientStore();
+ account.profileStore = new ProfileStore();
account.registered = false;
return account;
account.groupStore = new JsonGroupStore();
account.contactStore = new JsonContactsStore();
account.recipientStore = new RecipientStore();
+ account.profileStore = new ProfileStore();
account.registered = true;
account.isMultiDevice = true;
}
}
+ JsonNode profileStoreNode = rootNode.get("profileStore");
+ if (profileStoreNode != null) {
+ profileStore = jsonProcessor.convertValue(profileStoreNode, ProfileStore.class);
+ }
+ if (profileStore == null) {
+ profileStore = new ProfileStore();
+ }
+
JsonNode threadStoreNode = rootNode.get("threadStore");
if (threadStoreNode != null) {
LegacyJsonThreadStore threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
.putPOJO("groupStore", groupStore)
.putPOJO("contactStore", contactStore)
.putPOJO("recipientStore", recipientStore)
+ .putPOJO("profileStore", profileStore)
;
try {
- synchronized (fileChannel) {
- fileChannel.position(0);
- jsonProcessor.writeValue(Channels.newOutputStream(fileChannel), rootNode);
- fileChannel.truncate(fileChannel.position());
- fileChannel.force(false);
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+ // Write to memory first to prevent corrupting the file in case of serialization errors
+ jsonProcessor.writeValue(output, rootNode);
+ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+ synchronized (fileChannel) {
+ fileChannel.position(0);
+ input.transferTo(Channels.newOutputStream(fileChannel));
+ fileChannel.truncate(fileChannel.position());
+ fileChannel.force(false);
+ }
}
} catch (Exception e) {
System.err.println(String.format("Error saving file: %s", e.getMessage()));
return recipientStore;
}
+ public ProfileStore getProfileStore() {
+ return profileStore;
+ }
+
public String getUsername() {
return username;
}
@Override
public void close() throws IOException {
synchronized (fileChannel) {
- lock.close();
+ try {
+ lock.close();
+ } catch (ClosedChannelException ignored) {
+ }
fileChannel.close();
}
}